summaryrefslogtreecommitdiffstats
path: root/src/Mobs
diff options
context:
space:
mode:
authorSamuel Barney <samjbarney@gmail.com>2014-08-26 01:26:00 +0200
committerSamuel Barney <samjbarney@gmail.com>2014-08-26 01:26:00 +0200
commitaa0b20e4043437c319e1fe83413878e3f034049c (patch)
tree8de8b02b0d8df4a435536ca2267740c149769a64 /src/Mobs
parentAdded it to the AllComponents.h (diff)
downloadcuberite-aa0b20e4043437c319e1fe83413878e3f034049c.tar
cuberite-aa0b20e4043437c319e1fe83413878e3f034049c.tar.gz
cuberite-aa0b20e4043437c319e1fe83413878e3f034049c.tar.bz2
cuberite-aa0b20e4043437c319e1fe83413878e3f034049c.tar.lz
cuberite-aa0b20e4043437c319e1fe83413878e3f034049c.tar.xz
cuberite-aa0b20e4043437c319e1fe83413878e3f034049c.tar.zst
cuberite-aa0b20e4043437c319e1fe83413878e3f034049c.zip
Diffstat (limited to 'src/Mobs')
-rw-r--r--src/Mobs/Components/AIAggressiveComponent.cpp272
-rw-r--r--src/Mobs/Components/AIAggresssiveComponent.cpp21
2 files changed, 272 insertions, 21 deletions
diff --git a/src/Mobs/Components/AIAggressiveComponent.cpp b/src/Mobs/Components/AIAggressiveComponent.cpp
new file mode 100644
index 000000000..a1b22af59
--- /dev/null
+++ b/src/Mobs/Components/AIAggressiveComponent.cpp
@@ -0,0 +1,272 @@
+
+#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
+#include "AIAggressiveComponent.h"
+#include <iostream>
+
+#include "../Monster.h"
+
+#include "../../World.h"
+#include "../../Entities/Player.h"
+#include "../../Tracer.h"
+
+
+
+
+
+cAIAggressiveComponent::cAIAggressiveComponent(cMonster * a_Monster) : cAIComponent(a_Monster), m_Target(NULL){
+ m_EMPersonality = AGGRESSIVE;
+}
+
+
+
+
+
+void cAIAggressiveComponent::Tick(float a_Dt, cChunk & a_Chunk)
+{
+ if (m_EMState == CHASING)
+ {
+ CheckEventLostPlayer();
+ }
+ else
+ {
+ CheckEventSeePlayer();
+ }
+
+ if (m_Target == NULL)
+ return;
+
+ cTracer LineOfSight(m_Self->GetWorld());
+ Vector3d AttackDirection(m_Target->GetPosition() - m_Self->GetPosition());
+
+ if (ReachedFinalDestination() && !LineOfSight.Trace(m_Self->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)
+{
+}
+
+
+
+
+
+void cAIAggressiveComponent::EventSeePlayer(cEntity * a_Entity)
+{
+ if (!((cPlayer *)a_Entity)->IsGameModeCreative())
+ {
+ m_Target = a_Entity;
+ m_EMState = CHASING;
+ }
+}
+
+
+
+
+// What to do if in Chasing State
+void cAIAggressiveComponent::InStateChasing(float a_Dt)
+{
+ if (m_Target != NULL)
+ {
+ if (m_Target->IsPlayer())
+ {
+ if (((cPlayer *)m_Target)->IsGameModeCreative())
+ {
+ m_EMState = IDLE;
+ return;
+ }
+ }
+
+ if (!IsMovingToTargetPosition())
+ {
+ MoveToPosition(m_Target->GetPosition());
+ }
+ }
+}
+
+
+
+
+bool cAIAggressiveComponent::ReachedFinalDestination()
+{
+ if ((m_Self->GetPosition() - m_FinalDestination).Length() <= m_Self->GetAttackComponent().GetAttackRange())
+ {
+ return true;
+ }
+
+ return false;
+}
+
+
+
+
+
+void cAIAggressiveComponent::MoveToPosition(const Vector3d & a_Position)
+{
+ FinishPathFinding();
+
+ m_FinalDestination = a_Position;
+ m_bMovingToDestination = true;
+ TickPathFinding();
+}
+
+
+
+
+
+void cAIAggressiveComponent::TickPathFinding()
+{
+ const int PosX = (int)floor(m_Self->GetPosX());
+ const int PosY = (int)floor(m_Self->GetPosY());
+ const int PosZ = (int)floor(m_Self->GetPosZ());
+
+ std::vector<Vector3d> m_PotentialCoordinates;
+ m_TraversedCoordinates.push_back(Vector3i(PosX, PosY, PosZ));
+
+ static const struct // Define which directions to try to move to
+ {
+ int x, z;
+ } gCrossCoords[] =
+ {
+ { 1, 0},
+ {-1, 0},
+ { 0, 1},
+ { 0, -1},
+ } ;
+
+ if ((PosY - 1 < 0) || (PosY + 2 > cChunkDef::Height) /* PosY + 1 will never be true if PosY + 2 is not */)
+ {
+ // Too low/high, can't really do anything
+ FinishPathFinding();
+ return;
+ }
+
+ for (size_t i = 0; i < ARRAYCOUNT(gCrossCoords); i++)
+ {
+ if (IsCoordinateInTraversedList(Vector3i(gCrossCoords[i].x + PosX, PosY, gCrossCoords[i].z + PosZ)))
+ {
+ continue;
+ }
+
+ BLOCKTYPE BlockAtY = m_Self->GetWorld()->GetBlock(gCrossCoords[i].x + PosX, PosY, gCrossCoords[i].z + PosZ);
+ BLOCKTYPE BlockAtYP = m_Self->GetWorld()->GetBlock(gCrossCoords[i].x + PosX, PosY + 1, gCrossCoords[i].z + PosZ);
+ BLOCKTYPE BlockAtYPP = m_Self->GetWorld()->GetBlock(gCrossCoords[i].x + PosX, PosY + 2, gCrossCoords[i].z + PosZ);
+ int LowestY = m_Self->GetMovementComponent().FindFirstNonAirBlockPosition(gCrossCoords[i].x + PosX, gCrossCoords[i].z + PosZ);
+ BLOCKTYPE BlockAtLowestY = m_Self->GetWorld()->GetBlock(gCrossCoords[i].x + PosX, LowestY, gCrossCoords[i].z + PosZ);
+
+ if (
+ (!cBlockInfo::IsSolid(BlockAtY)) &&
+ (!cBlockInfo::IsSolid(BlockAtYP)) &&
+ (!IsBlockLava(BlockAtLowestY)) &&
+ (BlockAtLowestY != E_BLOCK_CACTUS) &&
+ (PosY - LowestY < 4)
+ )
+ {
+ m_PotentialCoordinates.push_back(Vector3d((gCrossCoords[i].x + PosX), PosY, gCrossCoords[i].z + PosZ));
+ }
+ else if (
+ (cBlockInfo::IsSolid(BlockAtY)) &&
+ (BlockAtY != E_BLOCK_CACTUS) &&
+ (!cBlockInfo::IsSolid(BlockAtYP)) &&
+ (!cBlockInfo::IsSolid(BlockAtYPP)) &&
+ (BlockAtY != E_BLOCK_FENCE) &&
+ (BlockAtY != E_BLOCK_FENCE_GATE)
+ )
+ {
+ m_PotentialCoordinates.push_back(Vector3d((gCrossCoords[i].x + PosX), PosY + 1, gCrossCoords[i].z + PosZ));
+ }
+ }
+
+ if (!m_PotentialCoordinates.empty())
+ {
+ Vector3f ShortestCoords = m_PotentialCoordinates.front();
+ for (std::vector<Vector3d>::const_iterator itr = m_PotentialCoordinates.begin(); itr != m_PotentialCoordinates.end(); ++itr)
+ {
+ Vector3f Distance = m_FinalDestination - ShortestCoords;
+ Vector3f Distance2 = m_FinalDestination - *itr;
+ if (Distance.SqrLength() > Distance2.SqrLength())
+ {
+ ShortestCoords = *itr;
+ }
+ }
+
+ m_Destination = ShortestCoords;
+ m_Destination.z += 0.5f;
+ m_Destination.x += 0.5f;
+ }
+ else
+ {
+ FinishPathFinding();
+ }
+}
+
+
+
+
+
+bool cAIAggressiveComponent::IsMovingToTargetPosition()
+{
+ // Difference between destination x and target x is negligible (to 10^-12 precision)
+ if (fabsf((float)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_FinalDestination.z - (float)m_Target->GetPosZ()) > std::numeric_limits<float>::epsilon())
+ {
+ return false;
+ }
+ return true;
+}
+
+
+
+
+
+// Checks to see if EventSeePlayer should be fired
+// monster sez: Do I see the player
+void cAIAggressiveComponent::CheckEventSeePlayer(void)
+{
+ // TODO: Rewrite this to use cWorld's DoWithPlayers()
+ cPlayer * Closest = m_Self->GetWorld()->FindClosestPlayer(m_Self->GetPosition(), (float)m_Self->GetEnvironmentComponent().GetSightDistance(), false);
+
+ if (Closest != NULL)
+ {
+ EventSeePlayer(Closest);
+ }
+}
+
+
+
+
+
+void cAIAggressiveComponent::CheckEventLostPlayer(void)
+{
+ if (m_Target != NULL)
+ {
+ if ((m_Target->GetPosition() - m_Self->GetPosition()).Length() > m_Self->GetEnvironmentComponent().GetSightDistance())
+ {
+ EventLosePlayer();
+ }
+ }
+ else
+ {
+ EventLosePlayer();
+ }
+}
+
+
+
+
+
+void cAIAggressiveComponent::EventLosePlayer(void)
+{
+ m_Target = NULL;
+ m_EMState = IDLE;
+}
diff --git a/src/Mobs/Components/AIAggresssiveComponent.cpp b/src/Mobs/Components/AIAggresssiveComponent.cpp
deleted file mode 100644
index fd39e15fa..000000000
--- a/src/Mobs/Components/AIAggresssiveComponent.cpp
+++ /dev/null
@@ -1,21 +0,0 @@
-
-#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
-#include "AIAggressiveComponent.h"
-#include <iostream>
-
-#include "../Monster.h"
-
-
-cAIAggressiveComponent::cAIAggressiveComponent(cMonster * a_Monster) : cAIComponent(a_Monster), m_Target(NULL){}
-
-void cAIAggressiveComponent::Tick(float a_Dt, cChunk & a_Chunk)
-{
- super::Tick(a_Dt, a_Chunk);
-}
-
-
-void cAIAggressiveComponent::Attack(float a_Dt)
-{
-}
-
-