diff options
Diffstat (limited to 'src')
43 files changed, 182 insertions, 1731 deletions
diff --git a/src/Bindings/ManualBindings.cpp b/src/Bindings/ManualBindings.cpp index d8134f159..f4764447c 100644 --- a/src/Bindings/ManualBindings.cpp +++ b/src/Bindings/ManualBindings.cpp @@ -1957,26 +1957,20 @@ static int tolua_cPlayer_PermissionMatches(lua_State * tolua_S) // Check the params: cLuaState L(tolua_S); if ( - !L.CheckParamUserType(1, "cPlayer") || - !L.CheckParamString (2, 3) || - !L.CheckParamEnd (4) + !L.CheckParamUserTable(1, "cPlayer") || + !L.CheckParamString (2, 3) || + !L.CheckParamEnd (4) ) { return 0; } // Get the params: - cPlayer * self = (cPlayer *)tolua_tousertype(tolua_S, 1, NULL); - if (self == NULL) - { - LOGWARNING("%s: invalid self (%p)", __FUNCTION__, self); - return 0; - } AString Permission, Template; L.GetStackValues(2, Permission, Template); // Push the result of the match: - L.Push(self->PermissionMatches(StringSplit(Permission, "."), StringSplit(Template, "."))); + L.Push(cPlayer::PermissionMatches(StringSplit(Permission, "."), StringSplit(Template, "."))); return 1; } diff --git a/src/BlockEntities/BeaconEntity.cpp b/src/BlockEntities/BeaconEntity.cpp index dcf659f47..02f45a097 100644 --- a/src/BlockEntities/BeaconEntity.cpp +++ b/src/BlockEntities/BeaconEntity.cpp @@ -303,68 +303,6 @@ void cBeaconEntity::UsedBy(cPlayer * a_Player) -bool cBeaconEntity::LoadFromJson(const Json::Value & a_Value) -{ - m_PosX = a_Value.get("x", 0).asInt(); - m_PosY = a_Value.get("y", 0).asInt(); - m_PosZ = a_Value.get("z", 0).asInt(); - - Json::Value AllSlots = a_Value.get("Slots", 0); - int SlotIdx = 0; - for (Json::Value::iterator itr = AllSlots.begin(); itr != AllSlots.end(); ++itr) - { - cItem Item; - Item.FromJson(*itr); - SetSlot(SlotIdx, Item); - SlotIdx++; - } - - m_BeaconLevel = (char)a_Value.get("Level", 0).asInt(); - int PrimaryEffect = a_Value.get("PrimaryEffect", 0).asInt(); - int SecondaryEffect = a_Value.get("SecondaryEffect", 0).asInt(); - - if ((PrimaryEffect >= 0) && (PrimaryEffect <= (int)cEntityEffect::effSaturation)) - { - m_PrimaryEffect = (cEntityEffect::eType)PrimaryEffect; - } - - if ((SecondaryEffect >= 0) && (SecondaryEffect <= (int)cEntityEffect::effSaturation)) - { - m_SecondaryEffect = (cEntityEffect::eType)SecondaryEffect; - } - - return true; -} - - - - - -void cBeaconEntity::SaveToJson(Json::Value& a_Value) -{ - a_Value["x"] = m_PosX; - a_Value["y"] = m_PosY; - a_Value["z"] = m_PosZ; - - Json::Value AllSlots; - int NumSlots = m_Contents.GetNumSlots(); - for (int i = 0; i < NumSlots; i++) - { - Json::Value Slot; - m_Contents.GetSlot(i).GetJson(Slot); - AllSlots.append(Slot); - } - a_Value["Slots"] = AllSlots; - - a_Value["Level"] = m_BeaconLevel; - a_Value["PrimaryEffect"] = (int)m_PrimaryEffect; - a_Value["SecondaryEffect"] = (int)m_SecondaryEffect; -} - - - - - void cBeaconEntity::SendTo(cClientHandle & a_Client) { a_Client.SendUpdateBlockEntity(*this); diff --git a/src/BlockEntities/BeaconEntity.h b/src/BlockEntities/BeaconEntity.h index 0d7150aef..8c2dad254 100644 --- a/src/BlockEntities/BeaconEntity.h +++ b/src/BlockEntities/BeaconEntity.h @@ -34,9 +34,7 @@ public: cBeaconEntity(int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World); - bool LoadFromJson(const Json::Value & a_Value); // cBlockEntity overrides: - virtual void SaveToJson(Json::Value& a_Value) override; virtual void SendTo(cClientHandle & a_Client) override; virtual bool Tick(float a_Dt, cChunk & a_Chunk) override; virtual void UsedBy(cPlayer * a_Player) override; diff --git a/src/BlockEntities/BlockEntity.h b/src/BlockEntities/BlockEntity.h index 066bbc696..54ab40f3e 100644 --- a/src/BlockEntities/BlockEntity.h +++ b/src/BlockEntities/BlockEntity.h @@ -74,8 +74,6 @@ public: int GetRelZ(void) const { return m_RelZ; } // tolua_end - - virtual void SaveToJson (Json::Value & a_Value) = 0; /// Called when a player uses this entity; should open the UI window virtual void UsedBy( cPlayer * a_Player) = 0; diff --git a/src/BlockEntities/ChestEntity.cpp b/src/BlockEntities/ChestEntity.cpp index a89e5747e..19d88b646 100644 --- a/src/BlockEntities/ChestEntity.cpp +++ b/src/BlockEntities/ChestEntity.cpp @@ -33,48 +33,6 @@ cChestEntity::~cChestEntity() -bool cChestEntity::LoadFromJson(const Json::Value & a_Value) -{ - m_PosX = a_Value.get("x", 0).asInt(); - m_PosY = a_Value.get("y", 0).asInt(); - m_PosZ = a_Value.get("z", 0).asInt(); - - Json::Value AllSlots = a_Value.get("Slots", 0); - int SlotIdx = 0; - for (Json::Value::iterator itr = AllSlots.begin(); itr != AllSlots.end(); ++itr) - { - cItem Item; - Item.FromJson(*itr); - SetSlot(SlotIdx, Item); - SlotIdx++; - } - return true; -} - - - - - -void cChestEntity::SaveToJson(Json::Value & a_Value) -{ - a_Value["x"] = m_PosX; - a_Value["y"] = m_PosY; - a_Value["z"] = m_PosZ; - - Json::Value AllSlots; - for (int i = m_Contents.GetNumSlots() - 1; i >= 0; i--) - { - Json::Value Slot; - m_Contents.GetSlot(i).GetJson(Slot); - AllSlots.append(Slot); - } - a_Value["Slots"] = AllSlots; -} - - - - - void cChestEntity::SendTo(cClientHandle & a_Client) { // The chest entity doesn't need anything sent to the client when it's created / gets in the viewdistance diff --git a/src/BlockEntities/ChestEntity.h b/src/BlockEntities/ChestEntity.h index fa36e08be..af5d851a8 100644 --- a/src/BlockEntities/ChestEntity.h +++ b/src/BlockEntities/ChestEntity.h @@ -39,11 +39,8 @@ public: virtual ~cChestEntity(); static const char * GetClassStatic(void) { return "cChestEntity"; } - - bool LoadFromJson(const Json::Value & a_Value); // cBlockEntity overrides: - virtual void SaveToJson(Json::Value & a_Value) override; virtual void SendTo(cClientHandle & a_Client) override; virtual void UsedBy(cPlayer * a_Player) override; diff --git a/src/BlockEntities/CommandBlockEntity.cpp b/src/BlockEntities/CommandBlockEntity.cpp index 318874a9b..1a5a3f01e 100644 --- a/src/BlockEntities/CommandBlockEntity.cpp +++ b/src/BlockEntities/CommandBlockEntity.cpp @@ -152,38 +152,6 @@ void cCommandBlockEntity::SendTo(cClientHandle & a_Client) -bool cCommandBlockEntity::LoadFromJson(const Json::Value & a_Value) -{ - m_PosX = a_Value.get("x", 0).asInt(); - m_PosY = a_Value.get("y", 0).asInt(); - m_PosZ = a_Value.get("z", 0).asInt(); - - m_Command = a_Value.get("Command", "").asString(); - m_LastOutput = a_Value.get("LastOutput", "").asString(); - m_Result = (NIBBLETYPE)a_Value.get("SuccessCount", 0).asInt(); - - return true; -} - - - - - -void cCommandBlockEntity::SaveToJson(Json::Value & a_Value) -{ - a_Value["x"] = m_PosX; - a_Value["y"] = m_PosY; - a_Value["z"] = m_PosZ; - - a_Value["Command"] = m_Command; - a_Value["LastOutput"] = m_LastOutput; - a_Value["SuccessCount"] = m_Result; -} - - - - - void cCommandBlockEntity::Execute() { ASSERT(m_World != NULL); // Execute should not be called before the command block is attached to a world diff --git a/src/BlockEntities/CommandBlockEntity.h b/src/BlockEntities/CommandBlockEntity.h index 22cd44322..939f38610 100644 --- a/src/BlockEntities/CommandBlockEntity.h +++ b/src/BlockEntities/CommandBlockEntity.h @@ -39,9 +39,6 @@ public: /// Creates a new empty command block entity cCommandBlockEntity(int a_X, int a_Y, int a_Z, cWorld * a_World); - bool LoadFromJson( const Json::Value& a_Value); - virtual void SaveToJson(Json::Value& a_Value) override; - virtual bool Tick(float a_Dt, cChunk & a_Chunk) override; virtual void SendTo(cClientHandle & a_Client) override; virtual void UsedBy(cPlayer * a_Player) override; diff --git a/src/BlockEntities/DropSpenserEntity.cpp b/src/BlockEntities/DropSpenserEntity.cpp index 05c7403e7..dac951b27 100644 --- a/src/BlockEntities/DropSpenserEntity.cpp +++ b/src/BlockEntities/DropSpenserEntity.cpp @@ -142,54 +142,6 @@ bool cDropSpenserEntity::Tick(float a_Dt, cChunk & a_Chunk) -bool cDropSpenserEntity::LoadFromJson(const Json::Value & a_Value) -{ - m_PosX = a_Value.get("x", 0).asInt(); - m_PosY = a_Value.get("y", 0).asInt(); - m_PosZ = a_Value.get("z", 0).asInt(); - - Json::Value AllSlots = a_Value.get("Slots", 0); - int SlotIdx = 0; - for (Json::Value::iterator itr = AllSlots.begin(); itr != AllSlots.end(); ++itr) - { - cItem Contents; - Contents.FromJson(*itr); - m_Contents.SetSlot(SlotIdx, Contents); - SlotIdx++; - if (SlotIdx >= m_Contents.GetNumSlots()) - { - return true; - } - } - - return true; -} - - - - - -void cDropSpenserEntity::SaveToJson(Json::Value & a_Value) -{ - a_Value["x"] = m_PosX; - a_Value["y"] = m_PosY; - a_Value["z"] = m_PosZ; - - Json::Value AllSlots; - int NumSlots = m_Contents.GetNumSlots(); - for (int i = 0; i < NumSlots; i++) - { - Json::Value Slot; - m_Contents.GetSlot(i).GetJson(Slot); - AllSlots.append(Slot); - } - a_Value["Slots"] = AllSlots; -} - - - - - void cDropSpenserEntity::SendTo(cClientHandle & a_Client) { // Nothing needs to be sent diff --git a/src/BlockEntities/DropSpenserEntity.h b/src/BlockEntities/DropSpenserEntity.h index c70cd0531..23f0ae89a 100644 --- a/src/BlockEntities/DropSpenserEntity.h +++ b/src/BlockEntities/DropSpenserEntity.h @@ -49,11 +49,8 @@ public: virtual ~cDropSpenserEntity(); static const char * GetClassStatic(void) { return "cDropSpenserEntity"; } - - bool LoadFromJson(const Json::Value & a_Value); // cBlockEntity overrides: - virtual void SaveToJson(Json::Value & a_Value) override; virtual bool Tick(float a_Dt, cChunk & a_Chunk) override; virtual void SendTo(cClientHandle & a_Client) override; virtual void UsedBy(cPlayer * a_Player) override; diff --git a/src/BlockEntities/EnderChestEntity.h b/src/BlockEntities/EnderChestEntity.h index 311af8d76..2719eb5e4 100644 --- a/src/BlockEntities/EnderChestEntity.h +++ b/src/BlockEntities/EnderChestEntity.h @@ -25,7 +25,6 @@ public: // cBlockEntity overrides: virtual void UsedBy(cPlayer * a_Player) override; - virtual void SaveToJson(Json::Value & a_Value) override { UNUSED(a_Value); } virtual void SendTo(cClientHandle & a_Client) override { UNUSED(a_Client); } static void LoadFromJson(const Json::Value & a_Value, cItemGrid & a_Grid); diff --git a/src/BlockEntities/FlowerPotEntity.cpp b/src/BlockEntities/FlowerPotEntity.cpp index d2bc59d34..01560f814 100644 --- a/src/BlockEntities/FlowerPotEntity.cpp +++ b/src/BlockEntities/FlowerPotEntity.cpp @@ -72,37 +72,6 @@ void cFlowerPotEntity::Destroy(void) -bool cFlowerPotEntity::LoadFromJson(const Json::Value & a_Value) -{ - m_PosX = a_Value.get("x", 0).asInt(); - m_PosY = a_Value.get("y", 0).asInt(); - m_PosZ = a_Value.get("z", 0).asInt(); - - m_Item = cItem(); - m_Item.FromJson(a_Value.get("Item", 0)); - - return true; -} - - - - - -void cFlowerPotEntity::SaveToJson(Json::Value & a_Value) -{ - a_Value["x"] = m_PosX; - a_Value["y"] = m_PosY; - a_Value["z"] = m_PosZ; - - Json::Value Item; - m_Item.GetJson(Item); - a_Value["Item"] = Item; -} - - - - - bool cFlowerPotEntity::IsFlower(short m_ItemType, short m_ItemData) { switch (m_ItemType) diff --git a/src/BlockEntities/FlowerPotEntity.h b/src/BlockEntities/FlowerPotEntity.h index b86f9c840..b68d3b118 100644 --- a/src/BlockEntities/FlowerPotEntity.h +++ b/src/BlockEntities/FlowerPotEntity.h @@ -38,9 +38,6 @@ public: /** Creates a new flowerpot entity at the specified block coords. a_World may be NULL */ cFlowerPotEntity(int a_BlocX, int a_BlockY, int a_BlockZ, cWorld * a_World); - - bool LoadFromJson( const Json::Value& a_Value); - virtual void SaveToJson(Json::Value& a_Value) override; virtual void Destroy(void) override; diff --git a/src/BlockEntities/FurnaceEntity.cpp b/src/BlockEntities/FurnaceEntity.cpp index fb88e9b35..4452fc00a 100644 --- a/src/BlockEntities/FurnaceEntity.cpp +++ b/src/BlockEntities/FurnaceEntity.cpp @@ -129,60 +129,6 @@ bool cFurnaceEntity::Tick(float a_Dt, cChunk & a_Chunk) -bool cFurnaceEntity::LoadFromJson(const Json::Value & a_Value) -{ - m_PosX = a_Value.get("x", 0).asInt(); - m_PosY = a_Value.get("y", 0).asInt(); - m_PosZ = a_Value.get("z", 0).asInt(); - - Json::Value AllSlots = a_Value.get("Slots", 0); - int SlotIdx = 0; - for (Json::Value::iterator itr = AllSlots.begin(); itr != AllSlots.end(); ++itr) - { - cItem Item; - Item.FromJson(*itr); - SetSlot(SlotIdx, Item); - SlotIdx++; - } - - m_NeedCookTime = (int)(a_Value.get("CookTime", 0).asDouble() / 50); - m_TimeCooked = (int)(a_Value.get("TimeCooked", 0).asDouble() / 50); - m_FuelBurnTime = (int)(a_Value.get("BurnTime", 0).asDouble() / 50); - m_TimeBurned = (int)(a_Value.get("TimeBurned", 0).asDouble() / 50); - - return true; -} - - - - - -void cFurnaceEntity::SaveToJson( Json::Value& a_Value) -{ - a_Value["x"] = m_PosX; - a_Value["y"] = m_PosY; - a_Value["z"] = m_PosZ; - - Json::Value AllSlots; - int NumSlots = m_Contents.GetNumSlots(); - for (int i = 0; i < NumSlots; i++) - { - Json::Value Slot; - m_Contents.GetSlot(i).GetJson(Slot); - AllSlots.append(Slot); - } - a_Value["Slots"] = AllSlots; - - a_Value["CookTime"] = m_NeedCookTime * 50; - a_Value["TimeCooked"] = m_TimeCooked * 50; - a_Value["BurnTime"] = m_FuelBurnTime * 50; - a_Value["TimeBurned"] = m_TimeBurned * 50; -} - - - - - void cFurnaceEntity::SendTo(cClientHandle & a_Client) { // Nothing needs to be sent diff --git a/src/BlockEntities/FurnaceEntity.h b/src/BlockEntities/FurnaceEntity.h index 7ac25cf52..ed3317af6 100644 --- a/src/BlockEntities/FurnaceEntity.h +++ b/src/BlockEntities/FurnaceEntity.h @@ -44,11 +44,8 @@ public: virtual ~cFurnaceEntity(); static const char * GetClassStatic() { return "cFurnaceEntity"; } - - bool LoadFromJson(const Json::Value & a_Value); // cBlockEntity overrides: - virtual void SaveToJson(Json::Value & a_Value) override; virtual void SendTo(cClientHandle & a_Client) override; virtual bool Tick(float a_Dt, cChunk & a_Chunk) override; virtual void UsedBy(cPlayer * a_Player) override; diff --git a/src/BlockEntities/HopperEntity.cpp b/src/BlockEntities/HopperEntity.cpp index 444378c92..103f516fc 100644 --- a/src/BlockEntities/HopperEntity.cpp +++ b/src/BlockEntities/HopperEntity.cpp @@ -70,17 +70,6 @@ bool cHopperEntity::Tick(float a_Dt, cChunk & a_Chunk) -void cHopperEntity::SaveToJson(Json::Value & a_Value) -{ - UNUSED(a_Value); - // TODO - LOGWARNING("%s: Not implemented yet", __FUNCTION__); -} - - - - - void cHopperEntity::SendTo(cClientHandle & a_Client) { // The hopper entity doesn't need anything sent to the client when it's created / gets in the viewdistance diff --git a/src/BlockEntities/HopperEntity.h b/src/BlockEntities/HopperEntity.h index 8e856fcda..5d06581c2 100644 --- a/src/BlockEntities/HopperEntity.h +++ b/src/BlockEntities/HopperEntity.h @@ -49,7 +49,6 @@ protected: // cBlockEntity overrides: virtual bool Tick(float a_Dt, cChunk & a_Chunk) override; - virtual void SaveToJson(Json::Value & a_Value) override; virtual void SendTo(cClientHandle & a_Client) override; virtual void UsedBy(cPlayer * a_Player) override; diff --git a/src/BlockEntities/JukeboxEntity.cpp b/src/BlockEntities/JukeboxEntity.cpp index 1131b99b0..bb9b335e0 100644 --- a/src/BlockEntities/JukeboxEntity.cpp +++ b/src/BlockEntities/JukeboxEntity.cpp @@ -117,31 +117,3 @@ void cJukeboxEntity::SetRecord(int a_Record) - -bool cJukeboxEntity::LoadFromJson(const Json::Value & a_Value) -{ - m_PosX = a_Value.get("x", 0).asInt(); - m_PosY = a_Value.get("y", 0).asInt(); - m_PosZ = a_Value.get("z", 0).asInt(); - - m_Record = a_Value.get("Record", 0).asInt(); - - return true; -} - - - - - -void cJukeboxEntity::SaveToJson(Json::Value & a_Value) -{ - a_Value["x"] = m_PosX; - a_Value["y"] = m_PosY; - a_Value["z"] = m_PosZ; - - a_Value["Record"] = m_Record; -} - - - - diff --git a/src/BlockEntities/JukeboxEntity.h b/src/BlockEntities/JukeboxEntity.h index a6fdf3c7e..49d2faa89 100644 --- a/src/BlockEntities/JukeboxEntity.h +++ b/src/BlockEntities/JukeboxEntity.h @@ -29,9 +29,6 @@ public: cJukeboxEntity(int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World); virtual ~cJukeboxEntity(); - bool LoadFromJson(const Json::Value & a_Value); - virtual void SaveToJson(Json::Value & a_Value) override; - // tolua_begin int GetRecord(void); diff --git a/src/BlockEntities/MobHeadEntity.cpp b/src/BlockEntities/MobHeadEntity.cpp index 9a1a40abe..67e13ffb2 100644 --- a/src/BlockEntities/MobHeadEntity.cpp +++ b/src/BlockEntities/MobHeadEntity.cpp @@ -77,35 +77,3 @@ void cMobHeadEntity::SendTo(cClientHandle & a_Client) - -bool cMobHeadEntity::LoadFromJson(const Json::Value & a_Value) -{ - m_PosX = a_Value.get("x", 0).asInt(); - m_PosY = a_Value.get("y", 0).asInt(); - m_PosZ = a_Value.get("z", 0).asInt(); - - m_Type = static_cast<eMobHeadType>(a_Value.get("Type", 0).asInt()); - m_Rotation = static_cast<eMobHeadRotation>(a_Value.get("Rotation", 0).asInt()); - m_Owner = a_Value.get("Owner", "").asString(); - - return true; -} - - - - - -void cMobHeadEntity::SaveToJson(Json::Value & a_Value) -{ - a_Value["x"] = m_PosX; - a_Value["y"] = m_PosY; - a_Value["z"] = m_PosZ; - - a_Value["Type"] = m_Type; - a_Value["Rotation"] = m_Rotation; - a_Value["Owner"] = m_Owner; -} - - - - diff --git a/src/BlockEntities/MobHeadEntity.h b/src/BlockEntities/MobHeadEntity.h index 45fa0d951..fcdeaa8a6 100644 --- a/src/BlockEntities/MobHeadEntity.h +++ b/src/BlockEntities/MobHeadEntity.h @@ -37,9 +37,6 @@ public: /** Creates a new mob head entity at the specified block coords. a_World may be NULL */ cMobHeadEntity(int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World); - bool LoadFromJson( const Json::Value& a_Value); - virtual void SaveToJson(Json::Value& a_Value) override; - // tolua_begin /** Set the Type */ diff --git a/src/BlockEntities/NoteEntity.cpp b/src/BlockEntities/NoteEntity.cpp index ecbedbcb1..a9af13c55 100644 --- a/src/BlockEntities/NoteEntity.cpp +++ b/src/BlockEntities/NoteEntity.cpp @@ -124,32 +124,3 @@ void cNoteEntity::IncrementPitch(void) - -bool cNoteEntity::LoadFromJson(const Json::Value & a_Value) -{ - - m_PosX = a_Value.get("x", 0).asInt(); - m_PosY = a_Value.get("y", 0).asInt(); - m_PosZ = a_Value.get("z", 0).asInt(); - - m_Pitch = (char)a_Value.get("p", 0).asInt(); - - return true; -} - - - - - -void cNoteEntity::SaveToJson(Json::Value & a_Value) -{ - a_Value["x"] = m_PosX; - a_Value["y"] = m_PosY; - a_Value["z"] = m_PosZ; - - a_Value["p"] = m_Pitch; -} - - - - diff --git a/src/BlockEntities/NoteEntity.h b/src/BlockEntities/NoteEntity.h index f538de060..d1ffa126a 100644 --- a/src/BlockEntities/NoteEntity.h +++ b/src/BlockEntities/NoteEntity.h @@ -44,9 +44,6 @@ public: cNoteEntity(int a_X, int a_Y, int a_Z, cWorld * a_World); virtual ~cNoteEntity() {} - bool LoadFromJson(const Json::Value & a_Value); - virtual void SaveToJson(Json::Value & a_Value) override; - // tolua_begin char GetPitch(void); diff --git a/src/BlockEntities/SignEntity.cpp b/src/BlockEntities/SignEntity.cpp index 423d254d2..d048d0218 100644 --- a/src/BlockEntities/SignEntity.cpp +++ b/src/BlockEntities/SignEntity.cpp @@ -22,7 +22,6 @@ cSignEntity::cSignEntity(BLOCKTYPE a_BlockType, int a_X, int a_Y, int a_Z, cWorl -// It don't do anything when 'used' void cSignEntity::UsedBy(cPlayer * a_Player) { UNUSED(a_Player); @@ -80,37 +79,3 @@ void cSignEntity::SendTo(cClientHandle & a_Client) - -bool cSignEntity::LoadFromJson(const Json::Value & a_Value) -{ - m_PosX = a_Value.get("x", 0).asInt(); - m_PosY = a_Value.get("y", 0).asInt(); - m_PosZ = a_Value.get("z", 0).asInt(); - - m_Line[0] = a_Value.get("Line1", "").asString(); - m_Line[1] = a_Value.get("Line2", "").asString(); - m_Line[2] = a_Value.get("Line3", "").asString(); - m_Line[3] = a_Value.get("Line4", "").asString(); - - return true; -} - - - - - -void cSignEntity::SaveToJson(Json::Value & a_Value) -{ - a_Value["x"] = m_PosX; - a_Value["y"] = m_PosY; - a_Value["z"] = m_PosZ; - - a_Value["Line1"] = m_Line[0]; - a_Value["Line2"] = m_Line[1]; - a_Value["Line3"] = m_Line[2]; - a_Value["Line4"] = m_Line[3]; -} - - - - diff --git a/src/BlockEntities/SignEntity.h b/src/BlockEntities/SignEntity.h index 33af100a4..53c43b758 100644 --- a/src/BlockEntities/SignEntity.h +++ b/src/BlockEntities/SignEntity.h @@ -37,9 +37,6 @@ public: /// Creates a new empty sign entity at the specified block coords and block type (wall or standing). a_World may be NULL cSignEntity(BLOCKTYPE a_BlockType, int a_X, int a_Y, int a_Z, cWorld * a_World); - bool LoadFromJson( const Json::Value& a_Value); - virtual void SaveToJson(Json::Value& a_Value) override; - // tolua_begin /// Sets all the sign's lines diff --git a/src/BlockID.h b/src/BlockID.h index 9a8830710..69b5e2fe0 100644 --- a/src/BlockID.h +++ b/src/BlockID.h @@ -186,6 +186,9 @@ enum ENUM_BLOCK_ID E_BLOCK_BLOCK_OF_COAL = 173, E_BLOCK_PACKED_ICE = 174, E_BLOCK_BIG_FLOWER = 175, + E_BLOCK_STANDING_BANNER = 176, + E_BLOCK_WALL_BANNER = 177, + E_BLOCK_INVERTED_DAYLIGHT_SENSOR = 178, E_BLOCK_RED_SANDSTONE = 179, E_BLOCK_RED_SANDSTONE_STAIRS = 180, E_BLOCK_DOUBLE_NEW_STONE_SLAB= 181, @@ -442,7 +445,7 @@ enum //////////////////////////////////////////////////////////////////////////////// // Block metas: - // E_BLOCK_BIG_FLOWER metas + // E_BLOCK_BIG_FLOWER metas: E_META_BIG_FLOWER_SUNFLOWER = 0, E_META_BIG_FLOWER_LILAC = 1, E_META_BIG_FLOWER_DOUBLE_TALL_GRASS = 2, @@ -477,6 +480,7 @@ enum // E_BLOCK_DIRT metas: E_META_DIRT_NORMAL = 0, E_META_DIRT_GRASSLESS = 1, + E_META_DIRT_COARSE = 1, E_META_DIRT_PODZOL = 2, // E_BLOCK_DISPENSER / E_BLOCK_DROPPER metas: @@ -497,7 +501,7 @@ enum E_META_DOUBLE_STONE_SLAB_NETHER_BRICK = 6, E_META_DOUBLE_STONE_SLAB_STONE_SECRET = 7, - // E_BLOCK_FLOWER metas + // E_BLOCK_FLOWER metas: E_META_FLOWER_POPPY = 0, E_META_FLOWER_BLUE_ORCHID = 1, E_META_FLOWER_ALLIUM = 2, @@ -507,7 +511,7 @@ enum E_META_FLOWER_PINK_TULIP = 7, E_META_FLOWER_OXEYE_DAISY = 8, - // E_BLOCK_JUKEBOX metas + // E_BLOCK_JUKEBOX metas: E_META_JUKEBOX_OFF = 0, E_META_JUKEBOX_ON = 1, @@ -531,30 +535,37 @@ enum E_META_LOG_BIRCH = 2, E_META_LOG_JUNGLE = 3, - // E_BLOCK_NEW_LEAVES metas + // E_BLOCK_NEW_LEAVES metas: E_META_NEW_LEAVES_ACACIA_WOOD = 0, E_META_NEW_LEAVES_DARK_OAK_WOOD = 1, - // E_BLOCK_NEW_LOG metas + // E_BLOCK_NEW_LOG metas: E_META_NEW_LOG_ACACIA_WOOD = 0, E_META_NEW_LOG_DARK_OAK_WOOD = 1, // E_BLOCK_PLANKS metas: - E_META_PLANKS_APPLE = 0, - E_META_PLANKS_CONIFER = 1, - E_META_PLANKS_BIRCH = 2, - E_META_PLANKS_JUNGLE = 3, + E_META_PLANKS_APPLE = 0, + E_META_PLANKS_CONIFER = 1, + E_META_PLANKS_BIRCH = 2, + E_META_PLANKS_JUNGLE = 3, + E_META_PLANKS_ACACIA = 4, + E_META_PLANKS_DARK_OAK = 5, // E_BLOCK_(XXX_WEIGHTED)_PRESSURE_PLATE metas: E_META_PRESSURE_PLATE_RAISED = 0, E_META_PRESSURE_PLATE_DEPRESSED = 1, + // E_BLOCK_PRISMARINE_BLOCK metas: + E_META_PRISMARINE_BLOCK_ROUGH = 0, + E_META_PRISMARINE_BLOCK_BRICKS = 1, + E_META_PRISMARINE_BLOCK_DARK = 2, + // E_BLOCK_QUARTZ_BLOCK metas: E_META_QUARTZ_NORMAL = 0, E_META_QUARTZ_CHISELLED = 1, E_META_QUARTZ_PILLAR = 2, - // E_BLOCK_RAIL metas + // E_BLOCK_RAIL metas: E_META_RAIL_ZM_ZP = 0, E_META_RAIL_XM_XP = 1, E_META_RAIL_ASCEND_XP = 2, @@ -566,6 +577,11 @@ enum E_META_RAIL_CURVED_ZM_XM = 8, E_META_RAIL_CURVED_ZM_XP = 9, + // E_BLOCK_RED_SANDSTONE metas: + E_META_RED_SANDSTONE_NORMAL = 0, + E_META_RED_SANDSTONE_ORNAMENT = 1, + E_META_RED_SANDSTONE_SMOOTH = 2, + // E_BLOCK_SAND metas: E_META_SAND_NORMAL = 0, E_META_SAND_RED = 1, @@ -598,7 +614,7 @@ enum E_META_SNOW_LAYER_SEVEN = 6, E_META_SNOW_LAYER_EIGHT = 7, - // E_BLOCK_STAINED_CLAY metas + // E_BLOCK_STAINED_CLAY metas: E_META_STAINED_CLAY_WHITE = 0, E_META_STAINED_CLAY_ORANGE = 1, E_META_STAINED_CLAY_MAGENTA = 2, @@ -616,7 +632,7 @@ enum E_META_STAINED_CLAY_RED = 14, E_META_STAINED_CLAY_BLACK = 15, - // E_BLOCK_STAINED_GLASS metas + // E_BLOCK_STAINED_GLASS metas: E_META_STAINED_GLASS_WHITE = 0, E_META_STAINED_GLASS_ORANGE = 1, E_META_STAINED_GLASS_MAGENTA = 2, @@ -634,7 +650,7 @@ enum E_META_STAINED_GLASS_RED = 14, E_META_STAINED_GLASS_BLACK = 15, - // E_BLOCK_STAINED_GLASS_PANE metas + // E_BLOCK_STAINED_GLASS_PANE metas: E_META_STAINED_GLASS_PANE_WHITE = 0, E_META_STAINED_GLASS_PANE_ORANGE = 1, E_META_STAINED_GLASS_PANE_MAGENTA = 2, @@ -655,8 +671,11 @@ enum // E_BLOCK_STONE metas: E_META_STONE = 0, E_META_STONE_GRANITE = 1, + E_META_STONE_POLISHED_GRANITE = 2, E_META_STONE_DIORITE = 3, + E_META_STONE_POLISHED_DIORITE = 4, E_META_STONE_ANDESITE = 5, + E_META_STONE_POLISHED_ANDESITE = 6, // E_BLOCK_STONE_SLAB metas: E_META_STONE_SLAB_STONE = 0, @@ -727,6 +746,24 @@ enum //////////////////////////////////////////////////////////////////////////////// // Item metas: + // E_ITEM_BANNER metas: + E_META_BANNER_BLACK = 0, + E_META_BANNER_RED = 1, + E_META_BANNER_GREEN = 2, + E_META_BANNER_BROWN = 3, + E_META_BANNER_BLUE = 4, + E_META_BANNER_PURPLE = 5, + E_META_BANNER_CYAN = 6, + E_META_BANNER_LIGHTGRAY = 7, + E_META_BANNER_GRAY = 8, + E_META_BANNER_PINK = 9, + E_META_BANNER_LIGHTGREEN = 10, + E_META_BANNER_YELLOW = 11, + E_META_BANNER_LIGHTBLUE = 12, + E_META_BANNER_MAGENTA = 13, + E_META_BANNER_ORANGE = 14, + E_META_BANNER_WHITE = 15, + // E_ITEM_COAL metas: E_META_COAL_NORMAL = 0, E_META_COAL_CHARCOAL = 1, @@ -753,6 +790,13 @@ enum E_META_GOLDEN_APPLE_NORMAL = 0, E_META_GOLDEN_APPLE_ENCHANTED = 1, + // E_ITEM_HEAD metas: + E_META_HEAD_SKELETON = 0, + E_META_HEAD_WITHER = 1, + E_META_HEAD_ZOMBIE = 2, + E_META_HEAD_PLAYER = 3, + E_META_HEAD_CREEPER = 4, + // E_ITEM_RAW_FISH metas: E_META_RAW_FISH_FISH = 0, E_META_RAW_FISH_SALMON = 1, @@ -762,8 +806,6 @@ enum // E_ITEM_COOKED_FISH metas: E_META_COOKED_FISH_FISH = 0, E_META_COOKED_FISH_SALMON = 1, - E_META_COOKED_FISH_CLOWNFISH = 2, - E_META_COOKED_FISH_PUFFERFISH = 3, // E_ITEM_MINECART_TRACKS metas: E_META_TRACKS_X = 1, diff --git a/src/BlockInfo.cpp b/src/BlockInfo.cpp index 05a1e13f8..bdd3a9c26 100644 --- a/src/BlockInfo.cpp +++ b/src/BlockInfo.cpp @@ -99,6 +99,7 @@ void cBlockInfo::Initialize(cBlockInfoArray & a_Info) a_Info[E_BLOCK_HOPPER ].m_SpreadLightFalloff = 1; a_Info[E_BLOCK_ICE ].m_SpreadLightFalloff = 1; a_Info[E_BLOCK_INACTIVE_COMPARATOR ].m_SpreadLightFalloff = 1; + a_Info[E_BLOCK_INVERTED_DAYLIGHT_SENSOR ].m_SpreadLightFalloff = 1; a_Info[E_BLOCK_IRON_BARS ].m_SpreadLightFalloff = 1; a_Info[E_BLOCK_IRON_DOOR ].m_SpreadLightFalloff = 1; a_Info[E_BLOCK_IRON_TRAPDOOR ].m_SpreadLightFalloff = 1; @@ -137,6 +138,7 @@ void cBlockInfo::Initialize(cBlockInfoArray & a_Info) a_Info[E_BLOCK_SPRUCE_FENCE_GATE ].m_SpreadLightFalloff = 1; a_Info[E_BLOCK_STAINED_GLASS ].m_SpreadLightFalloff = 1; a_Info[E_BLOCK_STAINED_GLASS_PANE ].m_SpreadLightFalloff = 1; + a_Info[E_BLOCK_STANDING_BANNER ].m_SpreadLightFalloff = 1; a_Info[E_BLOCK_STICKY_PISTON ].m_SpreadLightFalloff = 1; a_Info[E_BLOCK_STONE_BUTTON ].m_SpreadLightFalloff = 1; a_Info[E_BLOCK_STONE_PRESSURE_PLATE].m_SpreadLightFalloff = 1; @@ -149,6 +151,7 @@ void cBlockInfo::Initialize(cBlockInfoArray & a_Info) a_Info[E_BLOCK_TRIPWIRE ].m_SpreadLightFalloff = 1; a_Info[E_BLOCK_TRIPWIRE_HOOK ].m_SpreadLightFalloff = 1; a_Info[E_BLOCK_VINES ].m_SpreadLightFalloff = 1; + a_Info[E_BLOCK_WALL_BANNER ].m_SpreadLightFalloff = 1; a_Info[E_BLOCK_WALLSIGN ].m_SpreadLightFalloff = 1; a_Info[E_BLOCK_WOODEN_BUTTON ].m_SpreadLightFalloff = 1; a_Info[E_BLOCK_WOODEN_DOOR ].m_SpreadLightFalloff = 1; @@ -256,6 +259,7 @@ void cBlockInfo::Initialize(cBlockInfoArray & a_Info) a_Info[E_BLOCK_STAINED_GLASS_PANE ].m_Transparent = true; a_Info[E_BLOCK_STATIONARY_LAVA ].m_Transparent = true; a_Info[E_BLOCK_STATIONARY_WATER ].m_Transparent = true; + a_Info[E_BLOCK_STANDING_BANNER ].m_Transparent = true; a_Info[E_BLOCK_STICKY_PISTON ].m_Transparent = true; a_Info[E_BLOCK_STONE_BUTTON ].m_Transparent = true; a_Info[E_BLOCK_STONE_PRESSURE_PLATE].m_Transparent = true; @@ -268,6 +272,7 @@ void cBlockInfo::Initialize(cBlockInfoArray & a_Info) a_Info[E_BLOCK_TRIPWIRE ].m_Transparent = true; a_Info[E_BLOCK_TRIPWIRE_HOOK ].m_Transparent = true; a_Info[E_BLOCK_VINES ].m_Transparent = true; + a_Info[E_BLOCK_WALL_BANNER ].m_Transparent = true; a_Info[E_BLOCK_WALLSIGN ].m_Transparent = true; a_Info[E_BLOCK_WATER ].m_Transparent = true; a_Info[E_BLOCK_WOODEN_BUTTON ].m_Transparent = true; @@ -329,6 +334,7 @@ void cBlockInfo::Initialize(cBlockInfoArray & a_Info) a_Info[E_BLOCK_HEAVY_WEIGHTED_PRESSURE_PLATE].m_PistonBreakable = true; a_Info[E_BLOCK_INACTIVE_COMPARATOR ].m_PistonBreakable = true; a_Info[E_BLOCK_IRON_DOOR ].m_PistonBreakable = true; + a_Info[E_BLOCK_IRON_TRAPDOOR ].m_PistonBreakable = true; a_Info[E_BLOCK_JACK_O_LANTERN ].m_PistonBreakable = true; a_Info[E_BLOCK_LIGHT_WEIGHTED_PRESSURE_PLATE].m_PistonBreakable = true; a_Info[E_BLOCK_LILY_PAD ].m_PistonBreakable = true; @@ -474,12 +480,14 @@ void cBlockInfo::Initialize(cBlockInfoArray & a_Info) a_Info[E_BLOCK_SNOW ].m_IsSolid = false; a_Info[E_BLOCK_STATIONARY_LAVA ].m_IsSolid = false; a_Info[E_BLOCK_STATIONARY_WATER ].m_IsSolid = false; + a_Info[E_BLOCK_STANDING_BANNER ].m_IsSolid = false; a_Info[E_BLOCK_STONE_BUTTON ].m_IsSolid = false; a_Info[E_BLOCK_STONE_PRESSURE_PLATE].m_IsSolid = false; a_Info[E_BLOCK_TALL_GRASS ].m_IsSolid = false; a_Info[E_BLOCK_TORCH ].m_IsSolid = false; a_Info[E_BLOCK_TRIPWIRE ].m_IsSolid = false; a_Info[E_BLOCK_VINES ].m_IsSolid = false; + a_Info[E_BLOCK_WALL_BANNER ].m_IsSolid = false; a_Info[E_BLOCK_WALLSIGN ].m_IsSolid = false; a_Info[E_BLOCK_WATER ].m_IsSolid = false; a_Info[E_BLOCK_WOODEN_BUTTON ].m_IsSolid = false; @@ -735,7 +743,7 @@ void cBlockInfo::Initialize(cBlockInfoArray & a_Info) a_Info[E_BLOCK_NEW_LOG ].m_PlaceSound = "dig.wood"; a_Info[E_BLOCK_ACACIA_WOOD_STAIRS ].m_PlaceSound = "dig.wood"; a_Info[E_BLOCK_DARK_OAK_WOOD_STAIRS ].m_PlaceSound = "dig.wood"; - a_Info[E_BLOCK_SLIME_BLOCK ].m_PlaceSound = "dig.slime"; // TODO: Check that this is the correct name + a_Info[E_BLOCK_SLIME_BLOCK ].m_PlaceSound = "mob.slime.big"; a_Info[E_BLOCK_BARRIER ].m_PlaceSound = "dig.stone"; a_Info[E_BLOCK_IRON_TRAPDOOR ].m_PlaceSound = "dig.metal"; a_Info[E_BLOCK_PRISMARINE_BLOCK ].m_PlaceSound = "dig.stone"; @@ -746,6 +754,8 @@ void cBlockInfo::Initialize(cBlockInfoArray & a_Info) a_Info[E_BLOCK_BLOCK_OF_COAL ].m_PlaceSound = "dig.stone"; a_Info[E_BLOCK_PACKED_ICE ].m_PlaceSound = "dig.stone"; a_Info[E_BLOCK_BIG_FLOWER ].m_PlaceSound = "dig.grass"; + a_Info[E_BLOCK_STANDING_BANNER ].m_PlaceSound = "dig.wood"; + a_Info[E_BLOCK_WALL_BANNER ].m_PlaceSound = "dig.wood"; a_Info[E_BLOCK_RED_SANDSTONE ].m_PlaceSound = "dig.stone"; a_Info[E_BLOCK_RED_SANDSTONE_STAIRS ].m_PlaceSound = "dig.stone"; a_Info[E_BLOCK_NEW_STONE_SLAB ].m_PlaceSound = "dig.stone"; diff --git a/src/Blocks/BlockDirt.h b/src/Blocks/BlockDirt.h index 60d81db72..19f889372 100644 --- a/src/Blocks/BlockDirt.h +++ b/src/Blocks/BlockDirt.h @@ -21,7 +21,15 @@ public: virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override { - a_Pickups.push_back(cItem(E_BLOCK_DIRT, 1, 0)); + if (a_BlockMeta == E_META_DIRT_COARSE) + { + // Drop the coarse block (dirt, meta 1) + a_Pickups.Add(E_BLOCK_DIRT, 1, E_META_DIRT_COARSE); + } + else + { + a_Pickups.Add(E_BLOCK_DIRT, 1, E_META_DIRT_NORMAL); + } } diff --git a/src/Blocks/BlockDoor.h b/src/Blocks/BlockDoor.h index 0ff8bcfc8..92ad8da12 100644 --- a/src/Blocks/BlockDoor.h +++ b/src/Blocks/BlockDoor.h @@ -173,7 +173,23 @@ public: /** Returns true if the specified blocktype is any kind of door */ inline static bool IsDoor(BLOCKTYPE a_Block) { - return (a_Block == E_BLOCK_WOODEN_DOOR) || (a_Block == E_BLOCK_IRON_DOOR); + switch (a_Block) + { + case E_BLOCK_ACACIA_DOOR: + case E_BLOCK_BIRCH_DOOR: + case E_BLOCK_DARK_OAK_DOOR: + case E_BLOCK_IRON_DOOR: + case E_BLOCK_JUNGLE_DOOR: + case E_BLOCK_SPRUCE_DOOR: + case E_BLOCK_WOODEN_DOOR: + { + return true; + } + default: + { + return false; + } + } } diff --git a/src/Blocks/BlockPiston.h b/src/Blocks/BlockPiston.h index 3a3fc7224..f868f4d8e 100644 --- a/src/Blocks/BlockPiston.h +++ b/src/Blocks/BlockPiston.h @@ -100,6 +100,7 @@ private: case E_BLOCK_BREWING_STAND: case E_BLOCK_CHEST: case E_BLOCK_COMMAND_BLOCK: + case E_BLOCK_DAYLIGHT_SENSOR: case E_BLOCK_DISPENSER: case E_BLOCK_DROPPER: case E_BLOCK_ENCHANTMENT_TABLE: @@ -108,6 +109,7 @@ private: // Notice the lack of an E_BLOCK_ENDER_CHEST here; its because ender chests can totally be pushed/pulled in MCS :) case E_BLOCK_FURNACE: case E_BLOCK_LIT_FURNACE: + case E_BLOCK_INVERTED_DAYLIGHT_SENSOR: case E_BLOCK_HOPPER: case E_BLOCK_JUKEBOX: case E_BLOCK_MOB_SPAWNER: @@ -115,7 +117,9 @@ private: case E_BLOCK_NOTE_BLOCK: case E_BLOCK_OBSIDIAN: case E_BLOCK_PISTON_EXTENSION: + case E_BLOCK_STANDING_BANNER: case E_BLOCK_TRAPPED_CHEST: + case E_BLOCK_WALL_BANNER: { return false; } diff --git a/src/Blocks/BlockTrapdoor.h b/src/Blocks/BlockTrapdoor.h index 41256ae55..8c96de0f1 100644 --- a/src/Blocks/BlockTrapdoor.h +++ b/src/Blocks/BlockTrapdoor.h @@ -29,6 +29,12 @@ public: virtual void OnUse(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ) override { + if (m_BlockType == E_BLOCK_IRON_TRAPDOOR) + { + // Iron doors can only be toggled by redstone, not by right-clicking + return; + } + // Flip the ON bit on/off using the XOR bitwise operation NIBBLETYPE Meta = (a_ChunkInterface.GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ) ^ 0x04); a_ChunkInterface.SetBlockMeta(a_BlockX, a_BlockY, a_BlockZ, Meta); diff --git a/src/ClientHandle.h b/src/ClientHandle.h index 1f22762c0..20592c190 100644 --- a/src/ClientHandle.h +++ b/src/ClientHandle.h @@ -145,7 +145,9 @@ public: void SendCollectEntity (const cEntity & a_Entity, const cPlayer & a_Player); void SendDestroyEntity (const cEntity & a_Entity); void SendDisconnect (const AString & a_Reason); + void SendDisplayObjective (const AString & a_Objective, cScoreboard::eDisplaySlot a_Display); void SendEditSign (int a_BlockX, int a_BlockY, int a_BlockZ); + void SendEntityAnimation (const cEntity & a_Entity, char a_Animation); // tolua_export void SendEntityEffect (const cEntity & a_Entity, int a_EffectID, int a_Amplifier, short a_Duration); void SendEntityEquipment (const cEntity & a_Entity, short a_SlotNum, const cItem & a_Item); void SendEntityHeadLook (const cEntity & a_Entity); @@ -156,6 +158,8 @@ public: void SendEntityRelMoveLook (const cEntity & a_Entity, char a_RelX, char a_RelY, char a_RelZ); void SendEntityStatus (const cEntity & a_Entity, char a_Status); void SendEntityVelocity (const cEntity & a_Entity); + void SendExperience (void); + void SendExperienceOrb (const cExpOrb & a_ExpOrb); void SendExplosion (double a_BlockX, double a_BlockY, double a_BlockZ, float a_Radius, const cVector3iArray & a_BlocksAffected, const Vector3d & a_PlayerMotion); void SendGameMode (eGameMode a_GameMode); void SendHealth (void); @@ -164,15 +168,14 @@ public: void SendMapDecorators (int a_ID, const cMapDecoratorList & a_Decorators, unsigned int m_Scale); void SendMapInfo (int a_ID, unsigned int a_Scale); void SendPaintingSpawn (const cPainting & a_Painting); - void SendPickupSpawn (const cPickup & a_Pickup); - void SendEntityAnimation (const cEntity & a_Entity, char a_Animation); // tolua_export 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_ParticleAmount); + void SendPickupSpawn (const cPickup & a_Pickup); void SendPlayerAbilities (void); void SendPlayerListAddPlayer (const cPlayer & a_Player); void SendPlayerListRemovePlayer (const cPlayer & a_Player); + void SendPlayerListUpdateDisplayName(const cPlayer & a_Player, const AString & a_CustomName); void SendPlayerListUpdateGameMode (const cPlayer & a_Player); void SendPlayerListUpdatePing (const cPlayer & a_Player); - void SendPlayerListUpdateDisplayName(const cPlayer & a_Player, const AString & a_CustomName); void SendPlayerMaxSpeed (void); ///< Informs the client of the maximum player speed (1.6.1+) void SendPlayerMoveLook (void); void SendPlayerPosition (void); @@ -180,11 +183,8 @@ public: void SendPluginMessage (const AString & a_Channel, const AString & a_Message); // Exported in ManualBindings.cpp void SendRemoveEntityEffect (const cEntity & a_Entity, int a_EffectID); void SendRespawn (eDimension a_Dimension, bool a_ShouldIgnoreDimensionChecks = false); - void SendExperience (void); - void SendExperienceOrb (const cExpOrb & a_ExpOrb); - void SendScoreboardObjective (const AString & a_Name, const AString & a_DisplayName, Byte a_Mode); void SendScoreUpdate (const AString & a_Objective, const AString & a_Player, cObjective::Score a_Score, Byte a_Mode); - void SendDisplayObjective (const AString & a_Objective, cScoreboard::eDisplaySlot a_Display); + void SendScoreboardObjective (const AString & a_Name, const AString & a_DisplayName, Byte a_Mode); void SendSoundEffect (const AString & a_SoundName, double a_X, double a_Y, double a_Z, float a_Volume, float a_Pitch); // tolua_export void SendSoundParticleEffect (int a_EffectID, int a_SrcX, int a_SrcY, int a_SrcZ, int a_Data); void SendSpawnFallingBlock (const cFallingBlock & a_FallingBlock); diff --git a/src/Entities/Player.h b/src/Entities/Player.h index ffd0b7e03..22d6a2ae2 100644 --- a/src/Entities/Player.h +++ b/src/Entities/Player.h @@ -182,11 +182,11 @@ public: /** Sets the player team, NULL if none */ void SetTeam(cTeam * a_Team); + // tolua_end + /** Forces the player to query the scoreboard for his team */ cTeam * UpdateTeam(void); - // tolua_end - /** Return the associated statistic and achievement manager. */ cStatManager & GetStatManager() { return m_Stats; } @@ -421,9 +421,13 @@ public: /** Sets the player's bed (home) position */ void SetBedPos(const Vector3i & a_Pos) { m_LastBedPos = a_Pos; } + + // tolua_end /** Update movement-related statistics. */ void UpdateMovementStats(const Vector3d & a_DeltaPos); + + // tolua_begin /** Returns wheter the player can fly or not. */ virtual bool CanFly(void) const { return m_CanFly; } diff --git a/src/Items/ItemHandler.cpp b/src/Items/ItemHandler.cpp index caa623abc..912dde022 100644 --- a/src/Items/ItemHandler.cpp +++ b/src/Items/ItemHandler.cpp @@ -574,6 +574,7 @@ bool cItemHandler::CanHarvestBlock(BLOCKTYPE a_BlockType) case E_BLOCK_COBBLESTONE_WALL: case E_BLOCK_DIAMOND_BLOCK: case E_BLOCK_DIAMOND_ORE: + case E_BLOCK_DOUBLE_NEW_STONE_SLAB: case E_BLOCK_DOUBLE_STONE_SLAB: case E_BLOCK_EMERALD_ORE: case E_BLOCK_ENCHANTMENT_TABLE: @@ -587,6 +588,7 @@ bool cItemHandler::CanHarvestBlock(BLOCKTYPE a_BlockType) case E_BLOCK_LAPIS_BLOCK: case E_BLOCK_LAPIS_ORE: case E_BLOCK_LIT_FURNACE: + case E_BLOCK_MOB_SPAWNER: case E_BLOCK_MOSSY_COBBLESTONE: case E_BLOCK_NETHER_BRICK: case E_BLOCK_NETHER_BRICK_STAIRS: @@ -594,6 +596,7 @@ bool cItemHandler::CanHarvestBlock(BLOCKTYPE a_BlockType) case E_BLOCK_NETHERRACK: case E_BLOCK_NEW_STONE_SLAB: case E_BLOCK_OBSIDIAN: + case E_BLOCK_PACKED_ICE: case E_BLOCK_PRISMARINE_BLOCK: case E_BLOCK_RED_SANDSTONE: case E_BLOCK_RED_SANDSTONE_STAIRS: @@ -608,8 +611,6 @@ bool cItemHandler::CanHarvestBlock(BLOCKTYPE a_BlockType) case E_BLOCK_STONE_PRESSURE_PLATE: case E_BLOCK_STONE_SLAB: case E_BLOCK_VINES: - case E_BLOCK_PACKED_ICE: - case E_BLOCK_MOB_SPAWNER: { return false; } diff --git a/src/Items/ItemHoe.h b/src/Items/ItemHoe.h index de8b9a061..ae3723323 100644 --- a/src/Items/ItemHoe.h +++ b/src/Items/ItemHoe.h @@ -24,12 +24,35 @@ public: { return false; } - BLOCKTYPE Block = a_World->GetBlock(a_BlockX, a_BlockY, a_BlockZ); BLOCKTYPE UpperBlock = a_World->GetBlock(a_BlockX, a_BlockY + 1, a_BlockZ); + BLOCKTYPE Block; + NIBBLETYPE BlockMeta; + a_World->GetBlockTypeMeta(a_BlockX, a_BlockY, a_BlockZ, Block, BlockMeta); + if (((Block == E_BLOCK_DIRT) || (Block == E_BLOCK_GRASS)) && (UpperBlock == E_BLOCK_AIR)) { - a_World->FastSetBlock(a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_FARMLAND, 0); + BLOCKTYPE NewBlock = E_BLOCK_FARMLAND; + if (Block == E_BLOCK_DIRT) + { + switch (BlockMeta) + { + case E_META_DIRT_COARSE: + { + // Transform to normal dirt + NewBlock = E_BLOCK_DIRT; + break; + } + case E_META_DIRT_PODZOL: + { + // You can't transform this block with a hoe in vanilla + return false; + } + default: break; + } + } + + a_World->FastSetBlock(a_BlockX, a_BlockY, a_BlockZ, NewBlock, 0); a_World->BroadcastSoundEffect("dig.gravel", a_BlockX + 0.5, a_BlockY + 0.5, a_BlockZ + 0.5, 1.0f, 0.8f); a_Player->UseEquippedItem(); return true; diff --git a/src/Items/ItemPickaxe.h b/src/Items/ItemPickaxe.h index e0cf5d711..b5dc179f8 100644 --- a/src/Items/ItemPickaxe.h +++ b/src/Items/ItemPickaxe.h @@ -41,11 +41,11 @@ public: case E_BLOCK_DIAMOND_BLOCK: case E_BLOCK_DIAMOND_ORE: + case E_BLOCK_EMERALD_ORE: case E_BLOCK_GOLD_BLOCK: case E_BLOCK_GOLD_ORE: case E_BLOCK_REDSTONE_ORE: case E_BLOCK_REDSTONE_ORE_GLOWING: - case E_BLOCK_EMERALD_ORE: { return PickaxeLevel() >= 3; } @@ -59,29 +59,34 @@ public: } case E_BLOCK_ANVIL: - case E_BLOCK_ENCHANTMENT_TABLE: - case E_BLOCK_FURNACE: - case E_BLOCK_LIT_FURNACE: + case E_BLOCK_BRICK: + case E_BLOCK_CAULDRON: case E_BLOCK_COAL_ORE: - case E_BLOCK_STONE: case E_BLOCK_COBBLESTONE: + case E_BLOCK_COBBLESTONE_STAIRS: + case E_BLOCK_COBBLESTONE_WALL: + case E_BLOCK_DOUBLE_NEW_STONE_SLAB: + case E_BLOCK_DOUBLE_STONE_SLAB: + case E_BLOCK_ENCHANTMENT_TABLE: case E_BLOCK_END_STONE: + case E_BLOCK_FURNACE: + case E_BLOCK_LIT_FURNACE: + case E_BLOCK_MOB_SPAWNER: case E_BLOCK_MOSSY_COBBLESTONE: - case E_BLOCK_SANDSTONE_STAIRS: - case E_BLOCK_SANDSTONE: - case E_BLOCK_STONE_BRICKS: case E_BLOCK_NETHER_BRICK: + case E_BLOCK_NETHER_BRICK_STAIRS: case E_BLOCK_NETHERRACK: - case E_BLOCK_STONE_SLAB: - case E_BLOCK_DOUBLE_STONE_SLAB: - case E_BLOCK_STONE_PRESSURE_PLATE: - case E_BLOCK_BRICK: - case E_BLOCK_COBBLESTONE_STAIRS: - case E_BLOCK_COBBLESTONE_WALL: + case E_BLOCK_NEW_STONE_SLAB: + case E_BLOCK_PRISMARINE_BLOCK: + case E_BLOCK_RED_SANDSTONE: + case E_BLOCK_RED_SANDSTONE_STAIRS: + case E_BLOCK_SANDSTONE: + case E_BLOCK_SANDSTONE_STAIRS: + case E_BLOCK_STONE: + case E_BLOCK_STONE_BRICKS: case E_BLOCK_STONE_BRICK_STAIRS: - case E_BLOCK_NETHER_BRICK_STAIRS: - case E_BLOCK_CAULDRON: - case E_BLOCK_MOB_SPAWNER: + case E_BLOCK_STONE_PRESSURE_PLATE: + case E_BLOCK_STONE_SLAB: { return PickaxeLevel() >= 1; } diff --git a/src/Root.h b/src/Root.h index 9a482556c..84c6a98ec 100644 --- a/src/Root.h +++ b/src/Root.h @@ -41,11 +41,12 @@ namespace Json class cRoot { public: - static bool m_TerminateEventRaised; - static cRoot * Get() { return s_Root; } // tolua_end + static bool m_TerminateEventRaised; + + cRoot(void); ~cRoot(); @@ -129,15 +130,15 @@ public: /// Sends a chat message to all connected clients (in all worlds) void BroadcastChat (const AString & a_Message, eMessageType a_ChatPrefix = mtCustom); - void BroadcastChatInfo (const AString & a_Message) { BroadcastChat(a_Message, mtInformation); } + void BroadcastChat (const cCompositeChat & a_Message); + void BroadcastChatDeath (const AString & a_Message) { BroadcastChat(a_Message, mtDeath); } void BroadcastChatFailure(const AString & a_Message) { BroadcastChat(a_Message, mtFailure); } - void BroadcastChatSuccess(const AString & a_Message) { BroadcastChat(a_Message, mtSuccess); } - void BroadcastChatWarning(const AString & a_Message) { BroadcastChat(a_Message, mtWarning); } void BroadcastChatFatal (const AString & a_Message) { BroadcastChat(a_Message, mtFailure); } + void BroadcastChatInfo (const AString & a_Message) { BroadcastChat(a_Message, mtInformation); } void BroadcastChatJoin (const AString & a_Message) { BroadcastChat(a_Message, mtJoin); } void BroadcastChatLeave (const AString & a_Message) { BroadcastChat(a_Message, mtLeave); } - void BroadcastChatDeath (const AString & a_Message) { BroadcastChat(a_Message, mtDeath); } - void BroadcastChat (const cCompositeChat & a_Message); + void BroadcastChatSuccess(const AString & a_Message) { BroadcastChat(a_Message, mtSuccess); } + void BroadcastChatWarning(const AString & a_Message) { BroadcastChat(a_Message, mtWarning); } /// Returns the textual description of the protocol version: 49 -> "1.4.4". Provided specifically for Lua API static AString GetProtocolVersionTextFromInt(int a_ProtocolVersionNum); diff --git a/src/Simulator/SandSimulator.cpp b/src/Simulator/SandSimulator.cpp index e8887ce59..aad41e463 100644 --- a/src/Simulator/SandSimulator.cpp +++ b/src/Simulator/SandSimulator.cpp @@ -160,6 +160,7 @@ bool cSandSimulator::CanContinueFallThrough(BLOCKTYPE a_BlockType) case E_BLOCK_FIRE: case E_BLOCK_FLOWER_POT: case E_BLOCK_HEAVY_WEIGHTED_PRESSURE_PLATE: + case E_BLOCK_IRON_TRAPDOOR: case E_BLOCK_LAVA: case E_BLOCK_LEVER: case E_BLOCK_LIGHT_WEIGHTED_PRESSURE_PLATE: diff --git a/src/World.cpp b/src/World.cpp index 6059b841f..a3c804b44 100644 --- a/src/World.cpp +++ b/src/World.cpp @@ -2954,7 +2954,7 @@ bool cWorld::IsTrapdoorOpen(int a_BlockX, int a_BlockY, int a_BlockZ) BLOCKTYPE Block; NIBBLETYPE Meta; GetBlockTypeMeta(a_BlockX, a_BlockY, a_BlockZ, Block, Meta); - if (Block != E_BLOCK_TRAPDOOR) + if ((Block != E_BLOCK_TRAPDOOR) && (Block != E_BLOCK_IRON_TRAPDOOR)) { return false; } @@ -2971,7 +2971,7 @@ bool cWorld::SetTrapdoorOpen(int a_BlockX, int a_BlockY, int a_BlockZ, bool a_Op BLOCKTYPE Block; NIBBLETYPE Meta; GetBlockTypeMeta(a_BlockX, a_BlockY, a_BlockZ, Block, Meta); - if (Block != E_BLOCK_TRAPDOOR) + if ((Block != E_BLOCK_TRAPDOOR) && (Block != E_BLOCK_IRON_TRAPDOOR)) { return false; } diff --git a/src/WorldStorage/CMakeLists.txt b/src/WorldStorage/CMakeLists.txt index a00ff3b2f..59193db2a 100644 --- a/src/WorldStorage/CMakeLists.txt +++ b/src/WorldStorage/CMakeLists.txt @@ -14,7 +14,6 @@ SET (SRCS ScoreboardSerializer.cpp StatSerializer.cpp WSSAnvil.cpp - WSSCompact.cpp WorldStorage.cpp) SET (HDRS @@ -27,7 +26,6 @@ SET (HDRS ScoreboardSerializer.h StatSerializer.h WSSAnvil.h - WSSCompact.h WorldStorage.h) if(NOT MSVC) diff --git a/src/WorldStorage/WSSCompact.cpp b/src/WorldStorage/WSSCompact.cpp deleted file mode 100644 index 6760186b2..000000000 --- a/src/WorldStorage/WSSCompact.cpp +++ /dev/null @@ -1,1066 +0,0 @@ - -// WSSCompact.cpp - -// Interfaces to the cWSSCompact class representing the "compact" storage schema (PAK-files) - -#include "Globals.h" -#include "WSSCompact.h" -#include "../World.h" -#include "zlib/zlib.h" -#include "json/json.h" -#include "../StringCompression.h" -#include "../BlockEntities/BeaconEntity.h" -#include "../BlockEntities/ChestEntity.h" -#include "../BlockEntities/CommandBlockEntity.h" -#include "../BlockEntities/DispenserEntity.h" -#include "../BlockEntities/FlowerPotEntity.h" -#include "../BlockEntities/FurnaceEntity.h" -#include "../BlockEntities/JukeboxEntity.h" -#include "../BlockEntities/MobHeadEntity.h" -#include "../BlockEntities/NoteEntity.h" -#include "../BlockEntities/SignEntity.h" -#include "../SetChunkData.h" - - - - - -#pragma pack(push, 1) -/// The chunk header, as stored in the file: -struct cWSSCompact::sChunkHeader -{ - int m_ChunkX; - int m_ChunkZ; - int m_CompressedSize; - int m_UncompressedSize; -} ; -#pragma pack(pop) - - - - - -/// The maximum number of PAK files that are cached -const size_t MAX_PAK_FILES = 16; - -/// The maximum number of unsaved chunks before the cPAKFile saves them to disk -const int MAX_DIRTY_CHUNKS = 16; - - - - - -//////////////////////////////////////////////////////////////////////////////// -// cJsonChunkSerializer: - -cJsonChunkSerializer::cJsonChunkSerializer(void) : - m_HasJsonData(false) -{ -} - - - - - -void cJsonChunkSerializer::Entity(cEntity * a_Entity) -{ - // TODO: a_Entity->SaveToJson(m_Root); -} - - - - - -void cJsonChunkSerializer::BlockEntity(cBlockEntity * a_BlockEntity) -{ - const char * SaveInto = NULL; - switch (a_BlockEntity->GetBlockType()) - { - case E_BLOCK_BEACON: SaveInto = "Beacons"; break; - case E_BLOCK_CHEST: SaveInto = "Chests"; break; - case E_BLOCK_DISPENSER: SaveInto = "Dispensers"; break; - case E_BLOCK_DROPPER: SaveInto = "Droppers"; break; - case E_BLOCK_FLOWER_POT: SaveInto = "FlowerPots"; break; - case E_BLOCK_FURNACE: SaveInto = "Furnaces"; break; - case E_BLOCK_SIGN_POST: SaveInto = "Signs"; break; - case E_BLOCK_WALLSIGN: SaveInto = "Signs"; break; - case E_BLOCK_NOTE_BLOCK: SaveInto = "Notes"; break; - case E_BLOCK_JUKEBOX: SaveInto = "Jukeboxes"; break; - case E_BLOCK_COMMAND_BLOCK: SaveInto = "CommandBlocks"; break; - case E_BLOCK_HEAD: SaveInto = "MobHeads"; break; - - default: - { - ASSERT(!"Unhandled blocktype in BlockEntities list while saving to JSON"); - break; - } - } // switch (BlockEntity->GetBlockType()) - if (SaveInto == NULL) - { - return; - } - - Json::Value val; - a_BlockEntity->SaveToJson(val); - m_Root[SaveInto].append(val); - m_HasJsonData = true; -} - - - - - -void cJsonChunkSerializer::LightIsValid(bool a_IsLightValid) -{ - if (a_IsLightValid) - { - m_Root["IsLightValid"] = true; - m_HasJsonData = true; - } -} - - - - - -//////////////////////////////////////////////////////////////////////////////// -// cWSSCompact: - -cWSSCompact::~cWSSCompact() -{ - for (cPAKFiles::iterator itr = m_PAKFiles.begin(); itr != m_PAKFiles.end(); ++itr) - { - delete *itr; - } -} - - - - - -bool cWSSCompact::LoadChunk(const cChunkCoords & a_Chunk) -{ - AString ChunkData; - int UncompressedSize = 0; - if (!GetChunkData(a_Chunk, UncompressedSize, ChunkData)) - { - // The reason for failure is already printed in GetChunkData() - return false; - } - - return LoadChunkFromData(a_Chunk, UncompressedSize, ChunkData, m_World); -} - - - - - -bool cWSSCompact::SaveChunk(const cChunkCoords & a_Chunk) -{ - cCSLock Lock(m_CS); - - cPAKFile * f = LoadPAKFile(a_Chunk); - if (f == NULL) - { - // For some reason we couldn't locate the file - LOG("Cannot locate a proper PAK file for chunk [%d, %d]", a_Chunk.m_ChunkX, a_Chunk.m_ChunkZ); - return false; - } - return f->SaveChunk(a_Chunk, m_World); -} - - - - - -cWSSCompact::cPAKFile * cWSSCompact::LoadPAKFile(const cChunkCoords & a_Chunk) -{ - // ASSUMES that m_CS has been locked - - // We need to retain this weird conversion code, because some edge chunks are in the wrong PAK file - const int LayerX = FAST_FLOOR_DIV(a_Chunk.m_ChunkX, 32); - const int LayerZ = FAST_FLOOR_DIV(a_Chunk.m_ChunkZ, 32); - - // Is it already cached? - for (cPAKFiles::iterator itr = m_PAKFiles.begin(); itr != m_PAKFiles.end(); ++itr) - { - if (((*itr) != NULL) && ((*itr)->GetLayerX() == LayerX) && ((*itr)->GetLayerZ() == LayerZ)) - { - // Move the file to front and return it: - cPAKFile * f = *itr; - if (itr != m_PAKFiles.begin()) - { - m_PAKFiles.erase(itr); - m_PAKFiles.push_front(f); - } - return f; - } - } - - // Load it anew: - AString FileName; - Printf(FileName, "%s/X%i_Z%i.pak", m_World->GetName().c_str(), LayerX, LayerZ); - cPAKFile * f = new cPAKFile(FileName, LayerX, LayerZ, m_CompressionFactor); - if (f == NULL) - { - return NULL; - } - m_PAKFiles.push_front(f); - - // If there are too many PAK files cached, delete the last one used: - if (m_PAKFiles.size() > MAX_PAK_FILES) - { - delete m_PAKFiles.back(); - m_PAKFiles.pop_back(); - } - return f; -} - - - - - -bool cWSSCompact::GetChunkData(const cChunkCoords & a_Chunk, int & a_UncompressedSize, AString & a_Data) -{ - cCSLock Lock(m_CS); - cPAKFile * f = LoadPAKFile(a_Chunk); - if (f == NULL) - { - return false; - } - return f->GetChunkData(a_Chunk, a_UncompressedSize, a_Data); -} - - - - - -/* -// TODO: Rewrite saving to use the same principles as loading -bool cWSSCompact::SetChunkData(const cChunkCoords & a_Chunk, int a_UncompressedSize, const AString & a_Data) -{ - cCSLock Lock(m_CS); - cPAKFile * f = LoadPAKFile(a_Chunk); - if (f == NULL) - { - return false; - } - return f->SetChunkData(a_Chunk, a_UncompressedSize, a_Data); -} -*/ - - - - - -bool cWSSCompact::EraseChunkData(const cChunkCoords & a_Chunk) -{ - cCSLock Lock(m_CS); - cPAKFile * f = LoadPAKFile(a_Chunk); - if (f == NULL) - { - return false; - } - return f->EraseChunkData(a_Chunk); -} - - - - - -void cWSSCompact::LoadEntitiesFromJson(Json::Value & a_Value, cEntityList & a_Entities, cBlockEntityList & a_BlockEntities, cWorld * a_World) -{ - // Load beacon: - Json::Value AllBeacons = a_Value.get("Beacons", Json::nullValue); - if (!AllBeacons.empty()) - { - for (Json::Value::iterator itr = AllBeacons.begin(); itr != AllBeacons.end(); ++itr) - { - std::auto_ptr<cBeaconEntity> BeaconEntity(new cBeaconEntity(0, 0, 0, a_World)); - if (!BeaconEntity->LoadFromJson(*itr)) - { - LOGWARNING("ERROR READING BEACON FROM JSON!"); - } - else - { - a_BlockEntities.push_back(BeaconEntity.release()); - } - } // for itr - AllBeacons[] - } - - // Load chests: - Json::Value AllChests = a_Value.get("Chests", Json::nullValue); - if (!AllChests.empty()) - { - for (Json::Value::iterator itr = AllChests.begin(); itr != AllChests.end(); ++itr) - { - std::auto_ptr<cChestEntity> ChestEntity(new cChestEntity(0, 0, 0, a_World, E_BLOCK_CHEST)); - if (!ChestEntity->LoadFromJson(*itr)) - { - LOGWARNING("ERROR READING CHEST FROM JSON!"); - } - else - { - a_BlockEntities.push_back(ChestEntity.release()); - } - } // for itr - AllChests[] - } - - // Load dispensers: - Json::Value AllDispensers = a_Value.get("Dispensers", Json::nullValue); - for (Json::Value::iterator itr = AllDispensers.begin(); itr != AllDispensers.end(); ++itr) - { - std::auto_ptr<cDispenserEntity> DispenserEntity(new cDispenserEntity(0, 0, 0, a_World)); - if (!DispenserEntity->LoadFromJson(*itr)) - { - LOGWARNING("ERROR READING DISPENSER FROM JSON!"); - } - else - { - a_BlockEntities.push_back(DispenserEntity.release()); - } - } // for itr - AllDispensers[] - - // Load Flowerpots: - Json::Value AllFlowerPots = a_Value.get("FlowerPots", Json::nullValue); - for (Json::Value::iterator itr = AllFlowerPots.begin(); itr != AllFlowerPots.end(); ++itr) - { - std::auto_ptr<cFlowerPotEntity> FlowerPotEntity(new cFlowerPotEntity(0, 0, 0, a_World)); - if (!FlowerPotEntity->LoadFromJson(*itr)) - { - LOGWARNING("ERROR READING FLOWERPOT FROM JSON!"); - } - else - { - a_BlockEntities.push_back(FlowerPotEntity.release()); - } - } // for itr - AllFlowerPots[] - - // Load furnaces: - Json::Value AllFurnaces = a_Value.get("Furnaces", Json::nullValue); - for (Json::Value::iterator itr = AllFurnaces.begin(); itr != AllFurnaces.end(); ++itr) - { - // TODO: The block type and meta aren't correct, there's no way to get them here - std::auto_ptr<cFurnaceEntity> FurnaceEntity(new cFurnaceEntity(0, 0, 0, E_BLOCK_FURNACE, 0, a_World)); - if (!FurnaceEntity->LoadFromJson(*itr)) - { - LOGWARNING("ERROR READING FURNACE FROM JSON!"); - } - else - { - a_BlockEntities.push_back(FurnaceEntity.release()); - } - } // for itr - AllFurnaces[] - - // Load signs: - Json::Value AllSigns = a_Value.get("Signs", Json::nullValue); - for (Json::Value::iterator itr = AllSigns.begin(); itr != AllSigns.end(); ++itr) - { - std::auto_ptr<cSignEntity> SignEntity(new cSignEntity(E_BLOCK_SIGN_POST, 0, 0, 0, a_World)); - if (!SignEntity->LoadFromJson(*itr)) - { - LOGWARNING("ERROR READING SIGN FROM JSON!"); - } - else - { - a_BlockEntities.push_back(SignEntity.release()); - } - } // for itr - AllSigns[] - - // Load note blocks: - Json::Value AllNotes = a_Value.get("Notes", Json::nullValue); - for (Json::Value::iterator itr = AllNotes.begin(); itr != AllNotes.end(); ++itr) - { - std::auto_ptr<cNoteEntity> NoteEntity(new cNoteEntity(0, 0, 0, a_World)); - if (!NoteEntity->LoadFromJson(*itr)) - { - LOGWARNING("ERROR READING NOTE BLOCK FROM JSON!"); - } - else - { - a_BlockEntities.push_back(NoteEntity.release()); - } - } // for itr - AllNotes[] - - // Load jukeboxes: - Json::Value AllJukeboxes = a_Value.get("Jukeboxes", Json::nullValue); - for (Json::Value::iterator itr = AllJukeboxes.begin(); itr != AllJukeboxes.end(); ++itr) - { - std::auto_ptr<cJukeboxEntity> JukeboxEntity(new cJukeboxEntity(0, 0, 0, a_World)); - if (!JukeboxEntity->LoadFromJson(*itr)) - { - LOGWARNING("ERROR READING JUKEBOX FROM JSON!"); - } - else - { - a_BlockEntities.push_back(JukeboxEntity.release()); - } - } // for itr - AllJukeboxes[] - - // Load command blocks: - Json::Value AllCommandBlocks = a_Value.get("CommandBlocks", Json::nullValue); - for (Json::Value::iterator itr = AllCommandBlocks.begin(); itr != AllCommandBlocks.end(); ++itr) - { - std::auto_ptr<cCommandBlockEntity> CommandBlockEntity(new cCommandBlockEntity(0, 0, 0, a_World)); - if (!CommandBlockEntity->LoadFromJson(*itr)) - { - LOGWARNING("ERROR READING COMMAND BLOCK FROM JSON!"); - } - else - { - a_BlockEntities.push_back(CommandBlockEntity.release()); - } - } // for itr - AllCommandBlocks[] - - // Load mob heads: - Json::Value AllMobHeads = a_Value.get("MobHeads", Json::nullValue); - for (Json::Value::iterator itr = AllMobHeads.begin(); itr != AllMobHeads.end(); ++itr) - { - std::auto_ptr<cMobHeadEntity> MobHeadEntity(new cMobHeadEntity(0, 0, 0, a_World)); - if (!MobHeadEntity->LoadFromJson(*itr)) - { - LOGWARNING("ERROR READING MOB HEAD FROM JSON!"); - } - else - { - a_BlockEntities.push_back(MobHeadEntity.release()); - } - } // for itr - AllMobHeads[] -} - - - - - -//////////////////////////////////////////////////////////////////////////////// -// cWSSCompact::cPAKFile - -#define READ(Var) \ - if (f.Read(&Var, sizeof(Var)) != sizeof(Var)) \ - { \ - LOGERROR("ERROR READING %s FROM FILE %s (line %d); file offset %d", #Var, m_FileName.c_str(), __LINE__, f.Tell()); \ - return; \ - } - -cWSSCompact::cPAKFile::cPAKFile(const AString & a_FileName, int a_LayerX, int a_LayerZ, int a_CompressionFactor) : - m_FileName(a_FileName), - m_CompressionFactor(a_CompressionFactor), - m_LayerX(a_LayerX), - m_LayerZ(a_LayerZ), - m_NumDirty(0), - m_ChunkVersion( CHUNK_VERSION), // Init with latest version - m_PakVersion( PAK_VERSION) -{ - cFile f; - if (!f.Open(m_FileName, cFile::fmRead)) - { - return; - } - - // Read headers: - READ(m_PakVersion); - if (m_PakVersion != 1) - { - LOGERROR("File \"%s\" is in an unknown pak format (%d)", m_FileName.c_str(), m_PakVersion); - return; - } - - READ(m_ChunkVersion); - switch (m_ChunkVersion) - { - case 1: - { - m_ChunkSize.Set(16, 128, 16); - break; - } - case 2: - case 3: - { - m_ChunkSize.Set(16, 256, 16); - break; - } - default: - { - LOGERROR("File \"%s\" is in an unknown chunk format (%d)", m_FileName.c_str(), m_ChunkVersion); - return; - } - }; - - short NumChunks = 0; - READ(NumChunks); - - // Read chunk headers: - for (int i = 0; i < NumChunks; i++) - { - sChunkHeader * Header = new sChunkHeader; - - // Here we do not use the READ macro, as it does not free the resources - // allocated with new in case of error. - if (f.Read(Header, sizeof(*Header)) != sizeof(*Header)) - { - LOGERROR("ERROR READING %s FROM FILE %s (line %d); file offset %d", "Header", m_FileName.c_str(), __LINE__, f.Tell()); - delete Header; - Header = NULL; - return; - } - m_ChunkHeaders.push_back(Header); - } // for i - chunk headers - - // Read chunk data: - if (f.ReadRestOfFile(m_DataContents) == -1) - { - LOGERROR("Cannot read file \"%s\" contents", m_FileName.c_str()); - return; - } - - if (m_ChunkVersion == 1) // Convert chunks to version 2 - { - UpdateChunk1To2(); - } -#if AXIS_ORDER == AXIS_ORDER_XZY - if (m_ChunkVersion == 2) // Convert chunks to version 3 - { - UpdateChunk2To3(); - } -#endif -} - - - - - -cWSSCompact::cPAKFile::~cPAKFile() -{ - if (m_NumDirty > 0) - { - SynchronizeFile(); - } - for (sChunkHeaders::iterator itr = m_ChunkHeaders.begin(); itr != m_ChunkHeaders.end(); ++itr) - { - delete *itr; - } -} - - - - - -bool cWSSCompact::cPAKFile::GetChunkData(const cChunkCoords & a_Chunk, int & a_UncompressedSize, AString & a_Data) -{ - int ChunkX = a_Chunk.m_ChunkX; - int ChunkZ = a_Chunk.m_ChunkZ; - sChunkHeader * Header = NULL; - int Offset = 0; - for (sChunkHeaders::iterator itr = m_ChunkHeaders.begin(); itr != m_ChunkHeaders.end(); ++itr) - { - if (((*itr)->m_ChunkX == ChunkX) && ((*itr)->m_ChunkZ == ChunkZ)) - { - Header = *itr; - break; - } - Offset += (*itr)->m_CompressedSize; - } - if ((Header == NULL) || (Offset + Header->m_CompressedSize > (int)m_DataContents.size())) - { - // Chunk not found / data invalid - return false; - } - - a_UncompressedSize = Header->m_UncompressedSize; - a_Data.assign(m_DataContents, Offset, Header->m_CompressedSize); - return true; -} - - - - - -bool cWSSCompact::cPAKFile::SaveChunk(const cChunkCoords & a_Chunk, cWorld * a_World) -{ - if (!SaveChunkToData(a_Chunk, a_World)) - { - return false; - } - if (m_NumDirty > MAX_DIRTY_CHUNKS) - { - SynchronizeFile(); - } - return true; -} - - - - - -void cWSSCompact::cPAKFile::UpdateChunk1To2() -{ - int Offset = 0; - AString NewDataContents; - int ChunksConverted = 0; - for (sChunkHeaders::iterator itr = m_ChunkHeaders.begin(); itr != m_ChunkHeaders.end(); ++itr) - { - sChunkHeader * Header = *itr; - - if (ChunksConverted % 32 == 0) - { - LOGINFO("Updating \"%s\" version 1 to version 2: " SIZE_T_FMT " %%", m_FileName.c_str(), (ChunksConverted * 100) / m_ChunkHeaders.size()); - } - ChunksConverted++; - - AString Data; - int UncompressedSize = Header->m_UncompressedSize; - Data.assign(m_DataContents, Offset, Header->m_CompressedSize); - Offset += Header->m_CompressedSize; - - // Crude data integrity check: - int ExpectedSize = (16*128*16)*2 + (16*128*16)/2; // For version 1 - if (UncompressedSize < ExpectedSize) - { - LOGWARNING("Chunk [%d, %d] has too short decompressed data (%d bytes out of %d needed), erasing", - Header->m_ChunkX, Header->m_ChunkZ, - UncompressedSize, ExpectedSize - ); - Offset += Header->m_CompressedSize; - continue; - } - - // Decompress the data: - AString UncompressedData; - { - int errorcode = UncompressString(Data.data(), Data.size(), UncompressedData, (size_t)UncompressedSize); - if (errorcode != Z_OK) - { - LOGERROR("Error %d decompressing data for chunk [%d, %d]", - errorcode, - Header->m_ChunkX, Header->m_ChunkZ - ); - Offset += Header->m_CompressedSize; - continue; - } - } - - if (UncompressedSize != (int)UncompressedData.size()) - { - LOGWARNING("Uncompressed data size differs (exp %d bytes, got " SIZE_T_FMT ") for chunk [%d, %d]", - UncompressedSize, UncompressedData.size(), - Header->m_ChunkX, Header->m_ChunkZ - ); - Offset += Header->m_CompressedSize; - continue; - } - - - // Old version is 128 blocks high with YZX axis order - char ConvertedData[cChunkDef::BlockDataSize]; - int Index = 0; - unsigned int InChunkOffset = 0; - for (int x = 0; x < 16; ++x) for (int z = 0; z < 16; ++z) - { - for (int y = 0; y < 128; ++y) - { - ConvertedData[Index++] = UncompressedData[y + z * 128 + x * 128 * 16 + InChunkOffset]; - } - // Add 128 empty blocks after an old y column - memset(ConvertedData + Index, E_BLOCK_AIR, 128); - Index += 128; - } - InChunkOffset += (16 * 128 * 16); - for (int x = 0; x < 16; ++x) for (int z = 0; z < 16; ++z) // Metadata - { - for (int y = 0; y < 64; ++y) - { - ConvertedData[Index++] = UncompressedData[y + z * 64 + x * 64 * 16 + InChunkOffset]; - } - memset(ConvertedData + Index, 0, 64); - Index += 64; - } - InChunkOffset += (16 * 128 * 16) / 2; - for (int x = 0; x < 16; ++x) for (int z = 0; z < 16; ++z) // Block light - { - for (int y = 0; y < 64; ++y) - { - ConvertedData[Index++] = UncompressedData[y + z * 64 + x * 64 * 16 + InChunkOffset]; - } - memset(ConvertedData + Index, 0, 64); - Index += 64; - } - InChunkOffset += (16*128*16)/2; - for (int x = 0; x < 16; ++x) for (int z = 0; z < 16; ++z) // Sky light - { - for (int y = 0; y < 64; ++y) - { - ConvertedData[Index++] = UncompressedData[y + z * 64 + x * 64 * 16 + InChunkOffset]; - } - memset(ConvertedData + Index, 0, 64); - Index += 64; - } - InChunkOffset += (16 * 128 * 16) / 2; - - AString Converted(ConvertedData, ARRAYCOUNT(ConvertedData)); - - // Add JSON data afterwards - if (UncompressedData.size() > InChunkOffset) - { - Converted.append( UncompressedData.begin() + InChunkOffset, UncompressedData.end()); - } - - // Re-compress data - AString CompressedData; - { - int errorcode = CompressString(Converted.data(), Converted.size(), CompressedData, m_CompressionFactor); - if (errorcode != Z_OK) - { - LOGERROR("Error %d compressing data for chunk [%d, %d]", - errorcode, - Header->m_ChunkX, Header->m_ChunkZ - ); - continue; - } - } - - // Save into file's cache - Header->m_UncompressedSize = (int)Converted.size(); - Header->m_CompressedSize = (int)CompressedData.size(); - NewDataContents.append(CompressedData); - } - - // Done converting - m_DataContents = NewDataContents; - m_ChunkVersion = 2; - SynchronizeFile(); - - LOGINFO("Updated \"%s\" version 1 to version 2", m_FileName.c_str()); -} - - - - - -void cWSSCompact::cPAKFile::UpdateChunk2To3() -{ - int Offset = 0; - AString NewDataContents; - int ChunksConverted = 0; - for (sChunkHeaders::iterator itr = m_ChunkHeaders.begin(); itr != m_ChunkHeaders.end(); ++itr) - { - sChunkHeader * Header = *itr; - - if (ChunksConverted % 32 == 0) - { - LOGINFO("Updating \"%s\" version 2 to version 3: " SIZE_T_FMT " %%", m_FileName.c_str(), (ChunksConverted * 100) / m_ChunkHeaders.size()); - } - ChunksConverted++; - - AString Data; - int UncompressedSize = Header->m_UncompressedSize; - Data.assign(m_DataContents, Offset, Header->m_CompressedSize); - Offset += Header->m_CompressedSize; - - // Crude data integrity check: - const int ExpectedSize = (16 * 256 * 16) * 2 + (16 * 256 * 16) / 2; // For version 2 - if (UncompressedSize < ExpectedSize) - { - LOGWARNING("Chunk [%d, %d] has too short decompressed data (%d bytes out of %d needed), erasing", - Header->m_ChunkX, Header->m_ChunkZ, - UncompressedSize, ExpectedSize - ); - Offset += Header->m_CompressedSize; - continue; - } - - // Decompress the data: - AString UncompressedData; - { - int errorcode = UncompressString(Data.data(), Data.size(), UncompressedData, (size_t)UncompressedSize); - if (errorcode != Z_OK) - { - LOGERROR("Error %d decompressing data for chunk [%d, %d]", - errorcode, - Header->m_ChunkX, Header->m_ChunkZ - ); - Offset += Header->m_CompressedSize; - continue; - } - } - - if (UncompressedSize != (int)UncompressedData.size()) - { - LOGWARNING("Uncompressed data size differs (exp %d bytes, got " SIZE_T_FMT ") for chunk [%d, %d]", - UncompressedSize, UncompressedData.size(), - Header->m_ChunkX, Header->m_ChunkZ - ); - Offset += Header->m_CompressedSize; - continue; - } - - char ConvertedData[ExpectedSize]; - memset(ConvertedData, 0, ExpectedSize); - - // Cannot use cChunk::MakeIndex because it might change again????????? - // For compatibility, use what we know is current - #define MAKE_3_INDEX( x, y, z) ( x + (z * 16) + (y * 16 * 16)) - - unsigned int InChunkOffset = 0; - for (int x = 0; x < 16; ++x) for (int z = 0; z < 16; ++z) for (int y = 0; y < 256; ++y) // YZX Loop order is important, in 1.1 Y was first then Z then X - { - ConvertedData[ MAKE_3_INDEX(x, y, z) ] = UncompressedData[InChunkOffset]; - ++InChunkOffset; - } // for y, z, x - - - unsigned int index2 = 0; - for (int x = 0; x < 16; ++x) for (int z = 0; z < 16; ++z) for (int y = 0; y < 256; ++y) - { - ConvertedData[ InChunkOffset + MAKE_3_INDEX(x, y, z)/2 ] |= ( (UncompressedData[ InChunkOffset + index2/2 ] >> ((index2&1)*4)) & 0x0f) << ((x&1)*4); - ++index2; - } - InChunkOffset += index2 / 2; - index2 = 0; - - for (int x = 0; x < 16; ++x) for (int z = 0; z < 16; ++z) for (int y = 0; y < 256; ++y) - { - ConvertedData[ InChunkOffset + MAKE_3_INDEX(x, y, z)/2 ] |= ( (UncompressedData[ InChunkOffset + index2/2 ] >> ((index2&1)*4)) & 0x0f) << ((x&1)*4); - ++index2; - } - InChunkOffset += index2 / 2; - index2 = 0; - - for (int x = 0; x < 16; ++x) for (int z = 0; z < 16; ++z) for (int y = 0; y < 256; ++y) - { - ConvertedData[ InChunkOffset + MAKE_3_INDEX(x, y, z)/2 ] |= ( (UncompressedData[ InChunkOffset + index2/2 ] >> ((index2&1)*4)) & 0x0f) << ((x&1)*4); - ++index2; - } - InChunkOffset += index2 / 2; - - AString Converted(ConvertedData, ExpectedSize); - - // Add JSON data afterwards - if (UncompressedData.size() > InChunkOffset) - { - Converted.append( UncompressedData.begin() + InChunkOffset, UncompressedData.end()); - } - - // Re-compress data - AString CompressedData; - { - int errorcode = CompressString(Converted.data(), Converted.size(), CompressedData, m_CompressionFactor); - if (errorcode != Z_OK) - { - LOGERROR("Error %d compressing data for chunk [%d, %d]", - errorcode, - Header->m_ChunkX, Header->m_ChunkZ - ); - continue; - } - } - - // Save into file's cache - Header->m_UncompressedSize = (int)Converted.size(); - Header->m_CompressedSize = (int)CompressedData.size(); - NewDataContents.append(CompressedData); - } - - // Done converting - m_DataContents = NewDataContents; - m_ChunkVersion = 3; - SynchronizeFile(); - - LOGINFO("Updated \"%s\" version 2 to version 3", m_FileName.c_str()); -} - - - - - -bool cWSSCompact::LoadChunkFromData(const cChunkCoords & a_Chunk, int a_UncompressedSize, const AString & a_Data, cWorld * a_World) -{ - // Crude data integrity check: - if (a_UncompressedSize < cChunkDef::BlockDataSize) - { - LOGWARNING("Chunk [%d, %d] has too short decompressed data (%d bytes out of %d needed), erasing", - a_Chunk.m_ChunkX, a_Chunk.m_ChunkZ, - a_UncompressedSize, cChunkDef::BlockDataSize - ); - EraseChunkData(a_Chunk); - return false; - } - - // Decompress the data: - AString UncompressedData; - int errorcode = UncompressString(a_Data.data(), a_Data.size(), UncompressedData, (size_t)a_UncompressedSize); - if (errorcode != Z_OK) - { - LOGERROR("Error %d decompressing data for chunk [%d, %d]", - errorcode, - a_Chunk.m_ChunkX, a_Chunk.m_ChunkZ - ); - return false; - } - - if (a_UncompressedSize != (int)UncompressedData.size()) - { - LOGWARNING("Uncompressed data size differs (exp %d bytes, got " SIZE_T_FMT ") for chunk [%d, %d]", - a_UncompressedSize, UncompressedData.size(), - a_Chunk.m_ChunkX, a_Chunk.m_ChunkZ - ); - return false; - } - - cEntityList Entities; - cBlockEntityList BlockEntities; - bool IsLightValid = false; - - if (a_UncompressedSize > cChunkDef::BlockDataSize) - { - Json::Value root; // will contain the root value after parsing. - Json::Reader reader; - if (!reader.parse( UncompressedData.data() + cChunkDef::BlockDataSize, root, false)) - { - LOGERROR("Failed to parse trailing JSON in chunk [%d, %d]!", - a_Chunk.m_ChunkX, a_Chunk.m_ChunkZ - ); - } - else - { - LoadEntitiesFromJson(root, Entities, BlockEntities, a_World); - IsLightValid = root.get("IsLightValid", false).asBool(); - } - } - - BLOCKTYPE * BlockData = (BLOCKTYPE *)UncompressedData.data(); - NIBBLETYPE * MetaData = (NIBBLETYPE *)(BlockData + MetaOffset); - NIBBLETYPE * BlockLight = (NIBBLETYPE *)(BlockData + LightOffset); - NIBBLETYPE * SkyLight = (NIBBLETYPE *)(BlockData + SkyLightOffset); - - a_World->QueueSetChunkData(cSetChunkDataPtr(new cSetChunkData( - a_Chunk.m_ChunkX, a_Chunk.m_ChunkZ, - BlockData, MetaData, - IsLightValid ? BlockLight : NULL, - IsLightValid ? SkyLight : NULL, - NULL, NULL, - Entities, BlockEntities, - false - ))); - - return true; -} - - - - - -bool cWSSCompact::cPAKFile::EraseChunkData(const cChunkCoords & a_Chunk) -{ - int ChunkX = a_Chunk.m_ChunkX; - int ChunkZ = a_Chunk.m_ChunkZ; - int Offset = 0; - for (sChunkHeaders::iterator itr = m_ChunkHeaders.begin(); itr != m_ChunkHeaders.end(); ++itr) - { - if (((*itr)->m_ChunkX == ChunkX) && ((*itr)->m_ChunkZ == ChunkZ)) - { - m_DataContents.erase(Offset, (*itr)->m_CompressedSize); - delete *itr; - itr = m_ChunkHeaders.erase(itr); - return true; - } - Offset += (*itr)->m_CompressedSize; - } - - return false; -} - - - - - -bool cWSSCompact::cPAKFile::SaveChunkToData(const cChunkCoords & a_Chunk, cWorld * a_World) -{ - // Serialize the chunk: - cJsonChunkSerializer Serializer; - if (!a_World->GetChunkData(a_Chunk.m_ChunkX, a_Chunk.m_ChunkZ, Serializer)) - { - // Chunk not valid - LOG("cWSSCompact: Trying to save chunk [%d, %d] that has no data, ignoring request.", a_Chunk.m_ChunkX, a_Chunk.m_ChunkZ); - return false; - } - - AString Data; - Data.assign((const char *)Serializer.GetBlockData(), cChunkDef::BlockDataSize); - if (Serializer.HasJsonData()) - { - AString JsonData; - Json::StyledWriter writer; - JsonData = writer.write(Serializer.GetRoot()); - Data.append(JsonData); - } - - // Compress the data: - AString CompressedData; - int errorcode = CompressString(Data.data(), Data.size(), CompressedData, m_CompressionFactor); - if (errorcode != Z_OK) - { - LOGERROR("Error %i compressing data for chunk [%d, %d]", errorcode, a_Chunk.m_ChunkX, a_Chunk.m_ChunkZ); - return false; - } - - // Erase any existing data for the chunk: - EraseChunkData(a_Chunk); - - // Save the header: - sChunkHeader * Header = new sChunkHeader; - if (Header == NULL) - { - LOGWARNING("Cannot create a new chunk header to save chunk [%d, %d]", a_Chunk.m_ChunkX, a_Chunk.m_ChunkZ); - return false; - } - Header->m_CompressedSize = (int)CompressedData.size(); - Header->m_ChunkX = a_Chunk.m_ChunkX; - Header->m_ChunkZ = a_Chunk.m_ChunkZ; - Header->m_UncompressedSize = (int)Data.size(); - m_ChunkHeaders.push_back(Header); - - m_DataContents.append(CompressedData.data(), CompressedData.size()); - - m_NumDirty++; - return true; -} - - - - - -#define WRITE(Var) \ - if (f.Write(&Var, sizeof(Var)) != sizeof(Var)) \ - { \ - LOGERROR("cWSSCompact: ERROR writing %s to file \"%s\" (line %d); file offset %d", #Var, m_FileName.c_str(), __LINE__, f.Tell()); \ - return; \ - } - -void cWSSCompact::cPAKFile::SynchronizeFile(void) -{ - cFile f; - if (!f.Open(m_FileName, cFile::fmWrite)) - { - LOGERROR("Cannot open PAK file \"%s\" for writing", m_FileName.c_str()); - return; - } - - WRITE(m_PakVersion); - WRITE(m_ChunkVersion); - short NumChunks = (short)m_ChunkHeaders.size(); - WRITE(NumChunks); - for (sChunkHeaders::iterator itr = m_ChunkHeaders.begin(); itr != m_ChunkHeaders.end(); ++itr) - { - WRITE(**itr); - } - if (f.Write(m_DataContents.data(), m_DataContents.size()) != (int)m_DataContents.size()) - { - LOGERROR("cWSSCompact: ERROR writing chunk contents to file \"%s\" (line %d); file offset %d", m_FileName.c_str(), __LINE__, f.Tell()); - return; - } - m_NumDirty = 0; -} - - - - diff --git a/src/WorldStorage/WSSCompact.h b/src/WorldStorage/WSSCompact.h deleted file mode 100644 index 83e9cb49f..000000000 --- a/src/WorldStorage/WSSCompact.h +++ /dev/null @@ -1,157 +0,0 @@ - -// WSSCompact.h - -// Interfaces to the cWSSCompact class representing the "Compact" storage schema (PAK-files) - - - - - -#pragma once -#ifndef WSSCOMPACT_H_INCLUDED -#define WSSCOMPACT_H_INCLUDED - -#include "WorldStorage.h" -#include "../Vector3.h" -#include "json/json.h" -#include "ChunkDataCallback.h" - - - - - -/// Helper class for serializing a chunk into Json -class cJsonChunkSerializer : - public cChunkDataArrayCollector -{ -public: - - cJsonChunkSerializer(void); - - Json::Value & GetRoot (void) {return m_Root; } - BLOCKTYPE * GetBlockData(void) {return (BLOCKTYPE *)m_BlockData; } - bool HasJsonData (void) const {return m_HasJsonData; } - -protected: - - // NOTE: block data is serialized into inherited cChunkDataCollector's m_BlockData[] array - - // Entities and BlockEntities are serialized to Json - Json::Value m_Root; - bool m_HasJsonData; - - // cChunkDataCollector overrides: - virtual void Entity (cEntity * a_Entity) override; - virtual void BlockEntity (cBlockEntity * a_Entity) override; - virtual void LightIsValid (bool a_IsLightValid) override; -} ; - - - - - -class cWSSCompact : - public cWSSchema -{ -public: - cWSSCompact(cWorld * a_World, int a_CompressionFactor) : cWSSchema(a_World), m_CompressionFactor(a_CompressionFactor) {} - virtual ~cWSSCompact(); - -protected: - - enum - { - // Offsets to individual components in the joined blockdata array - MetaOffset = cChunkDef::NumBlocks, - LightOffset = MetaOffset + cChunkDef::NumBlocks / 2, - SkyLightOffset = LightOffset + cChunkDef::NumBlocks / 2, - } ; - - struct sChunkHeader; - typedef std::vector<sChunkHeader *> sChunkHeaders; - - /// Implements a cache for a single PAK file; implements lazy-write in order to be able to write multiple chunks fast - class cPAKFile - { - public: - - cPAKFile(const AString & a_FileName, int a_LayerX, int a_LayerZ, int a_CompressionFactor); - ~cPAKFile(); - - bool GetChunkData(const cChunkCoords & a_Chunk, int & a_UncompressedSize, AString & a_Data); - bool SetChunkData(const cChunkCoords & a_Chunk, int a_UncompressedSize, const AString & a_Data); - bool EraseChunkData(const cChunkCoords & a_Chunk); - - bool SaveChunk(const cChunkCoords & a_Chunk, cWorld * a_World); - - int GetLayerX(void) const {return m_LayerX; } - int GetLayerZ(void) const {return m_LayerZ; } - - static const int PAK_VERSION = 1; -#if AXIS_ORDER == AXIS_ORDER_XZY - static const int CHUNK_VERSION = 3; -#elif AXIS_ORDER == AXIS_ORDER_YZX - static const int CHUNK_VERSION = 2; -#endif - protected: - - AString m_FileName; - int m_CompressionFactor; - int m_LayerX; - int m_LayerZ; - - sChunkHeaders m_ChunkHeaders; - AString m_DataContents; // Data contents of the file, cached - - int m_NumDirty; // Number of chunks that were written into m_DataContents but not into the file - - Vector3i m_ChunkSize; // Is related to m_ChunkVersion - char m_ChunkVersion; - char m_PakVersion; - - bool SaveChunkToData(const cChunkCoords & a_Chunk, cWorld * a_World); // Saves the chunk to m_DataContents, updates headers and m_NumDirty - void SynchronizeFile(void); // Writes m_DataContents along with the headers to file, resets m_NumDirty - - void UpdateChunk1To2(void); // Height from 128 to 256 - void UpdateChunk2To3(void); // Axis order from YZX to XZY - } ; - - typedef std::list<cPAKFile *> cPAKFiles; - - cCriticalSection m_CS; - cPAKFiles m_PAKFiles; // A MRU cache of PAK files - - int m_CompressionFactor; - - /// Loads the correct PAK file either from cache or from disk, manages the m_PAKFiles cache - cPAKFile * LoadPAKFile(const cChunkCoords & a_Chunk); - - /// Gets chunk data from the correct file; locks CS as needed - bool GetChunkData(const cChunkCoords & a_Chunk, int & a_UncompressedSize, AString & a_Data); - - /// Sets chunk data to the correct file; locks CS as needed - bool SetChunkData(const cChunkCoords & a_Chunk, int a_UncompressedSize, const AString & a_Data); - - /// Erases chunk data from the correct file; locks CS as needed - bool EraseChunkData(const cChunkCoords & a_Chunk); - - /// Loads the chunk from the data (no locking needed) - bool LoadChunkFromData(const cChunkCoords & a_Chunk, int a_UncompressedSize, const AString & a_Data, cWorld * a_World); - - void LoadEntitiesFromJson(Json::Value & a_Value, cEntityList & a_Entities, cBlockEntityList & a_BlockEntities, cWorld * a_World); - - // cWSSchema overrides: - virtual bool LoadChunk(const cChunkCoords & a_Chunk) override; - virtual bool SaveChunk(const cChunkCoords & a_Chunk) override; - virtual const AString GetName(void) const override {return "compact"; } -} ; - - - - - -#endif // WSSCOMPACT_H_INCLUDED - - - - diff --git a/src/WorldStorage/WorldStorage.cpp b/src/WorldStorage/WorldStorage.cpp index 179cf9393..c611bfd90 100644 --- a/src/WorldStorage/WorldStorage.cpp +++ b/src/WorldStorage/WorldStorage.cpp @@ -7,7 +7,6 @@ #include "Globals.h" #include "WorldStorage.h" -#include "WSSCompact.h" #include "WSSAnvil.h" #include "../World.h" #include "../Generating/ChunkGenerator.h" @@ -187,7 +186,6 @@ void cWorldStorage::InitSchemas(int a_StorageCompressionFactor) { // The first schema added is considered the default m_Schemas.push_back(new cWSSAnvil (m_World, a_StorageCompressionFactor)); - m_Schemas.push_back(new cWSSCompact (m_World, a_StorageCompressionFactor)); m_Schemas.push_back(new cWSSForgetful(m_World)); // Add new schemas here |