From b18f6637b6c58db20353cd3e77584b646ab36b5c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pablo=20Beltr=C3=A1n?= Date: Mon, 21 Aug 2017 10:46:41 +0200 Subject: Fully implemented leashes (#3798) --- src/WorldStorage/NBTChunkSerializer.cpp | 38 +++++++++++++++- src/WorldStorage/NBTChunkSerializer.h | 2 + src/WorldStorage/WSSAnvil.cpp | 77 +++++++++++++++++++++++++++++++++ src/WorldStorage/WSSAnvil.h | 4 ++ 4 files changed, 119 insertions(+), 2 deletions(-) (limited to 'src/WorldStorage') diff --git a/src/WorldStorage/NBTChunkSerializer.cpp b/src/WorldStorage/NBTChunkSerializer.cpp index 480558fa3..62f981eb4 100644 --- a/src/WorldStorage/NBTChunkSerializer.cpp +++ b/src/WorldStorage/NBTChunkSerializer.cpp @@ -37,6 +37,7 @@ #include "../Entities/ExpOrb.h" #include "../Entities/HangingEntity.h" #include "../Entities/ItemFrame.h" +#include "../Entities/LeashKnot.h" #include "../Entities/Painting.h" #include "../Mobs/IncludeAllMonsters.h" @@ -574,6 +575,33 @@ void cNBTChunkSerializer::AddMonsterEntity(cMonster * a_Monster) m_Writer.AddByte("CanPickUpLoot", (a_Monster->CanPickUpLoot())? 1 : 0); m_Writer.AddString("CustomName", a_Monster->GetCustomName()); m_Writer.AddByte("CustomNameVisible", static_cast(a_Monster->IsCustomNameAlwaysVisible())); + + // Mob was leashed + if (a_Monster->IsLeashed() || (a_Monster->GetLeashToPos() != nullptr)) + { + m_Writer.AddByte("Leashed", 1); + + const Vector3d * LeashedToPos = nullptr; + + if (a_Monster->GetLeashToPos() != nullptr) + { + LeashedToPos = a_Monster->GetLeashToPos(); + } + else if (a_Monster->GetLeashedTo()->IsLeashKnot()) + { + LeashedToPos = & a_Monster->GetLeashedTo()->GetPosition(); + } + + if (LeashedToPos != nullptr) + { + m_Writer.BeginCompound("Leash"); + m_Writer.AddDouble("X", LeashedToPos->x); + m_Writer.AddDouble("Y", LeashedToPos->y); + m_Writer.AddDouble("Z", LeashedToPos->z); + m_Writer.EndCompound(); + } + } + switch (a_Monster->GetMobType()) { case mtBat: @@ -850,8 +878,13 @@ void cNBTChunkSerializer::AddItemFrameEntity(cItemFrame * a_ItemFrame) m_Writer.EndCompound(); } - - +void cNBTChunkSerializer::AddLeashKnotEntity(cLeashKnot * a_LeashKnot) +{ + m_Writer.BeginCompound(""); + AddBasicEntity(a_LeashKnot, "LeashKnot"); + AddHangingEntity(a_LeashKnot); + m_Writer.EndCompound(); +} void cNBTChunkSerializer::AddPaintingEntity(cPainting * a_Painting) @@ -965,6 +998,7 @@ void cNBTChunkSerializer::Entity(cEntity * a_Entity) case cEntity::etTNT: AddTNTEntity (reinterpret_cast (a_Entity)); break; case cEntity::etExpOrb: AddExpOrbEntity (reinterpret_cast (a_Entity)); break; case cEntity::etItemFrame: AddItemFrameEntity (reinterpret_cast (a_Entity)); break; + case cEntity::etLeashKnot: AddLeashKnotEntity (reinterpret_cast (a_Entity)); break; case cEntity::etPainting: AddPaintingEntity (reinterpret_cast (a_Entity)); break; case cEntity::etPlayer: return; // Players aren't saved into the world case cEntity::etFloater: return; // Floaters aren't saved either diff --git a/src/WorldStorage/NBTChunkSerializer.h b/src/WorldStorage/NBTChunkSerializer.h index a55e519a7..3637ea655 100644 --- a/src/WorldStorage/NBTChunkSerializer.h +++ b/src/WorldStorage/NBTChunkSerializer.h @@ -47,6 +47,7 @@ class cTNTEntity; class cExpOrb; class cHangingEntity; class cItemFrame; +class cLeashKnot; class cPainting; @@ -123,6 +124,7 @@ protected: void AddTNTEntity (cTNTEntity * a_TNT); void AddExpOrbEntity (cExpOrb * a_ExpOrb); void AddItemFrameEntity (cItemFrame * a_ItemFrame); + void AddLeashKnotEntity (cLeashKnot * a_LeashKnot); void AddPaintingEntity (cPainting * a_Painting); void AddMinecartChestContents(cMinecartWithChest * a_Minecart); diff --git a/src/WorldStorage/WSSAnvil.cpp b/src/WorldStorage/WSSAnvil.cpp index 77d1e46b8..7aa3eb0cd 100755 --- a/src/WorldStorage/WSSAnvil.cpp +++ b/src/WorldStorage/WSSAnvil.cpp @@ -50,10 +50,12 @@ #include "../Entities/ExpOrb.h" #include "../Entities/HangingEntity.h" #include "../Entities/ItemFrame.h" +#include "../Entities/LeashKnot.h" #include "../Entities/Painting.h" #include "../Protocol/MojangAPI.h" #include "Server.h" +#include "BoundingBox.h" @@ -1540,6 +1542,8 @@ void cWSSAnvil::LoadEntityFromNBT(cEntityList & a_Entities, const cParsedNBT & a { "minecraft:xp_orb", &cWSSAnvil::LoadExpOrbFromNBT }, { "ItemFrame", &cWSSAnvil::LoadItemFrameFromNBT }, { "minecraft:item_frame", &cWSSAnvil::LoadItemFrameFromNBT }, + { "LeashKnot", &cWSSAnvil::LoadLeashKnotFromNBT }, + { "minecraft:leash_knot", &cWSSAnvil::LoadLeashKnotFromNBT }, { "Arrow", &cWSSAnvil::LoadArrowFromNBT }, { "minecraft:arrow", &cWSSAnvil::LoadArrowFromNBT }, { "SplashPotion", &cWSSAnvil::LoadSplashPotionFromNBT }, @@ -1958,6 +1962,24 @@ void cWSSAnvil::LoadItemFrameFromNBT(cEntityList & a_Entities, const cParsedNBT +void cWSSAnvil::LoadLeashKnotFromNBT(cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx) +{ + auto LeashKnot = cpp14::make_unique(BLOCK_FACE_NONE, 0.0, 0.0, 0.0); + + if (!LoadEntityBaseFromNBT(*LeashKnot.get(), a_NBT, a_TagIdx)) + { + return; + } + + LoadHangingFromNBT(*LeashKnot.get(), a_NBT, a_TagIdx); + + a_Entities.emplace_back(std::move(LeashKnot)); +} + + + + + void cWSSAnvil::LoadPaintingFromNBT(cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx) { // Load painting name: @@ -3182,6 +3204,13 @@ bool cWSSAnvil::LoadMonsterBaseFromNBT(cMonster & a_Monster, const cParsedNBT & a_Monster.SetCustomNameAlwaysVisible(CustomNameVisible); } + // Leashed to a knot + int LeashedIdx = a_NBT.FindChildByName(a_TagIdx, "Leashed"); + if ((LeashedIdx >= 0) && a_NBT.GetByte(LeashedIdx)) + { + LoadLeashToPosition(a_Monster, a_NBT, a_TagIdx); + } + return true; } @@ -3189,6 +3218,54 @@ bool cWSSAnvil::LoadMonsterBaseFromNBT(cMonster & a_Monster, const cParsedNBT & +void cWSSAnvil::LoadLeashToPosition(cMonster & a_Monster, const cParsedNBT & a_NBT, int a_TagIdx) +{ + int LeashIdx = a_NBT.FindChildByName(a_TagIdx, "Leash"); + if (LeashIdx < 0) + { + return; + } + + double PosX = 0.0, PosY = 0.0, PosZ = 0.0; + bool KnotPosPresent = true; + int LeashDataLine = a_NBT.FindChildByName(LeashIdx, "X"); + if (LeashDataLine >= 0) + { + PosX = a_NBT.GetDouble(LeashDataLine); + } + else + { + KnotPosPresent = false; + } + LeashDataLine = a_NBT.FindChildByName(LeashIdx, "Y"); + if (LeashDataLine >= 0) + { + PosY = a_NBT.GetDouble(LeashDataLine); + } + else + { + KnotPosPresent = false; + } + LeashDataLine = a_NBT.FindChildByName(LeashIdx, "Z"); + if (LeashDataLine >= 0) + { + PosZ = a_NBT.GetDouble(LeashDataLine); + } + else + { + KnotPosPresent = false; + } + if (KnotPosPresent) + { + // Set leash pos for the mob + a_Monster.SetLeashToPos(new Vector3d(PosX, PosY, PosZ)); + } +} + + + + + bool cWSSAnvil::LoadProjectileBaseFromNBT(cProjectileEntity & a_Entity, const cParsedNBT & a_NBT, int a_TagIdx) { if (!LoadEntityBaseFromNBT(a_Entity, a_NBT, a_TagIdx)) diff --git a/src/WorldStorage/WSSAnvil.h b/src/WorldStorage/WSSAnvil.h index 454e6f73d..a53d8d8c4 100755 --- a/src/WorldStorage/WSSAnvil.h +++ b/src/WorldStorage/WSSAnvil.h @@ -179,6 +179,7 @@ protected: void LoadExpOrbFromNBT (cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx); void LoadHangingFromNBT (cHangingEntity & a_Hanging, const cParsedNBT & a_NBT, int a_TagIdx); void LoadItemFrameFromNBT (cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx); + void LoadLeashKnotFromNBT (cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx); void LoadPaintingFromNBT (cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx); void LoadOldMinecartFromNBT (cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx); @@ -238,6 +239,9 @@ protected: /** Loads monster common data from the NBT compound; returns true if successful */ bool LoadMonsterBaseFromNBT(cMonster & a_Monster, const cParsedNBT & a_NBT, int a_TagIdx); + /** Loads the position to where is leashed the monster */ + void LoadLeashToPosition(cMonster & a_Monster, const cParsedNBT & a_NBT, int a_TagIdx); + /** Loads projectile common data from the NBT compound; returns true if successful */ bool LoadProjectileBaseFromNBT(cProjectileEntity & a_Entity, const cParsedNBT & a_NBT, int a_TagIx); -- cgit v1.2.3