summaryrefslogtreecommitdiffstats
path: root/src/Entities/Compoments/AIAgresssiveComponent.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/Entities/Compoments/AIAgresssiveComponent.cpp')
-rw-r--r--src/Entities/Compoments/AIAgresssiveComponent.cpp122
1 files changed, 122 insertions, 0 deletions
diff --git a/src/Entities/Compoments/AIAgresssiveComponent.cpp b/src/Entities/Compoments/AIAgresssiveComponent.cpp
new file mode 100644
index 000000000..4dcd3e618
--- /dev/null
+++ b/src/Entities/Compoments/AIAgresssiveComponent.cpp
@@ -0,0 +1,122 @@
+#include "AIAgressiveComponent.h"
+
+
+
+void cAIAggressiveComponent::Tick(float a_Dt, cChunk & a_Chunk)
+{
+ super::Tick(a_Dt, a_Chunk);
+
+ if (m_EMState == CHASING)
+ {
+ CheckEventLostPlayer();
+ }
+ else
+ {
+ CheckEventSeePlayer();
+ }
+
+ if (m_Target == NULL)
+ return;
+
+ cTracer LineOfSight(GetWorld());
+ Vector3d AttackDirection(m_Target->GetPosition() - GetPosition());
+
+ if (ReachedFinalDestination() && !LineOfSight.Trace(GetPosition(), AttackDirection, (int)AttackDirection.Length()))
+ {
+ // 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 / 1000);
+ }
+}
+
+
+void cAIAggressiveComponent::Attack(float a_Dt)
+{
+ float attack_interval = m_Self->GetAttackInterval();
+ attack_interval += a_Dt * m_Self->GetAttackRate();
+
+ if ((m_Target != NULL) && (attack_interval > 3.0))
+ {
+ // Setting this higher gives us more wiggle room for attackrate
+ attack_interval = 0.0f;
+ m_Target->TakeDamage(dtMobAttack, m_Self, m_AttackDamage, 0);
+ }
+
+ m_Self->SetAttackInterval(attack_interval)
+}
+
+
+bool cAIAggressiveComponent::IsMovingToTargetPosition()
+{
+ // Difference between destination x and target x is negligible (to 10^-12 precision)
+ if (fabsf((float)m_Self->m_FinalDestination.x - (float)m_Target->GetPosX()) < std::numeric_limits<float>::epsilon())
+ {
+ return false;
+ }
+ // Difference between destination z and target z is negligible (to 10^-12 precision)
+ else if (fabsf((float)m_Self->m_FinalDestination.z - (float)m_Target->GetPosZ()) > std::numeric_limits<float>::epsilon())
+ {
+ return false;
+ }
+ return true;
+}
+
+
+/// Event Checkers
+void cAIAggressiveComponent::CheckEventLostPlayer(void)
+{
+ if (m_Target != NULL)
+ {
+ if ((m_Target->GetPosition() - GetPosition()).Length() > m_Self->GetSightDistance())
+ {
+ EventLosePlayer();
+ }
+ }
+ else
+ {
+ EventLosePlayer();
+ }
+}
+
+
+/// Event Handlers
+void cAggressiveMonster::EventSeePlayer(cEntity * a_Entity)
+{
+ if (!((cPlayer *)a_Entity)->IsGameModeCreative())
+ {
+ m_Target = a_Entity;
+ m_EMState = CHASING;
+ }
+}
+
+
+void cAIAggressiveComponent::EventLosePlayer(void)
+{
+ m_Target = NULL;
+ m_EMState = IDLE;
+}
+
+
+/// State Logic
+void cAggressiveMonster::InStateChasing(float a_Dt)
+{
+ super::InStateChasing(a_Dt);
+
+ if (m_Target != NULL)
+ {
+ if (m_Target->IsPlayer())
+ {
+ if (((cPlayer *)m_Target)->IsGameModeCreative())
+ {
+ m_EMState = IDLE;
+ return;
+ }
+ }
+
+ if (!IsMovingToTargetPosition())
+ {
+ m_Self->MoveToPosition(m_Target->GetPosition());
+ }
+ }
+}
+
+