diff options
Diffstat (limited to 'src/Mobs')
-rw-r--r-- | src/Mobs/Blaze.cpp | 14 | ||||
-rw-r--r-- | src/Mobs/Ghast.cpp | 13 | ||||
-rw-r--r-- | src/Mobs/Monster.cpp | 83 | ||||
-rw-r--r-- | src/Mobs/Monster.h | 16 | ||||
-rw-r--r-- | src/Mobs/Ocelot.cpp | 28 | ||||
-rw-r--r-- | src/Mobs/Ocelot.h | 3 | ||||
-rw-r--r-- | src/Mobs/Skeleton.cpp | 14 | ||||
-rw-r--r-- | src/Mobs/Slime.cpp | 4 | ||||
-rw-r--r-- | src/Mobs/Wither.cpp | 13 | ||||
-rw-r--r-- | src/Mobs/Wither.h | 1 | ||||
-rw-r--r-- | src/Mobs/Wolf.h | 2 |
11 files changed, 104 insertions, 87 deletions
diff --git a/src/Mobs/Blaze.cpp b/src/Mobs/Blaze.cpp index 8cdac12d1..a48bfa886 100644 --- a/src/Mobs/Blaze.cpp +++ b/src/Mobs/Blaze.cpp @@ -39,19 +39,17 @@ bool cBlaze::Attack(std::chrono::milliseconds a_Dt) // Setting this higher gives us more wiggle room for attackrate Vector3d Speed = GetLookVector() * 20; Speed.y = Speed.y + 1; - cFireChargeEntity * FireCharge = new cFireChargeEntity(this, GetPosX(), GetPosY() + 1, GetPosZ(), Speed); - if (FireCharge == nullptr) - { - return false; - } - if (!FireCharge->Initialize(*m_World)) + + auto FireCharge = cpp14::make_unique<cFireChargeEntity>(this, GetPosX(), GetPosY() + 1, GetPosZ(), Speed); + auto FireChargePtr = FireCharge.get(); + if (!FireChargePtr->Initialize(std::move(FireCharge), *m_World)) { - delete FireCharge; - FireCharge = nullptr; return false; } + ResetAttackCooldown(); // ToDo: Shoot 3 fireballs instead of 1. + return true; } return false; diff --git a/src/Mobs/Ghast.cpp b/src/Mobs/Ghast.cpp index 6f5a93d93..2488e63b1 100644 --- a/src/Mobs/Ghast.cpp +++ b/src/Mobs/Ghast.cpp @@ -39,17 +39,14 @@ bool cGhast::Attack(std::chrono::milliseconds a_Dt) // Setting this higher gives us more wiggle room for attackrate Vector3d Speed = GetLookVector() * 20; Speed.y = Speed.y + 1; - cGhastFireballEntity * GhastBall = new cGhastFireballEntity(this, GetPosX(), GetPosY() + 1, GetPosZ(), Speed); - if (GhastBall == nullptr) - { - return false; - } - if (!GhastBall->Initialize(*m_World)) + + auto GhastBall = cpp14::make_unique<cGhastFireballEntity>(this, GetPosX(), GetPosY() + 1, GetPosZ(), Speed); + auto GhastBallPtr = GhastBall.get(); + if (!GhastBallPtr->Initialize(std::move(GhastBall), *m_World)) { - delete GhastBall; - GhastBall = nullptr; return false; } + ResetAttackCooldown(); return true; } diff --git a/src/Mobs/Monster.cpp b/src/Mobs/Monster.cpp index ecda6e724..8077e41d6 100644 --- a/src/Mobs/Monster.cpp +++ b/src/Mobs/Monster.cpp @@ -5,6 +5,7 @@ #include "../Root.h" #include "../Server.h" #include "../ClientHandle.h" +#include "../Items/ItemHandler.h" #include "../World.h" #include "../EffectID.h" #include "../Entities/Player.h" @@ -996,7 +997,7 @@ void cMonster::UnsafeUnsetTarget() -cPawn * cMonster::GetTarget () +cPawn * cMonster::GetTarget() { return m_Target; } @@ -1005,29 +1006,25 @@ cPawn * cMonster::GetTarget () -cMonster * cMonster::NewMonsterFromType(eMonsterType a_MobType) +std::unique_ptr<cMonster> cMonster::NewMonsterFromType(eMonsterType a_MobType) { auto & Random = GetRandomProvider(); - cMonster * toReturn = nullptr; // Create the mob entity switch (a_MobType) { case mtMagmaCube: { - toReturn = new cMagmaCube(1 << Random.RandInt(2)); // Size 1, 2 or 4 - break; + return cpp14::make_unique<cMagmaCube>(1 << Random.RandInt(2)); // Size 1, 2 or 4 } case mtSlime: { - toReturn = new cSlime(1 << Random.RandInt(2)); // Size 1, 2 or 4 - break; + return cpp14::make_unique<cSlime>(1 << Random.RandInt(2)); // Size 1, 2 or 4 } case mtSkeleton: { // TODO: Actual detection of spawning in Nether - toReturn = new cSkeleton(false); - break; + return cpp14::make_unique<cSkeleton>(false); } case mtVillager: { @@ -1038,8 +1035,7 @@ cMonster * cMonster::NewMonsterFromType(eMonsterType a_MobType) VillagerType = 0; } - toReturn = new cVillager(static_cast<cVillager::eVillagerType>(VillagerType)); - break; + return cpp14::make_unique<cVillager>(static_cast<cVillager::eVillagerType>(VillagerType)); } case mtHorse: { @@ -1055,42 +1051,41 @@ cMonster * cMonster::NewMonsterFromType(eMonsterType a_MobType) HorseType = 0; } - toReturn = new cHorse(HorseType, HorseColor, HorseStyle, HorseTameTimes); - break; + return cpp14::make_unique<cHorse>(HorseType, HorseColor, HorseStyle, HorseTameTimes); } - case mtBat: toReturn = new cBat(); break; - case mtBlaze: toReturn = new cBlaze(); break; - case mtCaveSpider: toReturn = new cCaveSpider(); break; - case mtChicken: toReturn = new cChicken(); break; - case mtCow: toReturn = new cCow(); break; - case mtCreeper: toReturn = new cCreeper(); break; - case mtEnderDragon: toReturn = new cEnderDragon(); break; - case mtEnderman: toReturn = new cEnderman(); break; - case mtGhast: toReturn = new cGhast(); break; - case mtGiant: toReturn = new cGiant(); break; - case mtGuardian: toReturn = new cGuardian(); break; - case mtIronGolem: toReturn = new cIronGolem(); break; - case mtMooshroom: toReturn = new cMooshroom(); break; - case mtOcelot: toReturn = new cOcelot(); break; - case mtPig: toReturn = new cPig(); break; - case mtRabbit: toReturn = new cRabbit(); break; - case mtSheep: toReturn = new cSheep(); break; - case mtSilverfish: toReturn = new cSilverfish(); break; - case mtSnowGolem: toReturn = new cSnowGolem(); break; - case mtSpider: toReturn = new cSpider(); break; - case mtSquid: toReturn = new cSquid(); break; - case mtWitch: toReturn = new cWitch(); break; - case mtWither: toReturn = new cWither(); break; - case mtWolf: toReturn = new cWolf(); break; - case mtZombie: toReturn = new cZombie(false); break; // TODO: Infected zombie parameter - case mtZombiePigman: toReturn = new cZombiePigman(); break; + case mtBat: return cpp14::make_unique<cBat>(); + case mtBlaze: return cpp14::make_unique<cBlaze>(); + case mtCaveSpider: return cpp14::make_unique<cCaveSpider>(); + case mtChicken: return cpp14::make_unique<cChicken>(); + case mtCow: return cpp14::make_unique<cCow>(); + case mtCreeper: return cpp14::make_unique < cCreeper>(); + case mtEnderDragon: return cpp14::make_unique<cEnderDragon>(); + case mtEnderman: return cpp14::make_unique<cEnderman>(); + case mtGhast: return cpp14::make_unique<cGhast>(); + case mtGiant: return cpp14::make_unique<cGiant>(); + case mtGuardian: return cpp14::make_unique<cGuardian>(); + case mtIronGolem: return cpp14::make_unique<cIronGolem>(); + case mtMooshroom: return cpp14::make_unique<cMooshroom>(); + case mtOcelot: return cpp14::make_unique<cOcelot>(); + case mtPig: return cpp14::make_unique<cPig>(); + case mtRabbit: return cpp14::make_unique<cRabbit>(); + case mtSheep: return cpp14::make_unique<cSheep>(); + case mtSilverfish: return cpp14::make_unique<cSilverfish>(); + case mtSnowGolem: return cpp14::make_unique<cSnowGolem>(); + case mtSpider: return cpp14::make_unique<cSpider>(); + case mtSquid: return cpp14::make_unique<cSquid>(); + case mtWitch: return cpp14::make_unique<cWitch>(); + case mtWither: return cpp14::make_unique<cWither>(); + case mtWolf: return cpp14::make_unique<cWolf>(); + case mtZombie: return cpp14::make_unique<cZombie>(false); // TODO: Infected zombie parameter + case mtZombiePigman: return cpp14::make_unique<cZombiePigman>(); default: { ASSERT(!"Unhandled mob type whilst trying to spawn mob!"); + return nullptr; } } - return toReturn; } @@ -1099,7 +1094,13 @@ cMonster * cMonster::NewMonsterFromType(eMonsterType a_MobType) void cMonster::AddRandomDropItem(cItems & a_Drops, unsigned int a_Min, unsigned int a_Max, short a_Item, short a_ItemHealth) { - auto Count = GetRandomProvider().RandInt<char>(static_cast<char>(a_Min), static_cast<char>(a_Max)); + auto Count = GetRandomProvider().RandInt<unsigned int>(a_Min, a_Max); + auto MaxStackSize = static_cast<unsigned char>(ItemHandler(a_Item)->GetMaxStackSize()); + while (Count > MaxStackSize) + { + a_Drops.emplace_back(a_Item, MaxStackSize, a_ItemHealth); + Count -= MaxStackSize; + } if (Count > 0) { a_Drops.emplace_back(a_Item, Count, a_ItemHealth); diff --git a/src/Mobs/Monster.h b/src/Mobs/Monster.h index b79399a0f..268db6168 100644 --- a/src/Mobs/Monster.h +++ b/src/Mobs/Monster.h @@ -2,11 +2,11 @@ #pragma once #include "../Entities/Pawn.h" -#include "../Item.h" #include "MonsterTypes.h" #include "PathFinder.h" +class cItem; class cClientHandle; @@ -168,13 +168,13 @@ public: void UnsafeUnsetTarget(); /** Returns the current target. */ - cPawn * GetTarget (); + cPawn * GetTarget(); /** Creates a new object of the specified mob. a_MobType is the type of the mob to be created Asserts and returns null if mob type is not specified */ - static cMonster * NewMonsterFromType(eMonsterType a_MobType); + static std::unique_ptr<cMonster> NewMonsterFromType(eMonsterType a_MobType); /** Returns if this mob last target was a player to avoid destruction on player quit */ bool WasLastTargetAPlayer() const { return m_WasLastTargetAPlayer; } @@ -203,7 +203,11 @@ protected: bool ReachedFinalDestination(void) { return ((m_FinalDestination - GetPosition()).SqrLength() < WAYPOINT_RADIUS * WAYPOINT_RADIUS); } /** Returns whether or not the target is close enough for attack. */ - bool TargetIsInRange(void) { ASSERT(m_Target != nullptr); return ((m_Target->GetPosition() - GetPosition()).SqrLength() < (m_AttackRange * m_AttackRange)); } + bool TargetIsInRange(void) + { + ASSERT(GetTarget() != nullptr); + return ((GetTarget()->GetPosition() - GetPosition()).SqrLength() < (m_AttackRange * m_AttackRange)); + } /** Returns whether the monster needs to jump to reach a given height. */ inline bool DoesPosYRequireJump(double a_PosY) @@ -272,7 +276,9 @@ protected: void AddRandomWeaponDropItem(cItems & a_Drops, unsigned int a_LootingLevel); private: - /** A pointer to the entity this mobile is aiming to reach */ + /** A pointer to the entity this mobile is aiming to reach. + The validity of this pointer SHALL be guaranteed by the pointee; + it MUST be reset when the pointee changes worlds or is destroyed. */ cPawn * m_Target; } ; // tolua_export diff --git a/src/Mobs/Ocelot.cpp b/src/Mobs/Ocelot.cpp index 47776670c..e5004a1d1 100644 --- a/src/Mobs/Ocelot.cpp +++ b/src/Mobs/Ocelot.cpp @@ -6,6 +6,7 @@ #include "../Entities/Player.h" #include "../Items/ItemHandler.h" #include "Broadcaster.h" +#include "../BoundingBox.h" @@ -203,3 +204,30 @@ void cOcelot::SpawnOn(cClientHandle & a_ClientHandle) + +class cFindSittingCat : + public cEntityCallback +{ + virtual bool Item(cEntity * a_Entity) override + { + return ( + (a_Entity->GetEntityType() == cEntity::etMonster) && + (static_cast<cMonster *>(a_Entity)->GetMobType() == eMonsterType::mtOcelot) && + (static_cast<cOcelot *>(a_Entity)->IsSitting()) + ); + } +}; + + + + + +bool cOcelot::IsCatSittingOnBlock(cWorld * a_World, Vector3d a_BlockPosition) +{ + cFindSittingCat FindSittingCat; + return a_World->ForEachEntityInBox(cBoundingBox(Vector3d(a_BlockPosition.x, a_BlockPosition.y + 1, a_BlockPosition.z), 1), FindSittingCat); +} + + + + diff --git a/src/Mobs/Ocelot.h b/src/Mobs/Ocelot.h index 5729851fe..59b4f25af 100644 --- a/src/Mobs/Ocelot.h +++ b/src/Mobs/Ocelot.h @@ -54,6 +54,9 @@ public: } void SetCatType (eCatType a_CatType) { m_CatType = a_CatType; } + /** Returns true if there's a cat sitting above the given position */ + static bool IsCatSittingOnBlock(cWorld * a_World, Vector3d a_BlockPosition); + protected: bool m_IsSitting; diff --git a/src/Mobs/Skeleton.cpp b/src/Mobs/Skeleton.cpp index 0d6d5e428..e48991a06 100644 --- a/src/Mobs/Skeleton.cpp +++ b/src/Mobs/Skeleton.cpp @@ -57,19 +57,15 @@ bool cSkeleton::Attack(std::chrono::milliseconds a_Dt) Vector3d Inaccuracy = Vector3d(Random.RandReal<double>(-0.25, 0.25), Random.RandReal<double>(-0.25, 0.25), Random.RandReal<double>(-0.25, 0.25)); Vector3d Speed = (GetTarget()->GetPosition() + Inaccuracy - GetPosition()) * 5; Speed.y += Random.RandInt(-1, 1); - cArrowEntity * Arrow = new cArrowEntity(this, GetPosX(), GetPosY() + 1, GetPosZ(), Speed); - if (Arrow == nullptr) - { - return false; - } - if (!Arrow->Initialize(*m_World)) + + auto Arrow = cpp14::make_unique<cArrowEntity>(this, GetPosX(), GetPosY() + 1, GetPosZ(), Speed); + auto ArrowPtr = Arrow.get(); + if (!ArrowPtr->Initialize(std::move(Arrow), *m_World)) { - delete Arrow; - Arrow = nullptr; return false; } - ResetAttackCooldown(); + ResetAttackCooldown(); return true; } return false; diff --git a/src/Mobs/Slime.cpp b/src/Mobs/Slime.cpp index 3f832ae87..291a3a57f 100644 --- a/src/Mobs/Slime.cpp +++ b/src/Mobs/Slime.cpp @@ -78,10 +78,10 @@ void cSlime::KilledBy(TakeDamageInfo & a_TDI) double AddX = (i % 2 - 0.5) * m_Size / 4.0; double AddZ = (i / 2 - 0.5) * m_Size / 4.0; - cSlime * NewSlime = new cSlime(m_Size / 2); + auto NewSlime = cpp14::make_unique<cSlime>(m_Size / 2); NewSlime->SetPosition(GetPosX() + AddX, GetPosY() + 0.5, GetPosZ() + AddZ); NewSlime->SetYaw(Random.RandReal(360.0f)); - m_World->SpawnMobFinalize(NewSlime); + m_World->SpawnMobFinalize(std::move(NewSlime)); } } super::KilledBy(a_TDI); diff --git a/src/Mobs/Wither.cpp b/src/Mobs/Wither.cpp index fad51c05f..dd85d7d2b 100644 --- a/src/Mobs/Wither.cpp +++ b/src/Mobs/Wither.cpp @@ -15,6 +15,7 @@ cWither::cWither(void) : m_WitherInvulnerableTicks(220) { SetMaxHealth(300); + SetHealth(GetMaxHealth() / 3); } @@ -30,18 +31,6 @@ bool cWither::IsArmored(void) const -bool cWither::Initialize(cWorld & a_World) -{ - // Set health before BroadcastSpawnEntity() - SetHealth(GetMaxHealth() / 3); - - return super::Initialize(a_World); -} - - - - - bool cWither::DoTakeDamage(TakeDamageInfo & a_TDI) { if (a_TDI.DamageType == dtDrowning) diff --git a/src/Mobs/Wither.h b/src/Mobs/Wither.h index b430588c9..5f6ec607c 100644 --- a/src/Mobs/Wither.h +++ b/src/Mobs/Wither.h @@ -25,7 +25,6 @@ public: bool IsArmored(void) const; // cEntity overrides - virtual bool Initialize(cWorld & a_World) override; virtual void GetDrops(cItems & a_Drops, cEntity * a_Killer = nullptr) override; virtual bool DoTakeDamage(TakeDamageInfo & a_TDI) override; virtual void Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) override; diff --git a/src/Mobs/Wolf.h b/src/Mobs/Wolf.h index 70e761469..e05fedbf8 100644 --- a/src/Mobs/Wolf.h +++ b/src/Mobs/Wolf.h @@ -2,9 +2,9 @@ #pragma once #include "PassiveAggressiveMonster.h" -#include "../Entities/Entity.h" +class cEntity; |