13 Commits

31 changed files with 173 additions and 83 deletions

View File

@@ -12,11 +12,25 @@ enum class GameState : std::uint8_t {
Game, Game,
EndGame, EndGame,
Disconnected, Disconnected,
Closed
}; };
typedef std::map<std::uint8_t, Player> PlayerList; typedef std::map<std::uint8_t, Player> PlayerList;
class Game { class GameListener {
public:
virtual void OnPlayerJoin(PlayerID player) {}
virtual void OnPlayerLeave(PlayerID player) {}
virtual void OnGameStateUpdate(GameState newState) {}
virtual void OnGameBegin() {}
virtual void OnGameEnd() {}
virtual void OnGameClose() {}
};
typedef utils::ObjectNotifier<GameListener> GameNotifier;
class Game : public GameNotifier {
protected: protected:
World* m_World; World* m_World;
TeamList m_Teams = { Team{TeamColor::Red}, Team{TeamColor::Blue} }; TeamList m_Teams = { Team{TeamColor::Red}, Team{TeamColor::Blue} };

View File

@@ -56,6 +56,13 @@ struct Color {
std::uint8_t r, g, b; std::uint8_t r, g, b;
}; };
static constexpr Color BLACK{ 0, 0, 0 };
static constexpr Color WHITE{ 255, 255, 255 };
static constexpr Color RED{ 255, 0, 0 };
static constexpr Color GREEN{ 0, 255, 0 };
static constexpr Color BLUE{ 0, 0, 255 };
struct Tile { struct Tile {
virtual TileType getType() const = 0; virtual TileType getType() const = 0;
}; };
@@ -134,6 +141,7 @@ protected:
TowerTileColorPalette m_TowerPlacePalette; TowerTileColorPalette m_TowerPlacePalette;
Color m_WalkablePalette; Color m_WalkablePalette;
std::vector<Color> m_DecorationPalette; std::vector<Color> m_DecorationPalette;
Color m_Background;
std::unordered_map<ChunkCoord, ChunkPtr> m_Chunks; std::unordered_map<ChunkCoord, ChunkPtr> m_Chunks;
@@ -152,8 +160,6 @@ protected:
public: public:
World(Game* game); World(Game* game);
static constexpr std::uint8_t CastleWidth = 5, CastleHeight = 5;
bool loadMap(const protocol::WorldBeginDataPacket* worldHeader); bool loadMap(const protocol::WorldBeginDataPacket* worldHeader);
bool loadMap(const protocol::WorldDataPacket* worldData); bool loadMap(const protocol::WorldDataPacket* worldData);
@@ -172,6 +178,7 @@ public:
const TowerTileColorPalette& getTowerTileColorPalette() const { return m_TowerPlacePalette; } const TowerTileColorPalette& getTowerTileColorPalette() const { return m_TowerPlacePalette; }
const Color& getWalkableTileColor() const { return m_WalkablePalette; } const Color& getWalkableTileColor() const { return m_WalkablePalette; }
const std::vector<Color>& getDecorationPalette() const { return m_DecorationPalette; } const std::vector<Color>& getDecorationPalette() const { return m_DecorationPalette; }
const Color& getBackgroundColor() const { return m_Background; }
const TilePalette& getTilePalette() const { return m_TilePalette; } const TilePalette& getTilePalette() const { return m_TilePalette; }
@@ -225,7 +232,6 @@ public:
// MobListener // MobListener
virtual void OnMobDamage(Mob* target, float damage, Tower* source); virtual void OnMobDamage(Mob* target, float damage, Tower* source);
virtual void OnMobDie(Mob* mob);
virtual void OnMobCastleDamage(Mob* damager, TeamCastle* enemyCastle, float damage); virtual void OnMobCastleDamage(Mob* damager, TeamCastle* enemyCastle, float damage);
private: private:

View File

@@ -19,16 +19,16 @@ class Client {
private: private:
render::Renderer* m_Renderer; render::Renderer* m_Renderer;
ClientConnexion m_Connexion; ClientConnexion m_Connexion;
ClientGame m_Game; std::unique_ptr<ClientGame> m_Game;
bool m_Connected; bool m_Connected;
public: public:
Client(render::Renderer* renderer) : m_Renderer(renderer), m_Game(this), m_Connected(false) {} Client(render::Renderer* renderer) : m_Renderer(renderer), m_Game(std::make_unique<ClientGame>(this)), m_Connected(false) {}
const ClientGame& getGame() const { return m_Game; } const ClientGame& getGame() const { return *m_Game; }
const ClientConnexion& getConnexion() const { return m_Connexion; } const ClientConnexion& getConnexion() const { return m_Connexion; }
render::Renderer* getRenderer() const { return m_Renderer; } render::Renderer* getRenderer() const { return m_Renderer; }
ClientGame& getGame() { return m_Game; } ClientGame& getGame() { return *m_Game; }
ClientConnexion& getConnexion() { return m_Connexion; } ClientConnexion& getConnexion() { return m_Connexion; }
void tick(std::uint64_t delta); void tick(std::uint64_t delta);
@@ -45,6 +45,8 @@ public:
void placeTower(game::TowerType type, const glm::vec2& position); void placeTower(game::TowerType type, const glm::vec2& position);
void upgradeTower(game::TowerID tower, game::TowerLevel level); void upgradeTower(game::TowerID tower, game::TowerLevel level);
void removeTower(game::TowerID tower); void removeTower(game::TowerID tower);
private:
void reset();
}; };
} // namespace client } // namespace client

View File

@@ -37,7 +37,7 @@ public:
Client* getClient() const { return m_Client; } Client* getClient() const { return m_Client; }
render::Renderer* getRenderer() const { return m_Renderer; } render::Renderer* getRenderer() const { return m_Renderer; }
WorldClient& getWorld() { return m_WorldClient; } WorldClient& getWorldClient() { return m_WorldClient; }
virtual void HandlePacket(const protocol::ConnexionInfoPacket* packet); virtual void HandlePacket(const protocol::ConnexionInfoPacket* packet);
virtual void HandlePacket(const protocol::PlayerJoinPacket* packet); virtual void HandlePacket(const protocol::PlayerJoinPacket* packet);

View File

@@ -61,12 +61,11 @@ private:
bool m_ServerRunning; bool m_ServerRunning;
public: public:
Server(const std::string& worldFilePath); Server(const std::string& worldFilePath);
virtual ~Server() {} virtual ~Server();
bool start(std::uint16_t port); bool start(std::uint16_t port);
void stop(); void stop(); // force the server to stop
void close(); // at the end of a game
void lauchGame();
void removeConnexion(std::uint8_t connexionID); void removeConnexion(std::uint8_t connexionID);
@@ -74,6 +73,8 @@ public:
float getTPS() const { return m_TickCounter.getTPS(); } float getTPS() const { return m_TickCounter.getTPS(); }
bool isRunning() { return m_ServerRunning; }
const ServerGame& getGame() const { return m_Game; } const ServerGame& getGame() const { return m_Game; }
ServerGame& getGame() { return m_Game; } ServerGame& getGame() { return m_Game; }
@@ -88,6 +89,7 @@ private:
void accept(); void accept();
void updateSockets(); void updateSockets();
void clean();
void startThread(); void startThread();
void stopThread(); void stopThread();
void tick(std::uint64_t delta); void tick(std::uint64_t delta);

View File

@@ -9,11 +9,12 @@ namespace server {
class Server; class Server;
class ServerGame : public game::Game { class ServerGame : public game::Game, public game::GameListener {
private: private:
Server* m_Server; Server* m_Server;
ServerWorld m_ServerWorld; ServerWorld m_ServerWorld;
utils::AutoTimer m_GoldMineTimer{ 1000, std::bind(&ServerGame::updateGoldMines, this) }; utils::AutoTimer m_GoldMineTimer{ 1000, std::bind(&ServerGame::updateGoldMines, this) };
utils::CooldownTimer m_EndGameCooldown{ 1000 * 10 };
public: public:
ServerGame(Server* server); ServerGame(Server* server);
~ServerGame() {} ~ServerGame() {}
@@ -22,6 +23,13 @@ public:
virtual void tick(std::uint64_t delta); virtual void tick(std::uint64_t delta);
void startGame(); void startGame();
// GameListener
virtual void OnGameStateUpdate(game::GameState newState);
virtual void OnGameBegin();
virtual void OnGameEnd();
virtual void OnGameClose();
private: private:
void balanceTeams(); void balanceTeams();
void updateGoldMines(); void updateGoldMines();

View File

@@ -21,6 +21,8 @@ public:
void spawnMobs(game::MobType type, std::uint8_t level, game::PlayerID sender, std::uint8_t count); void spawnMobs(game::MobType type, std::uint8_t level, game::PlayerID sender, std::uint8_t count);
game::TowerPtr placeTowerAt(game::TowerType type, std::int32_t x, std::int32_t y, game::PlayerID builder); game::TowerPtr placeTowerAt(game::TowerType type, std::int32_t x, std::int32_t y, game::PlayerID builder);
virtual void OnMobDie(game::Mob* mob);
}; };
} // namespace server } // namespace server

View File

@@ -338,7 +338,7 @@
#include <thread> #include <thread>
#include <basetsd.h> #include <basetsd.h>
typedef SSIZE_T ssize_t; //typedef SSIZE_T ssize_t;
#ifndef NOMINMAX #ifndef NOMINMAX
#define NOMINMAX #define NOMINMAX

View File

@@ -45,6 +45,7 @@ struct WorldHeader {
game::TowerTileColorPalette m_TowerPlacePalette; game::TowerTileColorPalette m_TowerPlacePalette;
game::Color m_WalkablePalette; game::Color m_WalkablePalette;
std::vector<game::Color> m_DecorationPalette; std::vector<game::Color> m_DecorationPalette;
game::Color m_Background;
game::SpawnColorPalette m_SpawnColorPalette; game::SpawnColorPalette m_SpawnColorPalette;
@@ -128,6 +129,7 @@ public:
const game::TowerTileColorPalette& getTowerTilePalette() const { return m_Header.m_TowerPlacePalette; } const game::TowerTileColorPalette& getTowerTilePalette() const { return m_Header.m_TowerPlacePalette; }
const game::Color& getWalkableTileColor() const { return m_Header.m_WalkablePalette; } const game::Color& getWalkableTileColor() const { return m_Header.m_WalkablePalette; }
const std::vector<game::Color>& getDecorationPalette() const { return m_Header.m_DecorationPalette; } const std::vector<game::Color>& getDecorationPalette() const { return m_Header.m_DecorationPalette; }
const game::Color& getBackgroundColor() const { return m_Header.m_Background; }
const game::Spawn& getRedSpawn() const { return m_Header.m_RedSpawn; } const game::Spawn& getRedSpawn() const { return m_Header.m_RedSpawn; }
const game::Spawn& getBlueSpawn() const { return m_Header.m_BlueSpawn; } const game::Spawn& getBlueSpawn() const { return m_Header.m_BlueSpawn; }

View File

@@ -29,6 +29,8 @@ private:
std::unique_ptr<WorldShader> m_WorldShader; std::unique_ptr<WorldShader> m_WorldShader;
std::unique_ptr<EntityShader> m_EntityShader; std::unique_ptr<EntityShader> m_EntityShader;
glm::vec3 m_BackgroundColor;
bool m_IsometricView = true; bool m_IsometricView = true;
float m_IsometricShade = m_IsometricView; float m_IsometricShade = m_IsometricView;
glm::vec2 m_CamPos{}; glm::vec2 m_CamPos{};
@@ -49,6 +51,8 @@ public:
void setCamPos(const glm::vec2& newPos); void setCamPos(const glm::vec2& newPos);
void setIsometricView(bool isometric); // false = 2D true = Isometric void setIsometricView(bool isometric); // false = 2D true = Isometric
void setBackgroundColor(const glm::vec3& color) { m_BackgroundColor = color; }
glm::vec2 getCursorWorldPos(const glm::vec2& cursorPos, float aspectRatio, float zoom, float windowWidth, float windowHeight); glm::vec2 getCursorWorldPos(const glm::vec2& cursorPos, float aspectRatio, float zoom, float windowWidth, float windowHeight);
private: private:
void updateIsometricView(); void updateIsometricView();

View File

@@ -21,6 +21,7 @@ public:
virtual void render(); virtual void render();
void setCastle(const game::TeamCastle* castle) { m_Castle = castle; } void setCastle(const game::TeamCastle* castle) { m_Castle = castle; }
bool isShown() { return m_Castle != nullptr; }
}; };
} // namespace gui } // namespace gui

View File

@@ -10,15 +10,17 @@ namespace gui {
class GuiManager { class GuiManager {
private: private:
std::vector<std::shared_ptr<GuiWidget>> m_Widgets; std::vector<std::unique_ptr<GuiWidget>> m_Widgets;
public: public:
GuiManager(){}
void renderWidgets() { void renderWidgets() {
for (auto widget : m_Widgets) { for (auto& widget : m_Widgets) {
widget->render(); widget->render();
} }
} }
void addWidgets(const std::shared_ptr<GuiWidget>& widget) { void addWidget(std::unique_ptr<GuiWidget>&& widget) {
m_Widgets.push_back(std::move(widget)); m_Widgets.push_back(std::move(widget));
} }
}; };

View File

@@ -21,6 +21,7 @@ public:
virtual void render(); virtual void render();
void setMob(const game::Mob* mob) { m_Mob = mob; } void setMob(const game::Mob* mob) { m_Mob = mob; }
bool isShown() { return m_Mob != nullptr; }
}; };
} // namespace gui } // namespace gui

View File

@@ -9,6 +9,8 @@
#include <memory> #include <memory>
#include "render/gui/GuiManager.h"
struct SDL_Window; struct SDL_Window;
typedef void* SDL_GLContext; typedef void* SDL_GLContext;
@@ -20,15 +22,6 @@ class Client;
} // namespace client } // namespace client
namespace gui {
class MainMenu;
class GameMenu;
class FrameMenu;
class UpdateMenu;
} // namespace gui
namespace render { namespace render {
class Renderer; class Renderer;
@@ -38,11 +31,8 @@ private:
SDL_Window* m_Window; SDL_Window* m_Window;
SDL_GLContext m_GlContext; SDL_GLContext m_GlContext;
td::render::Renderer* m_Renderer; td::render::Renderer* m_Renderer;
td::gui::GuiManager m_GuiManager;
std::unique_ptr<td::client::Client> m_Client; std::unique_ptr<td::client::Client> m_Client;
std::unique_ptr<td::gui::MainMenu> m_MainMenu;
std::unique_ptr<td::gui::GameMenu> m_GameMenu;
std::unique_ptr<td::gui::FrameMenu> m_FrameMenu;
std::unique_ptr<td::gui::UpdateMenu> m_UpdateMenu;
public: public:
TowerGui(SDL_Window* wndow, SDL_GLContext glContext, td::render::Renderer* renderer); TowerGui(SDL_Window* wndow, SDL_GLContext glContext, td::render::Renderer* renderer);
~TowerGui(); ~TowerGui();

View File

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

View File

@@ -37,6 +37,7 @@ bool World::loadMap(const protocol::WorldBeginDataPacket* worldHeader) {
m_TowerPlacePalette = worldHeader->getTowerTilePalette(); m_TowerPlacePalette = worldHeader->getTowerTilePalette();
m_WalkablePalette = worldHeader->getWalkableTileColor(); m_WalkablePalette = worldHeader->getWalkableTileColor();
m_DecorationPalette = worldHeader->getDecorationPalette(); m_DecorationPalette = worldHeader->getDecorationPalette();
m_Background = worldHeader->getBackgroundColor();
getRedTeam().getSpawn() = worldHeader->getRedSpawn(); getRedTeam().getSpawn() = worldHeader->getRedSpawn();
getBlueTeam().getSpawn() = worldHeader->getBlueSpawn(); getBlueTeam().getSpawn() = worldHeader->getBlueSpawn();
@@ -105,6 +106,8 @@ bool World::saveMap(const std::string& fileName) const {
} }
void World::tick(std::uint64_t delta) { void World::tick(std::uint64_t delta) {
if (m_Game->getGameState() != GameState::Game) return;
tickMobs(delta); tickMobs(delta);
for (TowerPtr tower : m_Towers) { for (TowerPtr tower : m_Towers) {
tower->tick(delta, this); tower->tick(delta, this);
@@ -218,17 +221,6 @@ bool World::CanPlaceBigTower(const glm::vec2& worldPos, PlayerID playerID) const
return false; return false;
} }
void World::OnMobDie(Mob* mob) {
if (mob->OnDeath(this)) { // check if the mob is actually dead (slimes ...)
//reward players
Player* sender = m_Game->getPlayerById(mob->getSender());
sender->addExp(mob->getStats()->getExpReward());
Player* killer = m_Game->getPlayerById(mob->getLastDamageTower()->getBuilder());
killer->addGold(mob->getStats()->getMoneyCost());
}
}
void World::cleanDeadMobs() { void World::cleanDeadMobs() {
// safely remove mobs when unused // safely remove mobs when unused
for (std::size_t i = 0; i < m_Mobs.size(); i++) { for (std::size_t i = 0; i < m_Mobs.size(); i++) {
@@ -292,7 +284,7 @@ void World::OnExplosion(utils::shape::Circle explosion, float centerDamage, Towe
void World::OnMobCastleDamage(Mob* damager, TeamCastle* enemyCastle, float damage) { void World::OnMobCastleDamage(Mob* damager, TeamCastle* enemyCastle, float damage) {
enemyCastle->damage(damage); enemyCastle->damage(damage);
if (enemyCastle->getLife() <= 0) { if (enemyCastle->getLife() <= 0) {
// TODO: a team has won m_Game->notifyListeners(&GameListener::OnGameEnd);
} }
} }

View File

@@ -40,13 +40,19 @@ void Client::tick(std::uint64_t delta) {
m_Connected = m_Connexion.updateSocket(); m_Connected = m_Connexion.updateSocket();
if (!m_Connected) { if (!m_Connected) {
std::cout << "Disconnected ! (Reason : " << m_Connexion.getDisconnectReason() << ")\n"; std::cout << "Disconnected ! (Reason : " << m_Connexion.getDisconnectReason() << ")\n";
reset();
} else { } else {
m_Game.tick(delta); m_Game->tick(delta);
} }
} }
void Client::render() { void Client::render() {
m_Game.renderWorld(); m_Game->renderWorld();
}
void Client::reset() {
m_Game.reset(0);
m_Game = std::make_unique<ClientGame>(this);
} }
void Client::sendMobs(const std::vector<protocol::MobSend>& mobSends) { void Client::sendMobs(const std::vector<protocol::MobSend>& mobSends) {

View File

@@ -4,7 +4,7 @@
namespace td { namespace td {
namespace client { namespace client {
ClientConnexion::ClientConnexion() : Connexion(&m_Dispatcher) { ClientConnexion::ClientConnexion() : Connexion(&m_Dispatcher), m_ServerTPS(0) {
registerHandlers(); registerHandlers();
} }

View File

@@ -93,6 +93,7 @@ void ClientGame::HandlePacket(const protocol::UpdateMoneyPacket* packet) {
void ClientGame::HandlePacket(const protocol::DisconnectPacket* packet) { void ClientGame::HandlePacket(const protocol::DisconnectPacket* packet) {
m_GameState = game::GameState::Disconnected; m_GameState = game::GameState::Disconnected;
m_Renderer->setBackgroundColor({ 0, 0, 0 });
} }
void ClientGame::HandlePacket(const protocol::WorldDataPacket* packet) { void ClientGame::HandlePacket(const protocol::WorldDataPacket* packet) {

View File

@@ -17,6 +17,11 @@ WorldClient::WorldClient(ClientGame* game) : game::World(game), protocol::Packet
void WorldClient::HandlePacket(const protocol::WorldBeginDataPacket* packet) { void WorldClient::HandlePacket(const protocol::WorldBeginDataPacket* packet) {
loadMap(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),
static_cast<float>(backgroundColor.b / 255.0f) });
}
} }
void WorldClient::HandlePacket(const protocol::WorldDataPacket* packet) { void WorldClient::HandlePacket(const protocol::WorldDataPacket* packet) {

View File

@@ -37,10 +37,8 @@ void Lobby::tick() {
return; return;
if (utils::getTime() - m_StartTimerTime >= LobbyWaitingTime) { if (utils::getTime() - m_StartTimerTime >= LobbyWaitingTime) {
protocol::UpdateGameStatePacket packet(game::GameState::Game); m_Server->getGame().notifyListeners(&game::GameListener::OnGameBegin);
m_Server->broadcastPacket(&packet);
m_GameStarted = true; m_GameStarted = true;
m_Server->lauchGame();
return; return;
} }

View File

@@ -9,8 +9,9 @@ Server::Server(const std::string& worldFilePath) : m_ServerRunning(false) {
m_Game.getWorld()->loadMapFromFile(worldFilePath); m_Game.getWorld()->loadMapFromFile(worldFilePath);
} }
void Server::lauchGame() { Server::~Server() {
m_Game.startGame(); if (m_Thread.joinable())
m_Thread.join();
} }
void Server::startThread() { void Server::startThread() {
@@ -29,13 +30,16 @@ void Server::startThread() {
} }
} }
clean();
}); });
} }
void Server::close() {
stopThread();
}
void Server::stopThread() { void Server::stopThread() {
m_ServerRunning = false; m_ServerRunning = false;
if (m_Thread.joinable())
m_Thread.join();
} }
bool Server::start(std::uint16_t port) { bool Server::start(std::uint16_t port) {
@@ -54,19 +58,24 @@ bool Server::start(std::uint16_t port) {
return true; return true;
} }
void Server::stop() { void Server::clean() {
if (!m_ServerRunning)
return;
stopThread();
protocol::DisconnectPacket packet("Server closed");
broadcastPacket(&packet);
m_Listener.close(); m_Listener.close();
m_Listener.destroy(); m_Listener.destroy();
m_Connections.clear(); m_Connections.clear();
getPlayers().clear(); getPlayers().clear();
std::cout << "Server successfully stopped !\n";
}
void Server::stop() {
if (!m_ServerRunning)
return;
protocol::DisconnectPacket packet("Server closed");
broadcastPacket(&packet);
stopThread();
} }
void Server::tick(std::uint64_t delta) { void Server::tick(std::uint64_t delta) {

View File

@@ -5,13 +5,17 @@ namespace td {
namespace server { 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) {
bindListener(this);
} }
void ServerGame::tick(std::uint64_t delta) { void ServerGame::tick(std::uint64_t delta) {
if (m_GameState == game::GameState::Game) { if (m_GameState == game::GameState::Game) {
Game::tick(delta); Game::tick(delta);
updatePlayerStats(); updatePlayerStats();
} else if (m_GameState == game::GameState::EndGame) {
if (m_EndGameCooldown.update(delta)) {
notifyListeners(&game::GameListener::OnGameClose);
}
} }
} }
@@ -70,5 +74,31 @@ void ServerGame::balanceTeams() {
} }
} }
void ServerGame::OnGameStateUpdate(game::GameState newState) {
setGameState(newState);
protocol::UpdateGameStatePacket packet(newState);
m_Server->broadcastPacket(&packet);
}
void ServerGame::OnGameBegin() {
notifyListeners(&game::GameListener::OnGameStateUpdate, game::GameState::Game);
startGame();
}
void ServerGame::OnGameEnd() {
notifyListeners(&game::GameListener::OnGameStateUpdate, game::GameState::EndGame);
m_EndGameCooldown.applyCooldown();
}
void ServerGame::OnGameClose() {
notifyListeners(&game::GameListener::OnGameStateUpdate, game::GameState::Closed);
// Disconnect clients
protocol::DisconnectPacket packet("Game finished");
m_Server->broadcastPacket(&packet);
// Closing server
m_Server->close();
}
} // namespace game } // namespace game
} // namespace td } // namespace td

View File

@@ -55,5 +55,16 @@ game::TowerPtr ServerWorld::placeTowerAt(game::TowerType type, std::int32_t x, s
return tower; return tower;
} }
void ServerWorld::OnMobDie(game::Mob* mob) {
if (mob->OnDeath(this)) { // check if the mob is actually dead (slimes ...)
//reward players
game::Player* sender = m_Game->getPlayerById(mob->getSender());
sender->addExp(mob->getStats()->getExpReward());
game::Player* killer = m_Game->getPlayerById(mob->getLastDamageTower()->getBuilder());
killer->addGold(mob->getStats()->getMoneyCost());
}
}
} // namespace server } // namespace server
} // namespace td } // namespace td

View File

@@ -91,6 +91,8 @@ DataBuffer WorldBeginDataPacket::SerializeCustom() const {
memcpy((std::uint8_t*)data.data() + bufferSize, decoTilePalette.data(), decoTilePalette.size() * sizeof(game::Color)); memcpy((std::uint8_t*)data.data() + bufferSize, decoTilePalette.data(), decoTilePalette.size() * sizeof(game::Color));
data << m_Header.m_Background;
const game::Spawn& redSpawn = m_Header.m_RedSpawn, blueSpawn = m_Header.m_BlueSpawn; const game::Spawn& redSpawn = m_Header.m_RedSpawn, blueSpawn = m_Header.m_BlueSpawn;
const game::TeamCastle& redCastle = m_Header.m_RedCastle, blueCastle = m_Header.m_BlueCastle; const game::TeamCastle& redCastle = m_Header.m_RedCastle, blueCastle = m_Header.m_BlueCastle;
@@ -123,6 +125,8 @@ DataBuffer WorldBeginDataPacket::Serialize() const {
memcpy((std::uint8_t*)data.data() + bufferSize, decoTilePalette.data(), decoTilePalette.size() * sizeof(game::Color)); memcpy((std::uint8_t*)data.data() + bufferSize, decoTilePalette.data(), decoTilePalette.size() * sizeof(game::Color));
data << m_Header.m_World->getBackgroundColor();
const game::Spawn& redSpawn = m_Header.m_World->getRedTeam().getSpawn(), blueSpawn = m_Header.m_World->getBlueTeam().getSpawn(); const game::Spawn& redSpawn = m_Header.m_World->getRedTeam().getSpawn(), blueSpawn = m_Header.m_World->getBlueTeam().getSpawn();
const game::TeamCastle& redCastle = m_Header.m_World->getRedTeam().getCastle(), blueCastle = m_Header.m_World->getBlueTeam().getCastle(); const game::TeamCastle& redCastle = m_Header.m_World->getRedTeam().getCastle(), blueCastle = m_Header.m_World->getBlueTeam().getCastle();
@@ -155,6 +159,8 @@ void WorldBeginDataPacket::Deserialize(DataBuffer& data) {
data.SetReadOffset(data.GetReadOffset() + decoPalletteSizeByte); data.SetReadOffset(data.GetReadOffset() + decoPalletteSizeByte);
data >> m_Header.m_Background;
utils::shape::Rectangle redCastle, blueCastle; utils::shape::Rectangle redCastle, blueCastle;
data >> m_Header.m_RedSpawn >> redCastle; data >> m_Header.m_RedSpawn >> redCastle;

View File

@@ -17,7 +17,7 @@
namespace td { namespace td {
namespace render { namespace render {
Renderer::Renderer() { Renderer::Renderer() : m_BackgroundColor(0, 0, 0) {
} }
@@ -86,7 +86,7 @@ void Renderer::updateIsometricFade() {
void Renderer::prepare() { void Renderer::prepare() {
glClear(GL_COLOR_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT);
glClearColor(0, 0, 0, 0); glClearColor(m_BackgroundColor.r, m_BackgroundColor.g, m_BackgroundColor.b, 0);
updateIsometricFade(); updateIsometricFade();
} }

View File

@@ -38,7 +38,7 @@ WorldRenderer::WorldRenderer(game::World* world, client::ClientGame* client) : m
m_TowerPlacePopup = std::make_unique<gui::TowerPlacePopup>(m_Client->getClient()); m_TowerPlacePopup = std::make_unique<gui::TowerPlacePopup>(m_Client->getClient());
m_MobTooltip = std::make_unique<gui::MobTooltip>(m_Client->getClient()); m_MobTooltip = std::make_unique<gui::MobTooltip>(m_Client->getClient());
m_CastleTooltip = std::make_unique<gui::CastleTooltip>(m_Client->getClient()); m_CastleTooltip = std::make_unique<gui::CastleTooltip>(m_Client->getClient());
m_Client->getWorld().getWorldNotifier().bindListener(this); m_Client->getWorldClient().getWorldNotifier().bindListener(this);
} }
void WorldRenderer::updateCursorPos() { void WorldRenderer::updateCursorPos() {
@@ -101,6 +101,8 @@ void WorldRenderer::renderTowers() const {
void WorldRenderer::renderTileSelect() const { void WorldRenderer::renderTileSelect() const {
if (ImGui::IsAnyItemHovered()) return; if (ImGui::IsAnyItemHovered()) return;
if(m_MobTooltip->isShown() || m_CastleTooltip->isShown()) return;
Renderer::Model tileSelectModel; Renderer::Model tileSelectModel;
tileSelectModel.vao = m_SelectTileVao.get(); tileSelectModel.vao = m_SelectTileVao.get();
tileSelectModel.positon = { (int)m_CursorPos.x, (int)m_CursorPos.y }; tileSelectModel.positon = { (int)m_CursorPos.x, (int)m_CursorPos.y };

View File

@@ -14,6 +14,8 @@ GameMenu::GameMenu(client::Client* client) : GuiWidget(client), m_SummonMenu(std
} }
void GameMenu::render() { void GameMenu::render() {
if(!m_Client->isConnected()) return;
if (getClient()->getGame().getGameState() == td::game::GameState::Lobby) { if (getClient()->getGame().getGameState() == td::game::GameState::Lobby) {
ImGui::Begin("Lobby"); ImGui::Begin("Lobby");

View File

@@ -18,6 +18,12 @@ MainMenu::~MainMenu() {
} }
void MainMenu::render() { void MainMenu::render() {
if (m_Server != nullptr && !m_Server->isRunning()) {
m_Server.reset(0); // destroying server if it stoped
}
if(m_Client->isConnected()) return;
ImGui::Begin("Main Menu"); ImGui::Begin("Main Menu");
if (ImGui::Button("Rejoindre une partie##join")) { if (ImGui::Button("Rejoindre une partie##join")) {
ImGui::OpenPopup("Rejoindre une partie##join_popup"); ImGui::OpenPopup("Rejoindre une partie##join_popup");

View File

@@ -22,10 +22,10 @@ namespace td {
namespace render { namespace render {
void TowerGui::initWidgets() { void TowerGui::initWidgets() {
m_MainMenu = std::make_unique<td::gui::MainMenu>(m_Client.get()); m_GuiManager.addWidget(std::make_unique<td::gui::MainMenu>(m_Client.get()));
m_GameMenu = std::make_unique<td::gui::GameMenu>(m_Client.get()); m_GuiManager.addWidget(std::make_unique<td::gui::GameMenu>(m_Client.get()));
m_FrameMenu = std::make_unique<td::gui::FrameMenu>(m_Client.get()); m_GuiManager.addWidget(std::make_unique<td::gui::FrameMenu>(m_Client.get()));
m_UpdateMenu = std::make_unique<td::gui::UpdateMenu>(m_Client.get()); m_GuiManager.addWidget(std::make_unique<td::gui::UpdateMenu>(m_Client.get()));
} }
TowerGui::TowerGui(SDL_Window* sdl_window, SDL_GLContext glContext, td::render::Renderer* renderer) : m_Window(sdl_window), TowerGui::TowerGui(SDL_Window* sdl_window, SDL_GLContext glContext, td::render::Renderer* renderer) : m_Window(sdl_window),
@@ -69,13 +69,8 @@ void TowerGui::render() {
beginFrame(); beginFrame();
m_Client->render(); m_Client->render();
if (m_Client->isConnected())
m_GameMenu->render();
else
m_MainMenu->render();
m_FrameMenu->render(); m_GuiManager.renderWidgets();
m_UpdateMenu->render();
endFrame(); endFrame();
} }

View File

@@ -1,10 +1,3 @@
/*
* EntityShader.cpp
*
* Created on: 4 nov. 2020
* Author: simon
*/
#include "render/shaders/EntityShader.h" #include "render/shaders/EntityShader.h"
#ifdef __ANDROID__ #ifdef __ANDROID__