diff options
Diffstat (limited to '')
-rw-r--r-- | src/Mobs/CMakeLists.txt | 1 | ||||
-rw-r--r-- | src/Mobs/Components/AIAggressiveComponent.h | 25 | ||||
-rw-r--r-- | src/Mobs/Components/AIAggresssiveComponent.cpp | 155 | ||||
-rw-r--r-- | src/Mobs/Components/AIComponent.cpp | 5 | ||||
-rw-r--r-- | src/Mobs/Components/AIComponent.h | 15 | ||||
-rw-r--r-- | src/Mobs/Components/AllComponents.h | 3 | ||||
-rw-r--r-- | src/Mobs/Components/CMakeLists.txt | 11 |
7 files changed, 215 insertions, 0 deletions
diff --git a/src/Mobs/CMakeLists.txt b/src/Mobs/CMakeLists.txt index 53c265803..90294631e 100644 --- a/src/Mobs/CMakeLists.txt +++ b/src/Mobs/CMakeLists.txt @@ -10,3 +10,4 @@ file(GLOB SOURCE ) add_library(Mobs ${SOURCE}) +add_subdirectory(Components) diff --git a/src/Mobs/Components/AIAggressiveComponent.h b/src/Mobs/Components/AIAggressiveComponent.h new file mode 100644 index 000000000..28bfa7b2d --- /dev/null +++ b/src/Mobs/Components/AIAggressiveComponent.h @@ -0,0 +1,25 @@ +#pragma once +#include "AIComponent.h" + +class cAIAggressiveComponent : public cAIComponent { + typedef cAIComponent super; +protected: + enum MState{ATTACKING, IDLE, CHASING, ESCAPING} m_EMState; + cEntity * m_Target; +public: + cAIAggressiveComponent(cMonster * a_Monster); + + virtual void Tick(float a_Dt, cChunk & a_Chunk) override; + virtual void InStateChasing(float a_Dt); + + virtual void Attack(float a_Dt); + +protected: + virtual void CheckEventLostPlayer(void); + virtual void CheckEventSeePlayer(void); + virtual void EventLosePlayer(void); + virtual void EventSeePlayer(cEntity *); + + bool IsMovingToTargetPosition(); + bool ReachedFinalDestination(); +}; diff --git a/src/Mobs/Components/AIAggresssiveComponent.cpp b/src/Mobs/Components/AIAggresssiveComponent.cpp new file mode 100644 index 000000000..cd7e34e2f --- /dev/null +++ b/src/Mobs/Components/AIAggresssiveComponent.cpp @@ -0,0 +1,155 @@ + +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules +#include "AIAggressiveComponent.h" +#include "../Entities/Player.h" +#include "../Tracer.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); + + 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) +{ + 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_Self->GetAttackDamage(), 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; +} + + +bool cAIAggressiveComponent::ReachedFinalDestination() +{ + if ((m_Self->GetPosition() - m_Self->m_FinalDestination).Length() <= m_Self->GetAttackRange()) + { + return true; + } + + return false; +} + + +/// Event Checkers +//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->GetSightDistance(), false); + + if (Closest != NULL) + { + std::cout << "Found Player\n"; + EventSeePlayer(Closest); + } +} + + +void cAIAggressiveComponent::CheckEventLostPlayer(void) +{ + if (m_Target != NULL) + { + if ((m_Target->GetPosition() - m_Self->GetPosition()).Length() > m_Self->GetSightDistance()) + { + EventLosePlayer(); + } + } + else + { + EventLosePlayer(); + } +} + + +/// Event Handlers +void cAIAggressiveComponent::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 cAIAggressiveComponent::InStateChasing(float 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()); + } + } +} + + diff --git a/src/Mobs/Components/AIComponent.cpp b/src/Mobs/Components/AIComponent.cpp new file mode 100644 index 000000000..3f0a908b1 --- /dev/null +++ b/src/Mobs/Components/AIComponent.cpp @@ -0,0 +1,5 @@ +#include "Globals.h" +#include "AIComponent.h" +#include "Monster.h" + +cAIComponent::cAIComponent(cMonster * a_Entity) : m_Self(a_Entity){} diff --git a/src/Mobs/Components/AIComponent.h b/src/Mobs/Components/AIComponent.h new file mode 100644 index 000000000..3165f6c4f --- /dev/null +++ b/src/Mobs/Components/AIComponent.h @@ -0,0 +1,15 @@ +#pragma once +#include "../Entities/Entity.h" + +class cMonster; + +class cAIComponent +{ +protected: + cMonster * m_Self; +public: + cAIComponent(cMonster * a_Entity); + virtual ~cAIComponent(){} + + virtual void Tick(float a_Dt, cChunk & a_Chunk){} +}; diff --git a/src/Mobs/Components/AllComponents.h b/src/Mobs/Components/AllComponents.h new file mode 100644 index 000000000..1c8a76714 --- /dev/null +++ b/src/Mobs/Components/AllComponents.h @@ -0,0 +1,3 @@ +#pragma once + +#include "AIAggressiveComponent.h" diff --git a/src/Mobs/Components/CMakeLists.txt b/src/Mobs/Components/CMakeLists.txt new file mode 100644 index 000000000..55600cff6 --- /dev/null +++ b/src/Mobs/Components/CMakeLists.txt @@ -0,0 +1,11 @@ +cmake_minimum_required (VERSION 2.6) +project (MCServer) + +include_directories ("${PROJECT_SOURCE_DIR}/../") + +file(GLOB SOURCE + "*.cpp" + "*.h" +) + +add_library(Components ${SOURCE})
\ No newline at end of file |