1er commit
This commit is contained in:
51
include/game/BaseGame.h
Normal file
51
include/game/BaseGame.h
Normal file
@@ -0,0 +1,51 @@
|
||||
#pragma once
|
||||
|
||||
#include "game/Team.h"
|
||||
#include "game/World.h"
|
||||
#include "game/Player.h"
|
||||
|
||||
namespace td {
|
||||
namespace game {
|
||||
|
||||
enum class GameState : std::uint8_t{
|
||||
Lobby,
|
||||
Game,
|
||||
EndGame
|
||||
};
|
||||
|
||||
typedef std::map<std::uint8_t, Player> PlayerList;
|
||||
|
||||
class Game{
|
||||
protected:
|
||||
World* m_World;
|
||||
std::array<Team, 2> m_Teams = {Team{TeamColor::Red}, Team{TeamColor::Blue}};
|
||||
GameState m_GameState = GameState::Lobby;
|
||||
PlayerList m_Players;
|
||||
public:
|
||||
Game(World* world);
|
||||
virtual ~Game();
|
||||
|
||||
virtual void tick(std::uint64_t delta);
|
||||
|
||||
Team& getRedTeam(){ return m_Teams[(std::uint8_t)TeamColor::Red]; }
|
||||
const Team& getRedTeam() const{ return m_Teams[(std::uint8_t)TeamColor::Red]; }
|
||||
|
||||
Team& getBlueTeam(){ return m_Teams[(std::uint8_t)TeamColor::Blue]; }
|
||||
const Team& getBlueTeam() const{ return m_Teams[(std::uint8_t)TeamColor::Blue]; }
|
||||
|
||||
Team& getTeam(TeamColor team){ return m_Teams[(std::uint8_t)team]; }
|
||||
const Team& getTeam(TeamColor team) const{ return m_Teams[(std::uint8_t)team]; }
|
||||
|
||||
GameState getGameState() const{ return m_GameState; }
|
||||
void setGameState(GameState gameState){ m_GameState = gameState; };
|
||||
|
||||
const World* getWorld() const{ return m_World; }
|
||||
World* getWorld(){ return m_World; }
|
||||
|
||||
const PlayerList& getPlayers() const{ return m_Players; }
|
||||
PlayerList& getPlayers(){ return m_Players; }
|
||||
|
||||
};
|
||||
|
||||
} // namespace game
|
||||
} // namespace td
|
||||
36
include/game/Connexion.h
Normal file
36
include/game/Connexion.h
Normal file
@@ -0,0 +1,36 @@
|
||||
#pragma once
|
||||
|
||||
#include "network/TCPSocket.h"
|
||||
#include "protocol/PacketHandler.h"
|
||||
#include "protocol/PacketDispatcher.h"
|
||||
#include "game/Player.h"
|
||||
|
||||
namespace td {
|
||||
namespace protocol {
|
||||
|
||||
class Connexion : public protocol::PacketHandler{
|
||||
protected:
|
||||
protocol::PacketDispatcher m_Dispatcher;
|
||||
private:
|
||||
network::TCPSocket m_Socket;
|
||||
public:
|
||||
Connexion();
|
||||
Connexion(Connexion&& move);
|
||||
Connexion(protocol::PacketDispatcher* dispatcher);
|
||||
Connexion(protocol::PacketDispatcher* dispatcher, network::TCPSocket& socket);
|
||||
virtual ~Connexion();
|
||||
|
||||
virtual bool updateSocket();
|
||||
void closeConnection();
|
||||
|
||||
bool connect(const std::string& address, std::uint16_t port);
|
||||
|
||||
network::Socket::Status getSocketStatus() const{return m_Socket.GetStatus();}
|
||||
|
||||
void sendPacket(protocol::Packet* packet);
|
||||
|
||||
REMOVE_COPY(Connexion);
|
||||
};
|
||||
|
||||
} // namespace server
|
||||
} // namespace td
|
||||
25
include/game/GameManager.h
Normal file
25
include/game/GameManager.h
Normal file
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* GameManager.h
|
||||
*
|
||||
* Created on: 4 nov. 2020
|
||||
* Author: simon
|
||||
*/
|
||||
|
||||
#ifndef GAME_GAMEMANAGER_H_
|
||||
#define GAME_GAMEMANAGER_H_
|
||||
|
||||
namespace GameManager{
|
||||
|
||||
void render();
|
||||
void init();
|
||||
void destroy();
|
||||
void tick();
|
||||
|
||||
void startServer();
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
#endif /* GAME_GAMEMANAGER_H_ */
|
||||
139
include/game/Mobs.h
Normal file
139
include/game/Mobs.h
Normal file
@@ -0,0 +1,139 @@
|
||||
#pragma once
|
||||
|
||||
#include "Towers.h"
|
||||
|
||||
#include <cstdint>
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
|
||||
namespace td {
|
||||
namespace game {
|
||||
|
||||
enum class Direction : std::uint8_t{
|
||||
PositiveX = 1 << 0,
|
||||
NegativeX = 1 << 1,
|
||||
PositiveY = 1 << 2,
|
||||
NegativeY = 1 << 3,
|
||||
};
|
||||
|
||||
enum class EffectType : std::uint8_t{
|
||||
Slowness = 0,
|
||||
Stun,
|
||||
Fire,
|
||||
Poison,
|
||||
Heal,
|
||||
};
|
||||
|
||||
enum class MobType : std::uint8_t{
|
||||
Zombie = 0,
|
||||
Spider,
|
||||
Skeleton,
|
||||
Pigman,
|
||||
Creeper,
|
||||
Silverfish,
|
||||
Blaze,
|
||||
Witch,
|
||||
Slime,
|
||||
Giant
|
||||
};
|
||||
|
||||
typedef std::uint8_t PlayerID;
|
||||
typedef std::uint32_t MobID;
|
||||
typedef std::uint8_t MobLevel;
|
||||
typedef std::vector<TowerType> TowerImmunities;
|
||||
typedef std::vector<EffectType> EffectImmunities;
|
||||
|
||||
class MobStats{
|
||||
private:
|
||||
float m_Damage;
|
||||
float m_Speed;
|
||||
std::uint16_t m_MoneyCost;
|
||||
std::uint16_t m_ExpCost;
|
||||
std::uint16_t m_MaxLife;
|
||||
std::uint16_t m_ExpReward;
|
||||
public:
|
||||
MobStats(float damage, float speed, std::uint16_t moneyCost,
|
||||
std::uint16_t expCost, std::uint16_t maxLife,
|
||||
std::uint16_t expReward): m_Damage(damage), m_Speed(speed),
|
||||
m_MoneyCost(moneyCost), m_ExpCost(expCost), m_MaxLife(maxLife),
|
||||
m_ExpReward(expReward){
|
||||
}
|
||||
|
||||
float getDamage() const{ return m_Damage; }
|
||||
float getMovementSpeed() const{ return m_Speed; }
|
||||
std::uint16_t getMoneyCost() const{ return m_MoneyCost; }
|
||||
std::uint16_t getExpCost() const{ return m_ExpCost; }
|
||||
std::uint16_t getExpReward() const{ return m_ExpReward; }
|
||||
std::uint16_t getMaxLife() const{ return m_MaxLife; }
|
||||
};
|
||||
|
||||
const MobStats* getMobStats(MobType type, std::uint8_t level);
|
||||
const TowerImmunities& getMobTowerImmunities(MobType type, std::uint8_t level);
|
||||
const EffectImmunities& getMobEffectImmunities(MobType type, std::uint8_t level);
|
||||
|
||||
class Mob{
|
||||
protected:
|
||||
float m_Health;
|
||||
private:
|
||||
MobID m_ID;
|
||||
PlayerID m_Sender;
|
||||
MobLevel m_Level;
|
||||
Direction m_Direction;
|
||||
|
||||
float m_X = 0, m_Y = 0;
|
||||
public:
|
||||
Mob(MobID id, MobLevel level, PlayerID sender): m_Sender(sender), m_Level(level){
|
||||
|
||||
}
|
||||
|
||||
virtual MobType getType() const = 0;
|
||||
|
||||
virtual void tick(std::uint64_t delta){}
|
||||
|
||||
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); }
|
||||
float getHealth() const{ return m_Health; }
|
||||
bool isAlive() const{ return m_Health > 0; }
|
||||
|
||||
void damage(float dmg){ m_Health -= dmg; }
|
||||
void heal(float heal){ m_Health = std::min((float)getStats()->getMaxLife(), m_Health + heal); }
|
||||
|
||||
float getX() const{ return m_X; }
|
||||
float setX(float x){ m_X = x; }
|
||||
|
||||
float getY() const{ return m_Y; }
|
||||
float setY(float y){ m_Y = y; }
|
||||
|
||||
Direction getDirection() const{ return m_Direction; }
|
||||
void setDirection(Direction dir){ m_Direction = dir; }
|
||||
protected:
|
||||
void initHealth(){m_Health = (float)getStats()->getMaxLife();}
|
||||
};
|
||||
|
||||
typedef std::shared_ptr<Mob> MobPtr;
|
||||
|
||||
class Zombie : public Mob{
|
||||
public:
|
||||
Zombie(MobID id, std::uint8_t level, PlayerID sender): Mob(id, level, sender){initHealth();}
|
||||
|
||||
virtual MobType getType() const{ return MobType::Zombie; }
|
||||
};
|
||||
|
||||
class Spider : public Mob{
|
||||
public:
|
||||
Spider(MobID id, std::uint8_t level, PlayerID sender): Mob(id, level, sender){initHealth();}
|
||||
|
||||
virtual MobType getType() const{ return MobType::Spider; }
|
||||
};
|
||||
|
||||
namespace MobFactory{
|
||||
MobPtr createMob(MobID id, MobType type, std::uint8_t level, PlayerID sender);
|
||||
}
|
||||
|
||||
|
||||
} // namespace game
|
||||
} // namespace td
|
||||
|
||||
40
include/game/Player.h
Normal file
40
include/game/Player.h
Normal file
@@ -0,0 +1,40 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
|
||||
#include "game/Team.h"
|
||||
|
||||
namespace td{
|
||||
namespace game{
|
||||
|
||||
class Player{
|
||||
private:
|
||||
game::TeamColor m_TeamColor = game::TeamColor::None;
|
||||
|
||||
std::uint32_t m_Gold = 0;
|
||||
std::int32_t m_EXP;
|
||||
std::string m_Name;
|
||||
std::uint8_t m_ID;
|
||||
|
||||
std::uint8_t m_GoldPerSecond = 5;
|
||||
public:
|
||||
Player(std::uint8_t id = 0) : m_ID(id){}
|
||||
|
||||
const std::string& getName() const{return m_Name;}
|
||||
void setName(const std::string& name){m_Name = name;}
|
||||
|
||||
game::TeamColor getTeamColor() const{return m_TeamColor;}
|
||||
void setTeamColor(game::TeamColor teamColor){m_TeamColor = teamColor;}
|
||||
|
||||
std::uint8_t getGoldPerSecond() const{ return m_GoldPerSecond;}
|
||||
void setGoldPerSecond(std::uint8_t goldPerSecond){m_GoldPerSecond = goldPerSecond;}
|
||||
|
||||
std::uint32_t getGold() const{ return m_Gold;}
|
||||
void setGold(std::uint32_t gold){m_Gold = gold;}
|
||||
|
||||
std::uint8_t getID() const{return m_ID;}
|
||||
};
|
||||
|
||||
} // namespace game
|
||||
} // namespace td
|
||||
34
include/game/Team.h
Normal file
34
include/game/Team.h
Normal file
@@ -0,0 +1,34 @@
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
#include <algorithm>
|
||||
|
||||
namespace td {
|
||||
namespace game {
|
||||
|
||||
class Player;
|
||||
|
||||
enum class TeamColor : std::int8_t{
|
||||
None = -1,
|
||||
Red,
|
||||
Blue
|
||||
};
|
||||
|
||||
class Team{
|
||||
private:
|
||||
std::vector<Player*> m_Players;
|
||||
TeamColor m_Color;
|
||||
public:
|
||||
Team(TeamColor color);
|
||||
|
||||
void addPlayer(Player* newPlayer);
|
||||
void removePlayer(const Player* player);
|
||||
|
||||
TeamColor getColor() const;
|
||||
|
||||
std::uint8_t getPlayerCount() const;
|
||||
};
|
||||
|
||||
} // namespace game
|
||||
} // namespace td
|
||||
212
include/game/Towers.h
Normal file
212
include/game/Towers.h
Normal file
@@ -0,0 +1,212 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include "misc/Time.h"
|
||||
|
||||
namespace td {
|
||||
namespace game {
|
||||
|
||||
enum class TowerType : std::uint8_t{
|
||||
Archer = 0,
|
||||
Ice,
|
||||
Sorcerer,
|
||||
Zeus,
|
||||
Mage,
|
||||
Artillery,
|
||||
Quake,
|
||||
Poison,
|
||||
|
||||
Leach,
|
||||
Turret,
|
||||
Necromancer
|
||||
};
|
||||
|
||||
enum class TowerSize : bool{
|
||||
Little = 0, // 3x3
|
||||
Big, // 5x5
|
||||
};
|
||||
|
||||
enum class TowerPath : std::uint8_t{
|
||||
Top = 1, // Base path
|
||||
Bottom
|
||||
};
|
||||
|
||||
class TowerStats{
|
||||
private:
|
||||
float m_Rate;
|
||||
float m_Damage;
|
||||
std::uint8_t m_Range;
|
||||
public:
|
||||
TowerStats(float rate, float damage, std::uint8_t range): m_Rate(rate), m_Damage(damage),
|
||||
m_Range(range){
|
||||
}
|
||||
|
||||
float getDamageRate() const{ return m_Rate; }
|
||||
float getDamage() const{ return m_Damage; }
|
||||
std::uint8_t getRange() const{ return m_Range; }
|
||||
};
|
||||
|
||||
class TowerLevel{
|
||||
private:
|
||||
// 1, 2, 3, 4
|
||||
std::uint8_t m_Level : 3;
|
||||
// 0 : base path 1 : top path (if there is bottom path) 2 : bottom path (if there is top path)
|
||||
TowerPath m_Path : 1;
|
||||
public:
|
||||
TowerLevel(): m_Level(1), m_Path(TowerPath::Top){}
|
||||
TowerLevel(std::uint8_t level, TowerPath path): m_Level(level), m_Path(path){}
|
||||
|
||||
std::uint8_t getLevel() const{ return m_Level; }
|
||||
TowerPath getPath() const{ return m_Path; }
|
||||
|
||||
void setLevel(std::uint8_t level){ m_Level = level; }
|
||||
void setPath(TowerPath path){ m_Path = path; }
|
||||
|
||||
// operator to sort maps
|
||||
friend bool operator<(const TowerLevel& level, const TowerLevel& other){
|
||||
return level.getLevel() * (std::uint8_t)level.getPath() <
|
||||
other.getLevel() * (std::uint8_t)other.getPath();
|
||||
}
|
||||
};
|
||||
|
||||
const TowerStats* getTowerStats(TowerType type, TowerLevel level);
|
||||
|
||||
class Tower{
|
||||
private:
|
||||
std::uint16_t m_X, m_Y;
|
||||
TowerLevel m_Level{};
|
||||
protected:
|
||||
utils::Timer m_Timer;
|
||||
public: // converting seconds to millis
|
||||
Tower(std::uint16_t x, std::uint16_t y): m_X(x), m_Y(y), m_Timer(getStats()->getDamageRate() * 1000){}
|
||||
|
||||
virtual TowerType getType() const = 0;
|
||||
virtual TowerSize getSize() const = 0;
|
||||
virtual void tick(std::uint64_t delta) = 0;
|
||||
|
||||
void upgrade(std::uint8_t level, TowerPath path){
|
||||
m_Level.setLevel(level);
|
||||
m_Level.setPath(path);
|
||||
}
|
||||
|
||||
std::uint16_t getX() const{ return m_X; }
|
||||
std::uint16_t getY() const{ return m_Y; }
|
||||
const TowerLevel& getLevel() const{ return m_Level; }
|
||||
const TowerStats* getStats() const{ return getTowerStats(getType(), m_Level); }
|
||||
|
||||
};
|
||||
|
||||
// ---------- Little Towers ----------
|
||||
|
||||
class LittleTower : public Tower{
|
||||
public:
|
||||
LittleTower(std::uint16_t x, std::uint16_t y): Tower(x, y){}
|
||||
|
||||
virtual TowerSize getSize() const{ return TowerSize::Little; }
|
||||
|
||||
virtual TowerType getType() const = 0;
|
||||
virtual void tick(std::uint64_t delta) = 0;
|
||||
};
|
||||
|
||||
class ArcherTower : public LittleTower{
|
||||
public:
|
||||
ArcherTower(std::uint16_t x, std::uint16_t y): LittleTower(x, y){}
|
||||
|
||||
virtual TowerType getType() const{ return TowerType::Archer; }
|
||||
virtual void tick(std::uint64_t delta);
|
||||
};
|
||||
|
||||
class IceTower : public LittleTower{
|
||||
public:
|
||||
IceTower(std::uint16_t x, std::uint16_t y): LittleTower(x, y){}
|
||||
|
||||
virtual TowerType getType() const{ return TowerType::Ice; }
|
||||
virtual void tick(std::uint64_t delta);
|
||||
};
|
||||
|
||||
class MageTower : public LittleTower{
|
||||
public:
|
||||
MageTower(std::uint16_t x, std::uint16_t y): LittleTower(x, y){}
|
||||
|
||||
virtual TowerType getType() const{ return TowerType::Mage; }
|
||||
virtual void tick(std::uint64_t delta);
|
||||
};
|
||||
|
||||
class PoisonTower : public LittleTower{
|
||||
public:
|
||||
PoisonTower(std::uint16_t x, std::uint16_t y): LittleTower(x, y){}
|
||||
|
||||
virtual TowerType getType() const{ return TowerType::Poison; }
|
||||
virtual void tick(std::uint64_t delta);
|
||||
};
|
||||
|
||||
class QuakeTower : public LittleTower{
|
||||
public:
|
||||
QuakeTower(std::uint16_t x, std::uint16_t y): LittleTower(x, y){}
|
||||
|
||||
virtual TowerType getType() const{ return TowerType::Quake; }
|
||||
virtual void tick(std::uint64_t delta);
|
||||
};
|
||||
|
||||
class ArtilleryTower : public LittleTower{
|
||||
public:
|
||||
ArtilleryTower(std::uint16_t x, std::uint16_t y): LittleTower(x, y){}
|
||||
|
||||
virtual TowerType getType() const{ return TowerType::Artillery; }
|
||||
virtual void tick(std::uint64_t delta);
|
||||
};
|
||||
|
||||
class SorcererTower : public LittleTower{
|
||||
public:
|
||||
SorcererTower(std::uint16_t x, std::uint16_t y): LittleTower(x, y){}
|
||||
|
||||
virtual TowerType getType() const{ return TowerType::Sorcerer; }
|
||||
virtual void tick(std::uint64_t delta);
|
||||
};
|
||||
|
||||
class ZeusTower : public LittleTower{
|
||||
public:
|
||||
ZeusTower(std::uint16_t x, std::uint16_t y): LittleTower(x, y){}
|
||||
|
||||
virtual TowerType getType() const{ return TowerType::Zeus; }
|
||||
virtual void tick(std::uint64_t delta);
|
||||
};
|
||||
|
||||
// ---------- Big Towers ----------
|
||||
|
||||
class BigTower : public Tower{
|
||||
public:
|
||||
BigTower(std::uint16_t x, std::uint16_t y): Tower(x, y){}
|
||||
|
||||
virtual TowerSize getSize() const{ return TowerSize::Big; }
|
||||
|
||||
virtual TowerType getType() const = 0;
|
||||
virtual void tick(std::uint64_t delta) = 0;
|
||||
};
|
||||
|
||||
class TurretTower : public BigTower{
|
||||
public:
|
||||
TurretTower(std::uint16_t x, std::uint16_t y): BigTower(x, y){}
|
||||
|
||||
virtual TowerType getType() const{ return TowerType::Turret; }
|
||||
virtual void tick(std::uint64_t delta);
|
||||
};
|
||||
|
||||
class NecromancerTower : public BigTower{
|
||||
public:
|
||||
NecromancerTower(std::uint16_t x, std::uint16_t y): BigTower(x, y){}
|
||||
|
||||
virtual TowerType getType() const{ return TowerType::Necromancer; }
|
||||
virtual void tick(std::uint64_t delta);
|
||||
};
|
||||
|
||||
class LeachTower : public BigTower{
|
||||
public:
|
||||
LeachTower(std::uint16_t x, std::uint16_t y): BigTower(x, y){}
|
||||
|
||||
virtual TowerType getType() const{ return TowerType::Leach; }
|
||||
virtual void tick(std::uint64_t delta);
|
||||
};
|
||||
|
||||
} // namespace game
|
||||
} // namespace td
|
||||
190
include/game/World.h
Normal file
190
include/game/World.h
Normal file
@@ -0,0 +1,190 @@
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include <unordered_map>
|
||||
#include "Mobs.h"
|
||||
#include "Team.h"
|
||||
|
||||
namespace td{
|
||||
namespace game{
|
||||
typedef std::pair<std::int16_t, std::int16_t> ChunkCoord;
|
||||
}
|
||||
}
|
||||
namespace std{
|
||||
template <>
|
||||
struct hash<td::game::ChunkCoord>{
|
||||
std::size_t operator()(const td::game::ChunkCoord& key) const{
|
||||
// Compute individual hash values for first,
|
||||
// second and third and combine them using XOR
|
||||
// and bit shifting:
|
||||
return ((std::hash<std::int16_t>()(key.first) ^ (std::hash<std::int16_t>()(key.second) << 1)) >> 1);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
namespace td {
|
||||
|
||||
namespace protocol {
|
||||
|
||||
class WorldBeginDataPacket;
|
||||
class WorldDataPacket;
|
||||
|
||||
}
|
||||
|
||||
namespace game {
|
||||
|
||||
class Game;
|
||||
|
||||
enum class TileType : std::uint8_t{
|
||||
None = 0,
|
||||
Tower,
|
||||
Walk,
|
||||
Decoration,
|
||||
/*Heal,
|
||||
Lava,
|
||||
Bedrock,
|
||||
Freeze,
|
||||
Ice,*/
|
||||
};
|
||||
|
||||
struct Color{
|
||||
std::uint8_t r, g, b;
|
||||
};
|
||||
|
||||
struct Tile{
|
||||
virtual TileType getType() const = 0;
|
||||
};
|
||||
|
||||
struct TowerTile : Tile{
|
||||
std::uint8_t color_palette_ref;
|
||||
TeamColor team_owner;
|
||||
|
||||
virtual TileType getType() const{ return TileType::Tower; }
|
||||
};
|
||||
|
||||
struct WalkableTile : Tile{
|
||||
Direction direction;
|
||||
|
||||
virtual TileType getType() const{ return TileType::Walk; }
|
||||
};
|
||||
|
||||
struct DecorationTile : Tile{
|
||||
std::uint16_t color_palette_ref;
|
||||
|
||||
virtual TileType getType() const{ return TileType::Decoration; }
|
||||
};
|
||||
|
||||
struct Spawn{
|
||||
Direction direction;
|
||||
std::int32_t x, y;
|
||||
};
|
||||
|
||||
struct TeamCastle{
|
||||
std::int32_t x, y;
|
||||
std::uint16_t life = 1000;
|
||||
};
|
||||
|
||||
typedef std::shared_ptr<Tile> TilePtr;
|
||||
typedef std::vector<std::uint16_t> ChunkPalette;
|
||||
|
||||
typedef std::shared_ptr<WalkableTile> WalkableTilePtr;
|
||||
|
||||
typedef std::array<std::uint16_t, 32 * 32> ChunkData;
|
||||
typedef std::uint32_t TileIndex;
|
||||
|
||||
//32 x 32 area
|
||||
struct Chunk{
|
||||
enum{ ChunkWidth = 32, ChunkHeight = 32, ChunkSize = ChunkWidth * ChunkHeight };
|
||||
// stores index of tile palette
|
||||
ChunkData tiles{0};
|
||||
ChunkPalette palette;
|
||||
|
||||
TileIndex getTileIndex(std::uint16_t tileNumber) const{
|
||||
TileIndex chunkPaletteIndex = tiles.at(tileNumber);
|
||||
if(chunkPaletteIndex == 0) // index 0 means empty tile index 1 = first tile
|
||||
return 0;
|
||||
return palette.at(chunkPaletteIndex);
|
||||
}
|
||||
};
|
||||
|
||||
typedef std::shared_ptr<Chunk> ChunkPtr;
|
||||
|
||||
typedef std::array<Color, 2> TowerTileColorPalette;
|
||||
|
||||
typedef std::vector<TilePtr> TilePalette;
|
||||
|
||||
typedef std::vector<MobPtr> MobList;
|
||||
|
||||
typedef std::array<Color, 2> SpawnColorPalette;
|
||||
|
||||
|
||||
class World{
|
||||
protected:
|
||||
TowerTileColorPalette m_TowerPlacePalette;
|
||||
Color m_WalkablePalette;
|
||||
std::vector<Color> m_DecorationPalette;
|
||||
|
||||
std::unordered_map<ChunkCoord, ChunkPtr> m_Chunks;
|
||||
|
||||
SpawnColorPalette m_SpawnColorPalette;
|
||||
|
||||
Spawn m_Spawns[2];
|
||||
TeamCastle m_Castles[2];
|
||||
|
||||
TilePalette m_TilePalette;
|
||||
|
||||
MobList m_Mobs;
|
||||
|
||||
Game* m_Game;
|
||||
public:
|
||||
World(Game* game);
|
||||
|
||||
bool loadMap(const protocol::WorldBeginDataPacket* worldHeader);
|
||||
bool loadMap(const protocol::WorldDataPacket* worldData);
|
||||
|
||||
bool loadMapFromFile(const std::string& fileName);
|
||||
bool saveMap(const std::string& fileName) const;
|
||||
|
||||
void tick(std::uint64_t delta);
|
||||
|
||||
void spawnMobAt(MobID id, MobType type, std::uint8_t level, PlayerID sender, float x, float y, Direction dir);
|
||||
|
||||
TilePtr getTile(std::int32_t x, std::int32_t y);
|
||||
|
||||
const TowerTileColorPalette& getTowerTileColorPalette() const{ return m_TowerPlacePalette; }
|
||||
const Color& getWalkableTileColor() const{ return m_WalkablePalette; }
|
||||
const std::vector<Color>& getDecorationPalette() const{ return m_DecorationPalette; }
|
||||
|
||||
const TilePalette& getTilePalette() const{ return m_TilePalette; }
|
||||
|
||||
TilePtr getTilePtr(TileIndex index) const{
|
||||
if(index == 0)
|
||||
return nullptr;
|
||||
return m_TilePalette.at(index - 1);
|
||||
}
|
||||
|
||||
const std::unordered_map<ChunkCoord, ChunkPtr>& getChunks() const{ return m_Chunks; }
|
||||
|
||||
const Spawn& getRedSpawn() const{ return m_Spawns[(std::size_t) TeamColor::Red]; }
|
||||
const Spawn& getBlueSpawn() const{ return m_Spawns[(std::size_t) TeamColor::Blue]; }
|
||||
|
||||
const Spawn& getSpawn(TeamColor color) const{ return m_Spawns[(std::size_t) color]; }
|
||||
|
||||
const Color& getSpawnColor(TeamColor color) const{ return m_SpawnColorPalette[(std::size_t) color]; }
|
||||
const SpawnColorPalette& getSpawnColors() const{ return m_SpawnColorPalette; }
|
||||
|
||||
const TeamCastle& getRedCastle() const{ return m_Castles[(std::size_t) TeamColor::Red]; }
|
||||
const TeamCastle& getBlueCastle() const{ return m_Castles[(std::size_t) TeamColor::Blue]; }
|
||||
|
||||
const MobList& getMobList() const{ return m_Mobs; }
|
||||
MobList& getMobList(){ return m_Mobs; }
|
||||
|
||||
const Color& getTileColor(TilePtr tile) const;
|
||||
private:
|
||||
void moveMobs(std::uint64_t delta);
|
||||
};
|
||||
|
||||
} // namespace game
|
||||
} // namespace td
|
||||
34
include/game/client/Client.h
Normal file
34
include/game/client/Client.h
Normal file
@@ -0,0 +1,34 @@
|
||||
#pragma once
|
||||
|
||||
#include "ClientConnexion.h"
|
||||
#include "ClientGame.h"
|
||||
|
||||
#include "game/Team.h"
|
||||
#include "game/Player.h"
|
||||
|
||||
namespace td {
|
||||
namespace client {
|
||||
|
||||
class Client{
|
||||
private:
|
||||
ClientConnexion m_Connexion;
|
||||
ClientGame m_Game{m_Connexion.GetDispatcher()};
|
||||
bool m_Connected;
|
||||
public:
|
||||
Client(){}
|
||||
|
||||
const ClientGame& getGame() const{ return m_Game; }
|
||||
const ClientConnexion& getConnexion() const{ return m_Connexion; }
|
||||
|
||||
void tick(std::uint64_t delta);
|
||||
|
||||
void connect(const std::string& address, std::uint16_t port);
|
||||
void closeConnection();
|
||||
|
||||
bool isConnected() const{ return m_Connexion.getSocketStatus() == network::Socket::Connected; }
|
||||
|
||||
void selectTeam(game::TeamColor team);
|
||||
};
|
||||
|
||||
} // namespace client
|
||||
} // namespace td
|
||||
37
include/game/client/ClientConnexion.h
Normal file
37
include/game/client/ClientConnexion.h
Normal file
@@ -0,0 +1,37 @@
|
||||
#pragma once
|
||||
|
||||
#include "protocol/PacketHandler.h"
|
||||
#include "network/TCPSocket.h"
|
||||
#include "game/Connexion.h"
|
||||
|
||||
namespace td {
|
||||
namespace client {
|
||||
|
||||
class ClientConnexion : public protocol::Connexion{
|
||||
private:
|
||||
std::uint8_t m_ConnectionID;
|
||||
std::string m_DisconnectReason;
|
||||
float m_ServerTPS;
|
||||
int m_Ping = 0;
|
||||
public:
|
||||
ClientConnexion();
|
||||
|
||||
virtual bool updateSocket();
|
||||
|
||||
virtual void HandlePacket(protocol::KeepAlivePacket* packet);
|
||||
virtual void HandlePacket(protocol::ConnexionInfoPacket* packet);
|
||||
virtual void HandlePacket(protocol::DisconnectPacket* packet);
|
||||
virtual void HandlePacket(protocol::ServerTpsPacket* packet);
|
||||
|
||||
const std::string& getDisconnectReason() const{ return m_DisconnectReason; }
|
||||
float getServerTPS() const{ return m_ServerTPS; }
|
||||
int getServerPing() const {return m_Ping;}
|
||||
|
||||
REMOVE_COPY(ClientConnexion);
|
||||
private:
|
||||
void registerHandlers();
|
||||
void login();
|
||||
};
|
||||
|
||||
} // namespace client
|
||||
} // namespace td
|
||||
36
include/game/client/ClientGame.h
Normal file
36
include/game/client/ClientGame.h
Normal file
@@ -0,0 +1,36 @@
|
||||
#pragma once
|
||||
|
||||
#include "game/BaseGame.h"
|
||||
#include "protocol/PacketHandler.h"
|
||||
#include "WorldClient.h"
|
||||
|
||||
namespace td {
|
||||
namespace client {
|
||||
|
||||
class ClientGame : public protocol::PacketHandler, public game::Game{
|
||||
private:
|
||||
std::uint8_t m_ConnexionID;
|
||||
std::uint32_t m_LobbyTime = 0;
|
||||
game::Player* m_Player = nullptr;
|
||||
client::WorldClient m_WorldClient{this};
|
||||
public:
|
||||
ClientGame(protocol::PacketDispatcher* dispatcher);
|
||||
virtual ~ClientGame();
|
||||
|
||||
virtual void tick(std::uint64_t delta);
|
||||
|
||||
std::uint32_t getLobbyTime() const{return m_LobbyTime;}
|
||||
const game::Player* getPlayer() const{return m_Player;}
|
||||
|
||||
virtual void HandlePacket(protocol::ConnexionInfoPacket* packet);
|
||||
virtual void HandlePacket(protocol::PlayerJoinPacket* packet);
|
||||
virtual void HandlePacket(protocol::PlayerLeavePacket* packet);
|
||||
virtual void HandlePacket(protocol::PlayerListPacket* packet);
|
||||
virtual void HandlePacket(protocol::UpdatePlayerTeamPacket* packet);
|
||||
virtual void HandlePacket(protocol::UpdateGameStatePacket* packet);
|
||||
virtual void HandlePacket(protocol::UpdateLobbyTimePacket* packet);
|
||||
virtual void HandlePacket(protocol::UpdateMoneyPacket* packet);
|
||||
};
|
||||
|
||||
} // namespace client
|
||||
} // namespace td
|
||||
23
include/game/client/WorldClient.h
Normal file
23
include/game/client/WorldClient.h
Normal file
@@ -0,0 +1,23 @@
|
||||
#pragma once
|
||||
|
||||
#include "game/World.h"
|
||||
#include "protocol/PacketHandler.h"
|
||||
|
||||
namespace td {
|
||||
namespace client {
|
||||
|
||||
class ClientGame;
|
||||
|
||||
class WorldClient : public game::World, public protocol::PacketHandler{
|
||||
private:
|
||||
ClientGame* m_Game;
|
||||
public:
|
||||
WorldClient(ClientGame* game);
|
||||
|
||||
virtual void HandlePacket(protocol::WorldBeginDataPacket* packet);
|
||||
virtual void HandlePacket(protocol::WorldDataPacket* packet);
|
||||
virtual void HandlePacket(protocol::SpawnMobPacket* packet);
|
||||
};
|
||||
|
||||
} // namespace client
|
||||
} // namespace td
|
||||
31
include/game/server/Lobby.h
Normal file
31
include/game/server/Lobby.h
Normal file
@@ -0,0 +1,31 @@
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "misc/Time.h"
|
||||
|
||||
namespace td {
|
||||
namespace server {
|
||||
|
||||
class Server;
|
||||
|
||||
class Lobby{
|
||||
private:
|
||||
Server* m_Server;
|
||||
bool m_GameStarted = false;
|
||||
std::uint64_t m_StartTimerTime = 0;
|
||||
std::vector<std::uint8_t> m_Players;
|
||||
utils::Timer m_Timer;
|
||||
public:
|
||||
Lobby(Server* server);
|
||||
|
||||
void OnPlayerJoin(std::uint8_t playerID);
|
||||
void OnPlayerLeave(std::uint8_t playerID);
|
||||
|
||||
void sendTimeRemaining();
|
||||
|
||||
void tick();
|
||||
};
|
||||
|
||||
} // namespace server
|
||||
} // namespace td
|
||||
96
include/game/server/Server.h
Normal file
96
include/game/server/Server.h
Normal file
@@ -0,0 +1,96 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <map>
|
||||
|
||||
#include "network/TCPListener.h"
|
||||
#include "protocol/Protocol.h"
|
||||
#include "protocol/PacketDispatcher.h"
|
||||
#include "protocol/PacketHandler.h"
|
||||
#include "ServerGame.h"
|
||||
#include "ServerConnexion.h"
|
||||
#include "Lobby.h"
|
||||
|
||||
//#define LOBBY_WAITING_TIME 2 * 60 * 1000
|
||||
#define LOBBY_WAITING_TIME 5 * 1000
|
||||
|
||||
#define SERVER_TPS 20
|
||||
#define SERVER_TICK 1000 / SERVER_TPS
|
||||
|
||||
namespace td {
|
||||
namespace server {
|
||||
|
||||
typedef std::map<std::uint8_t, ServerConnexion> ConnexionMap;
|
||||
|
||||
class TickCounter{
|
||||
private:
|
||||
float m_TPS;
|
||||
std::uint64_t m_LastTPSTime;
|
||||
std::uint8_t m_TickCount;
|
||||
public:
|
||||
TickCounter(){}
|
||||
|
||||
void reset(){
|
||||
m_TPS = SERVER_TPS;
|
||||
m_LastTPSTime = utils::getTime();
|
||||
m_TickCount = 0;
|
||||
}
|
||||
|
||||
bool update(){ // return true when tps is updated
|
||||
m_TickCount++;
|
||||
if (m_TickCount >= SERVER_TPS){
|
||||
std::uint64_t timeElapsedSinceLast20Ticks = td::utils::getTime() - m_LastTPSTime;
|
||||
m_TPS = (float)SERVER_TPS / (float)(timeElapsedSinceLast20Ticks / 1000.0f);
|
||||
m_TickCount = 0;
|
||||
m_LastTPSTime = td::utils::getTime();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
float getTPS() const{ return m_TPS; }
|
||||
};
|
||||
|
||||
class Server{
|
||||
private:
|
||||
network::TCPListener m_Listener;
|
||||
ConnexionMap m_Connections;
|
||||
ServerGame m_Game{this};
|
||||
Lobby m_Lobby{this};
|
||||
TickCounter m_TickCounter;
|
||||
public:
|
||||
Server(const std::string& worldFilePath);
|
||||
virtual ~Server(){}
|
||||
|
||||
bool start(std::uint16_t port);
|
||||
void tick(std::uint64_t delta);
|
||||
void stop();
|
||||
|
||||
void lauchGame();
|
||||
|
||||
void removeConnexion(std::uint8_t connexionID);
|
||||
|
||||
void broadcastPacket(protocol::Packet* packet);
|
||||
|
||||
float getTPS() const{ return m_TickCounter.getTPS(); }
|
||||
|
||||
const ServerGame& getGame() const{ return m_Game; }
|
||||
ServerGame& getGame() { return m_Game; }
|
||||
|
||||
const Lobby& getLobby() const{ return m_Lobby; }
|
||||
const ConnexionMap& getConnexions() const{ return m_Connections; }
|
||||
ConnexionMap& getConnexions(){ return m_Connections; }
|
||||
|
||||
const game::PlayerList& getPlayers() const{ return m_Game.getPlayers(); }
|
||||
game::PlayerList& getPlayers(){ return m_Game.getPlayers(); }
|
||||
|
||||
private:
|
||||
void accept();
|
||||
void updateSockets();
|
||||
|
||||
void OnPlayerJoin(std::uint8_t id);
|
||||
void OnPlayerLeave(std::uint8_t id);
|
||||
};
|
||||
|
||||
} // namespace server
|
||||
} // namespace td
|
||||
56
include/game/server/ServerConnexion.h
Normal file
56
include/game/server/ServerConnexion.h
Normal file
@@ -0,0 +1,56 @@
|
||||
#pragma once
|
||||
|
||||
#include "network/TCPSocket.h"
|
||||
#include "protocol/PacketHandler.h"
|
||||
#include "protocol/PacketDispatcher.h"
|
||||
#include "game/Player.h"
|
||||
#include "game/Connexion.h"
|
||||
|
||||
namespace td{
|
||||
namespace server{
|
||||
|
||||
class Server;
|
||||
|
||||
struct KeepAlive
|
||||
{
|
||||
std::uint64_t keepAliveID = 0;
|
||||
std::uint64_t sendTime;
|
||||
bool recievedResponse = false;
|
||||
};
|
||||
|
||||
|
||||
class ServerConnexion : public protocol::Connexion{
|
||||
private:
|
||||
Server* m_Server = nullptr;
|
||||
std::uint8_t m_ID;
|
||||
KeepAlive m_KeepAlive;
|
||||
game::Player* m_Player;
|
||||
public:
|
||||
ServerConnexion();
|
||||
ServerConnexion(network::TCPSocket& socket, std::uint8_t id);
|
||||
ServerConnexion(ServerConnexion&& move);
|
||||
virtual ~ServerConnexion();
|
||||
|
||||
void setServer(Server* server);
|
||||
|
||||
virtual void HandlePacket(protocol::PlayerLoginPacket* packet);
|
||||
virtual void HandlePacket(protocol::KeepAlivePacket* packet);
|
||||
virtual void HandlePacket(protocol::SelectTeamPacket* packet);
|
||||
virtual void HandlePacket(protocol::DisconnectPacket* packet);
|
||||
|
||||
std::uint8_t getID() const{return m_ID;}
|
||||
const game::Player* getPlayer() const{return m_Player;}
|
||||
game::Player* getPlayer() {return m_Player;}
|
||||
|
||||
virtual bool updateSocket();
|
||||
|
||||
REMOVE_COPY(ServerConnexion);
|
||||
private:
|
||||
void registerHandlers();
|
||||
void checkKeepAlive();
|
||||
void sendKeepAlive();
|
||||
void initConnection();
|
||||
};
|
||||
|
||||
} // namespace server
|
||||
} // namespace td
|
||||
29
include/game/server/ServerGame.h
Normal file
29
include/game/server/ServerGame.h
Normal file
@@ -0,0 +1,29 @@
|
||||
#pragma once
|
||||
|
||||
#include "game/BaseGame.h"
|
||||
#include "misc/Time.h"
|
||||
#include "ServerWorld.h"
|
||||
|
||||
namespace td {
|
||||
namespace server {
|
||||
|
||||
class Server;
|
||||
|
||||
class ServerGame : public game::Game{
|
||||
private:
|
||||
Server* m_Server;
|
||||
ServerWorld m_ServerWorld;
|
||||
utils::Timer m_GoldMineTimer{1000, std::bind(&ServerGame::updateGoldMines, this)};
|
||||
public:
|
||||
ServerGame(Server* server);
|
||||
~ServerGame(){}
|
||||
|
||||
virtual void tick(std::uint64_t delta);
|
||||
void startGame();
|
||||
private:
|
||||
void balanceTeams();
|
||||
void updateGoldMines();
|
||||
};
|
||||
|
||||
} // namespace game
|
||||
} // namespace td
|
||||
21
include/game/server/ServerWorld.h
Normal file
21
include/game/server/ServerWorld.h
Normal file
@@ -0,0 +1,21 @@
|
||||
#pragma once
|
||||
|
||||
#include "game/World.h"
|
||||
|
||||
namespace td {
|
||||
namespace server {
|
||||
|
||||
class Server;
|
||||
class ServerGame;
|
||||
|
||||
class ServerWorld : public game::World{
|
||||
private:
|
||||
game::MobID m_CurrentMobID = 0;
|
||||
Server* m_Server;
|
||||
public:
|
||||
ServerWorld(Server* server, ServerGame* game);
|
||||
void spawnMobs(game::MobType type, std::uint8_t level, game::PlayerID sender, std::uint8_t count);
|
||||
};
|
||||
|
||||
} // namespace server
|
||||
} // namespace td
|
||||
14
include/misc/Compression.h
Normal file
14
include/misc/Compression.h
Normal file
@@ -0,0 +1,14 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include "network/DataBuffer.h"
|
||||
|
||||
namespace td {
|
||||
namespace utils {
|
||||
|
||||
DataBuffer Compress(const DataBuffer& buffer);
|
||||
DataBuffer Decompress(DataBuffer& buffer);
|
||||
DataBuffer Decompress(DataBuffer& buffer, std::size_t packetLength);
|
||||
|
||||
} // namespace utils
|
||||
} // namespace td
|
||||
12
include/misc/Random.h
Normal file
12
include/misc/Random.h
Normal file
@@ -0,0 +1,12 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
namespace td {
|
||||
namespace utils {
|
||||
|
||||
void initRandomizer();
|
||||
std::uint64_t getRandomNumber(std::size_t max);
|
||||
|
||||
} // namespace utils
|
||||
} // namespace td
|
||||
41
include/misc/Time.h
Normal file
41
include/misc/Time.h
Normal file
@@ -0,0 +1,41 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <functional>
|
||||
|
||||
namespace td {
|
||||
namespace utils {
|
||||
|
||||
std::uint64_t getTime();
|
||||
|
||||
|
||||
typedef std::function<void()> TimerExecFunction;
|
||||
|
||||
// utililty class to call function at regular period of time
|
||||
class Timer{
|
||||
private:
|
||||
std::uint64_t m_Interval;
|
||||
TimerExecFunction m_Function;
|
||||
|
||||
std::uint64_t m_LastTime = getTime();
|
||||
std::uint64_t m_InternalTime = 0;
|
||||
public:
|
||||
Timer() : m_Interval(0), m_Function(nullptr){}
|
||||
Timer(std::uint64_t interval) : m_Interval(interval), m_Function(nullptr){}
|
||||
Timer(std::uint64_t interval, TimerExecFunction callback) : m_Interval(interval), m_Function(callback){}
|
||||
|
||||
void update();
|
||||
void update(std::uint64_t delta);
|
||||
|
||||
void reset();
|
||||
|
||||
void setInterval(std::uint64_t newInterval){m_Interval = newInterval;}
|
||||
std::uint64_t getInterval() const{return m_Interval;}
|
||||
|
||||
void setCallbackFunction(TimerExecFunction newCallback){m_Function = newCallback;}
|
||||
TimerExecFunction getCallbackFunction() const{return m_Function;}
|
||||
};
|
||||
|
||||
|
||||
} // namespace utils
|
||||
} // namespace td
|
||||
167
include/network/DataBuffer.h
Normal file
167
include/network/DataBuffer.h
Normal file
@@ -0,0 +1,167 @@
|
||||
#ifndef MCLIB_COMMON_DATA_BUFFER_H_
|
||||
#define MCLIB_COMMON_DATA_BUFFER_H_
|
||||
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
#include <cstring>
|
||||
#include <cassert>
|
||||
#include <string>
|
||||
|
||||
namespace td{
|
||||
|
||||
class DataBuffer{
|
||||
private:
|
||||
typedef std::vector<std::uint8_t> Data;
|
||||
Data m_Buffer;
|
||||
std::size_t m_ReadOffset = 0;
|
||||
|
||||
public:
|
||||
typedef Data::iterator iterator;
|
||||
typedef Data::const_iterator const_iterator;
|
||||
typedef Data::reference reference;
|
||||
typedef Data::const_reference const_reference;
|
||||
|
||||
DataBuffer();
|
||||
DataBuffer(const DataBuffer& other);
|
||||
DataBuffer(const DataBuffer& other, std::size_t offset);
|
||||
DataBuffer(DataBuffer&& other);
|
||||
DataBuffer(const std::string& str);
|
||||
|
||||
DataBuffer& operator=(const DataBuffer& other);
|
||||
DataBuffer& operator=(DataBuffer&& other);
|
||||
|
||||
template <typename T>
|
||||
void Append(T data){
|
||||
std::size_t size = sizeof(data);
|
||||
std::size_t end_pos = m_Buffer.size();
|
||||
m_Buffer.resize(m_Buffer.size() + size);
|
||||
memcpy(&m_Buffer[end_pos], &data, size);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
DataBuffer& operator<<(T data){
|
||||
// Switch to big endian
|
||||
//std::reverse((std::uint8_t*)&data, (std::uint8_t*)&data + sizeof(T));
|
||||
Append(data);
|
||||
return *this;
|
||||
}
|
||||
|
||||
DataBuffer& operator<<(std::string str){
|
||||
m_Buffer.insert(m_Buffer.end(), str.begin(), str.end());
|
||||
return *this;
|
||||
}
|
||||
|
||||
DataBuffer& operator<<(DataBuffer& data){
|
||||
m_Buffer.insert(m_Buffer.end(), data.begin(), data.end());
|
||||
return *this;
|
||||
}
|
||||
|
||||
DataBuffer& operator<<(const DataBuffer& data){
|
||||
m_Buffer.insert(m_Buffer.end(), data.begin(), data.end());
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
DataBuffer& operator>>(T& data){
|
||||
assert(m_ReadOffset + sizeof(T) <= GetSize());
|
||||
data = *(T*)&m_Buffer[m_ReadOffset];
|
||||
//std::reverse((std::uint8_t*)&data, (std::uint8_t*)&data + sizeof(T));
|
||||
m_ReadOffset += sizeof(T);
|
||||
return *this;
|
||||
}
|
||||
|
||||
DataBuffer& operator>>(DataBuffer& data){
|
||||
data.Resize(GetSize() - m_ReadOffset);
|
||||
std::copy(m_Buffer.begin() + m_ReadOffset, m_Buffer.end(), data.begin());
|
||||
m_ReadOffset = m_Buffer.size();
|
||||
return *this;
|
||||
}
|
||||
|
||||
DataBuffer& operator>>(std::string& str){
|
||||
std::size_t stringSize = strlen((const char*) m_Buffer.data() + m_ReadOffset) + 1; // including null character
|
||||
str.resize(stringSize);
|
||||
std::copy(m_Buffer.begin() + m_ReadOffset, m_Buffer.begin() + m_ReadOffset + stringSize, str.begin());
|
||||
m_ReadOffset += stringSize;
|
||||
return *this;
|
||||
}
|
||||
|
||||
void ReadSome(char* buffer, std::size_t amount){
|
||||
assert(m_ReadOffset + amount <= GetSize());
|
||||
std::copy_n(m_Buffer.begin() + m_ReadOffset, amount, buffer);
|
||||
m_ReadOffset += amount;
|
||||
}
|
||||
|
||||
void ReadSome(std::uint8_t* buffer, std::size_t amount){
|
||||
assert(m_ReadOffset + amount <= GetSize());
|
||||
std::copy_n(m_Buffer.begin() + m_ReadOffset, amount, buffer);
|
||||
m_ReadOffset += amount;
|
||||
}
|
||||
|
||||
void ReadSome(DataBuffer& buffer, std::size_t amount){
|
||||
assert(m_ReadOffset + amount <= GetSize());
|
||||
buffer.Resize(amount);
|
||||
std::copy_n(m_Buffer.begin() + m_ReadOffset, amount, buffer.begin());
|
||||
m_ReadOffset += amount;
|
||||
}
|
||||
|
||||
void ReadSome(std::string& buffer, std::size_t amount){
|
||||
assert(m_ReadOffset + amount <= GetSize());
|
||||
buffer.resize(amount);
|
||||
std::copy_n(m_Buffer.begin() + m_ReadOffset, amount, buffer.begin());
|
||||
m_ReadOffset += amount;
|
||||
}
|
||||
|
||||
void Resize(std::size_t size){
|
||||
m_Buffer.resize(size);
|
||||
}
|
||||
|
||||
void Reserve(std::size_t amount){
|
||||
m_Buffer.reserve(amount);
|
||||
}
|
||||
|
||||
void erase(iterator it){
|
||||
m_Buffer.erase(it);
|
||||
}
|
||||
|
||||
void Clear(){
|
||||
m_Buffer.clear();
|
||||
m_ReadOffset = 0;
|
||||
}
|
||||
|
||||
bool IsFinished() const{
|
||||
return m_ReadOffset >= m_Buffer.size();
|
||||
}
|
||||
|
||||
std::uint8_t* data(){
|
||||
return m_Buffer.data();
|
||||
}
|
||||
|
||||
const std::uint8_t* data() const{
|
||||
return m_Buffer.data();
|
||||
}
|
||||
|
||||
std::size_t GetReadOffset() const{ return m_ReadOffset; }
|
||||
void SetReadOffset(std::size_t pos);
|
||||
|
||||
std::string ToString() const;
|
||||
std::size_t GetSize() const;
|
||||
bool IsEmpty() const;
|
||||
std::size_t GetRemaining() const;
|
||||
|
||||
iterator begin();
|
||||
iterator end();
|
||||
const_iterator begin() const;
|
||||
const_iterator end() const;
|
||||
|
||||
reference operator[](Data::size_type i){ return m_Buffer[i]; }
|
||||
const_reference operator[](Data::size_type i) const{ return m_Buffer[i]; }
|
||||
|
||||
bool ReadFile(const std::string& fileName);
|
||||
bool WriteFile(const std::string& fileName);
|
||||
};
|
||||
|
||||
std::ostream& operator<<(std::ostream& os, const DataBuffer& buffer);
|
||||
|
||||
} // ns td
|
||||
|
||||
#endif
|
||||
56
include/network/IPAddress.h
Normal file
56
include/network/IPAddress.h
Normal file
@@ -0,0 +1,56 @@
|
||||
#ifndef NETWORK_IPADDRESS_H_
|
||||
#define NETWORK_IPADDRESS_H_
|
||||
|
||||
#include <string>
|
||||
#include <iosfwd>
|
||||
#include <vector>
|
||||
|
||||
namespace td {
|
||||
namespace network {
|
||||
|
||||
/* IPv4 address */
|
||||
class IPAddress {
|
||||
private:
|
||||
std::uint32_t m_Address;
|
||||
bool m_Valid;
|
||||
|
||||
public:
|
||||
/* Create an invalid address */
|
||||
IPAddress() noexcept;
|
||||
|
||||
/* Initialize by string IP */
|
||||
IPAddress(const std::string& str);
|
||||
|
||||
/* Initialize by string IP */
|
||||
IPAddress(const std::wstring& str);
|
||||
|
||||
/* Initialize by octets */
|
||||
IPAddress(std::uint8_t octet1, std::uint8_t octet2, std::uint8_t octet3, std::uint8_t octet4) noexcept;
|
||||
|
||||
/* Get the specific octet. 1-4 */
|
||||
std::uint8_t GetOctet(std::uint8_t num) const;
|
||||
|
||||
/* Set the specific octet. 1-4 */
|
||||
void SetOctet(std::uint8_t num, std::uint8_t value);
|
||||
|
||||
/* Make sure the IP is valid. It will be invalid if the host wasn't found. */
|
||||
bool IsValid() const noexcept { return m_Valid; }
|
||||
|
||||
std::string ToString() const;
|
||||
|
||||
static IPAddress LocalAddress();
|
||||
|
||||
bool operator==(const IPAddress& right);
|
||||
bool operator!=(const IPAddress& right);
|
||||
bool operator==(bool b);
|
||||
};
|
||||
|
||||
typedef std::vector<IPAddress> IPAddresses;
|
||||
|
||||
std::ostream& operator<<(std::ostream& os, const IPAddress& addr);
|
||||
std::wostream& operator<<(std::wostream& os, const IPAddress& addr);
|
||||
|
||||
} // ns network
|
||||
} // ns td
|
||||
|
||||
#endif
|
||||
32
include/network/Network.h
Normal file
32
include/network/Network.h
Normal file
@@ -0,0 +1,32 @@
|
||||
#ifndef NETWORK_NETWORK_H_
|
||||
#define NETWORK_NETWORK_H_
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <ws2tcpip.h>
|
||||
#pragma comment(lib, "ws2_32.lib")
|
||||
#else
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#endif
|
||||
|
||||
#include "network/Socket.h"
|
||||
#include "network/IPAddress.h"
|
||||
#include "network/UDPSocket.h"
|
||||
#include "network/TCPSocket.h"
|
||||
|
||||
namespace td {
|
||||
namespace network {
|
||||
|
||||
class Dns {
|
||||
public:
|
||||
static IPAddresses Resolve(const std::string& host);
|
||||
};
|
||||
|
||||
} // ns network
|
||||
} // ns td
|
||||
|
||||
#endif
|
||||
90
include/network/Socket.h
Normal file
90
include/network/Socket.h
Normal file
@@ -0,0 +1,90 @@
|
||||
#ifndef NETWORK_SOCKET_H_
|
||||
#define NETWORK_SOCKET_H_
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
|
||||
#include "network/DataBuffer.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <ws2tcpip.h>
|
||||
#include <winsock2.h>
|
||||
#else
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#include <netdb.h>
|
||||
#include <sys/ioctl.h>
|
||||
|
||||
|
||||
#define closesocket close
|
||||
#endif
|
||||
|
||||
#ifndef INVALID_SOCKET
|
||||
#define INVALID_SOCKET -1
|
||||
#endif
|
||||
|
||||
#define REMOVE_COPY(className) \
|
||||
className(const className &) = delete;\
|
||||
className& operator=(const className &) = delete
|
||||
|
||||
namespace td {
|
||||
namespace network {
|
||||
|
||||
class IPAddress;
|
||||
|
||||
typedef int SocketHandle;
|
||||
|
||||
class Socket {
|
||||
public:
|
||||
enum Status { Connected, Disconnected, Error };
|
||||
enum Type { TCP, UDP };
|
||||
|
||||
private:
|
||||
bool m_Blocking;
|
||||
Type m_Type;
|
||||
Status m_Status;
|
||||
|
||||
protected:
|
||||
SocketHandle m_Handle;
|
||||
|
||||
Socket(Type type);
|
||||
void SetStatus(Status status);
|
||||
|
||||
public:
|
||||
virtual ~Socket();
|
||||
|
||||
Socket(Socket&& rhs) = default;
|
||||
Socket& operator=(Socket&& rhs) = default;
|
||||
|
||||
bool SetBlocking(bool block);
|
||||
bool IsBlocking() const noexcept;
|
||||
|
||||
Type GetType() const noexcept;
|
||||
Status GetStatus() const noexcept;
|
||||
SocketHandle GetHandle() const noexcept;
|
||||
|
||||
bool Connect(const std::string& ip, std::uint16_t port);
|
||||
virtual bool Connect(const IPAddress& address, std::uint16_t port) = 0;
|
||||
|
||||
void Disconnect();
|
||||
|
||||
std::size_t Send(const std::string& data);
|
||||
std::size_t Send(DataBuffer& buffer);
|
||||
|
||||
virtual std::size_t Send(const uint8_t* data, std::size_t size) = 0;
|
||||
virtual DataBuffer Receive(std::size_t amount) = 0;
|
||||
|
||||
virtual std::size_t Receive(DataBuffer& buffer, std::size_t amount) = 0;
|
||||
};
|
||||
|
||||
typedef std::shared_ptr<Socket> SocketPtr;
|
||||
|
||||
} // ns network
|
||||
} // ns td
|
||||
|
||||
#endif
|
||||
|
||||
34
include/network/TCPListener.h
Normal file
34
include/network/TCPListener.h
Normal file
@@ -0,0 +1,34 @@
|
||||
#pragma once
|
||||
#include "TCPSocket.h"
|
||||
|
||||
namespace td{
|
||||
namespace network{
|
||||
|
||||
class TCPListener{
|
||||
int m_Handle;
|
||||
std::uint16_t m_Port;
|
||||
int m_MaxConnections;
|
||||
|
||||
public:
|
||||
TCPListener();
|
||||
~TCPListener();
|
||||
|
||||
bool listen(std::uint16_t port, int maxConnections);
|
||||
bool accept(TCPSocket& newSocket);
|
||||
|
||||
void destroy();
|
||||
bool close();
|
||||
bool setBlocking(bool blocking);
|
||||
|
||||
std::uint16_t getListeningPort() const{
|
||||
return m_Port;
|
||||
}
|
||||
int getMaximumConnections() const{
|
||||
return m_MaxConnections;
|
||||
}
|
||||
|
||||
REMOVE_COPY(TCPListener);
|
||||
};
|
||||
|
||||
} // namespace network
|
||||
} // namespace td
|
||||
39
include/network/TCPSocket.h
Normal file
39
include/network/TCPSocket.h
Normal file
@@ -0,0 +1,39 @@
|
||||
#ifndef NETWORK_TCP_SOCKET_H_
|
||||
#define NETWORK_TCP_SOCKET_H_
|
||||
|
||||
#include "network/IPAddress.h"
|
||||
#include "network/Socket.h"
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
namespace td {
|
||||
namespace network {
|
||||
|
||||
class TCPListener;
|
||||
|
||||
class TCPSocket : public Socket {
|
||||
private:
|
||||
IPAddress m_RemoteIP;
|
||||
uint16_t m_Port;
|
||||
sockaddr_in m_RemoteAddr;
|
||||
|
||||
public:
|
||||
TCPSocket();
|
||||
TCPSocket(TCPSocket&& other);
|
||||
|
||||
virtual bool Connect(const IPAddress& address, std::uint16_t port);
|
||||
virtual std::size_t Send(const std::uint8_t* data, std::size_t size);
|
||||
virtual DataBuffer Receive(std::size_t amount);
|
||||
virtual std::size_t Receive(DataBuffer& buffer, std::size_t amount);
|
||||
|
||||
REMOVE_COPY(TCPSocket);
|
||||
|
||||
friend class TCPListener;
|
||||
};
|
||||
|
||||
void SendPacket(const DataBuffer& data, network::TCPSocket& socket);
|
||||
|
||||
} // ns network
|
||||
} // ns td
|
||||
|
||||
#endif
|
||||
29
include/network/UDPSocket.h
Normal file
29
include/network/UDPSocket.h
Normal file
@@ -0,0 +1,29 @@
|
||||
#ifndef NETWORK_UDP_SOCKET_H_
|
||||
#define NETWORK_UDP_SOCKET_H_
|
||||
|
||||
#include "network/IPAddress.h"
|
||||
#include "network/Socket.h"
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
namespace td {
|
||||
namespace network {
|
||||
|
||||
class UDPSocket : public Socket {
|
||||
private:
|
||||
IPAddress m_RemoteIP;
|
||||
uint16_t m_Port;
|
||||
sockaddr_in m_RemoteAddr;
|
||||
|
||||
public:
|
||||
UDPSocket();
|
||||
|
||||
bool Connect(const IPAddress& address, std::uint16_t port);
|
||||
std::size_t Send(const std::uint8_t* data, std::size_t size);
|
||||
DataBuffer Receive(std::size_t amount);
|
||||
};
|
||||
|
||||
} // ns network
|
||||
} // ns td
|
||||
|
||||
#endif
|
||||
33
include/protocol/PacketDispatcher.h
Normal file
33
include/protocol/PacketDispatcher.h
Normal file
@@ -0,0 +1,33 @@
|
||||
#pragma once
|
||||
|
||||
#include "protocol/Protocol.h"
|
||||
|
||||
#include <map>
|
||||
#include <vector>
|
||||
|
||||
namespace td {
|
||||
namespace protocol {
|
||||
|
||||
class PacketHandler;
|
||||
|
||||
class PacketDispatcher {
|
||||
private:
|
||||
std::map<PacketType, std::vector<PacketHandler*>> m_Handlers;
|
||||
|
||||
public:
|
||||
PacketDispatcher() = default;
|
||||
|
||||
PacketDispatcher(const PacketDispatcher& rhs) = delete;
|
||||
PacketDispatcher& operator=(const PacketDispatcher& rhs) = delete;
|
||||
PacketDispatcher(PacketDispatcher&& rhs) = delete;
|
||||
PacketDispatcher& operator=(PacketDispatcher&& rhs) = delete;
|
||||
|
||||
void Dispatch(Packet* packet);
|
||||
|
||||
void RegisterHandler(PacketType type, PacketHandler* handler);
|
||||
void UnregisterHandler(PacketType type, PacketHandler* handler);
|
||||
void UnregisterHandler(PacketHandler* handler);
|
||||
};
|
||||
|
||||
} // namespace protocol
|
||||
} // namespace td
|
||||
13
include/protocol/PacketFactory.h
Normal file
13
include/protocol/PacketFactory.h
Normal file
@@ -0,0 +1,13 @@
|
||||
#pragma once
|
||||
|
||||
#include "protocol/Protocol.h"
|
||||
|
||||
namespace td {
|
||||
namespace protocol {
|
||||
namespace PacketFactory {
|
||||
|
||||
Packet* createPacket(PacketType type, DataBuffer& buffer);
|
||||
|
||||
}
|
||||
} // namespace protocol
|
||||
} // namespace td
|
||||
39
include/protocol/PacketHandler.h
Normal file
39
include/protocol/PacketHandler.h
Normal file
@@ -0,0 +1,39 @@
|
||||
#pragma once
|
||||
|
||||
#include "protocol/Protocol.h"
|
||||
|
||||
namespace td {
|
||||
namespace protocol {
|
||||
|
||||
class PacketDispatcher;
|
||||
|
||||
class PacketHandler{
|
||||
private:
|
||||
PacketDispatcher* m_Dispatcher;
|
||||
public:
|
||||
PacketHandler(PacketDispatcher* dispatcher) : m_Dispatcher(dispatcher){}
|
||||
virtual ~PacketHandler(){}
|
||||
|
||||
PacketDispatcher* GetDispatcher(){return m_Dispatcher;}
|
||||
|
||||
virtual void HandlePacket(PlayerLoginPacket* packet){}
|
||||
virtual void HandlePacket(WorldBeginDataPacket* packet){}
|
||||
virtual void HandlePacket(WorldDataPacket* packet){}
|
||||
virtual void HandlePacket(KeepAlivePacket* packet){}
|
||||
virtual void HandlePacket(UpdateMoneyPacket* packet){}
|
||||
virtual void HandlePacket(UpdateExpPacket* packet){}
|
||||
virtual void HandlePacket(UpdateLobbyTimePacket* packet){}
|
||||
virtual void HandlePacket(UpdateGameStatePacket* packet){}
|
||||
virtual void HandlePacket(PlayerListPacket* packet){}
|
||||
virtual void HandlePacket(PlayerJoinPacket* packet){}
|
||||
virtual void HandlePacket(PlayerLeavePacket* packet){}
|
||||
virtual void HandlePacket(ConnexionInfoPacket* packet){}
|
||||
virtual void HandlePacket(SelectTeamPacket* packet){}
|
||||
virtual void HandlePacket(UpdatePlayerTeamPacket* packet){}
|
||||
virtual void HandlePacket(DisconnectPacket* packet){}
|
||||
virtual void HandlePacket(ServerTpsPacket* packet){}
|
||||
virtual void HandlePacket(SpawnMobPacket* packet){}
|
||||
};
|
||||
|
||||
} // namespace protocol
|
||||
} // namespace td
|
||||
384
include/protocol/Protocol.h
Normal file
384
include/protocol/Protocol.h
Normal file
@@ -0,0 +1,384 @@
|
||||
#pragma once
|
||||
|
||||
#include "network/DataBuffer.h"
|
||||
#include "game/World.h"
|
||||
#include "game/BaseGame.h"
|
||||
|
||||
namespace td {
|
||||
namespace protocol {
|
||||
|
||||
class PacketHandler;
|
||||
|
||||
enum class PacketType : std::uint8_t{
|
||||
PlayerLogin = 0,
|
||||
PlayerJoin,
|
||||
PlayerLeave,
|
||||
WorldBeginData,
|
||||
WorldData,
|
||||
ChunkData,
|
||||
KeepAlive,
|
||||
UpdateMoney,
|
||||
UpdateEXP,
|
||||
UpdateLobbyTime,
|
||||
UpdateGameState,
|
||||
Disconnect,
|
||||
PlayerList,
|
||||
ConnectionInfo,
|
||||
SelectTeam,
|
||||
UpdatePlayerTeam,
|
||||
ServerTps,
|
||||
SpawnMob,
|
||||
};
|
||||
|
||||
class Packet{
|
||||
public:
|
||||
Packet(){}
|
||||
virtual ~Packet(){}
|
||||
|
||||
virtual DataBuffer Serialize() const = 0;
|
||||
virtual void Deserialize(DataBuffer& data) = 0;
|
||||
virtual void Dispatch(PacketHandler* handler) = 0;
|
||||
|
||||
virtual PacketType getType() const = 0;
|
||||
std::uint8_t getID() const{ return (std::uint8_t)getType(); }
|
||||
};
|
||||
|
||||
|
||||
class KeepAlivePacket : public Packet{
|
||||
private:
|
||||
std::uint64_t m_AliveID;
|
||||
public:
|
||||
KeepAlivePacket(){}
|
||||
KeepAlivePacket(std::uint64_t aliveID): m_AliveID(aliveID){}
|
||||
virtual ~KeepAlivePacket(){}
|
||||
|
||||
virtual DataBuffer Serialize() const;
|
||||
virtual void Deserialize(DataBuffer& data);
|
||||
virtual void Dispatch(PacketHandler* handler);
|
||||
|
||||
std::uint64_t getAliveID(){ return m_AliveID; }
|
||||
|
||||
virtual PacketType getType() const{ return PacketType::KeepAlive; }
|
||||
};
|
||||
|
||||
class PlayerLoginPacket : public Packet{
|
||||
private:
|
||||
std::string m_PlayerName;
|
||||
public:
|
||||
PlayerLoginPacket(){}
|
||||
PlayerLoginPacket(std::string playerName): m_PlayerName(playerName){}
|
||||
virtual ~PlayerLoginPacket(){}
|
||||
|
||||
virtual DataBuffer Serialize() const;
|
||||
virtual void Deserialize(DataBuffer& data);
|
||||
virtual void Dispatch(PacketHandler* handler);
|
||||
|
||||
virtual PacketType getType() const{ return PacketType::PlayerLogin; }
|
||||
|
||||
const std::string& getPlayerName(){ return m_PlayerName; }
|
||||
};
|
||||
|
||||
class WorldBeginDataPacket : public Packet{
|
||||
private:
|
||||
game::TowerTileColorPalette m_TowerPlacePalette;
|
||||
game::Color m_WalkablePalette;
|
||||
std::vector<game::Color> m_DecorationPalette;
|
||||
|
||||
game::SpawnColorPalette m_SpawnColorPalette;
|
||||
|
||||
game::TilePalette m_TilePalette;
|
||||
|
||||
game::Spawn m_RedSpawn, m_BlueSpawn;
|
||||
game::TeamCastle m_RedTower, m_BlueTower;
|
||||
|
||||
const game::World* m_World;
|
||||
public:
|
||||
WorldBeginDataPacket(){}
|
||||
WorldBeginDataPacket(const game::World* world): m_World(world){}
|
||||
virtual ~WorldBeginDataPacket(){}
|
||||
|
||||
virtual DataBuffer Serialize() const;
|
||||
virtual void Deserialize(DataBuffer& data);
|
||||
virtual void Dispatch(PacketHandler* handler);
|
||||
|
||||
virtual PacketType getType() const{ return PacketType::WorldBeginData; }
|
||||
|
||||
const game::TowerTileColorPalette& getTowerTilePalette() const{ return m_TowerPlacePalette; }
|
||||
const game::Color& getWalkableTileColor() const{ return m_WalkablePalette; }
|
||||
const std::vector<game::Color>& getDecorationPalette() const{ return m_DecorationPalette; }
|
||||
|
||||
const game::Spawn& getRedSpawn() const{ return m_RedSpawn; }
|
||||
const game::Spawn& getBlueSpawn() const{ return m_BlueSpawn; }
|
||||
|
||||
const game::SpawnColorPalette& getSpawnPalette() const{ return m_SpawnColorPalette; }
|
||||
|
||||
const game::TeamCastle& getRedCastle() const{ return m_RedTower; }
|
||||
const game::TeamCastle& getBlueCastle() const{ return m_BlueTower; }
|
||||
|
||||
const game::TilePalette getTilePalette() const{ return m_TilePalette; }
|
||||
};
|
||||
|
||||
class WorldDataPacket : public Packet{
|
||||
private:
|
||||
std::unordered_map<game::ChunkCoord, game::ChunkPtr> m_Chunks;
|
||||
|
||||
const game::World* m_World;
|
||||
public:
|
||||
WorldDataPacket(){}
|
||||
WorldDataPacket(const game::World* world): m_World(world){}
|
||||
virtual ~WorldDataPacket(){}
|
||||
|
||||
virtual DataBuffer Serialize() const;
|
||||
virtual void Deserialize(DataBuffer& data);
|
||||
virtual void Dispatch(PacketHandler* handler);
|
||||
|
||||
virtual PacketType getType() const{ return PacketType::WorldData; }
|
||||
|
||||
const std::unordered_map<game::ChunkCoord, game::ChunkPtr>& getChunks() const{ return m_Chunks; }
|
||||
};
|
||||
|
||||
class UpdateMoneyPacket : public Packet{
|
||||
private:
|
||||
std::uint32_t m_NewAmount;
|
||||
public:
|
||||
UpdateMoneyPacket(){}
|
||||
UpdateMoneyPacket(std::uint32_t newAmount): m_NewAmount(newAmount){}
|
||||
virtual ~UpdateMoneyPacket(){}
|
||||
|
||||
std::uint32_t getGold() const{ return m_NewAmount; }
|
||||
|
||||
virtual DataBuffer Serialize() const;
|
||||
virtual void Deserialize(DataBuffer& data);
|
||||
virtual void Dispatch(PacketHandler* handler);
|
||||
|
||||
virtual PacketType getType() const{ return PacketType::UpdateMoney; }
|
||||
};
|
||||
|
||||
class UpdateExpPacket : public Packet{
|
||||
private:
|
||||
std::uint32_t m_NewAmount;
|
||||
public:
|
||||
UpdateExpPacket(){}
|
||||
UpdateExpPacket(std::uint32_t newAmount): m_NewAmount(newAmount){}
|
||||
virtual ~UpdateExpPacket(){}
|
||||
|
||||
virtual DataBuffer Serialize() const;
|
||||
virtual void Deserialize(DataBuffer& data);
|
||||
virtual void Dispatch(PacketHandler* handler);
|
||||
|
||||
virtual PacketType getType() const{ return PacketType::UpdateEXP; }
|
||||
};
|
||||
|
||||
class UpdateLobbyTimePacket : public Packet{
|
||||
private:
|
||||
std::uint32_t m_RemainingTime;
|
||||
public:
|
||||
UpdateLobbyTimePacket(){}
|
||||
UpdateLobbyTimePacket(std::uint32_t remainingTime): m_RemainingTime(remainingTime){}
|
||||
virtual ~UpdateLobbyTimePacket(){}
|
||||
|
||||
virtual DataBuffer Serialize() const;
|
||||
virtual void Deserialize(DataBuffer& data);
|
||||
virtual void Dispatch(PacketHandler* handler);
|
||||
|
||||
std::uint32_t getRemainingTime() const{ return m_RemainingTime; }
|
||||
|
||||
virtual PacketType getType() const{ return PacketType::UpdateLobbyTime; }
|
||||
};
|
||||
|
||||
class UpdateGameStatePacket : public Packet{
|
||||
private:
|
||||
game::GameState m_GameState;
|
||||
public:
|
||||
UpdateGameStatePacket(){}
|
||||
UpdateGameStatePacket(game::GameState gameState): m_GameState(gameState){}
|
||||
virtual ~UpdateGameStatePacket(){}
|
||||
|
||||
virtual DataBuffer Serialize() const;
|
||||
virtual void Deserialize(DataBuffer& data);
|
||||
virtual void Dispatch(PacketHandler* handler);
|
||||
|
||||
game::GameState getGameState() const{ return m_GameState; }
|
||||
|
||||
virtual PacketType getType() const{ return PacketType::UpdateGameState; }
|
||||
};
|
||||
|
||||
struct PlayerInfo{
|
||||
std::string name;
|
||||
game::TeamColor team;
|
||||
};
|
||||
|
||||
class PlayerListPacket : public Packet{
|
||||
private:
|
||||
std::map<std::uint8_t, PlayerInfo> m_Players;
|
||||
public:
|
||||
PlayerListPacket(){}
|
||||
PlayerListPacket(std::map<std::uint8_t, PlayerInfo> players): m_Players(players){}
|
||||
virtual ~PlayerListPacket(){}
|
||||
|
||||
virtual DataBuffer Serialize() const;
|
||||
virtual void Deserialize(DataBuffer& data);
|
||||
virtual void Dispatch(PacketHandler* handler);
|
||||
|
||||
const std::map<std::uint8_t, PlayerInfo>& getPlayers() const{ return m_Players; }
|
||||
|
||||
virtual PacketType getType() const{ return PacketType::PlayerList; }
|
||||
};
|
||||
|
||||
class PlayerJoinPacket : public Packet{
|
||||
private:
|
||||
std::uint8_t m_PlayerID;
|
||||
std::string m_PlayerName;
|
||||
public:
|
||||
PlayerJoinPacket(){}
|
||||
PlayerJoinPacket(std::uint8_t playerID, const std::string& playerName): m_PlayerID(playerID), m_PlayerName(playerName){}
|
||||
virtual ~PlayerJoinPacket(){}
|
||||
|
||||
virtual DataBuffer Serialize() const;
|
||||
virtual void Deserialize(DataBuffer& data);
|
||||
virtual void Dispatch(PacketHandler* handler);
|
||||
|
||||
std::uint8_t getPlayerID() const{ return m_PlayerID; }
|
||||
const std::string& getPlayerName() const{ return m_PlayerName; }
|
||||
|
||||
virtual PacketType getType() const{ return PacketType::PlayerJoin; }
|
||||
};
|
||||
|
||||
class PlayerLeavePacket : public Packet{
|
||||
private:
|
||||
std::uint8_t m_PlayerID;
|
||||
public:
|
||||
PlayerLeavePacket(){}
|
||||
PlayerLeavePacket(std::uint8_t playerID): m_PlayerID(playerID){}
|
||||
virtual ~PlayerLeavePacket(){}
|
||||
|
||||
virtual DataBuffer Serialize() const;
|
||||
virtual void Deserialize(DataBuffer& data);
|
||||
virtual void Dispatch(PacketHandler* handler);
|
||||
|
||||
std::uint8_t getPlayerID() const{ return m_PlayerID; }
|
||||
|
||||
virtual PacketType getType() const{ return PacketType::PlayerLeave; }
|
||||
};
|
||||
|
||||
class ConnexionInfoPacket : public Packet{
|
||||
private:
|
||||
std::uint8_t m_ConnectionID;
|
||||
public:
|
||||
ConnexionInfoPacket(){}
|
||||
ConnexionInfoPacket(std::uint8_t connectionID): m_ConnectionID(connectionID){}
|
||||
virtual ~ConnexionInfoPacket(){}
|
||||
|
||||
virtual DataBuffer Serialize() const;
|
||||
virtual void Deserialize(DataBuffer& data);
|
||||
virtual void Dispatch(PacketHandler* handler);
|
||||
|
||||
std::uint8_t getConnectionID() const{ return m_ConnectionID; }
|
||||
|
||||
virtual PacketType getType() const{ return PacketType::ConnectionInfo; }
|
||||
};
|
||||
|
||||
class SelectTeamPacket : public Packet{
|
||||
private:
|
||||
game::TeamColor m_SelectedTeam;
|
||||
public:
|
||||
SelectTeamPacket(){}
|
||||
SelectTeamPacket(game::TeamColor selectedTeam): m_SelectedTeam(selectedTeam){}
|
||||
virtual ~SelectTeamPacket(){}
|
||||
|
||||
virtual DataBuffer Serialize() const;
|
||||
virtual void Deserialize(DataBuffer& data);
|
||||
virtual void Dispatch(PacketHandler* handler);
|
||||
|
||||
game::TeamColor getSelectedTeam() const{ return m_SelectedTeam; }
|
||||
|
||||
virtual PacketType getType() const{ return PacketType::SelectTeam; }
|
||||
};
|
||||
|
||||
class UpdatePlayerTeamPacket : public Packet{
|
||||
private:
|
||||
std::uint8_t m_PlayerID;
|
||||
game::TeamColor m_SelectedTeam;
|
||||
public:
|
||||
UpdatePlayerTeamPacket(){}
|
||||
UpdatePlayerTeamPacket(std::uint8_t playerID, game::TeamColor selectedTeam): m_PlayerID(playerID), m_SelectedTeam(selectedTeam){}
|
||||
virtual ~UpdatePlayerTeamPacket(){}
|
||||
|
||||
virtual DataBuffer Serialize() const;
|
||||
virtual void Deserialize(DataBuffer& data);
|
||||
virtual void Dispatch(PacketHandler* handler);
|
||||
|
||||
game::TeamColor getSelectedTeam() const{ return m_SelectedTeam; }
|
||||
std::uint8_t getPlayerID() const{ return m_PlayerID; }
|
||||
|
||||
virtual PacketType getType() const{ return PacketType::UpdatePlayerTeam; }
|
||||
};
|
||||
|
||||
class DisconnectPacket : public Packet{
|
||||
private:
|
||||
std::string m_Reason; // only when sent from server
|
||||
public:
|
||||
DisconnectPacket(){}
|
||||
DisconnectPacket(std::string reason): m_Reason(reason){}
|
||||
virtual ~DisconnectPacket(){}
|
||||
|
||||
virtual DataBuffer Serialize() const;
|
||||
virtual void Deserialize(DataBuffer& data);
|
||||
virtual void Dispatch(PacketHandler* handler);
|
||||
|
||||
const std::string& getReason() const{ return m_Reason; }
|
||||
|
||||
virtual PacketType getType() const{ return PacketType::Disconnect; }
|
||||
};
|
||||
|
||||
class ServerTpsPacket : public Packet{
|
||||
private:
|
||||
float m_TPS;
|
||||
std::uint64_t m_PacketSendTime; // used to calculate ping
|
||||
public:
|
||||
ServerTpsPacket(){}
|
||||
ServerTpsPacket(float tps, std::uint64_t sendTime): m_TPS(tps), m_PacketSendTime(sendTime){}
|
||||
virtual ~ServerTpsPacket(){}
|
||||
|
||||
virtual DataBuffer Serialize() const;
|
||||
virtual void Deserialize(DataBuffer& data);
|
||||
virtual void Dispatch(PacketHandler* handler);
|
||||
|
||||
float getTPS() const{ return m_TPS; }
|
||||
std::uint64_t getPacketSendTime() const {return m_PacketSendTime;}
|
||||
|
||||
virtual PacketType getType() const{ return PacketType::ServerTps; }
|
||||
};
|
||||
|
||||
class SpawnMobPacket : public Packet{
|
||||
private:
|
||||
game::MobID m_MobID;
|
||||
game::MobType m_MobType;
|
||||
game::MobLevel m_MobLevel;
|
||||
game::Direction m_MobDirection;
|
||||
game::PlayerID m_Sender;
|
||||
float m_MobX, m_MobY;
|
||||
public:
|
||||
SpawnMobPacket(){}
|
||||
SpawnMobPacket(game::MobID id, game::MobType type, std::uint8_t level, game::PlayerID sender,
|
||||
float x, float y, game::Direction dir) : m_MobID(id), m_MobType(type), m_MobLevel(level),
|
||||
m_MobDirection(dir), m_Sender(sender), m_MobX(x), m_MobY(y){}
|
||||
virtual ~SpawnMobPacket(){}
|
||||
|
||||
virtual DataBuffer Serialize() const;
|
||||
virtual void Deserialize(DataBuffer& data);
|
||||
virtual void Dispatch(PacketHandler* handler);
|
||||
|
||||
game::MobID getMobID() const{ return m_MobID; }
|
||||
game::MobType getMobType() const{ return m_MobType; }
|
||||
game::MobLevel getMobLevel() const{ return m_MobLevel; }
|
||||
game::Direction getMobDirection() const{ return m_MobDirection; }
|
||||
game::PlayerID getSender() const{ return m_Sender; }
|
||||
float getMobX() const{ return m_MobX; }
|
||||
float getMobY() const{ return m_MobY; }
|
||||
|
||||
virtual PacketType getType() const{ return PacketType::SpawnMob; }
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
44
include/render/Renderer.h
Normal file
44
include/render/Renderer.h
Normal file
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Renderer.h
|
||||
*
|
||||
* Created on: 4 nov. 2020
|
||||
* Author: simon
|
||||
*/
|
||||
|
||||
#ifndef RENDER_RENDERER_H_
|
||||
#define RENDER_RENDERER_H_
|
||||
|
||||
#include <glm/glm.hpp>
|
||||
#include "loader/GLLoader.h"
|
||||
|
||||
namespace td {
|
||||
namespace render{
|
||||
|
||||
namespace Renderer{
|
||||
|
||||
struct Model{
|
||||
GL::VAO* vao;
|
||||
glm::vec2 positon;
|
||||
};
|
||||
|
||||
bool init();
|
||||
void destroy();
|
||||
|
||||
void prepare();
|
||||
void resize(const int width, const int height);
|
||||
|
||||
void renderVAO(const GL::VAO& vao);
|
||||
void renderModel(const Model& model);
|
||||
|
||||
void setZoom(float zoom);
|
||||
void setCamMovement(const glm::vec2& mov);
|
||||
void setCamPos(const glm::vec2& newPos);
|
||||
void setIsometricView(bool isometric); // false = 2D true = Isometric
|
||||
|
||||
}
|
||||
|
||||
|
||||
} // namespace render
|
||||
} // namespace td
|
||||
|
||||
#endif /* RENDER_RENDERER_H_ */
|
||||
23
include/render/WorldRenderer.h
Normal file
23
include/render/WorldRenderer.h
Normal file
@@ -0,0 +1,23 @@
|
||||
#pragma once
|
||||
|
||||
#include "game/World.h"
|
||||
|
||||
namespace td {
|
||||
namespace render {
|
||||
|
||||
namespace WorldRenderer{
|
||||
|
||||
void init(const game::World* world);
|
||||
void update();
|
||||
void render();
|
||||
void destroy();
|
||||
|
||||
void moveCam(float relativeX, float relativeY, float aspectRatio);
|
||||
void changeZoom(float zoom);
|
||||
void click(int mouseX, int mouseY);
|
||||
|
||||
} // namespace WorldRenderer
|
||||
|
||||
|
||||
} // namespace render
|
||||
} // namespace td
|
||||
23
include/render/gui/TowerGui.h
Normal file
23
include/render/gui/TowerGui.h
Normal file
@@ -0,0 +1,23 @@
|
||||
/*
|
||||
* TowerGUI.h
|
||||
*
|
||||
* Created on: 5 nov. 2020
|
||||
* Author: simon
|
||||
*/
|
||||
|
||||
#ifndef RENDER_GUI_TOWERGUI_H_
|
||||
#define RENDER_GUI_TOWERGUI_H_
|
||||
|
||||
struct GLFWwindow;
|
||||
|
||||
namespace TowerGui{
|
||||
|
||||
void init(GLFWwindow* window);
|
||||
void render();
|
||||
void destroy();
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endif /* RENDER_GUI_TOWERGUI_H_ */
|
||||
67
include/render/loader/GLLoader.h
Normal file
67
include/render/loader/GLLoader.h
Normal file
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
* GLLoader.h
|
||||
*
|
||||
* Created on: 4 nov. 2020
|
||||
* Author: simon
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
|
||||
#define REMOVE_COPY(className) \
|
||||
className(const className &) = delete;\
|
||||
className& operator=(const className &) = delete
|
||||
|
||||
|
||||
namespace GL{
|
||||
|
||||
struct VertexAttribPointer{
|
||||
unsigned int m_Index, m_Size;
|
||||
int m_Offset;
|
||||
};
|
||||
|
||||
class VBO{
|
||||
private:
|
||||
unsigned int m_ID, m_DataStride;
|
||||
std::vector<VertexAttribPointer> m_VertexAttribs;
|
||||
public:
|
||||
REMOVE_COPY(VBO);
|
||||
VBO(VBO&& other){
|
||||
m_VertexAttribs = std::move(other.m_VertexAttribs);
|
||||
m_ID = other.m_ID;
|
||||
m_DataStride = other.m_DataStride;
|
||||
other.m_ID = 0;
|
||||
other.m_DataStride = 0;
|
||||
}
|
||||
VBO(const std::vector<float>& data, unsigned int stride);
|
||||
~VBO();
|
||||
void bind() const;
|
||||
void unbind() const;
|
||||
void addVertexAttribPointer(unsigned int index, unsigned int coordinateSize, unsigned int offset);
|
||||
void bindVertexAttribs() const;
|
||||
};
|
||||
|
||||
class VAO{
|
||||
private:
|
||||
unsigned int m_ID, m_VertexCount;
|
||||
std::vector<VBO> m_Vbos; //use to destroy vbos when become unused
|
||||
public:
|
||||
REMOVE_COPY(VAO);
|
||||
VAO(VAO&& other){
|
||||
m_ID = other.m_ID;
|
||||
m_VertexCount = other.m_VertexCount;
|
||||
m_Vbos = std::move(other.m_Vbos);
|
||||
other.m_VertexCount = 0;
|
||||
other.m_ID = 0;
|
||||
}
|
||||
VAO(unsigned int vertexCount);
|
||||
~VAO();
|
||||
unsigned int getVertexCount() const {return m_VertexCount;}
|
||||
void bindVBO(VBO& vbo);
|
||||
void bind() const;
|
||||
void unbind() const;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
16
include/render/loader/TextureLoader.h
Normal file
16
include/render/loader/TextureLoader.h
Normal file
@@ -0,0 +1,16 @@
|
||||
/*
|
||||
* TextureLoader.h
|
||||
*
|
||||
* Created on: 15 nov. 2020
|
||||
* Author: simon
|
||||
*/
|
||||
|
||||
#ifndef RENDER_LOADER_TEXTURELOADER_H_
|
||||
#define RENDER_LOADER_TEXTURELOADER_H_
|
||||
|
||||
namespace TextureLoader{
|
||||
const unsigned int loadGLTexture(const char* fileName);
|
||||
}
|
||||
|
||||
|
||||
#endif /* RENDER_LOADER_TEXTURELOADER_H_ */
|
||||
18
include/render/loader/WorldLoader.h
Normal file
18
include/render/loader/WorldLoader.h
Normal file
@@ -0,0 +1,18 @@
|
||||
#pragma once
|
||||
|
||||
#include "game/World.h"
|
||||
#include "GLLoader.h"
|
||||
|
||||
namespace td {
|
||||
namespace render {
|
||||
|
||||
namespace WorldLoader {
|
||||
|
||||
GL::VAO loadMobModel();
|
||||
GL::VAO loadWorldModel(const td::game::World* world);
|
||||
|
||||
} // namespace WorldLoader
|
||||
|
||||
|
||||
} // namespace render
|
||||
} // namespace td
|
||||
7559
include/render/loader/stb_image.h
Executable file
7559
include/render/loader/stb_image.h
Executable file
File diff suppressed because it is too large
Load Diff
18
include/render/shaders/EntityShader.h
Normal file
18
include/render/shaders/EntityShader.h
Normal file
@@ -0,0 +1,18 @@
|
||||
#pragma once
|
||||
|
||||
#include "ShaderProgram.h"
|
||||
|
||||
class EntityShader : public ShaderProgram{
|
||||
private:
|
||||
unsigned int location_cam = 0, location_zoom = 0, location_aspect_ratio = 0, location_translation = 0, location_viewtype = 0;
|
||||
protected:
|
||||
void getAllUniformLocation();
|
||||
public:
|
||||
EntityShader();
|
||||
void loadShader();
|
||||
void setCamPos(const glm::vec2& camPos);
|
||||
void setZoom(float zoom);
|
||||
void setAspectRatio(float aspectRatio);
|
||||
void setModelPos(const glm::vec2& modelPos);
|
||||
void setIsometricView(float isometric);
|
||||
};
|
||||
47
include/render/shaders/ShaderProgram.h
Executable file
47
include/render/shaders/ShaderProgram.h
Executable file
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* ShaderProgram.h
|
||||
*
|
||||
* Created on: 31 janv. 2020
|
||||
* Author: simon
|
||||
*/
|
||||
|
||||
#ifndef RENDER_SHADERS_SHADERPROGRAM_H_
|
||||
#define RENDER_SHADERS_SHADERPROGRAM_H_
|
||||
|
||||
#include <string>
|
||||
#include <glm/glm.hpp>
|
||||
|
||||
namespace gl{
|
||||
enum class GLenum : unsigned int;
|
||||
}
|
||||
|
||||
class ShaderProgram {
|
||||
public:
|
||||
ShaderProgram();
|
||||
virtual ~ShaderProgram();
|
||||
void start() const;
|
||||
void stop() const;
|
||||
void loadProgramFile(const std::string& vertexFile, const std::string& fragmentFile);
|
||||
void loadProgram(const std::string& vertexSource, const std::string& fragmentSource);
|
||||
|
||||
protected:
|
||||
virtual void getAllUniformLocation() = 0;
|
||||
int getUniformLocation(const std::string& uniformName)const;
|
||||
void loadFloat(const int location, const float value)const;
|
||||
void loadInt(const int& location, const int& value)const;
|
||||
void loadVector(const int& location, const glm::vec2& vector)const;
|
||||
void loadVector(const int& location, const glm::vec3& vector)const;
|
||||
void loadVector(const int& location, const glm::vec4& vector)const;
|
||||
void loadBoolean(const int& location, const bool& value)const;
|
||||
void loadMatrix(const int& location, const glm::mat4& matrix);
|
||||
void cleanUp() const;
|
||||
|
||||
private:
|
||||
unsigned int programID;
|
||||
unsigned int vertexShaderID;
|
||||
unsigned int fragmentShaderID;
|
||||
int loadShaderFromFile(const std::string& file, gl::GLenum type);
|
||||
int loadShader(const std::string& source, gl::GLenum type);
|
||||
};
|
||||
|
||||
#endif /* RENDER_SHADERS_SHADERPROGRAM_H_ */
|
||||
27
include/render/shaders/WorldShader.h
Normal file
27
include/render/shaders/WorldShader.h
Normal file
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
* GameShader.h
|
||||
*
|
||||
* Created on: 4 nov. 2020
|
||||
* Author: simon
|
||||
*/
|
||||
|
||||
#ifndef RENDER_SHADERS_GAMESHADER_H_
|
||||
#define RENDER_SHADERS_GAMESHADER_H_
|
||||
|
||||
#include "ShaderProgram.h"
|
||||
|
||||
class WorldShader : public ShaderProgram{
|
||||
private:
|
||||
unsigned int location_cam = 0, location_zoom = 0, location_aspect_ratio = 0, location_viewtype = 0;
|
||||
protected:
|
||||
void getAllUniformLocation();
|
||||
public:
|
||||
WorldShader();
|
||||
void loadShader();
|
||||
void setCamPos(const glm::vec2& camPos);
|
||||
void setZoom(float zoom);
|
||||
void setAspectRatio(float aspectRatio);
|
||||
void setIsometricView(float isometric);
|
||||
};
|
||||
|
||||
#endif /* RENDER_SHADERS_GAMESHADER_H_ */
|
||||
31
include/window/Display.h
Normal file
31
include/window/Display.h
Normal file
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Display.h
|
||||
*
|
||||
* Created on: 4 nov. 2020
|
||||
* Author: simon
|
||||
*/
|
||||
|
||||
#ifndef WINDOW_DISPLAY_H_
|
||||
#define WINDOW_DISPLAY_H_
|
||||
|
||||
|
||||
namespace Display{
|
||||
|
||||
void create();
|
||||
void render();
|
||||
void update();
|
||||
void destroy();
|
||||
void pollEvents();
|
||||
|
||||
bool isCloseRequested();
|
||||
|
||||
const bool isMouseDown(int button);
|
||||
|
||||
float getAspectRatio();
|
||||
int getWindowWidth();
|
||||
int getWindowHeight();
|
||||
|
||||
}
|
||||
|
||||
|
||||
#endif /* WINDOW_DISPLAY_H_ */
|
||||
Reference in New Issue
Block a user