too many things
This commit is contained in:
30
src/td/Types.cpp
Normal file
30
src/td/Types.cpp
Normal file
@@ -0,0 +1,30 @@
|
||||
#include <td/Types.h>
|
||||
|
||||
#include <sp/common/DataBuffer.h>
|
||||
#include <sp/common/ByteSwapping.h>
|
||||
|
||||
namespace td {
|
||||
|
||||
sp::DataBuffer& operator<<(sp::DataBuffer& a_Buffer, const EntityCoords& a_Coords) {
|
||||
return a_Buffer << a_Coords.x << a_Coords.y;
|
||||
}
|
||||
|
||||
sp::DataBuffer& operator<<(sp::DataBuffer& a_Buffer, const FpFloat& a_Float) {
|
||||
auto raw = a_Float.raw_value();
|
||||
sp::ToNetwork(raw);
|
||||
return a_Buffer << raw;
|
||||
}
|
||||
|
||||
sp::DataBuffer& operator>>(sp::DataBuffer& a_Buffer, EntityCoords& a_Coords) {
|
||||
return a_Buffer >> a_Coords.x >> a_Coords.y;
|
||||
}
|
||||
|
||||
sp::DataBuffer& operator>>(sp::DataBuffer& a_Buffer, FpFloat& a_Float) {
|
||||
auto raw = a_Float.raw_value();
|
||||
a_Buffer >> raw;
|
||||
sp::FromNetwork(raw);
|
||||
a_Float = FpFloat::from_raw_value(raw);
|
||||
return a_Buffer;
|
||||
}
|
||||
|
||||
} // namespace td
|
||||
@@ -1,9 +1,11 @@
|
||||
#include <td/game/World.h>
|
||||
|
||||
#include <td/simulation/WorldTicker.h>
|
||||
|
||||
namespace td {
|
||||
namespace game {
|
||||
|
||||
World::World() : m_Teams{Team{TeamColor::Red}, Team{TeamColor::Blue}} {
|
||||
World::World() : m_CurrentState{.m_Teams{Team{TeamColor::Red}, Team{TeamColor::Blue}}} {
|
||||
|
||||
}
|
||||
|
||||
@@ -55,5 +57,9 @@ bool World::LoadMap(const protocol::pdata::WorldData& a_WorldData) {
|
||||
return true;
|
||||
}
|
||||
|
||||
void World::Tick(const protocol::LockStep& a_LockStep, FpFloat a_Delta) {
|
||||
m_CurrentState = m_Ticker.NextStep(*this, m_CurrentState, a_LockStep, a_Delta);
|
||||
}
|
||||
|
||||
} // namespace game
|
||||
} // namespace td
|
||||
|
||||
44
src/td/game/WorldTypes.cpp
Normal file
44
src/td/game/WorldTypes.cpp
Normal file
@@ -0,0 +1,44 @@
|
||||
#include <td/game/WorldTypes.h>
|
||||
|
||||
#include <sp/common/DataBuffer.h>
|
||||
|
||||
namespace td {
|
||||
namespace game {
|
||||
|
||||
sp::DataBuffer& operator>>(sp::DataBuffer& buffer, TileType& tile) {
|
||||
std::uint8_t raw;
|
||||
buffer >> raw;
|
||||
tile = TileType(raw);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
sp::DataBuffer& operator>>(sp::DataBuffer& buffer, TilePtr& tile) {
|
||||
game::TileType tileType;
|
||||
buffer >> tileType;
|
||||
switch (tileType) {
|
||||
case game::TileType::Tower: {
|
||||
auto tilePtr = std::make_shared<game::TowerTile>();
|
||||
buffer >> tilePtr->color_palette_ref >> tilePtr->team_owner;
|
||||
tile = tilePtr;
|
||||
break;
|
||||
}
|
||||
case game::TileType::Walk: {
|
||||
auto tilePtr = std::make_shared<game::WalkableTile>();
|
||||
buffer >> tilePtr->direction;
|
||||
tile = tilePtr;
|
||||
break;
|
||||
}
|
||||
case game::TileType::Decoration: {
|
||||
auto tilePtr = std::make_shared<game::DecorationTile>();
|
||||
buffer >> tilePtr->color_palette_ref;
|
||||
tile = tilePtr;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return buffer;
|
||||
}
|
||||
|
||||
} // namespace game
|
||||
} // namespace td
|
||||
@@ -125,6 +125,7 @@ void Display::PollEvents() {
|
||||
m_LastWidth = event.window.data1;
|
||||
m_LastHeight = event.window.data2;
|
||||
m_AspectRatio = (float)m_LastWidth / m_LastHeight;
|
||||
OnAspectRatioChange(m_AspectRatio);
|
||||
}
|
||||
|
||||
default:
|
||||
|
||||
115
src/td/protocol/packet/PacketSerialize.cpp
Normal file
115
src/td/protocol/packet/PacketSerialize.cpp
Normal file
@@ -0,0 +1,115 @@
|
||||
#include <td/protocol/packet/PacketSerialize.h>
|
||||
|
||||
#include <sp/io/MessageIO.h>
|
||||
|
||||
namespace sp {
|
||||
namespace details {
|
||||
|
||||
template <>
|
||||
void ReadMessage(DataBuffer& a_Buffer, td::protocol::pdata::WorldHeader& a_Header) {
|
||||
a_Buffer >> a_Header.m_TowerPlacePalette >> a_Header.m_WalkablePalette;
|
||||
|
||||
std::uint16_t decoPaletteSize;
|
||||
a_Buffer >> decoPaletteSize;
|
||||
|
||||
std::size_t decoPalletteSizeByte = decoPaletteSize * sizeof(td::Color);
|
||||
|
||||
a_Header.m_DecorationPalette.resize(decoPaletteSize);
|
||||
|
||||
memcpy(reinterpret_cast<std::uint8_t*>(a_Header.m_DecorationPalette.data()), a_Buffer.data() + a_Buffer.GetReadOffset(),
|
||||
decoPalletteSizeByte);
|
||||
|
||||
a_Buffer.SetReadOffset(a_Buffer.GetReadOffset() + decoPalletteSizeByte);
|
||||
|
||||
a_Buffer >> a_Header.m_Background;
|
||||
|
||||
td::utils::shape::Rectangle redCastle, blueCastle;
|
||||
|
||||
a_Buffer >> a_Header.m_RedSpawn >> redCastle;
|
||||
a_Buffer >> a_Header.m_BlueSpawn >> blueCastle;
|
||||
|
||||
a_Header.m_RedCastle.SetShape(redCastle);
|
||||
a_Header.m_BlueCastle.SetShape(blueCastle);
|
||||
|
||||
std::uint64_t tilePaletteSize;
|
||||
a_Buffer >> tilePaletteSize;
|
||||
|
||||
a_Header.m_TilePalette.reserve(tilePaletteSize);
|
||||
|
||||
for (std::uint64_t tileNumber = 0; tileNumber < tilePaletteSize; tileNumber++) {
|
||||
td::game::TilePtr tile;
|
||||
a_Buffer >> tile;
|
||||
a_Header.m_TilePalette.push_back(tile);
|
||||
}
|
||||
|
||||
a_Buffer >> a_Header.m_SpawnColorPalette;
|
||||
}
|
||||
|
||||
typedef std::vector<uint64_t> ChunkPackedData;
|
||||
|
||||
const int BITS_IN_BYTE = 8;
|
||||
const int BITS_IN_LONG = BITS_IN_BYTE * sizeof(std::uint64_t);
|
||||
|
||||
static unsigned int countBits(unsigned int number) {
|
||||
// log function in base 2
|
||||
// take only integer part
|
||||
return static_cast<unsigned int>(std::log2(number) + 1);
|
||||
}
|
||||
|
||||
|
||||
template <>
|
||||
void ReadMessage(DataBuffer& a_Buffer, td::protocol::pdata::WorldData& a_WorldData) {
|
||||
std::uint64_t chunkCount;
|
||||
a_Buffer >> chunkCount;
|
||||
|
||||
for (std::uint64_t chunkNumber = 0; chunkNumber < chunkCount; chunkNumber++) {
|
||||
td::game::ChunkPtr chunk = std::make_shared<td::game::Chunk>();
|
||||
|
||||
td::game::ChunkCoord chunkCoords;
|
||||
a_Buffer >> chunkCoords.x >> chunkCoords.y;
|
||||
|
||||
std::uint64_t chunkPaletteSize;
|
||||
// std::reverse(reinterpret_cast<std::uint8_t*>(&chunkPaletteSize), reinterpret_cast<std::uint8_t*>(&chunkPaletteSize) + 4);
|
||||
a_Buffer >> chunkPaletteSize;
|
||||
|
||||
td::game::ChunkPalette chunkPalette(chunkPaletteSize);
|
||||
|
||||
memcpy(reinterpret_cast<void*>(chunkPalette.data()), a_Buffer.data() + a_Buffer.GetReadOffset(),
|
||||
chunkPaletteSize * sizeof(td::game::ChunkPalette::value_type));
|
||||
a_Buffer.SetReadOffset(a_Buffer.GetReadOffset() + chunkPaletteSize * sizeof(td::game::ChunkPalette::value_type));
|
||||
|
||||
chunk->palette = chunkPalette;
|
||||
|
||||
std::uint8_t bitsPerTile = countBits(chunkPaletteSize);
|
||||
|
||||
// A bitmask that contains bitsPerTile set bits
|
||||
td::game::Chunk::ChunkData::value_type individualValueMask = ((1 << bitsPerTile) - 1);
|
||||
|
||||
ChunkPackedData chunkData(td::game::Chunk::ChunkSize / (BITS_IN_BYTE * sizeof(ChunkPackedData::value_type) / bitsPerTile), 0);
|
||||
|
||||
memcpy(reinterpret_cast<void*>(chunkData.data()), a_Buffer.data() + a_Buffer.GetReadOffset(),
|
||||
chunkData.size() * sizeof(ChunkPackedData::value_type));
|
||||
a_Buffer.SetReadOffset(a_Buffer.GetReadOffset() + chunkData.size() * sizeof(ChunkPackedData::value_type));
|
||||
|
||||
for (unsigned int tileNumber = 0; tileNumber < td::game::Chunk::ChunkSize; tileNumber++) {
|
||||
std::size_t startLong = (tileNumber * bitsPerTile) / BITS_IN_LONG;
|
||||
std::size_t startOffset = (tileNumber * bitsPerTile) % BITS_IN_LONG;
|
||||
std::size_t endLong = ((tileNumber + 1) * bitsPerTile - 1) / BITS_IN_LONG;
|
||||
|
||||
td::game::Chunk::ChunkData::value_type value;
|
||||
if (startLong == endLong) {
|
||||
value = (chunkData[startLong] >> startOffset);
|
||||
} else {
|
||||
int endOffset = BITS_IN_LONG - startOffset;
|
||||
value = (chunkData[startLong] >> startOffset | chunkData[endLong] << endOffset);
|
||||
}
|
||||
value &= individualValueMask;
|
||||
|
||||
chunk->tiles[tileNumber] = value;
|
||||
}
|
||||
a_WorldData.m_Chunks.insert({chunkCoords, chunk});
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace details
|
||||
} // namespace sp
|
||||
@@ -16,8 +16,10 @@ EntityRenderer::~EntityRenderer() {}
|
||||
void EntityRenderer::Render() {
|
||||
m_Shader->Start();
|
||||
for (const auto& mob : m_World.GetMobList()) {
|
||||
const auto mobCoords = mob->GetCenter();
|
||||
m_Shader->SetModelPos({mobCoords.GetX(), 1, mobCoords.GetY()});
|
||||
const auto mobCoords = mob->GetPosition();
|
||||
float x = static_cast<float>(mobCoords.x);
|
||||
float z = static_cast<float>(mobCoords.y);
|
||||
m_Shader->SetModelPos({x, 1, z});
|
||||
Renderer::Render(*m_EntityVao);
|
||||
}
|
||||
}
|
||||
|
||||
15
src/td/simulation/CommandApply.cpp
Normal file
15
src/td/simulation/CommandApply.cpp
Normal file
@@ -0,0 +1,15 @@
|
||||
#include <td/simulation/CommandApply.h>
|
||||
|
||||
namespace td {
|
||||
namespace sim {
|
||||
|
||||
CommandApply::CommandApply(const game::World& a_World, WorldSnapshot& a_Snapshot) : m_World(a_World), m_Snapshot(a_Snapshot) {}
|
||||
|
||||
void CommandApply::Handle(const protocol::cdata::SpawnTroop& a_SpawnTroop) {
|
||||
auto zombie = std::make_shared<game::Zombie>(0, *a_SpawnTroop.m_Level, a_SpawnTroop.m_Sender);
|
||||
zombie->GetPosition() = a_SpawnTroop.m_Position;
|
||||
m_Snapshot.m_Mobs.push_back(zombie);
|
||||
}
|
||||
|
||||
} // namespace sim
|
||||
} // namespace td
|
||||
@@ -1,4 +1,4 @@
|
||||
#include <td/game/GameHistory.h>
|
||||
#include <td/simulation/GameHistory.h>
|
||||
|
||||
namespace td {
|
||||
namespace game {
|
||||
32
src/td/simulation/RealTimeSimulation.cpp
Normal file
32
src/td/simulation/RealTimeSimulation.cpp
Normal file
@@ -0,0 +1,32 @@
|
||||
#include <td/simulation/RealTimeSimulation.h>
|
||||
|
||||
#include <chrono>
|
||||
|
||||
namespace td {
|
||||
namespace sim {
|
||||
|
||||
std::uint64_t GetTime() {
|
||||
return static_cast<std::uint64_t>(
|
||||
std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock().now().time_since_epoch()).count());
|
||||
}
|
||||
|
||||
RealTimeSimulation::RealTimeSimulation(game::World& a_World, GameHistory&& a_History, std::uint64_t a_StepTime) :
|
||||
m_StepTime(a_StepTime),
|
||||
m_World(a_World),
|
||||
m_History(std::move(a_History)),
|
||||
m_CurrentTime(0),
|
||||
m_LastTime(GetTime()),
|
||||
m_CurrentStep(0) {}
|
||||
|
||||
void RealTimeSimulation::Update() {
|
||||
m_CurrentTime += GetTime() - m_LastTime;
|
||||
m_LastTime = GetTime();
|
||||
if (m_CurrentTime > m_StepTime) {
|
||||
m_World.Tick(m_History[m_CurrentStep], FpFloat(m_StepTime) / FpFloat(1000));
|
||||
m_CurrentStep++;
|
||||
m_CurrentTime -= m_StepTime;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace sim
|
||||
} // namespace td
|
||||
41
src/td/simulation/WorldTicker.cpp
Normal file
41
src/td/simulation/WorldTicker.cpp
Normal file
@@ -0,0 +1,41 @@
|
||||
#include <td/simulation/WorldTicker.h>
|
||||
|
||||
#include <td/simulation/system/EntityMove.h>
|
||||
#include <td/simulation/CommandApply.h>
|
||||
|
||||
#define ADD_SYSTEM(class) std::move(std::make_unique<class>())
|
||||
|
||||
namespace td {
|
||||
namespace sim {
|
||||
|
||||
WorldTicker::WorldTicker() {
|
||||
AddSystem<EntityMove>();
|
||||
}
|
||||
|
||||
WorldSnapshot WorldTicker::NextStep(
|
||||
const game::World& a_World, const WorldSnapshot& a_PreviousState, const protocol::LockStep& a_LockStep, FpFloat a_Delta) {
|
||||
WorldSnapshot next = CreateNext(a_PreviousState);
|
||||
ApplySteps(a_World, next, a_LockStep);
|
||||
Tick(a_World, next, a_Delta);
|
||||
return next;
|
||||
}
|
||||
|
||||
void WorldTicker::ApplySteps(const game::World& a_World, WorldSnapshot& a_State, const protocol::LockStep& a_LockStep) {
|
||||
CommandApply cmdHandler(a_World, a_State);
|
||||
for (const auto& cmd : a_LockStep) {
|
||||
cmd->Dispatch(cmdHandler);
|
||||
}
|
||||
}
|
||||
|
||||
void WorldTicker::Tick(const game::World& a_World, WorldSnapshot& a_State, FpFloat a_Delta) {
|
||||
for (const auto& system : m_Systems) {
|
||||
system->Tick(a_World, a_State, a_Delta);
|
||||
}
|
||||
}
|
||||
|
||||
WorldSnapshot WorldTicker::CreateNext(const WorldSnapshot& a_PreviousState) {
|
||||
return a_PreviousState;
|
||||
}
|
||||
|
||||
} // namespace sim
|
||||
} // namespace td
|
||||
13
src/td/simulation/system/EntityMove.cpp
Normal file
13
src/td/simulation/system/EntityMove.cpp
Normal file
@@ -0,0 +1,13 @@
|
||||
#include <td/simulation/system/EntityMove.h>
|
||||
|
||||
namespace td {
|
||||
namespace sim {
|
||||
|
||||
void EntityMove::Tick(const game::World& a_World, WorldSnapshot& a_State, FpFloat a_Delta) {
|
||||
for (auto& mob : a_State.m_Mobs) {
|
||||
mob->GetPosition().x += a_Delta;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace sim
|
||||
} // namespace td
|
||||
Reference in New Issue
Block a user