Code refactoring.

master
Vectozavr 2021-10-17 14:21:10 +07:00
parent 3cbe93c6c0
commit fb7b4878ea
25 changed files with 252 additions and 212 deletions

View File

@ -9,7 +9,7 @@
#include "Player.h"
class Bonus final : public RigidBody {
protected:
private:
std::string _name;
public:
explicit Bonus(const std::string &bonusName, const std::string& filename, const std::string &materials = "", const Vec3D& scale = Vec3D{1, 1, 1});

View File

@ -45,7 +45,7 @@ void Client::processUpdate(sf::Packet& packet) {
_players[targetId]->setHealth(buf[3]);
_players[targetId]->rotateToAngle(Vec3D{0, buf[4], 0});
_players[targetId]->attached("head")->rotate(Matrix4x4::RotationY(buf[4]) * Vec3D{1, 0, 0}, buf[5] - _players[targetId]->headAngle());
_players[targetId]->attached(ObjectNameTag("head"))->rotate(Matrix4x4::RotationY(buf[4]) * Vec3D{1, 0, 0}, buf[5] - _players[targetId]->headAngle());
_players[targetId]->setHeadAngle(buf[5]);
} else if (targetId == _socket.ownId()) {
@ -118,8 +118,11 @@ void Client::processCustomPacket(MsgType type, sf::Packet& packet) {
case MsgType::RemoveBonus:
packet >> tmp;
if(_removeBonusCallBack != nullptr)
_removeBonusCallBack(tmp);
_removeBonusCallBack(ObjectNameTag(tmp));
break;
default:
throw std::logic_error{"Client::processCustomPacket: unknown MsgType"};
}
}
@ -152,7 +155,7 @@ void Client::takeBonus(const std::string& bonusName) {
_socket.send(packet, _socket.serverId());
if(_removeBonusCallBack != nullptr)
_removeBonusCallBack(bonusName);
_removeBonusCallBack(ObjectNameTag(bonusName));
}
void Client::addPlayer(sf::Uint16 id, std::shared_ptr<Player> player) {
@ -175,6 +178,6 @@ void Client::setAddBonusCallBack(std::function<void(const std::string &, const V
_addBonusCallBack = std::move(addBonus);
}
void Client::setRemoveBonusCallBack(std::function<void(const std::string &)> removeBonus) {
void Client::setRemoveBonusCallBack(std::function<void(const ObjectNameTag &)> removeBonus) {
_removeBonusCallBack = std::move(removeBonus);
}

View File

@ -19,7 +19,7 @@ private:
std::function<void(sf::Uint16)> _removePlayerCallBack;
std::function<void(const Vec3D&, const Vec3D&)> _addFireTraceCallBack;
std::function<void(const std::string&, const Vec3D&)> _addBonusCallBack;
std::function<void(const std::string&)> _removeBonusCallBack;
std::function<void(const ObjectNameTag&)> _removeBonusCallBack;
public:
explicit Client(std::shared_ptr<Player> player) : _player(player){};
@ -29,7 +29,7 @@ public:
void setRemovePlayerCallBack(std::function<void(sf::Uint16)> remove);
void setAddFireTraceCallBack(std::function<void(const Vec3D&, const Vec3D&)> addTrace);
void setAddBonusCallBack(std::function<void(const std::string&, const Vec3D&)> addBonus);
void setRemoveBonusCallBack(std::function<void(const std::string&)> removeBonus);
void setRemoveBonusCallBack(std::function<void(const ObjectNameTag&)> removeBonus);
void processInit(sf::Packet& packet) override;
void processUpdate(sf::Packet& packet) override;

View File

@ -19,7 +19,7 @@ Player::Player() {
_fullHealthSound.setBuffer(*ResourceManager::loadSoundBuffer(ShooterConsts::RESTORE_HEALTH_SOUND));
_fullAbilitySound.setBuffer(*ResourceManager::loadSoundBuffer(ShooterConsts::RESTORE_ABILITY_SOUND));
setCollisionCallBack([this](const std::string& objName, std::shared_ptr<RigidBody> obj) {collisionWithObject(objName, obj);});
setCollisionCallBack([this](const ObjectNameTag& tag, std::shared_ptr<RigidBody> obj) {collisionWithObject(tag, obj);});
}
void Player::rotateWeaponsRelativePoint(const Vec3D& point4D, const Vec3D& v, double val) {
@ -37,30 +37,30 @@ void Player::playKill() {
_killSound.play();
}
void Player::collisionWithObject(const std::string &objName, std::shared_ptr<RigidBody> obj) {
if(objName.find("Bonus_gun") != std::string::npos)
void Player::collisionWithObject(const ObjectNameTag& tag, std::shared_ptr<RigidBody> obj) {
if(tag.str().find("Bonus_gun") != std::string::npos)
addWeapon(std::make_shared<Gun>());
if(objName.find("Bonus_shotgun") != std::string::npos)
if(tag.str().find("Bonus_shotgun") != std::string::npos)
addWeapon(std::make_shared<Shotgun>());
if(objName.find("Bonus_ak47") != std::string::npos)
if(tag.str().find("Bonus_ak47") != std::string::npos)
addWeapon(std::make_shared<Ak47>());
if(objName.find("Bonus_gold_ak47") != std::string::npos)
if(tag.str().find("Bonus_gold_ak47") != std::string::npos)
addWeapon(std::make_shared<Gold_Ak47>());
if(objName.find("Bonus_rifle") != std::string::npos)
if(tag.str().find("Bonus_rifle") != std::string::npos)
addWeapon(std::make_shared<Rifle>());
if(objName.find("Bonus_hill") != std::string::npos)
if(tag.str().find("Bonus_hill") != std::string::npos)
setFullHealth();
if(objName.find("Bonus_ability") != std::string::npos)
if(tag.str().find("Bonus_ability") != std::string::npos)
setFullAbility();
if(objName.find("Bonus") != std::string::npos) {
_takeBonusCallBack(objName);
if(tag.str().find("Bonus") != std::string::npos) {
_takeBonusCallBack(tag.str());
}
}
@ -75,7 +75,7 @@ void Player::addWeapon(std::shared_ptr<Weapon> weapon) {
}
_weapons.push_back(weapon);
attach(weapon, weapon->name());
attach(weapon, ObjectNameTag(weapon->name()));
_weapons.back()->translate(position());
_weapons.back()->rotateRelativePoint(position() + Vec3D{0, 1.8, 0}, Vec3D{0, 1, 0}, _angle->y());
@ -88,7 +88,7 @@ void Player::initWeapons() {
if(!_weapons.empty()) {
for(auto weapon : _weapons)
unattach(weapon->name());
unattach(ObjectNameTag(weapon->name()));
_removeWeaponCallBack(_weapons[_selectedWeapon]);
_weapons.clear();
@ -125,11 +125,11 @@ void Player::previousWeapon() {
}
void Player::fire() {
if(attached("camera") != nullptr) {
if(attached(ObjectNameTag("camera")) != nullptr) {
auto damagedPlayers = _weapons[_selectedWeapon]->fire(_rayCastFunction);
for(auto& damagedPlayer : damagedPlayers) {
sf::Uint16 targetId = std::stoi(damagedPlayer.first.substr(6));
_damagePlayerCallBack(targetId, damagedPlayer.second);
for(auto& [damagedPlayerName, damage] : damagedPlayers) {
sf::Uint16 targetId = std::stoi(damagedPlayerName.str().substr(6));
_damagePlayerCallBack(targetId, damage);
}
}
}

View File

@ -44,7 +44,7 @@ private:
std::function<void(std::shared_ptr<Weapon>)> _addWeaponCallBack;
std::function<void(std::shared_ptr<Weapon>)> _removeWeaponCallBack;
std::function<std::pair<Vec3D, std::string>(const Vec3D&, const Vec3D&)> _rayCastFunction;
std::function<std::pair<Vec3D, ObjectNameTag>(const Vec3D&, const Vec3D&)> _rayCastFunction;
public:
Player();
@ -97,7 +97,7 @@ public:
void setRemoveWeaponCallBack(std::function<void(std::shared_ptr<Weapon>)> removeWeapon) {
_removeWeaponCallBack = std::move(removeWeapon);
}
void setRayCastFunction(std::function<std::pair<Vec3D, std::string>(const Vec3D&, const Vec3D&)> rayCastFunction) {
void setRayCastFunction(std::function<std::pair<Vec3D, ObjectNameTag>(const Vec3D&, const Vec3D&)> rayCastFunction) {
_rayCastFunction = std::move(rayCastFunction);
}
@ -105,7 +105,7 @@ public:
void setHeadAngle(double a) { _headAngle = a; }
[[nodiscard]] double headAngle() const { return _headAngle; };
void collisionWithObject(const std::string& objName, std::shared_ptr<RigidBody> obj);
void collisionWithObject(const ObjectNameTag& tag, std::shared_ptr<RigidBody> obj);
};

View File

@ -44,28 +44,28 @@ void PlayerController::update() {
Keyboard::isKeyPressed(sf::Keyboard::W) ||
Keyboard::isKeyPressed(sf::Keyboard::S));
std::shared_ptr<Object> camera = _player->attached("camera");
std::shared_ptr<Object> camera = _player->attached(ObjectNameTag("camera"));
if(camera != nullptr && _inRunning) {
if (!Timeline::isInAnimList("camera_hor_oscil")) {
Timeline::animate("camera_hor_oscil", new ATranslate(camera, -camera->left() / 6, 0.3,Animation::LoopOut::None, Animation::InterpolationType::cos));
Timeline::animate("camera_hor_oscil", new AWait(0));
Timeline::animate("camera_hor_oscil", new ATranslate(camera, camera->left() / 6, 0.3, Animation::LoopOut::None, Animation::InterpolationType::cos));
if (!Timeline::isInAnimList(AnimationListTag("camera_hor_oscil"))) {
Timeline::animate(AnimationListTag("camera_hor_oscil"), new ATranslate(camera, -camera->left() / 6, 0.3,Animation::LoopOut::None, Animation::InterpolationType::cos));
Timeline::animate(AnimationListTag("camera_hor_oscil"), new AWait(0));
Timeline::animate(AnimationListTag("camera_hor_oscil"), new ATranslate(camera, camera->left() / 6, 0.3, Animation::LoopOut::None, Animation::InterpolationType::cos));
Timeline::animate("camera_vert_oscil", new ATranslate(camera, -Vec3D{0, 1, 0} / 12, 0.15, Animation::LoopOut::None, Animation::InterpolationType::cos));
Timeline::animate("camera_vert_oscil", new AWait(0));
Timeline::animate("camera_vert_oscil", new ATranslate(camera, Vec3D{0, 1, 0} / 12, 0.15, Animation::LoopOut::None, Animation::InterpolationType::cos));
Timeline::animate("camera_vert_oscil", new AWait(0));
Timeline::animate("camera_vert_oscil", new ATranslate(camera, -Vec3D{0, 1, 0} / 12, 0.15, Animation::LoopOut::None, Animation::InterpolationType::cos));
Timeline::animate("camera_vert_oscil", new AWait(0));
Timeline::animate("camera_vert_oscil", new ATranslate(camera, Vec3D{0, 1, 0} / 12, 0.15, Animation::LoopOut::None, Animation::InterpolationType::cos));
Timeline::animate(AnimationListTag("camera_vert_oscil"), new ATranslate(camera, -Vec3D{0, 1, 0} / 12, 0.15, Animation::LoopOut::None, Animation::InterpolationType::cos));
Timeline::animate(AnimationListTag("camera_vert_oscil"), new AWait(0));
Timeline::animate(AnimationListTag("camera_vert_oscil"), new ATranslate(camera, Vec3D{0, 1, 0} / 12, 0.15, Animation::LoopOut::None, Animation::InterpolationType::cos));
Timeline::animate(AnimationListTag("camera_vert_oscil"), new AWait(0));
Timeline::animate(AnimationListTag("camera_vert_oscil"), new ATranslate(camera, -Vec3D{0, 1, 0} / 12, 0.15, Animation::LoopOut::None, Animation::InterpolationType::cos));
Timeline::animate(AnimationListTag("camera_vert_oscil"), new AWait(0));
Timeline::animate(AnimationListTag("camera_vert_oscil"), new ATranslate(camera, Vec3D{0, 1, 0} / 12, 0.15, Animation::LoopOut::None, Animation::InterpolationType::cos));
Timeline::animate("camera_init", new ATranslateToPoint( camera, _player->position() + Vec3D{0, 1.8, 0}, 0.3, Animation::LoopOut::None, Animation::InterpolationType::cos));
Timeline::animate(AnimationListTag("camera_init"), new ATranslateToPoint( camera, _player->position() + Vec3D{0, 1.8, 0}, 0.3, Animation::LoopOut::None, Animation::InterpolationType::cos));
}
} else if(camera != nullptr && inRunning_old && !_inRunning) {
Timeline::deleteAnimationList("camera_hor_oscil");
Timeline::deleteAnimationList("camera_vert_oscil");
Timeline::deleteAnimationList("camera_init");
Timeline::animate("camera_init", new ATranslateToPoint( camera, _player->position() + Vec3D{0, 1.8, 0}, 0.15, Animation::LoopOut::None, Animation::InterpolationType::cos));
Timeline::deleteAnimationList(AnimationListTag("camera_hor_oscil"));
Timeline::deleteAnimationList(AnimationListTag("camera_vert_oscil"));
Timeline::deleteAnimationList(AnimationListTag("camera_init"));
Timeline::animate(AnimationListTag("camera_init"), new ATranslateToPoint( camera, _player->position() + Vec3D{0, 1.8, 0}, 0.15, Animation::LoopOut::None, Animation::InterpolationType::cos));
}
// Left and right

View File

@ -10,7 +10,6 @@ void Server::broadcast() {
updatePacket << MsgType::Update;
for (auto& player : _players) {
//player.second->setHealth(player.second->health() + (Time::time() - _lastBroadcast)/100);
updatePacket << player.first << player.second->position().x() << player.second->position().y() << player.second->position().z() << player.second->health() << player.second->angle().y() << player.second->headAngle();
}
@ -36,12 +35,11 @@ void Server::processConnect(sf::Uint16 targetId) {
}
_socket.sendRely(sendPacket1, targetId);
// bonuses init
sendPacket2 << MsgType::InitBonuses;
for(auto& bonus : _bonuses) {
if(bonus.second.onTheMap)
sendPacket2 << bonus.first << bonus.second.position.x() << bonus.second.position.y() << bonus.second.position.z();
for(auto& [bonusName, bonusInfo] : _bonuses) {
if(bonusInfo->onTheMap)
sendPacket2 << bonusName << bonusInfo->position.x() << bonusInfo->position.y() << bonusInfo->position.z();
}
_socket.sendRely(sendPacket2, targetId);
@ -111,14 +109,19 @@ void Server::processCustomPacket(MsgType type, sf::Packet& packet, sf::Uint16 se
_players[senderId]->setFullAbility();
}
_bonuses[tmp].onTheMap = false;
_bonuses[tmp].lastTake = Time::time();
_bonuses[tmp] = std::make_shared<BonusInfo>(BonusInfo{_bonuses[tmp]->position, Time::time(), false});
sendPacket << MsgType::RemoveBonus << tmp;
for (auto& player : _players) {
if(player.first != senderId)
_socket.send(sendPacket, player.first);
}
break;
case MsgType::Error:
break;
default:
throw std::logic_error{"Server::processCustomPacket: unknown MsgType"};
}
}
@ -128,36 +131,36 @@ void Server::processStop() {
}
void Server::generateBonuses() {
_bonuses.insert({"Bonus_gun_1", {Point4D(-10, -2, -15), -2*_bonusRechargeTime, true}});
_bonuses.insert({"Bonus_gun_2", {Point4D(10, -2, 15), -2*_bonusRechargeTime, true}});
_bonuses.insert({"Bonus_gun_1", std::make_shared<BonusInfo>(BonusInfo{Point4D(-10, -2, -15), -2*_bonusRechargeTime, true})});
_bonuses.insert({"Bonus_gun_2", std::make_shared<BonusInfo>(BonusInfo{Point4D(10, -2, 15), -2*_bonusRechargeTime, true})});
_bonuses.insert({"Bonus_shotgun_1", {Point4D(-10, 13, -24), -2*_bonusRechargeTime, true}});
_bonuses.insert({"Bonus_shotgun_2", {Point4D(10, 13, 24), -2*_bonusRechargeTime, true}});
_bonuses.insert({"Bonus_shotgun_1", std::make_shared<BonusInfo>(BonusInfo{Point4D(-10, 13, -24), -2*_bonusRechargeTime, true})});
_bonuses.insert({"Bonus_shotgun_2", std::make_shared<BonusInfo>(BonusInfo{Point4D(10, 13, 24), -2*_bonusRechargeTime, true})});
_bonuses.insert({"Bonus_ak47_1", {Point4D(-25, 30, 50), -2*_bonusRechargeTime, true}});
_bonuses.insert({"Bonus_ak47_2", {Point4D(25, 30, -50), -2*_bonusRechargeTime, true}});
_bonuses.insert({"Bonus_ak47_1", std::make_shared<BonusInfo>(BonusInfo{Point4D(-25, 30, 50), -2*_bonusRechargeTime, true})});
_bonuses.insert({"Bonus_ak47_2", std::make_shared<BonusInfo>(BonusInfo{Point4D(25, 30, -50), -2*_bonusRechargeTime, true})});
_bonuses.insert({"Bonus_gold_ak47_1", {Point4D(-35, 80, 25), -2*_bonusRechargeTime, true}});
_bonuses.insert({"Bonus_gold_ak47_2", {Point4D(35, 80, -25), -2*_bonusRechargeTime, true}});
_bonuses.insert({"Bonus_gold_ak47_1", std::make_shared<BonusInfo>(BonusInfo{Point4D(-35, 80, 25), -2*_bonusRechargeTime, true})});
_bonuses.insert({"Bonus_gold_ak47_2", std::make_shared<BonusInfo>(BonusInfo{Point4D(35, 80, -25), -2*_bonusRechargeTime, true})});
_bonuses.insert({"Bonus_rifle_1", {Point4D(40, -2, 45), -2*_bonusRechargeTime, true}});
_bonuses.insert({"Bonus_rifle_2", {Point4D(-40, -2, -45), -2*_bonusRechargeTime, true}});
_bonuses.insert({"Bonus_rifle_1", std::make_shared<BonusInfo>(BonusInfo{Point4D(40, -2, 45), -2*_bonusRechargeTime, true})});
_bonuses.insert({"Bonus_rifle_2", std::make_shared<BonusInfo>(BonusInfo{Point4D(-40, -2, -45), -2*_bonusRechargeTime, true})});
_bonuses.insert({"Bonus_hill_1", {Point4D(-40, -2, 45), -2*_bonusRechargeTime, true}});
_bonuses.insert({"Bonus_hill_2", {Point4D(40, -2, -45), -2*_bonusRechargeTime, true}});
_bonuses.insert({"Bonus_hill_1", std::make_shared<BonusInfo>(BonusInfo{Point4D(-40, -2, 45), -2*_bonusRechargeTime, true})});
_bonuses.insert({"Bonus_hill_2", std::make_shared<BonusInfo>(BonusInfo{Point4D(40, -2, -45), -2*_bonusRechargeTime, true})});
_bonuses.insert({"Bonus_ability_1", {Point4D(25, 18, -33), -2*_bonusRechargeTime, true}});
_bonuses.insert({"Bonus_ability_2", {Point4D(-25, 18, 33), -2*_bonusRechargeTime, true}});
_bonuses.insert({"Bonus_ability_1", std::make_shared<BonusInfo>(BonusInfo{Point4D(25, 18, -33), -2*_bonusRechargeTime, true})});
_bonuses.insert({"Bonus_ability_2", std::make_shared<BonusInfo>(BonusInfo{Point4D(-25, 18, 33), -2*_bonusRechargeTime, true})});
}
void Server::updateInfo() {
for(auto& bonus : _bonuses) {
if(!bonus.second.onTheMap && std::abs(Time::time() - bonus.second.lastTake) > _bonusRechargeTime) {
for(auto& [bonusName, bonusInfo] : _bonuses) {
if(!bonusInfo->onTheMap && std::abs(Time::time() - bonusInfo->lastTake) > _bonusRechargeTime) {
sf::Packet sendPacket;
sendPacket << MsgType::AddBonus << bonus.first << bonus.second.position.x() << bonus.second.position.y() << bonus.second.position.z();
sendPacket << MsgType::AddBonus << bonusName << bonusInfo->position.x() << bonusInfo->position.y() << bonusInfo->position.z();
for (const auto& player : _players)
_socket.sendRely(sendPacket, player.first);
bonus.second.onTheMap = true;
bonusInfo = std::make_shared<BonusInfo>(BonusInfo{bonusInfo->position, bonusInfo->lastTake, true});
}
}
}

View File

@ -9,16 +9,16 @@
#include "Player.h"
#include "Bonus.h"
struct BonusInfo {
Point4D position{};
double lastTake = std::numeric_limits<double>::min();
bool onTheMap = false;
struct BonusInfo final {
const Point4D position{};
const double lastTake = std::numeric_limits<double>::min();
const bool onTheMap = false;
};
class Server final : public ServerUDP {
private:
std::map<sf::Uint16, std::shared_ptr<Player>> _players{};
std::map<std::string, BonusInfo> _bonuses{};
std::map<std::string, std::shared_ptr<BonusInfo>> _bonuses{};
double _bonusRechargeTime = 60;
public:

View File

@ -59,7 +59,7 @@ void Shooter::InitNetwork()
client->setRemovePlayerCallBack([this](sf::Uint16 id){ removePlayer(id); });
client->setAddFireTraceCallBack([this](const Vec3D& from, const Vec3D& to){ addFireTrace(from, to); });
client->setAddBonusCallBack([this](const std::string& bonusName, const Vec3D& position){ addBonus(bonusName, position); });
client->setRemoveBonusCallBack([this](const std::string& bonusName){ removeBonus(bonusName); });
client->setRemoveBonusCallBack([this](const ObjectNameTag& bonusName){ removeBonus(bonusName); });
}
void Shooter::start() {
@ -84,9 +84,9 @@ void Shooter::start() {
player->initWeapons();
camera->translateToPoint(player->position() + Vec3D{0, 1.8, 0});
player->attach(camera, "camera");
player->attach(camera, ObjectNameTag("camera"));
world->addBody(player, "Player");
world->addBody(player, ObjectNameTag("Player"));
player->translate(Vec3D{0, 10, 0});
client = std::make_shared<Client>(player);
@ -204,58 +204,58 @@ void Shooter::spawnPlayer(sf::Uint16 id) {
newPlayer->setCollision(false);
client->addPlayer(id, newPlayer);
world->addBody(newPlayer, name);
world->addBody(newPlayer, ObjectNameTag(name));
newPlayer->setVisible(true);
newPlayer->setAcceleration(Vec3D{0, 0, 0});
// add head and other stuff:
world->loadBody(name + "_head", ShooterConsts::CUBE_OBJ, "", Vec3D{0.7, 0.7, 0.7});
world->body(name + "_head")->translate(Vec3D{0, 2, 0});
world->body(name + "_head")->setCollider(false);
newPlayer->attach(world->body(name + "_head"), "head");
world->loadBody(ObjectNameTag(name + "_head"), ShooterConsts::CUBE_OBJ, "", Vec3D{0.7, 0.7, 0.7});
world->body(ObjectNameTag(name + "_head"))->translate(Vec3D{0, 2, 0});
world->body(ObjectNameTag(name + "_head"))->setCollider(false);
newPlayer->attach(world->body(ObjectNameTag(name + "_head")), ObjectNameTag("head"));
world->loadBody(name + "_eye1", ShooterConsts::CUBE_OBJ, "", Vec3D{0.2, 0.2, 0.05});
world->body(name + "_eye1")->translate(Vec3D{0.3, 2.1, 0.7});
world->body(name + "_eye1")->setCollider(false);
world->body(name + "_eye1")->setColor({147, 159, 255});
world->body(name + "_head")->attach(world->body(name + "_eye1"), "eye1");
world->loadBody(ObjectNameTag(name + "_eye1"), ShooterConsts::CUBE_OBJ, "", Vec3D{0.2, 0.2, 0.05});
world->body(ObjectNameTag(name + "_eye1"))->translate(Vec3D{0.3, 2.1, 0.7});
world->body(ObjectNameTag(name + "_eye1"))->setCollider(false);
world->body(ObjectNameTag(name + "_eye1"))->setColor({147, 159, 255});
world->body(ObjectNameTag(name + "_head"))->attach(world->body(ObjectNameTag(name + "_eye1")), ObjectNameTag("eye1"));
world->loadBody(name + "_eye2", ShooterConsts::CUBE_OBJ, "", Vec3D{0.2, 0.2, 0.05});
world->body(name + "_eye2")->translate(Vec3D{-0.3, 2.1, 0.7});
world->body(name + "_eye2")->setCollider(false);
world->body(name + "_eye2")->setColor({147, 159, 255});
world->body(name + "_head")->attach(world->body(name + "_eye2"), "eye2");
world->loadBody(ObjectNameTag(name + "_eye2"), ShooterConsts::CUBE_OBJ, "", Vec3D{0.2, 0.2, 0.05});
world->body(ObjectNameTag(name + "_eye2"))->translate(Vec3D{-0.3, 2.1, 0.7});
world->body(ObjectNameTag(name + "_eye2"))->setCollider(false);
world->body(ObjectNameTag(name + "_eye2"))->setColor({147, 159, 255});
world->body(ObjectNameTag(name + "_head"))->attach(world->body(ObjectNameTag(name + "_eye2")), ObjectNameTag("eye2"));
}
void Shooter::removePlayer(sf::Uint16 id) {
std::string name = std::to_string(id) + "_Enemy";
world->removeBody(name);
world->removeBody(name + "_head");
world->removeBody(name + "_eye1");
world->removeBody(name + "_eye2");
world->removeBody(ObjectNameTag(name));
world->removeBody(ObjectNameTag(name + "_head"));
world->removeBody(ObjectNameTag(name + "_eye1"));
world->removeBody(ObjectNameTag(name + "_eye2"));
}
void Shooter::addFireTrace(const Vec3D &from, const Vec3D &to) {
std::string traceName = "Client_fireTraces_" + std::to_string(fireTraces++);
world->addBody(std::make_shared<RigidBody>(Mesh::LineTo(from, to, 0.05)), traceName);
world->body(traceName)->setCollider(false);
world->addBody(std::make_shared<RigidBody>(Mesh::LineTo(from, to, 0.05)), ObjectNameTag(traceName));
world->body(ObjectNameTag(traceName))->setCollider(false);
Timeline::animate(traceName + "_fadeOut", new AColor(world->body(traceName), {255, 255, 255, 0}));
Timeline::animate(traceName + "_delete", new AFunction([this, traceName](){ deleteFireTrace(traceName); }, 1, 2));
Timeline::animate(AnimationListTag(traceName + "_fadeOut"), new AColor(world->body(ObjectNameTag(traceName)), {255, 255, 255, 0}));
Timeline::animate(AnimationListTag(traceName + "_delete"), new AFunction([this, traceName](){ removeFireTrace(ObjectNameTag(traceName)); }, 1, 2));
}
void Shooter::deleteFireTrace(const std::string& traceName) {
void Shooter::removeFireTrace(const ObjectNameTag& traceName) {
world->removeBody(traceName);
}
void Shooter::addBonus(const string &bonusName, const Vec3D &position) {
std::string name = bonusName.substr(6, bonusName.size()-3-5);
world->addBody(std::make_shared<Bonus>(bonusName, "obj/" + name + ".obj", "obj/" + name + "_mat.txt", Vec3D{3, 3, 3}), bonusName);
world->body(bonusName)->translateToPoint(position);
Timeline::animate(bonusName + "_rotation", new ARotate(world->body(bonusName), Vec3D{0, 2*Consts::PI, 0}, 4, Animation::LoopOut::Continue, Animation::InterpolationType::linear));
world->addBody(std::make_shared<Bonus>(bonusName, "obj/" + name + ".obj", "obj/" + name + "_mat.txt", Vec3D{3, 3, 3}), ObjectNameTag(bonusName));
world->body(ObjectNameTag(bonusName))->translateToPoint(position);
Timeline::animate(AnimationListTag(bonusName + "_rotation"), new ARotate(world->body(ObjectNameTag(bonusName)), Vec3D{0, 2*Consts::PI, 0}, 4, Animation::LoopOut::Continue, Animation::InterpolationType::linear));
}
void Shooter::removeBonus(const string &bonusName) {
void Shooter::removeBonus(const ObjectNameTag &bonusName) {
world->removeBody(bonusName);
}
@ -264,5 +264,5 @@ void Shooter::addWeapon(std::shared_ptr<Weapon> weapon) {
}
void Shooter::removeWeapon(std::shared_ptr<Weapon> weapon) {
world->removeBody(weapon->name());
world->removeBody(ObjectNameTag(weapon->name()));
}

View File

@ -44,9 +44,9 @@ private:
void spawnPlayer(sf::Uint16 id);
void removePlayer(sf::Uint16 id);
void addFireTrace(const Vec3D& from, const Vec3D& to);
void deleteFireTrace(const std::string& traceName);
void removeFireTrace(const ObjectNameTag& traceName);
void addBonus(const std::string& bonusName, const Vec3D& position);
void removeBonus(const std::string& bonusName);
void removeBonus(const ObjectNameTag& bonusName);
void addWeapon(std::shared_ptr<Weapon> weapon);
void removeWeapon(std::shared_ptr<Weapon> weapon);
public:

View File

@ -29,6 +29,7 @@ namespace Consts {
const int NETWORK_TIMEOUT = 1U;
const int NETWORK_WORLD_UPDATE_RATE = 30;
const double NETWORK_RELIABLE_RETRY_TIME = 1.0/20;
const uint16_t NETWORK_MAX_CLIENTS = 64;
}
#endif //SHOOTER_CONSTS_H

View File

@ -9,13 +9,13 @@
void Object::translate(const Vec3D &dv) {
_position = std::make_unique<Vec3D>(*_position + dv);
for(auto attached : _attachedObjects)
attached.second->translate(dv);
for(auto &[attachedName, attachedObject] : _attachedObjects)
attachedObject->translate(dv);
}
void Object::scale(const Vec3D &s) {
for(auto attached : _attachedObjects)
attached.second->scale(s);
for(auto &[attachedName, attachedObject] : _attachedObjects)
attachedObject->scale(s);
}
void Object::rotate(const Vec3D &r) {
@ -27,8 +27,8 @@ void Object::rotate(const Vec3D &r) {
_up = std::make_unique<Vec3D>(rotationMatrix * *_up);
_lookAt = std::make_unique<Vec3D>(rotationMatrix * *_lookAt);
for(auto attached : _attachedObjects)
attached.second->rotateRelativePoint(position(), r);
for(auto &[attachedName, attachedObject] : _attachedObjects)
attachedObject->rotateRelativePoint(position(), r);
}
void Object::rotate(const Vec3D &v, double rv) {
@ -38,8 +38,8 @@ void Object::rotate(const Vec3D &v, double rv) {
_up = std::make_unique<Vec3D>(rotationMatrix * *_up);
_lookAt = std::make_unique<Vec3D>(rotationMatrix * *_lookAt);
for(auto attached : _attachedObjects)
attached.second->rotateRelativePoint(position(), v, rv);
for(auto &[attachedName, attachedObject] : _attachedObjects)
attachedObject->rotateRelativePoint(position(), v, rv);
}
void Object::rotateRelativePoint(const Vec3D &s, const Vec3D &r) {
@ -59,8 +59,8 @@ void Object::rotateRelativePoint(const Vec3D &s, const Vec3D &r) {
// After rotation we translate XYZ by vector -r2 and recalculate position
_position = std::make_unique<Vec3D>(s + r2);
for(auto attached : _attachedObjects)
attached.second->rotateRelativePoint(s, r);
for(auto &[attachedName, attachedObject] : _attachedObjects)
attachedObject->rotateRelativePoint(s, r);
}
void Object::rotateRelativePoint(const Vec3D &s, const Vec3D &v, double r) {
@ -77,8 +77,8 @@ void Object::rotateRelativePoint(const Vec3D &s, const Vec3D &v, double r) {
// After rotation we translate XYZ by vector -r2 and recalculate position
_position = std::make_unique<Vec3D>(s + r2);
for(auto attached : _attachedObjects)
attached.second->rotateRelativePoint(s, v, r);
for(auto &[attachedName, attachedObject] : _attachedObjects)
attachedObject->rotateRelativePoint(s, v, r);
}
void Object::rotateLeft(double rl) {
@ -88,8 +88,8 @@ void Object::rotateLeft(double rl) {
rotate(*_left, rl);
for(auto attached : _attachedObjects)
attached.second->rotateRelativePoint(position(), *_left, rl);
for(auto &[attachedName, attachedObject] : _attachedObjects)
attachedObject->rotateRelativePoint(position(), *_left, rl);
}
void Object::rotateUp(double ru) {
@ -98,8 +98,8 @@ void Object::rotateUp(double ru) {
_angleLeftUpLookAt->z()});
rotate(*_up, ru);
for(auto attached : _attachedObjects)
attached.second->rotateRelativePoint(position(), *_up, ru);
for(auto &[attachedName, attachedObject] : _attachedObjects)
attachedObject->rotateRelativePoint(position(), *_up, ru);
}
void Object::rotateLookAt(double rlAt) {
@ -108,8 +108,8 @@ void Object::rotateLookAt(double rlAt) {
_angleLeftUpLookAt->z() + rlAt});
rotate(*_lookAt, rlAt);
for(auto attached : _attachedObjects)
attached.second->rotateRelativePoint(position(), *_lookAt, rlAt);
for(auto &[attachedName, attachedObject] : _attachedObjects)
attachedObject->rotateRelativePoint(position(), *_lookAt, rlAt);
}
void Object::translateToPoint(const Vec3D &point) {
@ -120,22 +120,22 @@ void Object::rotateToAngle(const Vec3D &v) {
rotate(v - *_angle);
}
std::shared_ptr<Object> Object::attached(const std::string &name) {
if(_attachedObjects.count(name) == 0)
std::shared_ptr<Object> Object::attached(const ObjectNameTag& tag) {
if(_attachedObjects.count(tag) == 0)
return nullptr;
return _attachedObjects.find(name)->second;
return _attachedObjects.find(tag)->second;
}
void Object::attach(std::shared_ptr<Object> object, const std::string &name) {
void Object::attach(std::shared_ptr<Object> object, const ObjectNameTag& tag) {
// TODO: solve problem with possible infinite recursive call chains
if(this != object.get())
_attachedObjects.emplace(name, object);
_attachedObjects.emplace(tag, object);
else
throw std::invalid_argument{"Object::attach: You cannot attach object to itself"};
}
void Object::unattach(const std::string &name) {
_attachedObjects.erase(name);
void Object::unattach(const ObjectNameTag& tag) {
_attachedObjects.erase(tag);
}
Object::~Object() {

View File

@ -7,8 +7,20 @@
#include <map>
#include "Vec3D.h"
#include <memory>
#include <string>
#include <utility>
class ObjectNameTag {
private:
const std::string _name;
public:
explicit ObjectNameTag(std::string name = "") : _name(std::move(name)) {}
[[nodiscard]] std::string str() const { return _name; }
bool operator==(const ObjectNameTag& tag) const { return _name == tag._name; }
bool operator!=(const ObjectNameTag& tag) const { return _name != tag._name; }
bool operator<(const ObjectNameTag& tag) const { return _name < tag._name; }
};
class Object {
protected:
@ -16,7 +28,7 @@ protected:
std::unique_ptr<Vec3D> _up = std::make_unique<Vec3D>(Vec3D{0, 1, 0}); // internal Y
std::unique_ptr<Vec3D> _lookAt = std::make_unique<Vec3D>(Vec3D{0, 0, 1}); // internal Z
std::map<std::string, std::shared_ptr<Object>> _attachedObjects;
std::map<ObjectNameTag, std::shared_ptr<Object>> _attachedObjects;
std::unique_ptr<Vec3D> _position = std::make_unique<Vec3D>(Vec3D{0, 0, 0});
std::unique_ptr<Vec3D> _angle = std::make_unique<Vec3D>(Vec3D{0, 0, 0});
@ -45,9 +57,9 @@ public:
void rotateUp(double ru);
void rotateLookAt(double rlAt);
void attach(std::shared_ptr<Object> object, const std::string& name);
void unattach(const std::string& name);
std::shared_ptr<Object> attached(const std::string& name);
void attach(std::shared_ptr<Object> object, const ObjectNameTag& tag);
void unattach(const ObjectNameTag& tag);
std::shared_ptr<Object> attached(const ObjectNameTag& tag);
virtual ~Object();
};

View File

@ -8,29 +8,29 @@
using namespace std;
void World::addBody(std::shared_ptr<RigidBody> body, const string &name) {
_objects.emplace(name, body);
Log::log("World::addBody(): inserted body '" + name + "' with " + std::to_string(_objects[name]->triangles().size()) + " tris.");
void World::addBody(std::shared_ptr<RigidBody> body, const ObjectNameTag& tag) {
_objects.emplace(tag, body);
Log::log("World::addBody(): inserted body '" + tag.str() + "' with " + std::to_string(_objects[tag]->triangles().size()) + " tris.");
}
void World::loadBody(const string &name, const string &filename, const std::string &materials, const Vec3D& scale) {
_objects.emplace(name, std::make_shared<RigidBody>(Mesh(filename, materials, scale)));
Log::log("World::loadBody(): inserted body from " + filename + " with title '" + name + "' with " + std::to_string(_objects[name]->triangles().size()) + " tris.");
void World::loadBody(const ObjectNameTag& tag, const string &filename, const std::string &materials, const Vec3D& scale) {
_objects.emplace(tag, std::make_shared<RigidBody>(Mesh(filename, materials, scale)));
Log::log("World::loadBody(): inserted body from " + filename + " with title '" + tag.str() + "' with " + std::to_string(_objects[tag]->triangles().size()) + " tris.");
}
std::pair<Vec3D, string> World::rayCast(const Vec3D& from, const Vec3D& to, const std::string& tag) {
std::pair<Vec3D, ObjectNameTag> World::rayCast(const Vec3D& from, const Vec3D& to, const std::string& tag) {
std::pair<Vec3D, string> result;
std::unique_ptr<Vec3D> point = std::make_unique<Vec3D>();
std::string name;
std::string bodyName;
double minDistance = Consts::RAY_CAST_MAX_DISTANCE;
for(auto& object : _objects) {
if(!tag.empty() && object.first.find(tag) == std::string::npos)
for(auto& [name, body] : _objects) {
if(!tag.empty() && name.str().find(tag) == std::string::npos)
continue;
for(auto& tri : object.second->triangles()) {
Triangle tri_translated(tri[0] + object.second->position().makePoint4D(), tri[1] + object.second->position().makePoint4D(), tri[2] + object.second->position().makePoint4D());
for(auto& tri : body->triangles()) {
Triangle tri_translated(tri[0] + body->position().makePoint4D(), tri[1] + body->position().makePoint4D(), tri[2] + body->position().makePoint4D());
Plane plane(tri_translated);
auto intersection = plane.intersection(from, to);
@ -38,48 +38,48 @@ std::pair<Vec3D, string> World::rayCast(const Vec3D& from, const Vec3D& to, cons
if(intersection.second > 0 && distance < minDistance && tri_translated.isPointInside(intersection.first)) {
minDistance = distance;
point = std::make_unique<Vec3D>(intersection.first);
name = object.first;
bodyName = name.str();
}
}
}
return {*point, name};
return {*point, ObjectNameTag(bodyName)};
}
void World::loadMap(const std::string& filename, const std::string& materials, const std::string& name, const Vec3D& scale) {
auto objs = Mesh::LoadObjects(filename, materials, scale);
for(unsigned i = 0; i < objs.size(); i++) {
string meshName = name + "_" + to_string(i);
ObjectNameTag meshName = ObjectNameTag(name + "_" + to_string(i));
addBody(std::make_shared<RigidBody>(*objs[i]), meshName);
}
}
void World::removeBody(string name) {
if(_objects.erase(name) > 0)
Log::log("World::removeBody(): removed body '" + name + "'");
void World::removeBody(const ObjectNameTag& tag) {
if(_objects.erase(tag) > 0)
Log::log("World::removeBody(): removed body '" + tag.str() + "'");
else
Log::log("World::removeBody(): cannot remove body '" + name + "': body does not exist.");
Log::log("World::removeBody(): cannot remove body '" + tag.str() + "': body does not exist.");
}
void World::checkCollision(const std::string& body) {
if (_objects[body]->isCollision()) {
void World::checkCollision(const ObjectNameTag& tag) {
if (_objects[tag]->isCollision()) {
_objects[body]->setInCollision(false);
_objects[tag]->setInCollision(false);
for (auto it = _objects.begin(); it != _objects.end();) {
auto obj = it->second;
std::string name = it->first;
ObjectNameTag name = it->first;
it++;
if(name != body) {
std::pair<bool, Simplex> gjk = _objects[body]->checkGJKCollision(obj);
if(name != tag) {
std::pair<bool, Simplex> gjk = _objects[tag]->checkGJKCollision(obj);
if (gjk.first) {
if (obj->isCollider()) {
CollisionPoint epa = _objects[body]->EPA(gjk.second, obj);
_objects[body]->solveCollision(epa);
CollisionPoint epa = _objects[tag]->EPA(gjk.second, obj);
_objects[tag]->solveCollision(epa);
}
if (_objects[body]->collisionCallBack() != nullptr)
_objects[body]->collisionCallBack()(name, obj);
if (_objects[tag]->collisionCallBack() != nullptr)
_objects[tag]->collisionCallBack()(name, obj);
}
}
}
@ -94,12 +94,12 @@ void World::update() {
}
void World::projectObjectsInCamera(std::shared_ptr<Camera> camera) {
for (auto &m : _objects)
camera->project(m.second);
for (auto &[name, body] : _objects)
camera->project(body);
}
std::shared_ptr<RigidBody> World::body(const string &name) {
if(_objects.count(name) == 0)
std::shared_ptr<RigidBody> World::body(const ObjectNameTag& tag) {
if(_objects.count(tag) == 0)
return nullptr;
return _objects.find(name)->second;
return _objects.find(tag)->second;
}

View File

@ -11,23 +11,23 @@
class World final {
private:
std::map<std::string, std::shared_ptr<RigidBody>> _objects;
std::map<ObjectNameTag, std::shared_ptr<RigidBody>> _objects;
public:
World() = default;
void checkCollision(const std::string& body);
void checkCollision(const ObjectNameTag& tag);
void update();
void projectObjectsInCamera(std::shared_ptr<Camera> camera);
void addBody(std::shared_ptr<RigidBody> mesh, const std::string& name = "");
std::shared_ptr<RigidBody> body(const std::string& name);
void removeBody(std::string name);
void loadBody(const std::string &name, const std::string &filename, const std::string &materials = "", const Vec3D& scale = Vec3D{1, 1, 1});
void addBody(std::shared_ptr<RigidBody> mesh, const ObjectNameTag& tag);
std::shared_ptr<RigidBody> body(const ObjectNameTag& tag);
void removeBody(const ObjectNameTag& tag);
void loadBody(const ObjectNameTag& tag, const std::string &filename, const std::string &materials = "", const Vec3D& scale = Vec3D{1, 1, 1});
// rayCast returns pair of Point4D and std::string:
// 1) Point4D is point of collision
// 2) std::string - title of the object
std::pair<Vec3D, std::string> rayCast(const Vec3D& from, const Vec3D& to, const std::string& tag = "");
std::pair<Vec3D, ObjectNameTag> rayCast(const Vec3D& from, const Vec3D& to, const std::string& tag = "");
void loadMap(const std::string& filename, const std::string& materials, const std::string& name = "map", const Vec3D & scale = Vec3D{1, 1, 1});
};

View File

@ -4,13 +4,14 @@
#include <list>
#include "Animation.h"
#include "Timeline.h"
namespace Timeline {
namespace {
std::map<std::string, std::list<Animation*>> _animations;
std::map<AnimationListTag, std::list<Animation*>> _animations;
}
void animate(const std::string& listName, Animation* anim) {
void animate(const AnimationListTag& listName, Animation* anim) {
_animations[listName].emplace_back(anim);
}
@ -18,13 +19,13 @@ namespace Timeline {
_animations.clear();
}
void deleteAnimationList(const std::string& listName) {
void deleteAnimationList(const AnimationListTag& listName) {
_animations[listName].clear();
_animations.erase(listName);
}
[[nodiscard]] bool isInAnimList(const std::string& name) {
return !_animations[name].empty();
[[nodiscard]] bool isInAnimList(const AnimationListTag& listName) {
return !_animations[listName].empty();
}
void update() {

View File

@ -7,14 +7,26 @@
#include "Animation.h"
class AnimationListTag {
private:
const std::string _name;
public:
explicit AnimationListTag(std::string name = "") : _name(std::move(name)) {}
[[nodiscard]] std::string str() const { return _name; }
bool operator==(const AnimationListTag& tag) const { return _name == tag._name; }
bool operator!=(const AnimationListTag& tag) const { return _name != tag._name; }
bool operator<(const AnimationListTag& tag) const { return _name < tag._name; }
};
namespace Timeline {
void update();
void animate(const std::string& listName, Animation* anim);
void animate(const AnimationListTag& listName, Animation* anim);
void deleteAllAnimations();
void deleteAnimationList(const std::string& listName);
void deleteAnimationList(const AnimationListTag& listName);
[[nodiscard]] bool isInAnimList(const std::string& name);
[[nodiscard]] bool isInAnimList(const AnimationListTag& listName);
}
#endif //SHOOTER_TIMELINE_H

View File

@ -82,9 +82,10 @@ bool ClientUDP::process()
sf::Packet packet;
sf::Uint16 senderId;
sf::Uint16 targetId;
MsgType type;
if ((type = _socket.receive(packet, senderId)) == MsgType::Empty)
MsgType type = _socket.receive(packet, senderId);
if (type == MsgType::Empty)
return false;
if (!connected() && type != MsgType::Init)
return true;
@ -119,6 +120,10 @@ bool ClientUDP::process()
processDisconnect(targetId);
break;
case MsgType::Confirm:
break;
default:
processCustomPacket(type, packet);
}

View File

@ -89,13 +89,13 @@ bool ServerUDP::process()
sf::Packet packet;
sf::Packet sendPacket;
sf::Uint16 senderId;
MsgType type;
if ((type = _socket.receive(packet, senderId)) == MsgType::Empty)
MsgType type = _socket.receive(packet, senderId);
if (type == MsgType::Empty)
return false;
switch (type)
{
switch (type) {
// here we process any operations based on msg type
case MsgType::Connect:
@ -117,6 +117,9 @@ bool ServerUDP::process()
_socket.sendRely(sendPacket, client);
processDisconnect(senderId);
break;
case MsgType::Confirm:
break;
default:
processCustomPacket(type, packet, senderId);

View File

@ -163,7 +163,7 @@ MsgType UDPSocket::receive(sf::Packet& packet, sf::Uint16& senderId)
if (!(packet >> version) || version != Consts::NETWORK_VERSION)
return MsgType::Error;
sf::Uint16 tmp;
for (tmp = 64; tmp >= 1; tmp--)
for (tmp = Consts::NETWORK_MAX_CLIENTS; tmp >= 1; tmp--)
{
if (!_connections.count(tmp))
senderId = tmp;

View File

@ -33,7 +33,7 @@ private:
Vec3D _findFurthestPoint(const Vec3D& direction);
Vec3D _support(std::shared_ptr<RigidBody> obj, const Vec3D& direction);
std::function<void(const std::string&, std::shared_ptr<RigidBody>)> _collisionCallBack;
std::function<void(const ObjectNameTag&, std::shared_ptr<RigidBody>)> _collisionCallBack;
static NextSimplex _nextSimplex(const Simplex& points);
static NextSimplex _lineCase(const Simplex& points);
@ -80,8 +80,8 @@ public:
[[nodiscard]] Vec3D velocity() const { return *_velocity; }
[[nodiscard]] Vec3D acceleration() const { return *_acceleration; }
[[nodiscard]] const std::function<void(const std::string&, std::shared_ptr<RigidBody>)>& collisionCallBack() const { return _collisionCallBack; }
void setCollisionCallBack(const std::function<void(const std::string&, std::shared_ptr<RigidBody>)>& f) { _collisionCallBack = f; }
[[nodiscard]] const std::function<void(const ObjectNameTag&, std::shared_ptr<RigidBody>)>& collisionCallBack() const { return _collisionCallBack; }
void setCollisionCallBack(const std::function<void(const ObjectNameTag& tag, std::shared_ptr<RigidBody>)>& f) { _collisionCallBack = f; }
~RigidBody() override = default;
};

View File

@ -24,12 +24,12 @@ Shotgun::Shotgun(int ammo, const std::string& weaponName) : Weapon(weaponName, S
_spreading = 5;
}
std::map<std::string, double>
Shotgun::processFire(std::function<std::pair<Vec3D, std::string>(const Vec3D&, const Vec3D&)> rayCastFunction) {
std::map<std::string, double> damagedPlayers;
std::map<ObjectNameTag, double>
Shotgun::processFire(std::function<std::pair<Vec3D, ObjectNameTag>(const Vec3D&, const Vec3D&)> rayCastFunction) {
std::map<ObjectNameTag, double> damagedPlayers;
for(int i = 0; i < 15; i++) {
std::map<std::string, double> damaged = addTrace(rayCastFunction, position() + Vec3D(triangles().back()[0]), -lookAt());
std::map<ObjectNameTag, double> damaged = addTrace(rayCastFunction, position() + Vec3D(triangles().back()[0]), -lookAt());
for(auto& player : damaged)
damagedPlayers[player.first] += player.second;
}

View File

@ -10,7 +10,7 @@
class Shotgun final : public Weapon {
public:
explicit Shotgun(int ammo = 15, const std::string& weaponName = "shotgun");
std::map<std::string, double> processFire(std::function<std::pair<Vec3D, std::string>(const Vec3D&, const Vec3D&)> rayCastFunction) override;
std::map<ObjectNameTag, double> processFire(std::function<std::pair<Vec3D, ObjectNameTag>(const Vec3D&, const Vec3D&)> rayCastFunction) override;
};

View File

@ -23,7 +23,7 @@ Weapon::Weapon(const std::string& weaponName, const std::string& objFileName, co
noAmmoSound.setBuffer(*ResourceManager::loadSoundBuffer(ShooterConsts::NO_AMMO_SOUND));
}
std::map<std::string, double> Weapon::fire(std::function<std::pair<Vec3D, std::string>(const Vec3D&, const Vec3D&)> rayCastFunction) {
std::map<ObjectNameTag, double> Weapon::fire(std::function<std::pair<Vec3D, ObjectNameTag>(const Vec3D&, const Vec3D&)> rayCastFunction) {
if(_clipAmmo == 0) {
reload();
if(_clipAmmo == 0)
@ -31,7 +31,7 @@ std::map<std::string, double> Weapon::fire(std::function<std::pair<Vec3D, std::s
}
if(_clipAmmo <= 0 || std::abs(Time::time() - _lastFireTime) < _fireDelay || std::abs(Time::time() - _lastReloadTime) < _reloadTime)
return std::map<std::string, double>();
return std::map<ObjectNameTag, double>();
_lastFireTime = Time::time();
_clipAmmo--;
@ -58,12 +58,12 @@ void Weapon::reload() {
_lastReloadTime = Time::time();
}
std::map<std::string, double> Weapon::processFire(std::function<std::pair<Vec3D, std::string>(const Vec3D&, const Vec3D&)> rayCastFunction) {
std::map<ObjectNameTag, double> Weapon::processFire(std::function<std::pair<Vec3D, ObjectNameTag>(const Vec3D&, const Vec3D&)> rayCastFunction) {
return addTrace(std::move(rayCastFunction), position() + Vec3D(triangles().back()[0]), -lookAt());
}
std::map<std::string, double> Weapon::addTrace(std::function<std::pair<Vec3D, std::string>(const Vec3D&, const Vec3D&)> rayCastFunction, const Vec3D& from, const Vec3D& directionTo) {
std::map<std::string, double> damagedPlayers;
std::map<ObjectNameTag, double> Weapon::addTrace(std::function<std::pair<Vec3D, ObjectNameTag>(const Vec3D&, const Vec3D&)> rayCastFunction, const Vec3D& from, const Vec3D& directionTo) {
std::map<ObjectNameTag, double> damagedPlayers;
double spreading = _spreading*ShooterConsts::FIRE_DISTANCE/100;
@ -72,7 +72,7 @@ std::map<std::string, double> Weapon::addTrace(std::function<std::pair<Vec3D, st
// damage player
auto rayCast = rayCastFunction(from, from + directionTo * ShooterConsts::FIRE_DISTANCE + randV);
if(rayCast.second.find("Enemy") != std::string::npos) {
if(rayCast.second.str().find("Enemy") != std::string::npos) {
damagedPlayers[rayCast.second] += _damage/(1.0 + (from - rayCast.first).abs());
}

View File

@ -42,14 +42,14 @@ protected:
std::function<void(const Vec3D&, const Vec3D&)> _addTraceCallBack;
std::map<std::string, double> addTrace(std::function<std::pair<Vec3D, std::string>(const Vec3D&, const Vec3D&)> rayCastFunction, const Vec3D& position, const Vec3D& direction);
std::map<ObjectNameTag, double> addTrace(std::function<std::pair<Vec3D, ObjectNameTag>(const Vec3D&, const Vec3D&)> rayCastFunction, const Vec3D& position, const Vec3D& direction);
virtual std::map<std::string, double> processFire(std::function<std::pair<Vec3D, std::string>(const Vec3D&, const Vec3D&)> rayCastFunction);
virtual std::map<ObjectNameTag, double> processFire(std::function<std::pair<Vec3D, ObjectNameTag>(const Vec3D&, const Vec3D&)> rayCastFunction);
public:
Weapon(const std::string& weaponName, const std::string& objFileName, const std::string& matFileName, const Vec3D& scale, const Vec3D& translate, const Vec3D& rotate);
std::map<std::string, double> fire(std::function<std::pair<Vec3D, std::string>(const Vec3D&, const Vec3D&)> rayCastFunction);
std::map<ObjectNameTag, double> fire(std::function<std::pair<Vec3D, ObjectNameTag>(const Vec3D&, const Vec3D&)> rayCastFunction);
void reload();
[[nodiscard]] std::pair<double, double> balance() const{ return std::make_pair(_clipAmmo, _stockAmmo); }
@ -58,7 +58,7 @@ public:
_addTraceCallBack = std::move(add);
}
[[nodiscard]] std::string name() const { return _name; }
[[nodiscard]] ObjectNameTag name() const { return ObjectNameTag(_name); }
void addAmmo(int ammoAdd) { _stockAmmo += ammoAdd; }