From 2574573c883fd7b5d19d19547f34dbef6820b5ea Mon Sep 17 00:00:00 2001 From: archshift Date: Sun, 8 Jun 2014 18:44:20 -0700 Subject: [PATCH] Monster: added IsUndead(), undead-specific entity effects --- src/Entities/Pawn.cpp | 6 ---- src/Mobs/Monster.cpp | 65 +++++++++++++++++++++++++++++++++++++++++++ src/Mobs/Monster.h | 6 ++++ 3 files changed, 71 insertions(+), 6 deletions(-) diff --git a/src/Entities/Pawn.cpp b/src/Entities/Pawn.cpp index 297b4afda..fee595e54 100644 --- a/src/Entities/Pawn.cpp +++ b/src/Entities/Pawn.cpp @@ -115,8 +115,6 @@ void cPawn::HandleEntityEffects(cEntityEffect::eType a_EffectType, cEntityEffect { // Base heal = 6, doubles for every increase in intensity Heal(6 * std::pow(2, a_Effect.GetIntensity()) * a_Effect.GetDistanceModifier()); - - // TODO: Harms undead return; } case cEntityEffect::effInstantDamage: @@ -124,8 +122,6 @@ void cPawn::HandleEntityEffects(cEntityEffect::eType a_EffectType, cEntityEffect // Base damage = 6, doubles for every increase in intensity int damage = 6 * std::pow(2, a_Effect.GetIntensity()); TakeDamage(dtPotionOfHarming, a_Effect.GetUser(), damage * a_Effect.GetDistanceModifier(), 0); - - // TODO: Heals undead return; } case cEntityEffect::effStrength: @@ -154,7 +150,6 @@ void cPawn::HandleEntityEffects(cEntityEffect::eType a_EffectType, cEntityEffect counter = 0; } - // TODO: Doesn't effect undead return; } case cEntityEffect::effPoison: @@ -173,7 +168,6 @@ void cPawn::HandleEntityEffects(cEntityEffect::eType a_EffectType, cEntityEffect counter = 0; } - // TODO: Doesn't effect undead or spiders return; } case cEntityEffect::effFireResistance: diff --git a/src/Mobs/Monster.cpp b/src/Mobs/Monster.cpp index 5843ca5a6..b8afbbc0c 100644 --- a/src/Mobs/Monster.cpp +++ b/src/Mobs/Monster.cpp @@ -435,6 +435,52 @@ void cMonster::HandleFalling() + +void cMonster::HandleEntityEffects(cEntityEffect::eType a_EffectType, cEntityEffect a_Effect) +{ + switch (a_EffectType) + { + case cEntityEffect::effPoison: + { + // Default effect for non-undead mobs and non-spiders + if (!IsUndead() && GetMobType() != mtSpider) break; + return; // No effect + } + case cEntityEffect::effRegeneration: + { + // Default effect for non-undead mobs + if (!IsUndead() && GetMobType()) break; + return; // No effect + } + case cEntityEffect::effInstantDamage: + { + // Default effect for non-undead mobs + if (!IsUndead() && GetMobType()) break; + + // Undead mobs are healed by instant damage + // Base heal = 6, doubles for every increase in intensity + Heal(6 * std::pow(2, a_Effect.GetIntensity()) * a_Effect.GetDistanceModifier()); + return; + } + case cEntityEffect::effInstantHealth: + { + // Default effect for non-undead mobs + if (!IsUndead() && GetMobType()) break; + + // Undead mobs are damaged by instant health + // Base damage = 6, doubles for every increase in intensity + int damage = 6 * std::pow(2, a_Effect.GetIntensity()); + TakeDamage(dtPotionOfHarming, a_Effect.GetUser(), damage * a_Effect.GetDistanceModifier(), 0); + return; + } + } + + super::HandleEntityEffects(a_EffectType, a_Effect); +} + + + + int cMonster::FindFirstNonAirBlockPosition(double a_PosX, double a_PosZ) { int PosY = POSY_TOINT; @@ -706,6 +752,25 @@ void cMonster::GetMonsterConfig(const AString & a_Name) +bool cMonster::IsUndead(void) +{ + switch (GetMobType()) + { + case mtZombie: + case mtZombiePigman: + case mtSkeleton: + case mtWither: + { + return true; + } + } + return false; +} + + + + + AString cMonster::MobTypeToString(cMonster::eType a_MobType) { // Mob types aren't sorted, so we need to search linearly: diff --git a/src/Mobs/Monster.h b/src/Mobs/Monster.h index 7d7e90eb2..dbf95fbed 100644 --- a/src/Mobs/Monster.h +++ b/src/Mobs/Monster.h @@ -107,6 +107,9 @@ public: /// Reads the monster configuration for the specified monster name and assigns it to this object. void GetMonsterConfig(const AString & a_Name); + /** Returns whether this mob is undead (skeleton, zombie, etc.) */ + bool IsUndead(void); + virtual void EventLosePlayer(void); virtual void CheckEventLostPlayer(void); @@ -178,6 +181,7 @@ protected: /** Stores if mobile is currently moving towards the ultimate, final destination */ bool m_bMovingToDestination; + /** Finds the first non-air block position (not the highest, as cWorld::GetHeight does) If current Y is nonsolid, goes down to try to find a solid block, then returns that + 1 If current Y is solid, goes up to find first nonsolid block, and returns that */ @@ -220,6 +224,8 @@ protected: int m_LastGroundHeight; /* =========================== */ + + virtual void HandleEntityEffects(cEntityEffect::eType a_EffectType, cEntityEffect a_Effect) override; float m_IdleInterval; float m_DestroyTimer;