2 Commits

Author SHA1 Message Date
784c558840 chore: bump version to "alpha-0.2.0" 2021-12-19 18:40:44 +01:00
5d366b6f6c feat: sync game 2021-12-19 18:40:14 +01:00
12 changed files with 143 additions and 5 deletions

View File

@@ -111,11 +111,13 @@ public:
virtual bool OnDeath(World* world) { return true; }
MobID getMobID() const { return m_ID; }
const TowerImmunities& getTowerImmunities() const { return getMobTowerImmunities(getType(), m_Level); }
const EffectImmunities& getEffectImmunities() const { return getMobEffectImmunities(getType(), m_Level); }
PlayerID getSender() const { return m_Sender; }
MobLevel getLevel() const { return m_Level; }
const MobStats* getStats() const { return getMobStats(getType(), m_Level); }
void setHealth(float newHealth) { m_Health = newHealth; }
float getHealth() const { return m_Health; }
bool isDead() const { return m_Health <= 0; }
bool isAlive() const { return m_Health > 0; }

View File

@@ -20,6 +20,8 @@ public:
virtual void HandlePacket(const protocol::UpgradeTowerPacket* packet);
virtual void HandlePacket(const protocol::WorldAddTowerPacket* packet);
virtual void HandlePacket(const protocol::RemoveTowerPacket* packet);
virtual void HandlePacket(const protocol::UpdateMobStatesPacket* packet);
virtual void HandlePacket(const protocol::UpdateCastleLifePacket* packet);
};

View File

@@ -13,8 +13,9 @@ class ServerGame : public game::Game, public game::GameListener {
private:
Server* m_Server;
ServerWorld m_ServerWorld;
utils::AutoTimer m_GoldMineTimer{ 1000, std::bind(&ServerGame::updateGoldMines, this) };
utils::CooldownTimer m_EndGameCooldown{ 1000 * 10 };
utils::AutoTimer m_GoldMineTimer;
utils::AutoTimer m_MobStatesTimer;
utils::CooldownTimer m_EndGameCooldown;
public:
ServerGame(Server* server);
~ServerGame() {}
@@ -32,6 +33,7 @@ public:
virtual void OnGameClose();
private:
void balanceTeams();
void updateMobStates();
void updateGoldMines();
void updatePlayerStats();
};

View File

@@ -23,6 +23,8 @@ public:
virtual void OnMobDie(game::Mob* mob);
virtual void OnMobCastleDamage(game::Mob* damager, game::TeamCastle* enemyCastle, float damage);
};
} // namespace server

View File

@@ -38,6 +38,8 @@ public:
virtual void HandlePacket(const RemoveTowerPacket* packet) {}
virtual void HandlePacket(const SendMobsPacket* packet) {}
virtual void HandlePacket(const UpgradeTowerPacket* packet) {}
virtual void HandlePacket(const UpdateMobStatesPacket* packet) {}
virtual void HandlePacket(const UpdateCastleLifePacket* packet) {}
};
} // namespace protocol

View File

@@ -33,6 +33,8 @@ enum class PacketType : std::uint8_t {
UpdatePlayerTeam,
ServerTps,
WorldAddTower,
UpdateMobStates,
UpdateCastleLife,
// client <--> server
KeepAlive,
@@ -515,5 +517,60 @@ public:
virtual PacketType getType() const { return PacketType::UpgradeTower; }
};
class MobState {
using Point = utils::shape::Point;
private:
game::MobID m_MobID;
Point m_MobPosition;
float m_MobLife;
game::Direction m_MobDirection;
public:
MobState() {}
MobState(game::MobID id, Point position, float life, game::Direction direction) :
m_MobID(id), m_MobPosition(position), m_MobLife(life), m_MobDirection(direction) {}
game::MobID getMobId() const { return m_MobID; }
Point getMobPosition() const { return m_MobPosition; }
float getMobLife() const { return m_MobLife; }
game::Direction getMobDirection() const { return m_MobDirection; }
};
class UpdateMobStatesPacket : public Packet {
private:
std::vector<MobState> m_MobStates;
public:
UpdateMobStatesPacket() {}
virtual ~UpdateMobStatesPacket() {}
virtual DataBuffer Serialize() const;
virtual void Deserialize(DataBuffer& data);
virtual void Dispatch(PacketHandler* handler) const;
void addMobState(MobState mobState) { m_MobStates.push_back(mobState); }
const std::vector<MobState>& getMobStates() const { return m_MobStates; }
virtual PacketType getType() const { return PacketType::UpdateMobStates; }
};
class UpdateCastleLifePacket : public Packet {
private:
std::uint16_t m_CastleLife;
game::TeamColor m_Team;
public:
UpdateCastleLifePacket() {}
UpdateCastleLifePacket(std::uint16_t life, game::TeamColor team) : m_CastleLife(life), m_Team(team) {}
virtual ~UpdateCastleLifePacket() {}
virtual DataBuffer Serialize() const;
virtual void Deserialize(DataBuffer& data);
virtual void Dispatch(PacketHandler* handler) const;
std::uint16_t getCastleLife() const { return m_CastleLife; }
game::TeamColor getTeamColor() const { return m_Team; }
virtual PacketType getType() const { return PacketType::UpdateCastleLife; }
};
}
}

View File

@@ -2,7 +2,7 @@
#include "misc/DataBuffer.h"
#define TD_VERSION "alpha-0.1.2"
#define TD_VERSION "alpha-0.2.0"
namespace td {
namespace utils {

View File

@@ -13,13 +13,15 @@ WorldClient::WorldClient(ClientGame* game) : game::World(game), protocol::Packet
GetDispatcher()->RegisterHandler(protocol::PacketType::SpawnMob, this);
GetDispatcher()->RegisterHandler(protocol::PacketType::UpgradeTower, this);
GetDispatcher()->RegisterHandler(protocol::PacketType::RemoveTower, this);
GetDispatcher()->RegisterHandler(protocol::PacketType::UpdateCastleLife, this);
GetDispatcher()->RegisterHandler(protocol::PacketType::UpdateMobStates, this);
}
void WorldClient::HandlePacket(const protocol::WorldBeginDataPacket* packet) {
loadMap(packet);
if (m_Game->getGameState() == game::GameState::Game) {
const game::Color& backgroundColor = getBackgroundColor();
m_Game->getRenderer()->setBackgroundColor({ static_cast<float>(backgroundColor.r / 255.0f), static_cast<float>(backgroundColor.g / 255.0f),
m_Game->getRenderer()->setBackgroundColor({ static_cast<float>(backgroundColor.r / 255.0f), static_cast<float>(backgroundColor.g / 255.0f),
static_cast<float>(backgroundColor.b / 255.0f) });
}
}
@@ -53,5 +55,22 @@ void WorldClient::HandlePacket(const protocol::RemoveTowerPacket* packet) {
}
}
void WorldClient::HandlePacket(const protocol::UpdateMobStatesPacket* packet) {
for (auto mobState : packet->getMobStates()) {
game::MobID mobId = mobState.getMobId();
auto it = std::find_if(getMobList().begin(), getMobList().end(), [mobId](game::MobPtr mob) { return mob->getMobID() == mobId; });
if (it != getMobList().end()) {
game::MobPtr& mob = *it;
mob->setCenter(mobState.getMobPosition());
mob->setDirection(mobState.getMobDirection());
mob->setHealth(mobState.getMobLife());
}
}
}
void WorldClient::HandlePacket(const protocol::UpdateCastleLifePacket* packet) {
getTeam(packet->getTeamColor()).getCastle().setLife(packet->getCastleLife());
}
} // namespace client
} // namespace td

View File

@@ -4,13 +4,17 @@
namespace td {
namespace server {
ServerGame::ServerGame(server::Server* server) : game::Game(&m_ServerWorld), m_Server(server), m_ServerWorld(server, this) {
ServerGame::ServerGame(server::Server* server) : game::Game(&m_ServerWorld), m_Server(server), m_ServerWorld(server, this),
m_GoldMineTimer{ 1000, std::bind(&ServerGame::updateGoldMines, this) },
m_MobStatesTimer{ 5000, std::bind(&ServerGame::updateMobStates, this) },
m_EndGameCooldown{ 1000 * 10 } {
bindListener(this);
}
void ServerGame::tick(std::uint64_t delta) {
if (m_GameState == game::GameState::Game) {
Game::tick(delta);
m_MobStatesTimer.update(delta);
updatePlayerStats();
} else if (m_GameState == game::GameState::EndGame) {
if (m_EndGameCooldown.update(delta)) {
@@ -55,6 +59,14 @@ void ServerGame::updateGoldMines() {
}
}
void ServerGame::updateMobStates() {
protocol::UpdateMobStatesPacket packet;
for (auto mob : m_World->getMobList()) {
packet.addMobState({ mob->getMobID(), mob->getCenter(), mob->getHealth(), mob->getDirection() });
}
m_Server->broadcastPacket(&packet);
}
void ServerGame::balanceTeams() {
for (auto& playerInfo : Game::m_Players) {
game::Player& player = playerInfo.second;

View File

@@ -66,5 +66,13 @@ void ServerWorld::OnMobDie(game::Mob* mob) {
}
}
void ServerWorld::OnMobCastleDamage(game::Mob* damager, game::TeamCastle* enemyCastle, float damage) {
// calling base class event
World::OnMobCastleDamage(damager, enemyCastle, damage);
protocol::UpdateCastleLifePacket packet(enemyCastle->getLife(), enemyCastle->getTeam()->getColor());
m_Server->broadcastPacket(&packet);
}
} // namespace server
} // namespace td

View File

@@ -31,6 +31,8 @@ static std::map<PacketType, PacketCreator> packets = {
{PacketType::RemoveTower, []() -> PacketPtr {return std::make_unique<RemoveTowerPacket>(); } },
{PacketType::SendMobs, []() -> PacketPtr {return std::make_unique<SendMobsPacket>(); } },
{PacketType::UpgradeTower, []() -> PacketPtr {return std::make_unique<UpgradeTowerPacket>(); } },
{PacketType::UpdateCastleLife, []() -> PacketPtr {return std::make_unique<UpdateCastleLifePacket>(); } },
{PacketType::UpdateMobStates, []() -> PacketPtr {return std::make_unique<UpdateMobStatesPacket>(); } },
};
PacketPtr createPacket(PacketType type, DataBuffer& buffer) {

View File

@@ -535,6 +535,34 @@ void UpgradeTowerPacket::Deserialize(DataBuffer& data) {
data >> m_TowerID >> m_TowerLevel;
}
DataBuffer UpdateCastleLifePacket::Serialize() const {
DataBuffer data;
data << getID() << m_CastleLife << m_Team;
return data;
}
void UpdateCastleLifePacket::Deserialize(DataBuffer& data) {
data >> m_CastleLife >> m_Team;
}
DataBuffer UpdateMobStatesPacket::Serialize() const {
DataBuffer data;
data << getID() << static_cast<std::uint64_t>(m_MobStates.size());
for (auto mobState : m_MobStates) {
data << mobState;
}
return data;
}
void UpdateMobStatesPacket::Deserialize(DataBuffer& data) {
std::uint64_t mobCount;
data >> mobCount;
m_MobStates.resize(mobCount);
for (std::uint64_t mobIndex = 0; mobIndex < mobCount; mobIndex++) {
data >> m_MobStates[mobIndex];
}
}
REGISTER_DISPATCH_CLASS(PlayerLoginPacket);
REGISTER_DISPATCH_CLASS(WorldBeginDataPacket);
REGISTER_DISPATCH_CLASS(WorldDataPacket);
@@ -557,6 +585,8 @@ REGISTER_DISPATCH_CLASS(WorldAddTowerPacket);
REGISTER_DISPATCH_CLASS(RemoveTowerPacket);
REGISTER_DISPATCH_CLASS(SendMobsPacket);
REGISTER_DISPATCH_CLASS(UpgradeTowerPacket);
REGISTER_DISPATCH_CLASS(UpdateCastleLifePacket);
REGISTER_DISPATCH_CLASS(UpdateMobStatesPacket);
} // namespace protocol
} // namespace td