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" #include "Player.h"
class Bonus final : public RigidBody { class Bonus final : public RigidBody {
protected: private:
std::string _name; std::string _name;
public: public:
explicit Bonus(const std::string &bonusName, const std::string& filename, const std::string &materials = "", const Vec3D& scale = Vec3D{1, 1, 1}); 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]->setHealth(buf[3]);
_players[targetId]->rotateToAngle(Vec3D{0, buf[4], 0}); _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]); _players[targetId]->setHeadAngle(buf[5]);
} else if (targetId == _socket.ownId()) { } else if (targetId == _socket.ownId()) {
@ -118,8 +118,11 @@ void Client::processCustomPacket(MsgType type, sf::Packet& packet) {
case MsgType::RemoveBonus: case MsgType::RemoveBonus:
packet >> tmp; packet >> tmp;
if(_removeBonusCallBack != nullptr) if(_removeBonusCallBack != nullptr)
_removeBonusCallBack(tmp); _removeBonusCallBack(ObjectNameTag(tmp));
break; 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()); _socket.send(packet, _socket.serverId());
if(_removeBonusCallBack != nullptr) if(_removeBonusCallBack != nullptr)
_removeBonusCallBack(bonusName); _removeBonusCallBack(ObjectNameTag(bonusName));
} }
void Client::addPlayer(sf::Uint16 id, std::shared_ptr<Player> player) { 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); _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); _removeBonusCallBack = std::move(removeBonus);
} }

View File

@ -19,7 +19,7 @@ private:
std::function<void(sf::Uint16)> _removePlayerCallBack; std::function<void(sf::Uint16)> _removePlayerCallBack;
std::function<void(const Vec3D&, const Vec3D&)> _addFireTraceCallBack; std::function<void(const Vec3D&, const Vec3D&)> _addFireTraceCallBack;
std::function<void(const std::string&, const Vec3D&)> _addBonusCallBack; std::function<void(const std::string&, const Vec3D&)> _addBonusCallBack;
std::function<void(const std::string&)> _removeBonusCallBack; std::function<void(const ObjectNameTag&)> _removeBonusCallBack;
public: public:
explicit Client(std::shared_ptr<Player> player) : _player(player){}; explicit Client(std::shared_ptr<Player> player) : _player(player){};
@ -29,7 +29,7 @@ public:
void setRemovePlayerCallBack(std::function<void(sf::Uint16)> remove); void setRemovePlayerCallBack(std::function<void(sf::Uint16)> remove);
void setAddFireTraceCallBack(std::function<void(const Vec3D&, const Vec3D&)> addTrace); void setAddFireTraceCallBack(std::function<void(const Vec3D&, const Vec3D&)> addTrace);
void setAddBonusCallBack(std::function<void(const std::string&, const Vec3D&)> addBonus); 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 processInit(sf::Packet& packet) override;
void processUpdate(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)); _fullHealthSound.setBuffer(*ResourceManager::loadSoundBuffer(ShooterConsts::RESTORE_HEALTH_SOUND));
_fullAbilitySound.setBuffer(*ResourceManager::loadSoundBuffer(ShooterConsts::RESTORE_ABILITY_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) { void Player::rotateWeaponsRelativePoint(const Vec3D& point4D, const Vec3D& v, double val) {
@ -37,30 +37,30 @@ void Player::playKill() {
_killSound.play(); _killSound.play();
} }
void Player::collisionWithObject(const std::string &objName, std::shared_ptr<RigidBody> obj) { void Player::collisionWithObject(const ObjectNameTag& tag, std::shared_ptr<RigidBody> obj) {
if(objName.find("Bonus_gun") != std::string::npos) if(tag.str().find("Bonus_gun") != std::string::npos)
addWeapon(std::make_shared<Gun>()); 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>()); 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>()); 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>()); 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>()); addWeapon(std::make_shared<Rifle>());
if(objName.find("Bonus_hill") != std::string::npos) if(tag.str().find("Bonus_hill") != std::string::npos)
setFullHealth(); setFullHealth();
if(objName.find("Bonus_ability") != std::string::npos) if(tag.str().find("Bonus_ability") != std::string::npos)
setFullAbility(); setFullAbility();
if(objName.find("Bonus") != std::string::npos) { if(tag.str().find("Bonus") != std::string::npos) {
_takeBonusCallBack(objName); _takeBonusCallBack(tag.str());
} }
} }
@ -75,7 +75,7 @@ void Player::addWeapon(std::shared_ptr<Weapon> weapon) {
} }
_weapons.push_back(weapon); _weapons.push_back(weapon);
attach(weapon, weapon->name()); attach(weapon, ObjectNameTag(weapon->name()));
_weapons.back()->translate(position()); _weapons.back()->translate(position());
_weapons.back()->rotateRelativePoint(position() + Vec3D{0, 1.8, 0}, Vec3D{0, 1, 0}, _angle->y()); _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()) { if(!_weapons.empty()) {
for(auto weapon : _weapons) for(auto weapon : _weapons)
unattach(weapon->name()); unattach(ObjectNameTag(weapon->name()));
_removeWeaponCallBack(_weapons[_selectedWeapon]); _removeWeaponCallBack(_weapons[_selectedWeapon]);
_weapons.clear(); _weapons.clear();
@ -125,11 +125,11 @@ void Player::previousWeapon() {
} }
void Player::fire() { void Player::fire() {
if(attached("camera") != nullptr) { if(attached(ObjectNameTag("camera")) != nullptr) {
auto damagedPlayers = _weapons[_selectedWeapon]->fire(_rayCastFunction); auto damagedPlayers = _weapons[_selectedWeapon]->fire(_rayCastFunction);
for(auto& damagedPlayer : damagedPlayers) { for(auto& [damagedPlayerName, damage] : damagedPlayers) {
sf::Uint16 targetId = std::stoi(damagedPlayer.first.substr(6)); sf::Uint16 targetId = std::stoi(damagedPlayerName.str().substr(6));
_damagePlayerCallBack(targetId, damagedPlayer.second); _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>)> _addWeaponCallBack;
std::function<void(std::shared_ptr<Weapon>)> _removeWeaponCallBack; 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: public:
Player(); Player();
@ -97,7 +97,7 @@ public:
void setRemoveWeaponCallBack(std::function<void(std::shared_ptr<Weapon>)> removeWeapon) { void setRemoveWeaponCallBack(std::function<void(std::shared_ptr<Weapon>)> removeWeapon) {
_removeWeaponCallBack = std::move(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); _rayCastFunction = std::move(rayCastFunction);
} }
@ -105,7 +105,7 @@ public:
void setHeadAngle(double a) { _headAngle = a; } void setHeadAngle(double a) { _headAngle = a; }
[[nodiscard]] double headAngle() const { return _headAngle; }; [[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::W) ||
Keyboard::isKeyPressed(sf::Keyboard::S)); 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(camera != nullptr && _inRunning) {
if (!Timeline::isInAnimList("camera_hor_oscil")) { if (!Timeline::isInAnimList(AnimationListTag("camera_hor_oscil"))) {
Timeline::animate("camera_hor_oscil", new ATranslate(camera, -camera->left() / 6, 0.3,Animation::LoopOut::None, Animation::InterpolationType::cos)); Timeline::animate(AnimationListTag("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(AnimationListTag("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)); 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(AnimationListTag("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(AnimationListTag("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("camera_vert_oscil", new AWait(0)); Timeline::animate(AnimationListTag("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("camera_vert_oscil", new AWait(0)); Timeline::animate(AnimationListTag("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("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) { } else if(camera != nullptr && inRunning_old && !_inRunning) {
Timeline::deleteAnimationList("camera_hor_oscil"); Timeline::deleteAnimationList(AnimationListTag("camera_hor_oscil"));
Timeline::deleteAnimationList("camera_vert_oscil"); Timeline::deleteAnimationList(AnimationListTag("camera_vert_oscil"));
Timeline::deleteAnimationList("camera_init"); Timeline::deleteAnimationList(AnimationListTag("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::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 // Left and right

View File

@ -10,7 +10,6 @@ void Server::broadcast() {
updatePacket << MsgType::Update; updatePacket << MsgType::Update;
for (auto& player : _players) { 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(); 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); _socket.sendRely(sendPacket1, targetId);
// bonuses init // bonuses init
sendPacket2 << MsgType::InitBonuses; sendPacket2 << MsgType::InitBonuses;
for(auto& bonus : _bonuses) { for(auto& [bonusName, bonusInfo] : _bonuses) {
if(bonus.second.onTheMap) if(bonusInfo->onTheMap)
sendPacket2 << bonus.first << bonus.second.position.x() << bonus.second.position.y() << bonus.second.position.z(); sendPacket2 << bonusName << bonusInfo->position.x() << bonusInfo->position.y() << bonusInfo->position.z();
} }
_socket.sendRely(sendPacket2, targetId); _socket.sendRely(sendPacket2, targetId);
@ -111,14 +109,19 @@ void Server::processCustomPacket(MsgType type, sf::Packet& packet, sf::Uint16 se
_players[senderId]->setFullAbility(); _players[senderId]->setFullAbility();
} }
_bonuses[tmp].onTheMap = false; _bonuses[tmp] = std::make_shared<BonusInfo>(BonusInfo{_bonuses[tmp]->position, Time::time(), false});
_bonuses[tmp].lastTake = Time::time();
sendPacket << MsgType::RemoveBonus << tmp; sendPacket << MsgType::RemoveBonus << tmp;
for (auto& player : _players) { for (auto& player : _players) {
if(player.first != senderId) if(player.first != senderId)
_socket.send(sendPacket, player.first); _socket.send(sendPacket, player.first);
} }
break; break;
case MsgType::Error:
break;
default:
throw std::logic_error{"Server::processCustomPacket: unknown MsgType"};
} }
} }
@ -128,36 +131,36 @@ void Server::processStop() {
} }
void Server::generateBonuses() { void Server::generateBonuses() {
_bonuses.insert({"Bonus_gun_1", {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", {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_1", std::make_shared<BonusInfo>(BonusInfo{Point4D(-10, 13, -24), -2*_bonusRechargeTime, true})});
_bonuses.insert({"Bonus_shotgun_2", {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_1", std::make_shared<BonusInfo>(BonusInfo{Point4D(-25, 30, 50), -2*_bonusRechargeTime, true})});
_bonuses.insert({"Bonus_ak47_2", {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_1", std::make_shared<BonusInfo>(BonusInfo{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_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_1", std::make_shared<BonusInfo>(BonusInfo{Point4D(40, -2, 45), -2*_bonusRechargeTime, true})});
_bonuses.insert({"Bonus_rifle_2", {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_1", std::make_shared<BonusInfo>(BonusInfo{Point4D(-40, -2, 45), -2*_bonusRechargeTime, true})});
_bonuses.insert({"Bonus_hill_2", {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_1", std::make_shared<BonusInfo>(BonusInfo{Point4D(25, 18, -33), -2*_bonusRechargeTime, true})});
_bonuses.insert({"Bonus_ability_2", {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() { void Server::updateInfo() {
for(auto& bonus : _bonuses) { for(auto& [bonusName, bonusInfo] : _bonuses) {
if(!bonus.second.onTheMap && std::abs(Time::time() - bonus.second.lastTake) > _bonusRechargeTime) { if(!bonusInfo->onTheMap && std::abs(Time::time() - bonusInfo->lastTake) > _bonusRechargeTime) {
sf::Packet sendPacket; 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) for (const auto& player : _players)
_socket.sendRely(sendPacket, player.first); _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 "Player.h"
#include "Bonus.h" #include "Bonus.h"
struct BonusInfo { struct BonusInfo final {
Point4D position{}; const Point4D position{};
double lastTake = std::numeric_limits<double>::min(); const double lastTake = std::numeric_limits<double>::min();
bool onTheMap = false; const bool onTheMap = false;
}; };
class Server final : public ServerUDP { class Server final : public ServerUDP {
private: private:
std::map<sf::Uint16, std::shared_ptr<Player>> _players{}; 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; double _bonusRechargeTime = 60;
public: public:

View File

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

View File

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

View File

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

View File

@ -7,8 +7,20 @@
#include <map> #include <map>
#include "Vec3D.h" #include "Vec3D.h"
#include <memory>
#include <string> #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 { class Object {
protected: 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> _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::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> _position = std::make_unique<Vec3D>(Vec3D{0, 0, 0});
std::unique_ptr<Vec3D> _angle = 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 rotateUp(double ru);
void rotateLookAt(double rlAt); void rotateLookAt(double rlAt);
void attach(std::shared_ptr<Object> object, const std::string& name); void attach(std::shared_ptr<Object> object, const ObjectNameTag& tag);
void unattach(const std::string& name); void unattach(const ObjectNameTag& tag);
std::shared_ptr<Object> attached(const std::string& name); std::shared_ptr<Object> attached(const ObjectNameTag& tag);
virtual ~Object(); virtual ~Object();
}; };

View File

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

View File

@ -11,23 +11,23 @@
class World final { class World final {
private: private:
std::map<std::string, std::shared_ptr<RigidBody>> _objects; std::map<ObjectNameTag, std::shared_ptr<RigidBody>> _objects;
public: public:
World() = default; World() = default;
void checkCollision(const std::string& body); void checkCollision(const ObjectNameTag& tag);
void update(); void update();
void projectObjectsInCamera(std::shared_ptr<Camera> camera); void projectObjectsInCamera(std::shared_ptr<Camera> camera);
void addBody(std::shared_ptr<RigidBody> mesh, const std::string& name = ""); void addBody(std::shared_ptr<RigidBody> mesh, const ObjectNameTag& tag);
std::shared_ptr<RigidBody> body(const std::string& name); std::shared_ptr<RigidBody> body(const ObjectNameTag& tag);
void removeBody(std::string name); void removeBody(const ObjectNameTag& tag);
void loadBody(const std::string &name, const std::string &filename, const std::string &materials = "", const Vec3D& scale = Vec3D{1, 1, 1}); 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: // rayCast returns pair of Point4D and std::string:
// 1) Point4D is point of collision // 1) Point4D is point of collision
// 2) std::string - title of the object // 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}); 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 <list>
#include "Animation.h" #include "Animation.h"
#include "Timeline.h"
namespace Timeline { namespace Timeline {
namespace { 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); _animations[listName].emplace_back(anim);
} }
@ -18,13 +19,13 @@ namespace Timeline {
_animations.clear(); _animations.clear();
} }
void deleteAnimationList(const std::string& listName) { void deleteAnimationList(const AnimationListTag& listName) {
_animations[listName].clear(); _animations[listName].clear();
_animations.erase(listName); _animations.erase(listName);
} }
[[nodiscard]] bool isInAnimList(const std::string& name) { [[nodiscard]] bool isInAnimList(const AnimationListTag& listName) {
return !_animations[name].empty(); return !_animations[listName].empty();
} }
void update() { void update() {

View File

@ -7,14 +7,26 @@
#include "Animation.h" #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 { namespace Timeline {
void update(); void update();
void animate(const std::string& listName, Animation* anim); void animate(const AnimationListTag& listName, Animation* anim);
void deleteAllAnimations(); 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 #endif //SHOOTER_TIMELINE_H

View File

@ -82,9 +82,10 @@ bool ClientUDP::process()
sf::Packet packet; sf::Packet packet;
sf::Uint16 senderId; sf::Uint16 senderId;
sf::Uint16 targetId; 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; return false;
if (!connected() && type != MsgType::Init) if (!connected() && type != MsgType::Init)
return true; return true;
@ -119,6 +120,10 @@ bool ClientUDP::process()
processDisconnect(targetId); processDisconnect(targetId);
break; break;
case MsgType::Confirm:
break;
default: default:
processCustomPacket(type, packet); processCustomPacket(type, packet);
} }

View File

@ -89,13 +89,13 @@ bool ServerUDP::process()
sf::Packet packet; sf::Packet packet;
sf::Packet sendPacket; sf::Packet sendPacket;
sf::Uint16 senderId; 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; return false;
switch (type) switch (type) {
{
// here we process any operations based on msg type // here we process any operations based on msg type
case MsgType::Connect: case MsgType::Connect:
@ -117,6 +117,9 @@ bool ServerUDP::process()
_socket.sendRely(sendPacket, client); _socket.sendRely(sendPacket, client);
processDisconnect(senderId); processDisconnect(senderId);
break;
case MsgType::Confirm:
break; break;
default: default:
processCustomPacket(type, packet, senderId); 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) if (!(packet >> version) || version != Consts::NETWORK_VERSION)
return MsgType::Error; return MsgType::Error;
sf::Uint16 tmp; sf::Uint16 tmp;
for (tmp = 64; tmp >= 1; tmp--) for (tmp = Consts::NETWORK_MAX_CLIENTS; tmp >= 1; tmp--)
{ {
if (!_connections.count(tmp)) if (!_connections.count(tmp))
senderId = tmp; senderId = tmp;

View File

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

View File

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

View File

@ -10,7 +10,7 @@
class Shotgun final : public Weapon { class Shotgun final : public Weapon {
public: public:
explicit Shotgun(int ammo = 15, const std::string& weaponName = "shotgun"); 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)); 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) { if(_clipAmmo == 0) {
reload(); reload();
if(_clipAmmo == 0) 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) 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(); _lastFireTime = Time::time();
_clipAmmo--; _clipAmmo--;
@ -58,12 +58,12 @@ void Weapon::reload() {
_lastReloadTime = Time::time(); _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()); 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<ObjectNameTag, double> Weapon::addTrace(std::function<std::pair<Vec3D, ObjectNameTag>(const Vec3D&, const Vec3D&)> rayCastFunction, const Vec3D& from, const Vec3D& directionTo) {
std::map<std::string, double> damagedPlayers; std::map<ObjectNameTag, double> damagedPlayers;
double spreading = _spreading*ShooterConsts::FIRE_DISTANCE/100; 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 // damage player
auto rayCast = rayCastFunction(from, from + directionTo * ShooterConsts::FIRE_DISTANCE + randV); 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()); 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::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: public:
Weapon(const std::string& weaponName, const std::string& objFileName, const std::string& matFileName, const Vec3D& scale, const Vec3D& translate, const Vec3D& rotate); 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(); void reload();
[[nodiscard]] std::pair<double, double> balance() const{ return std::make_pair(_clipAmmo, _stockAmmo); } [[nodiscard]] std::pair<double, double> balance() const{ return std::make_pair(_clipAmmo, _stockAmmo); }
@ -58,7 +58,7 @@ public:
_addTraceCallBack = std::move(add); _addTraceCallBack = std::move(add);
} }
[[nodiscard]] std::string name() const { return _name; } [[nodiscard]] ObjectNameTag name() const { return ObjectNameTag(_name); }
void addAmmo(int ammoAdd) { _stockAmmo += ammoAdd; } void addAmmo(int ammoAdd) { _stockAmmo += ammoAdd; }