7 #include "../ClientHandle.h" 8 #include "../Items/ItemHandler.h" 10 #include "../EffectID.h" 11 #include "../Entities/Player.h" 12 #include "../Entities/ExpOrb.h" 13 #include "../MonsterConfig.h" 14 #include "../BoundingBox.h" 17 #include "../FastRandom.h" 20 #include "../Entities/LeashKnot.h" 39 {
mtBat,
"bat",
"Bat",
"bat"},
40 {
mtBlaze,
"blaze",
"Blaze",
"blaze"},
41 {
mtCaveSpider,
"cavespider",
"CaveSpider",
"cave_spider"},
42 {
mtChicken,
"chicken",
"Chicken",
"chicken"},
43 {
mtCow,
"cow",
"Cow",
"cow"},
44 {
mtCreeper,
"creeper",
"Creeper",
"creeper"},
45 {
mtEnderman,
"enderman",
"Enderman",
"enderman"},
46 {
mtEnderDragon,
"enderdragon",
"EnderDragon",
"ender_dragon"},
47 {
mtGhast,
"ghast",
"Ghast",
"ghast"},
48 {
mtGiant,
"giant",
"Giant",
"giant"},
49 {
mtGuardian,
"guardian",
"Guardian",
"guardian"},
50 {
mtHorse,
"horse",
"EntityHorse",
"horse"},
51 {
mtIronGolem,
"irongolem",
"VillagerGolem",
"iron_golem"},
52 {
mtMagmaCube,
"magmacube",
"LavaSlime",
"magma_cube"},
53 {
mtMooshroom,
"mooshroom",
"MushroomCow",
"mooshroom"},
54 {
mtOcelot,
"ocelot",
"Ozelot",
"ocelot"},
55 {
mtPig,
"pig",
"Pig",
"pig"},
56 {
mtRabbit,
"rabbit",
"Rabbit",
"rabbit"},
57 {
mtSheep,
"sheep",
"Sheep",
"sheep"},
58 {
mtSilverfish,
"silverfish",
"Silverfish",
"silverfish"},
59 {
mtSkeleton,
"skeleton",
"Skeleton",
"skeleton"},
60 {
mtSlime,
"slime",
"Slime",
"slime"},
61 {
mtSnowGolem,
"snowgolem",
"SnowMan",
"snow_golem"},
62 {
mtSpider,
"spider",
"Spider",
"spider"},
63 {
mtSquid,
"squid",
"Squid",
"squid"},
64 {
mtVillager,
"villager",
"Villager",
"villager"},
65 {
mtWitch,
"witch",
"Witch",
"witch"},
66 {
mtWither,
"wither",
"WitherBoss",
"wither"},
67 {
mtWolf,
"wolf",
"Wolf",
"wolf"},
68 {
mtZombie,
"zombie",
"Zombie",
"zombie"},
80 :
super(etMonster, a_Width, a_Height)
82 , m_EMPersonality(AGGRESSIVE)
83 , m_PathFinder(a_Width, a_Height)
84 , m_PathfinderActivated(false)
88 , m_MobType(a_MobType)
90 , m_CustomNameAlwaysVisible(false)
91 , m_SoundHurt(a_SoundHurt)
92 , m_SoundDeath(a_SoundDeath)
96 , m_AttackCoolDownTicksLeft(0)
98 , m_DropChanceWeapon(0.085f)
99 , m_DropChanceHelmet(0.085f)
100 , m_DropChanceChestplate(0.085f)
101 , m_DropChanceLeggings(0.085f)
102 , m_DropChanceBoots(0.085f)
103 , m_CanPickUpLoot(true)
104 , m_TicksSinceLastDamaged(100)
105 , m_BurnsInDaylight(false)
106 , m_RelativeWalkSpeed(1)
108 , m_AgingTimer(20 * 60 * 20)
109 , m_WasLastTargetAPlayer(false)
110 , m_LeashedTo(nullptr)
111 , m_LeashToPos(nullptr)
112 , m_IsLeashActionJustDone(false)
113 , m_CanBeLeashed(GetMobFamily() ==
eFamily::mfPassive)
116 if (!a_ConfigName.empty())
140 Unleash(
false, a_ShouldBroadcast);
211 if ((std::abs(Distance.
x) > 0.05) || (std::abs(Distance.
z) > 0.05))
300 if (!static_cast<cPlayer *>(
GetTarget())->CanMobsTarget())
311 bool a_IsFollowingPath =
false;
340 a_IsFollowingPath =
true;
409 if (LeashKnot !=
nullptr)
421 static const double CloseFollowDistance = 1.8;
422 static const double LeashNaturalLength = 5.0;
423 static const double LeashMaximumLength = 10.0;
424 static const double LeashSpringConstant = 20.0;
427 const auto Displacement = LeashedToPos -
GetPosition();
428 const auto Distance = Displacement.Length();
429 const auto Direction = Displacement.NormalizeCopy();
432 if (Distance > LeashMaximumLength)
434 LOGD(
"Leash broken (distance)");
440 if (Distance > LeashNaturalLength)
443 const auto Extension = Distance - LeashNaturalLength;
444 auto Acceleration =
Direction * (Extension * LeashSpringConstant);
449 Acceleration.y = 0.0;
453 using namespace std::chrono;
454 AddSpeed(Acceleration * duration_cast<duration<double>>(a_Dt).count());
458 if (Distance > CloseFollowDistance)
460 const Vector3d TargetBlock((LeashedToPos -
Direction * CloseFollowDistance).Floor());
473 if (!a_IsFollowingPath && (
GetTarget() !=
nullptr))
481 double BodyRotation, BodyPitch;
483 VectorToEuler(BodyDistance.
x, BodyDistance.
y, BodyDistance.
z, BodyRotation, BodyPitch);
501 HeadDistance = BodyDistance;
505 double HeadRotation, HeadPitch;
507 VectorToEuler(HeadDistance.
x, HeadDistance.
y, HeadDistance.
z, HeadRotation, HeadPitch);
508 if ((std::abs(BodyRotation - HeadRotation) < 70) && (std::abs(HeadPitch) < 60))
579 (static_cast<cPlayer *>(a_TDI.
Attacker)->CanMobsTarget())
781 int rem = Random.RandInt(1, 7);
785 Dist.
x =
static_cast<double>(Random.RandInt(-5, 5));
786 Dist.
z =
static_cast<double>(Random.RandInt(-5, 5));
788 if ((Dist.
SqrLength() > 2) && (rem >= 3))
794 if ((Chunk ==
nullptr) || !Chunk->
IsValid())
803 int YBelowUs =
static_cast<int>(Destination.
y) - 1;
867 if (a_CustomName.length() > 64)
1049 ASSERT(!
"Unhandled mob type");
1061 switch (a_MobFamily)
1070 ASSERT(!
"Unhandled mob family");
1091 if (OldTarget !=
nullptr)
1097 if (a_NewTarget !=
nullptr)
1138 return cpp14::make_unique<cMagmaCube>(1 << Random.RandInt(2));
1142 return cpp14::make_unique<cSlime>(1 << Random.RandInt(2));
1147 return cpp14::make_unique<cSkeleton>(
false);
1151 int VillagerType = Random.RandInt(6);
1152 if (VillagerType == 6)
1163 int HorseType = Random.RandInt(7);
1164 int HorseColor = Random.RandInt(6);
1165 int HorseStyle = Random.RandInt(4);
1166 int HorseTameTimes = Random.RandInt(1, 6);
1168 if ((HorseType == 5) || (HorseType == 6) || (HorseType == 7))
1174 return cpp14::make_unique<cHorse>(HorseType, HorseColor, HorseStyle, HorseTameTimes);
1177 case mtBat:
return cpp14::make_unique<cBat>();
1178 case mtBlaze:
return cpp14::make_unique<cBlaze>();
1179 case mtCaveSpider:
return cpp14::make_unique<cCaveSpider>();
1180 case mtChicken:
return cpp14::make_unique<cChicken>();
1181 case mtCow:
return cpp14::make_unique<cCow>();
1182 case mtCreeper:
return cpp14::make_unique < cCreeper>();
1183 case mtEnderDragon:
return cpp14::make_unique<cEnderDragon>();
1184 case mtEnderman:
return cpp14::make_unique<cEnderman>();
1185 case mtGhast:
return cpp14::make_unique<cGhast>();
1186 case mtGiant:
return cpp14::make_unique<cGiant>();
1187 case mtGuardian:
return cpp14::make_unique<cGuardian>();
1188 case mtIronGolem:
return cpp14::make_unique<cIronGolem>();
1189 case mtMooshroom:
return cpp14::make_unique<cMooshroom>();
1190 case mtOcelot:
return cpp14::make_unique<cOcelot>();
1191 case mtPig:
return cpp14::make_unique<cPig>();
1192 case mtRabbit:
return cpp14::make_unique<cRabbit>();
1193 case mtSheep:
return cpp14::make_unique<cSheep>();
1194 case mtSilverfish:
return cpp14::make_unique<cSilverfish>();
1195 case mtSnowGolem:
return cpp14::make_unique<cSnowGolem>();
1196 case mtSpider:
return cpp14::make_unique<cSpider>();
1197 case mtSquid:
return cpp14::make_unique<cSquid>();
1198 case mtWitch:
return cpp14::make_unique<cWitch>();
1199 case mtWither:
return cpp14::make_unique<cWither>();
1200 case mtWolf:
return cpp14::make_unique<cWolf>();
1201 case mtZombie:
return cpp14::make_unique<cZombie>(
false);
1205 ASSERT(!
"Unhandled mob type whilst trying to spawn mob!");
1219 while (Count > MaxStackSize)
1221 a_Drops.emplace_back(a_Item, MaxStackSize, a_ItemHealth);
1222 Count -= MaxStackSize;
1226 a_Drops.emplace_back(a_Item, Count, a_ItemHealth);
1238 a_Drops.push_back(
cItem(a_Item, 1, a_ItemHealth));
1249 if (r1.RandBool((5 + a_LootingLevel) / 200.0))
1251 size_t Rare = r1.RandInt<
size_t>(a_Items.
Size() - 1);
1252 a_Drops.push_back(a_Items.at(Rare));
1264 double LootingBonus = a_LootingLevel / 100.0;
1351 int RelY =
FloorC(a_Location.
y);
1385 int CurrentBlock = Chunk->GetHeight(Rel.x, Rel.z);
1386 while (CurrentBlock > MobHeight)
1388 BLOCKTYPE Block = Chunk->GetBlock(Rel.x, CurrentBlock, Rel.z);
1432 if (a_ShouldBroadcast)
1456 if (a_ShouldDropLeashPickup)
1463 if (a_ShouldBroadcast)
1477 Unleash(a_ShouldDropLeashPickup,
true);
int GetChunkZ(void) const
double m_RelativeWalkSpeed
Vector3d m_FinalDestination
Coordinates for the ultimate, final destination.
double GetPosY(void) const
bool IsValid(void) const
Returns true iff the chunk block data is valid (loaded / generated)
virtual void InStateEscaping(std::chrono::milliseconds a_Dt, cChunk &a_Chunk)
bool IsLightValid(void) const
double GetPosX(void) const
virtual void Destroyed() override
BLOCKTYPE GetBlock(Vector3i a_BlockPos)
Returns the block type at the specified position.
bool IsBlockWater(BLOCKTYPE a_BlockType)
void AddRandomWeaponDropItem(cItems &a_Drops, unsigned int a_LootingLevel)
Adds weapon that is equipped with the chance saved in m_DropChance... to the drop.
bool DoesPosYRequireJump(double a_PosY)
Returns whether the monster needs to jump to reach a given height.
static std::unique_ptr< cMonster > NewMonsterFromType(eMonsterType a_MobType)
Creates a new object of the specified mob.
void MoveToWayPoint(cChunk &a_Chunk)
Move in a straight line to the next waypoint in the path, will jump if needed.
virtual cItem GetEquippedHelmet(void) const
Returns the currently equipped helmet; empty item if none.
static bool IsSolid(BLOCKTYPE a_Type)
void AddSpeedZ(double a_AddSpeedZ)
void GetBlockTypeMeta(Vector3i a_RelPos, BLOCKTYPE &a_BlockType, NIBBLETYPE &a_BlockMeta) const
unsigned char BLOCKTYPE
The datatype used by blockdata.
virtual bool DoTakeDamage(TakeDamageInfo &a_TDI)
Makes this entity take damage specified in the a_TDI.
bool RemoveOneEquippedItem(void)
Removes one item out of the currently equipped item stack, returns true if successful, false if empty-handed.
virtual void Tick(std::chrono::milliseconds a_Dt, cChunk &a_Chunk) override
MTRand & GetRandomProvider()
Returns the current thread's random number source.
#define GET_AND_VERIFY_CURRENT_CHUNK(ChunkVarName, X, Z)
bool HasAnyMobLeashed() const
Returs whether the entity has any mob leashed to.
virtual void BroadcastEntityMetadata(const cEntity &a_Entity, const cClientHandle *a_Exclude=nullptr) override
void AddRandomArmorDropItem(cItems &a_Drops, unsigned int a_LootingLevel)
Adds armor that is equipped with the chance saved in m_DropChance... to the drop. ...
const cItem & GetEquippedItem(void) const
void SetHeadYaw(double a_HeadYaw)
virtual char GetMaxStackSize(void)
Returns the maximum stack size for a given item.
cPawn * GetTarget()
Returns the current target.
virtual bool IsOnFire(void) const
void SendLeashEntity(const cEntity &a_Entity, const cEntity &a_EntityLeashedTo)
cPawn * m_Target
A pointer to the entity this mobile is aiming to reach.
const Vector3d & GetSpeed(void) const
Exported in ManualBindings.
void AddRandomDropItem(cItems &a_Drops, unsigned int a_Min, unsigned int a_Max, short a_Item, short a_ItemHealth=0)
Adds a random number of a_Item between a_Min and a_Max to itemdrops a_Drops.
virtual cItem GetEquippedBoots(void) const
Returns the currently equipped boots; empty item if none.
virtual bool IsInWater(void) const
Returns true if any part of the entity is in a water block.
virtual ~cMonster() override
void SetPitch(double a_Pitch)
virtual void MoveToPosition(const Vector3d &a_Position)
Engage pathfinder and tell it to calculate a path to a given position, and move the mob accordingly...
unsigned char NIBBLETYPE
The datatype used by nibbledata (meta, light, skylight)
void AddRandomRareDropItem(cItems &a_Drops, cItems &a_Items, unsigned int a_LootingLevel)
Adds one rare item out of the list of rare items a_Items modified by the looting level a_LootingLevel...
virtual void KilledBy(TakeDamageInfo &a_TDI) override
Called when the health drops below zero.
cEntity * GetLeashedTo() const
Returns the entity to where this mob is leashed, returns nullptr if it's not leashed.
cEntity * m_LeashedTo
Entity leashed to.
bool IsWeatherSunnyAt(int a_BlockX, int a_BlockZ)
Returns true if it is sunny at the specified location.
virtual void Destroyed() override
void SpawnItemPickups(const cItems &a_Pickups, Vector3i a_BlockPos, double a_FlyAwaySpeed=1.0, bool a_IsPlayerCreated=false)
Spawns item pickups for each item in the list.
void SendSpawnMob(const cMonster &a_Mob)
static cLeashKnot * FindKnotAtPos(cWorldInterface &a_WorldInterface, Vector3i a_BlockPos)
Returns the leash knot entity representing the knot at the specified position.
void AddSpeedX(double a_AddSpeedX)
enum cMonster::MState m_EMState
void NoLongerTargetingMe(cMonster *a_Monster)
Remove the monster from the list of monsters targeting this pawn.
eMonsterType
Identifies individual monster type, as well as their network type-ID.
virtual void Destroy(bool a_ShouldBroadcast=true)
Destroys the entity and schedules it for memory freeing; if a_ShouldBroadcast is set to true...
bool ReachedFinalDestination(void)
Returns if the ultimate, final destination has been reached.
double GetHeight(void) const
bool WouldBurnAt(Vector3d a_Location, cChunk &a_Chunk)
bool m_IsLeashActionJustDone
Mob has ben leashed or unleashed in current player action.
virtual void BroadcastSoundEffect(const AString &a_SoundName, Vector3d a_Position, float a_Volume, float a_Pitch, const cClientHandle *a_Exclude=nullptr) override
void SetSpeedZ(double a_SpeedZ)
Sets the speed in the Z axis, leaving the other speed components intact.
virtual void CheckEventLostPlayer(void)
virtual void EventLosePlayer(void)
IntType RandInt(IntType a_Min, IntType a_Max)
Return a random IntType in the range [a_Min, a_Max].
static const struct @18 g_MobTypeNames[]
Map for eType <-> string Needs to be alpha-sorted by the strings, because binary search is used in St...
const char * m_VanillaName
void StartBurning(int a_TicksLeftBurning)
Puts the entity on fire for the specified amount of ticks.
static int GetSpawnDelay(cMonster::eFamily a_MobFamily)
Returns the spawn delay (number of game ticks between spawn attempts) for the given mob family...
void UnsafeUnsetTarget()
Unset the target without notifying the target entity.
void SetCustomName(const AString &a_CustomName)
Sets the custom name of the monster.
bool m_WasLastTargetAPlayer
virtual bool IsOnGround(void) const
Returns whether the entity is on ground or not.
void AddLeashedMob(cMonster *a_Monster)
Adds a mob to the leashed list of mobs.
virtual cItem GetEquippedLeggings(void) const
Returns the currently equipped leggings; empty item if none.
void Add(const cItem &a_Item)
bool IsTicking(void) const
Returns true if the entity is valid and ticking.
bool m_PathfinderActivated
Stores if pathfinder is being used - set when final destination is set, and unset when stopped moving...
virtual bool DoTakeDamage(TakeDamageInfo &a_TDI) override
Makes this entity take damage specified in the a_TDI.
virtual bool IsUndead(void)
Returns whether this mob is undead (skeleton, zombie, etc.)
Vector3d m_NextWayPointPosition
Coordinates of the next position that should be reached.
virtual int GetTimeOfDay(void) const override
void SetPitchAndYawFromDestination(bool a_IsFollowingPath)
Sets the body yaw and head yaw.
static eFamily FamilyFromType(eMonsterType a_MobType)
Returns the mob family based on the type.
int m_TicksSinceLastDamaged
void AddSpeed(double a_AddSpeedX, double a_AddSpeedY, double a_AddSpeedZ)
void RemoveLeashedMob(cMonster *a_Monster)
Removes a mob from the leashed list of mobs.
std::chrono::milliseconds m_DestroyTimer
virtual void HandleFalling(void)
void SetTarget(cPawn *a_NewTarget)
Sets the target that this mob will chase.
cMonster(const AString &a_ConfigName, eMonsterType a_MobType, const AString &a_SoundHurt, const AString &a_SoundDeath, double a_Width, double a_Height)
Creates the mob object.
bool DoWithNearestPlayer(Vector3d a_Pos, double a_RangeLimit, cPlayerListCallback a_Callback, bool a_CheckLineOfSight=true, bool a_IgnoreSpectator=true)
Calls the callback for nearest player for given position, Returns false if player not found...
float GetGravity(void) const
static AString MobTypeToVanillaNBT(eMonsterType a_MobType)
Translates the MobType enum to the vanilla nbt name.
bool IsLeashed() const
Returns whether the monster is leashed to an entity.
int m_AttackCoolDownTicksLeft
float m_DropChanceLeggings
virtual void SpawnOn(cClientHandle &a_ClientHandle) override
Descendants override this function to send a command to the specified client to spawn the entity on t...
int FindFirstNonAirBlockPosition(double a_PosX, double a_PosZ)
Finds the lowest non-air block position (not the highest, as cWorld::GetHeight does) If current Y is ...
virtual void BroadcastLeashEntity(const cEntity &a_Entity, const cEntity &a_EntityLeashedTo) override
std::chrono::milliseconds m_IdleInterval
float m_DropChanceChestplate
virtual void Destroy(bool a_ShouldBroadcast=true) override
Destroys the entity and schedules it for memory freeing; if a_ShouldBroadcast is set to true...
virtual void CheckEventSeePlayer(cChunk &a_Chunk)
T Clamp(T a_Value, T a_Min, T a_Max)
Clamp X to the specified range.
virtual void OnRightClicked(cPlayer &a_Player)
Called when the specified player right-clicks this entity.
void SetCustomNameAlwaysVisible(bool a_CustomNameAlwaysVisible)
Sets the custom name visiblity of this monster.
static AString MobTypeToString(eMonsterType a_MobType)
Translates MobType enum to a string, empty string if unknown.
cPathFinder m_PathFinder
The pathfinder instance handles pathfinding for this monster.
cMonsterConfig * GetMonsterConfig(void)
void HandleDaylightBurning(cChunk &a_Chunk, bool WouldBurn)
double SqrLength(void) const
static eMonsterType StringToMobType(const AString &a_MobTypeName)
Translates MobType string to the enum, mtInvalidType if not recognized.
bool IsPlayer(void) const
void SetSpeedY(double a_SpeedY)
Sets the speed in the Y axis, leaving the other speed components intact.
virtual std::vector< UInt32 > SpawnSplitExperienceOrbs(Vector3d a_Pos, int a_Reward) override
Spawns experience orbs of the specified total value at the given location.
ePathFinderStatus GetNextWayPoint(cChunk &a_Chunk, const Vector3d &a_Source, Vector3d *a_Destination, Vector3d *a_OutputWaypoint, bool a_DontCare=false)
Updates the PathFinder's internal state and returns a waypoint.
void ResetAttackCooldown()
static bool IsTransparent(BLOCKTYPE a_Type)
void SetSpeedX(double a_SpeedX)
Sets the speed in the X axis, leaving the other speed components intact.
void AssignAttributes(cMonster *a_Monster, const AString &a_Name)
int GetChunkX(void) const
void CalcLeashActions(std::chrono::milliseconds a_Dt)
Leash calculations inside Tick function.
bool m_CustomNameAlwaysVisible
virtual void EventSeePlayer(cPlayer *a_Player, cChunk &a_Chunk)
virtual void BroadcastUnleashEntity(const cEntity &a_Entity) override
cChunk * GetNeighborChunk(int a_BlockX, int a_BlockZ)
Returns the chunk into which the specified block belongs, by walking the neighbors.
virtual cItem GetEquippedWeapon(void) const
Returns the curently equipped weapon; empty item if none.
void QueueLightChunk(int a_ChunkX, int a_ChunkZ, std::unique_ptr< cChunkCoordCallback > a_Callback={})
Queues a chunk for lighting; a_Callback is called after the chunk is lighted.
const Vector3d & GetPosition(void) const
Exported in ManualBindings.
const char * m_VanillaNameNBT
virtual void InStateIdle(std::chrono::milliseconds a_Dt, cChunk &a_Chunk)
bool m_bOnGround
Stores if the entity is on the ground.
void GetMonsterConfig(const AString &a_Name)
Reads the monster configuration for the specified monster name and assigns it to this object...
eFamily GetMobFamily(void) const
virtual void OnRightClicked(cPlayer &a_Player) override
Called when the specified player right-clicks this entity.
double GetPosZ(void) const
bool IsGameModeCreative(void) const
Returns true if the player is in Creative mode, either explicitly, or by inheriting from current worl...
void TargetingMe(cMonster *a_Monster)
Add the monster to the list of monsters targeting this pawn.
void AddPosY(double a_AddPosY)
void LeashTo(cEntity &a_Entity, bool a_ShouldBroadcast=true)
Leash the monster to an entity.
virtual void Tick(std::chrono::milliseconds a_Dt, cChunk &a_Chunk) override
void SetYaw(double a_Yaw)
void Unleash(bool a_ShouldDropLeashPickup)
Unleash the monster.
void StopMovingToPosition()
Stops pathfinding.
virtual void InStateChasing(std::chrono::milliseconds a_Dt, cChunk &a_Chunk)
virtual void KilledBy(TakeDamageInfo &a_TDI) override
Called when the health drops below zero.
AString StrToLower(const AString &s)
Returns a lower-cased copy of the string.
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)
cInventory & GetInventory(void)
static AString MobTypeToVanillaName(eMonsterType a_MobType)
Translates MobType enum to the vanilla name of the mob, empty string if unknown.
#define ARRAYCOUNT(X)
Evaluates to the number of elements in an array (compile-time!)
virtual cItem GetEquippedChestplate(void) const
Returns the currently equipped chestplate; empty item if none.
cItemHandler * ItemHandler(int a_ItemType)
bool IsLeashKnot(void) const
void SetLeashToPos(Vector3d *pos)
Sets entity position to where is leashed this mob.
void AddRandomUncommonDropItem(cItems &a_Drops, float a_Chance, short a_Item, short a_ItemHealth=0)
Adds a item a_Item with the chance of a_Chance (in percent) to itemdrops a_Drops. ...
#define PREPARE_REL_AND_CHUNK(Position, OriginalChunk)
cWorld * GetWorld(void) const
This class bridges a vector of cItem for safe access via Lua.
virtual void HandleFalling(void) override
bool CanBeLeashed() const
Returns whether the mob can be leashed.
virtual void BroadcastMovementUpdate(const cClientHandle *a_Exclude=nullptr)
Updates clients of changes in the entity.
std::enable_if< std::is_arithmetic< T >::value, C >::type CeilC(T a_Value)
Ceils a value, then casts it to C (an int by default)
void VectorToEuler(double a_X, double a_Y, double a_Z, double &a_Pan, double &a_Pitch)
std::unique_ptr< Vector3d > m_LeashToPos
Entity pos where this mob was leashed to.