diff options
Diffstat (limited to 'src/Mobs')
-rw-r--r-- | src/Mobs/AggressiveMonster.cpp | 11 | ||||
-rw-r--r-- | src/Mobs/Blaze.cpp | 2 | ||||
-rw-r--r-- | src/Mobs/CMakeLists.txt | 6 | ||||
-rw-r--r-- | src/Mobs/CaveSpider.cpp | 4 | ||||
-rw-r--r-- | src/Mobs/Chicken.cpp | 2 | ||||
-rw-r--r-- | src/Mobs/Cow.cpp | 2 | ||||
-rw-r--r-- | src/Mobs/Creeper.cpp | 8 | ||||
-rw-r--r-- | src/Mobs/Enderman.cpp | 4 | ||||
-rw-r--r-- | src/Mobs/Ghast.cpp | 2 | ||||
-rw-r--r-- | src/Mobs/Guardian.cpp | 11 | ||||
-rw-r--r-- | src/Mobs/Horse.cpp | 10 | ||||
-rw-r--r-- | src/Mobs/Monster.cpp | 38 | ||||
-rw-r--r-- | src/Mobs/Monster.h | 15 | ||||
-rw-r--r-- | src/Mobs/Mooshroom.cpp | 2 | ||||
-rw-r--r-- | src/Mobs/PassiveAggressiveMonster.cpp | 2 | ||||
-rw-r--r-- | src/Mobs/PassiveMonster.cpp | 2 | ||||
-rw-r--r-- | src/Mobs/Path.cpp | 132 | ||||
-rw-r--r-- | src/Mobs/Path.h | 27 | ||||
-rw-r--r-- | src/Mobs/Pig.cpp | 2 | ||||
-rw-r--r-- | src/Mobs/Rabbit.cpp | 2 | ||||
-rw-r--r-- | src/Mobs/Sheep.cpp | 6 | ||||
-rw-r--r-- | src/Mobs/Skeleton.cpp | 9 | ||||
-rw-r--r-- | src/Mobs/Slime.cpp | 2 | ||||
-rw-r--r-- | src/Mobs/Spider.cpp | 2 | ||||
-rw-r--r-- | src/Mobs/Squid.cpp | 11 | ||||
-rw-r--r-- | src/Mobs/Witch.cpp | 2 | ||||
-rw-r--r-- | src/Mobs/Wolf.cpp | 7 | ||||
-rw-r--r-- | src/Mobs/Zombie.cpp | 2 | ||||
-rw-r--r-- | src/Mobs/ZombiePigman.cpp | 2 |
29 files changed, 229 insertions, 98 deletions
diff --git a/src/Mobs/AggressiveMonster.cpp b/src/Mobs/AggressiveMonster.cpp index 648599999..7fde1e56b 100644 --- a/src/Mobs/AggressiveMonster.cpp +++ b/src/Mobs/AggressiveMonster.cpp @@ -30,7 +30,7 @@ void cAggressiveMonster::InStateChasing(std::chrono::milliseconds a_Dt) { if (m_Target->IsPlayer()) { - if (((cPlayer *)m_Target)->IsGameModeCreative()) + if (static_cast<cPlayer *>(m_Target)->IsGameModeCreative()) { m_EMState = IDLE; return; @@ -46,7 +46,7 @@ void cAggressiveMonster::InStateChasing(std::chrono::milliseconds a_Dt) void cAggressiveMonster::EventSeePlayer(cEntity * a_Entity) { - if (!((cPlayer *)a_Entity)->IsGameModeCreative()) + if (!static_cast<cPlayer *>(a_Entity)->IsGameModeCreative()) { super::EventSeePlayer(a_Entity); m_EMState = CHASING; @@ -80,9 +80,10 @@ void cAggressiveMonster::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) Vector3d AttackDirection(m_Target->GetPosition() + Vector3d(0, m_Target->GetHeight(), 0) - MyHeadPosition); - if (ReachedFinalDestination() && !LineOfSight.Trace(MyHeadPosition, AttackDirection, static_cast<int>(AttackDirection.Length()))) + if (TargetIsInRange() && !LineOfSight.Trace(MyHeadPosition, AttackDirection, static_cast<int>(AttackDirection.Length()))) { // Attack if reached destination, target isn't null, and have a clear line of sight to target (so won't attack through walls) + StopMovingToPosition(); Attack(a_Dt); } } @@ -110,12 +111,12 @@ void cAggressiveMonster::Attack(std::chrono::milliseconds a_Dt) bool cAggressiveMonster::IsMovingToTargetPosition() { // Difference between destination x and target x is negligible (to 10^-12 precision) - if (fabsf((float)m_FinalDestination.x - (float)m_Target->GetPosX()) < std::numeric_limits<float>::epsilon()) + if (fabsf(static_cast<float>(m_FinalDestination.x) - static_cast<float>(m_Target->GetPosX())) < std::numeric_limits<float>::epsilon()) { return false; } // Difference between destination z and target z is negligible (to 10^-12 precision) - else if (fabsf((float)m_FinalDestination.z - (float)m_Target->GetPosZ()) > std::numeric_limits<float>::epsilon()) + else if (fabsf(static_cast<float>(m_FinalDestination.z) - static_cast<float>(m_Target->GetPosZ())) > std::numeric_limits<float>::epsilon()) { return false; } diff --git a/src/Mobs/Blaze.cpp b/src/Mobs/Blaze.cpp index d4ad24166..731da6b18 100644 --- a/src/Mobs/Blaze.cpp +++ b/src/Mobs/Blaze.cpp @@ -23,7 +23,7 @@ void cBlaze::GetDrops(cItems & a_Drops, cEntity * a_Killer) { if ((a_Killer != nullptr) && (a_Killer->IsPlayer() || a_Killer->IsA("cWolf"))) { - int LootingLevel = a_Killer->GetEquippedWeapon().m_Enchantments.GetLevel(cEnchantments::enchLooting); + unsigned int LootingLevel = a_Killer->GetEquippedWeapon().m_Enchantments.GetLevel(cEnchantments::enchLooting); AddRandomDropItem(a_Drops, 0, 1 + LootingLevel, E_ITEM_BLAZE_ROD); } } diff --git a/src/Mobs/CMakeLists.txt b/src/Mobs/CMakeLists.txt index ffbcdf3ea..e99494508 100644 --- a/src/Mobs/CMakeLists.txt +++ b/src/Mobs/CMakeLists.txt @@ -80,6 +80,12 @@ SET (HDRS Zombie.h ZombiePigman.h) +if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang") + set_source_files_properties(Monster.cpp PROPERTIES COMPILE_FLAGS "-Wno-error=sign-conversion -Wno-error=conversion -Wno-error=switch -Wno-error=switch-enum -Wno-error=float-equal -Wno-error=old-style-cast") + set_source_files_properties(SnowGolem.cpp PROPERTIES COMPILE_FLAGS "-Wno-error=old-style-cast") + set_source_files_properties(Villager.cpp PROPERTIES COMPILE_FLAGS "-Wno-error=old-style-cast") +endif() + if(NOT MSVC) add_library(Mobs ${SRCS} ${HDRS}) endif() diff --git a/src/Mobs/CaveSpider.cpp b/src/Mobs/CaveSpider.cpp index fa530db82..a8b40f52e 100644 --- a/src/Mobs/CaveSpider.cpp +++ b/src/Mobs/CaveSpider.cpp @@ -34,7 +34,7 @@ void cCaveSpider::Attack(std::chrono::milliseconds a_Dt) if (m_Target->IsPawn()) { // TODO: Easy = no poison, Medium = 7 seconds, Hard = 15 seconds - ((cPawn *) m_Target)->AddEntityEffect(cEntityEffect::effPoison, 7 * 20, 0); + static_cast<cPawn *>(m_Target)->AddEntityEffect(cEntityEffect::effPoison, 7 * 20, 0); } } @@ -44,7 +44,7 @@ void cCaveSpider::Attack(std::chrono::milliseconds a_Dt) void cCaveSpider::GetDrops(cItems & a_Drops, cEntity * a_Killer) { - int LootingLevel = 0; + unsigned int LootingLevel = 0; if (a_Killer != nullptr) { LootingLevel = a_Killer->GetEquippedWeapon().m_Enchantments.GetLevel(cEnchantments::enchLooting); diff --git a/src/Mobs/Chicken.cpp b/src/Mobs/Chicken.cpp index b2b21d4ae..a52d1a2da 100644 --- a/src/Mobs/Chicken.cpp +++ b/src/Mobs/Chicken.cpp @@ -48,7 +48,7 @@ void cChicken::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) void cChicken::GetDrops(cItems & a_Drops, cEntity * a_Killer) { - int LootingLevel = 0; + unsigned int LootingLevel = 0; if (a_Killer != nullptr) { LootingLevel = a_Killer->GetEquippedWeapon().m_Enchantments.GetLevel(cEnchantments::enchLooting); diff --git a/src/Mobs/Cow.cpp b/src/Mobs/Cow.cpp index 7dc6f3f37..a45010201 100644 --- a/src/Mobs/Cow.cpp +++ b/src/Mobs/Cow.cpp @@ -21,7 +21,7 @@ cCow::cCow(void) : void cCow::GetDrops(cItems & a_Drops, cEntity * a_Killer) { - int LootingLevel = 0; + unsigned int LootingLevel = 0; if (a_Killer != nullptr) { LootingLevel = a_Killer->GetEquippedWeapon().m_Enchantments.GetLevel(cEnchantments::enchLooting); diff --git a/src/Mobs/Creeper.cpp b/src/Mobs/Creeper.cpp index 41796402f..30bd41f13 100644 --- a/src/Mobs/Creeper.cpp +++ b/src/Mobs/Creeper.cpp @@ -27,7 +27,7 @@ void cCreeper::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) { super::Tick(a_Dt, a_Chunk); - if (!ReachedFinalDestination() && !m_BurnedWithFlintAndSteel) + if (!TargetIsInRange() && !m_BurnedWithFlintAndSteel) { m_ExplodingTimer = 0; m_bIsBlowing = false; @@ -60,7 +60,7 @@ void cCreeper::GetDrops(cItems & a_Drops, cEntity * a_Killer) return; } - int LootingLevel = 0; + unsigned int LootingLevel = 0; if (a_Killer != nullptr) { LootingLevel = a_Killer->GetEquippedWeapon().m_Enchantments.GetLevel(cEnchantments::enchLooting); @@ -124,7 +124,7 @@ void cCreeper::Attack(std::chrono::milliseconds a_Dt) if (!m_bIsBlowing) { - m_World->BroadcastSoundEffect("game.tnt.primed", GetPosX(), GetPosY(), GetPosZ(), 1.f, (float)(0.75 + ((float)((GetUniqueID() * 23) % 32)) / 64)); + m_World->BroadcastSoundEffect("game.tnt.primed", GetPosX(), GetPosY(), GetPosZ(), 1.f, (0.75f + (static_cast<float>((GetUniqueID() * 23) % 32)) / 64)); m_bIsBlowing = true; m_World->BroadcastEntityMetadata(*this); } @@ -142,7 +142,7 @@ void cCreeper::OnRightClicked(cPlayer & a_Player) { a_Player.UseEquippedItem(); } - m_World->BroadcastSoundEffect("game.tnt.primed", GetPosX(), GetPosY(), GetPosZ(), 1.f, (float)(0.75 + ((float)((GetUniqueID() * 23) % 32)) / 64)); + m_World->BroadcastSoundEffect("game.tnt.primed", GetPosX(), GetPosY(), GetPosZ(), 1.f, (0.75f + (static_cast<float>((GetUniqueID() * 23) % 32)) / 64)); m_bIsBlowing = true; m_World->BroadcastEntityMetadata(*this); m_BurnedWithFlintAndSteel = true; diff --git a/src/Mobs/Enderman.cpp b/src/Mobs/Enderman.cpp index 42c33884a..30bf82067 100644 --- a/src/Mobs/Enderman.cpp +++ b/src/Mobs/Enderman.cpp @@ -55,7 +55,7 @@ public: } cTracer LineOfSight(a_Player->GetWorld()); - if (LineOfSight.Trace(m_EndermanPos, Direction, (int)Direction.Length())) + if (LineOfSight.Trace(m_EndermanPos, Direction, static_cast<int>(Direction.Length()))) { // No direct line of sight return false; @@ -91,7 +91,7 @@ cEnderman::cEnderman(void) : void cEnderman::GetDrops(cItems & a_Drops, cEntity * a_Killer) { - int LootingLevel = 0; + unsigned int LootingLevel = 0; if (a_Killer != nullptr) { LootingLevel = a_Killer->GetEquippedWeapon().m_Enchantments.GetLevel(cEnchantments::enchLooting); diff --git a/src/Mobs/Ghast.cpp b/src/Mobs/Ghast.cpp index d17047ab7..15bbe484b 100644 --- a/src/Mobs/Ghast.cpp +++ b/src/Mobs/Ghast.cpp @@ -19,7 +19,7 @@ cGhast::cGhast(void) : void cGhast::GetDrops(cItems & a_Drops, cEntity * a_Killer) { - int LootingLevel = 0; + unsigned int LootingLevel = 0; if (a_Killer != nullptr) { LootingLevel = a_Killer->GetEquippedWeapon().m_Enchantments.GetLevel(cEnchantments::enchLooting); diff --git a/src/Mobs/Guardian.cpp b/src/Mobs/Guardian.cpp index 5eb30785b..1429e2b13 100644 --- a/src/Mobs/Guardian.cpp +++ b/src/Mobs/Guardian.cpp @@ -21,7 +21,7 @@ cGuardian::cGuardian(void) : void cGuardian::GetDrops(cItems & a_Drops, cEntity * a_Killer) { // Drops 0-3 Ink Sacs - int LootingLevel = 0; + unsigned int LootingLevel = 0; if (a_Killer != nullptr) { LootingLevel = a_Killer->GetEquippedWeapon().m_Enchantments.GetLevel(cEnchantments::enchLooting); @@ -37,19 +37,20 @@ void cGuardian::GetDrops(cItems & a_Drops, cEntity * a_Killer) void cGuardian::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) { + m_IsFollowingPath = false; // Disable Pathfinding until it's fixed. TODO + // We must first process current location, and only then tick, otherwise we risk processing a location in a chunk // that is not where the entity currently resides (FS #411) - Vector3d Pos = GetPosition(); // TODO: Not a real behavior, but cool :D - int RelY = (int)floor(Pos.y); + int RelY = FloorC(Pos.y); if ((RelY < 0) || (RelY >= cChunkDef::Height)) { return; } - int RelX = (int)floor(Pos.x) - a_Chunk.GetPosX() * cChunkDef::Width; - int RelZ = (int)floor(Pos.z) - a_Chunk.GetPosZ() * cChunkDef::Width; + int RelX = FloorC(Pos.x) - a_Chunk.GetPosX() * cChunkDef::Width; + int RelZ = FloorC(Pos.z) - a_Chunk.GetPosZ() * cChunkDef::Width; BLOCKTYPE BlockType; if (a_Chunk.UnboundedRelGetBlockType(RelX, RelY, RelZ, BlockType) && !IsBlockWater(BlockType) && !IsOnFire()) { diff --git a/src/Mobs/Horse.cpp b/src/Mobs/Horse.cpp index 5b4c78bfc..ce3bd65eb 100644 --- a/src/Mobs/Horse.cpp +++ b/src/Mobs/Horse.cpp @@ -55,10 +55,10 @@ void cHorse::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) { if (m_World->GetTickRandomNumber(50) == 25) { - m_World->BroadcastSoundParticleEffect(2000, (int)GetPosX(), (int)GetPosY(), (int)GetPosZ(), 0); - m_World->BroadcastSoundParticleEffect(2000, (int)GetPosX(), (int)GetPosY(), (int)GetPosZ(), 2); - m_World->BroadcastSoundParticleEffect(2000, (int)GetPosX(), (int)GetPosY(), (int)GetPosZ(), 6); - m_World->BroadcastSoundParticleEffect(2000, (int)GetPosX(), (int)GetPosY(), (int)GetPosZ(), 8); + m_World->BroadcastSoundParticleEffect(2000, FloorC(GetPosX()), FloorC(GetPosY()), FloorC(GetPosZ()), 0); + m_World->BroadcastSoundParticleEffect(2000, FloorC(GetPosX()), FloorC(GetPosY()), FloorC(GetPosZ()), 2); + m_World->BroadcastSoundParticleEffect(2000, FloorC(GetPosX()), FloorC(GetPosY()), FloorC(GetPosZ()), 6); + m_World->BroadcastSoundParticleEffect(2000, FloorC(GetPosX()), FloorC(GetPosY()), FloorC(GetPosZ()), 8); m_Attachee->Detach(); m_bIsRearing = true; @@ -140,7 +140,7 @@ void cHorse::OnRightClicked(cPlayer & a_Player) void cHorse::GetDrops(cItems & a_Drops, cEntity * a_Killer) { - int LootingLevel = 0; + unsigned int LootingLevel = 0; if (a_Killer != nullptr) { LootingLevel = a_Killer->GetEquippedWeapon().m_Enchantments.GetLevel(cEnchantments::enchLooting); diff --git a/src/Mobs/Monster.cpp b/src/Mobs/Monster.cpp index f5d961096..8d71c54e8 100644 --- a/src/Mobs/Monster.cpp +++ b/src/Mobs/Monster.cpp @@ -169,7 +169,7 @@ bool cMonster::TickPathFinding(cChunk & a_Chunk) m_NoPathToTarget = false; m_NoMoreWayPoints = false; m_PathFinderDestination = m_FinalDestination; - m_Path = new cPath(a_Chunk, GetPosition().Floor(), m_PathFinderDestination.Floor(), 20); + m_Path = new cPath(a_Chunk, GetPosition(), m_PathFinderDestination, 20, GetWidth(), GetHeight()); } switch (m_Path->Step(a_Chunk)) @@ -183,7 +183,7 @@ bool cMonster::TickPathFinding(cChunk & a_Chunk) case ePathFinderStatus::PATH_NOT_FOUND: { - ResetPathFinding(); // Try to calculate a path again. + StopMovingToPosition(); // Try to calculate a path again. // Note that the next time may succeed, e.g. if a player breaks a barrier. break; } @@ -196,14 +196,22 @@ bool cMonster::TickPathFinding(cChunk & a_Chunk) { if (m_NoMoreWayPoints || (--m_GiveUpCounter == 0)) { - ResetPathFinding(); // Try to calculate a path again. + if (m_EMState == ATTACKING) + { + ResetPathFinding(); // Try to calculate a path again. + // This results in mobs hanging around an unreachable target (player). + } + else + { + StopMovingToPosition(); // Find a different place to go to. + } return false; } else if (!m_Path->IsLastPoint()) // Have we arrived at the next cell, as denoted by m_NextWayPointPosition? { if ((m_Path->IsFirstPoint() || ReachedNextWaypoint())) { - m_NextWayPointPosition = Vector3d(0.5, 0, 0.5) + m_Path->GetNextPoint(); + m_NextWayPointPosition = m_Path->GetNextPoint(); m_GiveUpCounter = 40; // Give up after 40 ticks (2 seconds) if failed to reach m_NextWayPointPosition. } } @@ -391,6 +399,7 @@ void cMonster::MoveToPosition(const Vector3d & a_Position) void cMonster::StopMovingToPosition() { m_IsFollowingPath = false; + ResetPathFinding(); } @@ -508,8 +517,15 @@ void cMonster::SetPitchAndYawFromDestination() } - - Vector3d BodyDistance = m_NextWayPointPosition - GetPosition(); + Vector3d BodyDistance; + if (!m_IsFollowingPath && (m_Target != nullptr)) + { + BodyDistance = m_Target->GetPosition() - GetPosition(); + } + else + { + BodyDistance = m_NextWayPointPosition - GetPosition(); + } double BodyRotation, BodyPitch; BodyDistance.Normalize(); VectorToEuler(BodyDistance.x, BodyDistance.y, BodyDistance.z, BodyRotation, BodyPitch); @@ -520,7 +536,7 @@ void cMonster::SetPitchAndYawFromDestination() double HeadRotation, HeadPitch; Distance.Normalize(); VectorToEuler(Distance.x, Distance.y, Distance.z, HeadRotation, HeadPitch); - if (std::abs(BodyRotation - HeadRotation) < 120) + if (std::abs(BodyRotation - HeadRotation) < 90) { SetHeadYaw(HeadRotation); SetPitch(-HeadPitch); @@ -1138,10 +1154,10 @@ void cMonster::AddRandomUncommonDropItem(cItems & a_Drops, float a_Chance, short -void cMonster::AddRandomRareDropItem(cItems & a_Drops, cItems & a_Items, short a_LootingLevel) +void cMonster::AddRandomRareDropItem(cItems & a_Drops, cItems & a_Items, unsigned int a_LootingLevel) { MTRand r1; - int Count = r1.randInt() % 200; + unsigned int Count = r1.randInt() % 200; if (Count < (5 + a_LootingLevel)) { int Rare = r1.randInt() % a_Items.Size(); @@ -1153,7 +1169,7 @@ void cMonster::AddRandomRareDropItem(cItems & a_Drops, cItems & a_Items, short a -void cMonster::AddRandomArmorDropItem(cItems & a_Drops, short a_LootingLevel) +void cMonster::AddRandomArmorDropItem(cItems & a_Drops, unsigned int a_LootingLevel) { MTRand r1; if (r1.randInt() % 200 < ((m_DropChanceHelmet * 200) + (a_LootingLevel * 2))) @@ -1193,7 +1209,7 @@ void cMonster::AddRandomArmorDropItem(cItems & a_Drops, short a_LootingLevel) -void cMonster::AddRandomWeaponDropItem(cItems & a_Drops, short a_LootingLevel) +void cMonster::AddRandomWeaponDropItem(cItems & a_Drops, unsigned int a_LootingLevel) { MTRand r1; if (r1.randInt() % 200 < ((m_DropChanceWeapon * 200) + (a_LootingLevel * 2))) diff --git a/src/Mobs/Monster.h b/src/Mobs/Monster.h index c4043b0e5..1076c9544 100644 --- a/src/Mobs/Monster.h +++ b/src/Mobs/Monster.h @@ -193,13 +193,16 @@ protected: If no suitable position is found, returns cChunkDef::Height. */ int FindFirstNonAirBlockPosition(double a_PosX, double a_PosZ); - /** Returns if the ultimate, final destination has been reached */ - bool ReachedFinalDestination(void) { return ((m_FinalDestination - GetPosition()).SqrLength() < (m_AttackRange * m_AttackRange)); } + /** Returns if the ultimate, final destination has been reached. */ + bool ReachedFinalDestination(void) { return ((m_FinalDestination - GetPosition()).Length() < GetWidth()/2); } + + /** Returns whether or not the target is close enough for attack. */ + bool TargetIsInRange(void) { return ((m_FinalDestination - GetPosition()).SqrLength() < (m_AttackRange * m_AttackRange)); } /** Returns if the intermediate waypoint of m_NextWayPointPosition has been reached */ bool ReachedNextWaypoint(void) { return ((m_NextWayPointPosition - GetPosition()).SqrLength() < 0.25); } - /** Returns if a monster can reach a given height by jumping */ + /** Returns if a monster can reach a given height by jumping. */ inline bool DoesPosYRequireJump(int a_PosY) { return ((a_PosY > POSY_TOINT) && (a_PosY == POSY_TOINT + 1)); @@ -274,13 +277,13 @@ protected: void AddRandomUncommonDropItem(cItems & a_Drops, float a_Chance, short a_Item, short a_ItemHealth = 0); /** Adds one rare item out of the list of rare items a_Items modified by the looting level a_LootingLevel(I-III or custom) to the itemdrop a_Drops*/ - void AddRandomRareDropItem(cItems & a_Drops, cItems & a_Items, short a_LootingLevel); + void AddRandomRareDropItem(cItems & a_Drops, cItems & a_Items, unsigned int a_LootingLevel); /** Adds armor that is equipped with the chance saved in m_DropChance[...] (this will be greter than 1 if piccked up or 0.085 + (0.01 per LootingLevel) if born with) to the drop*/ - void AddRandomArmorDropItem(cItems & a_Drops, short a_LootingLevel); + void AddRandomArmorDropItem(cItems & a_Drops, unsigned int a_LootingLevel); /** Adds weapon that is equipped with the chance saved in m_DropChance[...] (this will be greter than 1 if piccked up or 0.085 + (0.01 per LootingLevel) if born with) to the drop*/ - void AddRandomWeaponDropItem(cItems & a_Drops, short a_LootingLevel); + void AddRandomWeaponDropItem(cItems & a_Drops, unsigned int a_LootingLevel); } ; // tolua_export diff --git a/src/Mobs/Mooshroom.cpp b/src/Mobs/Mooshroom.cpp index ec533cfca..3b2fbad57 100644 --- a/src/Mobs/Mooshroom.cpp +++ b/src/Mobs/Mooshroom.cpp @@ -24,7 +24,7 @@ cMooshroom::cMooshroom(void) : void cMooshroom::GetDrops(cItems & a_Drops, cEntity * a_Killer) { - int LootingLevel = 0; + unsigned int LootingLevel = 0; if (a_Killer != nullptr) { LootingLevel = a_Killer->GetEquippedWeapon().m_Enchantments.GetLevel(cEnchantments::enchLooting); diff --git a/src/Mobs/PassiveAggressiveMonster.cpp b/src/Mobs/PassiveAggressiveMonster.cpp index cb8650cb9..f5577f71f 100644 --- a/src/Mobs/PassiveAggressiveMonster.cpp +++ b/src/Mobs/PassiveAggressiveMonster.cpp @@ -28,7 +28,7 @@ bool cPassiveAggressiveMonster::DoTakeDamage(TakeDamageInfo & a_TDI) if ((m_Target != nullptr) && (m_Target->IsPlayer())) { - if (!((cPlayer *)m_Target)->IsGameModeCreative()) + if (!static_cast<cPlayer *>(m_Target)->IsGameModeCreative()) { m_EMState = CHASING; } diff --git a/src/Mobs/PassiveMonster.cpp b/src/Mobs/PassiveMonster.cpp index 012ca9949..c220a7128 100644 --- a/src/Mobs/PassiveMonster.cpp +++ b/src/Mobs/PassiveMonster.cpp @@ -48,7 +48,7 @@ void cPassiveMonster::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) { return; } - cPlayer * a_Closest_Player = m_World->FindClosestPlayer(GetPosition(), (float)m_SightDistance); + cPlayer * a_Closest_Player = m_World->FindClosestPlayer(GetPosition(), static_cast<float>(m_SightDistance)); if (a_Closest_Player != nullptr) { if (a_Closest_Player->GetEquippedItem().IsEqual(FollowedItem)) diff --git a/src/Mobs/Path.cpp b/src/Mobs/Path.cpp index eba29be7e..e987381f7 100644 --- a/src/Mobs/Path.cpp +++ b/src/Mobs/Path.cpp @@ -6,6 +6,7 @@ #include "Path.h" #include "../Chunk.h" +#define JUMP_G_COST 20 #define DISTANCE_MANHATTAN 0 // 1: More speed, a bit less accuracy 0: Max accuracy, less speed. #define HEURISTICS_ONLY 0 // 1: Much more speed, much less accurate. @@ -31,12 +32,11 @@ bool compareHeuristics::operator()(cPathCell * & a_Cell1, cPathCell * & a_Cell2) /* cPath implementation */ cPath::cPath( cChunk & a_Chunk, - const Vector3i & a_StartingPoint, const Vector3i & a_EndingPoint, int a_MaxSteps, + const Vector3d & a_StartingPoint, const Vector3d & a_EndingPoint, int a_MaxSteps, double a_BoundingBoxWidth, double a_BoundingBoxHeight, int a_MaxUp, int a_MaxDown ) : - m_Destination(a_EndingPoint.Floor()), - m_Source(a_StartingPoint.Floor()), + m_CurrentPoint(0), // GetNextPoint increments this to 1, but that's fine, since the first cell is always a_StartingPoint m_Chunk(&a_Chunk), m_BadChunkFound(false) @@ -44,6 +44,21 @@ cPath::cPath( // TODO: if src not walkable OR dest not walkable, then abort. // Borrow a new "isWalkable" from ProcessIfWalkable, make ProcessIfWalkable also call isWalkable + a_BoundingBoxWidth = 1; // Until we improve physics, if ever. + + m_BoundingBoxWidth = CeilC(a_BoundingBoxWidth); + m_BoundingBoxHeight = CeilC(a_BoundingBoxHeight); + m_HalfWidth = a_BoundingBoxWidth / 2; + + int HalfWidthInt = FloorC(a_BoundingBoxWidth / 2); + m_Source.x = FloorC(a_StartingPoint.x - HalfWidthInt); + m_Source.y = FloorC(a_StartingPoint.y); + m_Source.z = FloorC(a_StartingPoint.z - HalfWidthInt); + + m_Destination.x = FloorC(a_EndingPoint.x - HalfWidthInt); + m_Destination.y = FloorC(a_EndingPoint.y); + m_Destination.z = FloorC(a_EndingPoint.z - HalfWidthInt); + if (GetCell(m_Source)->m_IsSolid || GetCell(m_Destination)->m_IsSolid) { m_Status = ePathFinderStatus::PATH_NOT_FOUND; @@ -142,13 +157,19 @@ bool cPath::IsSolid(const Vector3i & a_Location) int RelZ = a_Location.z - m_Chunk->GetPosZ() * cChunkDef::Width; m_Chunk->GetBlockTypeMeta(RelX, a_Location.y, RelZ, BlockType, BlockMeta); - if ((BlockType == E_BLOCK_FENCE) || (BlockType == E_BLOCK_FENCE_GATE)) + if ( + (BlockType == E_BLOCK_FENCE) || + (BlockType == E_BLOCK_FENCE_GATE) || + (BlockType == E_BLOCK_NETHER_BRICK_FENCE) || + ((BlockType >= E_BLOCK_SPRUCE_FENCE_GATE) && (BlockType <= E_BLOCK_ACACIA_FENCE)) + ) { + // TODO move this out of IsSolid to a proper place. GetCell(a_Location + Vector3i(0, 1, 0))->m_IsSolid = true; // Mobs will always think that the fence is 2 blocks high and therefore won't jump over. } if (BlockType == E_BLOCK_STATIONARY_WATER) { - GetCell(a_Location + Vector3i(0, -1, 0))->m_IsSolid = true; // Mobs will always think that the fence is 2 blocks high and therefore won't jump over. + GetCell(a_Location + Vector3i(0, -1, 0))->m_IsSolid = true; } return cBlockInfo::IsSolid(BlockType); @@ -179,7 +200,7 @@ bool cPath::Step_Internal() // Calculation not finished yet. // Check if we have a new NearestPoint. - + // TODO I don't like this that much, there should be a smarter way. if ((m_Destination - CurrentCell->m_Location).Length() < 5) { if (m_Rand.NextInt(4) == 0) @@ -193,21 +214,50 @@ bool cPath::Step_Internal() } // process a currentCell by inspecting all neighbors. - // Check North, South, East, West on all 3 different heights. - int i; - for (i = -1; i <= 1; ++i) + + // Check North, South, East, West on our height. + ProcessIfWalkable(CurrentCell->m_Location + Vector3i(1, 0, 0), CurrentCell, 10); + ProcessIfWalkable(CurrentCell->m_Location + Vector3i(-1, 0, 0), CurrentCell, 10); + ProcessIfWalkable(CurrentCell->m_Location + Vector3i(0, 0, 1), CurrentCell, 10); + ProcessIfWalkable(CurrentCell->m_Location + Vector3i(0, 0, -1), CurrentCell, 10); + + // Check diagonals on XY plane. + // x = -1: west, x = 1: east. + for (int x = -1; x <= 1; x += 2) { - ProcessIfWalkable(CurrentCell->m_Location + Vector3i(1, i, 0), CurrentCell, 10); - ProcessIfWalkable(CurrentCell->m_Location + Vector3i(-1, i, 0), CurrentCell, 10); - ProcessIfWalkable(CurrentCell->m_Location + Vector3i(0, i, 1), CurrentCell, 10); - ProcessIfWalkable(CurrentCell->m_Location + Vector3i(0, i, -1), CurrentCell, 10); + if (GetCell(CurrentCell->m_Location + Vector3i(x, 0, 0))->m_IsSolid) // If there's a solid our east / west. + { + if (!GetCell(CurrentCell->m_Location + Vector3i(0, 1, 0))->m_IsSolid) // If there isn't a solid above. + { + ProcessIfWalkable(CurrentCell->m_Location + Vector3i(x, 1, 0), CurrentCell, JUMP_G_COST); // Check east-up / west-up. + } + } + else + { + ProcessIfWalkable(CurrentCell->m_Location + Vector3i(x, -1, 0), CurrentCell, 14); // Else check east-down / west-down. + } + } + + // Check diagonals on the YZ plane. + for (int z = -1; z <= 1; z += 2) + { + if (GetCell(CurrentCell->m_Location + Vector3i(0, 0, z))->m_IsSolid) // If there's a solid our north / south. + { + if (!GetCell(CurrentCell->m_Location + Vector3i(0, 1, 0))->m_IsSolid) // If there isn't a solid above. + { + ProcessIfWalkable(CurrentCell->m_Location + Vector3i(0, 1, z), CurrentCell, JUMP_G_COST); // Check north-up / south-up. + } + } + else + { + ProcessIfWalkable(CurrentCell->m_Location + Vector3i(0, -1, z), CurrentCell, 14); // Else check north-down / south-down. + } } - // Check diagonals on mob's height only. - int x, z; - for (x = -1; x <= 1; x += 2) + // Check diagonals on the XZ plane. (Normal diagonals, this plane is special because of gravity, etc) + for (int x = -1; x <= 1; x += 2) { - for (z = -1; z <= 1; z += 2) + for (int z = -1; z <= 1; z += 2) { // This condition prevents diagonal corner cutting. if (!GetCell(CurrentCell->m_Location + Vector3i(x, 0, 0))->m_IsSolid && !GetCell(CurrentCell->m_Location + Vector3i(0, 0, z))->m_IsSolid) @@ -320,7 +370,53 @@ si::setBlock((Ret)->m_Location.x, (Ret)->m_Location.y, (Ret)->m_Location.z, debu void cPath::ProcessIfWalkable(const Vector3i & a_Location, cPathCell * a_Parent, int a_Cost) { cPathCell * cell = GetCell(a_Location); - if (!cell->m_IsSolid && GetCell(a_Location + Vector3i(0, -1, 0))->m_IsSolid && !GetCell(a_Location + Vector3i(0, 1, 0))->m_IsSolid) + int x, y, z; + + // Make sure we fit in the position. + for (y = 0; y < m_BoundingBoxHeight; ++y) + { + for (x = 0; x < m_BoundingBoxWidth; ++x) + { + for (z = 0; z < m_BoundingBoxWidth; ++z) + { + if (GetCell(a_Location + Vector3i(x, y, z))->m_IsSolid) + { + return; + } + } + } + } + + /*y =-1; + for (x = 0; x < m_BoundingBoxWidth; ++x) + { + for (z = 0; z < m_BoundingBoxWidth; ++z) + { + if (!GetCell(a_Location + Vector3i(x, y, z))->m_IsSolid) + { + return; + } + } + } + ProcessCell(cell, a_Parent, a_Cost);*/ + + // Make sure there's at least 1 piece of solid below us. + + bool GroundFlag = false; + y =-1; + for (x = 0; x < m_BoundingBoxWidth; ++x) + { + for (z = 0; z < m_BoundingBoxWidth; ++z) + { + if (GetCell(a_Location + Vector3i(x, y, z))->m_IsSolid) + { + GroundFlag = true; + break; + } + } + } + + if (GroundFlag) { ProcessCell(cell, a_Parent, a_Cost); } diff --git a/src/Mobs/Path.h b/src/Mobs/Path.h index b296bbdf5..c250eece2 100644 --- a/src/Mobs/Path.h +++ b/src/Mobs/Path.h @@ -68,8 +68,8 @@ public: @param a_MaxSteps The maximum steps before giving up. */ cPath( cChunk & a_Chunk, - const Vector3i & a_StartingPoint, const Vector3i & a_EndingPoint, int a_MaxSteps, - double a_BoundingBoxWidth = 1, double a_BoundingBoxHeight = 2, + const Vector3d & a_StartingPoint, const Vector3d & a_EndingPoint, int a_MaxSteps, + double a_BoundingBoxWidth, double a_BoundingBoxHeight, int a_MaxUp = 1, int a_MaxDown = 1 ); @@ -89,10 +89,11 @@ public: /* Point retrieval functions, inlined for performance. */ /** Returns the next point in the path. */ - inline Vector3i GetNextPoint() + inline Vector3d GetNextPoint() { ASSERT(m_Status == ePathFinderStatus::PATH_FOUND); - return m_PathPoints[m_PathPoints.size() - 1 - (++m_CurrentPoint)]; + Vector3i Point = m_PathPoints[m_PathPoints.size() - 1 - (++m_CurrentPoint)]; + return Vector3d(Point.x + m_HalfWidth, Point.y, Point.z + m_HalfWidth); } /** Checks whether this is the last point or not. Never call getnextPoint when this is true. */ inline bool IsLastPoint() @@ -106,14 +107,15 @@ public: return (m_CurrentPoint == 0); } /** Get the point at a_index. Remark: Internally, the indexes are reversed. */ - inline Vector3i GetPoint(size_t a_index) + inline Vector3d GetPoint(size_t a_index) { ASSERT(m_Status == ePathFinderStatus::PATH_FOUND); ASSERT(a_index < m_PathPoints.size()); - return m_PathPoints[m_PathPoints.size() - 1 - a_index]; + Vector3i Point = m_PathPoints[m_PathPoints.size() - 1 - a_index]; + return Vector3d(Point.x + m_HalfWidth, Point.y, Point.z + m_HalfWidth); } /** Returns the total number of points this path has. */ - inline int GetPointCount() + inline size_t GetPointCount() { if (m_Status != ePathFinderStatus::PATH_FOUND) { @@ -128,13 +130,13 @@ public: { // Guaranteed to have no hash collisions for any 128x128x128 area. Suitable for pathfinding. int32_t t = 0; - t += (int8_t)a_Vector.x; + t += static_cast<int8_t>(a_Vector.x); t = t << 8; - t += (int8_t)a_Vector.y; + t += static_cast<int8_t>(a_Vector.y); t = t << 8; - t += (int8_t)a_Vector.z; + t += static_cast<int8_t>(a_Vector.z); t = t << 8; - return (size_t)t; + return static_cast<size_t>(t); } }; private: @@ -161,6 +163,9 @@ private: std::unordered_map<Vector3i, cPathCell, VectorHasher> m_Map; Vector3i m_Destination; Vector3i m_Source; + int m_BoundingBoxWidth; + int m_BoundingBoxHeight; + double m_HalfWidth; int m_StepsLeft; cPathCell * m_NearestPointToTarget; cFastRandom m_Rand; diff --git a/src/Mobs/Pig.cpp b/src/Mobs/Pig.cpp index 56d6abfd5..efa779ac2 100644 --- a/src/Mobs/Pig.cpp +++ b/src/Mobs/Pig.cpp @@ -21,7 +21,7 @@ cPig::cPig(void) : void cPig::GetDrops(cItems & a_Drops, cEntity * a_Killer) { - int LootingLevel = 0; + unsigned int LootingLevel = 0; if (a_Killer != nullptr) { LootingLevel = a_Killer->GetEquippedWeapon().m_Enchantments.GetLevel(cEnchantments::enchLooting); diff --git a/src/Mobs/Rabbit.cpp b/src/Mobs/Rabbit.cpp index cf49d2744..c7f3d58f0 100644 --- a/src/Mobs/Rabbit.cpp +++ b/src/Mobs/Rabbit.cpp @@ -20,7 +20,7 @@ cRabbit::cRabbit(void) : void cRabbit::GetDrops(cItems & a_Drops, cEntity * a_Killer) { - int LootingLevel = 0; + unsigned int LootingLevel = 0; if (a_Killer != nullptr) { LootingLevel = a_Killer->GetEquippedWeapon().m_Enchantments.GetLevel(cEnchantments::enchLooting); diff --git a/src/Mobs/Sheep.cpp b/src/Mobs/Sheep.cpp index ec24f167e..dcfef8135 100644 --- a/src/Mobs/Sheep.cpp +++ b/src/Mobs/Sheep.cpp @@ -37,10 +37,10 @@ void cSheep::GetDrops(cItems & a_Drops, cEntity * a_Killer) { if (!m_IsSheared) { - a_Drops.push_back(cItem(E_BLOCK_WOOL, 1, m_WoolColor)); + a_Drops.push_back(cItem(E_BLOCK_WOOL, 1, static_cast<short>(m_WoolColor))); } - int LootingLevel = 0; + unsigned int LootingLevel = 0; if (a_Killer != nullptr) { LootingLevel = a_Killer->GetEquippedWeapon().m_Enchantments.GetLevel(cEnchantments::enchLooting); @@ -65,7 +65,7 @@ void cSheep::OnRightClicked(cPlayer & a_Player) cItems Drops; int NumDrops = m_World->GetTickRandomNumber(2) + 1; - Drops.push_back(cItem(E_BLOCK_WOOL, NumDrops, m_WoolColor)); + Drops.push_back(cItem(E_BLOCK_WOOL, static_cast<char>(NumDrops), static_cast<short>(m_WoolColor))); m_World->SpawnItemPickups(Drops, GetPosX(), GetPosY(), GetPosZ(), 10); m_World->BroadcastSoundEffect("mob.sheep.shear", GetPosX(), GetPosY(), GetPosZ(), 1.0f, 1.0f); } diff --git a/src/Mobs/Skeleton.cpp b/src/Mobs/Skeleton.cpp index f99404669..767e5b95c 100644 --- a/src/Mobs/Skeleton.cpp +++ b/src/Mobs/Skeleton.cpp @@ -22,7 +22,7 @@ cSkeleton::cSkeleton(bool IsWither) : void cSkeleton::GetDrops(cItems & a_Drops, cEntity * a_Killer) { - int LootingLevel = 0; + unsigned int LootingLevel = 0; if (a_Killer != nullptr) { LootingLevel = a_Killer->GetEquippedWeapon().m_Enchantments.GetLevel(cEnchantments::enchLooting); @@ -50,12 +50,13 @@ void cSkeleton::GetDrops(cItems & a_Drops, cEntity * a_Killer) void cSkeleton::Attack(std::chrono::milliseconds a_Dt) { + cFastRandom Random; m_AttackInterval += (static_cast<float>(a_Dt.count()) / 1000) * m_AttackRate; if ((m_Target != nullptr) && (m_AttackInterval > 3.0)) { - // Setting this higher gives us more wiggle room for attackrate - Vector3d Speed = GetLookVector() * 20; - Speed.y = Speed.y + 1; + Vector3d Inaccuracy = Vector3d(Random.NextFloat(0.5) - 0.25, Random.NextFloat(0.5) - 0.25, Random.NextFloat(0.5) - 0.25); + Vector3d Speed = (m_Target->GetPosition() + Inaccuracy - GetPosition()) * 5; + Speed.y = Speed.y - 1 + Random.NextInt(3); cArrowEntity * Arrow = new cArrowEntity(this, GetPosX(), GetPosY() + 1, GetPosZ(), Speed); if (Arrow == nullptr) { diff --git a/src/Mobs/Slime.cpp b/src/Mobs/Slime.cpp index 7fc4821d8..4988d1082 100644 --- a/src/Mobs/Slime.cpp +++ b/src/Mobs/Slime.cpp @@ -29,7 +29,7 @@ cSlime::cSlime(int a_Size) : void cSlime::GetDrops(cItems & a_Drops, cEntity * a_Killer) { - int LootingLevel = 0; + unsigned int LootingLevel = 0; if (a_Killer != nullptr) { LootingLevel = a_Killer->GetEquippedWeapon().m_Enchantments.GetLevel(cEnchantments::enchLooting); diff --git a/src/Mobs/Spider.cpp b/src/Mobs/Spider.cpp index deb263c41..184a1d912 100644 --- a/src/Mobs/Spider.cpp +++ b/src/Mobs/Spider.cpp @@ -18,7 +18,7 @@ cSpider::cSpider(void) : void cSpider::GetDrops(cItems & a_Drops, cEntity * a_Killer) { - int LootingLevel = 0; + unsigned int LootingLevel = 0; if (a_Killer != nullptr) { LootingLevel = a_Killer->GetEquippedWeapon().m_Enchantments.GetLevel(cEnchantments::enchLooting); diff --git a/src/Mobs/Squid.cpp b/src/Mobs/Squid.cpp index 3c508b65f..30fbfa1ff 100644 --- a/src/Mobs/Squid.cpp +++ b/src/Mobs/Squid.cpp @@ -21,7 +21,7 @@ cSquid::cSquid(void) : void cSquid::GetDrops(cItems & a_Drops, cEntity * a_Killer) { // Drops 0-3 Ink Sacs - int LootingLevel = 0; + unsigned int LootingLevel = 0; if (a_Killer != nullptr) { LootingLevel = a_Killer->GetEquippedWeapon().m_Enchantments.GetLevel(cEnchantments::enchLooting); @@ -35,19 +35,20 @@ void cSquid::GetDrops(cItems & a_Drops, cEntity * a_Killer) void cSquid::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) { + m_IsFollowingPath = false; // Disable Pathfinding until it's fixed. TODO + // We must first process current location, and only then tick, otherwise we risk processing a location in a chunk // that is not where the entity currently resides (FS #411) - Vector3d Pos = GetPosition(); // TODO: Not a real behavior, but cool :D - int RelY = (int)floor(Pos.y); + int RelY = FloorC(Pos.y); if ((RelY < 0) || (RelY >= cChunkDef::Height)) { return; } - int RelX = (int)floor(Pos.x) - a_Chunk.GetPosX() * cChunkDef::Width; - int RelZ = (int)floor(Pos.z) - a_Chunk.GetPosZ() * cChunkDef::Width; + int RelX = FloorC(Pos.x) - a_Chunk.GetPosX() * cChunkDef::Width; + int RelZ = FloorC(Pos.z) - a_Chunk.GetPosZ() * cChunkDef::Width; BLOCKTYPE BlockType; if (a_Chunk.UnboundedRelGetBlockType(RelX, RelY, RelZ, BlockType) && !IsBlockWater(BlockType) && !IsOnFire()) { diff --git a/src/Mobs/Witch.cpp b/src/Mobs/Witch.cpp index a3cadbaa0..1f672b4f7 100644 --- a/src/Mobs/Witch.cpp +++ b/src/Mobs/Witch.cpp @@ -19,7 +19,7 @@ cWitch::cWitch(void) : void cWitch::GetDrops(cItems & a_Drops, cEntity * a_Killer) { - int LootingLevel = 0; + unsigned int LootingLevel = 0; if (a_Killer != nullptr) { LootingLevel = a_Killer->GetEquippedWeapon().m_Enchantments.GetLevel(cEnchantments::enchLooting); diff --git a/src/Mobs/Wolf.cpp b/src/Mobs/Wolf.cpp index 3c2ec1520..7b5953523 100644 --- a/src/Mobs/Wolf.cpp +++ b/src/Mobs/Wolf.cpp @@ -20,6 +20,7 @@ cWolf::cWolf(void) : m_OwnerName(""), m_CollarColor(14) { + m_RelativeWalkSpeed = 2; } @@ -50,7 +51,7 @@ void cWolf::Attack(std::chrono::milliseconds a_Dt) if ((m_Target != nullptr) && (m_Target->IsPlayer())) { - if (((cPlayer *)m_Target)->GetName() != m_OwnerName) + if (static_cast<cPlayer *>(m_Target)->GetName() != m_OwnerName) { super::Attack(a_Dt); } @@ -157,7 +158,7 @@ void cWolf::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) super::Tick(a_Dt, a_Chunk); } - cPlayer * a_Closest_Player = m_World->FindClosestPlayer(GetPosition(), (float)m_SightDistance); + cPlayer * a_Closest_Player = m_World->FindClosestPlayer(GetPosition(), static_cast<float>(m_SightDistance)); if (a_Closest_Player != nullptr) { switch (a_Closest_Player->GetEquippedItem().m_ItemType) @@ -230,7 +231,7 @@ void cWolf::TickFollowPlayer() { // The player is present in the world, follow him: double Distance = (Callback.OwnerPos - GetPosition()).Length(); - if (Distance > 30) + if (Distance > 20) { Callback.OwnerPos.y = FindFirstNonAirBlockPosition(Callback.OwnerPos.x, Callback.OwnerPos.z); TeleportToCoords(Callback.OwnerPos.x, Callback.OwnerPos.y, Callback.OwnerPos.z); diff --git a/src/Mobs/Zombie.cpp b/src/Mobs/Zombie.cpp index fa4ac855d..a5b44e6c0 100644 --- a/src/Mobs/Zombie.cpp +++ b/src/Mobs/Zombie.cpp @@ -23,7 +23,7 @@ cZombie::cZombie(bool a_IsVillagerZombie) : void cZombie::GetDrops(cItems & a_Drops, cEntity * a_Killer) { - int LootingLevel = 0; + unsigned int LootingLevel = 0; if (a_Killer != nullptr) { LootingLevel = a_Killer->GetEquippedWeapon().m_Enchantments.GetLevel(cEnchantments::enchLooting); diff --git a/src/Mobs/ZombiePigman.cpp b/src/Mobs/ZombiePigman.cpp index 8b415b0af..96d587287 100644 --- a/src/Mobs/ZombiePigman.cpp +++ b/src/Mobs/ZombiePigman.cpp @@ -18,7 +18,7 @@ cZombiePigman::cZombiePigman(void) : void cZombiePigman::GetDrops(cItems & a_Drops, cEntity * a_Killer) { - int LootingLevel = 0; + unsigned int LootingLevel = 0; if (a_Killer != nullptr) { LootingLevel = a_Killer->GetEquippedWeapon().m_Enchantments.GetLevel(cEnchantments::enchLooting); |