From 53e22b11857fed62e2313d6d84d90f88ed412ffb Mon Sep 17 00:00:00 2001 From: Alexander Harkness Date: Mon, 29 Jul 2013 12:13:03 +0100 Subject: Changed everyting to Unix line endings. --- source/WorldStorage/NBTChunkSerializer.cpp | 918 ++++++++++++++--------------- source/WorldStorage/NBTChunkSerializer.h | 220 +++---- 2 files changed, 569 insertions(+), 569 deletions(-) (limited to 'source/WorldStorage') diff --git a/source/WorldStorage/NBTChunkSerializer.cpp b/source/WorldStorage/NBTChunkSerializer.cpp index d391325c9..da1b9e1c4 100644 --- a/source/WorldStorage/NBTChunkSerializer.cpp +++ b/source/WorldStorage/NBTChunkSerializer.cpp @@ -1,459 +1,459 @@ - -// NBTChunkSerializer.cpp - - -#include "Globals.h" -#include "NBTChunkSerializer.h" -#include "../BlockID.h" -#include "../BlockEntities/ChestEntity.h" -#include "../BlockEntities/DispenserEntity.h" -#include "../BlockEntities/DropperEntity.h" -#include "../BlockEntities/FurnaceEntity.h" -#include "../BlockEntities/HopperEntity.h" -#include "../BlockEntities/JukeboxEntity.h" -#include "../BlockEntities/NoteEntity.h" -#include "../BlockEntities/SignEntity.h" -#include "../ItemGrid.h" -#include "../StringCompression.h" -#include "../Entity.h" -#include "../OSSupport/MakeDir.h" -#include "FastNBT.h" -#include "../FallingBlock.h" -#include "../Minecart.h" -#include "../Mobs/Monster.h" -#include "../Pickup.h" - - - - -cNBTChunkSerializer::cNBTChunkSerializer(cFastNBTWriter & a_Writer) : - m_BiomesAreValid(false), - m_Writer(a_Writer), - m_IsTagOpen(false), - m_HasHadEntity(false), - m_HasHadBlockEntity(false), - m_IsLightValid(false) -{ -} - - - - - -void cNBTChunkSerializer::Finish(void) -{ - if (m_IsTagOpen) - { - m_Writer.EndList(); - } - - // If light not valid, reset it to all zeroes: - if (!m_IsLightValid) - { - memset(m_BlockLight, 0, sizeof(m_BlockLight)); - memset(m_BlockSkyLight, 0, sizeof(m_BlockSkyLight)); - } -} - - - - - -void cNBTChunkSerializer::AddItem(const cItem & a_Item, int a_Slot, const AString & a_CompoundName) -{ - m_Writer.BeginCompound(a_CompoundName); - m_Writer.AddShort("id", (short)(a_Item.m_ItemType)); - m_Writer.AddShort("Damage", a_Item.m_ItemDamage); - m_Writer.AddByte ("Count", a_Item.m_ItemCount); - if (a_Slot >= 0) - { - m_Writer.AddByte ("Slot", (unsigned char)a_Slot); - } - - // Write the enchantments: - if (!a_Item.m_Enchantments.IsEmpty()) - { - const char * TagName = (a_Item.m_ItemType == E_ITEM_BOOK) ? "StoredEnchantments" : "ench"; - m_Writer.BeginCompound("tag"); - a_Item.m_Enchantments.WriteToNBTCompound(m_Writer, TagName); - m_Writer.EndCompound(); - } - - m_Writer.EndCompound(); -} - - - - - -void cNBTChunkSerializer::AddItemGrid(const cItemGrid & a_Grid, int a_BeginSlotNum) -{ - int NumSlots = a_Grid.GetNumSlots(); - for (int i = 0; i < NumSlots; i++) - { - const cItem & Item = a_Grid.GetSlot(i); - if (Item.IsEmpty()) - { - continue; - } - AddItem(Item, i + a_BeginSlotNum); - } // for i - chest slots[] -} - - - - - -void cNBTChunkSerializer::AddBasicTileEntity(cBlockEntity * a_Entity, const char * a_EntityTypeID) -{ - m_Writer.AddInt ("x", a_Entity->GetPosX()); - m_Writer.AddInt ("y", a_Entity->GetPosY()); - m_Writer.AddInt ("z", a_Entity->GetPosZ()); - m_Writer.AddString("id", a_EntityTypeID); -} - - - - - -void cNBTChunkSerializer::AddChestEntity(cChestEntity * a_Entity) -{ - m_Writer.BeginCompound(""); - AddBasicTileEntity(a_Entity, "Chest"); - m_Writer.BeginList("Items", TAG_Compound); - AddItemGrid(a_Entity->GetContents()); - m_Writer.EndList(); - m_Writer.EndCompound(); -} - - - - - -void cNBTChunkSerializer::AddDispenserEntity(cDispenserEntity * a_Entity) -{ - m_Writer.BeginCompound(""); - AddBasicTileEntity(a_Entity, "Trap"); - m_Writer.BeginList("Items", TAG_Compound); - AddItemGrid(a_Entity->GetContents()); - m_Writer.EndList(); - m_Writer.EndCompound(); -} - - - - - -void cNBTChunkSerializer::AddDropperEntity(cDropperEntity * a_Entity) -{ - m_Writer.BeginCompound(""); - AddBasicTileEntity(a_Entity, "Dropper"); - m_Writer.BeginList("Items", TAG_Compound); - AddItemGrid(a_Entity->GetContents()); - m_Writer.EndList(); - m_Writer.EndCompound(); -} - - - - - -void cNBTChunkSerializer::AddFurnaceEntity(cFurnaceEntity * a_Furnace) -{ - m_Writer.BeginCompound(""); - AddBasicTileEntity(a_Furnace, "Furnace"); - m_Writer.BeginList("Items", TAG_Compound); - AddItemGrid(a_Furnace->GetContents()); - m_Writer.EndList(); - m_Writer.AddShort("BurnTime", a_Furnace->GetFuelBurnTimeLeft()); - m_Writer.AddShort("CookTime", a_Furnace->GetTimeCooked()); - m_Writer.EndCompound(); -} - - - - - -void cNBTChunkSerializer::AddHopperEntity(cHopperEntity * a_Entity) -{ - m_Writer.BeginCompound(""); - AddBasicTileEntity(a_Entity, "Hopper"); - m_Writer.BeginList("Items", TAG_Compound); - AddItemGrid(a_Entity->GetContents()); - m_Writer.EndList(); - m_Writer.EndCompound(); -} - - - - - -void cNBTChunkSerializer::AddJukeboxEntity(cJukeboxEntity * a_Jukebox) -{ - m_Writer.BeginCompound(""); - AddBasicTileEntity(a_Jukebox, "RecordPlayer"); - m_Writer.AddInt("Record", a_Jukebox->GetRecord()); - m_Writer.EndCompound(); -} - - - - - -void cNBTChunkSerializer::AddNoteEntity(cNoteEntity * a_Note) -{ - m_Writer.BeginCompound(""); - AddBasicTileEntity(a_Note, "Music"); - m_Writer.AddByte("note", a_Note->GetPitch()); - m_Writer.EndCompound(); -} - - - - - -void cNBTChunkSerializer::AddSignEntity(cSignEntity * a_Sign) -{ - m_Writer.BeginCompound(""); - AddBasicTileEntity(a_Sign, "Sign"); - m_Writer.AddString("Text1", a_Sign->GetLine(0)); - m_Writer.AddString("Text2", a_Sign->GetLine(1)); - m_Writer.AddString("Text3", a_Sign->GetLine(2)); - m_Writer.AddString("Text4", a_Sign->GetLine(3)); - m_Writer.EndCompound(); -} - - - - - -void cNBTChunkSerializer::AddBasicEntity(cEntity * a_Entity, const AString & a_ClassName) -{ - m_Writer.AddString("id", a_ClassName); - m_Writer.BeginList("Pos", TAG_Double); - m_Writer.AddDouble("", a_Entity->GetPosX()); - m_Writer.AddDouble("", a_Entity->GetPosY()); - m_Writer.AddDouble("", a_Entity->GetPosZ()); - m_Writer.EndList(); - m_Writer.BeginList("Motion", TAG_Double); - m_Writer.AddDouble("", a_Entity->GetSpeedX()); - m_Writer.AddDouble("", a_Entity->GetSpeedY()); - m_Writer.AddDouble("", a_Entity->GetSpeedZ()); - m_Writer.EndList(); - m_Writer.BeginList("Rotation", TAG_Double); - m_Writer.AddDouble("", a_Entity->GetRotation()); - m_Writer.AddDouble("", a_Entity->GetPitch()); - m_Writer.EndList(); -} - - - - - -void cNBTChunkSerializer::AddFallingBlockEntity(cFallingBlock * a_FallingBlock) -{ - m_Writer.BeginCompound(""); - AddBasicEntity(a_FallingBlock, "FallingSand"); - m_Writer.AddInt("TileID", a_FallingBlock->GetBlockType()); - m_Writer.AddByte("Data", a_FallingBlock->GetBlockMeta()); - m_Writer.AddByte("Time", 1); // Unused in MCServer, Vanilla said to need nonzero - m_Writer.AddByte("DropItem", 1); - m_Writer.AddByte("HurtEntities", a_FallingBlock->GetBlockType() == E_BLOCK_ANVIL); - m_Writer.EndCompound(); -} - - - - - -void cNBTChunkSerializer::AddMinecartEntity(cMinecart * a_Minecart) -{ - const char * EntityClass = NULL; - switch (a_Minecart->GetPayload()) - { - case cMinecart::mpNone: EntityClass = "MinecartRideable"; break; - case cMinecart::mpChest: EntityClass = "MinecartChest"; break; - case cMinecart::mpFurnace: EntityClass = "MinecartFurnace"; break; - default: - { - ASSERT(!"Unhandled minecart payload type"); - return; - } - } // switch (payload) - - m_Writer.BeginCompound(""); - AddBasicEntity(a_Minecart, EntityClass); - switch (a_Minecart->GetPayload()) - { - case cMinecart::mpChest: - { - // Add chest contents into the Items tag: - AddMinecartChestContents((cMinecartWithChest *)a_Minecart); - break; - } - - case cMinecart::mpFurnace: - { - // TODO: Add "Push" and "Fuel" tags - break; - } - } // switch (Payload) - m_Writer.EndCompound(); -} - - - - - -void cNBTChunkSerializer::AddMonsterEntity(cMonster * a_Monster) -{ - // TODO -} - - - - - -void cNBTChunkSerializer::AddPickupEntity(cPickup * a_Pickup) -{ - m_Writer.BeginCompound(""); - AddBasicEntity(a_Pickup, "Item"); - AddItem(a_Pickup->GetItem(), -1, "Item"); - m_Writer.AddShort("Health", a_Pickup->GetHealth()); - m_Writer.AddShort("Age", a_Pickup->GetAge()); - m_Writer.EndCompound(); -} - - - - - -void cNBTChunkSerializer::AddMinecartChestContents(cMinecartWithChest * a_Minecart) -{ - m_Writer.BeginList("Items", TAG_Compound); - for (int i = 0; i < cMinecartWithChest::NumSlots; i++) - { - const cItem & Item = a_Minecart->GetSlot(i); - if (Item.IsEmpty()) - { - continue; - } - AddItem(Item, i); - } - m_Writer.EndList(); -} - - - - - -bool cNBTChunkSerializer::LightIsValid(bool a_IsLightValid) -{ - m_IsLightValid = a_IsLightValid; - return a_IsLightValid; // We want lighting only if it's valid, otherwise don't bother -} - - - - - -void cNBTChunkSerializer::BiomeData(const cChunkDef::BiomeMap * a_BiomeMap) -{ - memcpy(m_Biomes, a_BiomeMap, sizeof(m_Biomes)); - for (int i = 0; i < ARRAYCOUNT(m_Biomes); i++) - { - if ((*a_BiomeMap)[i] < 255) - { - // Normal MC biome, copy as-is: - m_VanillaBiomes[i] = (unsigned char)((*a_BiomeMap)[i]); - } - else - { - // TODO: MCS-specific biome, need to map to some basic MC biome: - ASSERT(!"Unimplemented MCS-specific biome"); - return; - } - } // for i - m_BiomeMap[] - m_BiomesAreValid = true; -} - - - - - -void cNBTChunkSerializer::Entity(cEntity * a_Entity) -{ - // Add entity into NBT: - if (m_IsTagOpen) - { - if (!m_HasHadEntity) - { - m_Writer.EndList(); - m_Writer.BeginList("Entities", TAG_Compound); - } - } - else - { - m_Writer.BeginList("Entities", TAG_Compound); - } - m_IsTagOpen = true; - m_HasHadEntity = true; - - switch (a_Entity->GetEntityType()) - { - case cEntity::etFallingBlock: AddFallingBlockEntity((cFallingBlock *)a_Entity); break; - case cEntity::etMinecart: AddMinecartEntity ((cMinecart *) a_Entity); break; - case cEntity::etMonster: AddMonsterEntity ((cMonster *) a_Entity); break; - case cEntity::etPickup: AddPickupEntity ((cPickup *) a_Entity); break; - case cEntity::etPlayer: return; // Players aren't saved into the world - default: - { - ASSERT(!"Unhandled entity type is being saved"); - break; - } - } -} - - - - - -void cNBTChunkSerializer::BlockEntity(cBlockEntity * a_Entity) -{ - if (m_IsTagOpen) - { - if (!m_HasHadBlockEntity) - { - m_Writer.EndList(); - m_Writer.BeginList("TileEntities", TAG_Compound); - } - } - else - { - m_Writer.BeginList("TileEntities", TAG_Compound); - } - m_IsTagOpen = true; - - // 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_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_NOTE_BLOCK: AddNoteEntity ((cNoteEntity *) a_Entity); break; - case E_BLOCK_JUKEBOX: AddJukeboxEntity ((cJukeboxEntity *) a_Entity); break; - default: - { - ASSERT(!"Unhandled block entity saved into Anvil"); - } - } - m_HasHadBlockEntity = true; -} - - - - + +// NBTChunkSerializer.cpp + + +#include "Globals.h" +#include "NBTChunkSerializer.h" +#include "../BlockID.h" +#include "../BlockEntities/ChestEntity.h" +#include "../BlockEntities/DispenserEntity.h" +#include "../BlockEntities/DropperEntity.h" +#include "../BlockEntities/FurnaceEntity.h" +#include "../BlockEntities/HopperEntity.h" +#include "../BlockEntities/JukeboxEntity.h" +#include "../BlockEntities/NoteEntity.h" +#include "../BlockEntities/SignEntity.h" +#include "../ItemGrid.h" +#include "../StringCompression.h" +#include "../Entity.h" +#include "../OSSupport/MakeDir.h" +#include "FastNBT.h" +#include "../FallingBlock.h" +#include "../Minecart.h" +#include "../Mobs/Monster.h" +#include "../Pickup.h" + + + + +cNBTChunkSerializer::cNBTChunkSerializer(cFastNBTWriter & a_Writer) : + m_BiomesAreValid(false), + m_Writer(a_Writer), + m_IsTagOpen(false), + m_HasHadEntity(false), + m_HasHadBlockEntity(false), + m_IsLightValid(false) +{ +} + + + + + +void cNBTChunkSerializer::Finish(void) +{ + if (m_IsTagOpen) + { + m_Writer.EndList(); + } + + // If light not valid, reset it to all zeroes: + if (!m_IsLightValid) + { + memset(m_BlockLight, 0, sizeof(m_BlockLight)); + memset(m_BlockSkyLight, 0, sizeof(m_BlockSkyLight)); + } +} + + + + + +void cNBTChunkSerializer::AddItem(const cItem & a_Item, int a_Slot, const AString & a_CompoundName) +{ + m_Writer.BeginCompound(a_CompoundName); + m_Writer.AddShort("id", (short)(a_Item.m_ItemType)); + m_Writer.AddShort("Damage", a_Item.m_ItemDamage); + m_Writer.AddByte ("Count", a_Item.m_ItemCount); + if (a_Slot >= 0) + { + m_Writer.AddByte ("Slot", (unsigned char)a_Slot); + } + + // Write the enchantments: + if (!a_Item.m_Enchantments.IsEmpty()) + { + const char * TagName = (a_Item.m_ItemType == E_ITEM_BOOK) ? "StoredEnchantments" : "ench"; + m_Writer.BeginCompound("tag"); + a_Item.m_Enchantments.WriteToNBTCompound(m_Writer, TagName); + m_Writer.EndCompound(); + } + + m_Writer.EndCompound(); +} + + + + + +void cNBTChunkSerializer::AddItemGrid(const cItemGrid & a_Grid, int a_BeginSlotNum) +{ + int NumSlots = a_Grid.GetNumSlots(); + for (int i = 0; i < NumSlots; i++) + { + const cItem & Item = a_Grid.GetSlot(i); + if (Item.IsEmpty()) + { + continue; + } + AddItem(Item, i + a_BeginSlotNum); + } // for i - chest slots[] +} + + + + + +void cNBTChunkSerializer::AddBasicTileEntity(cBlockEntity * a_Entity, const char * a_EntityTypeID) +{ + m_Writer.AddInt ("x", a_Entity->GetPosX()); + m_Writer.AddInt ("y", a_Entity->GetPosY()); + m_Writer.AddInt ("z", a_Entity->GetPosZ()); + m_Writer.AddString("id", a_EntityTypeID); +} + + + + + +void cNBTChunkSerializer::AddChestEntity(cChestEntity * a_Entity) +{ + m_Writer.BeginCompound(""); + AddBasicTileEntity(a_Entity, "Chest"); + m_Writer.BeginList("Items", TAG_Compound); + AddItemGrid(a_Entity->GetContents()); + m_Writer.EndList(); + m_Writer.EndCompound(); +} + + + + + +void cNBTChunkSerializer::AddDispenserEntity(cDispenserEntity * a_Entity) +{ + m_Writer.BeginCompound(""); + AddBasicTileEntity(a_Entity, "Trap"); + m_Writer.BeginList("Items", TAG_Compound); + AddItemGrid(a_Entity->GetContents()); + m_Writer.EndList(); + m_Writer.EndCompound(); +} + + + + + +void cNBTChunkSerializer::AddDropperEntity(cDropperEntity * a_Entity) +{ + m_Writer.BeginCompound(""); + AddBasicTileEntity(a_Entity, "Dropper"); + m_Writer.BeginList("Items", TAG_Compound); + AddItemGrid(a_Entity->GetContents()); + m_Writer.EndList(); + m_Writer.EndCompound(); +} + + + + + +void cNBTChunkSerializer::AddFurnaceEntity(cFurnaceEntity * a_Furnace) +{ + m_Writer.BeginCompound(""); + AddBasicTileEntity(a_Furnace, "Furnace"); + m_Writer.BeginList("Items", TAG_Compound); + AddItemGrid(a_Furnace->GetContents()); + m_Writer.EndList(); + m_Writer.AddShort("BurnTime", a_Furnace->GetFuelBurnTimeLeft()); + m_Writer.AddShort("CookTime", a_Furnace->GetTimeCooked()); + m_Writer.EndCompound(); +} + + + + + +void cNBTChunkSerializer::AddHopperEntity(cHopperEntity * a_Entity) +{ + m_Writer.BeginCompound(""); + AddBasicTileEntity(a_Entity, "Hopper"); + m_Writer.BeginList("Items", TAG_Compound); + AddItemGrid(a_Entity->GetContents()); + m_Writer.EndList(); + m_Writer.EndCompound(); +} + + + + + +void cNBTChunkSerializer::AddJukeboxEntity(cJukeboxEntity * a_Jukebox) +{ + m_Writer.BeginCompound(""); + AddBasicTileEntity(a_Jukebox, "RecordPlayer"); + m_Writer.AddInt("Record", a_Jukebox->GetRecord()); + m_Writer.EndCompound(); +} + + + + + +void cNBTChunkSerializer::AddNoteEntity(cNoteEntity * a_Note) +{ + m_Writer.BeginCompound(""); + AddBasicTileEntity(a_Note, "Music"); + m_Writer.AddByte("note", a_Note->GetPitch()); + m_Writer.EndCompound(); +} + + + + + +void cNBTChunkSerializer::AddSignEntity(cSignEntity * a_Sign) +{ + m_Writer.BeginCompound(""); + AddBasicTileEntity(a_Sign, "Sign"); + m_Writer.AddString("Text1", a_Sign->GetLine(0)); + m_Writer.AddString("Text2", a_Sign->GetLine(1)); + m_Writer.AddString("Text3", a_Sign->GetLine(2)); + m_Writer.AddString("Text4", a_Sign->GetLine(3)); + m_Writer.EndCompound(); +} + + + + + +void cNBTChunkSerializer::AddBasicEntity(cEntity * a_Entity, const AString & a_ClassName) +{ + m_Writer.AddString("id", a_ClassName); + m_Writer.BeginList("Pos", TAG_Double); + m_Writer.AddDouble("", a_Entity->GetPosX()); + m_Writer.AddDouble("", a_Entity->GetPosY()); + m_Writer.AddDouble("", a_Entity->GetPosZ()); + m_Writer.EndList(); + m_Writer.BeginList("Motion", TAG_Double); + m_Writer.AddDouble("", a_Entity->GetSpeedX()); + m_Writer.AddDouble("", a_Entity->GetSpeedY()); + m_Writer.AddDouble("", a_Entity->GetSpeedZ()); + m_Writer.EndList(); + m_Writer.BeginList("Rotation", TAG_Double); + m_Writer.AddDouble("", a_Entity->GetRotation()); + m_Writer.AddDouble("", a_Entity->GetPitch()); + m_Writer.EndList(); +} + + + + + +void cNBTChunkSerializer::AddFallingBlockEntity(cFallingBlock * a_FallingBlock) +{ + m_Writer.BeginCompound(""); + AddBasicEntity(a_FallingBlock, "FallingSand"); + m_Writer.AddInt("TileID", a_FallingBlock->GetBlockType()); + m_Writer.AddByte("Data", a_FallingBlock->GetBlockMeta()); + m_Writer.AddByte("Time", 1); // Unused in MCServer, Vanilla said to need nonzero + m_Writer.AddByte("DropItem", 1); + m_Writer.AddByte("HurtEntities", a_FallingBlock->GetBlockType() == E_BLOCK_ANVIL); + m_Writer.EndCompound(); +} + + + + + +void cNBTChunkSerializer::AddMinecartEntity(cMinecart * a_Minecart) +{ + const char * EntityClass = NULL; + switch (a_Minecart->GetPayload()) + { + case cMinecart::mpNone: EntityClass = "MinecartRideable"; break; + case cMinecart::mpChest: EntityClass = "MinecartChest"; break; + case cMinecart::mpFurnace: EntityClass = "MinecartFurnace"; break; + default: + { + ASSERT(!"Unhandled minecart payload type"); + return; + } + } // switch (payload) + + m_Writer.BeginCompound(""); + AddBasicEntity(a_Minecart, EntityClass); + switch (a_Minecart->GetPayload()) + { + case cMinecart::mpChest: + { + // Add chest contents into the Items tag: + AddMinecartChestContents((cMinecartWithChest *)a_Minecart); + break; + } + + case cMinecart::mpFurnace: + { + // TODO: Add "Push" and "Fuel" tags + break; + } + } // switch (Payload) + m_Writer.EndCompound(); +} + + + + + +void cNBTChunkSerializer::AddMonsterEntity(cMonster * a_Monster) +{ + // TODO +} + + + + + +void cNBTChunkSerializer::AddPickupEntity(cPickup * a_Pickup) +{ + m_Writer.BeginCompound(""); + AddBasicEntity(a_Pickup, "Item"); + AddItem(a_Pickup->GetItem(), -1, "Item"); + m_Writer.AddShort("Health", a_Pickup->GetHealth()); + m_Writer.AddShort("Age", a_Pickup->GetAge()); + m_Writer.EndCompound(); +} + + + + + +void cNBTChunkSerializer::AddMinecartChestContents(cMinecartWithChest * a_Minecart) +{ + m_Writer.BeginList("Items", TAG_Compound); + for (int i = 0; i < cMinecartWithChest::NumSlots; i++) + { + const cItem & Item = a_Minecart->GetSlot(i); + if (Item.IsEmpty()) + { + continue; + } + AddItem(Item, i); + } + m_Writer.EndList(); +} + + + + + +bool cNBTChunkSerializer::LightIsValid(bool a_IsLightValid) +{ + m_IsLightValid = a_IsLightValid; + return a_IsLightValid; // We want lighting only if it's valid, otherwise don't bother +} + + + + + +void cNBTChunkSerializer::BiomeData(const cChunkDef::BiomeMap * a_BiomeMap) +{ + memcpy(m_Biomes, a_BiomeMap, sizeof(m_Biomes)); + for (int i = 0; i < ARRAYCOUNT(m_Biomes); i++) + { + if ((*a_BiomeMap)[i] < 255) + { + // Normal MC biome, copy as-is: + m_VanillaBiomes[i] = (unsigned char)((*a_BiomeMap)[i]); + } + else + { + // TODO: MCS-specific biome, need to map to some basic MC biome: + ASSERT(!"Unimplemented MCS-specific biome"); + return; + } + } // for i - m_BiomeMap[] + m_BiomesAreValid = true; +} + + + + + +void cNBTChunkSerializer::Entity(cEntity * a_Entity) +{ + // Add entity into NBT: + if (m_IsTagOpen) + { + if (!m_HasHadEntity) + { + m_Writer.EndList(); + m_Writer.BeginList("Entities", TAG_Compound); + } + } + else + { + m_Writer.BeginList("Entities", TAG_Compound); + } + m_IsTagOpen = true; + m_HasHadEntity = true; + + switch (a_Entity->GetEntityType()) + { + case cEntity::etFallingBlock: AddFallingBlockEntity((cFallingBlock *)a_Entity); break; + case cEntity::etMinecart: AddMinecartEntity ((cMinecart *) a_Entity); break; + case cEntity::etMonster: AddMonsterEntity ((cMonster *) a_Entity); break; + case cEntity::etPickup: AddPickupEntity ((cPickup *) a_Entity); break; + case cEntity::etPlayer: return; // Players aren't saved into the world + default: + { + ASSERT(!"Unhandled entity type is being saved"); + break; + } + } +} + + + + + +void cNBTChunkSerializer::BlockEntity(cBlockEntity * a_Entity) +{ + if (m_IsTagOpen) + { + if (!m_HasHadBlockEntity) + { + m_Writer.EndList(); + m_Writer.BeginList("TileEntities", TAG_Compound); + } + } + else + { + m_Writer.BeginList("TileEntities", TAG_Compound); + } + m_IsTagOpen = true; + + // 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_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_NOTE_BLOCK: AddNoteEntity ((cNoteEntity *) a_Entity); break; + case E_BLOCK_JUKEBOX: AddJukeboxEntity ((cJukeboxEntity *) a_Entity); break; + default: + { + ASSERT(!"Unhandled block entity saved into Anvil"); + } + } + m_HasHadBlockEntity = true; +} + + + + diff --git a/source/WorldStorage/NBTChunkSerializer.h b/source/WorldStorage/NBTChunkSerializer.h index c71286797..1ccd356b0 100644 --- a/source/WorldStorage/NBTChunkSerializer.h +++ b/source/WorldStorage/NBTChunkSerializer.h @@ -1,110 +1,110 @@ - -// NBTChunkSerializer.h - -// Declares the cNBTChunkSerializer class that is used for saving individual chunks into NBT format used by Anvil - - - - - -#pragma once - -#include "../ChunkDef.h" - - - - - -// fwd: -class cFastNBTWriter; -class cEntity; -class cBlockEntity; -class cChestEntity; -class cDispenserEntity; -class cDropperEntity; -class cFurnaceEntity; -class cHopperEntity; -class cJukeboxEntity; -class cNoteEntity; -class cSignEntity; -class cFallingBlock; -class cMinecart; -class cMinecartWithChest; -class cMinecartWithFurnace; -class cMonster; -class cPickup; -class cItemGrid; - - - - - -class cNBTChunkSerializer : - public cChunkDataSeparateCollector -{ -public: - cChunkDef::BiomeMap m_Biomes; - unsigned char m_VanillaBiomes[cChunkDef::Width * cChunkDef::Width]; - bool m_BiomesAreValid; - - - cNBTChunkSerializer(cFastNBTWriter & a_Writer); - - /// Close NBT tags that we've opened - void Finish(void); - - bool IsLightValid(void) const {return m_IsLightValid; } - -protected: - - /* From cChunkDataSeparateCollector we inherit: - - m_BlockTypes[] - - m_BlockMetas[] - - m_BlockLight[] - - m_BlockSkyLight[] - */ - - cFastNBTWriter & m_Writer; - - bool m_IsTagOpen; // True if a tag has been opened in the callbacks and not yet closed. - bool m_HasHadEntity; // True if any Entity has already been received and processed - bool m_HasHadBlockEntity; // True if any BlockEntity has already been received and processed - bool m_IsLightValid; // True if the chunk lighting is valid - - - /// Writes an item into the writer, if slot >= 0, adds the Slot tag. The compound is named as requested. - void AddItem(const cItem & a_Item, int a_Slot, const AString & a_CompoundName = ""); - - /// Writes an item grid into the writer; begins the stored slot numbers with a_BeginSlotNum. Note that it doesn't begin nor end the list tag - void AddItemGrid(const cItemGrid & a_Grid, int a_BeginSlotNum = 0); - - // Block entities: - void AddBasicTileEntity(cBlockEntity * a_Entity, const char * a_EntityTypeID); - void AddChestEntity (cChestEntity * a_Entity); - void AddDispenserEntity(cDispenserEntity * a_Entity); - void AddDropperEntity (cDropperEntity * a_Entity); - void AddFurnaceEntity (cFurnaceEntity * a_Furnace); - void AddHopperEntity (cHopperEntity * a_Entity); - void AddJukeboxEntity (cJukeboxEntity * a_Jukebox); - void AddNoteEntity (cNoteEntity * a_Note); - void AddSignEntity (cSignEntity * a_Sign); - - // Entities: - void AddBasicEntity (cEntity * a_Entity, const AString & a_ClassName); - void AddFallingBlockEntity(cFallingBlock * a_FallingBlock); - void AddMinecartEntity (cMinecart * a_Minecart); - void AddMonsterEntity (cMonster * a_Monster); - void AddPickupEntity (cPickup * a_Pickup); - - void AddMinecartChestContents(cMinecartWithChest * a_Minecart); - - // cChunkDataSeparateCollector overrides: - virtual bool LightIsValid(bool a_IsLightValid) override; - virtual void BiomeData(const cChunkDef::BiomeMap * a_BiomeMap) override; - virtual void Entity(cEntity * a_Entity) override; - virtual void BlockEntity(cBlockEntity * a_Entity) override; -} ; // class cNBTChunkSerializer - - - - + +// NBTChunkSerializer.h + +// Declares the cNBTChunkSerializer class that is used for saving individual chunks into NBT format used by Anvil + + + + + +#pragma once + +#include "../ChunkDef.h" + + + + + +// fwd: +class cFastNBTWriter; +class cEntity; +class cBlockEntity; +class cChestEntity; +class cDispenserEntity; +class cDropperEntity; +class cFurnaceEntity; +class cHopperEntity; +class cJukeboxEntity; +class cNoteEntity; +class cSignEntity; +class cFallingBlock; +class cMinecart; +class cMinecartWithChest; +class cMinecartWithFurnace; +class cMonster; +class cPickup; +class cItemGrid; + + + + + +class cNBTChunkSerializer : + public cChunkDataSeparateCollector +{ +public: + cChunkDef::BiomeMap m_Biomes; + unsigned char m_VanillaBiomes[cChunkDef::Width * cChunkDef::Width]; + bool m_BiomesAreValid; + + + cNBTChunkSerializer(cFastNBTWriter & a_Writer); + + /// Close NBT tags that we've opened + void Finish(void); + + bool IsLightValid(void) const {return m_IsLightValid; } + +protected: + + /* From cChunkDataSeparateCollector we inherit: + - m_BlockTypes[] + - m_BlockMetas[] + - m_BlockLight[] + - m_BlockSkyLight[] + */ + + cFastNBTWriter & m_Writer; + + bool m_IsTagOpen; // True if a tag has been opened in the callbacks and not yet closed. + bool m_HasHadEntity; // True if any Entity has already been received and processed + bool m_HasHadBlockEntity; // True if any BlockEntity has already been received and processed + bool m_IsLightValid; // True if the chunk lighting is valid + + + /// Writes an item into the writer, if slot >= 0, adds the Slot tag. The compound is named as requested. + void AddItem(const cItem & a_Item, int a_Slot, const AString & a_CompoundName = ""); + + /// Writes an item grid into the writer; begins the stored slot numbers with a_BeginSlotNum. Note that it doesn't begin nor end the list tag + void AddItemGrid(const cItemGrid & a_Grid, int a_BeginSlotNum = 0); + + // Block entities: + void AddBasicTileEntity(cBlockEntity * a_Entity, const char * a_EntityTypeID); + void AddChestEntity (cChestEntity * a_Entity); + void AddDispenserEntity(cDispenserEntity * a_Entity); + void AddDropperEntity (cDropperEntity * a_Entity); + void AddFurnaceEntity (cFurnaceEntity * a_Furnace); + void AddHopperEntity (cHopperEntity * a_Entity); + void AddJukeboxEntity (cJukeboxEntity * a_Jukebox); + void AddNoteEntity (cNoteEntity * a_Note); + void AddSignEntity (cSignEntity * a_Sign); + + // Entities: + void AddBasicEntity (cEntity * a_Entity, const AString & a_ClassName); + void AddFallingBlockEntity(cFallingBlock * a_FallingBlock); + void AddMinecartEntity (cMinecart * a_Minecart); + void AddMonsterEntity (cMonster * a_Monster); + void AddPickupEntity (cPickup * a_Pickup); + + void AddMinecartChestContents(cMinecartWithChest * a_Minecart); + + // cChunkDataSeparateCollector overrides: + virtual bool LightIsValid(bool a_IsLightValid) override; + virtual void BiomeData(const cChunkDef::BiomeMap * a_BiomeMap) override; + virtual void Entity(cEntity * a_Entity) override; + virtual void BlockEntity(cBlockEntity * a_Entity) override; +} ; // class cNBTChunkSerializer + + + + -- cgit v1.2.3