migrating save files
This commit is contained in:
@@ -40,10 +40,10 @@ bool World::LoadMap(const protocol::pdata::WorldHeader& a_WorldHeader) {
|
||||
m_SpawnColorPalette = a_WorldHeader.m_SpawnColorPalette;
|
||||
|
||||
GetRedTeam().GetCastle() = a_WorldHeader.m_RedCastle;
|
||||
GetRedTeam().GetCastle().SetTeam(&GetRedTeam());
|
||||
// GetRedTeam().GetCastle().SetTeam(&GetRedTeam());
|
||||
|
||||
GetBlueTeam().GetCastle() = a_WorldHeader.m_BlueCastle;
|
||||
GetBlueTeam().GetCastle().SetTeam(&GetBlueTeam());
|
||||
// GetBlueTeam().GetCastle().SetTeam(&GetBlueTeam());
|
||||
|
||||
m_TilePalette = a_WorldHeader.m_TilePalette;
|
||||
|
||||
|
||||
@@ -5,40 +5,7 @@
|
||||
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
|
||||
|
||||
79
src/td/protocol/packet/ChunkSerialize.cpp
Normal file
79
src/td/protocol/packet/ChunkSerialize.cpp
Normal file
@@ -0,0 +1,79 @@
|
||||
#include <td/protocol/packet/PacketSerialize.h>
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
namespace td {
|
||||
namespace game {
|
||||
|
||||
sp::DataBuffer& operator<<(sp::DataBuffer& a_Buffer, const ChunkPtr& a_Chunk) {
|
||||
a_Buffer << a_Chunk->m_Palette;
|
||||
|
||||
int bitsPerTile = countBits(a_Chunk->m_Palette.size());
|
||||
|
||||
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);
|
||||
|
||||
for (unsigned int tileNumber = 0; tileNumber < td::game::Chunk::ChunkSize; tileNumber++) {
|
||||
std::size_t startLong = static_cast<std::size_t>((tileNumber * bitsPerTile) / BITS_IN_LONG);
|
||||
std::size_t startOffset = static_cast<std::size_t>((tileNumber * bitsPerTile) % BITS_IN_LONG);
|
||||
std::size_t endLong = static_cast<std::size_t>(((tileNumber + 1) * bitsPerTile - 1) / BITS_IN_LONG);
|
||||
|
||||
std::uint64_t value = static_cast<std::uint64_t>(a_Chunk->m_Tiles[tileNumber]);
|
||||
|
||||
value &= individualValueMask;
|
||||
|
||||
chunkData[startLong] |= (value << startOffset);
|
||||
|
||||
if (startLong != endLong) {
|
||||
chunkData[endLong] = (value >> (BITS_IN_LONG - startOffset));
|
||||
}
|
||||
}
|
||||
|
||||
return a_Buffer << chunkData;
|
||||
}
|
||||
|
||||
sp::DataBuffer& operator>>(sp::DataBuffer& a_Buffer, ChunkPtr& a_Chunk) {
|
||||
a_Chunk = std::make_shared<td::game::Chunk>();
|
||||
|
||||
a_Buffer >> a_Chunk->m_Palette;
|
||||
|
||||
std::uint8_t bitsPerTile = countBits(a_Chunk->m_Palette.size());
|
||||
|
||||
// A bitmask that contains bitsPerTile set bits
|
||||
td::game::Chunk::ChunkData::value_type individualValueMask = ((1 << bitsPerTile) - 1);
|
||||
|
||||
ChunkPackedData chunkData;
|
||||
a_Buffer >> chunkData;
|
||||
|
||||
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;
|
||||
|
||||
a_Chunk->m_Tiles[tileNumber] = value;
|
||||
}
|
||||
|
||||
return a_Buffer;
|
||||
}
|
||||
|
||||
} // namespace game
|
||||
} // namespace td
|
||||
@@ -1,113 +1,88 @@
|
||||
#include <td/protocol/packet/PacketData.h>
|
||||
#include <td/protocol/packet/PacketSerialize.h>
|
||||
|
||||
#include <sp/io/MessageIO.h>
|
||||
|
||||
namespace sp {
|
||||
|
||||
template <>
|
||||
void ReadMessage(DataBuffer& a_Buffer, td::protocol::pdata::WorldHeader& a_Header) {
|
||||
a_Buffer >> a_Header.m_TowerPlacePalette >> a_Header.m_WalkablePalette;
|
||||
// temp
|
||||
template<>
|
||||
void ReadMessage(DataBuffer& a_Buffer, td::protocol::pdata::PredictCommand& a_Header){}
|
||||
|
||||
std::uint16_t decoPaletteSize;
|
||||
a_Buffer >> decoPaletteSize;
|
||||
template<>
|
||||
DataBuffer WriteMessage(const td::protocol::pdata::PredictCommand& a_Header){}
|
||||
|
||||
std::size_t decoPalletteSizeByte = decoPaletteSize * sizeof(td::Color);
|
||||
} // namespace sp
|
||||
|
||||
a_Header.m_DecorationPalette.resize(decoPaletteSize);
|
||||
namespace td {
|
||||
namespace game {
|
||||
|
||||
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;
|
||||
sp::DataBuffer& operator<<(sp::DataBuffer& a_Buffer, const TeamCastle& a_Castle) {
|
||||
return a_Buffer << a_Castle.GetCenterX() << a_Castle.GetCenterY();
|
||||
}
|
||||
|
||||
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);
|
||||
sp::DataBuffer& operator>>(sp::DataBuffer& a_Buffer, TeamCastle& a_Castle) {
|
||||
float x, y;
|
||||
a_Buffer >> x >> y;
|
||||
a_Castle.SetCenter({x, y});
|
||||
return a_Buffer;
|
||||
}
|
||||
|
||||
sp::DataBuffer& operator<<(sp::DataBuffer& buffer, const TilePtr& tile) {
|
||||
buffer << tile->GetType();
|
||||
|
||||
template <>
|
||||
void ReadMessage(DataBuffer& a_Buffer, td::protocol::pdata::WorldData& a_WorldData) {
|
||||
std::uint64_t chunkCount;
|
||||
a_Buffer >> chunkCount;
|
||||
switch (tile->GetType()) {
|
||||
|
||||
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;
|
||||
case game::TileType::Tower: {
|
||||
const game::TowerTile* towerTile = dynamic_cast<const game::TowerTile*>(tile.get());
|
||||
buffer << towerTile->color_palette_ref << towerTile->team_owner;
|
||||
break;
|
||||
}
|
||||
a_WorldData.m_Chunks.insert({chunkCoords, chunk});
|
||||
|
||||
case game::TileType::Walk: {
|
||||
const game::WalkableTile* walkTile = dynamic_cast<const game::WalkableTile*>(tile.get());
|
||||
buffer << walkTile->direction;
|
||||
break;
|
||||
}
|
||||
|
||||
case game::TileType::Decoration: {
|
||||
const game::DecorationTile* decoTile = dynamic_cast<const game::DecorationTile*>(tile.get());
|
||||
buffer << decoTile->color_palette_ref;
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
} // namespace sp
|
||||
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
|
||||
|
||||
@@ -17,10 +17,7 @@ GL::VertexArray LoadWorldModel(const td::game::World* world) {
|
||||
std::vector<float> positions;
|
||||
std::vector<float> colors;
|
||||
|
||||
for (const auto& chunkInfo : world->GetChunks()) {
|
||||
const td::game::ChunkCoord& coords = chunkInfo.first;
|
||||
td::game::ChunkPtr chunk = chunkInfo.second;
|
||||
|
||||
for (const auto& [coords, chunk] : world->GetChunks()) {
|
||||
std::int32_t chunkX = coords.x * td::game::Chunk::ChunkWidth;
|
||||
std::int32_t chunkY = coords.y * td::game::Chunk::ChunkHeight;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user