Compare commits
18 Commits
7b8c13612c
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
8d184d1160
|
|||
| 7ddf47a81a | |||
| 7a1db0305d | |||
| 700a2b0c18 | |||
| 398439886b | |||
| 7c4ed3910f | |||
| 90c834cc49 | |||
| d23761dc10 | |||
| 3d8fd2e519 | |||
| 4bd32e8d0b | |||
| 09bba12814 | |||
| bb76e9493f | |||
|
|
808ef7b3f6 | ||
|
|
23938a0cb5 | ||
|
|
5631efcf9e | ||
|
|
8e7b446003 | ||
|
|
51ec035490 | ||
| 1f94ae2586 |
46
.gitea/workflows/linux.yaml
Normal file
46
.gitea/workflows/linux.yaml
Normal file
@@ -0,0 +1,46 @@
|
||||
name: Linux arm64
|
||||
run-name: Build And Test
|
||||
|
||||
on: [push]
|
||||
|
||||
jobs:
|
||||
Build:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Install deps
|
||||
run : |
|
||||
apt update
|
||||
apt install -y libsdl2-dev libglew-dev
|
||||
|
||||
- name: Check out repository code
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Prepare XMake
|
||||
uses: xmake-io/github-action-setup-xmake@v1
|
||||
with:
|
||||
xmake-version: latest
|
||||
actions-cache-folder: '.xmake-cache'
|
||||
actions-cache-key: 'xmake-ubuntu'
|
||||
|
||||
- name: Calc deps hash
|
||||
uses: seepine/hash-files@v1
|
||||
id: get-hash
|
||||
with:
|
||||
patterns: |
|
||||
**/xmake.lua
|
||||
**/xmake/*.lua
|
||||
|
||||
- name: Packages cache
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: ~/.xmake
|
||||
key: ${{ runner.os }}-${{ steps.get-hash.outputs.hash }}
|
||||
|
||||
- name: XMake config
|
||||
run: xmake f -p linux -y --root
|
||||
|
||||
- name: Build
|
||||
run: xmake --root
|
||||
|
||||
- name: Test
|
||||
run: xmake test --root
|
||||
18
README.md
Normal file
18
README.md
Normal file
@@ -0,0 +1,18 @@
|
||||
# TowerDefense
|
||||
|
||||
Unmaintained multiplayer tower defense game prototype
|
||||
(OpenGL + TCP)
|
||||
|
||||
## Screenshots 🖼
|
||||
|
||||
[[screenshots/game.png]]
|
||||
|
||||
## Build ⚙️
|
||||
```
|
||||
xmake
|
||||
```
|
||||
|
||||
## Run 🏃
|
||||
```
|
||||
xmake run
|
||||
```
|
||||
@@ -20,6 +20,7 @@ public:
|
||||
virtual void HandlePacket(const protocol::SpawnMobPacket* packet) override;
|
||||
virtual void HandlePacket(const protocol::UpgradeTowerPacket* packet) override;
|
||||
virtual void HandlePacket(const protocol::WorldAddTowerPacket* packet) override;
|
||||
virtual void HandlePacket(const protocol::RemoveMobPacket* packet) override;
|
||||
virtual void HandlePacket(const protocol::RemoveTowerPacket* packet) override;
|
||||
virtual void HandlePacket(const protocol::UpdateMobStatesPacket* packet) override;
|
||||
virtual void HandlePacket(const protocol::UpdateCastleLifePacket* packet) override;
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
#include "td/misc/DataBuffer.h"
|
||||
|
||||
#define TD_VERSION "alpha-0.3.0"
|
||||
#define TD_VERSION "alpha-0.4.0"
|
||||
|
||||
namespace td {
|
||||
namespace utils {
|
||||
|
||||
@@ -35,6 +35,7 @@ public:
|
||||
virtual void OnGameClose() override;
|
||||
|
||||
virtual void OnPlayerJoin(game::PlayerID id) override;
|
||||
virtual void OnPlayerLeave(game::PlayerID id) override;
|
||||
private:
|
||||
void BalanceTeams();
|
||||
void InitPlayerStats();
|
||||
|
||||
@@ -99,7 +99,7 @@ private:
|
||||
utils::CooldownTimer m_AttackTimer;
|
||||
|
||||
public:
|
||||
Mob(MobID id, MobLevel level, PlayerID sender) : m_Sender(sender), m_Level(level),
|
||||
Mob(MobID id, MobLevel level, PlayerID sender) : m_ID(id), m_Sender(sender), m_Level(level),
|
||||
m_HitCooldown(0), m_EffectFireTimer(1000), m_EffectPoisonTimer(1000),
|
||||
m_EffectHealTimer(1000), m_CastleTarget(nullptr), m_AttackTimer(1000) {
|
||||
|
||||
|
||||
@@ -174,6 +174,7 @@ public:
|
||||
void Reset(); // clear mobs and towers
|
||||
|
||||
void SpawnMobAt(MobID id, MobType type, std::uint8_t level, PlayerID sender, float x, float y, Direction dir);
|
||||
MobPtr RemoveMob(MobID id);
|
||||
|
||||
TowerPtr PlaceTowerAt(TowerID id, TowerType type, std::int32_t x, std::int32_t y, PlayerID builder);
|
||||
TowerPtr RemoveTower(TowerID id);
|
||||
@@ -219,7 +220,9 @@ public:
|
||||
|
||||
const TeamList& GetTeams() const;
|
||||
|
||||
TowerList& GetTowers() { return m_Towers; }
|
||||
const TowerList& GetTowers() const { return m_Towers; }
|
||||
|
||||
TowerPtr GetTowerById(TowerID tower);
|
||||
|
||||
const Player* GetPlayerById(PlayerID id) const;
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#include <cstring>
|
||||
#include <cassert>
|
||||
#include <string>
|
||||
#include <cstdint>
|
||||
|
||||
namespace td {
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#include <string>
|
||||
#include <iosfwd>
|
||||
#include <vector>
|
||||
#include <cstdint>
|
||||
|
||||
namespace td {
|
||||
namespace network {
|
||||
|
||||
@@ -27,6 +27,7 @@ public:
|
||||
virtual void HandlePacket(const PlayerLeavePacket* packet) {}
|
||||
virtual void HandlePacket(const PlayerListPacket* packet) {}
|
||||
virtual void HandlePacket(const PlayerLoginPacket* packet) {}
|
||||
virtual void HandlePacket(const RemoveMobPacket* packet) {}
|
||||
virtual void HandlePacket(const RemoveTowerPacket* packet) {}
|
||||
virtual void HandlePacket(const SelectTeamPacket* packet) {}
|
||||
virtual void HandlePacket(const SendMobsPacket* packet) {}
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#include "packets/PlayerLeavePacket.h"
|
||||
#include "packets/PlayerListPacket.h"
|
||||
#include "packets/PlayerLoginPacket.h"
|
||||
#include "packets/RemoveMobPacket.h"
|
||||
#include "packets/RemoveTowerPacket.h"
|
||||
#include "packets/SelectTeamPacket.h"
|
||||
#include "packets/SendMobsPacket.h"
|
||||
|
||||
@@ -29,6 +29,7 @@ class UpdateCastleLifePacket;
|
||||
class UpdateMobStatesPacket;
|
||||
class PlayerBuyItemPacket;
|
||||
class PlayerBuyMobUpgradePacket;
|
||||
class RemoveMobPacket;
|
||||
|
||||
} // namespace protocol
|
||||
} // namespace td
|
||||
|
||||
@@ -13,7 +13,6 @@ enum class PacketType : std::uint8_t {
|
||||
// client --> server
|
||||
PlayerLogin = 0,
|
||||
SelectTeam,
|
||||
SpawnMob,
|
||||
SendMobs,
|
||||
PlaceTower,
|
||||
|
||||
@@ -33,6 +32,8 @@ enum class PacketType : std::uint8_t {
|
||||
WorldAddTower,
|
||||
UpdateMobStates,
|
||||
UpdateCastleLife,
|
||||
SpawnMob,
|
||||
RemoveMob,
|
||||
|
||||
// client <--> server
|
||||
KeepAlive,
|
||||
|
||||
27
include/td/protocol/packets/RemoveMobPacket.h
Normal file
27
include/td/protocol/packets/RemoveMobPacket.h
Normal file
@@ -0,0 +1,27 @@
|
||||
#pragma once
|
||||
|
||||
#include "td/protocol/Protocol.h"
|
||||
#include "td/game/BaseGame.h"
|
||||
|
||||
namespace td {
|
||||
namespace protocol {
|
||||
|
||||
class RemoveMobPacket : public Packet {
|
||||
private:
|
||||
game::MobID m_MobID;
|
||||
public:
|
||||
RemoveMobPacket() {}
|
||||
RemoveMobPacket(game::MobID id) : m_MobID(id) {}
|
||||
virtual ~RemoveMobPacket() {}
|
||||
|
||||
virtual DataBuffer Serialize(bool packetID = true) const;
|
||||
virtual void Deserialize(DataBuffer& data);
|
||||
virtual void Dispatch(PacketHandler* handler) const;
|
||||
|
||||
game::MobID GetMobID() const { return m_MobID; }
|
||||
|
||||
virtual PacketType GetType() const { return PacketType::RemoveMob; }
|
||||
};
|
||||
|
||||
} // namespace protocol
|
||||
} // namespace td
|
||||
BIN
screenshots/game.png
Normal file
BIN
screenshots/game.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 165 KiB |
@@ -8,6 +8,7 @@
|
||||
#include "td/protocol/packets/WorldDataPacket.h"
|
||||
#include "td/protocol/packets/SpawnMobPacket.h"
|
||||
#include "td/protocol/packets/UpgradeTowerPacket.h"
|
||||
#include "td/protocol/packets/RemoveMobPacket.h"
|
||||
#include "td/protocol/packets/RemoveTowerPacket.h"
|
||||
#include "td/protocol/packets/UpdateCastleLifePacket.h"
|
||||
#include "td/protocol/packets/UpdateMobStatesPacket.h"
|
||||
@@ -21,6 +22,7 @@ WorldClient::WorldClient(ClientGame* game) : game::World(game), protocol::Packet
|
||||
GetDispatcher()->RegisterHandler(protocol::PacketType::WorldData, this);
|
||||
GetDispatcher()->RegisterHandler(protocol::PacketType::SpawnMob, this);
|
||||
GetDispatcher()->RegisterHandler(protocol::PacketType::UpgradeTower, this);
|
||||
GetDispatcher()->RegisterHandler(protocol::PacketType::RemoveMob, this);
|
||||
GetDispatcher()->RegisterHandler(protocol::PacketType::RemoveTower, this);
|
||||
GetDispatcher()->RegisterHandler(protocol::PacketType::UpdateCastleLife, this);
|
||||
GetDispatcher()->RegisterHandler(protocol::PacketType::UpdateMobStates, this);
|
||||
@@ -50,7 +52,9 @@ void WorldClient::HandlePacket(const protocol::SpawnMobPacket* packet) {
|
||||
|
||||
void WorldClient::HandlePacket(const protocol::UpgradeTowerPacket* packet) {
|
||||
game::TowerPtr tower = GetTowerById(packet->GetTowerID());
|
||||
if (tower == nullptr) return; // this should not happen but who knows ?
|
||||
|
||||
SAFE_CHECK(tower);
|
||||
|
||||
tower->Upgrade(packet->GetTowerLevel().GetLevel(), packet->GetTowerLevel().GetPath());
|
||||
}
|
||||
|
||||
@@ -63,9 +67,17 @@ void WorldClient::HandlePacket(const protocol::WorldAddTowerPacket* packet) {
|
||||
void WorldClient::HandlePacket(const protocol::RemoveTowerPacket* packet) {
|
||||
game::TowerPtr tower = RemoveTower(packet->GetTowerID());
|
||||
|
||||
if (tower != nullptr) {
|
||||
GetWorldNotifier().NotifyListeners(&WorldListener::OnTowerRemove, tower);
|
||||
}
|
||||
SAFE_CHECK(tower);
|
||||
|
||||
GetWorldNotifier().NotifyListeners(&WorldListener::OnTowerRemove, tower);
|
||||
}
|
||||
|
||||
void WorldClient::HandlePacket(const protocol::RemoveMobPacket* packet) {
|
||||
game::MobPtr mob = RemoveMob(packet->GetMobID());
|
||||
|
||||
SAFE_CHECK(mob);
|
||||
|
||||
//GetWorldNotifier().NotifyListeners(&MobListener::OnMobDie, mob.get());
|
||||
}
|
||||
|
||||
void WorldClient::HandlePacket(const protocol::UpdateMobStatesPacket* packet) {
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <algorithm>
|
||||
|
||||
#include "client/render/Renderer.h"
|
||||
#include "client/render/GL.h"
|
||||
|
||||
@@ -163,12 +163,16 @@ void Server::BroadcastPacket(const protocol::Packet* packet) {
|
||||
}
|
||||
|
||||
void Server::RemoveConnexion(std::uint8_t connexionID) {
|
||||
std::string playerName = GetGame().GetPlayerById(connexionID)->GetName();
|
||||
m_Connections.erase(connexionID);
|
||||
|
||||
td::game::Player* player = GetGame().GetPlayerById(connexionID);
|
||||
SAFE_CHECK(player);
|
||||
|
||||
std::string playerName = player->GetName();
|
||||
|
||||
GetGame().RemovePlayer(connexionID);
|
||||
m_Connections.erase(connexionID);
|
||||
m_Lobby.OnPlayerLeave(connexionID);
|
||||
|
||||
|
||||
utils::LOG(utils::format("\t[%s] left !", playerName.c_str()));
|
||||
|
||||
OnPlayerLeave(connexionID);
|
||||
@@ -176,13 +180,10 @@ void Server::RemoveConnexion(std::uint8_t connexionID) {
|
||||
|
||||
void Server::OnPlayerJoin(std::uint8_t id) {
|
||||
m_Lobby.OnPlayerJoin(id);
|
||||
|
||||
GetPlayers().insert({ id, game::Player{id} });
|
||||
}
|
||||
|
||||
void Server::OnPlayerLeave(std::uint8_t id) {
|
||||
protocol::PlayerLeavePacket packet(id);
|
||||
BroadcastPacket(&packet);
|
||||
GetGame().NotifyListeners(&game::GameListener::OnPlayerLeave, id);
|
||||
|
||||
if (GetPlayers().empty() && m_Game.GetGameState() != game::GameState::Lobby) {
|
||||
utils::LOG("All players left. Go back to lobby ...");
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#include "td/protocol/packets/RemoveTowerPacket.h"
|
||||
#include "td/protocol/packets/SelectTeamPacket.h"
|
||||
#include "td/protocol/packets/SendMobsPacket.h"
|
||||
#include "td/protocol/packets/SpawnMobPacket.h"
|
||||
#include "td/protocol/packets/UpdatePlayerTeamPacket.h"
|
||||
#include "td/protocol/packets/UpdateGameStatePacket.h"
|
||||
#include "td/protocol/packets/UpgradeTowerPacket.h"
|
||||
@@ -92,62 +93,94 @@ void ServerConnexion::SendKeepAlive() {
|
||||
}
|
||||
|
||||
void ServerConnexion::HandlePacket(const protocol::PlayerLoginPacket* packet) {
|
||||
if (m_Player->GetName().empty() && !packet->GetPlayerName().empty()) {
|
||||
m_Player->SetName(packet->GetPlayerName());
|
||||
|
||||
utils::LOG(utils::format("\t[%s] joined !", m_Player->GetName().c_str()));
|
||||
if (m_Server->GetGame().GetGameState() != game::GameState::Lobby) {
|
||||
protocol::DisconnectPacket packet("Cannot join during game");
|
||||
SendPacket(&packet);
|
||||
|
||||
protocol::PlayerJoinPacket joinPacket(m_ID, m_Player->GetName());
|
||||
m_Server->BroadcastPacket(&joinPacket);
|
||||
CloseConnection();
|
||||
return;
|
||||
}
|
||||
|
||||
SAFE_CHECK(!packet->GetPlayerName().empty());
|
||||
|
||||
std::map<std::uint8_t, protocol::PlayerInfo> playerNames;
|
||||
for (const auto& pair : m_Server->GetPlayers()) {
|
||||
const game::Player& player = pair.second;
|
||||
if (!player.GetName().empty()) {
|
||||
protocol::PlayerInfo playerInfo;
|
||||
playerInfo.name = player.GetName();
|
||||
playerInfo.team = player.GetTeamColor();
|
||||
playerNames.insert({ player.GetID(), playerInfo });
|
||||
}
|
||||
if (!m_Player) { // player does not exist yet
|
||||
auto playerPos = m_Server->GetPlayers().insert({ m_ID, game::Player{m_ID} });
|
||||
m_Player = &playerPos.first->second;
|
||||
}
|
||||
|
||||
SAFE_CHECK(m_Player->GetName().empty());
|
||||
|
||||
m_Player->SetName(packet->GetPlayerName());
|
||||
|
||||
utils::LOG(utils::format("\t[%s] joined !", m_Player->GetName().c_str()));
|
||||
|
||||
protocol::PlayerJoinPacket joinPacket(m_ID, m_Player->GetName());
|
||||
m_Server->BroadcastPacket(&joinPacket);
|
||||
|
||||
std::map<std::uint8_t, protocol::PlayerInfo> playerNames;
|
||||
for (const auto& pair : m_Server->GetPlayers()) {
|
||||
const game::Player& player = pair.second;
|
||||
if (!player.GetName().empty()) {
|
||||
protocol::PlayerInfo playerInfo;
|
||||
playerInfo.name = player.GetName();
|
||||
playerInfo.team = player.GetTeamColor();
|
||||
playerNames.insert({ player.GetID(), playerInfo });
|
||||
}
|
||||
}
|
||||
|
||||
protocol::PlayerListPacket listPacket(playerNames);
|
||||
SendPacket(&listPacket);
|
||||
protocol::PlayerListPacket listPacket(playerNames);
|
||||
SendPacket(&listPacket);
|
||||
|
||||
protocol::UpdateGameStatePacket statePacket(m_Server->GetGame().GetGameState());
|
||||
SendPacket(&statePacket);
|
||||
protocol::UpdateGameStatePacket statePacket(m_Server->GetGame().GetGameState());
|
||||
SendPacket(&statePacket);
|
||||
|
||||
m_Server->GetGame().NotifyListeners(&game::GameListener::OnPlayerJoin, m_ID);
|
||||
|
||||
protocol::WorldBeginDataPacket headerDataPacket(m_Server->GetGame().GetWorld());
|
||||
protocol::WorldDataPacket dataPacket(m_Server->GetGame().GetWorld());
|
||||
SendPacket(&headerDataPacket);
|
||||
SendPacket(&dataPacket);
|
||||
m_Server->GetGame().NotifyListeners(&game::GameListener::OnPlayerJoin, m_ID);
|
||||
|
||||
protocol::WorldBeginDataPacket headerDataPacket(m_Server->GetGame().GetWorld());
|
||||
protocol::WorldDataPacket dataPacket(m_Server->GetGame().GetWorld());
|
||||
SendPacket(&headerDataPacket);
|
||||
SendPacket(&dataPacket);
|
||||
|
||||
// place towers
|
||||
for (auto tower : m_Server->GetGame().GetWorld()->GetTowers()) {
|
||||
protocol::WorldAddTowerPacket packet(tower->GetID(), static_cast<std::int32_t>(tower->GetCenterX() - 0.5f),
|
||||
static_cast<std::int32_t>(tower->GetCenterY() - 0.5f), tower->GetType(), tower->GetBuilder());
|
||||
SendPacket(&packet);
|
||||
}
|
||||
|
||||
// spawn mobs
|
||||
for (auto mob : m_Server->GetGame().GetWorld()->GetMobList()) {
|
||||
protocol::SpawnMobPacket packet(mob->GetMobID(), mob->GetType(), mob->GetLevel(), mob->GetSender(),
|
||||
mob->GetCenterX(), mob->GetCenterY(), mob->GetDirection());
|
||||
SendPacket(&packet);
|
||||
// TODO : update health
|
||||
}
|
||||
}
|
||||
|
||||
void ServerConnexion::HandlePacket(const protocol::SelectTeamPacket* packet) {
|
||||
SAFE_CHECK(m_Server->GetGame().GetGameState() == game::GameState::Lobby);
|
||||
SAFE_CHECK(static_cast<std::int8_t>(packet->GetSelectedTeam()) >= -1 ||
|
||||
static_cast<std::int8_t>(packet->GetSelectedTeam()) <= 1);
|
||||
|
||||
if (static_cast<std::int8_t>(packet->GetSelectedTeam()) >= -1 || static_cast<std::int8_t>(packet->GetSelectedTeam()) <= 1) {
|
||||
if (m_Player->GetTeamColor() == game::TeamColor::None) { // join a team
|
||||
m_Server->GetGame().GetTeam(packet->GetSelectedTeam()).AddPlayer(m_Player);
|
||||
} else if (packet->GetSelectedTeam() == game::TeamColor::None) { // leave a team
|
||||
m_Server->GetGame().GetTeam(m_Player->GetTeamColor()).RemovePlayer(m_Player);
|
||||
m_Player->SetTeamColor(game::TeamColor::None);
|
||||
} else { // change team
|
||||
m_Server->GetGame().GetTeam(m_Player->GetTeamColor()).RemovePlayer(m_Player);
|
||||
m_Server->GetGame().GetTeam(packet->GetSelectedTeam()).AddPlayer(m_Player);
|
||||
}
|
||||
m_Player->SetTeamColor(packet->GetSelectedTeam());
|
||||
protocol::UpdatePlayerTeamPacket updateTeamPacket(m_ID, packet->GetSelectedTeam());
|
||||
m_Server->BroadcastPacket(&updateTeamPacket);
|
||||
if (m_Player->GetTeamColor() == game::TeamColor::None) { // join a team
|
||||
m_Server->GetGame().GetTeam(packet->GetSelectedTeam()).AddPlayer(m_Player);
|
||||
} else if (packet->GetSelectedTeam() == game::TeamColor::None) { // leave a team
|
||||
m_Server->GetGame().GetTeam(m_Player->GetTeamColor()).RemovePlayer(m_Player);
|
||||
m_Player->SetTeamColor(game::TeamColor::None);
|
||||
} else { // change team
|
||||
m_Server->GetGame().GetTeam(m_Player->GetTeamColor()).RemovePlayer(m_Player);
|
||||
m_Server->GetGame().GetTeam(packet->GetSelectedTeam()).AddPlayer(m_Player);
|
||||
}
|
||||
m_Player->SetTeamColor(packet->GetSelectedTeam());
|
||||
protocol::UpdatePlayerTeamPacket updateTeamPacket(m_ID, packet->GetSelectedTeam());
|
||||
m_Server->BroadcastPacket(&updateTeamPacket);
|
||||
}
|
||||
|
||||
void ServerConnexion::HandlePacket(const protocol::KeepAlivePacket* packet) {
|
||||
if (packet->GetAliveID() == m_KeepAlive.keepAliveID)
|
||||
m_KeepAlive.recievedResponse = true;
|
||||
SAFE_CHECK(packet->GetAliveID() == m_KeepAlive.keepAliveID);
|
||||
|
||||
m_KeepAlive.recievedResponse = true;
|
||||
}
|
||||
|
||||
void ServerConnexion::HandlePacket(const protocol::DisconnectPacket* packet) {
|
||||
@@ -156,7 +189,6 @@ void ServerConnexion::HandlePacket(const protocol::DisconnectPacket* packet) {
|
||||
|
||||
void ServerConnexion::SetServer(Server* server) {
|
||||
m_Server = server;
|
||||
m_Player = &m_Server->GetPlayers().at(m_ID);
|
||||
InitConnection();
|
||||
SendKeepAlive();
|
||||
}
|
||||
@@ -209,8 +241,9 @@ void ServerConnexion::HandlePacket(const protocol::RemoveTowerPacket* packet) {
|
||||
}
|
||||
|
||||
ServerConnexion::~ServerConnexion() {
|
||||
if (GetDispatcher() != nullptr)
|
||||
GetDispatcher()->UnregisterHandler(this);
|
||||
SAFE_CHECK(GetDispatcher() != nullptr);
|
||||
|
||||
GetDispatcher()->UnregisterHandler(this);
|
||||
}
|
||||
|
||||
} // namespace server
|
||||
|
||||
@@ -2,6 +2,9 @@
|
||||
#include "server/Server.h"
|
||||
|
||||
#include "td/protocol/packets/DisconnectPacket.h"
|
||||
#include "td/protocol/packets/PlayerLeavePacket.h"
|
||||
#include "td/protocol/packets/RemoveMobPacket.h"
|
||||
#include "td/protocol/packets/RemoveTowerPacket.h"
|
||||
#include "td/protocol/packets/UpdatePlayerTeamPacket.h"
|
||||
#include "td/protocol/packets/UpdateGameStatePacket.h"
|
||||
#include "td/protocol/packets/UpdateMoneyPacket.h"
|
||||
@@ -134,10 +137,41 @@ void ServerGame::OnGameClose() {
|
||||
m_Server->Restart();
|
||||
}
|
||||
|
||||
void ServerGame::OnPlayerJoin(game::PlayerID id){
|
||||
void ServerGame::OnPlayerJoin(game::PlayerID id) {
|
||||
if (m_GameState == game::GameState::Game)
|
||||
BalanceTeams();
|
||||
}
|
||||
|
||||
void ServerGame::OnPlayerLeave(game::PlayerID playerId) {
|
||||
// temporary fix
|
||||
|
||||
auto& mobList = GetWorld()->GetMobList();
|
||||
for(std::size_t i = 0; i < mobList.size(); i++) {
|
||||
auto mob = mobList.at(i);
|
||||
|
||||
if(mob->GetSender() == playerId) {
|
||||
protocol::RemoveMobPacket packet(mob->GetMobID());
|
||||
m_Server->BroadcastPacket(&packet);
|
||||
|
||||
mobList.erase(mobList.begin() + i);
|
||||
}
|
||||
}
|
||||
|
||||
auto& towerList = GetWorld()->GetTowers();
|
||||
for(std::size_t i = 0; i < towerList.size(); i++) {
|
||||
auto tower = towerList.at(i);
|
||||
|
||||
if(tower->GetBuilder() == playerId) {
|
||||
protocol::RemoveTowerPacket packet(tower->GetID());
|
||||
m_Server->BroadcastPacket(&packet);
|
||||
|
||||
towerList.erase(towerList.begin() + i);
|
||||
}
|
||||
}
|
||||
|
||||
protocol::PlayerLeavePacket packet(playerId);
|
||||
m_Server->BroadcastPacket(&packet);
|
||||
}
|
||||
|
||||
} // namespace game
|
||||
} // namespace td
|
||||
|
||||
@@ -123,6 +123,17 @@ void World::SpawnMobAt(MobID id, MobType type, std::uint8_t level, PlayerID send
|
||||
GetMobNotifier().NotifyListeners(&MobListener::OnMobSpawn, mob.get());
|
||||
}
|
||||
|
||||
MobPtr World::RemoveMob(MobID mobId) {
|
||||
auto it = std::find_if(m_Mobs.begin(), m_Mobs.end(), [mobId](MobPtr mob) { return mob->GetMobID() == mobId;});
|
||||
if (it == m_Mobs.end()) return nullptr;
|
||||
|
||||
MobPtr mob = *it;
|
||||
|
||||
m_Mobs.erase(it);
|
||||
|
||||
return mob;
|
||||
}
|
||||
|
||||
TowerPtr World::PlaceTowerAt(TowerID id, TowerType type, std::int32_t x, std::int32_t y, PlayerID builder) {
|
||||
TowerPtr tower = TowerFactory::CreateTower(type, id, x, y, builder);
|
||||
m_Towers.push_back(tower);
|
||||
|
||||
@@ -36,6 +36,7 @@ static std::map<PacketType, PacketCreator> packets = {
|
||||
{PacketType::UpdateMobStates, []() -> PacketPtr {return std::make_unique<UpdateMobStatesPacket>(); } },
|
||||
{PacketType::PlayerBuyItem, []() -> PacketPtr {return std::make_unique<PlayerBuyItemPacket>(); } },
|
||||
{PacketType::PlayerBuyMobUpgrade, []() -> PacketPtr {return std::make_unique<PlayerBuyMobUpgradePacket>(); } },
|
||||
{PacketType::RemoveMob, []() -> PacketPtr {return std::make_unique<RemoveMobPacket>(); } },
|
||||
};
|
||||
|
||||
PacketPtr CreatePacket(PacketType type, DataBuffer& buffer) {
|
||||
|
||||
@@ -39,6 +39,7 @@ REGISTER_DISPATCH_CLASS(UpdateCastleLifePacket)
|
||||
REGISTER_DISPATCH_CLASS(UpdateMobStatesPacket)
|
||||
REGISTER_DISPATCH_CLASS(PlayerBuyItemPacket)
|
||||
REGISTER_DISPATCH_CLASS(PlayerBuyMobUpgradePacket)
|
||||
REGISTER_DISPATCH_CLASS(RemoveMobPacket)
|
||||
|
||||
} // namespace protocol
|
||||
} // namespace td
|
||||
19
src/td/protocol/packets/RemoveMobPacket.cpp
Normal file
19
src/td/protocol/packets/RemoveMobPacket.cpp
Normal file
@@ -0,0 +1,19 @@
|
||||
#include "td/protocol/packets/RemoveMobPacket.h"
|
||||
|
||||
namespace td {
|
||||
namespace protocol {
|
||||
|
||||
DataBuffer RemoveMobPacket::Serialize(bool packetID) const {
|
||||
DataBuffer data;
|
||||
|
||||
WritePacketID(data, packetID);
|
||||
data << m_MobID;
|
||||
return data;
|
||||
}
|
||||
|
||||
void RemoveMobPacket::Deserialize(DataBuffer& data) {
|
||||
data >> m_MobID;
|
||||
}
|
||||
|
||||
} // namespace protocol
|
||||
} // namespace td
|
||||
20
xmake.lua
20
xmake.lua
@@ -1,8 +1,9 @@
|
||||
add_rules("mode.debug", "mode.release")
|
||||
|
||||
add_defines("TD_IMPL_OPENGL_LOADER_GLEW")
|
||||
add_requires("libsdl >= 2", "zlib", "glew")
|
||||
add_requires("libsdl2", "zlib", "glew")
|
||||
|
||||
set_languages("c++17")
|
||||
|
||||
target("TowerDefenseData")
|
||||
set_kind("static")
|
||||
@@ -10,8 +11,6 @@ target("TowerDefenseData")
|
||||
add_includedirs("include")
|
||||
add_files("src/td/**.cpp")
|
||||
|
||||
set_languages("c++17")
|
||||
|
||||
add_packages("zlib")
|
||||
|
||||
add_links("pthread")
|
||||
@@ -21,18 +20,7 @@ target("TowerDefenseData")
|
||||
add_links("ws2_32") -- link network stuff
|
||||
end
|
||||
|
||||
if is_mode("release") then
|
||||
-- mark symbols visibility as hidden
|
||||
set_symbols("hidden")
|
||||
|
||||
-- strip all symbols
|
||||
add_ldflags("-s")
|
||||
|
||||
set_warnings("all", "error")
|
||||
|
||||
set_optimize("fastest")
|
||||
|
||||
else -- debug stuff
|
||||
if is_mode("debug") then
|
||||
if is_os("linux") then
|
||||
add_links("dw")
|
||||
end
|
||||
@@ -75,7 +63,7 @@ target("TowerDefenseClient")
|
||||
add_files("src/ClientMain.cpp", "src/client/**.cpp")
|
||||
add_includedirs("include")
|
||||
|
||||
add_packages("libsdl", "glew", "opengl")
|
||||
add_packages("libsdl2", "glew", "opengl")
|
||||
|
||||
-- run windows program with wine on linux
|
||||
if is_host("linux") and is_os("windows") then
|
||||
|
||||
Reference in New Issue
Block a user