From 17c5d4e0c9532ac8381f098dc3629b3066e720ec Mon Sep 17 00:00:00 2001 From: LogicParrot Date: Sat, 2 Sep 2017 18:15:22 +0300 Subject: Reimplemented creepers using Behaviors --- src/Entities/WitherSkullEntity.cpp | 1 + src/Mobs/Behaviors/BehaviorAttacker.cpp | 2 +- src/Mobs/Behaviors/BehaviorAttacker.h | 2 +- .../Behaviors/BehaviorAttackerSuicideBomber.cpp | 15 ++++++-- src/Mobs/Behaviors/BehaviorAttackerSuicideBomber.h | 2 +- src/Mobs/Creeper.cpp | 1 - src/Mobs/Creeper.h | 1 - src/Mobs/Monster.cpp | 41 ++++++++++++---------- 8 files changed, 39 insertions(+), 26 deletions(-) (limited to 'src') diff --git a/src/Entities/WitherSkullEntity.cpp b/src/Entities/WitherSkullEntity.cpp index 03385b283..cbf3d7ae9 100644 --- a/src/Entities/WitherSkullEntity.cpp +++ b/src/Entities/WitherSkullEntity.cpp @@ -1,4 +1,5 @@ + // WitherSkullEntity.cpp // Implements the cWitherSkullEntity class representing the entity used by both blue and black wither skulls diff --git a/src/Mobs/Behaviors/BehaviorAttacker.cpp b/src/Mobs/Behaviors/BehaviorAttacker.cpp index 0b6ce16f3..50ce8f6ad 100644 --- a/src/Mobs/Behaviors/BehaviorAttacker.cpp +++ b/src/Mobs/Behaviors/BehaviorAttacker.cpp @@ -101,7 +101,6 @@ void cBehaviorAttacker::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) { if (TargetIsInStrikeRadius() && TargetIsInLineOfSight()) { - m_Parent->StopMovingToPosition(); StrikeIfReady(); } else @@ -209,6 +208,7 @@ void cBehaviorAttacker::Strike() m_IsStriking = true; m_StrikeTickCnt = 0; m_Parent->PinBehavior(this); + m_Parent->StopMovingToPosition(); } diff --git a/src/Mobs/Behaviors/BehaviorAttacker.h b/src/Mobs/Behaviors/BehaviorAttacker.h index de375d60e..82a377112 100644 --- a/src/Mobs/Behaviors/BehaviorAttacker.h +++ b/src/Mobs/Behaviors/BehaviorAttacker.h @@ -14,7 +14,7 @@ class cBehaviorAttacker : public cBehavior public: cBehaviorAttacker(); - void AttachToMonster(cMonster & a_Parent); + virtual void AttachToMonster(cMonster & a_Parent); // Our host monster will call these once it loads its config file diff --git a/src/Mobs/Behaviors/BehaviorAttackerSuicideBomber.cpp b/src/Mobs/Behaviors/BehaviorAttackerSuicideBomber.cpp index a704e77da..bab9fd88f 100644 --- a/src/Mobs/Behaviors/BehaviorAttackerSuicideBomber.cpp +++ b/src/Mobs/Behaviors/BehaviorAttackerSuicideBomber.cpp @@ -21,15 +21,27 @@ cBehaviorAttackerSuicideBomber::cBehaviorAttackerSuicideBomber() : +void cBehaviorAttackerSuicideBomber::AttachToMonster(cMonster & a_Parent) +{ + cBehaviorAttacker::AttachToMonster(a_Parent); + m_Parent->AttachRightClickBehavior(this); +} + + + + + bool cBehaviorAttackerSuicideBomber::DoStrike(int a_StrikeTickCnt) { UNUSED(a_StrikeTickCnt); + LOGD("Suicide doStrike"); // phase 1: start blowing up if (a_StrikeTickCnt == 1) { + LOGD("Suicide START"); ASSERT(!m_bIsBlowing); m_Parent->GetWorld()->BroadcastSoundEffect("entity.creeper.primed", m_Parent->GetPosX(), m_Parent->GetPosY(), m_Parent->GetPosZ(), 1.f, (0.75f + (static_cast((m_Parent->GetUniqueID() * 23) % 32)) / 64)); @@ -72,9 +84,6 @@ void cBehaviorAttackerSuicideBomber::OnRightClicked(cPlayer & a_Player) } if (!m_BurnedWithFlintAndSteel) { - m_Parent->GetWorld()->BroadcastSoundEffect("entity.creeper.primed", m_Parent->GetPosX(), m_Parent->GetPosY(), m_Parent->GetPosZ(), 1.f, (0.75f + (static_cast((m_Parent->GetUniqueID() * 23) % 32)) / 64)); - m_bIsBlowing = true; - m_Parent->GetWorld()->BroadcastEntityMetadata(*m_Parent); m_BurnedWithFlintAndSteel = true; Strike(); } diff --git a/src/Mobs/Behaviors/BehaviorAttackerSuicideBomber.h b/src/Mobs/Behaviors/BehaviorAttackerSuicideBomber.h index d635446c3..b9cb155e8 100644 --- a/src/Mobs/Behaviors/BehaviorAttackerSuicideBomber.h +++ b/src/Mobs/Behaviors/BehaviorAttackerSuicideBomber.h @@ -8,7 +8,7 @@ class cBehaviorAttackerSuicideBomber : public cBehaviorAttacker { public: cBehaviorAttackerSuicideBomber(); - + void AttachToMonster(cMonster & a_Parent) override; // cBehaviorAttacker also implements those and we need to call super on them void DoTakeDamage(TakeDamageInfo & a_TDI) override; diff --git a/src/Mobs/Creeper.cpp b/src/Mobs/Creeper.cpp index 7dd110038..8fb46a3c3 100644 --- a/src/Mobs/Creeper.cpp +++ b/src/Mobs/Creeper.cpp @@ -17,7 +17,6 @@ cCreeper::cCreeper(void) : m_BehaviorAttackerSuicideBomber.AttachToMonster(*this); m_BehaviorWanderer.AttachToMonster(*this); m_BehaviorAggressive.AttachToMonster(*this); - m_BehaviourDayLightBurner.AttachToMonster(*this); GetMonsterConfig("Creeper"); } diff --git a/src/Mobs/Creeper.h b/src/Mobs/Creeper.h index 60a33fe7b..c08a6e451 100644 --- a/src/Mobs/Creeper.h +++ b/src/Mobs/Creeper.h @@ -32,7 +32,6 @@ private: // other behaviors cBehaviorAggressive m_BehaviorAggressive; - cBehaviorDayLightBurner m_BehaviourDayLightBurner; } ; diff --git a/src/Mobs/Monster.cpp b/src/Mobs/Monster.cpp index ae2d601cc..bf6eda50c 100644 --- a/src/Mobs/Monster.cpp +++ b/src/Mobs/Monster.cpp @@ -332,31 +332,37 @@ void cMonster::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) // do not tick behaviors // mobTodo temporary leash special case. Needs a behavior eventually. } - else if (m_PinnedBehavior != nullptr) - { - // A behavior is pinned. We give it control automatically. - ASSERT(m_CurrentTickControllingBehavior == m_PinnedBehavior); - m_CurrentTickControllingBehavior->Tick(a_Dt, a_Chunk); - } else { - // ask the behaviors sequentially if they are interested in controlling this mob - // Stop at the first one that says yes. - m_NewTickControllingBehavior = nullptr; - for (cBehavior * Behavior : m_AttachedTickBehaviors) + // STEP 1: Decide who'll control us this tick + + if (m_PinnedBehavior != nullptr) + { + // A behavior is pinned. We give it control automatically. + m_NewTickControllingBehavior = m_PinnedBehavior; + } + else { - if (Behavior->IsControlDesired(a_Dt, a_Chunk)) + // ask the behaviors sequentially if they are interested in controlling this mob + // Stop at the first one that says yes. + m_NewTickControllingBehavior = nullptr; + for (cBehavior * Behavior : m_AttachedTickBehaviors) { - m_NewTickControllingBehavior = Behavior; - break; + if (Behavior->IsControlDesired(a_Dt, a_Chunk)) + { + m_NewTickControllingBehavior = Behavior; + break; + } } } ASSERT(m_NewTickControllingBehavior != nullptr); // it's not OK if no one asks for control + + // STEP 2: decide whether to tick or do behavior swapping + if (m_CurrentTickControllingBehavior == m_NewTickControllingBehavior) { // The Behavior asking for control is the same as the behavior from last tick. // Nothing special, just tick it. - // LOGD("mobDebug - Tick"); m_CurrentTickControllingBehavior->Tick(a_Dt, a_Chunk); } else if (m_CurrentTickControllingBehavior == nullptr) @@ -374,6 +380,8 @@ void cMonster::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) } + // STEP 3: Behavior swapping if needed + // Make the current controlling behavior clean up if (m_TickControllingBehaviorState == OldControlEnding) { @@ -1359,9 +1367,7 @@ void cMonster::AttachDoTakeDamageBehavior(cBehavior * a_Behavior) void cMonster::PinBehavior(cBehavior * a_Behavior) { - ASSERT(m_TickControllingBehaviorState == Normal); m_PinnedBehavior = a_Behavior; - ASSERT(m_CurrentTickControllingBehavior == m_PinnedBehavior); } @@ -1370,8 +1376,7 @@ void cMonster::PinBehavior(cBehavior * a_Behavior) void cMonster::UnpinBehavior(cBehavior * a_Behavior) { - ASSERT(m_TickControllingBehaviorState == Normal); - ASSERT(m_PinnedBehavior = a_Behavior); + ASSERT(m_PinnedBehavior == a_Behavior); m_PinnedBehavior = nullptr; } -- cgit v1.2.3