summaryrefslogtreecommitdiffstats
path: root/src/Mobs/Behaviors
diff options
context:
space:
mode:
Diffstat (limited to 'src/Mobs/Behaviors')
-rw-r--r--src/Mobs/Behaviors/BehaviorAggressive.cpp1
-rw-r--r--src/Mobs/Behaviors/BehaviorAttacker.cpp64
-rw-r--r--src/Mobs/Behaviors/BehaviorAttacker.h43
-rw-r--r--src/Mobs/Behaviors/BehaviorCoward.cpp2
4 files changed, 62 insertions, 48 deletions
diff --git a/src/Mobs/Behaviors/BehaviorAggressive.cpp b/src/Mobs/Behaviors/BehaviorAggressive.cpp
index ccea67eb4..b55c1b476 100644
--- a/src/Mobs/Behaviors/BehaviorAggressive.cpp
+++ b/src/Mobs/Behaviors/BehaviorAggressive.cpp
@@ -34,5 +34,6 @@ void cBehaviorAggressive::PreTick(std::chrono::milliseconds a_Dt, cChunk & a_Chu
cPawn * cBehaviorAggressive::FindNewTarget()
{
cPlayer * Closest = m_Parent->GetNearestPlayer();
+ if (!Closest->CanMobsTarget()) return nullptr;
return Closest; // May be null
}
diff --git a/src/Mobs/Behaviors/BehaviorAttacker.cpp b/src/Mobs/Behaviors/BehaviorAttacker.cpp
index 56a879e84..3113516ff 100644
--- a/src/Mobs/Behaviors/BehaviorAttacker.cpp
+++ b/src/Mobs/Behaviors/BehaviorAttacker.cpp
@@ -15,6 +15,7 @@ cBehaviorAttacker::cBehaviorAttacker() :
, m_AttackRange(1)
, m_AttackCoolDownTicksLeft(0)
, m_TicksSinceLastDamaged(100)
+ , m_IsStriking(false)
{
}
@@ -26,7 +27,6 @@ cBehaviorAttacker::cBehaviorAttacker() :
void cBehaviorAttacker::AttachToMonster(cMonster & a_Parent, cBehaviorStriker & a_ParentStriker)
{
m_Parent = &a_Parent;
- m_ParentStriker = &a_ParentStriker;
m_Parent->AttachTickBehavior(this);
m_Parent->AttachDestroyBehavior(this);
m_Parent->AttachPostTickBehavior(this);
@@ -54,8 +54,13 @@ void cBehaviorAttacker::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk)
{
UNUSED(a_Dt);
UNUSED(a_Chunk);
- /*
- * if ((GetTarget() != nullptr))
+
+ if (m_IsStriking) return;
+ // If we're striking, return. This allows derived classes to implement multi-tick strikes
+ // E.g. a blaze shooting 3 fireballs in consequative ticks.
+ // Derived class is expected to set m_IsStriking to false when the strike is done.
+
+ if ((GetTarget() != nullptr))
{
ASSERT(GetTarget()->IsTicking());
@@ -66,8 +71,8 @@ void cBehaviorAttacker::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk)
SetTarget(nullptr);
}
}
- } //mobTodo copied from monster.cpp
- * */
+ }
+
ASSERT((GetTarget() == nullptr) || (GetTarget()->IsPawn() && (GetTarget()->GetWorld() == m_Parent->GetWorld())));
// Stop targeting out of range targets
@@ -79,24 +84,20 @@ void cBehaviorAttacker::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk)
}
else
{
- if (TargetIsInStrikeRange())
+ if (TargetIsInStrikeRadiusAndLineOfSight())
{
- StrikeTarget();
+ StrikeTargetIfReady();
}
else
{
- ApproachTarget(); // potential mobTodo: decoupling approaching from attacking
- // Not important now, but important for future extensibility, e.g.
- // cow chases wheat but using the netherman approacher to teleport around.
+ m_Parent->MoveToPosition(m_Target->GetPosition());
+ // todo BehaviorApproacher
}
}
}
}
-void cBehaviorAttacker::ApproachTarget()
-{
- m_Parent->MoveToPosition(m_Target->GetPosition());
-}
+
@@ -189,7 +190,17 @@ void cBehaviorAttacker::SetTarget(cPawn * a_Target)
-bool cBehaviorAttacker::TargetIsInStrikeRange()
+bool cBehaviorAttacker::TargetIsInStrikeRadius(void)
+{
+ ASSERT(GetTarget() != nullptr);
+ return ((GetTarget()->GetPosition() - m_Parent->GetPosition()).SqrLength() < (m_AttackRange * m_AttackRange));
+}
+
+
+
+
+
+bool cBehaviorAttacker::TargetIsInStrikeRadiusAndLineOfSight()
{
ASSERT(m_Target != nullptr);
ASSERT(m_Parent != nullptr);
@@ -199,13 +210,17 @@ bool cBehaviorAttacker::TargetIsInStrikeRange()
Vector3d MyHeadPosition = m_Parent->GetPosition() + Vector3d(0, m_Parent->GetHeight(), 0);
Vector3d AttackDirection(GetTarget()->GetPosition() + Vector3d(0, GetTarget()->GetHeight(), 0) - MyHeadPosition);
- if (TargetIsInRange() && !LineOfSight.Trace(MyHeadPosition, AttackDirection, static_cast<int>(AttackDirection.Length())) && (GetHealth() > 0.0))
+ if (TargetIsInStrikeRadius() &&
+ !LineOfSight.Trace(MyHeadPosition, AttackDirection, static_cast<int>(AttackDirection.Length())) &&
+ (m_Parent->GetHealth() > 0.0)
+ )
+ {
+ return true;
+ }
+ else
{
- // Attack if reached destination, target isn't null, and have a clear line of sight to target (so won't attack through walls)
- Attack(a_Dt);
+ return false;
}
-
- return ((m_Target->GetPosition() - m_Parent->GetPosition()).SqrLength() < (m_AttackRange * m_AttackRange));
}
@@ -235,15 +250,12 @@ void cBehaviorAttacker::ResetStrikeCooldown()
-void cBehaviorAttacker::StrikeTarget()
+void cBehaviorAttacker::StrikeTargetIfReady()
{
if (m_AttackCoolDownTicksLeft != 0)
{
- cBehaviorStriker * Striker = m_ParentStriker;
- if (Striker != nullptr)
- {
- // Striker->Strike(m_Target); //mobTodo
- }
+ m_IsStriking = true;
+ StrikeTarget(); // Different derived classes implement strikes in different ways
ResetStrikeCooldown();
}
}
diff --git a/src/Mobs/Behaviors/BehaviorAttacker.h b/src/Mobs/Behaviors/BehaviorAttacker.h
index 67592acba..4573f9a4a 100644
--- a/src/Mobs/Behaviors/BehaviorAttacker.h
+++ b/src/Mobs/Behaviors/BehaviorAttacker.h
@@ -17,39 +17,32 @@ public:
cBehaviorAttacker();
void AttachToMonster(cMonster & a_Parent, cBehaviorStriker & a_ParentStriker);
- // Functions our host Monster should invoke:
- bool IsControlDesired(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) override;
- void Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) override;
- void Destroyed() override;
- void PostTick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) override;
- void DoTakeDamage(TakeDamageInfo & a_TDI) override;
// Our host monster will call these once it loads its config file
void SetAttackRate(float a_AttackRate);
void SetAttackRange(int a_AttackRange);
void SetAttackDamage(int a_AttackDamage);
+ // Behavior functions
+ virtual bool IsControlDesired(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) override;
+ virtual void Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) override;
+ void Destroyed() override;
+ virtual void PostTick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk) override;
+ void DoTakeDamage(TakeDamageInfo & a_TDI) override;
+
/** Returns the target pointer, or a nullptr if we're not targeting anyone. */
cPawn * GetTarget();
- /** Sets the target. */
+ /** Sets a new target. Forgets the older target if present. */
void SetTarget(cPawn * a_Target);
protected:
- void ApproachTarget();
- // virtual void ApproachTarget() = 0; //mobTodo
-private:
+ virtual void StrikeTarget() = 0;
- /** Our parent */
- cMonster * m_Parent;
- cBehaviorStriker * m_ParentStriker;
-
- // The mob we want to attack
- cPawn * m_Target;
-
- // Target stuff
- bool TargetIsInStrikeRange();
+ // Target related methods
+ bool TargetIsInStrikeRadius();
+ bool TargetIsInStrikeRadiusAndLineOfSight();
bool TargetOutOfSight();
- void StrikeTarget();
+ void StrikeTargetIfReady();
// Cooldown stuff
void ResetStrikeCooldown();
@@ -61,4 +54,14 @@ private:
int m_AttackCoolDownTicksLeft;
int m_TicksSinceLastDamaged; // How many ticks ago were we last damaged by a player?
+
+ bool m_IsStriking;
+private:
+
+ /** Our parent */
+ cMonster * m_Parent;
+
+ // The mob we want to attack
+ cPawn * m_Target;
+
};
diff --git a/src/Mobs/Behaviors/BehaviorCoward.cpp b/src/Mobs/Behaviors/BehaviorCoward.cpp
index c2c59a633..132735e0f 100644
--- a/src/Mobs/Behaviors/BehaviorCoward.cpp
+++ b/src/Mobs/Behaviors/BehaviorCoward.cpp
@@ -16,7 +16,6 @@ cBehaviorCoward::cBehaviorCoward() :
void cBehaviorCoward::AttachToMonster(cMonster & a_Parent)
{
- LOGD("mobDebug - Behavior Coward: Attach");
m_Parent = &a_Parent;
m_Parent->AttachTickBehavior(this);
m_Parent->AttachDoTakeDamageBehavior(this);
@@ -87,7 +86,6 @@ void cBehaviorCoward::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk)
void cBehaviorCoward::DoTakeDamage(TakeDamageInfo & a_TDI)
{
- LOGD("mobDebug - Behavior Coward: DoTakeDamage");
if ((a_TDI.Attacker != m_Parent) && (a_TDI.Attacker != nullptr))
{
m_Attacker = a_TDI.Attacker;