diff --git a/src/ClientHandle.h b/src/ClientHandle.h index b1f13954b..a714cf8b9 100644 --- a/src/ClientHandle.h +++ b/src/ClientHandle.h @@ -109,8 +109,8 @@ public: void SendGameMode (eGameMode a_GameMode); void SendHealth (void); void SendInventorySlot (char a_WindowID, short a_SlotNum, const cItem & a_Item); - void SendMapColumn (int a_ID, int a_X, int a_Y, const Byte * a_Colors, unsigned int a_Length) override; - void SendMapInfo (int a_ID, unsigned int a_Scale) override; + void SendMapColumn (int a_ID, int a_X, int a_Y, const Byte * a_Colors, unsigned int a_Length); + void SendMapInfo (int a_ID, unsigned int a_Scale); void SendPickupSpawn (const cPickup & a_Pickup); void SendEntityAnimation (const cEntity & a_Entity, char a_Animation); void SendParticleEffect (const AString & a_ParticleName, float a_SrcX, float a_SrcY, float a_SrcZ, float a_OffsetX, float a_OffsetY, float a_OffsetZ, float a_ParticleData, int a_ParticleAmmount); diff --git a/src/Map.cpp b/src/Map.cpp index f1b690698..f99b01752 100644 --- a/src/Map.cpp +++ b/src/Map.cpp @@ -12,6 +12,24 @@ +cMap::cMap(unsigned int a_ID, cWorld * a_World) + : m_ID(a_ID) + , m_Width(128) + , m_Height(128) + , m_Scale(3) + , m_CenterX(0) + , m_CenterZ(0) + , m_World(a_World) +{ + m_Data.assign(m_Width * m_Height, 0); + + // Do not update map +} + + + + + cMap::cMap(unsigned int a_ID, int a_CenterX, int a_CenterZ, cWorld * a_World, unsigned int a_Scale) : m_ID(a_ID) , m_Width(128) diff --git a/src/Map.h b/src/Map.h index 80bbd4ab4..dbb15afdd 100644 --- a/src/Map.h +++ b/src/Map.h @@ -37,6 +37,9 @@ public: public: + /// Construct an empty map + cMap(unsigned int a_ID, cWorld * a_World); + cMap(unsigned int a_ID, int a_CenterX, int a_CenterZ, cWorld * a_World, unsigned int a_Scale = 3); /** Update the map (Query the world) */ diff --git a/src/World.cpp b/src/World.cpp index f8c1091f0..a308778df 100644 --- a/src/World.cpp +++ b/src/World.cpp @@ -11,7 +11,9 @@ #include "ChunkMap.h" #include "Generating/ChunkDesc.h" #include "OSSupport/Timer.h" + #include "WorldStorage/ScoreboardSerializer.h" +#include "WorldStorage/MapSerializer.h" // Entities (except mobs): #include "Entities/ExpOrb.h" @@ -261,6 +263,8 @@ cWorld::cWorld(const AString & a_WorldName) : // Load the scoreboard cScoreboardSerializer Serializer(m_WorldName, &m_Scoreboard); Serializer.Load(); + + LoadMapData(); } @@ -284,6 +288,8 @@ cWorld::~cWorld() cScoreboardSerializer Serializer(m_WorldName, &m_Scoreboard); Serializer.Save(); + SaveMapData(); + delete m_ChunkMap; } @@ -2945,6 +2951,54 @@ cFluidSimulator * cWorld::InitializeFluidSimulator(cIniFile & a_IniFile, const c + +void cWorld::LoadMapData(void) +{ + cIDCountSerializer IDSerializer(GetName()); + + IDSerializer.Load(); + + unsigned int MapCount = IDSerializer.GetMapCount(); + + m_MapData.clear(); + + for (unsigned int i = 0; i < MapCount; ++i) + { + cMap Map(i, this); + + cMapSerializer Serializer(GetName(), &Map); + + Serializer.Load(); + + m_MapData.push_back(Map); + } +} + + + + + +void cWorld::SaveMapData(void) +{ + cIDCountSerializer IDSerializer(GetName()); + + IDSerializer.SetMapCount(m_MapData.size()); + + IDSerializer.Save(); + + for (cMapList::iterator it = m_MapData.begin(); it != m_MapData.end(); ++it) + { + cMap & Map = *it; + + cMapSerializer Serializer(GetName(), &Map); + + Serializer.Save(); + } +} + + + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // cWorld::cTaskSaveAllChunks: diff --git a/src/World.h b/src/World.h index fa83fe73e..02e56a247 100644 --- a/src/World.h +++ b/src/World.h @@ -24,6 +24,7 @@ #include "Entities/ProjectileEntity.h" #include "ForEachChunkProvider.h" #include "Scoreboard.h" +#include "Map.h" #include "Blocks/WorldInterface.h" #include "Blocks/BroadcastInterface.h" @@ -811,6 +812,10 @@ private: cChunkGenerator m_Generator; cScoreboard m_Scoreboard; + + typedef std::vector cMapList; + + cMapList m_MapData; /** The callbacks that the ChunkGenerator uses to store new chunks and interface to plugins */ cChunkGeneratorCallbacks m_GeneratorCallbacks; @@ -876,6 +881,12 @@ private: /** Creates a new redstone simulator.*/ cRedstoneSimulator * InitializeRedstoneSimulator(cIniFile & a_IniFile); + + /** Loads the map data from the disk */ + void LoadMapData(void); + + /** Saves the map data to the disk */ + void SaveMapData(void); }; // tolua_export diff --git a/src/WorldStorage/MapSerializer.cpp b/src/WorldStorage/MapSerializer.cpp index ea0d3ec47..aab4c7816 100644 --- a/src/WorldStorage/MapSerializer.cpp +++ b/src/WorldStorage/MapSerializer.cpp @@ -9,6 +9,7 @@ #include "FastNBT.h" #include "../Map.h" +#include "../World.h" @@ -141,7 +142,7 @@ bool cMapSerializer::LoadMapFromNBT(const cParsedNBT & a_NBT) { eDimension Dimension = (eDimension) a_NBT.GetByte(CurrLine); - // ASSERT(Dimension == m_World.GetDimension()); + ASSERT(Dimension == m_Map->m_World->GetDimension()); } CurrLine = a_NBT.FindChildByName(Data, "width"); @@ -184,6 +185,82 @@ bool cMapSerializer::LoadMapFromNBT(const cParsedNBT & a_NBT) +cIDCountSerializer::cIDCountSerializer(const AString & a_WorldName) : m_MapCount(0) +{ + AString DataPath; + Printf(DataPath, "%s/data", a_WorldName.c_str()); + + Printf(m_Path, "%s/idcounts.dat", DataPath.c_str()); + + cFile::CreateFolder(FILE_IO_PREFIX + DataPath); +} + + + + + +bool cIDCountSerializer::Load(void) +{ + AString Data = cFile::ReadWholeFile(FILE_IO_PREFIX + m_Path); + if (Data.empty()) + { + return false; + } + + // NOTE: idcounts.dat is not compressed (raw format) + + // Parse the NBT data: + cParsedNBT NBT(Data.data(), Data.size()); + if (!NBT.IsValid()) + { + // NBT Parsing failed + return false; + } + + int CurrLine = NBT.FindChildByName(0, "map"); + if (CurrLine >= 0) + { + m_MapCount = (int)NBT.GetShort(CurrLine); + } + + return true; +} + + + + + +bool cIDCountSerializer::Save(void) +{ + cFastNBTWriter Writer; + + Writer.AddShort("map", m_MapCount); + + Writer.Finish(); + + #ifdef _DEBUG + cParsedNBT TestParse(Writer.GetResult().data(), Writer.GetResult().size()); + ASSERT(TestParse.IsValid()); + #endif // _DEBUG + + cFile File; + if (!File.Open(FILE_IO_PREFIX + m_Path, cFile::fmWrite)) + { + return false; + } + + // NOTE: idcounts.dat is not compressed (raw format) + + File.Write(Writer.GetResult().data(), Writer.GetResult().size()); + File.Close(); + + return true; +} + + + + + diff --git a/src/WorldStorage/MapSerializer.h b/src/WorldStorage/MapSerializer.h index 71791a2fb..d9da107bc 100644 --- a/src/WorldStorage/MapSerializer.h +++ b/src/WorldStorage/MapSerializer.h @@ -50,3 +50,28 @@ private: +class cIDCountSerializer +{ +public: + + cIDCountSerializer(const AString & a_WorldName); + + bool Load(void); + + bool Save(void); + + inline unsigned int GetMapCount(void) const { return m_MapCount; } + + inline void SetMapCount(unsigned int a_MapCount) { m_MapCount = a_MapCount; } + + +private: + + AString m_Path; + + unsigned int m_MapCount; +}; + + + +