From 05d71675f69e13d8ab590a33b38ee6d0f8a77b6f Mon Sep 17 00:00:00 2001 From: "luksor111@gmail.com" Date: Wed, 19 Dec 2012 21:19:36 +0000 Subject: Added dispensers (they can't dispense items yet) Fixed crash when digging snow Moved BlockPlace hook check, so Core plugin will no longer block item usage Player chat messages are now visible in the console git-svn-id: http://mc-server.googlecode.com/svn/trunk@1081 0a769ca7-a7f5-676a-18bf-c427514a06d6 --- source/WorldStorage/WSSAnvil.cpp | 86 +++++++++++++++++++++++++++++++++++--- source/WorldStorage/WSSAnvil.h | 11 ++--- source/WorldStorage/WSSCompact.cpp | 34 ++++++++++++--- 3 files changed, 114 insertions(+), 17 deletions(-) (limited to 'source/WorldStorage') diff --git a/source/WorldStorage/WSSAnvil.cpp b/source/WorldStorage/WSSAnvil.cpp index e30b3c409..895386e4c 100644 --- a/source/WorldStorage/WSSAnvil.cpp +++ b/source/WorldStorage/WSSAnvil.cpp @@ -9,6 +9,7 @@ #include "zlib.h" #include "../BlockID.h" #include "../ChestEntity.h" +#include "../DispenserEntity.h" #include "../FurnaceEntity.h" #include "../SignEntity.h" #include "../NoteEntity.h" @@ -132,8 +133,27 @@ protected: m_Writer.EndList(); m_Writer.EndCompound(); } + + + void AddDispenserEntity(cDispenserEntity * a_Entity) + { + m_Writer.BeginCompound(""); + AddBasicTileEntity(a_Entity, "Trap"); + m_Writer.BeginList("Items", TAG_Compound); + for (int i = 0; i < 9; i++) + { + const cItem * Item = a_Entity->GetSlot(i); + if ((Item == NULL) || Item->IsEmpty()) + { + continue; + } + AddItem(Item, i); + } + m_Writer.EndList(); + m_Writer.EndCompound(); + } - + void AddFurnaceEntity(cFurnaceEntity * a_Furnace) { m_Writer.BeginCompound(""); @@ -229,12 +249,13 @@ protected: // Add tile-entity into NBT: switch (a_Entity->GetBlockType()) { - case E_BLOCK_CHEST: AddChestEntity ((cChestEntity *) a_Entity); break; - case E_BLOCK_FURNACE: AddFurnaceEntity((cFurnaceEntity *)a_Entity); break; + case E_BLOCK_CHEST: AddChestEntity ((cChestEntity *) a_Entity); break; + case E_BLOCK_DISPENSER: AddDispenserEntity ((cDispenserEntity *) a_Entity); break; + case E_BLOCK_FURNACE: AddFurnaceEntity ((cFurnaceEntity *) a_Entity); break; case E_BLOCK_SIGN_POST: - case E_BLOCK_WALLSIGN: AddSignEntity ((cSignEntity *) a_Entity); break; - case E_BLOCK_NOTE_BLOCK: AddNoteEntity ((cNoteEntity *) a_Entity); break; - case E_BLOCK_JUKEBOX: AddJukeboxEntity((cJukeboxEntity *)a_Entity); break; + case E_BLOCK_WALLSIGN: AddSignEntity ((cSignEntity *) a_Entity); break; + case E_BLOCK_NOTE_BLOCK: AddNoteEntity ((cNoteEntity *) a_Entity); break; + case E_BLOCK_JUKEBOX: AddJukeboxEntity ((cJukeboxEntity *) a_Entity); break; default: { ASSERT(!"Unhandled block entity saved into Anvil"); @@ -728,6 +749,10 @@ void cWSSAnvil::LoadBlockEntitiesFromNBT(cBlockEntityList & a_BlockEntities, con { LoadChestFromNBT(a_BlockEntities, a_NBT, Child); } + else if (strncmp(a_NBT.GetData(sID), "Trap", a_NBT.GetDataLength(sID)) == 0) + { + LoadDispenserFromNBT(a_BlockEntities, a_NBT, Child); + } else if (strncmp(a_NBT.GetData(sID), "Furnace", a_NBT.GetDataLength(sID)) == 0) { LoadFurnaceFromNBT(a_BlockEntities, a_NBT, Child); @@ -801,6 +826,55 @@ void cWSSAnvil::LoadChestFromNBT(cBlockEntityList & a_BlockEntities, const cPars +void cWSSAnvil::LoadDispenserFromNBT(cBlockEntityList & a_BlockEntities, const cParsedNBT & a_NBT, int a_TagIdx) +{ + ASSERT(a_NBT.GetType(a_TagIdx) == TAG_Compound); + int x, y, z; + if (!GetBlockEntityNBTPos(a_NBT, a_TagIdx, x, y, z)) + { + return; + } + int Items = a_NBT.FindChildByName(a_TagIdx, "Items"); + if ((Items < 0) || (a_NBT.GetType(Items) != TAG_List)) + { + return; // Make it an empty dispenser - the chunk loader will provide an empty cDispenserEntity for this + } + std::auto_ptr Dispenser(new cDispenserEntity(x, y, z, m_World)); + for (int Child = a_NBT.GetFirstChild(Items); Child != -1; Child = a_NBT.GetNextSibling(Child)) + { + int Slot = a_NBT.FindChildByName(Child, "Slot"); + if ((Slot < 0) || (a_NBT.GetType(Slot) != TAG_Byte)) + { + continue; + } + cItem Item; + int ID = a_NBT.FindChildByName(Child, "id"); + if ((ID < 0) || (a_NBT.GetType(ID) != TAG_Short)) + { + continue; + } + Item.m_ItemID = (ENUM_ITEM_ID)(a_NBT.GetShort(ID)); + int Damage = a_NBT.FindChildByName(Child, "Damage"); + if ((Damage < 0) || (a_NBT.GetType(Damage) != TAG_Short)) + { + continue; + } + Item.m_ItemHealth = a_NBT.GetShort(Damage); + int Count = a_NBT.FindChildByName(Child, "Count"); + if ((Count < 0) || (a_NBT.GetType(Count) != TAG_Byte)) + { + continue; + } + Item.m_ItemCount = a_NBT.GetByte(Count); + Dispenser->SetSlot(a_NBT.GetByte(Slot), Item); + } // for itr - ItemDefs[] + a_BlockEntities.push_back(Dispenser.release()); +} + + + + + void cWSSAnvil::LoadFurnaceFromNBT(cBlockEntityList & a_BlockEntities, const cParsedNBT & a_NBT, int a_TagIdx) { ASSERT(a_NBT.GetType(a_TagIdx) == TAG_Compound); diff --git a/source/WorldStorage/WSSAnvil.h b/source/WorldStorage/WSSAnvil.h index 37c1f0b4e..cdd225bd5 100644 --- a/source/WorldStorage/WSSAnvil.h +++ b/source/WorldStorage/WSSAnvil.h @@ -111,11 +111,12 @@ protected: /// Loads the chunk's BlockEntities from NBT data (a_Tag is the Level\\TileEntities list tag; may be -1) void LoadBlockEntitiesFromNBT(cBlockEntityList & a_BlockEntitites, const cParsedNBT & a_NBT, int a_Tag); - void LoadChestFromNBT (cBlockEntityList & a_BlockEntities, const cParsedNBT & a_NBT, int a_TagIdx); - void LoadFurnaceFromNBT(cBlockEntityList & a_BlockEntities, const cParsedNBT & a_NBT, int a_TagIdx); - void LoadSignFromNBT (cBlockEntityList & a_BlockEntities, const cParsedNBT & a_NBT, int a_TagIdx); - void LoadNoteFromNBT (cBlockEntityList & a_BlockEntities, const cParsedNBT & a_NBT, int a_TagIdx); - void LoadJukeboxFromNBT(cBlockEntityList & a_BlockEntities, const cParsedNBT & a_NBT, int a_TagIdx); + void LoadChestFromNBT (cBlockEntityList & a_BlockEntities, const cParsedNBT & a_NBT, int a_TagIdx); + void LoadDispenserFromNBT (cBlockEntityList & a_BlockEntities, const cParsedNBT & a_NBT, int a_TagIdx); + void LoadFurnaceFromNBT (cBlockEntityList & a_BlockEntities, const cParsedNBT & a_NBT, int a_TagIdx); + void LoadSignFromNBT (cBlockEntityList & a_BlockEntities, const cParsedNBT & a_NBT, int a_TagIdx); + void LoadNoteFromNBT (cBlockEntityList & a_BlockEntities, const cParsedNBT & a_NBT, int a_TagIdx); + void LoadJukeboxFromNBT (cBlockEntityList & a_BlockEntities, const cParsedNBT & a_NBT, int a_TagIdx); /// Helper function for extracting the X, Y, and Z int subtags of a NBT compound; returns true if successful bool GetBlockEntityNBTPos(const cParsedNBT & a_NBT, int a_TagIdx, int & a_X, int & a_Y, int & a_Z); diff --git a/source/WorldStorage/WSSCompact.cpp b/source/WorldStorage/WSSCompact.cpp index 22e25eb6f..87cf1d930 100644 --- a/source/WorldStorage/WSSCompact.cpp +++ b/source/WorldStorage/WSSCompact.cpp @@ -11,6 +11,7 @@ #include "../StringCompression.h" #include "../ChestEntity.h" #include "../SignEntity.h" +#include "../DispenserEntity.h" #include "../FurnaceEntity.h" #include "../NoteEntity.h" #include "../JukeboxEntity.h" @@ -71,12 +72,13 @@ void cJsonChunkSerializer::BlockEntity(cBlockEntity * a_BlockEntity) const char * SaveInto = NULL; switch (a_BlockEntity->GetBlockType()) { - case E_BLOCK_CHEST: SaveInto = "Chests"; 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_CHEST: SaveInto = "Chests"; break; + case E_BLOCK_DISPENSER: SaveInto = "Dispensers"; 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; default: { @@ -281,6 +283,26 @@ void cWSSCompact::LoadEntitiesFromJson(Json::Value & a_Value, cEntityList & a_En } // for itr - AllChests[] } + // Load dispensers + Json::Value AllDispensers = a_Value.get("Dispensers", Json::nullValue); + if( !AllDispensers.empty() ) + { + for( Json::Value::iterator itr = AllDispensers.begin(); itr != AllDispensers.end(); ++itr ) + { + Json::Value & Dispenser = *itr; + cDispenserEntity * DispenserEntity = new cDispenserEntity(0,0,0, a_World); + if( !DispenserEntity->LoadFromJson( Dispenser ) ) + { + LOGERROR("ERROR READING DISPENSER FROM JSON!" ); + delete DispenserEntity; + } + else + { + a_BlockEntities.push_back( DispenserEntity ); + } + } // for itr - AllDispensers[] + } + // Load furnaces Json::Value AllFurnaces = a_Value.get("Furnaces", Json::nullValue); if( !AllFurnaces.empty() ) -- cgit v1.2.3