From e8dd3278eaf66a49eea74769d1215944d6985d58 Mon Sep 17 00:00:00 2001 From: LogicParrot Date: Sat, 2 Sep 2017 16:30:55 +0300 Subject: Implemented creepers using Behaviors --- src/Mobs/Behaviors/BehaviorAttacker.cpp | 12 ++++----- src/Mobs/Behaviors/BehaviorAttacker.h | 17 +++++++------ src/Mobs/Behaviors/BehaviorAttackerMelee.cpp | 2 +- src/Mobs/Behaviors/BehaviorAttackerMelee.h | 2 +- src/Mobs/Behaviors/BehaviorAttackerRanged.cpp | 2 +- src/Mobs/Behaviors/BehaviorAttackerRanged.h | 2 +- .../Behaviors/BehaviorAttackerSuicideBomber.cpp | 29 +++++++++++----------- src/Mobs/Behaviors/BehaviorAttackerSuicideBomber.h | 2 +- src/Mobs/Creeper.cpp | 10 +++++--- src/Mobs/Creeper.h | 12 +++++++-- 10 files changed, 52 insertions(+), 38 deletions(-) (limited to 'src') diff --git a/src/Mobs/Behaviors/BehaviorAttacker.cpp b/src/Mobs/Behaviors/BehaviorAttacker.cpp index 2a22b3666..0b6ce16f3 100644 --- a/src/Mobs/Behaviors/BehaviorAttacker.cpp +++ b/src/Mobs/Behaviors/BehaviorAttacker.cpp @@ -59,7 +59,7 @@ void cBehaviorAttacker::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) if (m_IsStriking) { - if (DoStrikeTarget(++m_StrikeTickCnt)) + if (DoStrike(++m_StrikeTickCnt)) { m_Parent->UnpinBehavior(this); m_IsStriking = false; @@ -102,7 +102,7 @@ void cBehaviorAttacker::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) if (TargetIsInStrikeRadius() && TargetIsInLineOfSight()) { m_Parent->StopMovingToPosition(); - StrikeTargetIfReady(); + StrikeIfReady(); } else { @@ -200,9 +200,9 @@ void cBehaviorAttacker::SetTarget(cPawn * a_Target) -void cBehaviorAttacker::StrikeTarget() +void cBehaviorAttacker::Strike() { - if (m_IsStriking || (m_Target == nullptr)) + if (m_IsStriking) { return; } @@ -286,10 +286,10 @@ void cBehaviorAttacker::ResetStrikeCooldown() -void cBehaviorAttacker::StrikeTargetIfReady() +void cBehaviorAttacker::StrikeIfReady() { if (m_AttackCoolDownTicksLeft == 0) { - StrikeTarget(); + Strike(); } } diff --git a/src/Mobs/Behaviors/BehaviorAttacker.h b/src/Mobs/Behaviors/BehaviorAttacker.h index eeb6de2a0..de375d60e 100644 --- a/src/Mobs/Behaviors/BehaviorAttacker.h +++ b/src/Mobs/Behaviors/BehaviorAttacker.h @@ -35,26 +35,29 @@ public: /** Sets a new target. Forgets the older target if present. Set this to nullptr to unset target. */ void SetTarget(cPawn * a_Target); - /** Makes the mob strike a target the next tick. Ignores the strike cooldown. - * Ignored if already striking or if no target is set. */ - void StrikeTarget(); + /** Makes the mob perform a strike the next tick. Ignores the strike cooldown. + * Ignored if already striking. Some attack behaviors do not require a target + to be set (e.g. creeper explosion). The behaviors that require a target + ignore this call if the target is null. */ + void Strike(); /** Makes the mob strike a target the next tick only if the strike cooldown permits it. * Ignored if already striking or if no target is set. */ - void StrikeTargetIfReady(); + void StrikeIfReady(); protected: /** Called when the actual attack should be made. Will be called again and again every tick until it returns false. a_StrikeTickCnt tracks how many times it was called. It is 1 the first call. It increments by 1 each call. This mechanism allows multi-tick attacks, like blazes shooting multiple - fireballs, but most attacks are single tick and return true the first call. */ - virtual bool DoStrikeTarget(int a_StrikeTickCnt) = 0; + fireballs, but most attacks are single tick and return true the first call. Target is not guaranteed to be valid + during these calls. The behavior is pinned until true is returned, meaning no other behaviors can tick. */ + virtual bool DoStrike(int a_StrikeTickCnt) = 0; // Target related methods bool TargetIsInStrikeRadius(); bool TargetIsInLineOfSight(); bool TargetTooFar(); - void StrikeTargetIfReady(std::chrono::milliseconds a_Dt, cChunk & a_Chunk); + void StrikeIfReady(std::chrono::milliseconds a_Dt, cChunk & a_Chunk); // Cooldown stuff void ResetStrikeCooldown(); diff --git a/src/Mobs/Behaviors/BehaviorAttackerMelee.cpp b/src/Mobs/Behaviors/BehaviorAttackerMelee.cpp index 8203326e6..2bc0ef29d 100644 --- a/src/Mobs/Behaviors/BehaviorAttackerMelee.cpp +++ b/src/Mobs/Behaviors/BehaviorAttackerMelee.cpp @@ -5,7 +5,7 @@ #include "../../Entities/Pawn.h" #include "../../BlockID.h" -bool cBehaviorAttackerMelee::DoStrikeTarget(int a_StrikeTickCnt) +bool cBehaviorAttackerMelee::DoStrike(int a_StrikeTickCnt) { UNUSED(a_StrikeTickCnt); GetTarget()->TakeDamage(dtMobAttack, m_Parent, m_AttackDamage, 0); diff --git a/src/Mobs/Behaviors/BehaviorAttackerMelee.h b/src/Mobs/Behaviors/BehaviorAttackerMelee.h index bfde615f8..617b9d321 100644 --- a/src/Mobs/Behaviors/BehaviorAttackerMelee.h +++ b/src/Mobs/Behaviors/BehaviorAttackerMelee.h @@ -7,5 +7,5 @@ Use BehaviorAttackerMelee::SetTarget to attack. */ class cBehaviorAttackerMelee : public cBehaviorAttacker { public: - bool DoStrikeTarget(int a_StrikeTickCnt) override; + bool DoStrike(int a_StrikeTickCnt) override; }; diff --git a/src/Mobs/Behaviors/BehaviorAttackerRanged.cpp b/src/Mobs/Behaviors/BehaviorAttackerRanged.cpp index 2d5e0f0e3..366c77c68 100644 --- a/src/Mobs/Behaviors/BehaviorAttackerRanged.cpp +++ b/src/Mobs/Behaviors/BehaviorAttackerRanged.cpp @@ -6,7 +6,7 @@ #include "../../BlockID.h" #include "../../Entities/ArrowEntity.h" -bool cBehaviorAttackerRanged::DoStrikeTarget(int a_StrikeTickCnt) +bool cBehaviorAttackerRanged::DoStrike(int a_StrikeTickCnt) { UNUSED(a_StrikeTickCnt); auto & Random = GetRandomProvider(); diff --git a/src/Mobs/Behaviors/BehaviorAttackerRanged.h b/src/Mobs/Behaviors/BehaviorAttackerRanged.h index 069f9092f..012590490 100644 --- a/src/Mobs/Behaviors/BehaviorAttackerRanged.h +++ b/src/Mobs/Behaviors/BehaviorAttackerRanged.h @@ -7,5 +7,5 @@ Use BehaviorAttackerMelee::SetTarget to attack. */ class cBehaviorAttackerRanged : public cBehaviorAttacker { public: - bool DoStrikeTarget(int a_StrikeTickCnt) override; + bool DoStrike(int a_StrikeTickCnt) override; }; diff --git a/src/Mobs/Behaviors/BehaviorAttackerSuicideBomber.cpp b/src/Mobs/Behaviors/BehaviorAttackerSuicideBomber.cpp index ddf30326a..a704e77da 100644 --- a/src/Mobs/Behaviors/BehaviorAttackerSuicideBomber.cpp +++ b/src/Mobs/Behaviors/BehaviorAttackerSuicideBomber.cpp @@ -12,8 +12,7 @@ cBehaviorAttackerSuicideBomber::cBehaviorAttackerSuicideBomber() : m_bIsBlowing(false), m_bIsCharged(false), - m_BurnedWithFlintAndSteel(false), - m_ExplodingTimer(0) + m_BurnedWithFlintAndSteel(false) { } @@ -22,20 +21,11 @@ cBehaviorAttackerSuicideBomber::cBehaviorAttackerSuicideBomber() : -bool cBehaviorAttackerSuicideBomber::StrikeTarget(int a_StrikeTickCnt) +bool cBehaviorAttackerSuicideBomber::DoStrike(int a_StrikeTickCnt) { UNUSED(a_StrikeTickCnt); - ASSERT(GetTarget() != nullptr);// mobTodo guaranteed ? - if ((!TargetIsInStrikeRadius()) && (!m_BurnedWithFlintAndSteel)) - { - if (m_bIsBlowing) - { - m_bIsBlowing = false; - m_Parent->GetWorld()->BroadcastEntityMetadata(*m_Parent); - } - } // phase 1: start blowing up if (a_StrikeTickCnt == 1) @@ -48,15 +38,24 @@ bool cBehaviorAttackerSuicideBomber::StrikeTarget(int a_StrikeTickCnt) return false; } - return false; + ASSERT(m_bIsBlowing); + if (((GetTarget() == nullptr) || (!TargetIsInStrikeRadius())) && (!m_BurnedWithFlintAndSteel)) + { + m_bIsBlowing = false; + m_Parent->GetWorld()->BroadcastEntityMetadata(*m_Parent); + return true; + } if (a_StrikeTickCnt == 30) { - // mobTodo && (m_Parent->GetHealth() > 0.0) guaranteed ? + ASSERT(m_Parent->GetHealth() > 0.0); m_Parent->GetWorld()->DoExplosionAt((m_bIsCharged ? 5 : 3), m_Parent->GetPosX(), m_Parent->GetPosY(), m_Parent->GetPosZ(), false, esMonster, this); m_Parent->Destroy(); // Just in case we aren't killed by the explosion + return true; } + + return false; } @@ -77,7 +76,7 @@ void cBehaviorAttackerSuicideBomber::OnRightClicked(cPlayer & a_Player) m_bIsBlowing = true; m_Parent->GetWorld()->BroadcastEntityMetadata(*m_Parent); m_BurnedWithFlintAndSteel = true; - m_Parent->PinBehavior(this); + Strike(); } } } diff --git a/src/Mobs/Behaviors/BehaviorAttackerSuicideBomber.h b/src/Mobs/Behaviors/BehaviorAttackerSuicideBomber.h index 706bf0739..d635446c3 100644 --- a/src/Mobs/Behaviors/BehaviorAttackerSuicideBomber.h +++ b/src/Mobs/Behaviors/BehaviorAttackerSuicideBomber.h @@ -12,7 +12,7 @@ public: // cBehaviorAttacker also implements those and we need to call super on them void DoTakeDamage(TakeDamageInfo & a_TDI) override; - bool StrikeTarget(int a_StrikeTickCnt) override; + bool DoStrike(int a_StrikeTickCnt) override; void OnRightClicked(cPlayer & a_Player) override; bool IsBlowing(void) const; diff --git a/src/Mobs/Creeper.cpp b/src/Mobs/Creeper.cpp index 8d98a567f..7dd110038 100644 --- a/src/Mobs/Creeper.cpp +++ b/src/Mobs/Creeper.cpp @@ -14,6 +14,10 @@ cCreeper::cCreeper(void) : super(mtCreeper, "entity.creeper.hurt", "entity.creeper.death", 0.6, 1.8) { m_EMPersonality = AGGRESSIVE; + m_BehaviorAttackerSuicideBomber.AttachToMonster(*this); + m_BehaviorWanderer.AttachToMonster(*this); + m_BehaviorAggressive.AttachToMonster(*this); + m_BehaviourDayLightBurner.AttachToMonster(*this); GetMonsterConfig("Creeper"); } @@ -69,7 +73,7 @@ void cCreeper::GetDrops(cItems & a_Drops, cEntity * a_Killer) bool cCreeper::IsBlowing(void) const { - return m_BehaviorSuicideBomber.IsBlowing(); + return m_BehaviorAttackerSuicideBomber.IsBlowing(); } @@ -78,7 +82,7 @@ bool cCreeper::IsBlowing(void) const bool cCreeper::IsCharged(void) const { - return m_BehaviorSuicideBomber.IsCharged(); + return m_BehaviorAttackerSuicideBomber.IsCharged(); } @@ -87,5 +91,5 @@ bool cCreeper::IsCharged(void) const bool cCreeper::IsBurnedWithFlintAndSteel(void) const { - return m_BehaviorSuicideBomber.IsBurnedWithFlintAndSteel(); + return m_BehaviorAttackerSuicideBomber.IsBurnedWithFlintAndSteel(); } diff --git a/src/Mobs/Creeper.h b/src/Mobs/Creeper.h index 3d1af2ed1..60a33fe7b 100644 --- a/src/Mobs/Creeper.h +++ b/src/Mobs/Creeper.h @@ -3,7 +3,9 @@ #include "Monster.h" #include "Behaviors/BehaviorAttackerSuicideBomber.h" - +#include "Behaviors/BehaviorWanderer.h" +#include "Behaviors/BehaviorAggressive.h" +#include "Behaviors/BehaviorDayLightBurner.h" @@ -24,7 +26,13 @@ public: bool IsBurnedWithFlintAndSteel(void) const; private: - cBehaviorAttackerSuicideBomber m_BehaviorSuicideBomber; + // tick behaviors + cBehaviorAttackerSuicideBomber m_BehaviorAttackerSuicideBomber; + cBehaviorWanderer m_BehaviorWanderer; + + // other behaviors + cBehaviorAggressive m_BehaviorAggressive; + cBehaviorDayLightBurner m_BehaviourDayLightBurner; } ; -- cgit v1.2.3