Added EventHandler, bug fixes with chat and with Error messages

master
Vectozavr 2023-05-27 18:14:17 +03:00
parent d722d60d9e
commit 8818a73fcb
11 changed files with 190 additions and 223 deletions

2
3dzavr

@ -1 +1 @@
Subproject commit 5217578e1500cbe567ddf13a44fffd60e3ad445c Subproject commit 1a01de8d9fbb9a6f27e3662f17c24358e2bfc699

View File

@ -112,7 +112,8 @@ add_executable(${CMAKE_PROJECT_NAME}
3dzavr/engine/network/UDPConnection.h 3dzavr/engine/network/UDPConnection.h
3dzavr/engine/network/UDPSocket.cpp 3dzavr/engine/network/UDPSocket.cpp
3dzavr/engine/network/UDPSocket.h 3dzavr/engine/network/UDPSocket.h
) 3dzavr/engine/utils/EventHandler.cpp
3dzavr/engine/utils/EventHandler.h)
if(APPLE OR UNIX) if(APPLE OR UNIX)
include_directories(/usr/local/include) include_directories(/usr/local/include)

View File

@ -9,6 +9,8 @@
#include "ShooterConsts.h" #include "ShooterConsts.h"
#include "3dzavr/engine/io/SoundController.h" #include "3dzavr/engine/io/SoundController.h"
#include "network/Chat.h" #include "network/Chat.h"
#include "3dzavr/engine/utils/EventHandler.h"
#include <iostream>
using namespace std; using namespace std;
// Read server/client settings and start both. // Read server/client settings and start both.
@ -55,17 +57,6 @@ void Shooter::initNetwork() {
client->requestMap(clientIp, &current_map); client->requestMap(clientIp, &current_map);
client->connect(clientIp, clientPort); client->connect(clientIp, clientPort);
player->setPlayerNickName(playerName); player->setPlayerNickName(playerName);
// TODO: encapsulate call backs inside ShooterClient
client->setSpawnPlayerCallBack([this](sf::Uint16 id) { spawnPlayer(id); });
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 ObjectNameTag &bonusName) { removeBonus(bonusName); });
client->setChangeEnemyWeaponCallBack(
[this](const std::string &weaponName, sf::Uint16 id) { changeEnemyWeapon(weaponName, id); });
} }
void Shooter::start() { void Shooter::start() {
@ -79,20 +70,54 @@ void Shooter::start() {
world->loadMap(current_map, Vec3D{5, 5, 5}); world->loadMap(current_map, Vec3D{5, 5, 5});
// TODO: encapsulate call backs inside Player EventHandler::listen<void(sf::Uint16)>(
player->setAddTraceCallBack([this](const Vec3D &from, const Vec3D &to) { Event("spawn_player"),
client->addTrace(from, to); [this](sf::Uint16 targetId) {
spawnPlayer(targetId);
});
EventHandler::listen<void(sf::Uint16)>(
Event("remove_player"),
[this](sf::Uint16 targetId) {
removePlayer(targetId);
});
EventHandler::listen<void()>(Event("fire"), [this](){ player->fireWeaponAnimation(); });
EventHandler::listen<void(const Vec3D&, const Vec3D&)>(
Event("your_bullet"),
[this](const Vec3D &from, const Vec3D &to) {
addFireTrace(from, to); addFireTrace(from, to);
}); });
player->setDamagePlayerCallBack( EventHandler::listen<void(const Vec3D&, const Vec3D&)>(
[this](sf::Uint16 targetId, double damage) { client->damagePlayer(targetId, damage); }); Event("enemy_bullet"),
player->setRayCastFunction( [this](const Vec3D &from, const Vec3D &to) {
[this](const Vec3D &from, const Vec3D &to) { return world->rayCast(from, to, "Player Weapon fireTrace bulletHole"); }); addFireTrace(from, to);
player->setTakeBonusCallBack([this](const string &bonusName) { client->takeBonus(bonusName); }); });
player->setAddWeaponCallBack([this](std::shared_ptr<Weapon> weapon) { addWeapon(std::move(weapon)); }); EventHandler::listen<void(std::shared_ptr<Weapon>)>(
player->setRemoveWeaponCallBack([this](std::shared_ptr<Weapon> weapon) { removeWeapon(std::move(weapon)); }); Event("add_weapon"),
[this](std::shared_ptr<Weapon> weapon) {
addWeapon(weapon);
});
EventHandler::listen<void(std::shared_ptr<Weapon>)>(
Event("remove_weapon"),
[this](std::shared_ptr<Weapon> weapon) {
removeWeapon(weapon);
});
EventHandler::listen<void(const std::string&, sf::Uint16)>(
Event("change_enemy_weapon"),
[this](const std::string &weaponName, sf::Uint16 enemyId) {
changeEnemyWeapon(weaponName, enemyId);
});
EventHandler::listen<void(const string&, const Vec3D&)>(
Event("add_bonus"),
[this](const string &bonusName, const Vec3D &position) { addBonus(bonusName, position); }
);
EventHandler::listen<void(const ObjectNameTag &)>(
Event("remove_bonus"),
[this](const ObjectNameTag &bonusName) { removeBonus(bonusName); }
);
player->reInitWeapons(); EventHandler::listen<void()>(Event("reload_weapon"), [this](){ player->reloadWeaponAnimation(); });
player->setRayCastFunction([this](const Vec3D &from, const Vec3D &to) { return world->rayCast(from, to, "Player Weapon fireTrace bulletHole"); });
camera->translateToPoint(player->position() + Vec3D{0, 1.8, 0}); camera->translateToPoint(player->position() + Vec3D{0, 1.8, 0});
player->attach(camera); player->attach(camera);
@ -110,6 +135,8 @@ void Shooter::start() {
server->stop(); server->stop();
} }
player->reInitWeapons();
// windows init: // windows init:
mainMenu.setTitle("Main menu"); mainMenu.setTitle("Main menu");
mainMenu.setBackgroundTexture(ShooterConsts::MAIN_MENU_BACK, 1.1, 1.1, screen->width(), screen->height()); mainMenu.setBackgroundTexture(ShooterConsts::MAIN_MENU_BACK, 1.1, 1.1, screen->width(), screen->height());
@ -131,6 +158,7 @@ void Shooter::start() {
server->stop(); server->stop();
this->exit(); this->exit();
}, "Exit", 5, 5, ShooterConsts::MAIN_MENU_GUI, {0, 66}, {0, 86}, {0, 46}, Consts::MEDIUM_FONT, {255, 255, 255}); }, "Exit", 5, 5, ShooterConsts::MAIN_MENU_GUI, {0, 66}, {0, 86}, {0, 46}, Consts::MEDIUM_FONT, {255, 255, 255});
client->setChatManager(chat); client->setChatManager(chat);
} }
@ -179,10 +207,10 @@ void Shooter::update() {
if (isTypingMessage) { if (isTypingMessage) {
string symbols = screen->getInputSymbols(); string symbols = screen->getInputSymbols();
for (char s : symbols) { for (char s : symbols) {
if (s == (char)8) {//backspace if (s == (char)8) { //backspace
message = message.substr(0, message.size() - 1); message = message.substr(0, message.size() - 1);
} }
else if (s == (char)27) {//escape else if (s == (char)27) { //escape
message = ""; //FIXME: не работает потому что isKeyTapped имеют задержку, message = ""; //FIXME: не работает потому что isKeyTapped имеют задержку,
isTypingMessage = false; //т. е. этот код выполняется после нажатия на ESC, isTypingMessage = false; //т. е. этот код выполняется после нажатия на ESC,
} // но при следующем цикле при проверке isKeyTapped(ESC) возвращается TRUE } // но при следующем цикле при проверке isKeyTapped(ESC) возвращается TRUE
@ -213,15 +241,16 @@ void Shooter::drawChat() {
sf::Color chatColor = isTypingMessage? sf::Color(50, 50, 50, 255) : sf::Color(50, 50, 50, chat->update(Time::deltaTime())); sf::Color chatColor = isTypingMessage? sf::Color(50, 50, 50, 255) : sf::Color(50, 50, 50, chat->update(Time::deltaTime()));
string chatText = isTypingMessage ? chat->getChat() : chat->getChatPreview(); string chatText = isTypingMessage ? chat->getChat() : chat->getChatPreview();
screen->drawText(chatText, Vec2D{ 0, (double)screen->height()*0.25 }, 20, chatColor); screen->drawText(chatText, Vec2D{ 10, (double)screen->height()*0.25 }, 20, chatColor);
if (isTypingMessage){ if (isTypingMessage){
screen->drawTetragon( screen->drawTetragon(
Vec2D{ (double)screen->width() * 0.05, (double)screen->height() * 0.7 }, Vec2D{ (double)screen->width() * 0.05, (double)screen->height() * 0.7},
Vec2D{ (double)screen->width() * 0.95, (double)screen->height() * 0.7 }, Vec2D{ (double)screen->width() * 0.95, (double)screen->height() * 0.7},
Vec2D{ (double)screen->width() * 0.95, (double)screen->height() * 0.7+40 }, Vec2D{ (double)screen->width() * 0.95, (double)screen->height() * 0.7+50 },
Vec2D{ (double)screen->width() * 0.05, (double)screen->height() * 0.7+40 }, sf::Color(150, 150, 150, 150)); Vec2D{ (double)screen->width() * 0.05, (double)screen->height() * 0.7+50 }, sf::Color(150, 150, 150, 150));
screen->drawText(message, Vec2D{(double)screen->width() * 0.05, (double)screen->height() * 0.7}, 30, sf::Color(0, 0, 0, 255));
screen->drawText(message, Vec2D{(double)screen->width() * 0.05 + 10, (double)screen->height() * 0.7 - 30}, 30, sf::Color(0, 0, 0, 255));
} }
} }
@ -407,9 +436,7 @@ void Shooter::removeBonus(const ObjectNameTag &bonusName) {
void Shooter::addWeapon(std::shared_ptr<Weapon> weapon) { void Shooter::addWeapon(std::shared_ptr<Weapon> weapon) {
world->addBody(weapon); world->addBody(weapon);
if (client != nullptr) { EventHandler::call<void(const std::string&)>(Event("change_weapon"), weapon->name().str());
client->changeWeapon(weapon->name().str());
}
} }
void Shooter::changeEnemyWeapon(const std::string &weaponName, sf::Uint16 enemyId) { void Shooter::changeEnemyWeapon(const std::string &weaponName, sf::Uint16 enemyId) {

View File

@ -1,6 +1,7 @@
#include "Chat.h" #include "Chat.h"
#include <string> #include <string>
#include <iostream> #include <iostream>
void ChatManager::addNewMessage(std::string author, std::string message) { void ChatManager::addNewMessage(std::string author, std::string message) {
hide = 7.0; hide = 7.0;
messages.push_back(message); messages.push_back(message);

View File

@ -11,6 +11,30 @@
#include "../3dzavr/engine/animation/Timeline.h" #include "../3dzavr/engine/animation/Timeline.h"
#include "ShooterMsgType.h" #include "ShooterMsgType.h"
#include "../3dzavr/engine/animation/Animations.h" #include "../3dzavr/engine/animation/Animations.h"
#include "../3dzavr/engine/utils/EventHandler.h"
ShooterClient::ShooterClient(std::shared_ptr<Player> player) : _player(player) {
EventHandler::listen<void(const std::string&)>(
Event("take_bonus"),
[this](const std::string& name){ this->takeBonus(name); }
);
EventHandler::listen<void(sf::Uint16, double)>(
Event("damage_player"),
[this](sf::Uint16 targetId, double damage) { damagePlayer(targetId, damage); } );
EventHandler::listen<void(const Vec3D&, const Vec3D&)>(
Event("your_bullet"),
[this](const Vec3D &from, const Vec3D &to) {
sendTrace(from, to);
});
EventHandler::listen<void(const std::string&)>(
Event("change_weapon"),
[this](const std::string &name){ changeWeapon(name); }
);
}
void ShooterClient::updatePacket() { void ShooterClient::updatePacket() {
sf::Packet packet; sf::Packet packet;
@ -26,9 +50,8 @@ void ShooterClient::processInit(sf::Packet &packet) {
while (packet >> targetId >> x >> y >> z >> health >> kills >> deaths) { while (packet >> targetId >> x >> y >> z >> health >> kills >> deaths) {
if (targetId != _socket.ownId()) { if (targetId != _socket.ownId()) {
if (_spawnPlayerCallBack != nullptr) { EventHandler::call<void(sf::Uint16)>(Event("spawn_player"), targetId);
_spawnPlayerCallBack(targetId);
}
_players[targetId]->translateToPoint(Vec3D{x, y, z}); _players[targetId]->translateToPoint(Vec3D{x, y, z});
_players[targetId]->setHealth(health); _players[targetId]->setHealth(health);
_players[targetId]->setKills(kills); _players[targetId]->setKills(kills);
@ -110,15 +133,13 @@ void ShooterClient::processNewClient(sf::Packet &packet) {
packet >> targetId; packet >> targetId;
if (_spawnPlayerCallBack != nullptr) { EventHandler::call<void(sf::Uint16)>(Event("spawn_player"), targetId);
_spawnPlayerCallBack(targetId);
}
} }
void ShooterClient::processDisconnect(sf::Uint16 targetId) { void ShooterClient::processDisconnect(sf::Uint16 targetId) {
if (targetId != _socket.ownId() && _players.count(targetId)) { if (targetId != _socket.ownId() && _players.count(targetId)) {
_players.erase(targetId); _players.erase(targetId);
_removePlayerCallBack(targetId); EventHandler::call<void(sf::Uint16)>(Event("remove_player"), targetId);
} }
} }
@ -131,7 +152,8 @@ void ShooterClient::sendMessage(string message){
packet << MsgType::Custom << ShooterMsgType::newMessage << message; packet << MsgType::Custom << ShooterMsgType::newMessage << message;
_socket.send(packet, _socket.serverId()); _socket.send(packet, _socket.serverId());
} }
void ShooterClient::newMessage(string message, string name) {
void ShooterClient::sendChatMessage(string message, string name) {
chatManager->addNewMessage(name, message); chatManager->addNewMessage(name, message);
} }
@ -204,45 +226,45 @@ void ShooterClient::processCustomPacket(sf::Packet &packet) {
} }
break; break;
case ShooterMsgType::FireTrace: case ShooterMsgType::FireTrace:
if (buffId[0] != _socket.ownId()) {
packet >> dbuff[0] >> dbuff[1] >> dbuff[2] >> dbuff[3] >> dbuff[4] >> dbuff[5]; packet >> dbuff[0] >> dbuff[1] >> dbuff[2] >> dbuff[3] >> dbuff[4] >> dbuff[5];
if (_addFireTraceCallBack != nullptr) { EventHandler::call<void(const Vec3D&, const Vec3D&)>(
_addFireTraceCallBack(Vec3D(dbuff[0], dbuff[1], dbuff[2]), Vec3D(dbuff[3], dbuff[4], dbuff[5])); Event("enemy_bullet"),
Vec3D(dbuff[0], dbuff[1], dbuff[2]), Vec3D(dbuff[3], dbuff[4], dbuff[5]));
} }
break; break;
case ShooterMsgType::InitBonuses: case ShooterMsgType::InitBonuses:
while (packet >> tmp >> dbuff[0] >> dbuff[1] >> dbuff[2]) { while (packet >> tmp >> dbuff[0] >> dbuff[1] >> dbuff[2]) {
if (_addBonusCallBack != nullptr) { EventHandler::call<void(const string&, const Vec3D&)>(
_addBonusCallBack(tmp, Vec3D(dbuff[0], dbuff[1], dbuff[2])); Event("add_bonus"), tmp, Vec3D(dbuff[0], dbuff[1], dbuff[2]));
}
} }
break; break;
case ShooterMsgType::AddBonus: case ShooterMsgType::AddBonus:
packet >> tmp >> dbuff[0] >> dbuff[1] >> dbuff[2]; packet >> tmp >> dbuff[0] >> dbuff[1] >> dbuff[2];
if (_addBonusCallBack != nullptr) { EventHandler::call<void(const string&, const Vec3D&)>(
_addBonusCallBack(tmp, Vec3D(dbuff[0], dbuff[1], dbuff[2])); Event("add_bonus"), tmp, Vec3D(dbuff[0], dbuff[1], dbuff[2]));
}
break; break;
case ShooterMsgType::RemoveBonus: case ShooterMsgType::RemoveBonus:
packet >> tmp; packet >> tmp;
if (_removeBonusCallBack != nullptr) { EventHandler::call<void(const ObjectNameTag &)>(
_removeBonusCallBack(ObjectNameTag(tmp)); Event("remove_bonus"), ObjectNameTag(tmp));
}
break; break;
case ShooterMsgType::ChangeWeapon: case ShooterMsgType::ChangeWeapon:
packet >> buffId[0] >> tmp; packet >> buffId[0] >> tmp;
if (_changeEnemyWeaponCallBack != nullptr) { EventHandler::call<void(const std::string&, sf::Uint16)>(
_changeEnemyWeaponCallBack(tmp, buffId[0]); Event("change_enemy_weapon"), tmp, buffId[0]);
}
break; break;
case ShooterMsgType::newMessage: case ShooterMsgType::newMessage:
packet >> name >> message; packet >> name >> message;
newMessage(message, name); sendChatMessage(message, name);
break; break;
default: default:
Log::log("ShooterClient::processCustomPacket: unknown message type " + Log::log("ShooterClient::processCustomPacket: unknown message type " +
@ -266,7 +288,7 @@ void ShooterClient::damagePlayer(sf::Uint16 targetId, double damage) {
Log::log("ShooterClient: damagePlayer " + std::to_string(targetId) + " ( -" + std::to_string(damage) + "hp )"); Log::log("ShooterClient: damagePlayer " + std::to_string(targetId) + " ( -" + std::to_string(damage) + "hp )");
} }
void ShooterClient::addTrace(const Vec3D &from, const Vec3D &to) { void ShooterClient::sendTrace(const Vec3D &from, const Vec3D &to) {
sf::Packet packet; sf::Packet packet;
packet << MsgType::Custom << ShooterMsgType::FireTrace << from.x() << from.y() << from.z() << to.x() << to.y() packet << MsgType::Custom << ShooterMsgType::FireTrace << from.x() << from.y() << from.z() << to.x() << to.y()
@ -280,9 +302,8 @@ void ShooterClient::takeBonus(const std::string &bonusName) {
packet << MsgType::Custom << ShooterMsgType::RemoveBonus << bonusName; packet << MsgType::Custom << ShooterMsgType::RemoveBonus << bonusName;
_socket.sendRely(packet, _socket.serverId()); _socket.sendRely(packet, _socket.serverId());
if (_removeBonusCallBack != nullptr) { EventHandler::call<void(const ObjectNameTag &)>(
_removeBonusCallBack(ObjectNameTag(bonusName)); Event("remove_bonus"), ObjectNameTag(bonusName));
}
} }
void ShooterClient::changeWeapon(const std::string &weaponName) { void ShooterClient::changeWeapon(const std::string &weaponName) {
@ -296,31 +317,6 @@ void ShooterClient::addPlayer(sf::Uint16 id, std::shared_ptr<Player> player) {
_players.insert({id, player}); _players.insert({id, player});
} }
void ShooterClient::setSpawnPlayerCallBack(std::function<void(sf::Uint16)> spawn) {
_spawnPlayerCallBack = std::move(spawn);
}
void ShooterClient::setRemovePlayerCallBack(std::function<void(sf::Uint16)> remove) {
_removePlayerCallBack = std::move(remove);
}
void ShooterClient::setAddFireTraceCallBack(std::function<void(const Vec3D &, const Vec3D &)> addTrace) {
_addFireTraceCallBack = std::move(addTrace);
}
void ShooterClient::setAddBonusCallBack(std::function<void(const std::string &, const Vec3D &)> addBonus) {
_addBonusCallBack = std::move(addBonus);
}
void ShooterClient::setRemoveBonusCallBack(std::function<void(const ObjectNameTag &)> removeBonus) {
_removeBonusCallBack = std::move(removeBonus);
}
void
ShooterClient::setChangeEnemyWeaponCallBack(std::function<void(const std::string &, sf::Uint16)> changeEnemyWeapon) {
_changeEnemyWeaponCallBack = std::move(changeEnemyWeapon);
}
void ShooterClient::requestMap(const std::string& clientIp, std::string *current_map) { void ShooterClient::requestMap(const std::string& clientIp, std::string *current_map) {
Log::log("---------[FTP server]---------"); Log::log("---------[FTP server]---------");
sf::Ftp ftp; sf::Ftp ftp;

View File

@ -17,35 +17,25 @@ private:
std::map<sf::Uint16, std::shared_ptr<Player>> _players{}; std::map<sf::Uint16, std::shared_ptr<Player>> _players{};
std::shared_ptr<Player> _player; std::shared_ptr<Player> _player;
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;
std::shared_ptr<ChatManager> chatManager; std::shared_ptr<ChatManager> chatManager;
void damagePlayer(sf::Uint16 targetId, double damage);
void takeBonus(const std::string &bonusName);
void sendTrace(const Vec3D &from, const Vec3D &to);
void changeWeapon(const std::string &weaponName);
public: public:
explicit ShooterClient(std::shared_ptr<Player> player) : _player(player) {}; explicit ShooterClient(std::shared_ptr<Player> player);
void sendMessage(std::string message); void sendMessage(std::string message);
void newMessage(std::string message, std::string name); void sendChatMessage(std::string message, std::string name);
void updatePacket() override; void updatePacket() override;
void setSpawnPlayerCallBack(std::function<void(sf::Uint16)> spawn);
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 ObjectNameTag &)> removeBonus);
void setChangeEnemyWeaponCallBack(std::function<void(const std::string &, sf::Uint16)> changeEnemyWeapon);
void processInit(sf::Packet &packet) override; void processInit(sf::Packet &packet) override;
void processUpdate(sf::Packet &packet) override; void processUpdate(sf::Packet &packet) override;
@ -58,14 +48,6 @@ public:
void processDisconnected() override; void processDisconnected() override;
void damagePlayer(sf::Uint16 targetId, double damage);
void takeBonus(const std::string &bonusName);
void addTrace(const Vec3D &from, const Vec3D &to);
void changeWeapon(const std::string &weaponName);
void setChatManager(std::shared_ptr<ChatManager> chat) { chatManager = chat; }; void setChatManager(std::shared_ptr<ChatManager> chat) { chatManager = chat; };
void addPlayer(sf::Uint16 id, std::shared_ptr<Player> player); void addPlayer(sf::Uint16 id, std::shared_ptr<Player> player);

View File

@ -8,6 +8,8 @@
#include "../3dzavr/engine/io/Screen.h" #include "../3dzavr/engine/io/Screen.h"
#include "../3dzavr/engine/utils/Log.h" #include "../3dzavr/engine/utils/Log.h"
#include "../3dzavr/engine/animation/Animations.h" #include "../3dzavr/engine/animation/Animations.h"
#include "../3dzavr/engine/utils/EventHandler.h"
Player::Player(ObjectNameTag name, const std::string &filename, const Vec3D &scale) : RigidBody(std::move(name), filename, scale) { Player::Player(ObjectNameTag name, const std::string &filename, const Vec3D &scale) : RigidBody(std::move(name), filename, scale) {
setAcceleration(Vec3D{0, -ShooterConsts::GRAVITY, 0}); setAcceleration(Vec3D{0, -ShooterConsts::GRAVITY, 0});
@ -54,9 +56,7 @@ void Player::collisionWithObject(const ObjectNameTag &tag, std::shared_ptr<Rigid
} }
if (tag.str().find("Bonus") != std::string::npos) { if (tag.str().find("Bonus") != std::string::npos) {
if (_takeBonusCallBack != nullptr) { EventHandler::call<void(const std::string&)>(Event("take_bonus"), tag.str());
_takeBonusCallBack(tag.str());
}
} }
} }
@ -76,38 +76,6 @@ void Player::addWeapon(std::shared_ptr<Weapon> weapon) {
_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());
_weapons.back()->rotateRelativePoint(position() + Vec3D{0, 1.8, 0}, left(), headAngle()); _weapons.back()->rotateRelativePoint(position() + Vec3D{0, 1.8, 0}, left(), headAngle());
// add animation of reloading
_weapons.back()->setReloadCallBack([this]() {
Timeline::addAnimation<ARotateLeft>(AnimationListTag("reload_weapon"),
_weapons[_selectedWeapon],
-2 * Consts::PI,
_weapons[_selectedWeapon]->reloadTime() / 2,
Animation::LoopOut::None,
Animation::InterpolationType::Cos);
});
// adding fire animation
_weapons.back()->setFireCallBack([this]() {
Timeline::addAnimation<ARotateLeft>(AnimationListTag("fire_weapon"),
_weapons[_selectedWeapon],
-_weapons[_selectedWeapon]->fireDelay(),
_weapons[_selectedWeapon]->fireDelay()/3,
Animation::LoopOut::None,
Animation::InterpolationType::Cos);
Timeline::addAnimation<AWait>(AnimationListTag("fire_weapon"), 0);
Timeline::addAnimation<ARotateLeft>(AnimationListTag("fire_weapon"),
_weapons[_selectedWeapon],
_weapons[_selectedWeapon]->fireDelay(),
_weapons[_selectedWeapon]->fireDelay()/3,
Animation::LoopOut::None,
Animation::InterpolationType::Cos);
});
// add call back function to create fire traces
if (_addTraceCallBack != nullptr) {
_weapons.back()->setAddTraceCallBack(_addTraceCallBack);
}
} }
void Player::reInitWeapons() { void Player::reInitWeapons() {
@ -117,34 +85,33 @@ void Player::reInitWeapons() {
unattach(ObjectNameTag(weapon->name())); unattach(ObjectNameTag(weapon->name()));
} }
if (_removeWeaponCallBack != nullptr) { EventHandler::call<void(std::shared_ptr<Weapon>)>(Event("remove_weapon"),
_removeWeaponCallBack(_weapons[_selectedWeapon]); _weapons[_selectedWeapon]);
}
_weapons.clear(); _weapons.clear();
} }
_selectedWeapon = 0; _selectedWeapon = 0;
addWeapon(std::make_shared<Gun>()); addWeapon(std::make_shared<Gun>());
if (_addWeaponCallBack != nullptr) {
_addWeaponCallBack(_weapons[_selectedWeapon]); EventHandler::call<void(std::shared_ptr<Weapon>)>(Event("add_weapon"),
} _weapons[_selectedWeapon]);
} }
void Player::selectNextWeapon() { void Player::selectNextWeapon() {
if (_weapons.size() > 1) { if (_weapons.size() > 1) {
// change '_selectedWeapon' // change '_selectedWeapon'
if (_removeWeaponCallBack != nullptr) { EventHandler::call<void(std::shared_ptr<Weapon>)>(Event("remove_weapon"),
_removeWeaponCallBack(_weapons[_selectedWeapon]); _weapons[_selectedWeapon]);
}
_selectedWeapon = (_selectedWeapon + 1) % _weapons.size(); _selectedWeapon = (_selectedWeapon + 1) % _weapons.size();
if (_addWeaponCallBack != nullptr) { EventHandler::call<void(std::shared_ptr<Weapon>)>(Event("add_weapon"),
_addWeaponCallBack(_weapons[_selectedWeapon]); _weapons[_selectedWeapon]);
}
Log::log("selectedWeapon " + std::to_string(_selectedWeapon)); Log::log("selectedWeapon " + std::to_string(_selectedWeapon));
SoundController::loadAndPlay(SoundTag("changeWeapon"), ShooterConsts::CHANGE_WEAPON_SOUND); SoundController::loadAndPlay(SoundTag("changeWeapon"), ShooterConsts::CHANGE_WEAPON_SOUND);
rotateWeapon(); selectWeaponAnimation();
} }
} }
@ -152,20 +119,21 @@ void Player::selectNextWeapon() {
void Player::selectPreviousWeapon() { void Player::selectPreviousWeapon() {
if (_weapons.size() > 1) { if (_weapons.size() > 1) {
// change '_selectedWeapon' // change '_selectedWeapon'
if (_removeWeaponCallBack != nullptr) { EventHandler::call<void(std::shared_ptr<Weapon>)>(Event("remove_weapon"),
_removeWeaponCallBack(_weapons[_selectedWeapon]); _weapons[_selectedWeapon]);
}
if (_selectedWeapon > 0) { if (_selectedWeapon > 0) {
_selectedWeapon = (_selectedWeapon - 1) % _weapons.size(); _selectedWeapon = (_selectedWeapon - 1) % _weapons.size();
} else { } else {
_selectedWeapon = _weapons.size() - 1; _selectedWeapon = _weapons.size() - 1;
} }
if (_addWeaponCallBack != nullptr) {
_addWeaponCallBack(_weapons[_selectedWeapon]); EventHandler::call<void(std::shared_ptr<Weapon>)>(Event("add_weapon"),
} _weapons[_selectedWeapon]);
Log::log("selectedWeapon " + std::to_string(_selectedWeapon)); Log::log("selectedWeapon " + std::to_string(_selectedWeapon));
SoundController::loadAndPlay(SoundTag("changeWeapon"), ShooterConsts::CHANGE_WEAPON_SOUND); SoundController::loadAndPlay(SoundTag("changeWeapon"), ShooterConsts::CHANGE_WEAPON_SOUND);
rotateWeapon(); selectWeaponAnimation();
} }
} }
@ -175,9 +143,7 @@ bool Player::fire() {
auto fireInfo = _weapons[_selectedWeapon]->fire(_rayCastFunction, camera->position(), camera->lookAt()); auto fireInfo = _weapons[_selectedWeapon]->fire(_rayCastFunction, camera->position(), camera->lookAt());
for (auto&[damagedPlayerName, damage] : fireInfo.damagedPlayers) { for (auto&[damagedPlayerName, damage] : fireInfo.damagedPlayers) {
sf::Uint16 targetId = std::stoi(damagedPlayerName.str().substr(6)); sf::Uint16 targetId = std::stoi(damagedPlayerName.str().substr(6));
if (_damagePlayerCallBack != nullptr) { EventHandler::call<void(sf::Uint16, double)>(Event("damage_player"), targetId, damage);
_damagePlayerCallBack(targetId, damage);
}
} }
return fireInfo.shot; return fireInfo.shot;
} }
@ -198,7 +164,7 @@ void Player::setFullAbility() {
SoundController::loadAndPlay(SoundTag("addAbility"), ShooterConsts::RESTORE_ABILITY_SOUND); SoundController::loadAndPlay(SoundTag("addAbility"), ShooterConsts::RESTORE_ABILITY_SOUND);
} }
void Player::rotateWeapon() { void Player::selectWeaponAnimation() {
Timeline::addAnimation<ARotateLeft>(AnimationListTag("select_weapon"), Timeline::addAnimation<ARotateLeft>(AnimationListTag("select_weapon"),
_weapons[_selectedWeapon], _weapons[_selectedWeapon],
-2 * Consts::PI, -2 * Consts::PI,
@ -206,3 +172,28 @@ void Player::rotateWeapon() {
Animation::LoopOut::None, Animation::LoopOut::None,
Animation::InterpolationType::Cos); Animation::InterpolationType::Cos);
} }
void Player::fireWeaponAnimation() {
Timeline::addAnimation<ARotateLeft>(AnimationListTag("fire_weapon"),
_weapons[_selectedWeapon],
-_weapons[_selectedWeapon]->fireDelay(),
_weapons[_selectedWeapon]->fireDelay()/3,
Animation::LoopOut::None,
Animation::InterpolationType::Cos);
Timeline::addAnimation<AWait>(AnimationListTag("fire_weapon"), 0);
Timeline::addAnimation<ARotateLeft>(AnimationListTag("fire_weapon"),
_weapons[_selectedWeapon],
_weapons[_selectedWeapon]->fireDelay(),
_weapons[_selectedWeapon]->fireDelay()/3,
Animation::LoopOut::None,
Animation::InterpolationType::Cos);
}
void Player::reloadWeaponAnimation() {
Timeline::addAnimation<ARotateLeft>(AnimationListTag("reload_weapon"),
_weapons[_selectedWeapon],
-2 * Consts::PI,
_weapons[_selectedWeapon]->reloadTime() / 2,
Animation::LoopOut::None,
Animation::InterpolationType::Cos);
}

View File

@ -33,17 +33,10 @@ private:
std::string _nickName = ShooterConsts::PLAYER_NAME; std::string _nickName = ShooterConsts::PLAYER_NAME;
std::function<void(sf::Uint16 targetId, double)> _damagePlayerCallBack;
std::function<void(const Vec3D &, const Vec3D &)> _addTraceCallBack;
std::function<void(const std::string &)> _takeBonusCallBack;
std::function<void(std::shared_ptr<Weapon>)> _addWeaponCallBack;
std::function<void(std::shared_ptr<Weapon>)> _removeWeaponCallBack;
std::function<IntersectionInformation(const Vec3D &, const Vec3D &)> _rayCastFunction; std::function<IntersectionInformation(const Vec3D &, const Vec3D &)> _rayCastFunction;
void collisionWithObject(const ObjectNameTag &tag, std::shared_ptr<RigidBody> obj); void collisionWithObject(const ObjectNameTag &tag, std::shared_ptr<RigidBody> obj);
void rotateWeapon();
public: public:
explicit Player(ObjectNameTag name, const std::string &filename = ShooterConsts::CUBE_OBJ, const Vec3D &scale = Vec3D{1, 1, 1}); explicit Player(ObjectNameTag name, const std::string &filename = ShooterConsts::CUBE_OBJ, const Vec3D &scale = Vec3D{1, 1, 1});
@ -55,7 +48,6 @@ public:
[[nodiscard]] double ability() const { return _ability; } [[nodiscard]] double ability() const { return _ability; }
void setFullHealth(); void setFullHealth();
void setFullAbility(); void setFullAbility();
@ -88,26 +80,6 @@ public:
void setDeaths(int deaths) { _deaths = deaths; } void setDeaths(int deaths) { _deaths = deaths; }
void setDamagePlayerCallBack(std::function<void(sf::Uint16 targetId, double)> hit) {
_damagePlayerCallBack = std::move(hit);
}
void setAddTraceCallBack(std::function<void(const Vec3D &, const Vec3D &)> add) {
_addTraceCallBack = std::move(add);
}
void setTakeBonusCallBack(std::function<void(const std::string &)> take) {
_takeBonusCallBack = std::move(take);
}
void setAddWeaponCallBack(std::function<void(std::shared_ptr<Weapon>)> addWeapon) {
_addWeaponCallBack = std::move(addWeapon);
}
void setRemoveWeaponCallBack(std::function<void(std::shared_ptr<Weapon>)> removeWeapon) {
_removeWeaponCallBack = std::move(removeWeapon);
}
void setRayCastFunction(std::function<IntersectionInformation(const Vec3D &, const Vec3D &)> rayCastFunction) { void setRayCastFunction(std::function<IntersectionInformation(const Vec3D &, const Vec3D &)> rayCastFunction) {
_rayCastFunction = std::move(rayCastFunction); _rayCastFunction = std::move(rayCastFunction);
} }
@ -120,6 +92,12 @@ public:
[[nodiscard]] std::string playerNickName() const { return _nickName; } [[nodiscard]] std::string playerNickName() const { return _nickName; }
void setPlayerNickName(const std::string &name) { _nickName = name; } void setPlayerNickName(const std::string &name) { _nickName = name; }
void selectWeaponAnimation();
void fireWeaponAnimation();
void reloadWeaponAnimation();
}; };

View File

@ -2,6 +2,8 @@
// Created by Иван Ильин on 19.09.2021. // Created by Иван Ильин on 19.09.2021.
// //
#include <cmath>
#include "PlayerController.h" #include "PlayerController.h"
#include "../3dzavr/engine/utils/Log.h" #include "../3dzavr/engine/utils/Log.h"
#include "../3dzavr/engine/animation/Animations.h" #include "../3dzavr/engine/animation/Animations.h"

View File

@ -6,6 +6,7 @@
#include "../3dzavr/engine/utils/ResourceManager.h" #include "../3dzavr/engine/utils/ResourceManager.h"
#include "../3dzavr/engine/utils/Log.h" #include "../3dzavr/engine/utils/Log.h"
#include "../ShooterConsts.h" #include "../ShooterConsts.h"
#include "../3dzavr/engine/utils/EventHandler.h"
using namespace std; using namespace std;
@ -46,9 +47,7 @@ FireInformation Weapon::fire(std::function<IntersectionInformation(const Vec3D &
SoundController::loadAndPlay(SoundTag("fireSound_" + name().str()), _fireSound); SoundController::loadAndPlay(SoundTag("fireSound_" + name().str()), _fireSound);
Log::log("Weapon::fire (" + std::to_string(_stockAmmo) + " : " + std::to_string(_clipAmmo) + ")"); Log::log("Weapon::fire (" + std::to_string(_stockAmmo) + " : " + std::to_string(_clipAmmo) + ")");
if (_fireCallBack != nullptr) { EventHandler::call<void()>(Event("fire"));
_fireCallBack();
}
return FireInformation{processFire(std::move(rayCastFunction), position, direction), true}; return FireInformation{processFire(std::move(rayCastFunction), position, direction), true};
} }
@ -69,9 +68,7 @@ void Weapon::reload() {
Log::log("Weapon::reload (" + std::to_string(_stockAmmo) + " : " + std::to_string(_clipAmmo) + ")"); Log::log("Weapon::reload (" + std::to_string(_stockAmmo) + " : " + std::to_string(_clipAmmo) + ")");
_lastReloadTime = Time::time(); _lastReloadTime = Time::time();
if (_reloadCallBack != nullptr) { EventHandler::call<void()>(Event("reload_weapon"));
_reloadCallBack();
}
} }
std::map<ObjectNameTag, double> std::map<ObjectNameTag, double>
@ -116,7 +113,8 @@ Weapon::fireABullet(std::function<IntersectionInformation(const Vec3D &, const V
Vec3D lineTo = rayCast.intersected ? rayCast.pointOfIntersection : position() + Vec3D lineTo = rayCast.intersected ? rayCast.pointOfIntersection : position() +
direction * ShooterConsts::FIRE_DISTANCE + direction * ShooterConsts::FIRE_DISTANCE +
randV; randV;
_addTraceCallBack(lineFrom, lineTo);
EventHandler::call<void(const Vec3D&, const Vec3D&)>(Event("your_bullet"), lineFrom, lineTo);
return damagedPlayers; return damagedPlayers;
} }

View File

@ -37,10 +37,6 @@ private:
double _lastFireTime = std::numeric_limits<double>::min(); double _lastFireTime = std::numeric_limits<double>::min();
double _lastReloadTime = std::numeric_limits<double>::min(); double _lastReloadTime = std::numeric_limits<double>::min();
std::function<void(const Vec3D &, const Vec3D &)> _addTraceCallBack;
std::function<void()> _reloadCallBack;
std::function<void()> _fireCallBack;
protected: protected:
std::map<ObjectNameTag, double> std::map<ObjectNameTag, double>
fireABullet(std::function<IntersectionInformation(const Vec3D &, const Vec3D &)> rayCastFunction, fireABullet(std::function<IntersectionInformation(const Vec3D &, const Vec3D &)> rayCastFunction,
@ -65,11 +61,6 @@ public:
[[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); }
void setAddTraceCallBack(std::function<void(Vec3D, Vec3D)> add) { _addTraceCallBack = std::move(add); }
void setReloadCallBack(std::function<void()> reload) { _reloadCallBack = std::move(reload); }
void setFireCallBack(std::function<void()> fire) { _fireCallBack = std::move(fire); }
void addAPack() { _stockAmmo += initialPack(); } void addAPack() { _stockAmmo += initialPack(); }
[[nodiscard]] int initialPack() const { return _initialPack; } [[nodiscard]] int initialPack() const { return _initialPack; }