From 60bcc06f43e0c249204149153976e534b239d138 Mon Sep 17 00:00:00 2001 From: Mat Date: Sat, 4 Apr 2020 14:44:17 +0300 Subject: Implement wither skeletons (#4563) --- src/WorldStorage/NBTChunkSerializer.cpp | 70 ++++++++++++++++----------------- src/WorldStorage/WSSAnvil.cpp | 37 ++++++++++++++--- src/WorldStorage/WSSAnvil.h | 1 + 3 files changed, 67 insertions(+), 41 deletions(-) (limited to 'src/WorldStorage') diff --git a/src/WorldStorage/NBTChunkSerializer.cpp b/src/WorldStorage/NBTChunkSerializer.cpp index 014ee2c27..3e8994786 100644 --- a/src/WorldStorage/NBTChunkSerializer.cpp +++ b/src/WorldStorage/NBTChunkSerializer.cpp @@ -710,37 +710,38 @@ public: const char * EntityClass = nullptr; switch (a_Monster->GetMobType()) { - case mtBat: EntityClass = "Bat"; break; - case mtBlaze: EntityClass = "Blaze"; break; - case mtCaveSpider: EntityClass = "CaveSpider"; break; - case mtChicken: EntityClass = "Chicken"; break; - case mtCow: EntityClass = "Cow"; break; - case mtCreeper: EntityClass = "Creeper"; break; - case mtEnderDragon: EntityClass = "EnderDragon"; break; - case mtEnderman: EntityClass = "Enderman"; break; - case mtGhast: EntityClass = "Ghast"; break; - case mtGiant: EntityClass = "Giant"; break; - case mtGuardian: EntityClass = "Guardian"; break; - case mtHorse: EntityClass = "Horse"; break; - case mtIronGolem: EntityClass = "VillagerGolem"; break; - case mtMagmaCube: EntityClass = "LavaSlime"; break; - case mtMooshroom: EntityClass = "MushroomCow"; break; - case mtOcelot: EntityClass = "Ozelot"; break; - case mtPig: EntityClass = "Pig"; break; - case mtRabbit: EntityClass = "Rabbit"; break; - case mtSheep: EntityClass = "Sheep"; break; - case mtSilverfish: EntityClass = "Silverfish"; break; - case mtSkeleton: EntityClass = "Skeleton"; break; - case mtSlime: EntityClass = "Slime"; break; - case mtSnowGolem: EntityClass = "SnowMan"; break; - case mtSpider: EntityClass = "Spider"; break; - case mtSquid: EntityClass = "Squid"; break; - case mtVillager: EntityClass = "Villager"; break; - case mtWitch: EntityClass = "Witch"; break; - case mtWither: EntityClass = "WitherBoss"; break; - case mtWolf: EntityClass = "Wolf"; break; - case mtZombie: EntityClass = "Zombie"; break; - case mtZombiePigman: EntityClass = "PigZombie"; break; + case mtBat: EntityClass = "Bat"; break; + case mtBlaze: EntityClass = "Blaze"; break; + case mtCaveSpider: EntityClass = "CaveSpider"; break; + case mtChicken: EntityClass = "Chicken"; break; + case mtCow: EntityClass = "Cow"; break; + case mtCreeper: EntityClass = "Creeper"; break; + case mtEnderDragon: EntityClass = "EnderDragon"; break; + case mtEnderman: EntityClass = "Enderman"; break; + case mtGhast: EntityClass = "Ghast"; break; + case mtGiant: EntityClass = "Giant"; break; + case mtGuardian: EntityClass = "Guardian"; break; + case mtHorse: EntityClass = "Horse"; break; + case mtIronGolem: EntityClass = "VillagerGolem"; break; + case mtMagmaCube: EntityClass = "LavaSlime"; break; + case mtMooshroom: EntityClass = "MushroomCow"; break; + case mtOcelot: EntityClass = "Ozelot"; break; + case mtPig: EntityClass = "Pig"; break; + case mtRabbit: EntityClass = "Rabbit"; break; + case mtSheep: EntityClass = "Sheep"; break; + case mtSilverfish: EntityClass = "Silverfish"; break; + case mtSkeleton: EntityClass = "Skeleton"; break; + case mtSlime: EntityClass = "Slime"; break; + case mtSnowGolem: EntityClass = "SnowMan"; break; + case mtSpider: EntityClass = "Spider"; break; + case mtSquid: EntityClass = "Squid"; break; + case mtVillager: EntityClass = "Villager"; break; + case mtWitch: EntityClass = "Witch"; break; + case mtWither: EntityClass = "WitherBoss"; break; + case mtWitherSkeleton: EntityClass = "WitherSkeleton"; break; + case mtWolf: EntityClass = "Wolf"; break; + case mtZombie: EntityClass = "Zombie"; break; + case mtZombiePigman: EntityClass = "PigZombie"; break; default: { ASSERT(!"Unhandled monster type"); @@ -869,11 +870,6 @@ public: mWriter.AddInt("Size", static_cast(a_Monster)->GetSize()); break; } - case mtSkeleton: - { - mWriter.AddByte("SkeletonType", (static_cast(a_Monster)->IsWither() ? 1 : 0)); - break; - } case mtVillager: { const cVillager *Villager = static_cast(a_Monster); @@ -927,10 +923,12 @@ public: case mtIronGolem: case mtMooshroom: case mtSilverfish: + case mtSkeleton: case mtSnowGolem: case mtSpider: case mtSquid: case mtWitch: + case mtWitherSkeleton: { // Other mobs have no special tags. break; diff --git a/src/WorldStorage/WSSAnvil.cpp b/src/WorldStorage/WSSAnvil.cpp index 65facd817..31934e181 100755 --- a/src/WorldStorage/WSSAnvil.cpp +++ b/src/WorldStorage/WSSAnvil.cpp @@ -1560,6 +1560,8 @@ void cWSSAnvil::LoadEntityFromNBT(cEntityList & a_Entities, const cParsedNBT & a { "minecraft:witch", &cWSSAnvil::LoadWitchFromNBT }, { "WitherBoss", &cWSSAnvil::LoadWitherFromNBT }, { "minecraft:wither", &cWSSAnvil::LoadWitherFromNBT }, + { "WitherSkeleton", &cWSSAnvil::LoadWitherSkeletonFromNBT }, + { "minecraft:wither_skeleton", &cWSSAnvil::LoadWitherSkeletonFromNBT }, { "Wolf", &cWSSAnvil::LoadWolfFromNBT }, { "minecraft:wolf", &cWSSAnvil::LoadWolfFromNBT }, { "Zombie", &cWSSAnvil::LoadZombieFromNBT }, @@ -2660,15 +2662,20 @@ void cWSSAnvil::LoadSilverfishFromNBT(cEntityList & a_Entities, const cParsedNBT void cWSSAnvil::LoadSkeletonFromNBT(cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx) { + // Wither skeleton is a separate mob in Minecraft 1.11+, but we need this to + // load them from older worlds where wither skeletons were only a skeleton with a flag int TypeIdx = a_NBT.FindChildByName(a_TagIdx, "SkeletonType"); - if (TypeIdx < 0) + + std::unique_ptr Monster; + if ((TypeIdx > 0) && (a_NBT.GetByte(TypeIdx) == 1)) { - return; + Monster = cpp14::make_unique(); + } + else + { + Monster = cpp14::make_unique(); } - bool Type = ((a_NBT.GetByte(TypeIdx) == 1) ? true : false); - - std::unique_ptr Monster = cpp14::make_unique(Type); if (!LoadEntityBaseFromNBT(*Monster.get(), a_NBT, a_TagIdx)) { return; @@ -2863,6 +2870,26 @@ void cWSSAnvil::LoadWitherFromNBT(cEntityList & a_Entities, const cParsedNBT & a +void cWSSAnvil::LoadWitherSkeletonFromNBT(cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx) +{ + auto Monster = cpp14::make_unique(); + if (!LoadEntityBaseFromNBT(*Monster.get(), a_NBT, a_TagIdx)) + { + return; + } + + if (!LoadMonsterBaseFromNBT(*Monster.get(), a_NBT, a_TagIdx)) + { + return; + } + + a_Entities.emplace_back(std::move(Monster)); +} + + + + + void cWSSAnvil::LoadWolfFromNBT(cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx) { std::unique_ptr Monster = cpp14::make_unique(); diff --git a/src/WorldStorage/WSSAnvil.h b/src/WorldStorage/WSSAnvil.h index 949ff61ff..e6b3e5ee9 100755 --- a/src/WorldStorage/WSSAnvil.h +++ b/src/WorldStorage/WSSAnvil.h @@ -228,6 +228,7 @@ protected: void LoadVillagerFromNBT (cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx); void LoadWitchFromNBT (cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx); void LoadWitherFromNBT (cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx); + void LoadWitherSkeletonFromNBT (cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx); void LoadWolfFromNBT (cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx); void LoadZombieFromNBT (cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx); void LoadPigZombieFromNBT (cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx); -- cgit v1.2.3