Add Zombie Villagers
This commit is contained in:
parent
df8d7332d0
commit
8438def87e
@ -9306,6 +9306,10 @@ a_Player:OpenWindow(Window);
|
||||
{
|
||||
Notes = "",
|
||||
},
|
||||
mtZombieVillager =
|
||||
{
|
||||
Notes = "",
|
||||
},
|
||||
},
|
||||
ConstantGroups =
|
||||
{
|
||||
@ -17065,6 +17069,7 @@ end
|
||||
"mtWolf",
|
||||
"mtZombie",
|
||||
"mtZombiePigman",
|
||||
"mtZombieVillager",
|
||||
"mtMax",
|
||||
},
|
||||
TextBefore = [[
|
||||
|
@ -220,3 +220,10 @@ AttackRate=1.0
|
||||
IsFireproof=1
|
||||
MaxHealth=20
|
||||
SightDistance=25.0
|
||||
|
||||
[ZombieVillager]
|
||||
AttackDamage=4.0
|
||||
AttackRange=2.0
|
||||
AttackRate=1.0
|
||||
MaxHealth=20
|
||||
SightDistance=25.0
|
||||
|
@ -16,37 +16,38 @@ struct
|
||||
const char * String;
|
||||
} g_EntityTypes[] =
|
||||
{
|
||||
{entBat, "Bat"},
|
||||
{entBlaze, "Blaze"},
|
||||
{entCaveSpider, "CaveSpider"},
|
||||
{entChicken, "Chicken"},
|
||||
{entCow, "Cow"},
|
||||
{entCreeper, "Creeper"},
|
||||
{entEnderDragon, "EnderDragon"},
|
||||
{entEnderman, "Enderman"},
|
||||
{entGhast, "Ghast"},
|
||||
{entGiant, "Giant"},
|
||||
{entGuardian, "Guardian"},
|
||||
{entLavaSlime, "LavaSlime"},
|
||||
{entMushroomCow, "MushroomCow"},
|
||||
{entOzelot, "Ozelot"},
|
||||
{entPig, "Pig"},
|
||||
{entPigZombie, "PigZombie"},
|
||||
{entRabbit, "Rabbit"},
|
||||
{entSheep, "Sheep"},
|
||||
{entSilverfish, "Slverfish"},
|
||||
{entSkeleton, "Skeleton"},
|
||||
{entSlime, "Slime"},
|
||||
{entSnowMan, "SnowMan"},
|
||||
{entSpider, "Spider"},
|
||||
{entSquid, "Squid"},
|
||||
{entVillager, "Villager"},
|
||||
{entVillagerGolem, "VillagerGolem"},
|
||||
{entWitch, "Witch"},
|
||||
{entWitherBoss, "WitherBoss"},
|
||||
{entWolf, "Wolf"},
|
||||
{entZombie, "Zombie"},
|
||||
{entUnknown, "Unknown"},
|
||||
{entBat, "Bat"},
|
||||
{entBlaze, "Blaze"},
|
||||
{entCaveSpider, "CaveSpider"},
|
||||
{entChicken, "Chicken"},
|
||||
{entCow, "Cow"},
|
||||
{entCreeper, "Creeper"},
|
||||
{entEnderDragon, "EnderDragon"},
|
||||
{entEnderman, "Enderman"},
|
||||
{entGhast, "Ghast"},
|
||||
{entGiant, "Giant"},
|
||||
{entGuardian, "Guardian"},
|
||||
{entLavaSlime, "LavaSlime"},
|
||||
{entMushroomCow, "MushroomCow"},
|
||||
{entOzelot, "Ozelot"},
|
||||
{entPig, "Pig"},
|
||||
{entPigZombie, "PigZombie"},
|
||||
{entRabbit, "Rabbit"},
|
||||
{entSheep, "Sheep"},
|
||||
{entSilverfish, "Slverfish"},
|
||||
{entSkeleton, "Skeleton"},
|
||||
{entSlime, "Slime"},
|
||||
{entSnowMan, "SnowMan"},
|
||||
{entSpider, "Spider"},
|
||||
{entSquid, "Squid"},
|
||||
{entVillager, "Villager"},
|
||||
{entVillagerGolem, "VillagerGolem"},
|
||||
{entWitch, "Witch"},
|
||||
{entWitherBoss, "WitherBoss"},
|
||||
{entWolf, "Wolf"},
|
||||
{entZombie, "Zombie"},
|
||||
{entZombieVillager, "ZombieVillager"},
|
||||
{entUnknown, "Unknown"},
|
||||
} ;
|
||||
|
||||
|
||||
|
@ -45,6 +45,7 @@ enum eEntityType
|
||||
entWitherBoss,
|
||||
entWolf,
|
||||
entZombie,
|
||||
entZombieVillager,
|
||||
entUnknown,
|
||||
entMax = entUnknown,
|
||||
} ;
|
||||
|
@ -1079,6 +1079,7 @@ enum ENUM_ITEM_META : short
|
||||
E_META_SPAWN_EGG_PRIMED_TNT = 20,
|
||||
E_META_SPAWN_EGG_FALLING_BLOCK = 21,
|
||||
E_META_SPAWN_EGG_FIREWORK = 22,
|
||||
E_META_SPAWN_EGG_ZOMBIE_VILLAGER = 27,
|
||||
E_META_SPAWN_EGG_BOAT = 41,
|
||||
E_META_SPAWN_EGG_MINECART = 42,
|
||||
E_META_SPAWN_EGG_MINECART_CHEST = 43,
|
||||
|
@ -456,9 +456,10 @@ bool cEntity::DoTakeDamage(TakeDamageInfo & a_TDI)
|
||||
switch (Monster->GetMobType())
|
||||
{
|
||||
case mtSkeleton:
|
||||
case mtZombie:
|
||||
case mtWither:
|
||||
case mtZombie:
|
||||
case mtZombiePigman:
|
||||
case mtZombieVillager:
|
||||
{
|
||||
a_TDI.FinalDamage += 2.5f * SmiteLevel;
|
||||
break;
|
||||
|
@ -87,11 +87,8 @@ public:
|
||||
case E_META_SPAWN_EGG_WOLF: return mtWolf;
|
||||
case E_META_SPAWN_EGG_ZOMBIE: return mtZombie;
|
||||
case E_META_SPAWN_EGG_ZOMBIE_PIGMAN: return mtZombiePigman;
|
||||
case E_META_SPAWN_EGG_ZOMBIE_VILLAGER: return mtZombieVillager;
|
||||
default: return mtInvalidType;
|
||||
}
|
||||
return mtInvalidType;
|
||||
}
|
||||
} ;
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -36,7 +36,8 @@ SET (SRCS
|
||||
WitherSkeleton.cpp
|
||||
Wolf.cpp
|
||||
Zombie.cpp
|
||||
ZombiePigman.cpp)
|
||||
ZombiePigman.cpp
|
||||
ZombieVillager.cpp)
|
||||
|
||||
SET (HDRS
|
||||
AggressiveMonster.h
|
||||
@ -78,7 +79,8 @@ SET (HDRS
|
||||
WitherSkeleton.h
|
||||
Wolf.h
|
||||
Zombie.h
|
||||
ZombiePigman.h)
|
||||
ZombiePigman.h
|
||||
ZombieVillager.h)
|
||||
|
||||
if(NOT MSVC)
|
||||
add_library(Mobs ${SRCS} ${HDRS})
|
||||
|
@ -30,3 +30,4 @@
|
||||
#include "Wolf.h"
|
||||
#include "Zombie.h"
|
||||
#include "ZombiePigman.h"
|
||||
#include "ZombieVillager.h"
|
||||
|
@ -69,6 +69,7 @@ static const struct
|
||||
{mtWolf, "wolf", "Wolf", "wolf"},
|
||||
{mtZombie, "zombie", "Zombie", "zombie"},
|
||||
{mtZombiePigman, "zombiepigman", "PigZombie", "zombie_pigman"},
|
||||
{mtZombieVillager, "zombievillager", "ZombieVillager", "zombie_villager"},
|
||||
} ;
|
||||
|
||||
|
||||
@ -662,6 +663,7 @@ void cMonster::KilledBy(TakeDamageInfo & a_TDI)
|
||||
case mtWitherSkeleton:
|
||||
case mtZombie:
|
||||
case mtZombiePigman:
|
||||
case mtZombieVillager:
|
||||
case mtSlime:
|
||||
case mtMagmaCube:
|
||||
{
|
||||
@ -1078,6 +1080,7 @@ cMonster::eFamily cMonster::FamilyFromType(eMonsterType a_Type)
|
||||
case mtWolf: return mfPassive;
|
||||
case mtZombie: return mfHostile;
|
||||
case mtZombiePigman: return mfHostile;
|
||||
case mtZombieVillager: return mfHostile;
|
||||
|
||||
default:
|
||||
{
|
||||
@ -1176,17 +1179,7 @@ std::unique_ptr<cMonster> cMonster::NewMonsterFromType(eMonsterType a_MobType)
|
||||
{
|
||||
return cpp14::make_unique<cSlime>(1 << Random.RandInt(2)); // Size 1, 2 or 4
|
||||
}
|
||||
case mtVillager:
|
||||
{
|
||||
int VillagerType = Random.RandInt(6);
|
||||
if (VillagerType == 6)
|
||||
{
|
||||
// Give farmers a better chance of spawning
|
||||
VillagerType = 0;
|
||||
}
|
||||
|
||||
return cpp14::make_unique<cVillager>(static_cast<cVillager::eVillagerType>(VillagerType));
|
||||
}
|
||||
case mtVillager: return cpp14::make_unique<cVillager>(cVillager::GetRandomProfession());
|
||||
case mtHorse:
|
||||
{
|
||||
// Horses take a type (species), a colour, and a style (dots, stripes, etc.)
|
||||
@ -1203,7 +1196,10 @@ std::unique_ptr<cMonster> cMonster::NewMonsterFromType(eMonsterType a_MobType)
|
||||
|
||||
return cpp14::make_unique<cHorse>(HorseType, HorseColor, HorseStyle, HorseTameTimes);
|
||||
}
|
||||
|
||||
case mtZombieVillager:
|
||||
{
|
||||
return cpp14::make_unique<cZombieVillager>(cVillager::GetRandomProfession());
|
||||
}
|
||||
case mtBat: return cpp14::make_unique<cBat>();
|
||||
case mtBlaze: return cpp14::make_unique<cBlaze>();
|
||||
case mtCaveSpider: return cpp14::make_unique<cCaveSpider>();
|
||||
|
@ -11,6 +11,7 @@ enum eMonsterType
|
||||
{
|
||||
mtInvalidType = -1,
|
||||
|
||||
<<<<<<< HEAD
|
||||
mtBat,
|
||||
mtBlaze,
|
||||
mtCaveSpider,
|
||||
@ -43,6 +44,41 @@ enum eMonsterType
|
||||
mtWolf,
|
||||
mtZombie,
|
||||
mtZombiePigman,
|
||||
=======
|
||||
mtBat = E_META_SPAWN_EGG_BAT,
|
||||
mtBlaze = E_META_SPAWN_EGG_BLAZE,
|
||||
mtCaveSpider = E_META_SPAWN_EGG_CAVE_SPIDER,
|
||||
mtChicken = E_META_SPAWN_EGG_CHICKEN,
|
||||
mtCow = E_META_SPAWN_EGG_COW,
|
||||
mtCreeper = E_META_SPAWN_EGG_CREEPER,
|
||||
mtEnderDragon = E_META_SPAWN_EGG_ENDER_DRAGON,
|
||||
mtEnderman = E_META_SPAWN_EGG_ENDERMAN,
|
||||
mtGhast = E_META_SPAWN_EGG_GHAST,
|
||||
mtGiant = E_META_SPAWN_EGG_GIANT,
|
||||
mtGuardian = E_META_SPAWN_EGG_GUARDIAN,
|
||||
mtHorse = E_META_SPAWN_EGG_HORSE,
|
||||
mtIronGolem = E_META_SPAWN_EGG_IRON_GOLEM,
|
||||
mtMagmaCube = E_META_SPAWN_EGG_MAGMA_CUBE,
|
||||
mtMooshroom = E_META_SPAWN_EGG_MOOSHROOM,
|
||||
mtOcelot = E_META_SPAWN_EGG_OCELOT,
|
||||
mtPig = E_META_SPAWN_EGG_PIG,
|
||||
mtRabbit = E_META_SPAWN_EGG_RABBIT,
|
||||
mtSheep = E_META_SPAWN_EGG_SHEEP,
|
||||
mtSilverfish = E_META_SPAWN_EGG_SILVERFISH,
|
||||
mtSkeleton = E_META_SPAWN_EGG_SKELETON,
|
||||
mtSlime = E_META_SPAWN_EGG_SLIME,
|
||||
mtSnowGolem = E_META_SPAWN_EGG_SNOW_GOLEM,
|
||||
mtSpider = E_META_SPAWN_EGG_SPIDER,
|
||||
mtSquid = E_META_SPAWN_EGG_SQUID,
|
||||
mtVillager = E_META_SPAWN_EGG_VILLAGER,
|
||||
mtWitch = E_META_SPAWN_EGG_WITCH,
|
||||
mtWither = E_META_SPAWN_EGG_WITHER,
|
||||
mtWolf = E_META_SPAWN_EGG_WOLF,
|
||||
mtZombie = E_META_SPAWN_EGG_ZOMBIE,
|
||||
mtZombiePigman = E_META_SPAWN_EGG_ZOMBIE_PIGMAN,
|
||||
mtZombieVillager = E_META_SPAWN_EGG_ZOMBIE_VILLAGER,
|
||||
mtMax = 120, // This is just a hotfix for https://forum.cuberite.org/thread-1616.html. Tolua is too bad to find the highest value, so this is needed.
|
||||
>>>>>>> Add Zombie Villagers
|
||||
} ;
|
||||
|
||||
// tolua_end
|
||||
|
@ -107,6 +107,26 @@ void cVillager::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk)
|
||||
|
||||
|
||||
|
||||
|
||||
void cVillager::KilledBy(TakeDamageInfo & a_TDI)
|
||||
{
|
||||
super::KilledBy(a_TDI);
|
||||
|
||||
// TODO: 0% chance on Easy, 50% chance on Normal and 100% chance on Hard
|
||||
if (GetRandomProvider().RandBool(0.5) && (a_TDI.Attacker != nullptr) && (a_TDI.Attacker->IsMob()))
|
||||
{
|
||||
eMonsterType MonsterType = (static_cast<cMonster *>(a_TDI.Attacker)->GetMobType());
|
||||
if ((MonsterType == mtZombie) || (MonsterType == mtZombieVillager))
|
||||
{
|
||||
m_World->SpawnMob(GetPosX(), GetPosY(), GetPosZ(), mtZombieVillager, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Farmer functions:
|
||||
|
||||
@ -203,7 +223,17 @@ bool cVillager::IsBlockFarmable(BLOCKTYPE a_BlockType)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
default: return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
cVillager::eVillagerType cVillager::GetRandomProfession()
|
||||
{
|
||||
int Profession = GetRandomProvider().RandInt(cVillager::eVillagerType::vtMax - 1);
|
||||
|
||||
return static_cast<cVillager::eVillagerType>(Profession);
|
||||
}
|
||||
|
@ -29,9 +29,13 @@ public:
|
||||
|
||||
CLASS_PROTODEF(cVillager)
|
||||
|
||||
/** Returns a random Profession. */
|
||||
static eVillagerType GetRandomProfession();
|
||||
|
||||
// cEntity overrides
|
||||
virtual bool DoTakeDamage(TakeDamageInfo & a_TDI) override;
|
||||
virtual void Tick (std::chrono::milliseconds a_Dt, cChunk & a_Chunk) override;
|
||||
virtual void KilledBy (TakeDamageInfo & a_TDI) override;
|
||||
|
||||
// cVillager functions
|
||||
/** return true if the given blocktype are: crops, potatoes or carrots. */
|
||||
|
@ -9,10 +9,8 @@
|
||||
|
||||
|
||||
|
||||
cZombie::cZombie(bool a_IsVillagerZombie) :
|
||||
super("Zombie", mtZombie, "entity.zombie.hurt", "entity.zombie.death", "entity.zombie.ambient", 0.6, 1.8),
|
||||
m_IsVillagerZombie(a_IsVillagerZombie),
|
||||
m_IsConverting(false)
|
||||
cZombie::cZombie() :
|
||||
super("Zombie", mtZombie, "entity.zombie.hurt", "entity.zombie.death", "entity.zombie.ambient", 0.6, 1.8)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -12,21 +12,13 @@ class cZombie :
|
||||
typedef cAggressiveMonster super;
|
||||
|
||||
public:
|
||||
cZombie(bool a_IsVillagerZombie);
|
||||
cZombie();
|
||||
|
||||
CLASS_PROTODEF(cZombie)
|
||||
|
||||
virtual void GetDrops(cItems & a_Drops, cEntity * a_Killer = nullptr) override;
|
||||
virtual bool IsUndead(void) override { return true; }
|
||||
|
||||
bool IsVillagerZombie(void) const { return m_IsVillagerZombie; }
|
||||
bool IsConverting (void) const { return m_IsConverting; }
|
||||
|
||||
private:
|
||||
|
||||
bool m_IsVillagerZombie;
|
||||
bool m_IsConverting;
|
||||
|
||||
} ;
|
||||
|
||||
|
||||
|
87
src/Mobs/ZombieVillager.cpp
Normal file
87
src/Mobs/ZombieVillager.cpp
Normal file
@ -0,0 +1,87 @@
|
||||
|
||||
#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
|
||||
|
||||
#include "ZombieVillager.h"
|
||||
#include "../World.h"
|
||||
#include "../LineBlockTracer.h"
|
||||
#include "../Entities/Player.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
cZombieVillager::cZombieVillager(cVillager::eVillagerType a_Profession) :
|
||||
super("ZombieVillager", mtZombieVillager, "entity.zombie_villager.hurt", "entity.zombie_villager.death", "entity.ambient", 0.6, 1.8),
|
||||
m_ConversionTime(-1),
|
||||
m_Profession(a_Profession)
|
||||
{
|
||||
SetBurnsInDaylight(true);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cZombieVillager::GetDrops(cItems & a_Drops, cEntity * a_Killer)
|
||||
{
|
||||
unsigned int LootingLevel = 0;
|
||||
if (a_Killer != nullptr)
|
||||
{
|
||||
LootingLevel = a_Killer->GetEquippedWeapon().m_Enchantments.GetLevel(cEnchantments::enchLooting);
|
||||
}
|
||||
AddRandomDropItem(a_Drops, 0, 2 + LootingLevel, E_ITEM_ROTTEN_FLESH);
|
||||
cItems RareDrops;
|
||||
RareDrops.Add(cItem(E_ITEM_IRON));
|
||||
RareDrops.Add(cItem(E_ITEM_CARROT));
|
||||
RareDrops.Add(cItem(E_ITEM_POTATO));
|
||||
AddRandomRareDropItem(a_Drops, RareDrops, LootingLevel);
|
||||
AddRandomArmorDropItem(a_Drops, LootingLevel);
|
||||
AddRandomWeaponDropItem(a_Drops, LootingLevel);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cZombieVillager::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk)
|
||||
{
|
||||
super::Tick(a_Dt, a_Chunk);
|
||||
if (!IsTicking())
|
||||
{
|
||||
// The base class tick destroyed us
|
||||
return;
|
||||
}
|
||||
|
||||
LOGD("Conversion time: %d", m_ConversionTime);
|
||||
|
||||
if (m_ConversionTime == 0)
|
||||
{
|
||||
m_World->BroadcastSoundEffect("entity.zombie_villager.cure", GetPosition(), 1.0f, 1.0f);
|
||||
Destroy();
|
||||
m_World->SpawnMob(GetPosX(), GetPosY(), GetPosZ(), mtVillager, false);
|
||||
}
|
||||
else if (m_ConversionTime > 0)
|
||||
{
|
||||
m_ConversionTime--;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cZombieVillager::OnRightClicked(cPlayer & a_Player)
|
||||
{
|
||||
super::OnRightClicked(a_Player);
|
||||
|
||||
const cItem & EquippedItem = a_Player.GetEquippedItem();
|
||||
if ((EquippedItem.m_ItemType == E_ITEM_GOLDEN_APPLE) && GetEntityEffect(cEntityEffect::effWeakness) != nullptr)
|
||||
{
|
||||
if (!a_Player.IsGameModeCreative())
|
||||
{
|
||||
a_Player.GetInventory().RemoveOneEquippedItem();
|
||||
}
|
||||
|
||||
m_ConversionTime = 6000;
|
||||
}
|
||||
}
|
33
src/Mobs/ZombieVillager.h
Normal file
33
src/Mobs/ZombieVillager.h
Normal file
@ -0,0 +1,33 @@
|
||||
#pragma once
|
||||
|
||||
#include "AggressiveMonster.h"
|
||||
#include "Villager.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class cZombieVillager :
|
||||
public cAggressiveMonster
|
||||
{
|
||||
typedef cAggressiveMonster super;
|
||||
|
||||
public:
|
||||
cZombieVillager(cVillager::eVillagerType a_Profession);
|
||||
|
||||
CLASS_PROTODEF(cZombieVillager)
|
||||
|
||||
virtual void GetDrops (cItems & a_Drops, cEntity * a_Killer = nullptr) override;
|
||||
virtual void Tick (std::chrono::milliseconds a_Dt, cChunk & a_Chunk) override;
|
||||
virtual void OnRightClicked (cPlayer & a_Player) override;
|
||||
virtual bool IsUndead (void) override { return true; }
|
||||
|
||||
int ConversionTime (void) const { return m_ConversionTime; }
|
||||
cVillager::eVillagerType GetProfession (void) const { return m_Profession; }
|
||||
|
||||
private:
|
||||
|
||||
int m_ConversionTime;
|
||||
cVillager::eVillagerType m_Profession;
|
||||
|
||||
} ;
|
@ -1008,11 +1008,11 @@ void cProtocol_1_10_0::WriteMobMetadata(cPacketizer & a_Pkt, const cMonster & a_
|
||||
|
||||
a_Pkt.WriteBEUInt8(ZOMBIE_TYPE);
|
||||
a_Pkt.WriteBEUInt8(METADATA_TYPE_VARINT);
|
||||
a_Pkt.WriteVarInt32(Zombie.IsVillagerZombie() ? 1 : 0); // TODO: This actually encodes the zombie villager profession, but that isn't implemented yet.
|
||||
a_Pkt.WriteVarInt32(0);
|
||||
|
||||
a_Pkt.WriteBEUInt8(ZOMBIE_CONVERTING);
|
||||
a_Pkt.WriteBEUInt8(METADATA_TYPE_BOOL);
|
||||
a_Pkt.WriteBool(Zombie.IsConverting());
|
||||
a_Pkt.WriteBool(false);
|
||||
break;
|
||||
} // case mtZombie
|
||||
|
||||
@ -1025,6 +1025,23 @@ void cProtocol_1_10_0::WriteMobMetadata(cPacketizer & a_Pkt, const cMonster & a_
|
||||
break;
|
||||
} // case mtZombiePigman
|
||||
|
||||
case mtZombieVillager:
|
||||
{
|
||||
auto & ZombieVillager = reinterpret_cast<const cZombieVillager &>(a_Mob);
|
||||
a_Pkt.WriteBEUInt8(ZOMBIE_IS_BABY);
|
||||
a_Pkt.WriteBEUInt8(METADATA_TYPE_BOOL);
|
||||
a_Pkt.WriteBool(ZombieVillager.IsBaby());
|
||||
|
||||
a_Pkt.WriteBEUInt8(ZOMBIE_TYPE);
|
||||
a_Pkt.WriteBEUInt8(METADATA_TYPE_VARINT);
|
||||
a_Pkt.WriteVarInt32(ZombieVillager.GetProfession());
|
||||
|
||||
a_Pkt.WriteBEUInt8(ZOMBIE_CONVERTING);
|
||||
a_Pkt.WriteBEUInt8(METADATA_TYPE_BOOL);
|
||||
a_Pkt.WriteBool(ZombieVillager.ConversionTime() != -1);
|
||||
break;
|
||||
} // case mtZombieVillager
|
||||
|
||||
default: break;
|
||||
} // switch (a_Mob.GetType())
|
||||
}
|
||||
|
@ -1182,15 +1182,6 @@ void cProtocol_1_11_0::WriteMobMetadata(cPacketizer & a_Pkt, const cMonster & a_
|
||||
a_Pkt.WriteBEUInt8(ZOMBIE_IS_BABY);
|
||||
a_Pkt.WriteBEUInt8(METADATA_TYPE_BOOL);
|
||||
a_Pkt.WriteBool(Zombie.IsBaby());
|
||||
|
||||
// These don't exist
|
||||
// a_Pkt.WriteBEUInt8(ZOMBIE_TYPE);
|
||||
// a_Pkt.WriteBEUInt8(METADATA_TYPE_VARINT);
|
||||
// a_Pkt.WriteVarInt32(Zombie.IsVillagerZombie() ? 1 : 0);
|
||||
|
||||
// a_Pkt.WriteBEUInt8(ZOMBIE_CONVERTING);
|
||||
// a_Pkt.WriteBEUInt8(METADATA_TYPE_BOOL);
|
||||
// a_Pkt.WriteBool(Zombie.IsConverting());
|
||||
break;
|
||||
} // case mtZombie
|
||||
|
||||
@ -1203,6 +1194,23 @@ void cProtocol_1_11_0::WriteMobMetadata(cPacketizer & a_Pkt, const cMonster & a_
|
||||
break;
|
||||
} // case mtZombiePigman
|
||||
|
||||
case mtZombieVillager:
|
||||
{
|
||||
auto & ZombieVillager = reinterpret_cast<const cZombieVillager &>(a_Mob);
|
||||
a_Pkt.WriteBEUInt8(ZOMBIE_IS_BABY);
|
||||
a_Pkt.WriteBEUInt8(METADATA_TYPE_BOOL);
|
||||
a_Pkt.WriteBool(ZombieVillager.IsBaby());
|
||||
|
||||
a_Pkt.WriteBEUInt8(ZOMBIE_VILLAGER_CONVERTING);
|
||||
a_Pkt.WriteBEUInt8(METADATA_TYPE_VARINT);
|
||||
a_Pkt.WriteVarInt32(static_cast<UInt32>(ZombieVillager.ConversionTime()));
|
||||
|
||||
a_Pkt.WriteBEUInt8(ZOMBIE_VILLAGER_PROFESSION);
|
||||
a_Pkt.WriteBEUInt8(METADATA_TYPE_VARINT);
|
||||
a_Pkt.WriteVarInt32(static_cast<UInt32>(ZombieVillager.GetProfession()));
|
||||
break;
|
||||
} // case mtZombieVillager
|
||||
|
||||
default: break;
|
||||
} // switch (a_Mob.GetType())
|
||||
}
|
||||
|
@ -908,9 +908,6 @@ void cProtocol_1_12::WriteMobMetadata(cPacketizer & a_Pkt, const cMonster & a_Mo
|
||||
// a_Pkt.WriteBEUInt8(METADATA_TYPE_VARINT);
|
||||
// a_Pkt.WriteVarInt32(Zombie.IsVillagerZombie() ? 1 : 0);
|
||||
|
||||
// a_Pkt.WriteBEUInt8(ZOMBIE_CONVERTING);
|
||||
// a_Pkt.WriteBEUInt8(METADATA_TYPE_BOOL);
|
||||
// a_Pkt.WriteBool(Zombie.IsConverting());
|
||||
break;
|
||||
} // case mtZombie
|
||||
|
||||
@ -923,6 +920,23 @@ void cProtocol_1_12::WriteMobMetadata(cPacketizer & a_Pkt, const cMonster & a_Mo
|
||||
break;
|
||||
} // case mtZombiePigman
|
||||
|
||||
case mtZombieVillager:
|
||||
{
|
||||
auto & ZombieVillager = reinterpret_cast<const cZombieVillager &>(a_Mob);
|
||||
a_Pkt.WriteBEUInt8(ZOMBIE_IS_BABY);
|
||||
a_Pkt.WriteBEUInt8(METADATA_TYPE_BOOL);
|
||||
a_Pkt.WriteBool(ZombieVillager.IsBaby());
|
||||
|
||||
a_Pkt.WriteBEUInt8(ZOMBIE_VILLAGER_CONVERTING);
|
||||
a_Pkt.WriteBEUInt8(METADATA_TYPE_VARINT);
|
||||
a_Pkt.WriteVarInt32(static_cast<UInt32>(ZombieVillager.ConversionTime()));
|
||||
|
||||
a_Pkt.WriteBEUInt8(ZOMBIE_VILLAGER_PROFESSION);
|
||||
a_Pkt.WriteBEUInt8(METADATA_TYPE_VARINT);
|
||||
a_Pkt.WriteVarInt32(static_cast<UInt32>(ZombieVillager.GetProfession()));
|
||||
break;
|
||||
} // case mtZombieVillager
|
||||
|
||||
case mtBlaze:
|
||||
case mtEnderDragon:
|
||||
case mtGuardian:
|
||||
|
@ -3825,9 +3825,9 @@ void cProtocol_1_8_0::WriteMobMetadata(cPacketizer & a_Pkt, const cMonster & a_M
|
||||
a_Pkt.WriteBEUInt8(0x0c);
|
||||
a_Pkt.WriteBEInt8(Zombie.IsBaby() ? 1 : -1);
|
||||
a_Pkt.WriteBEUInt8(0x0d);
|
||||
a_Pkt.WriteBEUInt8(Zombie.IsVillagerZombie() ? 1 : 0);
|
||||
a_Pkt.WriteBEUInt8(0);
|
||||
a_Pkt.WriteBEUInt8(0x0e);
|
||||
a_Pkt.WriteBEUInt8(Zombie.IsConverting() ? 1 : 0);
|
||||
a_Pkt.WriteBEUInt8(0);
|
||||
break;
|
||||
} // case mtZombie
|
||||
|
||||
@ -3839,6 +3839,18 @@ void cProtocol_1_8_0::WriteMobMetadata(cPacketizer & a_Pkt, const cMonster & a_M
|
||||
break;
|
||||
} // case mtZombiePigman
|
||||
|
||||
case mtZombieVillager:
|
||||
{
|
||||
auto & ZombieVillager = reinterpret_cast<const cZombieVillager &>(a_Mob);
|
||||
a_Pkt.WriteBEUInt8(0x0c);
|
||||
a_Pkt.WriteBEInt8(ZombieVillager.IsBaby() ? 1 : -1);
|
||||
a_Pkt.WriteBEUInt8(0x0d);
|
||||
a_Pkt.WriteBEUInt8(1);
|
||||
a_Pkt.WriteBEUInt8(0x0e);
|
||||
a_Pkt.WriteBEUInt8((ZombieVillager.ConversionTime() == -1) ? 0 : 1);
|
||||
break;
|
||||
} // case mtZombieVillager
|
||||
|
||||
default: break;
|
||||
} // switch (a_Mob.GetType())
|
||||
}
|
||||
|
@ -4329,11 +4329,11 @@ void cProtocol_1_9_0::WriteMobMetadata(cPacketizer & a_Pkt, const cMonster & a_M
|
||||
|
||||
a_Pkt.WriteBEUInt8(12); // Index 12: Is a villager
|
||||
a_Pkt.WriteBEUInt8(METADATA_TYPE_VARINT);
|
||||
a_Pkt.WriteVarInt32(Zombie.IsVillagerZombie() ? 1 : 0); // TODO: This actually encodes the zombie villager profession, but that isn't implemented yet.
|
||||
a_Pkt.WriteVarInt32(0);
|
||||
|
||||
a_Pkt.WriteBEUInt8(13); // Index 13: Is converting
|
||||
a_Pkt.WriteBEUInt8(METADATA_TYPE_BOOL);
|
||||
a_Pkt.WriteBool(Zombie.IsConverting());
|
||||
a_Pkt.WriteBool(false);
|
||||
break;
|
||||
} // case mtZombie
|
||||
|
||||
@ -4346,6 +4346,23 @@ void cProtocol_1_9_0::WriteMobMetadata(cPacketizer & a_Pkt, const cMonster & a_M
|
||||
break;
|
||||
} // case mtZombiePigman
|
||||
|
||||
case mtZombieVillager:
|
||||
{
|
||||
auto & ZombieVillager = reinterpret_cast<const cZombieVillager &>(a_Mob);
|
||||
a_Pkt.WriteBEUInt8(11); // Index 11: Is baby
|
||||
a_Pkt.WriteBEUInt8(METADATA_TYPE_BOOL);
|
||||
a_Pkt.WriteBool(ZombieVillager.IsBaby());
|
||||
|
||||
a_Pkt.WriteBEUInt8(12); // Index 12: Is a villager
|
||||
a_Pkt.WriteBEUInt8(METADATA_TYPE_VARINT);
|
||||
a_Pkt.WriteVarInt32(ZombieVillager.GetProfession());
|
||||
|
||||
a_Pkt.WriteBEUInt8(13); // Index 13: Is converting
|
||||
a_Pkt.WriteBEUInt8(METADATA_TYPE_BOOL);
|
||||
a_Pkt.WriteBool(ZombieVillager.ConversionTime() != -1);
|
||||
break;
|
||||
} // case mtZombieVillager
|
||||
|
||||
default: break;
|
||||
} // switch (a_Mob.GetType())
|
||||
}
|
||||
|
@ -738,10 +738,17 @@ public:
|
||||
case mtVillager: EntityClass = "Villager"; break;
|
||||
case mtWitch: EntityClass = "Witch"; break;
|
||||
case mtWither: EntityClass = "WitherBoss"; break;
|
||||
<<<<<<< HEAD
|
||||
case mtWitherSkeleton: EntityClass = "WitherSkeleton"; break;
|
||||
case mtWolf: EntityClass = "Wolf"; break;
|
||||
case mtZombie: EntityClass = "Zombie"; break;
|
||||
case mtZombiePigman: EntityClass = "PigZombie"; break;
|
||||
=======
|
||||
case mtWolf: EntityClass = "Wolf"; break;
|
||||
case mtZombie: EntityClass = "Zombie"; break;
|
||||
case mtZombiePigman: EntityClass = "PigZombie"; break;
|
||||
case mtZombieVillager: EntityClass = "ZombieVillager"; break;
|
||||
>>>>>>> Add Zombie Villagers
|
||||
default:
|
||||
{
|
||||
ASSERT(!"Unhandled monster type");
|
||||
@ -901,10 +908,7 @@ public:
|
||||
}
|
||||
case mtZombie:
|
||||
{
|
||||
const cZombie *Zombie = static_cast<const cZombie *>(a_Monster);
|
||||
mWriter.AddByte("IsVillager", Zombie->IsVillagerZombie() ? 1 : 0);
|
||||
mWriter.AddByte("IsConverting", Zombie->IsConverting() ? 1 : 0);
|
||||
mWriter.AddInt ("Age", Zombie->GetAge());
|
||||
mWriter.AddInt("Age", static_cast<const cZombie *>(a_Monster)->GetAge());
|
||||
break;
|
||||
}
|
||||
case mtZombiePigman:
|
||||
@ -912,6 +916,13 @@ public:
|
||||
mWriter.AddInt("Age", static_cast<const cZombiePigman *>(a_Monster)->GetAge());
|
||||
break;
|
||||
}
|
||||
case mtZombieVillager:
|
||||
{
|
||||
const cZombieVillager *ZombieVillager = reinterpret_cast<const cZombieVillager *>(a_Monster);
|
||||
mWriter.AddInt("Profession", ZombieVillager->GetProfession());
|
||||
mWriter.AddInt("ConversionTime", ZombieVillager->ConversionTime());
|
||||
mWriter.AddInt("Age", ZombieVillager->GetAge());
|
||||
}
|
||||
case mtBlaze:
|
||||
case mtCaveSpider:
|
||||
case mtChicken:
|
||||
|
@ -1568,6 +1568,8 @@ void cWSSAnvil::LoadEntityFromNBT(cEntityList & a_Entities, const cParsedNBT & a
|
||||
{ "minecraft:zombie", &cWSSAnvil::LoadZombieFromNBT },
|
||||
{ "PigZombie", &cWSSAnvil::LoadPigZombieFromNBT },
|
||||
{ "minecraft:zombie_pigman", &cWSSAnvil::LoadPigZombieFromNBT },
|
||||
{ "ZombieVillager", &cWSSAnvil::LoadZombieVillagerFromNBT },
|
||||
{ "minecraft:zombie_villager", &cWSSAnvil::LoadZombieVillagerFromNBT },
|
||||
};
|
||||
|
||||
auto it = EntityTypeToFunction.find(AString(a_IDTag, a_IDTagLength));
|
||||
@ -2968,15 +2970,7 @@ void cWSSAnvil::LoadWolfFromNBT(cEntityList & a_Entities, const cParsedNBT & a_N
|
||||
|
||||
void cWSSAnvil::LoadZombieFromNBT(cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx)
|
||||
{
|
||||
int IsVillagerIdx = a_NBT.FindChildByName(a_TagIdx, "IsVillager");
|
||||
if (IsVillagerIdx < 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
bool IsVillagerZombie = ((a_NBT.GetByte(IsVillagerIdx) == 1) ? true : false);
|
||||
|
||||
std::unique_ptr<cZombie> Monster = cpp14::make_unique<cZombie>(IsVillagerZombie);
|
||||
std::unique_ptr<cZombie> Monster = cpp14::make_unique<cZombie>();
|
||||
if (!LoadEntityBaseFromNBT(*Monster.get(), a_NBT, a_TagIdx))
|
||||
{
|
||||
return;
|
||||
@ -2994,7 +2988,7 @@ void cWSSAnvil::LoadZombieFromNBT(cEntityList & a_Entities, const cParsedNBT & a
|
||||
switch (a_NBT.GetType(AgeableIdx))
|
||||
{
|
||||
case TAG_Byte: Age = static_cast<int>(a_NBT.GetByte(AgeableIdx)); break;
|
||||
case TAG_Int: Age = a_NBT.GetInt (AgeableIdx); break;
|
||||
case TAG_Int: Age = a_NBT.GetInt(AgeableIdx); break;
|
||||
default: Age = 0; break;
|
||||
}
|
||||
Monster->SetAge(Age);
|
||||
@ -3040,6 +3034,49 @@ void cWSSAnvil::LoadPigZombieFromNBT(cEntityList & a_Entities, const cParsedNBT
|
||||
|
||||
|
||||
|
||||
void cWSSAnvil::LoadZombieVillagerFromNBT(cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx)
|
||||
{
|
||||
int ProfessionIdx = a_NBT.FindChildByName(a_TagIdx, "Profession");
|
||||
if (ProfessionIdx < 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
cVillager::eVillagerType Profession = static_cast<cVillager::eVillagerType>(a_NBT.GetInt(ProfessionIdx));
|
||||
|
||||
std::unique_ptr<cZombieVillager> Monster = cpp14::make_unique<cZombieVillager>(Profession);
|
||||
if (!LoadEntityBaseFromNBT(*Monster.get(), a_NBT, a_TagIdx))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!LoadMonsterBaseFromNBT(*Monster.get(), a_NBT, a_TagIdx))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO: Conversion time
|
||||
|
||||
int AgeableIdx = a_NBT.FindChildByName(a_TagIdx, "Age");
|
||||
if (AgeableIdx > 0)
|
||||
{
|
||||
int Age;
|
||||
switch (a_NBT.GetType(AgeableIdx))
|
||||
{
|
||||
case TAG_Byte: Age = static_cast<int>(a_NBT.GetByte(AgeableIdx)); break;
|
||||
case TAG_Int: Age = a_NBT.GetInt (AgeableIdx); break;
|
||||
default: Age = 0; break;
|
||||
}
|
||||
Monster->SetAge(Age);
|
||||
}
|
||||
|
||||
a_Entities.emplace_back(std::move(Monster));
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
std::pair<AString, cUUID> cWSSAnvil::LoadEntityOwner(const cParsedNBT & a_NBT, int a_TagIdx)
|
||||
{
|
||||
// Load the owner information. OwnerUUID or Owner may be specified, possibly both:
|
||||
|
@ -232,6 +232,7 @@ protected:
|
||||
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);
|
||||
void LoadZombieVillagerFromNBT (cEntityList & a_Entities, const cParsedNBT & a_NBT, int a_TagIdx);
|
||||
|
||||
/** Loads the owner name and UUID from the entity at the specified NBT tag.
|
||||
Returns a pair of {name, uuid}. If the entity is not owned, name is an empty string and uuid is nil. */
|
||||
|
Loading…
Reference in New Issue
Block a user