Cuberite
A lightweight, fast and extensible game server for Minecraft
NBTChunkSerializer.cpp
Go to the documentation of this file.
1 
2 // NBTChunkSerializer.cpp
3 
4 
5 #include "Globals.h"
6 #include "NBTChunkSerializer.h"
8 #include "NamespaceSerializer.h"
9 #include "../ChunkDataCallback.h"
10 #include "../ItemGrid.h"
11 #include "../StringCompression.h"
12 #include "../UUID.h"
13 #include "FastNBT.h"
14 
15 #include "../BlockEntities/BannerEntity.h"
16 #include "../BlockEntities/BeaconEntity.h"
17 #include "../BlockEntities/BedEntity.h"
18 #include "../BlockEntities/BrewingstandEntity.h"
19 #include "../BlockEntities/ChestEntity.h"
20 #include "../BlockEntities/CommandBlockEntity.h"
21 #include "../BlockEntities/DispenserEntity.h"
22 #include "../BlockEntities/DropperEntity.h"
23 #include "../BlockEntities/EnchantingTableEntity.h"
24 #include "../BlockEntities/EnderChestEntity.h"
25 #include "../BlockEntities/EndPortalEntity.h"
26 #include "../BlockEntities/FurnaceEntity.h"
27 #include "../BlockEntities/HopperEntity.h"
28 #include "../BlockEntities/JukeboxEntity.h"
29 #include "../BlockEntities/MobSpawnerEntity.h"
30 #include "../BlockEntities/NoteEntity.h"
31 #include "../BlockEntities/SignEntity.h"
32 #include "../BlockEntities/MobHeadEntity.h"
33 #include "../BlockEntities/FlowerPotEntity.h"
34 
35 #include "../Entities/Entity.h"
36 #include "../Entities/EnderCrystal.h"
37 #include "../Entities/FallingBlock.h"
38 #include "../Entities/Boat.h"
39 #include "../Entities/Minecart.h"
40 #include "../Entities/Pickup.h"
41 #include "../Entities/ArrowEntity.h"
42 #include "../Entities/SplashPotionEntity.h"
43 #include "../Entities/TNTEntity.h"
44 #include "../Entities/ExpOrb.h"
45 #include "../Entities/HangingEntity.h"
46 #include "../Entities/ItemFrame.h"
47 #include "../Entities/LeashKnot.h"
48 #include "../Entities/Painting.h"
49 
50 #include "../Mobs/IncludeAllMonsters.h"
51 
52 
53 
54 
55 
57 class SerializerCollector final :
59 {
60 public:
61 
62  // The data collected from the chunk:
65 
67  bool mIsTagOpen;
68 
71 
74 
77 
80 
81 
82 
83 
84 
86  mIsTagOpen(false),
87  mHasHadEntity(false),
88  mHasHadBlockEntity(false),
89  mIsLightValid(false),
90  mWriter(aWriter)
91  {
92  }
93 
94 
95 
96 
97 
98  virtual void LightIsValid(bool a_IsLightValid) override
99  {
100  mIsLightValid = a_IsLightValid;
101  }
102 
103 
104 
105 
106 
107  virtual void HeightMap(const cChunkDef::HeightMap & a_HeightMap) override
108  {
109  for (int RelZ = 0; RelZ < cChunkDef::Width; RelZ++)
110  {
111  for (int RelX = 0; RelX < cChunkDef::Width; RelX++)
112  {
113  Heights[RelX + RelZ * cChunkDef::Width] = cChunkDef::GetHeight(a_HeightMap, RelX, RelZ);
114  }
115  }
116  }
117 
118 
119 
120 
121 
122  virtual void BiomeMap(const cChunkDef::BiomeMap & a_BiomeMap) override
123  {
124  for (size_t i = 0; i < ARRAYCOUNT(Biomes); i++)
125  {
126  if (a_BiomeMap[i] < 255)
127  {
128  // Normal MC biome, copy as-is:
129  Biomes[i] = static_cast<Byte>(a_BiomeMap[i]);
130  }
131  else
132  {
133  // TODO: MCS-specific biome, need to map to some basic MC biome:
134  ASSERT(!"Unimplemented MCS-specific biome");
135  return;
136  }
137  } // for i - mBiomeMap[]
138  }
139 
140 
141 
142 
143 
144  virtual void Entity(cEntity * a_Entity) override
145  {
146  // Add entity into NBT:
147  if (mIsTagOpen)
148  {
149  if (!mHasHadEntity)
150  {
151  mWriter.EndList();
152  mWriter.BeginList("Entities", TAG_Compound);
153  }
154  }
155  else
156  {
157  mWriter.BeginList("Entities", TAG_Compound);
158  }
159  mIsTagOpen = true;
160  mHasHadEntity = true;
161 
162  switch (a_Entity->GetEntityType())
163  {
164  case cEntity::etBoat: AddBoatEntity (static_cast<cBoat *> (a_Entity)); break;
165  case cEntity::etEnderCrystal: AddEnderCrystalEntity(static_cast<cEnderCrystal *> (a_Entity)); break;
166  case cEntity::etFallingBlock: AddFallingBlockEntity(static_cast<cFallingBlock *> (a_Entity)); break;
167  case cEntity::etMinecart: AddMinecartEntity (static_cast<cMinecart *> (a_Entity)); break;
168  case cEntity::etMonster: AddMonsterEntity (static_cast<cMonster *> (a_Entity)); break;
169  case cEntity::etPickup: AddPickupEntity (static_cast<cPickup *> (a_Entity)); break;
170  case cEntity::etProjectile: AddProjectileEntity (static_cast<cProjectileEntity *>(a_Entity)); break;
171  case cEntity::etTNT: AddTNTEntity (static_cast<cTNTEntity *> (a_Entity)); break;
172  case cEntity::etExpOrb: AddExpOrbEntity (static_cast<cExpOrb *> (a_Entity)); break;
173  case cEntity::etItemFrame: AddItemFrameEntity (static_cast<cItemFrame *> (a_Entity)); break;
174  case cEntity::etLeashKnot: AddLeashKnotEntity (static_cast<cLeashKnot *> (a_Entity)); break;
175  case cEntity::etPainting: AddPaintingEntity (static_cast<cPainting *> (a_Entity)); break;
176  case cEntity::etPlayer: return; // Players aren't saved into the world
177  case cEntity::etFloater: return; // Floaters aren't saved either
178  default:
179  {
180  ASSERT(!"Unhandled entity type is being saved");
181  break;
182  }
183  }
184  }
185 
186 
187 
188 
189 
190  virtual void BlockEntity(cBlockEntity * a_Entity) override
191  {
192  if (mIsTagOpen)
193  {
194  if (!mHasHadBlockEntity)
195  {
196  mWriter.EndList();
197  mWriter.BeginList("TileEntities", TAG_Compound);
198  }
199  }
200  else
201  {
202  mWriter.BeginList("TileEntities", TAG_Compound);
203  }
204  mIsTagOpen = true;
205 
206  // Add tile-entity into NBT:
207  switch (a_Entity->GetBlockType())
208  {
209  // Banners:
211  case E_BLOCK_WALL_BANNER: AddBannerEntity (static_cast<cBannerEntity *> (a_Entity)); break;
212 
213  // Others:
214  case E_BLOCK_BEACON: AddBeaconEntity (static_cast<cBeaconEntity *> (a_Entity)); break;
215  case E_BLOCK_BED: AddBedEntity (static_cast<cBedEntity *> (a_Entity)); break;
216  case E_BLOCK_BREWING_STAND: AddBrewingstandEntity (static_cast<cBrewingstandEntity *> (a_Entity)); break;
217  case E_BLOCK_CHEST: AddChestEntity (static_cast<cChestEntity *> (a_Entity), a_Entity->GetBlockType()); break;
218  case E_BLOCK_COMMAND_BLOCK: AddCommandBlockEntity (static_cast<cCommandBlockEntity *> (a_Entity)); break;
219  case E_BLOCK_DISPENSER: AddDispenserEntity (static_cast<cDispenserEntity *> (a_Entity)); break;
220  case E_BLOCK_DROPPER: AddDropperEntity (static_cast<cDropperEntity *> (a_Entity)); break;
221  case E_BLOCK_ENCHANTMENT_TABLE: AddEnchantingTableEntity(static_cast<cEnchantingTableEntity *>(a_Entity)); break;
222  case E_BLOCK_ENDER_CHEST: AddEnderchestEntity (static_cast<cEnderChestEntity *> (a_Entity)); break;
223  case E_BLOCK_END_PORTAL: AddEndPortalEntity (static_cast<cEndPortalEntity *> (a_Entity)); break;
224  case E_BLOCK_FLOWER_POT: AddFlowerPotEntity (static_cast<cFlowerPotEntity *> (a_Entity)); break;
225  case E_BLOCK_FURNACE: AddFurnaceEntity (static_cast<cFurnaceEntity *> (a_Entity)); break;
226  case E_BLOCK_HEAD: AddMobHeadEntity (static_cast<cMobHeadEntity *> (a_Entity)); break;
227  case E_BLOCK_HOPPER: AddHopperEntity (static_cast<cHopperEntity *> (a_Entity)); break;
228  case E_BLOCK_JUKEBOX: AddJukeboxEntity (static_cast<cJukeboxEntity *> (a_Entity)); break;
229  case E_BLOCK_LIT_FURNACE: AddFurnaceEntity (static_cast<cFurnaceEntity *> (a_Entity)); break;
230  case E_BLOCK_MOB_SPAWNER: AddMobSpawnerEntity (static_cast<cMobSpawnerEntity *> (a_Entity)); break;
231  case E_BLOCK_NOTE_BLOCK: AddNoteEntity (static_cast<cNoteEntity *> (a_Entity)); break;
232  case E_BLOCK_SIGN_POST: AddSignEntity (static_cast<cSignEntity *> (a_Entity)); break;
233  case E_BLOCK_TRAPPED_CHEST: AddChestEntity (static_cast<cChestEntity *> (a_Entity), a_Entity->GetBlockType()); break;
234  case E_BLOCK_WALLSIGN: AddSignEntity (static_cast<cSignEntity *> (a_Entity)); break;
235  default:
236  {
237  ASSERT(!"Unhandled block entity saved into Anvil");
238  }
239  }
240  mHasHadBlockEntity = true;
241  }
242 
243 
244 
245 
246 
247  void Finish(void)
248  {
249  if (mIsTagOpen)
250  {
251  mWriter.EndList();
252  }
253 
254  // Check if "Entity" and "TileEntities" lists exists. MCEdit requires this.
255  if (!mHasHadEntity)
256  {
257  mWriter.BeginList("Entities", TAG_Compound);
258  mWriter.EndList();
259  }
260  if (!mHasHadBlockEntity)
261  {
262  mWriter.BeginList("TileEntities", TAG_Compound);
263  mWriter.EndList();
264  }
265  }
266 
267 
268 
269 
270 
274  void AddItem(const cItem & a_Item, int a_Slot, const AString & a_CompoundName = AString())
275  {
276  mWriter.BeginCompound(a_CompoundName);
277  mWriter.AddShort("id", static_cast<Int16>(a_Item.m_ItemType));
278  mWriter.AddShort("Damage", static_cast<Int16>((a_Item.m_ItemDamage)));
279  mWriter.AddByte ("Count", static_cast<Byte>(a_Item.m_ItemCount));
280  if (a_Slot >= 0)
281  {
282  mWriter.AddByte ("Slot", static_cast<unsigned char>(a_Slot));
283  }
284 
285  // Write the tag compound (for enchantment, firework, custom name and repair cost):
286  if (
287  (!a_Item.m_Enchantments.IsEmpty()) ||
288  ((a_Item.m_ItemType == E_ITEM_FIREWORK_ROCKET) || (a_Item.m_ItemType == E_ITEM_FIREWORK_STAR)) ||
289  (a_Item.m_RepairCost > 0) ||
290  (a_Item.m_CustomName != "") ||
291  (!a_Item.m_LoreTable.empty())
292  )
293  {
294  mWriter.BeginCompound("tag");
295  if (a_Item.m_RepairCost > 0)
296  {
297  mWriter.AddInt("RepairCost", a_Item.m_RepairCost);
298  }
299 
300  if ((a_Item.m_CustomName != "") || (!a_Item.m_LoreTable.empty()))
301  {
302  mWriter.BeginCompound("display");
303  if (a_Item.m_CustomName != "")
304  {
305  mWriter.AddString("Name", a_Item.m_CustomName);
306  }
307  if (!a_Item.m_LoreTable.empty())
308  {
309  mWriter.BeginList("Lore", TAG_String);
310 
311  for (const auto & Line : a_Item.m_LoreTable)
312  {
313  mWriter.AddString("", Line);
314  }
315 
316  mWriter.EndList();
317  }
319  }
320 
321  if ((a_Item.m_ItemType == E_ITEM_FIREWORK_ROCKET) || (a_Item.m_ItemType == E_ITEM_FIREWORK_STAR))
322  {
324  }
325 
326  if (!a_Item.m_Enchantments.IsEmpty())
327  {
328  const char * TagName = (a_Item.m_ItemType == E_ITEM_BOOK) ? "StoredEnchantments" : "ench";
330  }
332  }
333 
335  }
336 
337 
338 
339 
340 
344  void AddItemGrid(const cItemGrid & a_Grid, int a_BeginSlotNum = 0)
345  {
346  int NumSlots = a_Grid.GetNumSlots();
347  for (int i = 0; i < NumSlots; i++)
348  {
349  const cItem & Item = a_Grid.GetSlot(i);
350  if (Item.IsEmpty())
351  {
352  continue;
353  }
354  AddItem(Item, i + a_BeginSlotNum);
355  } // for i - slots[]
356  }
357 
358 
359 
360 
361 
362  void AddBasicTileEntity(cBlockEntity * a_Entity, const char * a_EntityTypeID)
363  {
364  mWriter.AddInt ("x", a_Entity->GetPosX());
365  mWriter.AddInt ("y", a_Entity->GetPosY());
366  mWriter.AddInt ("z", a_Entity->GetPosZ());
367  mWriter.AddString("id", a_EntityTypeID);
368  }
369 
370 
371 
372 
373 
375  {
377  AddBasicTileEntity(a_Entity,"Banner");
378  mWriter.AddInt("Base", static_cast<int>(a_Entity->GetBaseColor()));
379  if (!a_Entity->GetCustomName().empty())
380  {
381  mWriter.AddString("CustomName", a_Entity->GetCustomName());
382  }
384  }
385 
386 
387 
388 
389 
391  {
393  AddBasicTileEntity(a_Entity, "Beacon");
394  mWriter.AddInt("Levels", a_Entity->GetBeaconLevel());
395  mWriter.AddInt("Primary", static_cast<int>(a_Entity->GetPrimaryEffect()));
396  mWriter.AddInt("Secondary", static_cast<int>(a_Entity->GetSecondaryEffect()));
397  mWriter.BeginList("Items", TAG_Compound);
398  AddItemGrid(a_Entity->GetContents());
399  mWriter.EndList();
401  }
402 
403 
404 
405 
406 
407  void AddBedEntity(cBedEntity * a_Entity)
408  {
410  AddBasicTileEntity(a_Entity, "Bed");
411  mWriter.AddInt("color", a_Entity->GetColor());
413  }
414 
415 
416 
417 
418 
420  {
422  AddBasicTileEntity(a_Brewingstand, "Brewingstand");
423  mWriter.BeginList("Items", TAG_Compound);
424  AddItemGrid(a_Brewingstand->GetContents());
425  mWriter.EndList();
426  mWriter.AddShort("BrewTime", a_Brewingstand->GetTimeBrewed());
427  mWriter.AddShort("Fuel", a_Brewingstand->GetRemainingFuel());
429  }
430 
431 
432 
433 
434 
435  void AddChestEntity(cChestEntity * a_Entity, BLOCKTYPE a_ChestType)
436  {
438  AddBasicTileEntity(a_Entity, "Chest");
439  mWriter.BeginList("Items", TAG_Compound);
440  AddItemGrid(a_Entity->GetContents());
441  mWriter.EndList();
443  }
444 
445 
446 
447 
448 
450  {
452  AddBasicTileEntity(a_Entity, "Trap");
453  mWriter.BeginList("Items", TAG_Compound);
454  AddItemGrid(a_Entity->GetContents());
455  mWriter.EndList();
457  }
458 
459 
460 
461 
462 
464  {
466  AddBasicTileEntity(a_Entity, "Dropper");
467  mWriter.BeginList("Items", TAG_Compound);
468  AddItemGrid(a_Entity->GetContents());
469  mWriter.EndList();
471  }
472 
473 
474 
475 
476 
478  {
480  AddBasicTileEntity(a_Entity, "EnchantingTable");
481  if (!a_Entity->GetCustomName().empty())
482  {
483  mWriter.AddString("CustomName", a_Entity->GetCustomName());
484  }
486  }
487 
488 
489 
490 
492  {
494  AddBasicTileEntity(a_Entity, "EnderChest");
496  }
497 
498 
499 
500 
502  {
504  AddBasicTileEntity(a_Entity, "EndPortal");
506  }
507 
508 
509 
510 
511 
513  {
515  AddBasicTileEntity(a_Furnace, "Furnace");
516  mWriter.BeginList("Items", TAG_Compound);
517  AddItemGrid(a_Furnace->GetContents());
518  mWriter.EndList();
519  mWriter.AddShort("BurnTime", static_cast<Int16>(a_Furnace->GetFuelBurnTimeLeft()));
520  mWriter.AddShort("CookTime", static_cast<Int16>(a_Furnace->GetTimeCooked()));
522  }
523 
524 
525 
526 
527 
529  {
531  AddBasicTileEntity(a_Entity, "Hopper");
532  mWriter.BeginList("Items", TAG_Compound);
533  AddItemGrid(a_Entity->GetContents());
534  mWriter.EndList();
536  }
537 
538 
539 
540 
541 
543  {
545  AddBasicTileEntity(a_Jukebox, "RecordPlayer");
546  mWriter.AddInt("Record", a_Jukebox->GetRecord());
548  }
549 
550 
551 
552 
553 
555  {
557  AddBasicTileEntity(a_MobSpawner, "MobSpawner");
558  mWriter.AddString("EntityId", NamespaceSerializer::From(a_MobSpawner->GetEntity()));
559  mWriter.AddShort("SpawnCount", a_MobSpawner->GetSpawnCount());
560  mWriter.AddShort("SpawnRange", a_MobSpawner->GetSpawnRange());
561  mWriter.AddShort("Delay", a_MobSpawner->GetSpawnDelay());
562  mWriter.AddShort("MinSpawnDelay", a_MobSpawner->GetMinSpawnDelay());
563  mWriter.AddShort("MaxSpawnDelay", a_MobSpawner->GetMaxSpawnDelay());
564  mWriter.AddShort("MaxNearbyEntities", a_MobSpawner->GetMaxNearbyEntities());
565  mWriter.AddShort("RequiredPlayerRange", a_MobSpawner->GetRequiredPlayerRange());
567  }
568 
569 
570 
571 
572 
573  void AddNoteEntity(cNoteEntity * a_Note)
574  {
576  AddBasicTileEntity(a_Note, "Music");
577  mWriter.AddByte("note", static_cast<Byte>(a_Note->GetNote()));
579  }
580 
581 
582 
583 
584 
586  {
588  AddBasicTileEntity(a_CmdBlock, "Control");
589  mWriter.AddString("Command", a_CmdBlock->GetCommand());
590  mWriter.AddInt ("SuccessCount", a_CmdBlock->GetResult());
591  mWriter.AddString("LastOutput", a_CmdBlock->GetLastOutput());
592  mWriter.AddByte ("TrackOutput", 1); // TODO 2014-01-18 xdot: Figure out what TrackOutput is and save it.
594  }
595 
596 
597 
598 
599 
600  void AddSignEntity(cSignEntity * a_Sign)
601  {
603  AddBasicTileEntity(a_Sign, "Sign");
604  mWriter.AddString("Text1", a_Sign->GetLine(0));
605  mWriter.AddString("Text2", a_Sign->GetLine(1));
606  mWriter.AddString("Text3", a_Sign->GetLine(2));
607  mWriter.AddString("Text4", a_Sign->GetLine(3));
609  }
610 
611 
612 
613 
614 
616  {
618  AddBasicTileEntity(a_MobHead, "Skull");
619  mWriter.AddByte ("SkullType", a_MobHead->GetType() & 0xFF);
620  mWriter.AddByte ("Rot", a_MobHead->GetRotation() & 0xFF);
621 
622  // The new Block Entity format for a Mob Head. See: https://minecraft.wiki/w/Head#Block_entity
623  mWriter.BeginCompound("Owner");
624  mWriter.AddString("Id", a_MobHead->GetOwnerUUID().ToShortString());
625  mWriter.AddString("Name", a_MobHead->GetOwnerName());
626  mWriter.BeginCompound("Properties");
627  mWriter.BeginList("textures", TAG_Compound);
629  mWriter.AddString("Signature", a_MobHead->GetOwnerTextureSignature());
630  mWriter.AddString("Value", a_MobHead->GetOwnerTexture());
632  mWriter.EndList();
636  }
637 
638 
639 
640 
641 
643  {
645  AddBasicTileEntity(a_FlowerPot, "FlowerPot");
646  mWriter.AddInt ("Item", static_cast<Int32>(a_FlowerPot->GetItem().m_ItemType));
647  mWriter.AddInt ("Data", static_cast<Int32>(a_FlowerPot->GetItem().m_ItemDamage));
649  }
650 
651 
652 
653 
654 
655  void AddBasicEntity(cEntity * a_Entity, const std::string_view a_ClassName)
656  {
657  mWriter.AddString("id", a_ClassName);
658  mWriter.BeginList("Pos", TAG_Double);
659  mWriter.AddDouble("", a_Entity->GetPosX());
660  mWriter.AddDouble("", a_Entity->GetPosY());
661  mWriter.AddDouble("", a_Entity->GetPosZ());
662  mWriter.EndList();
663  mWriter.BeginList("Motion", TAG_Double);
664  mWriter.AddDouble("", a_Entity->GetSpeedX());
665  mWriter.AddDouble("", a_Entity->GetSpeedY());
666  mWriter.AddDouble("", a_Entity->GetSpeedZ());
667  mWriter.EndList();
668  mWriter.BeginList("Rotation", TAG_Double);
669  mWriter.AddDouble("", a_Entity->GetYaw());
670  mWriter.AddDouble("", a_Entity->GetPitch());
671  mWriter.EndList();
672  mWriter.AddFloat("Health", a_Entity->GetHealth());
673  }
674 
675 
676 
677 
678 
679  void AddBoatEntity(cBoat * a_Boat)
680  {
682  AddBasicEntity(a_Boat, "Boat");
685  }
686 
687 
688 
689 
690 
691  void AddEnderCrystalEntity(cEnderCrystal * a_EnderCrystal)
692  {
694  AddBasicEntity(a_EnderCrystal, "EnderCrystal");
695  mWriter.AddByte("ShowBottom", a_EnderCrystal->ShowsBottom() ? 1 : 0);
696  if (a_EnderCrystal->DisplaysBeam())
697  {
698  mWriter.BeginCompound("BeamTarget");
699  const auto & BeamTarget = a_EnderCrystal->GetBeamTarget();
700  mWriter.AddInt("X", BeamTarget.x);
701  mWriter.AddInt("Y", BeamTarget.y);
702  mWriter.AddInt("Z", BeamTarget.z);
704  }
706  }
707 
708 
709 
710 
711 
712  void AddFallingBlockEntity(cFallingBlock * a_FallingBlock)
713  {
715  AddBasicEntity(a_FallingBlock, "FallingSand");
716  mWriter.AddInt("TileID", a_FallingBlock->GetBlockType());
717  mWriter.AddByte("Data", a_FallingBlock->GetBlockMeta());
718  mWriter.AddByte("Time", 1); // Unused in Cuberite, Vanilla said to need nonzero
719  mWriter.AddByte("DropItem", 1);
720  mWriter.AddByte("HurtEntities", a_FallingBlock->GetBlockType() == E_BLOCK_ANVIL);
722  }
723 
724 
725 
726 
727 
728  void AddMinecartEntity(cMinecart * a_Minecart)
729  {
731 
732  switch (a_Minecart->GetPayload())
733  {
734  case cMinecart::mpChest:
735  {
736  AddBasicEntity(a_Minecart, "MinecartChest");
737  // Add chest contents into the Items tag:
738  AddMinecartChestContents(static_cast<cMinecartWithChest *>(a_Minecart));
739  break;
740  }
742  {
743  AddBasicEntity(a_Minecart, "MinecartFurnace");
744  // TODO: Add "Push" and "Fuel" tags
745  break;
746  }
747  case cMinecart::mpHopper:
748  {
749  AddBasicEntity(a_Minecart, "MinecartHopper");
750  // TODO: Add hopper contents?
751  break;
752  }
753  case cMinecart::mpTNT:
754  {
755  AddBasicEntity(a_Minecart, "MinecartTNT");
756  break;
757  }
758  case cMinecart::mpNone:
759  {
760  AddBasicEntity(a_Minecart, "MinecartRideable");
761  break;
762  }
763  } // switch (Payload)
764 
766  }
767 
768 
769 
770 
771 
772  void AddMonsterEntity(cMonster * a_Monster)
773  {
775  AddBasicEntity(a_Monster, NamespaceSerializer::From(a_Monster->GetMobType()));
776  mWriter.BeginList("DropChances", TAG_Float);
777  mWriter.AddFloat("", a_Monster->GetDropChanceWeapon());
778  mWriter.AddFloat("", a_Monster->GetDropChanceHelmet());
779  mWriter.AddFloat("", a_Monster->GetDropChanceChestplate());
780  mWriter.AddFloat("", a_Monster->GetDropChanceLeggings());
781  mWriter.AddFloat("", a_Monster->GetDropChanceBoots());
782  mWriter.EndList();
783  mWriter.AddByte("CanPickUpLoot", (a_Monster->CanPickUpLoot())? 1 : 0);
784  mWriter.AddString("CustomName", a_Monster->GetCustomName());
785  mWriter.AddByte("CustomNameVisible", static_cast<Byte>(a_Monster->IsCustomNameAlwaysVisible()));
786 
787  // Mob was leashed
788  if (a_Monster->IsLeashed() || (a_Monster->GetLeashToPos() != nullptr))
789  {
790  mWriter.AddByte("Leashed", 1);
791 
792  const Vector3d * LeashedToPos = nullptr;
793 
794  if (a_Monster->GetLeashToPos() != nullptr)
795  {
796  LeashedToPos = a_Monster->GetLeashToPos();
797  }
798  else if (a_Monster->GetLeashedTo()->IsLeashKnot())
799  {
800  LeashedToPos = & a_Monster->GetLeashedTo()->GetPosition();
801  }
802 
803  if (LeashedToPos != nullptr)
804  {
805  mWriter.BeginCompound("Leash");
806  mWriter.AddDouble("X", LeashedToPos->x);
807  mWriter.AddDouble("Y", LeashedToPos->y);
808  mWriter.AddDouble("Z", LeashedToPos->z);
810  }
811  }
812 
813  switch (a_Monster->GetMobType())
814  {
815  case mtBat:
816  {
817  mWriter.AddByte("BatFlags", static_cast<const cBat *>(a_Monster)->IsHanging());
818  break;
819  }
820  case mtCreeper:
821  {
822  const cCreeper *Creeper = static_cast<const cCreeper *>(a_Monster);
823  mWriter.AddByte("powered", Creeper->IsCharged());
824  mWriter.AddByte("ignited", Creeper->IsBlowing());
825  break;
826  }
827  case mtEnderman:
828  {
829  const cEnderman *Enderman = static_cast<const cEnderman *>(a_Monster);
830  mWriter.AddShort("carried", static_cast<Int16>(Enderman->GetCarriedBlock()));
831  mWriter.AddShort("carriedData", static_cast<Int16>(Enderman->GetCarriedMeta()));
832  break;
833  }
834  case mtHorse:
835  {
836  const cHorse *Horse = static_cast<const cHorse *>(a_Monster);
837  mWriter.AddByte("ChestedHorse", Horse->IsChested()? 1 : 0);
838  mWriter.AddByte("EatingHaystack", Horse->IsEating()? 1 : 0);
839  mWriter.AddByte("Tame", Horse->IsTame()? 1: 0);
840  mWriter.AddInt ("Type", Horse->GetHorseType());
841  mWriter.AddInt ("Color", Horse->GetHorseColor());
842  mWriter.AddInt ("Style", Horse->GetHorseStyle());
843  mWriter.AddInt ("ArmorType", Horse->GetHorseArmour());
844  mWriter.AddByte("Saddle", Horse->IsSaddled()? 1 : 0);
845  mWriter.AddInt ("Age", Horse->GetAge());
846  break;
847  }
848  case mtMagmaCube:
849  {
850  mWriter.AddInt("Size", static_cast<const cMagmaCube *>(a_Monster)->GetSize());
851  break;
852  }
853  case mtOcelot:
854  {
855  const auto *Ocelot = static_cast<const cOcelot *>(a_Monster);
856  if (!Ocelot->GetOwnerName().empty())
857  {
858  mWriter.AddString("Owner", Ocelot->GetOwnerName());
859  }
860  if (!Ocelot->GetOwnerUUID().IsNil())
861  {
862  mWriter.AddString("OwnerUUID", Ocelot->GetOwnerUUID().ToShortString());
863  }
864  mWriter.AddByte("Sitting", Ocelot->IsSitting() ? 1 : 0);
865  mWriter.AddInt("CatType", Ocelot->GetOcelotType());
866  mWriter.AddInt("Age", Ocelot->GetAge());
867  break;
868  }
869  case mtPig:
870  {
871  mWriter.AddInt("Age", static_cast<const cPig *>(a_Monster)->GetAge());
872  break;
873  }
874  case mtRabbit:
875  {
876  const cRabbit * Rabbit = static_cast<const cRabbit *>(a_Monster);
877  mWriter.AddInt("RabbitType", static_cast<Int32>(Rabbit->GetRabbitType()));
878  mWriter.AddInt("MoreCarrotTicks", Rabbit->GetMoreCarrotTicks());
879  mWriter.AddInt("Age", Rabbit->GetAge());
880  break;
881  }
882  case mtSheep:
883  {
884  const cSheep *Sheep = static_cast<const cSheep *>(a_Monster);
885  mWriter.AddByte("Sheared", Sheep->IsSheared()? 1 : 0);
886  mWriter.AddByte("Color", static_cast<Byte>(Sheep->GetFurColor()));
887  mWriter.AddInt ("Age", Sheep->GetAge());
888  break;
889  }
890  case mtSlime:
891  {
892  mWriter.AddInt("Size", static_cast<const cSlime *>(a_Monster)->GetSize());
893  break;
894  }
895  case mtVillager:
896  {
897  const cVillager *Villager = static_cast<const cVillager *>(a_Monster);
898  mWriter.AddInt("Profession", Villager->GetVilType());
899  mWriter.AddInt("Age", Villager->GetAge());
900  mWriter.BeginList("Inventory", TAG_Compound);
901  AddItemGrid(Villager->GetInventory());
902  mWriter.EndList();
903  break;
904  }
905  case mtWither:
906  {
907  mWriter.AddInt("Invul", static_cast<Int32>(static_cast<const cWither *>(a_Monster)->GetWitherInvulnerableTicks()));
908  break;
909  }
910  case mtWolf:
911  {
912  const cWolf *Wolf = static_cast<const cWolf *>(a_Monster);
913  if (!Wolf->GetOwnerName().empty())
914  {
915  mWriter.AddString("Owner", Wolf->GetOwnerName());
916  }
917  if (!Wolf->GetOwnerUUID().IsNil())
918  {
919  mWriter.AddString("OwnerUUID", Wolf->GetOwnerUUID().ToShortString());
920  }
921  mWriter.AddByte("Sitting", Wolf->IsSitting() ? 1 : 0);
922  mWriter.AddByte("Angry", Wolf->IsAngry() ? 1 : 0);
923  mWriter.AddByte("CollarColor", static_cast<Byte>(Wolf->GetCollarColor()));
924  mWriter.AddInt ("Age", Wolf->GetAge());
925  break;
926  }
927  case mtZombie:
928  {
929  mWriter.AddInt("Age", static_cast<const cZombie *>(a_Monster)->GetAge());
930  break;
931  }
932  case mtZombiePigman:
933  {
934  mWriter.AddInt("Age", static_cast<const cZombiePigman *>(a_Monster)->GetAge());
935  break;
936  }
937  case mtZombieVillager:
938  {
939  const cZombieVillager *ZombieVillager = reinterpret_cast<const cZombieVillager *>(a_Monster);
940  mWriter.AddInt("Profession", ZombieVillager->GetProfession());
941  mWriter.AddInt("ConversionTime", ZombieVillager->ConversionTime());
942  mWriter.AddInt("Age", ZombieVillager->GetAge());
943  break;
944  }
945  case mtBlaze:
946  case mtCaveSpider:
947  case mtChicken:
948  case mtCow:
949  case mtEnderDragon:
950  case mtGhast:
951  case mtGiant:
952  case mtGuardian:
953  case mtIronGolem:
954  case mtMooshroom:
955  case mtSilverfish:
956  case mtSkeleton:
957  case mtSnowGolem:
958  case mtSpider:
959  case mtSquid:
960  case mtWitch:
961  case mtWitherSkeleton:
962  {
963  // Other mobs have no special tags.
964  break;
965  }
966  case mtCat:
967  case mtCod:
968  case mtDolphin:
969  case mtDonkey:
970  case mtDrowned:
971  case mtElderGuardian:
972  case mtEndermite:
973  case mtEvoker:
974  case mtFox:
975  case mtHoglin:
976  case mtHusk:
977  case mtIllusioner:
978  case mtLlama:
979  case mtMule:
980  case mtPanda:
981  case mtParrot:
982  case mtPhantom:
983  case mtPiglin:
984  case mtPiglinBrute:
985  case mtPillager:
986  case mtPolarBear:
987  case mtPufferfish:
988  case mtRavager:
989  case mtSalmon:
990  case mtShulker:
991  case mtSkeletonHorse:
992  case mtStray:
993  case mtStrider:
994  case mtTraderLlama:
995  case mtTropicalFish:
996  case mtTurtle:
997  case mtVex:
998  case mtVindicator:
999  case mtWanderingTrader:
1000  case mtZoglin:
1001  case mtZombieHorse:
1002  {
1003  // All the entities not added
1004  LOGD("Saving unimplemented entity type: %d", NamespaceSerializer::From(a_Monster->GetMobType()));
1005  break;
1006  }
1007  case mtInvalidType:
1008  {
1009  ASSERT(!"NBTChunkSerializer::SerializerCollector::AddMonsterEntity: Recieved mob of invalid type");
1010  break;
1011  }
1012  }
1013  mWriter.EndCompound();
1014  }
1015 
1016 
1017 
1018 
1019 
1020  void AddPickupEntity(cPickup * a_Pickup)
1021  {
1022  mWriter.BeginCompound("");
1023  AddBasicEntity(a_Pickup, "Item");
1024  AddItem(a_Pickup->GetItem(), -1, "Item");
1025  mWriter.AddShort("Age", static_cast<Int16>(a_Pickup->GetAge()));
1026  mWriter.EndCompound();
1027  }
1028 
1029 
1030 
1031 
1032 
1034  {
1035  mWriter.BeginCompound("");
1036  AddBasicEntity(a_Projectile, a_Projectile->GetMCAClassName());
1037  mWriter.AddByte("inGround", a_Projectile->IsInGround() ? 1 : 0);
1038 
1039  switch (a_Projectile->GetProjectileKind())
1040  {
1042  {
1043  cArrowEntity * Arrow = static_cast<cArrowEntity *>(a_Projectile);
1044 
1045  mWriter.AddShort("xTile", static_cast<Int16>(Arrow->GetBlockHit().x));
1046  mWriter.AddShort("yTile", static_cast<Int16>(Arrow->GetBlockHit().y));
1047  mWriter.AddShort("zTile", static_cast<Int16>(Arrow->GetBlockHit().z));
1048  mWriter.AddByte("pickup", static_cast<unsigned char>(Arrow->GetPickupState()));
1049  mWriter.AddDouble("damage", Arrow->GetDamageCoeff());
1050  break;
1051  }
1053  {
1054  cSplashPotionEntity * Potion = static_cast<cSplashPotionEntity *>(a_Projectile);
1055 
1056  mWriter.AddInt("EffectType", static_cast<Int16>(Potion->GetEntityEffectType()));
1057  mWriter.AddInt("EffectDuration", static_cast<Int16>(Potion->GetEntityEffect().GetDuration()));
1058  mWriter.AddShort("EffectIntensity", Potion->GetEntityEffect().GetIntensity());
1059  mWriter.AddDouble("EffectDistanceModifier", Potion->GetEntityEffect().GetDistanceModifier());
1060  mWriter.AddInt("PotionName", Potion->GetPotionColor());
1061  break;
1062  }
1064  {
1065  mWriter.AddInt("ExplosionPower", 1);
1066  break;
1067  }
1072  {
1073  break;
1074  }
1075  default:
1076  {
1077  ASSERT(!"Unsaved projectile entity!");
1078  }
1079  } // switch (ProjectileKind)
1080 
1081  if (!a_Projectile->GetCreatorName().empty())
1082  {
1083  mWriter.AddString("ownerName", a_Projectile->GetCreatorName());
1084  }
1085  mWriter.EndCompound();
1086  }
1087 
1088 
1089 
1090 
1091 
1093  {
1094  mWriter.AddInt("TileX", FloorC(a_Hanging->GetPosX()));
1095  mWriter.AddInt("TileY", FloorC(a_Hanging->GetPosY()));
1096  mWriter.AddInt("TileZ", FloorC(a_Hanging->GetPosZ()));
1097  mWriter.AddByte("Facing", a_Hanging->GetProtocolFacing());
1098  }
1099 
1100 
1101 
1102 
1103 
1104  void AddTNTEntity(cTNTEntity * a_TNT)
1105  {
1106  mWriter.BeginCompound("");
1107  AddBasicEntity(a_TNT, "PrimedTnt");
1108  mWriter.AddByte("Fuse", static_cast<unsigned char>(a_TNT->GetFuseTicks()));
1109  mWriter.EndCompound();
1110  }
1111 
1112 
1113 
1114 
1115 
1116  void AddExpOrbEntity(cExpOrb * a_ExpOrb)
1117  {
1118  mWriter.BeginCompound("");
1119  AddBasicEntity(a_ExpOrb, "XPOrb");
1120  mWriter.AddShort("Age", static_cast<Int16>(a_ExpOrb->GetAge()));
1121  mWriter.AddShort("Value", static_cast<Int16>(a_ExpOrb->GetReward()));
1122  mWriter.EndCompound();
1123  }
1124 
1125 
1126 
1127 
1128 
1129  void AddItemFrameEntity(cItemFrame * a_ItemFrame)
1130  {
1131  mWriter.BeginCompound("");
1132  AddBasicEntity(a_ItemFrame, "ItemFrame");
1133  AddHangingEntity(a_ItemFrame);
1134  AddItem(a_ItemFrame->GetItem(), -1, "Item");
1135  mWriter.AddByte("ItemRotation", static_cast<Byte>(a_ItemFrame->GetItemRotation()));
1136  mWriter.AddFloat("ItemDropChance", 1.0F);
1137  mWriter.EndCompound();
1138  }
1139 
1140 
1141 
1142 
1143 
1144  void AddLeashKnotEntity(cLeashKnot * a_LeashKnot)
1145  {
1146  mWriter.BeginCompound("");
1147  AddBasicEntity(a_LeashKnot, "LeashKnot");
1148  AddHangingEntity(a_LeashKnot);
1149  mWriter.EndCompound();
1150  }
1151 
1152 
1153 
1154 
1155 
1156  void AddPaintingEntity(cPainting * a_Painting)
1157  {
1158  mWriter.BeginCompound("");
1159  AddBasicEntity(a_Painting, "Painting");
1160  AddHangingEntity(a_Painting);
1161  mWriter.AddString("Motive", a_Painting->GetName());
1162  mWriter.EndCompound();
1163  }
1164 
1165 
1166 
1167 
1168 
1170  {
1171  mWriter.BeginList("Items", TAG_Compound);
1173  {
1174  const cItem & Item = a_Minecart->GetSlot(i);
1175  if (Item.IsEmpty())
1176  {
1177  continue;
1178  }
1179  AddItem(Item, i);
1180  }
1181  mWriter.EndList();
1182  }
1183 }; // SerializerCollector
1184 
1185 
1186 
1187 
1188 
1190 // NBTChunkSerializer:
1191 
1192 void NBTChunkSerializer::Serialize(const cWorld & aWorld, cChunkCoords aCoords, cFastNBTWriter & aWriter)
1193 {
1194  SerializerCollector serializer(aWriter);
1195  aWriter.BeginCompound("Level");
1196  aWriter.AddInt("xPos", aCoords.m_ChunkX);
1197  aWriter.AddInt("zPos", aCoords.m_ChunkZ);
1198  [[maybe_unused]] const bool Result = aWorld.GetChunkData(aCoords, serializer); // Chunk must be present in order to save
1199  ASSERT(Result);
1200  serializer.Finish(); // Close NBT tags
1201 
1202  // Save biomes:
1203  aWriter.AddByteArray("Biomes", reinterpret_cast<const char *>(serializer.Biomes), ARRAYCOUNT(serializer.Biomes));
1204 
1205  // Save heightmap (Vanilla require this):
1206  aWriter.AddIntArray("HeightMap", reinterpret_cast<const int *>(serializer.Heights), ARRAYCOUNT(serializer.Heights));
1207 
1208  // Save blockdata:
1209  aWriter.BeginList("Sections", TAG_Compound);
1210  ChunkDef_ForEachSection(serializer.m_BlockData, serializer.m_LightData,
1211  {
1212  aWriter.BeginCompound("");
1213 
1214  if (Blocks != nullptr)
1215  {
1216  aWriter.AddByteArray("Blocks", reinterpret_cast<const char *>(Blocks->data()), Blocks->size());
1217  }
1218  else
1219  {
1220  aWriter.AddByteArray("Blocks", ChunkBlockData::SectionBlockCount, ChunkBlockData::DefaultValue);
1221  }
1222 
1223  if (Metas != nullptr)
1224  {
1225  aWriter.AddByteArray("Data", reinterpret_cast<const char *>(Metas->data()), Metas->size());
1226  }
1227  else
1228  {
1230  }
1231 
1232  if (BlockLights != nullptr)
1233  {
1234  aWriter.AddByteArray("BlockLight", reinterpret_cast<const char *>(BlockLights->data()), BlockLights->size());
1235  }
1236  else
1237  {
1239  }
1240 
1241  if (SkyLights != nullptr)
1242  {
1243  aWriter.AddByteArray("SkyLight", reinterpret_cast<const char *>(SkyLights->data()), SkyLights->size());
1244  }
1245  else
1246  {
1248  }
1249 
1250  aWriter.AddByte("Y", static_cast<unsigned char>(Y));
1251  aWriter.EndCompound();
1252  });
1253  aWriter.EndList(); // "Sections"
1254 
1255  // Store the information that the lighting is valid.
1256  // For compatibility reason, the default is "invalid" (missing) - this means older data is re-lighted upon loading.
1257  if (serializer.mIsLightValid)
1258  {
1259  aWriter.AddByte("MCSIsLightValid", 1);
1260  }
1261 
1262  // Save the world age to the chunk data. Required by vanilla and mcedit.
1263  aWriter.AddLong("LastUpdate", aWorld.GetWorldAge().count());
1264 
1265  // Store the flag that the chunk has all the ores, trees, dungeons etc. Cuberite chunks are always complete.
1266  aWriter.AddByte("TerrainPopulated", 1);
1267 
1268  aWriter.EndCompound(); // "Level"
1269 }
@ E_BLOCK_HEAD
Definition: BlockType.h:159
@ E_BLOCK_STANDING_BANNER
Definition: BlockType.h:195
@ E_BLOCK_BREWING_STAND
Definition: BlockType.h:132
@ E_BLOCK_JUKEBOX
Definition: BlockType.h:99
@ E_BLOCK_ENCHANTMENT_TABLE
Definition: BlockType.h:131
@ E_BLOCK_FURNACE
Definition: BlockType.h:73
@ E_BLOCK_SIGN_POST
Definition: BlockType.h:76
@ E_BLOCK_BEACON
Definition: BlockType.h:153
@ E_BLOCK_CHEST
Definition: BlockType.h:64
@ E_BLOCK_LIT_FURNACE
Definition: BlockType.h:74
@ E_BLOCK_TRAPPED_CHEST
Definition: BlockType.h:161
@ E_BLOCK_ANVIL
Definition: BlockType.h:160
@ E_BLOCK_COMMAND_BLOCK
Definition: BlockType.h:152
@ E_BLOCK_NOTE_BLOCK
Definition: BlockType.h:35
@ E_BLOCK_BED
Definition: BlockType.h:36
@ E_BLOCK_HOPPER
Definition: BlockType.h:171
@ E_BLOCK_DROPPER
Definition: BlockType.h:176
@ E_BLOCK_ENDER_CHEST
Definition: BlockType.h:145
@ E_BLOCK_END_PORTAL
Definition: BlockType.h:134
@ E_BLOCK_DISPENSER
Definition: BlockType.h:33
@ E_BLOCK_FLOWER_POT
Definition: BlockType.h:155
@ E_BLOCK_MOB_SPAWNER
Definition: BlockType.h:62
@ E_BLOCK_WALLSIGN
Definition: BlockType.h:82
@ E_BLOCK_WALL_BANNER
Definition: BlockType.h:196
ENUM_ITEM_TYPE
Definition: BlockType.h:295
@ E_ITEM_FIREWORK_STAR
Definition: BlockType.h:448
@ E_ITEM_FIREWORK_ROCKET
Definition: BlockType.h:447
@ E_ITEM_BOOK
Definition: BlockType.h:385
#define ChunkDef_ForEachSection(BlockData, LightData, Callback)
Invokes the callback functor for every chunk section containing at least one present block or light s...
Definition: ChunkData.h:136
unsigned char BLOCKTYPE
The datatype used by blockdata.
Definition: ChunkDef.h:41
#define ARRAYCOUNT(X)
Evaluates to the number of elements in an array (compile-time!)
Definition: Globals.h:231
signed short Int16
Definition: Globals.h:153
signed int Int32
Definition: Globals.h:152
unsigned char UInt8
Definition: Globals.h:159
#define ASSERT(x)
Definition: Globals.h:276
std::enable_if< std::is_arithmetic< T >::value, C >::type FloorC(T a_Value)
Floors a value, then casts it to C (an int by default).
Definition: Globals.h:347
unsigned char Byte
Definition: Globals.h:161
#define LOGD
Definition: LoggerSimple.h:83
@ mtZombieVillager
Definition: MonsterTypes.h:82
@ mtVindicator
Definition: MonsterTypes.h:72
@ mtElderGuardian
Definition: MonsterTypes.h:25
@ mtHoglin
Definition: MonsterTypes.h:35
@ mtSkeleton
Definition: MonsterTypes.h:59
@ mtSheep
Definition: MonsterTypes.h:56
@ mtEndermite
Definition: MonsterTypes.h:28
@ mtPiglin
Definition: MonsterTypes.h:48
@ mtTurtle
Definition: MonsterTypes.h:69
@ mtPolarBear
Definition: MonsterTypes.h:51
@ mtDolphin
Definition: MonsterTypes.h:22
@ mtMagmaCube
Definition: MonsterTypes.h:40
@ mtWanderingTrader
Definition: MonsterTypes.h:73
@ mtWolf
Definition: MonsterTypes.h:77
@ mtStray
Definition: MonsterTypes.h:65
@ mtRabbit
Definition: MonsterTypes.h:53
@ mtTraderLlama
Definition: MonsterTypes.h:67
@ mtCat
Definition: MonsterTypes.h:16
@ mtZombie
Definition: MonsterTypes.h:79
@ mtOcelot
Definition: MonsterTypes.h:43
@ mtRavager
Definition: MonsterTypes.h:54
@ mtDonkey
Definition: MonsterTypes.h:23
@ mtVex
Definition: MonsterTypes.h:70
@ mtEnderman
Definition: MonsterTypes.h:27
@ mtTropicalFish
Definition: MonsterTypes.h:68
@ mtHusk
Definition: MonsterTypes.h:36
@ mtCaveSpider
Definition: MonsterTypes.h:17
@ mtEvoker
Definition: MonsterTypes.h:29
@ mtPhantom
Definition: MonsterTypes.h:46
@ mtShulker
Definition: MonsterTypes.h:57
@ mtPufferfish
Definition: MonsterTypes.h:52
@ mtWither
Definition: MonsterTypes.h:75
@ mtSkeletonHorse
Definition: MonsterTypes.h:60
@ mtPig
Definition: MonsterTypes.h:47
@ mtDrowned
Definition: MonsterTypes.h:24
@ mtVillager
Definition: MonsterTypes.h:71
@ mtHorse
Definition: MonsterTypes.h:34
@ mtZombieHorse
Definition: MonsterTypes.h:80
@ mtWitch
Definition: MonsterTypes.h:74
@ mtCow
Definition: MonsterTypes.h:20
@ mtSalmon
Definition: MonsterTypes.h:55
@ mtEnderDragon
Definition: MonsterTypes.h:26
@ mtPiglinBrute
Definition: MonsterTypes.h:49
@ mtMooshroom
Definition: MonsterTypes.h:41
@ mtSquid
Definition: MonsterTypes.h:64
@ mtInvalidType
Definition: MonsterTypes.h:12
@ mtBat
Definition: MonsterTypes.h:14
@ mtIllusioner
Definition: MonsterTypes.h:37
@ mtChicken
Definition: MonsterTypes.h:18
@ mtGiant
Definition: MonsterTypes.h:32
@ mtSnowGolem
Definition: MonsterTypes.h:62
@ mtFox
Definition: MonsterTypes.h:30
@ mtBlaze
Definition: MonsterTypes.h:15
@ mtLlama
Definition: MonsterTypes.h:39
@ mtIronGolem
Definition: MonsterTypes.h:38
@ mtCreeper
Definition: MonsterTypes.h:21
@ mtSpider
Definition: MonsterTypes.h:63
@ mtMule
Definition: MonsterTypes.h:42
@ mtPillager
Definition: MonsterTypes.h:50
@ mtGhast
Definition: MonsterTypes.h:31
@ mtParrot
Definition: MonsterTypes.h:45
@ mtSilverfish
Definition: MonsterTypes.h:58
@ mtZoglin
Definition: MonsterTypes.h:78
@ mtPanda
Definition: MonsterTypes.h:44
@ mtCod
Definition: MonsterTypes.h:19
@ mtStrider
Definition: MonsterTypes.h:66
@ mtZombiePigman
Definition: MonsterTypes.h:85
@ mtSlime
Definition: MonsterTypes.h:61
@ mtWitherSkeleton
Definition: MonsterTypes.h:76
@ mtGuardian
Definition: MonsterTypes.h:33
Item
Definition: Items.h:4
@ Rabbit
@ Potion
std::string AString
Definition: StringUtils.h:11
@ TAG_Float
Definition: FastNBT.h:37
@ TAG_String
Definition: FastNBT.h:40
@ TAG_Compound
Definition: FastNBT.h:42
@ TAG_Double
Definition: FastNBT.h:38
void WriteToNBTCompound(const cEnchantments &a_Enchantments, cFastNBTWriter &a_Writer, const AString &a_ListTagName)
Writes the enchantments into the specified NBT writer; begins with the LIST tag of the specified name...
std::string_view From(CustomStatistic a_ID)
unsigned char GetBaseColor() const
Definition: BannerEntity.h:30
const AString & GetCustomName() const
Definition: BannerEntity.h:33
cEntityEffect::eType GetPrimaryEffect(void) const
Definition: BeaconEntity.h:48
char GetBeaconLevel(void) const
Returns the beacon level.
Definition: BeaconEntity.h:46
cEntityEffect::eType GetSecondaryEffect(void) const
Definition: BeaconEntity.h:49
short GetColor(void) const
Returns the color of the bed.
Definition: BedEntity.h:28
int GetPosZ() const
Definition: BlockEntity.h:93
int GetPosY() const
Definition: BlockEntity.h:92
int GetPosX() const
Definition: BlockEntity.h:91
BLOCKTYPE GetBlockType() const
Definition: BlockEntity.h:97
cItemGrid & GetContents(void)
Returns the ItemGrid used for storing the contents.
short GetTimeBrewed(void)
Returns the time that the current items has been brewing, in ticks.
short GetRemainingFuel(void)
Returns the remaining fuel that is left.
const AString & GetLastOutput(void) const
Retrieves the last line of output generated by the command block.
NIBBLETYPE GetResult(void) const
Retrieves the result (signal strength) of the last operation.
const AString & GetCommand(void) const
Retrieves stored command.
const AString & GetCustomName() const
cItem GetItem(void) const
Get the item in the flower pot.
int GetFuelBurnTimeLeft(void) const
Returns the time until the current fuel is depleted, in ticks.
Definition: FurnaceEntity.h:83
int GetTimeCooked(void) const
Returns the time that the current item has been cooking, in ticks.
Definition: FurnaceEntity.h:77
int GetRecord(void)
eMobHeadRotation GetRotation(void) const
Returns the rotation of the mob head.
Definition: MobHeadEntity.h:48
AString GetOwnerTexture(void) const
Returns the texture of the mob head.
Definition: MobHeadEntity.h:54
AString GetOwnerName(void) const
Returns the player name of the mob head.
Definition: MobHeadEntity.h:51
AString GetOwnerTextureSignature(void) const
Returns the texture signature of the mob head.
Definition: MobHeadEntity.h:57
eMobHeadType GetType(void) const
Returns the type of the mob head.
Definition: MobHeadEntity.h:45
cUUID GetOwnerUUID(void) const
Returns the player UUID of the mob head.
Definition: MobHeadEntity.h:68
short GetSpawnDelay(void) const
short GetRequiredPlayerRange(void) const
short GetMaxSpawnDelay(void) const
short GetSpawnRange(void) const
short GetMinSpawnDelay(void) const
short GetSpawnCount(void) const
eMonsterType GetEntity(void) const
short GetMaxNearbyEntities(void) const
unsigned char GetNote(void)
Definition: NoteEntity.cpp:261
AString GetLine(size_t a_Index) const
Retrieves individual line (zero-based index)
Definition: SignEntity.cpp:74
static constexpr NIBBLETYPE DefaultMetaValue
Definition: ChunkData.h:63
static constexpr size_t SectionMetaCount
Definition: ChunkData.h:60
static constexpr NIBBLETYPE DefaultSkyLightValue
Definition: ChunkData.h:104
static constexpr NIBBLETYPE DefaultBlockLightValue
Definition: ChunkData.h:103
static constexpr size_t SectionLightCount
Definition: ChunkData.h:101
A simple implementation of the cChunkDataCallback interface that just copies the cChunkData.
Wraps the chunk coords into a single structure.
Definition: ChunkDef.h:57
int m_ChunkZ
Definition: ChunkDef.h:60
int m_ChunkX
Definition: ChunkDef.h:59
HEIGHTTYPE HeightMap[Width *Width]
The type used for any heightmap operations and storage; idx = x + Width * z; Height points to the hig...
Definition: ChunkDef.h:132
static const int Width
Definition: ChunkDef.h:124
static HEIGHTTYPE GetHeight(const HeightMap &a_HeightMap, int a_X, int a_Z)
Definition: ChunkDef.h:303
EMCSBiome BiomeMap[Width *Width]
The type used for any biomemap operations and storage inside Cuberite, using Cuberite biomes (need no...
Definition: ChunkDef.h:137
bool IsEmpty(void) const
Returns true if there are no enchantments.
Definition: Boat.h:20
static AString MaterialToString(const eMaterial a_Material)
Returns the eMaterial as string.
Definition: Boat.cpp:275
eMaterial GetMaterial(void) const
Returns the eMaterial of the boat.
Definition: Boat.h:61
Vector3i GetBeamTarget() const
Definition: EnderCrystal.h:26
bool DisplaysBeam() const
If the EnderCrystal should send it's beam to the client and save it.
Definition: EnderCrystal.h:30
bool ShowsBottom() const
Definition: EnderCrystal.h:33
Definition: Entity.h:76
double GetSpeedZ(void) const
Definition: Entity.h:204
double GetSpeedY(void) const
Definition: Entity.h:203
double GetPosX(void) const
Definition: Entity.h:195
double GetPosZ(void) const
Definition: Entity.h:197
eEntityType GetEntityType(void) const
Definition: Entity.h:156
double GetPitch(void) const
Definition: Entity.h:199
bool IsLeashKnot(void) const
Definition: Entity.h:172
double GetPosY(void) const
Definition: Entity.h:196
double GetYaw(void) const
Definition: Entity.h:198
float GetHealth(void) const
Returns the health of this entity.
Definition: Entity.h:367
const Vector3d & GetPosition(void) const
Exported in ManualBindings.
Definition: Entity.h:297
@ etPickup
Definition: Entity.h:93
@ etProjectile
Definition: Entity.h:99
@ etItemFrame
Definition: Entity.h:102
@ etMinecart
Definition: Entity.h:96
@ etFallingBlock
Definition: Entity.h:95
@ etExpOrb
Definition: Entity.h:100
@ etPainting
Definition: Entity.h:103
@ etEnderCrystal
Definition: Entity.h:91
@ etMonster
Definition: Entity.h:94
@ etFloater
Definition: Entity.h:101
@ etLeashKnot
Definition: Entity.h:104
@ etBoat
Definition: Entity.h:97
@ etTNT
Definition: Entity.h:98
@ etPlayer
Definition: Entity.h:92
double GetSpeedX(void) const
Definition: Entity.h:202
Definition: ExpOrb.h:13
int GetReward(void) const
Get the exp amount.
Definition: ExpOrb.h:40
int GetAge(void) const
Returns the number of ticks that this entity has existed.
Definition: ExpOrb.h:34
NIBBLETYPE GetBlockMeta(void) const
Definition: FallingBlock.h:29
BLOCKTYPE GetBlockType(void) const
Definition: FallingBlock.h:28
Byte GetProtocolFacing() const
Returns the direction in which the entity is facing.
Definition: HangingEntity.h:28
Byte GetItemRotation(void) const
Returns the rotation from the item in the frame.
Definition: ItemFrame.h:33
const cItem & GetItem(void) const
Returns the item in the frame.
Definition: ItemFrame.h:27
@ mpHopper
Definition: Minecart.h:35
@ mpNone
Definition: Minecart.h:31
@ mpChest
Definition: Minecart.h:32
@ mpFurnace
Definition: Minecart.h:33
ePayload GetPayload(void) const
Definition: Minecart.h:47
const cItem & GetSlot(int a_Idx) const
Definition: Minecart.h:145
const AString & GetName(void) const
Returns the protocol name of the painting.
Definition: Painting.h:25
Definition: Pickup.h:20
cItem & GetItem(void)
Definition: Pickup.h:31
int GetAge(void) const
Returns the number of ticks that this entity has existed.
Definition: Pickup.h:51
bool IsInGround(void) const
Returns true if the projectile has hit the ground and is stuck there.
AString GetCreatorName(void) const
Returns the name of the player that created the projectile Will be empty for non-player creators.
AString GetMCAClassName(void) const
Returns the string that is used as the entity type (class name) in MCA files.
eKind GetProjectileKind(void) const
Returns the kind of the projectile (fast class identification)
unsigned GetFuseTicks(void) const
Returns the fuse ticks until the tnt will explode.
Definition: TNTEntity.h:34
Definition: Item.h:37
cEnchantments m_Enchantments
Definition: Item.h:166
char m_ItemCount
Definition: Item.h:164
AString m_CustomName
Definition: Item.h:167
AStringVector m_LoreTable
Definition: Item.h:171
short m_ItemType
Definition: Item.h:163
int m_RepairCost
Definition: Item.h:200
cFireworkItem m_FireworkItem
Definition: Item.h:201
short m_ItemDamage
Definition: Item.h:165
const cItem & GetSlot(int a_X, int a_Y) const
Definition: ItemGrid.cpp:96
int GetNumSlots(void) const
Definition: ItemGrid.h:40
Definition: Bat.h:12
BLOCKTYPE GetCarriedBlock(void) const
Definition: Enderman.h:27
NIBBLETYPE GetCarriedMeta(void) const
Definition: Enderman.h:28
Definition: Horse.h:14
bool IsTame(void) const override
Definition: Horse.h:35
bool IsEating(void) const
Definition: Horse.h:32
bool IsChested(void) const
Definition: Horse.h:31
int GetHorseArmour(void) const
Definition: Horse.cpp:233
bool IsSaddled(void) const
Definition: Horse.h:30
int GetHorseType(void) const
Definition: Horse.h:36
int GetHorseStyle(void) const
Definition: Horse.h:38
int GetHorseColor(void) const
Definition: Horse.h:37
int GetSize(void) const
Definition: MagmaCube.h:21
const AString & GetCustomName(void) const
Gets the custom name of the monster.
Definition: Monster.h:168
float GetDropChanceChestplate()
Definition: Monster.h:133
float GetDropChanceHelmet()
Definition: Monster.h:132
Vector3d * GetLeashToPos() const
Gets entity position to where mob should be leashed.
Definition: Monster.h:106
bool IsCustomNameAlwaysVisible(void) const
Is the custom name of this monster always visible? If not, you only see the name when you sight the m...
Definition: Monster.h:175
bool IsLeashed() const
Returns whether the monster is leashed to an entity.
Definition: Monster.h:86
float GetDropChanceWeapon()
Definition: Monster.h:131
eMonsterType GetMobType(void) const
Definition: Monster.h:70
bool CanPickUpLoot()
Definition: Monster.h:136
cEntity * GetLeashedTo() const
Returns the entity to where this mob is leashed, returns nullptr if it's not leashed.
Definition: Monster.h:95
float GetDropChanceBoots()
Definition: Monster.h:135
float GetDropChanceLeggings()
Definition: Monster.h:134
int GetAge(void) const
Definition: Monster.h:157
Definition: Ocelot.h:13
Definition: Pig.h:12
Definition: Rabbit.h:27
Definition: Sheep.h:12
bool IsSheared(void) const
Definition: Sheep.h:39
int GetFurColor(void) const
Definition: Sheep.h:42
Definition: Slime.h:12
int GetSize(void) const
Definition: Slime.h:27
int GetVilType(void) const
Definition: Villager.h:94
cItemGrid & GetInventory(void)
Returns the villager hidden inventory (8 slots).
Definition: Villager.h:43
Definition: Wither.h:12
Definition: Wolf.h:14
cUUID GetOwnerUUID(void) const
Definition: Wolf.h:36
AString GetOwnerName(void) const
Definition: Wolf.h:35
bool IsSitting(void) const override
Definition: Wolf.h:31
bool IsAngry(void) const
Definition: Wolf.h:34
int GetCollarColor(void) const
Definition: Wolf.h:37
Definition: Zombie.h:11
cVillager::eVillagerType GetProfession(void) const
int ConversionTime(void) const
AString ToShortString() const
Converts the UUID to a short form string (i.e without dashes).
Definition: UUID.cpp:133
bool IsNil() const
Returns true if this contains the "nil" UUID with all bits set to 0.
Definition: UUID.h:30
T x
Definition: Vector3.h:17
T y
Definition: Vector3.h:17
T z
Definition: Vector3.h:17
Definition: World.h:53
bool GetChunkData(cChunkCoords a_Coords, cChunkDataCallback &a_Callback) const
Calls the callback with the chunk's data, if available (with ChunkCS locked).
Definition: World.cpp:2202
void AddByteArray(const AString &a_Name, const char *a_Value, size_t a_NumElements)
Definition: FastNBT.cpp:628
void AddByte(const AString &a_Name, unsigned char a_Value)
Definition: FastNBT.cpp:551
void AddDouble(const AString &a_Name, double a_Value)
Definition: FastNBT.cpp:605
void AddShort(const AString &a_Name, Int16 a_Value)
Definition: FastNBT.cpp:561
void AddInt(const AString &a_Name, Int32 a_Value)
Definition: FastNBT.cpp:572
void AddString(const AString &a_Name, std::string_view a_Value)
Definition: FastNBT.cpp:616
void EndList(void)
Definition: FastNBT.cpp:536
void BeginList(const AString &a_Name, eTagType a_ChildrenType)
Definition: FastNBT.cpp:512
void AddFloat(const AString &a_Name, float a_Value)
Definition: FastNBT.cpp:594
void AddIntArray(const AString &a_Name, const Int32 *a_Value, size_t a_NumElements)
Definition: FastNBT.cpp:652
void EndCompound(void)
Definition: FastNBT.cpp:499
void BeginCompound(const AString &a_Name)
Definition: FastNBT.cpp:481
static void WriteToNBTCompound(const cFireworkItem &a_FireworkItem, cFastNBTWriter &a_Writer, const ENUM_ITEM_TYPE a_Type)
Writes firework NBT data to a Writer object.
Collects and stores the chunk data via the cChunkDataCallback interface.
void AddItemFrameEntity(cItemFrame *a_ItemFrame)
void AddEnderCrystalEntity(cEnderCrystal *a_EnderCrystal)
void AddCommandBlockEntity(cCommandBlockEntity *a_CmdBlock)
bool mIsTagOpen
True if a tag has been opened in the callbacks and not yet closed.
void AddPickupEntity(cPickup *a_Pickup)
void AddMinecartEntity(cMinecart *a_Minecart)
void AddBeaconEntity(cBeaconEntity *a_Entity)
void AddFallingBlockEntity(cFallingBlock *a_FallingBlock)
void AddBrewingstandEntity(cBrewingstandEntity *a_Brewingstand)
virtual void Entity(cEntity *a_Entity) override
void AddEnderchestEntity(cEnderChestEntity *a_Entity)
void AddNoteEntity(cNoteEntity *a_Note)
void AddChestEntity(cChestEntity *a_Entity, BLOCKTYPE a_ChestType)
void AddPaintingEntity(cPainting *a_Painting)
void AddMinecartChestContents(cMinecartWithChest *a_Minecart)
void AddLeashKnotEntity(cLeashKnot *a_LeashKnot)
void AddFlowerPotEntity(cFlowerPotEntity *a_FlowerPot)
void AddDispenserEntity(cDispenserEntity *a_Entity)
void AddJukeboxEntity(cJukeboxEntity *a_Jukebox)
void AddBedEntity(cBedEntity *a_Entity)
void AddTNTEntity(cTNTEntity *a_TNT)
bool mIsLightValid
True if the chunk lighting is valid.
void AddDropperEntity(cDropperEntity *a_Entity)
void AddItem(const cItem &a_Item, int a_Slot, const AString &a_CompoundName=AString())
Writes an item into the writer.
void AddBasicTileEntity(cBlockEntity *a_Entity, const char *a_EntityTypeID)
bool mHasHadBlockEntity
True if any BlockEntity has already been received and processed.
int Heights[cChunkDef::Width *cChunkDef::Width]
virtual void BiomeMap(const cChunkDef::BiomeMap &a_BiomeMap) override
void AddMobSpawnerEntity(cMobSpawnerEntity *a_MobSpawner)
void AddItemGrid(const cItemGrid &a_Grid, int a_BeginSlotNum=0)
Writes an item grid into the writer.
void AddBasicEntity(cEntity *a_Entity, const std::string_view a_ClassName)
void AddHangingEntity(cHangingEntity *a_Hanging)
void AddMonsterEntity(cMonster *a_Monster)
cFastNBTWriter & mWriter
The NBT writer used to store the data.
virtual void HeightMap(const cChunkDef::HeightMap &a_HeightMap) override
void AddMobHeadEntity(cMobHeadEntity *a_MobHead)
void AddFurnaceEntity(cFurnaceEntity *a_Furnace)
void AddProjectileEntity(cProjectileEntity *a_Projectile)
void AddBoatEntity(cBoat *a_Boat)
void AddSignEntity(cSignEntity *a_Sign)
UInt8 Biomes[cChunkDef::Width *cChunkDef::Width]
void AddExpOrbEntity(cExpOrb *a_ExpOrb)
void AddHopperEntity(cHopperEntity *a_Entity)
void AddBannerEntity(cBannerEntity *a_Entity)
void AddEnchantingTableEntity(cEnchantingTableEntity *a_Entity)
bool mHasHadEntity
True if any Entity has already been received and processed.
virtual void LightIsValid(bool a_IsLightValid) override
void AddEndPortalEntity(cEndPortalEntity *a_Entity)
virtual void BlockEntity(cBlockEntity *a_Entity) override
SerializerCollector(cFastNBTWriter &aWriter)
static void Serialize(const cWorld &aWorld, cChunkCoords aCoords, cFastNBTWriter &aWriter)
Serializes the chunk into the specified writer.