Files
Tower-Defense/include/game/World.h

185 lines
4.5 KiB
C++

#pragma once
#include <memory>
#include <vector>
#include <map>
#include <unordered_map>
#include <glm/glm.hpp>
#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; }
};
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;
TilePalette m_TilePalette;
MobList m_Mobs;
std::vector<TowerPtr> m_Towers;
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;
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);
}
bool CanPlaceLittleTower(const glm::vec2& worldPos) const;
bool CanPlaceBigTower(const glm::vec2& worldPos) const;
const std::unordered_map<ChunkCoord, ChunkPtr>& getChunks() const { return m_Chunks; }
const Color& getSpawnColor(TeamColor color) const { return m_SpawnColorPalette[(std::size_t)color]; }
const SpawnColorPalette& getSpawnColors() const { return m_SpawnColorPalette; }
const MobList& getMobList() const { return m_Mobs; }
MobList& getMobList() { return m_Mobs; }
const Color* getTileColor(TilePtr tile) const;
Team& getRedTeam();
const Team& getRedTeam() const;
Team& getBlueTeam();
const Team& getBlueTeam() const;
Team& getTeam(TeamColor team);
const Team& getTeam(TeamColor team) const;
private:
void moveMobs(std::uint64_t delta);
};
} // namespace game
} // namespace td