Add weapon in enemy's hand. So now you can see weapons of your enemies.

Also make some correction of rotation in Object.cpp & Mesh.cpp
master
Vectozavr 2021-10-18 22:30:02 +07:00
parent 8678e8c929
commit 7f4b9027ee
14 changed files with 104 additions and 51 deletions

View File

@ -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> player) {
_players.insert({ id, player });
}
@ -180,3 +194,7 @@ void Client::setAddBonusCallBack(std::function<void(const std::string &, const V
void Client::setRemoveBonusCallBack(std::function<void(const ObjectNameTag &)> removeBonus) {
_removeBonusCallBack = std::move(removeBonus);
}
void Client::setChangeEnemyWeaponCallBack(std::function<void(const std::string&, sf::Uint16)> changeEnemyWeapon) {
_changeEnemyWeaponCallBack = std::move(changeEnemyWeapon);
}

View File

@ -13,13 +13,12 @@ private:
std::map<sf::Uint16, std::shared_ptr<Player>> _players{};
std::shared_ptr<Player> _player;
void spawnPlayer(sf::Uint16 id);
std::function<void(sf::Uint16)> _spawnPlayerCallBack;
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 ObjectNameTag&)> _removeBonusCallBack;
std::function<void(const std::string&, sf::Uint16)> _changeEnemyWeaponCallBack;
public:
explicit Client(std::shared_ptr<Player> player) : _player(player){};
@ -31,6 +30,8 @@ public:
void setAddBonusCallBack(std::function<void(const std::string&, const Vec3D&)> addBonus);
void setRemoveBonusCallBack(std::function<void(const ObjectNameTag&)> removeBonus);
void setChangeEnemyWeaponCallBack(std::function<void(const std::string&, sf::Uint16)> 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> player);
};

View File

@ -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);

View File

@ -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;

View File

@ -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> 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> weapon) {

View File

@ -49,6 +49,7 @@ private:
void removeBonus(const ObjectNameTag& bonusName);
void addWeapon(std::shared_ptr<Weapon> weapon);
void removeWeapon(std::shared_ptr<Weapon> weapon);
void changeEnemyWeapon(const std::string& weaponName, sf::Uint16 enemyId);
public:
Shooter() : mainMenu(screen, mouse) {};
};

View File

@ -86,30 +86,22 @@ void Object::rotateLeft(double rl) {
_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>(Vec3D{_angleLeftUpLookAt->x(),
_angleLeftUpLookAt->y() + ru,
_angleLeftUpLookAt->z()});
rotate(*_up, ru);
for(auto &[attachedName, attachedObject] : _attachedObjects)
attachedObject->rotateRelativePoint(position(), *_up, ru);
rotate(Vec3D(*_up), ru);
}
void Object::rotateLookAt(double rlAt) {
_angleLeftUpLookAt = std::make_unique<Vec3D>(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) {

View File

@ -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> object, const ObjectNameTag& tag);
void unattach(const ObjectNameTag& tag);
std::shared_ptr<Object> attached(const ObjectNameTag& tag);

View File

@ -112,15 +112,14 @@ std::shared_ptr<sf::Font> ResourceManager::loadFont(const std::string& filename)
}
std::vector<std::shared_ptr<Mesh>> ResourceManager::loadObjects(const std::string &filename) {
std::vector<std::shared_ptr<Mesh>> objects{};
std::map<std::string, sf::Color> 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<std::shared_ptr<Mesh>> objects{};
std::map<std::string, sf::Color> maters{};
}
std::ifstream file(filename);
if (!file.is_open())

View File

@ -29,6 +29,7 @@ enum class MsgType
InitBonuses,
AddBonus,
RemoveBonus,
ChangeWeapon,
};
sf::Packet& operator<<(sf::Packet& packet, MsgType type);

View File

@ -25,11 +25,11 @@ Shotgun::Shotgun(int ammo, const std::string& weaponName) : Weapon(weaponName, S
}
std::map<ObjectNameTag, double>
Shotgun::processFire(std::function<std::pair<Vec3D, ObjectNameTag>(const Vec3D&, const Vec3D&)> rayCastFunction) {
Shotgun::processFire(std::function<std::pair<Vec3D, ObjectNameTag>(const Vec3D&, const Vec3D&)> rayCastFunction, const Vec3D& position, const Vec3D& direction) {
std::map<ObjectNameTag, double> damagedPlayers;
for(int i = 0; i < 15; i++) {
std::map<ObjectNameTag, double> damaged = addTrace(rayCastFunction, position() + Vec3D(triangles().back()[0]), -lookAt());
std::map<ObjectNameTag, double> damaged = addTrace(rayCastFunction, position, direction);
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<ObjectNameTag, double> processFire(std::function<std::pair<Vec3D, ObjectNameTag>(const Vec3D&, const Vec3D&)> rayCastFunction) override;
std::map<ObjectNameTag, double> processFire(std::function<std::pair<Vec3D, ObjectNameTag>(const Vec3D&, const Vec3D&)> rayCastFunction, const Vec3D& position, const Vec3D& direction) override;
};

View File

@ -21,7 +21,7 @@ Weapon::Weapon(const std::string& weaponName, const std::string& objFileName, co
translate(t);
}
std::map<ObjectNameTag, double> Weapon::fire(std::function<std::pair<Vec3D, ObjectNameTag>(const Vec3D&, const Vec3D&)> rayCastFunction) {
std::map<ObjectNameTag, double> Weapon::fire(std::function<std::pair<Vec3D, ObjectNameTag>(const Vec3D&, const Vec3D&)> rayCastFunction, const Vec3D& position, const Vec3D& direction) {
if(_clipAmmo == 0) {
reload();
if(_clipAmmo == 0)
@ -37,7 +37,7 @@ std::map<ObjectNameTag, double> Weapon::fire(std::function<std::pair<Vec3D, Obje
SoundController::playSound(SoundTag("fire"), fireSound);
Log::log("Weapon::fire (" + std::to_string(_stockAmmo) + " : " + std::to_string(_clipAmmo) + ")");
return processFire(std::move(rayCastFunction));
return processFire(std::move(rayCastFunction), position, direction);
}
void Weapon::reload() {
@ -56,8 +56,8 @@ void Weapon::reload() {
_lastReloadTime = Time::time();
}
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<ObjectNameTag, double> Weapon::processFire(std::function<std::pair<Vec3D, ObjectNameTag>(const Vec3D&, const Vec3D&)> rayCastFunction, const Vec3D& position, const Vec3D& direction) {
return addTrace(std::move(rayCastFunction), position, direction);
}
std::map<ObjectNameTag, double> Weapon::addTrace(std::function<std::pair<Vec3D, ObjectNameTag>(const Vec3D&, const Vec3D&)> rayCastFunction, const Vec3D& from, const Vec3D& directionTo) {
@ -75,8 +75,9 @@ std::map<ObjectNameTag, double> Weapon::addTrace(std::function<std::pair<Vec3D,
}
// add trace line
Vec3D to = rayCast.first == Vec3D(0) ? from + directionTo * ShooterConsts::FIRE_DISTANCE + randV: rayCast.first;
_addTraceCallBack(from, to);
Vec3D lineFrom = position() + Vec3D(triangles().back()[0]);
Vec3D lineTo = rayCast.first == Vec3D(0) ? position() + -lookAt() * ShooterConsts::FIRE_DISTANCE + randV: rayCast.first;
_addTraceCallBack(lineFrom, lineTo);
return damagedPlayers;
}

View File

@ -41,12 +41,12 @@ protected:
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<ObjectNameTag, double> processFire(std::function<std::pair<Vec3D, ObjectNameTag>(const Vec3D&, const Vec3D&)> rayCastFunction);
virtual std::map<ObjectNameTag, double> processFire(std::function<std::pair<Vec3D, ObjectNameTag>(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<ObjectNameTag, double> fire(std::function<std::pair<Vec3D, ObjectNameTag>(const Vec3D&, const Vec3D&)> rayCastFunction);
std::map<ObjectNameTag, double> fire(std::function<std::pair<Vec3D, ObjectNameTag>(const Vec3D&, const Vec3D&)> rayCastFunction, const Vec3D& position, const Vec3D& direction);
void reload();
[[nodiscard]] std::pair<double, double> balance() const{ return std::make_pair(_clipAmmo, _stockAmmo); }