diff --git a/Client.cpp b/Client.cpp index 2ffecf4..20ed0e3 100644 --- a/Client.cpp +++ b/Client.cpp @@ -14,11 +14,6 @@ void Client::updatePacket() { _socket.send(packet, _socket.serverId()); } -void Client::spawnPlayer(sf::Uint16 id) { - if(_spawnPlayerCallBack != nullptr) - _spawnPlayerCallBack(id); -} - void Client::processInit(sf::Packet& packet) { sf::Uint16 targetId; double buf[4]; @@ -26,7 +21,8 @@ void Client::processInit(sf::Packet& packet) { while (packet >> targetId >> buf[0] >> buf[1] >> buf[2] >> buf[3]) { if(targetId != _socket.ownId()) { - spawnPlayer(targetId); + if(_spawnPlayerCallBack != nullptr) + _spawnPlayerCallBack(targetId); _players[targetId]->translateToPoint(Vec3D{ buf[0], buf[1], buf[2]}); _players[targetId]->setHealth(buf[3]); @@ -45,7 +41,11 @@ void Client::processUpdate(sf::Packet& packet) { _players[targetId]->setHealth(buf[3]); _players[targetId]->rotateToAngle(Vec3D{0, buf[4], 0}); - _players[targetId]->attached(ObjectNameTag("head"))->rotate(Matrix4x4::RotationY(buf[4]) * Vec3D{1, 0, 0}, buf[5] - _players[targetId]->headAngle()); + auto head = _players[targetId]->attached(ObjectNameTag("head")); + auto weapon = _players[targetId]->attached(ObjectNameTag("Weapon")); + + head->rotateLeft(buf[5] - _players[targetId]->headAngle()); + weapon->rotateLeft(-(buf[5] - _players[targetId]->headAngle())); _players[targetId]->setHeadAngle(buf[5]); } else if (targetId == _socket.ownId()) { @@ -59,7 +59,8 @@ void Client::processNewClient(sf::Packet& packet) { packet >> targetId; - spawnPlayer(targetId); + if(_spawnPlayerCallBack != nullptr) + _spawnPlayerCallBack(targetId); } void Client::processDisconnect(sf::Uint16 targetId) { @@ -120,6 +121,12 @@ void Client::processCustomPacket(MsgType type, sf::Packet& packet) { if(_removeBonusCallBack != nullptr) _removeBonusCallBack(ObjectNameTag(tmp)); break; + case MsgType::ChangeWeapon: + packet >> buffId[0] >> tmp; + + if(_changeEnemyWeaponCallBack != nullptr) + _changeEnemyWeaponCallBack(tmp, buffId[0]); + break; default: return; } @@ -135,7 +142,7 @@ void Client::damagePlayer(sf::Uint16 targetId, double damage) { sf::Packet packet; packet << MsgType::Damage << targetId << damage; - _socket.send(packet, _socket.serverId()); + _socket.sendRely(packet, _socket.serverId()); Log::log("Client: damagePlayer " + std::to_string(targetId) + " ( -" + std::to_string(damage) + "hp )"); } @@ -151,12 +158,19 @@ void Client::takeBonus(const std::string& bonusName) { sf::Packet packet; packet << MsgType::RemoveBonus << bonusName; - _socket.send(packet, _socket.serverId()); + _socket.sendRely(packet, _socket.serverId()); if(_removeBonusCallBack != nullptr) _removeBonusCallBack(ObjectNameTag(bonusName)); } +void Client::changeWeapon(const std::string &weaponName) { + sf::Packet packet; + + packet << MsgType::ChangeWeapon << weaponName; + _socket.sendRely(packet, _socket.serverId()); +} + void Client::addPlayer(sf::Uint16 id, std::shared_ptr player) { _players.insert({ id, player }); } @@ -180,3 +194,7 @@ void Client::setAddBonusCallBack(std::function removeBonus) { _removeBonusCallBack = std::move(removeBonus); } + +void Client::setChangeEnemyWeaponCallBack(std::function changeEnemyWeapon) { + _changeEnemyWeaponCallBack = std::move(changeEnemyWeapon); +} diff --git a/Client.h b/Client.h index 86a43f3..6f4ddb9 100644 --- a/Client.h +++ b/Client.h @@ -13,13 +13,12 @@ private: std::map> _players{}; std::shared_ptr _player; - void spawnPlayer(sf::Uint16 id); - std::function _spawnPlayerCallBack; std::function _removePlayerCallBack; std::function _addFireTraceCallBack; std::function _addBonusCallBack; std::function _removeBonusCallBack; + std::function _changeEnemyWeaponCallBack; public: explicit Client(std::shared_ptr player) : _player(player){}; @@ -31,6 +30,8 @@ public: void setAddBonusCallBack(std::function addBonus); void setRemoveBonusCallBack(std::function removeBonus); + void setChangeEnemyWeaponCallBack(std::function changeEnemyWeapon); + void processInit(sf::Packet& packet) override; void processUpdate(sf::Packet& packet) override; void processNewClient(sf::Packet& packet) override; @@ -46,6 +47,8 @@ public: void addTrace(const Vec3D& from, const Vec3D& to); + void changeWeapon(const std::string& weaponName); + void addPlayer(sf::Uint16 id, std::shared_ptr player); }; diff --git a/Player.cpp b/Player.cpp index fafbdc7..db28ad1 100644 --- a/Player.cpp +++ b/Player.cpp @@ -110,8 +110,9 @@ void Player::previousWeapon() { } void Player::fire() { - if(attached(ObjectNameTag("Camera")) != nullptr) { - auto damagedPlayers = _weapons[_selectedWeapon]->fire(_rayCastFunction); + auto camera = attached(ObjectNameTag("Camera")); + if(camera != nullptr) { + auto damagedPlayers = _weapons[_selectedWeapon]->fire(_rayCastFunction, camera->position(), camera->lookAt()); for(auto& [damagedPlayerName, damage] : damagedPlayers) { sf::Uint16 targetId = std::stoi(damagedPlayerName.str().substr(6)); _damagePlayerCallBack(targetId, damage); diff --git a/Server.cpp b/Server.cpp index 292ff5b..8c1fdcd 100644 --- a/Server.cpp +++ b/Server.cpp @@ -87,7 +87,7 @@ void Server::processCustomPacket(MsgType type, sf::Packet& packet, sf::Uint16 se sendPacket << MsgType::Kill << targetId << senderId; for (auto& player : _players) - _socket.send(sendPacket, player.first); + _socket.sendRely(sendPacket, player.first); } break; case MsgType::FireTrace: @@ -114,8 +114,18 @@ void Server::processCustomPacket(MsgType type, sf::Packet& packet, sf::Uint16 se sendPacket << MsgType::RemoveBonus << tmp; for (auto& player : _players) { if(player.first != senderId) - _socket.send(sendPacket, player.first); + _socket.sendRely(sendPacket, player.first); } + break; + case MsgType::ChangeWeapon: + packet >> tmp; + sendPacket << MsgType::ChangeWeapon << senderId << tmp; + + for (auto& player : _players) { + if(player.first != senderId) + _socket.sendRely(sendPacket, player.first); + } + break; default: return; diff --git a/Shooter.cpp b/Shooter.cpp index 6d87f58..d28a9de 100644 --- a/Shooter.cpp +++ b/Shooter.cpp @@ -63,6 +63,7 @@ void Shooter::InitNetwork() 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 ObjectNameTag& bonusName){ removeBonus(bonusName); }); + client->setChangeEnemyWeaponCallBack([this](const std::string& weaponName, sf::Uint16 id){ changeEnemyWeapon(weaponName, id); }); } void Shooter::start() { @@ -227,6 +228,8 @@ void Shooter::spawnPlayer(sf::Uint16 id) { 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")); + + changeEnemyWeapon("gun", id); } void Shooter::removePlayer(sf::Uint16 id) { @@ -235,6 +238,7 @@ void Shooter::removePlayer(sf::Uint16 id) { world->removeBody(ObjectNameTag(name + "_head")); world->removeBody(ObjectNameTag(name + "_eye1")); world->removeBody(ObjectNameTag(name + "_eye2")); + world->removeBody(ObjectNameTag("enemyWeapon_" + std::to_string(id))); } void Shooter::addFireTrace(const Vec3D &from, const Vec3D &to) { @@ -263,6 +267,30 @@ void Shooter::removeBonus(const ObjectNameTag &bonusName) { void Shooter::addWeapon(std::shared_ptr weapon) { world->addBody(weapon, weapon->name()); + + if(client != nullptr) + client->changeWeapon(weapon->name().str()); +} + +void Shooter::changeEnemyWeapon(const std::string& weaponName, sf::Uint16 enemyId) { + ObjectNameTag weaponTag("enemyWeapon_" + std::to_string(enemyId)); + auto head = world->body(ObjectNameTag("Enemy_" + std::to_string(enemyId) + "_head")); + auto enemy = world->body(ObjectNameTag("Enemy_" + std::to_string(enemyId))); + + + // remove old weapon: + world->removeBody(weaponTag); + enemy->unattach(ObjectNameTag("Weapon")); + + world->loadBody(weaponTag, "obj/" + weaponName + ".obj"); + world->body(weaponTag)->setCollider(false); + world->body(weaponTag)->scale(Vec3D(3, 3, 3)); + + world->body(weaponTag)->translateToPoint(head->position() - enemy->left() - enemy->up()); + + world->body(weaponTag)->rotate(Vec3D(0, Consts::PI + head->angle().y(), 0)); + world->body(weaponTag)->rotateLeft(-head->angleLeftUpLookAt().x()); + enemy->attach(world->body(weaponTag), ObjectNameTag("Weapon")); } void Shooter::removeWeapon(std::shared_ptr weapon) { diff --git a/Shooter.h b/Shooter.h index 0e6f5b8..969bf5f 100644 --- a/Shooter.h +++ b/Shooter.h @@ -49,6 +49,7 @@ private: void removeBonus(const ObjectNameTag& bonusName); void addWeapon(std::shared_ptr weapon); void removeWeapon(std::shared_ptr weapon); + void changeEnemyWeapon(const std::string& weaponName, sf::Uint16 enemyId); public: Shooter() : mainMenu(screen, mouse) {}; }; diff --git a/engine/Object.cpp b/engine/Object.cpp index 4c65c33..8b566bd 100644 --- a/engine/Object.cpp +++ b/engine/Object.cpp @@ -83,33 +83,25 @@ void Object::rotateRelativePoint(const Vec3D &s, const Vec3D &v, double r) { void Object::rotateLeft(double rl) { _angleLeftUpLookAt = std::make_unique(Vec3D{_angleLeftUpLookAt->x() + rl, - _angleLeftUpLookAt->y(), - _angleLeftUpLookAt->z()}); + _angleLeftUpLookAt->y(), + _angleLeftUpLookAt->z()}); - rotate(*_left, rl); - - for(auto &[attachedName, attachedObject] : _attachedObjects) - attachedObject->rotateRelativePoint(position(), *_left, rl); + rotate(Vec3D(*_left), rl); } void Object::rotateUp(double ru) { _angleLeftUpLookAt = std::make_unique(Vec3D{_angleLeftUpLookAt->x(), - _angleLeftUpLookAt->y() + ru, - _angleLeftUpLookAt->z()}); - rotate(*_up, ru); + _angleLeftUpLookAt->y() + ru, + _angleLeftUpLookAt->z()}); - for(auto &[attachedName, attachedObject] : _attachedObjects) - attachedObject->rotateRelativePoint(position(), *_up, ru); + rotate(Vec3D(*_up), ru); } void Object::rotateLookAt(double rlAt) { _angleLeftUpLookAt = std::make_unique(Vec3D{_angleLeftUpLookAt->x(), _angleLeftUpLookAt->y(), _angleLeftUpLookAt->z() + rlAt}); - rotate(*_lookAt, rlAt); - - for(auto &[attachedName, attachedObject] : _attachedObjects) - attachedObject->rotateRelativePoint(position(), *_lookAt, rlAt); + rotate(Vec3D(*_lookAt), rlAt); } void Object::translateToPoint(const Vec3D &point) { diff --git a/engine/Object.h b/engine/Object.h index c9cbcab..b142a63 100644 --- a/engine/Object.h +++ b/engine/Object.h @@ -44,6 +44,9 @@ public: virtual void rotateToAngle(const Vec3D& v); virtual void rotateRelativePoint(const Vec3D& s, const Vec3D& r); virtual void rotateRelativePoint(const Vec3D& s, const Vec3D& v, double r); + void rotateLeft(double rl); + void rotateUp(double ru); + void rotateLookAt(double rlAt); [[nodiscard]] Vec3D position() const { return *_position; } [[nodiscard]] Vec3D angle() const { return *_angle; } @@ -53,10 +56,6 @@ public: [[nodiscard]] Vec3D up() const { return *_up; } [[nodiscard]] Vec3D lookAt() const { return *_lookAt; } - void rotateLeft(double rl); - void rotateUp(double ru); - void rotateLookAt(double rlAt); - void attach(std::shared_ptr object, const ObjectNameTag& tag); void unattach(const ObjectNameTag& tag); std::shared_ptr attached(const ObjectNameTag& tag); diff --git a/engine/ResourceManager.cpp b/engine/ResourceManager.cpp index 1aafa6b..a89f110 100644 --- a/engine/ResourceManager.cpp +++ b/engine/ResourceManager.cpp @@ -112,15 +112,14 @@ std::shared_ptr ResourceManager::loadFont(const std::string& filename) } std::vector> ResourceManager::loadObjects(const std::string &filename) { + std::vector> objects{}; + std::map maters{}; // If objects is already loaded - return pointer to it auto it = _instance->_objects.find(filename); - if (it != _instance->_objects.end()) + if (it != _instance->_objects.end()) { return it->second; - - - std::vector> objects{}; - std::map maters{}; + } std::ifstream file(filename); if (!file.is_open()) diff --git a/engine/network/MsgType.h b/engine/network/MsgType.h index 435f4f4..cd7aa0f 100644 --- a/engine/network/MsgType.h +++ b/engine/network/MsgType.h @@ -29,6 +29,7 @@ enum class MsgType InitBonuses, AddBonus, RemoveBonus, + ChangeWeapon, }; sf::Packet& operator<<(sf::Packet& packet, MsgType type); diff --git a/weapon/Shotgun.cpp b/weapon/Shotgun.cpp index 73ecd1f..59cd8ab 100644 --- a/weapon/Shotgun.cpp +++ b/weapon/Shotgun.cpp @@ -25,11 +25,11 @@ Shotgun::Shotgun(int ammo, const std::string& weaponName) : Weapon(weaponName, S } std::map -Shotgun::processFire(std::function(const Vec3D&, const Vec3D&)> rayCastFunction) { +Shotgun::processFire(std::function(const Vec3D&, const Vec3D&)> rayCastFunction, const Vec3D& position, const Vec3D& direction) { std::map damagedPlayers; for(int i = 0; i < 15; i++) { - std::map damaged = addTrace(rayCastFunction, position() + Vec3D(triangles().back()[0]), -lookAt()); + std::map damaged = addTrace(rayCastFunction, position, direction); for(auto& player : damaged) damagedPlayers[player.first] += player.second; } diff --git a/weapon/Shotgun.h b/weapon/Shotgun.h index af04244..625f2af 100644 --- a/weapon/Shotgun.h +++ b/weapon/Shotgun.h @@ -10,7 +10,7 @@ class Shotgun final : public Weapon { public: explicit Shotgun(int ammo = 15, const std::string& weaponName = "shotgun"); - std::map processFire(std::function(const Vec3D&, const Vec3D&)> rayCastFunction) override; + std::map processFire(std::function(const Vec3D&, const Vec3D&)> rayCastFunction, const Vec3D& position, const Vec3D& direction) override; }; diff --git a/weapon/Weapon.cpp b/weapon/Weapon.cpp index f228308..28dd570 100644 --- a/weapon/Weapon.cpp +++ b/weapon/Weapon.cpp @@ -21,7 +21,7 @@ Weapon::Weapon(const std::string& weaponName, const std::string& objFileName, co translate(t); } -std::map Weapon::fire(std::function(const Vec3D&, const Vec3D&)> rayCastFunction) { +std::map Weapon::fire(std::function(const Vec3D&, const Vec3D&)> rayCastFunction, const Vec3D& position, const Vec3D& direction) { if(_clipAmmo == 0) { reload(); if(_clipAmmo == 0) @@ -37,7 +37,7 @@ std::map Weapon::fire(std::function Weapon::processFire(std::function(const Vec3D&, const Vec3D&)> rayCastFunction) { - return addTrace(std::move(rayCastFunction), position() + Vec3D(triangles().back()[0]), -lookAt()); +std::map Weapon::processFire(std::function(const Vec3D&, const Vec3D&)> rayCastFunction, const Vec3D& position, const Vec3D& direction) { + return addTrace(std::move(rayCastFunction), position, direction); } std::map Weapon::addTrace(std::function(const Vec3D&, const Vec3D&)> rayCastFunction, const Vec3D& from, const Vec3D& directionTo) { @@ -75,8 +75,9 @@ std::map Weapon::addTrace(std::function addTrace(std::function(const Vec3D&, const Vec3D&)> rayCastFunction, const Vec3D& position, const Vec3D& direction); - virtual std::map processFire(std::function(const Vec3D&, const Vec3D&)> rayCastFunction); + virtual std::map processFire(std::function(const Vec3D&, const Vec3D&)> rayCastFunction, const Vec3D& position, const Vec3D& direction); public: Weapon(const std::string& weaponName, const std::string& objFileName, const Vec3D& scale, const Vec3D& translate, const Vec3D& rotate); - std::map fire(std::function(const Vec3D&, const Vec3D&)> rayCastFunction); + std::map fire(std::function(const Vec3D&, const Vec3D&)> rayCastFunction, const Vec3D& position, const Vec3D& direction); void reload(); [[nodiscard]] std::pair balance() const{ return std::make_pair(_clipAmmo, _stockAmmo); }