diff options
author | Tiger Wang <ziwei.tiger@hotmail.co.uk> | 2014-07-18 21:10:51 +0200 |
---|---|---|
committer | Tiger Wang <ziwei.tiger@hotmail.co.uk> | 2014-07-18 21:10:51 +0200 |
commit | 37140ae57835680d2c4fb3aa365082622d3a150e (patch) | |
tree | 89a636c74375b3c9f0fe77b20ecbadc693bd0989 /src/WorldStorage | |
parent | Merge branch 'master' of https://github.com/mc-server/MCServer into portals (diff) | |
parent | Monster fixes (diff) | |
download | cuberite-37140ae57835680d2c4fb3aa365082622d3a150e.tar cuberite-37140ae57835680d2c4fb3aa365082622d3a150e.tar.gz cuberite-37140ae57835680d2c4fb3aa365082622d3a150e.tar.bz2 cuberite-37140ae57835680d2c4fb3aa365082622d3a150e.tar.lz cuberite-37140ae57835680d2c4fb3aa365082622d3a150e.tar.xz cuberite-37140ae57835680d2c4fb3aa365082622d3a150e.tar.zst cuberite-37140ae57835680d2c4fb3aa365082622d3a150e.zip |
Diffstat (limited to 'src/WorldStorage')
-rw-r--r-- | src/WorldStorage/FastNBT.cpp | 8 | ||||
-rw-r--r-- | src/WorldStorage/FastNBT.h | 6 | ||||
-rw-r--r-- | src/WorldStorage/FireworksSerializer.cpp | 8 | ||||
-rw-r--r-- | src/WorldStorage/MapSerializer.h | 7 | ||||
-rw-r--r-- | src/WorldStorage/NBTChunkSerializer.cpp | 70 | ||||
-rw-r--r-- | src/WorldStorage/NBTChunkSerializer.h | 3 | ||||
-rw-r--r-- | src/WorldStorage/SchematicFileSerializer.cpp | 2 | ||||
-rw-r--r-- | src/WorldStorage/ScoreboardSerializer.cpp | 10 | ||||
-rw-r--r-- | src/WorldStorage/WSSAnvil.cpp | 84 | ||||
-rw-r--r-- | src/WorldStorage/WSSAnvil.h | 3 | ||||
-rw-r--r-- | src/WorldStorage/WSSCompact.cpp | 36 | ||||
-rw-r--r-- | src/WorldStorage/WSSCompact.h | 6 | ||||
-rw-r--r-- | src/WorldStorage/WorldStorage.cpp | 41 | ||||
-rw-r--r-- | src/WorldStorage/WorldStorage.h | 7 |
14 files changed, 160 insertions, 131 deletions
diff --git a/src/WorldStorage/FastNBT.cpp b/src/WorldStorage/FastNBT.cpp index a047d67c7..c6294b99c 100644 --- a/src/WorldStorage/FastNBT.cpp +++ b/src/WorldStorage/FastNBT.cpp @@ -10,7 +10,7 @@ -// The number of NBT tags that are reserved when an NBT parsing is started. +// The number of NBT tags that are reserved when an NBT parsing is started. // You can override this by using a cmdline define #ifndef NBT_RESERVE_SIZE #define NBT_RESERVE_SIZE 200 @@ -25,7 +25,7 @@ -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// // cParsedNBT: #define NEEDBYTES(N) \ @@ -69,7 +69,7 @@ bool cParsedNBT::Parse(void) m_Pos = 1; - RETURN_FALSE_IF_FALSE(ReadString(m_Tags.back().m_NameStart, m_Tags.back().m_NameLength)); + RETURN_FALSE_IF_FALSE(ReadString(m_Tags.back().m_NameStart, m_Tags.back().m_NameLength)); RETURN_FALSE_IF_FALSE(ReadCompound()); return true; @@ -329,7 +329,7 @@ int cParsedNBT::FindTagByPath(int a_Tag, const AString & a_Path) const -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// // cFastNBTWriter: cFastNBTWriter::cFastNBTWriter(const AString & a_RootTagName) : diff --git a/src/WorldStorage/FastNBT.h b/src/WorldStorage/FastNBT.h index fe28005ac..7aa83fc24 100644 --- a/src/WorldStorage/FastNBT.h +++ b/src/WorldStorage/FastNBT.h @@ -5,11 +5,11 @@ /* The fast parser parses the data into a vector of cFastNBTTag structures. These structures describe the NBT tree, -but themselves are allocated in a vector, thus minimizing reallocation. +but themselves are allocated in a vector, thus minimizing reallocation. The structures have a minimal constructor, setting all member "pointers" to "invalid". The fast writer doesn't need a NBT tree structure built beforehand, it is commanded to open, append and close tags -(just like XML); it keeps the internal tag stack and reports errors in usage. +(just like XML); it keeps the internal tag stack and reports errors in usage. It directly outputs a string containing the serialized NBT data. */ @@ -173,7 +173,7 @@ public: } /** Returns the value stored in a Byte tag. Not valid for any other tag type. */ - inline unsigned char GetByte(int a_Tag) const + inline unsigned char GetByte(int a_Tag) const { ASSERT(m_Tags[(size_t)a_Tag].m_Type == TAG_Byte); return (unsigned char)(m_Data[(size_t)m_Tags[(size_t)a_Tag].m_DataStart]); diff --git a/src/WorldStorage/FireworksSerializer.cpp b/src/WorldStorage/FireworksSerializer.cpp index 181cfde0d..ecb600483 100644 --- a/src/WorldStorage/FireworksSerializer.cpp +++ b/src/WorldStorage/FireworksSerializer.cpp @@ -72,7 +72,7 @@ void cFireworkItem::ParseFromNBT(cFireworkItem & a_FireworkItem, const cParsedNB for (int explosiontag = a_NBT.GetFirstChild(a_TagIdx); explosiontag >= 0; explosiontag = a_NBT.GetNextSibling(explosiontag)) { eTagType TagType = a_NBT.GetType(explosiontag); - if (TagType == TAG_Byte) // Custon name tag + if (TagType == TAG_Byte) // Custon name tag { AString ExplosionName = a_NBT.GetName(explosiontag); @@ -98,7 +98,7 @@ void cFireworkItem::ParseFromNBT(cFireworkItem & a_FireworkItem, const cParsedNB // Divide by four as data length returned in bytes size_t DataLength = a_NBT.GetDataLength(explosiontag); // round to the next highest multiple of four - DataLength -= DataLength % 4; + DataLength -= DataLength % 4; if (DataLength == 0) { continue; @@ -114,7 +114,7 @@ void cFireworkItem::ParseFromNBT(cFireworkItem & a_FireworkItem, const cParsedNB { size_t DataLength = a_NBT.GetDataLength(explosiontag) / 4; // round to the next highest multiple of four - DataLength -= DataLength % 4; + DataLength -= DataLength % 4; if (DataLength == 0) { continue; @@ -135,7 +135,7 @@ void cFireworkItem::ParseFromNBT(cFireworkItem & a_FireworkItem, const cParsedNB for (int fireworkstag = a_NBT.GetFirstChild(a_TagIdx); fireworkstag >= 0; fireworkstag = a_NBT.GetNextSibling(fireworkstag)) { eTagType TagType = a_NBT.GetType(fireworkstag); - if (TagType == TAG_Byte) // Custon name tag + if (TagType == TAG_Byte) // Custon name tag { if (a_NBT.GetName(fireworkstag) == "Flight") { diff --git a/src/WorldStorage/MapSerializer.h b/src/WorldStorage/MapSerializer.h index eb7678a08..4fa40f6f9 100644 --- a/src/WorldStorage/MapSerializer.h +++ b/src/WorldStorage/MapSerializer.h @@ -52,10 +52,9 @@ private: /** Utility class used to serialize item ID counts. - * - * In order to perform bounds checking (while loading), - * the last registered ID of each item is serialized to an NBT file. - */ +In order to perform bounds checking (while loading), +the last registered ID of each item is serialized to an NBT file. +*/ class cIDCountSerializer { public: diff --git a/src/WorldStorage/NBTChunkSerializer.cpp b/src/WorldStorage/NBTChunkSerializer.cpp index 93ade6448..702690872 100644 --- a/src/WorldStorage/NBTChunkSerializer.cpp +++ b/src/WorldStorage/NBTChunkSerializer.cpp @@ -29,6 +29,7 @@ #include "../Entities/Minecart.h" #include "../Entities/Pickup.h" #include "../Entities/ArrowEntity.h" +#include "../Entities/SplashPotionEntity.h" #include "../Entities/TNTEntity.h" #include "../Entities/ExpOrb.h" #include "../Entities/HangingEntity.h" @@ -175,10 +176,10 @@ void cNBTChunkSerializer::AddBasicTileEntity(cBlockEntity * a_Entity, const char -void cNBTChunkSerializer::AddChestEntity(cChestEntity * a_Entity) +void cNBTChunkSerializer::AddChestEntity(cChestEntity * a_Entity, BLOCKTYPE a_ChestType) { m_Writer.BeginCompound(""); - AddBasicTileEntity(a_Entity, "Chest"); + AddBasicTileEntity(a_Entity, (a_ChestType == E_BLOCK_CHEST) ? "Chest" : "TrappedChest"); m_Writer.BeginList("Items", TAG_Compound); AddItemGrid(a_Entity->GetContents()); m_Writer.EndList(); @@ -278,7 +279,7 @@ void cNBTChunkSerializer::AddCommandBlockEntity(cCommandBlockEntity * a_CmdBlock m_Writer.AddString("Command", a_CmdBlock->GetCommand()); m_Writer.AddInt ("SuccessCount", a_CmdBlock->GetResult()); m_Writer.AddString("LastOutput", a_CmdBlock->GetLastOutput()); - m_Writer.AddByte ("TrackOutput", 1); // TODO 2014-01-18 xdot: Figure out what TrackOutput is and save it. + m_Writer.AddByte ("TrackOutput", 1); // TODO 2014-01-18 xdot: Figure out what TrackOutput is and save it. m_Writer.EndCompound(); } @@ -590,22 +591,31 @@ void cNBTChunkSerializer::AddProjectileEntity(cProjectileEntity * a_Projectile) m_Writer.BeginCompound(""); AddBasicEntity(a_Projectile, a_Projectile->GetMCAClassName()); Vector3d Pos = a_Projectile->GetPosition(); - m_Writer.AddShort("xTile", (Int16)floor(Pos.x)); - m_Writer.AddShort("yTile", (Int16)floor(Pos.y)); - m_Writer.AddShort("zTile", (Int16)floor(Pos.z)); - m_Writer.AddShort("inTile", 0); // TODO: Query the block type - m_Writer.AddShort("shake", 0); // TODO: Any shake? - m_Writer.AddByte ("inGround", a_Projectile->IsInGround() ? 1 : 0); + m_Writer.AddByte("inGround", a_Projectile->IsInGround() ? 1 : 0); switch (a_Projectile->GetProjectileKind()) { case cProjectileEntity::pkArrow: { - m_Writer.AddByte("inData", 0); // TODO: Query the block meta (is it needed?) - m_Writer.AddByte("pickup", ((cArrowEntity *)a_Projectile)->GetPickupState()); - m_Writer.AddDouble("damage", ((cArrowEntity *)a_Projectile)->GetDamageCoeff()); + cArrowEntity * Arrow = (cArrowEntity *)a_Projectile; + + m_Writer.AddInt("xTile", (Int16)Arrow->GetBlockHit().x); + m_Writer.AddInt("yTile", (Int16)Arrow->GetBlockHit().y); + m_Writer.AddInt("zTile", (Int16)Arrow->GetBlockHit().z); + m_Writer.AddByte("pickup", Arrow->GetPickupState()); + m_Writer.AddDouble("damage", Arrow->GetDamageCoeff()); break; } + case cProjectileEntity::pkSplashPotion: + { + cSplashPotionEntity * Potion = (cSplashPotionEntity *)a_Projectile; + + m_Writer.AddInt("EffectType", (Int16)Potion->GetEntityEffectType()); + m_Writer.AddInt("EffectDuration", (Int16)Potion->GetEntityEffect().GetDuration()); + m_Writer.AddShort("EffectIntensity", Potion->GetEntityEffect().GetIntensity()); + m_Writer.AddDouble("EffectDistanceModifier", Potion->GetEntityEffect().GetDistanceModifier()); + m_Writer.AddInt("PotionName", Potion->GetPotionParticleType()); + } case cProjectileEntity::pkGhastFireball: { m_Writer.AddInt("ExplosionPower", 1); @@ -622,13 +632,10 @@ void cNBTChunkSerializer::AddProjectileEntity(cProjectileEntity * a_Projectile) ASSERT(!"Unsaved projectile entity!"); } } // switch (ProjectileKind) - cEntity * Creator = a_Projectile->GetCreator(); - if (Creator != NULL) + + if (!a_Projectile->GetCreatorName().empty()) { - if (Creator->GetEntityType() == cEntity::etPlayer) - { - m_Writer.AddString("ownerName", ((cPlayer *)Creator)->GetName()); - } + m_Writer.AddString("ownerName", a_Projectile->GetCreatorName()); } m_Writer.EndCompound(); } @@ -818,18 +825,21 @@ void cNBTChunkSerializer::BlockEntity(cBlockEntity * a_Entity) // Add tile-entity into NBT: switch (a_Entity->GetBlockType()) { - case E_BLOCK_CHEST: AddChestEntity ((cChestEntity *) a_Entity); break; - case E_BLOCK_DISPENSER: AddDispenserEntity ((cDispenserEntity *) a_Entity); break; - case E_BLOCK_DROPPER: AddDropperEntity ((cDropperEntity *) a_Entity); break; - case E_BLOCK_FLOWER_POT: AddFlowerPotEntity ((cFlowerPotEntity *) a_Entity); break; - case E_BLOCK_FURNACE: AddFurnaceEntity ((cFurnaceEntity *) a_Entity); break; - case E_BLOCK_HOPPER: AddHopperEntity ((cHopperEntity *) a_Entity); break; - case E_BLOCK_SIGN_POST: - case E_BLOCK_WALLSIGN: AddSignEntity ((cSignEntity *) a_Entity); break; - case E_BLOCK_HEAD: AddMobHeadEntity ((cMobHeadEntity *) 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_COMMAND_BLOCK: AddCommandBlockEntity((cCommandBlockEntity *) a_Entity); break; + case E_BLOCK_CHEST: AddChestEntity ((cChestEntity *) a_Entity, a_Entity->GetBlockType()); break; + case E_BLOCK_COMMAND_BLOCK: AddCommandBlockEntity((cCommandBlockEntity *)a_Entity); break; + case E_BLOCK_DISPENSER: AddDispenserEntity ((cDispenserEntity *) a_Entity); break; + case E_BLOCK_DROPPER: AddDropperEntity ((cDropperEntity *) a_Entity); break; + case E_BLOCK_ENDER_CHEST: /* No data to be saved */ break; + case E_BLOCK_FLOWER_POT: AddFlowerPotEntity ((cFlowerPotEntity *) a_Entity); break; + case E_BLOCK_FURNACE: AddFurnaceEntity ((cFurnaceEntity *) a_Entity); break; + case E_BLOCK_HEAD: AddMobHeadEntity ((cMobHeadEntity *) a_Entity); break; + case E_BLOCK_HOPPER: AddHopperEntity ((cHopperEntity *) a_Entity); break; + case E_BLOCK_JUKEBOX: AddJukeboxEntity ((cJukeboxEntity *) a_Entity); break; + case E_BLOCK_LIT_FURNACE: AddFurnaceEntity ((cFurnaceEntity *) a_Entity); break; + case E_BLOCK_NOTE_BLOCK: AddNoteEntity ((cNoteEntity *) a_Entity); break; + case E_BLOCK_SIGN_POST: AddSignEntity ((cSignEntity *) a_Entity); break; + case E_BLOCK_TRAPPED_CHEST: AddChestEntity ((cChestEntity *) a_Entity, a_Entity->GetBlockType()); break; + case E_BLOCK_WALLSIGN: AddSignEntity ((cSignEntity *) a_Entity); break; default: { diff --git a/src/WorldStorage/NBTChunkSerializer.h b/src/WorldStorage/NBTChunkSerializer.h index 112afc27e..710a06a70 100644 --- a/src/WorldStorage/NBTChunkSerializer.h +++ b/src/WorldStorage/NBTChunkSerializer.h @@ -46,6 +46,7 @@ class cTNTEntity; class cExpOrb; class cHangingEntity; class cItemFrame; +class cEntityEffect; @@ -92,7 +93,7 @@ protected: // Block entities: void AddBasicTileEntity(cBlockEntity * a_Entity, const char * a_EntityTypeID); - void AddChestEntity (cChestEntity * a_Entity); + void AddChestEntity (cChestEntity * a_Entity, BLOCKTYPE a_ChestType); void AddDispenserEntity(cDispenserEntity * a_Entity); void AddDropperEntity (cDropperEntity * a_Entity); void AddFurnaceEntity (cFurnaceEntity * a_Furnace); diff --git a/src/WorldStorage/SchematicFileSerializer.cpp b/src/WorldStorage/SchematicFileSerializer.cpp index 1cf99efd9..64f4cb00d 100644 --- a/src/WorldStorage/SchematicFileSerializer.cpp +++ b/src/WorldStorage/SchematicFileSerializer.cpp @@ -44,7 +44,7 @@ public: -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// // cSchematicFileSerializer: bool cSchematicFileSerializer::LoadFromSchematicFile(cBlockArea & a_BlockArea, const AString & a_FileName) diff --git a/src/WorldStorage/ScoreboardSerializer.cpp b/src/WorldStorage/ScoreboardSerializer.cpp index 6c885bb45..da8236e0d 100644 --- a/src/WorldStorage/ScoreboardSerializer.cpp +++ b/src/WorldStorage/ScoreboardSerializer.cpp @@ -117,7 +117,7 @@ void cScoreboardSerializer::SaveScoreboardToNBT(cFastNBTWriter & a_Writer) a_Writer.EndCompound(); } - a_Writer.EndList(); // Objectives + a_Writer.EndList(); // Objectives a_Writer.BeginList("PlayerScores", TAG_Compound); @@ -138,7 +138,7 @@ void cScoreboardSerializer::SaveScoreboardToNBT(cFastNBTWriter & a_Writer) } } - a_Writer.EndList(); // PlayerScores + a_Writer.EndList(); // PlayerScores a_Writer.BeginList("Teams", TAG_Compound); @@ -169,7 +169,7 @@ void cScoreboardSerializer::SaveScoreboardToNBT(cFastNBTWriter & a_Writer) a_Writer.EndCompound(); } - a_Writer.EndList(); // Teams + a_Writer.EndList(); // Teams a_Writer.BeginCompound("DisplaySlots"); @@ -182,9 +182,9 @@ void cScoreboardSerializer::SaveScoreboardToNBT(cFastNBTWriter & a_Writer) Objective = m_ScoreBoard->GetObjectiveIn(cScoreboard::dsName); a_Writer.AddString("slot_2", (Objective == NULL) ? "" : Objective->GetName()); - a_Writer.EndCompound(); // DisplaySlots + a_Writer.EndCompound(); // DisplaySlots - a_Writer.EndCompound(); // Data + a_Writer.EndCompound(); // Data } diff --git a/src/WorldStorage/WSSAnvil.cpp b/src/WorldStorage/WSSAnvil.cpp index f714c0414..1dbf20bc0 100644 --- a/src/WorldStorage/WSSAnvil.cpp +++ b/src/WorldStorage/WSSAnvil.cpp @@ -36,6 +36,7 @@ #include "../Entities/Minecart.h" #include "../Entities/Pickup.h" #include "../Entities/ArrowEntity.h" +#include "../Entities/SplashPotionEntity.h" #include "../Entities/ThrownEggEntity.h" #include "../Entities/ThrownEnderPearlEntity.h" #include "../Entities/ThrownSnowballEntity.h" @@ -55,7 +56,7 @@ thus making skylight visible in Minutor's Lighting mode */ // #define DEBUG_SKYLIGHT -/** Maximum number of MCA files that are cached in memory. +/** Maximum number of MCA files that are cached in memory. Since only the header is actually in the memory, this number can be high, but still, each file means an OS FS handle. */ #define MAX_MCA_FILES 32 @@ -68,7 +69,7 @@ Since only the header is actually in the memory, this number can be high, but st -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// // cWSSAnvil: cWSSAnvil::cWSSAnvil(cWorld * a_World, int a_CompressionFactor) : @@ -392,7 +393,7 @@ bool cWSSAnvil::LoadChunkFromNBT(const cChunkCoords & a_Chunk, const cParsedNBT m_World->SetChunkData( a_Chunk.m_ChunkX, a_Chunk.m_ChunkZ, - BlockTypes, MetaData, + BlockTypes, MetaData, IsLightValid ? BlockLight : NULL, IsLightValid ? SkyLight : NULL, NULL, Biomes, @@ -448,7 +449,7 @@ bool cWSSAnvil::SaveChunkToNBT(const cChunkCoords & a_Chunk, cFastNBTWriter & a_ const char * BlockLight = (const char *)(Serializer.m_BlockSkyLight); #else const char * BlockLight = (const char *)(Serializer.m_BlockLight); - #endif + #endif const char * BlockSkyLight = (const char *)(Serializer.m_BlockSkyLight); for (int Y = 0; Y < 16; Y++) { @@ -462,7 +463,7 @@ bool cWSSAnvil::SaveChunkToNBT(const cChunkCoords & a_Chunk, cFastNBTWriter & a_ } a_Writer.EndList(); // "Sections" - // Store the information that the lighting is valid. + // Store the information that the lighting is valid. // For compatibility reason, the default is "invalid" (missing) - this means older data is re-lighted upon loading. if (Serializer.IsLightValid()) { @@ -582,7 +583,7 @@ void cWSSAnvil::LoadBlockEntitiesFromNBT(cBlockEntityList & a_BlockEntities, con } if (strncmp(a_NBT.GetData(sID), "Chest", a_NBT.GetDataLength(sID)) == 0) { - LoadChestFromNBT(a_BlockEntities, a_NBT, Child); + LoadChestFromNBT(a_BlockEntities, a_NBT, Child, E_BLOCK_CHEST); } else if (strncmp(a_NBT.GetData(sID), "Control", a_NBT.GetDataLength(sID)) == 0) { @@ -624,6 +625,10 @@ void cWSSAnvil::LoadBlockEntitiesFromNBT(cBlockEntityList & a_BlockEntities, con { LoadDispenserFromNBT(a_BlockEntities, a_NBT, Child); } + else if (strncmp(a_NBT.GetData(sID), "TrappedChest", a_NBT.GetDataLength(sID)) == 0) + { + LoadChestFromNBT(a_BlockEntities, a_NBT, Child, E_BLOCK_TRAPPED_CHEST); + } // TODO: Other block entities } // for Child - tag children } @@ -740,7 +745,7 @@ void cWSSAnvil::LoadItemGridFromNBT(cItemGrid & a_ItemGrid, const cParsedNBT & a -void cWSSAnvil::LoadChestFromNBT(cBlockEntityList & a_BlockEntities, const cParsedNBT & a_NBT, int a_TagIdx) +void cWSSAnvil::LoadChestFromNBT(cBlockEntityList & a_BlockEntities, const cParsedNBT & a_NBT, int a_TagIdx, BLOCKTYPE a_ChestType) { ASSERT(a_NBT.GetType(a_TagIdx) == TAG_Compound); int x, y, z; @@ -753,7 +758,7 @@ void cWSSAnvil::LoadChestFromNBT(cBlockEntityList & a_BlockEntities, const cPars { return; // Make it an empty chest - the chunk loader will provide an empty cChestEntity for this } - std::auto_ptr<cChestEntity> Chest(new cChestEntity(x, y, z, m_World)); + std::auto_ptr<cChestEntity> Chest(new cChestEntity(x, y, z, m_World, a_ChestType)); LoadItemGridFromNBT(Chest->GetContents(), a_NBT, Items); a_BlockEntities.push_back(Chest.release()); } @@ -1152,6 +1157,10 @@ void cWSSAnvil::LoadEntityFromNBT(cEntityList & a_Entities, const cParsedNBT & a { LoadArrowFromNBT(a_Entities, a_NBT, a_EntityTagIdx); } + else if (strncmp(a_IDTag, "SplashPotion", a_IDTagLength) == 0) + { + LoadSplashPotionFromNBT(a_Entities, a_NBT, a_EntityTagIdx); + } else if (strncmp(a_IDTag, "Snowball", a_IDTagLength) == 0) { LoadSnowballFromNBT(a_Entities, a_NBT, a_EntityTagIdx); @@ -1347,7 +1356,7 @@ void cWSSAnvil::LoadFallingBlockFromNBT(cEntityList & a_Entities, const cParsedN void cWSSAnvil::LoadMinecartRFromNBT(cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx) { - std::auto_ptr<cRideableMinecart> Minecart(new cRideableMinecart(0, 0, 0, cItem(), 1)); // TODO: Load the block and the height + std::auto_ptr<cRideableMinecart> Minecart(new cRideableMinecart(0, 0, 0, cItem(), 1)); // TODO: Load the block and the height if (!LoadEntityBaseFromNBT(*Minecart.get(), a_NBT, a_TagIdx)) { return; @@ -1456,7 +1465,7 @@ void cWSSAnvil::LoadPickupFromNBT(cEntityList & a_Entities, const cParsedNBT & a return; } - std::auto_ptr<cPickup> Pickup(new cPickup(0, 0, 0, Item, false)); // Pickup delay doesn't matter, just say false + std::auto_ptr<cPickup> Pickup(new cPickup(0, 0, 0, Item, false)); // Pickup delay doesn't matter, just say false if (!LoadEntityBaseFromNBT(*Pickup.get(), a_NBT, a_TagIdx)) { return; @@ -1642,6 +1651,15 @@ void cWSSAnvil::LoadArrowFromNBT(cEntityList & a_Entities, const cParsedNBT & a_ Arrow->SetDamageCoeff(a_NBT.GetDouble(DamageIdx)); } + // Load block hit: + int InBlockXIdx = a_NBT.FindChildByName(a_TagIdx, "xTile"); + int InBlockYIdx = a_NBT.FindChildByName(a_TagIdx, "yTile"); + int InBlockZIdx = a_NBT.FindChildByName(a_TagIdx, "zTile"); + if ((InBlockXIdx > 0) && (InBlockYIdx > 0) && (InBlockZIdx > 0)) + { + Arrow->SetBlockHit(Vector3i(a_NBT.GetInt(InBlockXIdx), a_NBT.GetInt(InBlockYIdx), a_NBT.GetInt(InBlockZIdx))); + } + // Store the new arrow in the entities list: a_Entities.push_back(Arrow.release()); } @@ -1649,6 +1667,29 @@ void cWSSAnvil::LoadArrowFromNBT(cEntityList & a_Entities, const cParsedNBT & a_ +void cWSSAnvil::LoadSplashPotionFromNBT(cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx) +{ + std::auto_ptr<cSplashPotionEntity> SplashPotion(new cSplashPotionEntity(NULL, 0, 0, 0, Vector3d(0, 0, 0), cEntityEffect::effNoEffect, cEntityEffect(), 0)); + if (!LoadProjectileBaseFromNBT(*SplashPotion.get(), a_NBT, a_TagIdx)) + { + return; + } + + int EffectDuration = a_NBT.FindChildByName(a_TagIdx, "EffectDuration"); + int EffectIntensity = a_NBT.FindChildByName(a_TagIdx, "EffectIntensity"); + int EffectDistanceModifier = a_NBT.FindChildByName(a_TagIdx, "EffectDistanceModifier"); + + SplashPotion->SetEntityEffectType((cEntityEffect::eType) a_NBT.FindChildByName(a_TagIdx, "EffectType")); + SplashPotion->SetEntityEffect(cEntityEffect(EffectDuration, EffectIntensity, EffectDistanceModifier)); + SplashPotion->SetPotionParticleType(a_NBT.FindChildByName(a_TagIdx, "PotionName")); + + // Store the new splash potion in the entities list: + a_Entities.push_back(SplashPotion.release()); +} + + + + void cWSSAnvil::LoadSnowballFromNBT(cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx) { @@ -2073,10 +2114,11 @@ void cWSSAnvil::LoadPigFromNBT(cEntityList & a_Entities, const cParsedNBT & a_NB void cWSSAnvil::LoadSheepFromNBT(cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx) { int ColorIdx = a_NBT.FindChildByName(a_TagIdx, "Color"); - - if (ColorIdx < 0) { return; } - - int Color = (int)a_NBT.GetByte(ColorIdx); + int Color = -1; + if (ColorIdx > 0) + { + Color = (int)a_NBT.GetByte(ColorIdx); + } std::auto_ptr<cSheep> Monster(new cSheep(Color)); if (!LoadEntityBaseFromNBT(*Monster.get(), a_NBT, a_TagIdx)) @@ -2089,6 +2131,12 @@ void cWSSAnvil::LoadSheepFromNBT(cEntityList & a_Entities, const cParsedNBT & a_ return; } + int ShearedIdx = a_NBT.FindChildByName(a_TagIdx, "Sheared"); + if (ShearedIdx > 0) + { + Monster->SetSheared(a_NBT.GetByte(ShearedIdx) != 0); + } + a_Entities.push_back(Monster.release()); } @@ -2315,8 +2363,8 @@ void cWSSAnvil::LoadWolfFromNBT(cEntityList & a_Entities, const cParsedNBT & a_N return; } int OwnerIdx = a_NBT.FindChildByName(a_TagIdx, "Owner"); - if (OwnerIdx > 0) - { + if (OwnerIdx > 0) + { AString OwnerName = a_NBT.GetString(OwnerIdx); if (OwnerName != "") { @@ -2482,8 +2530,6 @@ bool cWSSAnvil::LoadProjectileBaseFromNBT(cProjectileEntity & a_Entity, const cP } a_Entity.SetIsInGround(IsInGround); - // TODO: Load inTile, TileCoords - return true; } @@ -2554,7 +2600,7 @@ bool cWSSAnvil::GetBlockEntityNBTPos(const cParsedNBT & a_NBT, int a_TagIdx, int -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// // cWSSAnvil::cMCAFile: cWSSAnvil::cMCAFile::cMCAFile(const AString & a_FileName, int a_RegionX, int a_RegionZ) : diff --git a/src/WorldStorage/WSSAnvil.h b/src/WorldStorage/WSSAnvil.h index 7542a828a..5b629f017 100644 --- a/src/WorldStorage/WSSAnvil.h +++ b/src/WorldStorage/WSSAnvil.h @@ -133,7 +133,7 @@ protected: */ void LoadItemGridFromNBT(cItemGrid & a_ItemGrid, const cParsedNBT & a_NBT, int a_ItemsTagIdx, int s_SlotOffset = 0); - void LoadChestFromNBT (cBlockEntityList & a_BlockEntities, const cParsedNBT & a_NBT, int a_TagIdx); + void LoadChestFromNBT (cBlockEntityList & a_BlockEntities, const cParsedNBT & a_NBT, int a_TagIdx, BLOCKTYPE a_ChestType); void LoadDispenserFromNBT (cBlockEntityList & a_BlockEntities, const cParsedNBT & a_NBT, int a_TagIdx); void LoadDropperFromNBT (cBlockEntityList & a_BlockEntities, const cParsedNBT & a_NBT, int a_TagIdx); void LoadFlowerPotFromNBT (cBlockEntityList & a_BlockEntities, const cParsedNBT & a_NBT, int a_TagIdx); @@ -163,6 +163,7 @@ protected: void LoadMinecartHFromNBT (cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx); void LoadArrowFromNBT (cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx); + void LoadSplashPotionFromNBT (cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx); void LoadSnowballFromNBT (cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx); void LoadEggFromNBT (cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx); void LoadFireballFromNBT (cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx); diff --git a/src/WorldStorage/WSSCompact.cpp b/src/WorldStorage/WSSCompact.cpp index a853f6ec9..ff43b6905 100644 --- a/src/WorldStorage/WSSCompact.cpp +++ b/src/WorldStorage/WSSCompact.cpp @@ -48,7 +48,7 @@ const int MAX_DIRTY_CHUNKS = 16; -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// // cJsonChunkSerializer: cJsonChunkSerializer::cJsonChunkSerializer(void) : @@ -120,7 +120,7 @@ void cJsonChunkSerializer::LightIsValid(bool a_IsLightValid) -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// // cWSSCompact: cWSSCompact::~cWSSCompact() @@ -273,7 +273,7 @@ void cWSSCompact::LoadEntitiesFromJson(Json::Value & a_Value, cEntityList & a_En { for (Json::Value::iterator itr = AllChests.begin(); itr != AllChests.end(); ++itr ) { - std::auto_ptr<cChestEntity> ChestEntity(new cChestEntity(0, 0, 0, a_World)); + 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!" ); @@ -411,7 +411,7 @@ void cWSSCompact::LoadEntitiesFromJson(Json::Value & a_Value, cEntityList & a_En -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// // cWSSCompact::cPAKFile #define READ(Var) \ @@ -427,7 +427,7 @@ cWSSCompact::cPAKFile::cPAKFile(const AString & a_FileName, int a_LayerX, int a_ m_LayerX(a_LayerX), m_LayerZ(a_LayerZ), m_NumDirty(0), - m_ChunkVersion( CHUNK_VERSION ), // Init with latest version + m_ChunkVersion( CHUNK_VERSION ), // Init with latest version m_PakVersion( PAK_VERSION ) { cFile f; @@ -486,12 +486,12 @@ cWSSCompact::cPAKFile::cPAKFile(const AString & a_FileName, int a_LayerX, int a_ return; } - if( m_ChunkVersion == 1 ) // Convert chunks to version 2 + 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 + if( m_ChunkVersion == 2 ) // Convert chunks to version 3 { UpdateChunk2To3(); } @@ -586,7 +586,7 @@ void cWSSCompact::cPAKFile::UpdateChunk1To2() Offset += Header->m_CompressedSize; // Crude data integrity check: - int ExpectedSize = (16*128*16)*2 + (16*128*16)/2; // For version 1 + 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", @@ -603,7 +603,7 @@ void cWSSCompact::cPAKFile::UpdateChunk1To2() int errorcode = UncompressString(Data.data(), Data.size(), UncompressedData, (size_t)UncompressedSize); if (errorcode != Z_OK) { - LOGERROR("Error %d decompressing data for chunk [%d, %d]", + LOGERROR("Error %d decompressing data for chunk [%d, %d]", errorcode, Header->m_ChunkX, Header->m_ChunkZ ); @@ -627,7 +627,7 @@ void cWSSCompact::cPAKFile::UpdateChunk1To2() 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 x = 0; x < 16; ++x ) for( int z = 0; z < 16; ++z ) { for( int y = 0; y < 128; ++y ) { @@ -638,7 +638,7 @@ void cWSSCompact::cPAKFile::UpdateChunk1To2() Index += 128; } InChunkOffset += (16 * 128 * 16); - for( int x = 0; x < 16; ++x ) for( int z = 0; z < 16; ++z ) // Metadata + for( int x = 0; x < 16; ++x ) for( int z = 0; z < 16; ++z ) // Metadata { for( int y = 0; y < 64; ++y ) { @@ -648,7 +648,7 @@ void cWSSCompact::cPAKFile::UpdateChunk1To2() 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 x = 0; x < 16; ++x ) for( int z = 0; z < 16; ++z ) // Block light { for( int y = 0; y < 64; ++y ) { @@ -658,7 +658,7 @@ void cWSSCompact::cPAKFile::UpdateChunk1To2() 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 x = 0; x < 16; ++x ) for( int z = 0; z < 16; ++z ) // Sky light { for( int y = 0; y < 64; ++y ) { @@ -683,7 +683,7 @@ void cWSSCompact::cPAKFile::UpdateChunk1To2() int errorcode = CompressString(Converted.data(), Converted.size(), CompressedData, m_CompressionFactor); if (errorcode != Z_OK) { - LOGERROR("Error %d compressing data for chunk [%d, %d]", + LOGERROR("Error %d compressing data for chunk [%d, %d]", errorcode, Header->m_ChunkX, Header->m_ChunkZ ); @@ -747,7 +747,7 @@ void cWSSCompact::cPAKFile::UpdateChunk2To3() int errorcode = UncompressString(Data.data(), Data.size(), UncompressedData, (size_t)UncompressedSize); if (errorcode != Z_OK) { - LOGERROR("Error %d decompressing data for chunk [%d, %d]", + LOGERROR("Error %d decompressing data for chunk [%d, %d]", errorcode, Header->m_ChunkX, Header->m_ChunkZ ); @@ -774,7 +774,7 @@ void cWSSCompact::cPAKFile::UpdateChunk2To3() #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 + 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; @@ -819,7 +819,7 @@ void cWSSCompact::cPAKFile::UpdateChunk2To3() int errorcode = CompressString(Converted.data(), Converted.size(), CompressedData, m_CompressionFactor); if (errorcode != Z_OK) { - LOGERROR("Error %d compressing data for chunk [%d, %d]", + LOGERROR("Error %d compressing data for chunk [%d, %d]", errorcode, Header->m_ChunkX, Header->m_ChunkZ ); @@ -863,7 +863,7 @@ bool cWSSCompact::LoadChunkFromData(const cChunkCoords & a_Chunk, int a_Uncompre 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]", + LOGERROR("Error %d decompressing data for chunk [%d, %d]", errorcode, a_Chunk.m_ChunkX, a_Chunk.m_ChunkZ ); diff --git a/src/WorldStorage/WSSCompact.h b/src/WorldStorage/WSSCompact.h index b148005f6..83e9cb49f 100644 --- a/src/WorldStorage/WSSCompact.h +++ b/src/WorldStorage/WSSCompact.h @@ -105,15 +105,15 @@ protected: 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 + 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 + void UpdateChunk1To2(void); // Height from 128 to 256 + void UpdateChunk2To3(void); // Axis order from YZX to XZY } ; typedef std::list<cPAKFile *> cPAKFiles; diff --git a/src/WorldStorage/WorldStorage.cpp b/src/WorldStorage/WorldStorage.cpp index 6867ad5bc..155aa6b14 100644 --- a/src/WorldStorage/WorldStorage.cpp +++ b/src/WorldStorage/WorldStorage.cpp @@ -17,13 +17,6 @@ -/// If a chunk with this Y coord is de-queued, it is a signal to emit the saved-all message (cWorldStorage::QueueSavedMessage()) -#define CHUNK_Y_MESSAGE 2 - - - - - /// Example storage schema - forgets all chunks ;) class cWSSForgetful : public cWSSchema @@ -42,7 +35,7 @@ protected: -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// // cWorldStorage: cWorldStorage::cWorldStorage(void) : @@ -103,7 +96,7 @@ void cWorldStorage::WaitForFinish(void) // Wait for the thread to finish: m_ShouldTerminate = true; - m_Event.Set(); // Wake up the thread if waiting + m_Event.Set(); // Wake up the thread if waiting super::Wait(); LOG("World storage thread finished"); } @@ -168,17 +161,6 @@ void cWorldStorage::QueueSaveChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ) -void cWorldStorage::QueueSavedMessage(void) -{ - // Pushes a special coord pair into the queue, signalizing a message instead - m_SaveQueue.EnqueueItem(cChunkCoords(0, CHUNK_Y_MESSAGE, 0)); - m_Event.Set(); -} - - - - - void cWorldStorage::UnqueueLoad(int a_ChunkX, int a_ChunkY, int a_ChunkZ) { m_LoadQueue.Remove(sChunkLoad(a_ChunkX, a_ChunkY, a_ChunkZ,true)); @@ -220,7 +202,7 @@ void cWorldStorage::InitSchemas(int a_StorageCompressionFactor) } // for itr - m_Schemas[] // Unknown schema selected, let the admin know: - LOGWARNING("Unknown storage schema name \"%s\". Using default (\"%s\"). Available schemas:", + LOGWARNING("Unknown storage schema name \"%s\". Using default (\"%s\"). Available schemas:", m_StorageSchemaName.c_str(), m_SaveSchema->GetName().c_str() ); for (cWSSchemaList::iterator itr = m_Schemas.begin(); itr != m_Schemas.end(); ++itr) @@ -286,19 +268,12 @@ bool cWorldStorage::SaveOneChunk(void) { cChunkCoords ToSave(0, 0, 0); bool ShouldSave = m_SaveQueue.TryDequeueItem(ToSave); - if(ShouldSave) { - if (ToSave.m_ChunkY == CHUNK_Y_MESSAGE) - { - LOGINFO("Saved all chunks in world %s", m_World->GetName().c_str()); - return ShouldSave; - } - if (ShouldSave && m_World->IsChunkValid(ToSave.m_ChunkX, ToSave.m_ChunkZ)) + if (ShouldSave && m_World->IsChunkValid(ToSave.m_ChunkX, ToSave.m_ChunkZ)) + { + m_World->MarkChunkSaving(ToSave.m_ChunkX, ToSave.m_ChunkZ); + if (m_SaveSchema->SaveChunk(ToSave)) { - m_World->MarkChunkSaving(ToSave.m_ChunkX, ToSave.m_ChunkZ); - if (m_SaveSchema->SaveChunk(ToSave)) - { - m_World->MarkChunkSaved(ToSave.m_ChunkX, ToSave.m_ChunkZ); - } + m_World->MarkChunkSaved(ToSave.m_ChunkX, ToSave.m_ChunkZ); } } return ShouldSave; diff --git a/src/WorldStorage/WorldStorage.h b/src/WorldStorage/WorldStorage.h index bb189b6c9..bf764a539 100644 --- a/src/WorldStorage/WorldStorage.h +++ b/src/WorldStorage/WorldStorage.h @@ -67,9 +67,6 @@ public: void QueueLoadChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ, bool a_Generate); // Queues the chunk for loading; if not loaded, the chunk will be generated if a_Generate is true void QueueSaveChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ); - /// Signals that a message should be output to the console when all the chunks have been saved - void QueueSavedMessage(void); - /// Loads the chunk specified; returns true on success, false on failure bool LoadChunk(int a_ChunkX, int a_ChunkY, int a_ChunkZ); @@ -98,7 +95,7 @@ protected: bool operator==(const sChunkLoad other) const { - return this->m_ChunkX == other.m_ChunkX && + return this->m_ChunkX == other.m_ChunkX && this->m_ChunkY == other.m_ChunkY && this->m_ChunkZ == other.m_ChunkZ; } @@ -106,7 +103,7 @@ protected: struct FuncTable { static void Delete(sChunkLoad) {}; - static void Combine(sChunkLoad& a_orig, const sChunkLoad a_new) + static void Combine(sChunkLoad& a_orig, const sChunkLoad a_new) { a_orig.m_Generate |= a_new.m_Generate; }; |