summaryrefslogtreecommitdiffstats
path: root/source/Mobs/Monster.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'source/Mobs/Monster.cpp')
-rw-r--r--source/Mobs/Monster.cpp512
1 files changed, 0 insertions, 512 deletions
diff --git a/source/Mobs/Monster.cpp b/source/Mobs/Monster.cpp
deleted file mode 100644
index a42ae30ee..000000000
--- a/source/Mobs/Monster.cpp
+++ /dev/null
@@ -1,512 +0,0 @@
-
-#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
-
-#include "Monster.h"
-#include "../Root.h"
-#include "../Server.h"
-#include "../ClientHandle.h"
-#include "../World.h"
-#include "../Entities/Player.h"
-#include "../Defines.h"
-#include "../MonsterConfig.h"
-#include "../MersenneTwister.h"
-
-#include "../Vector3f.h"
-#include "../Vector3i.h"
-#include "../Vector3d.h"
-#include "../Tracer.h"
-#include "../Chunk.h"
-
-// #include "../../iniFile/iniFile.h"
-
-
-
-
-
-cMonster::cMonster(const AString & a_ConfigName, char a_ProtocolMobType, const AString & a_SoundHurt, const AString & a_SoundDeath, double a_Width, double a_Height)
- : super(etMob, a_Width, a_Height)
- , m_Target(NULL)
- , m_AttackRate(3)
- , idle_interval(0)
- , m_bMovingToDestination(false)
- , m_DestinationTime( 0 )
- , m_DestroyTimer( 0 )
- , m_Jump(0)
- , m_MobType(a_ProtocolMobType)
- , m_SoundHurt(a_SoundHurt)
- , m_SoundDeath(a_SoundDeath)
- , m_EMState(IDLE)
- , m_SightDistance(25)
- , m_SeePlayerInterval (0)
- , m_EMPersonality(AGGRESSIVE)
- , m_AttackDamage(1.0f)
- , m_AttackRange(5.0f)
- , m_AttackInterval(0)
- , m_BurnsInDaylight(false)
-{
- if (!a_ConfigName.empty())
- {
- GetMonsterConfig(a_ConfigName);
- }
-}
-
-
-
-
-
-void cMonster::SpawnOn(cClientHandle & a_Client)
-{
- a_Client.SendSpawnMob(*this);
-}
-
-
-
-
-
-void cMonster::MoveToPosition( const Vector3f & a_Position )
-{
- m_bMovingToDestination = true;
-
- m_Destination = a_Position;
-}
-
-
-
-
-
-bool cMonster::ReachedDestination()
-{
- Vector3f Distance = (m_Destination) - GetPosition();
- if( Distance.SqrLength() < 2.f )
- return true;
-
- return false;
-}
-
-
-
-
-
-void cMonster::Tick(float a_Dt, cChunk & a_Chunk)
-{
- super::Tick(a_Dt, a_Chunk);
-
- if (m_Health <= 0)
- {
- // The mob is dead, but we're still animating the "puff" they leave when they die
- m_DestroyTimer += a_Dt / 1000;
- if (m_DestroyTimer > 1)
- {
- Destroy(true);
- }
- return;
- }
-
- // Burning in daylight
- HandleDaylightBurning(a_Chunk);
-
- HandlePhysics(a_Dt,a_Chunk);
- BroadcastMovementUpdate();
-
- a_Dt /= 1000;
-
- if (m_bMovingToDestination)
- {
- Vector3f Pos( GetPosition() );
- Vector3f Distance = m_Destination - Pos;
- if( !ReachedDestination() )
- {
- Distance.y = 0;
- Distance.Normalize();
- Distance *= 3;
- SetSpeedX( Distance.x );
- SetSpeedZ( Distance.z );
-
- if (m_EMState == ESCAPING)
- { //Runs Faster when escaping :D otherwise they just walk away
- SetSpeedX (GetSpeedX() * 2.f);
- SetSpeedZ (GetSpeedZ() * 2.f);
- }
- }
- else
- {
- m_bMovingToDestination = false;
- }
-
- if( GetSpeed().SqrLength() > 0.f )
- {
- if( m_bOnGround )
- {
- Vector3f NormSpeed = Vector3f(GetSpeed()).NormalizeCopy();
- Vector3f NextBlock = Vector3f( GetPosition() ) + NormSpeed;
- int NextHeight;
- if (!m_World->TryGetHeight((int)NextBlock.x, (int)NextBlock.z, NextHeight))
- {
- // The chunk at NextBlock is not loaded
- return;
- }
- if( NextHeight > (GetPosY() - 1.0) && (NextHeight - GetPosY()) < 2.5 )
- {
- m_bOnGround = false;
- SetSpeedY(5.f); // Jump!!
- }
- }
- }
- }
-
- Vector3d Distance = m_Destination - GetPosition();
- if (Distance.SqrLength() > 0.1f)
- {
- double Rotation, Pitch;
- Distance.Normalize();
- VectorToEuler( Distance.x, Distance.y, Distance.z, Rotation, Pitch );
- SetHeadYaw (Rotation);
- SetRotation( Rotation );
- SetPitch( -Pitch );
- }
-
- switch (m_EMState)
- {
- case IDLE:
- {
- // If enemy passive we ignore checks for player visibility
- InStateIdle(a_Dt);
- break;
- }
-
- case CHASING:
- {
- // If we do not see a player anymore skip chasing action
- InStateChasing(a_Dt);
- break;
- }
-
- case ESCAPING:
- {
- InStateEscaping(a_Dt);
- break;
- }
- } // switch (m_EMState)
-}
-
-
-
-
-
-
-void cMonster::DoTakeDamage(TakeDamageInfo & a_TDI)
-{
- super::DoTakeDamage(a_TDI);
- if((m_SoundHurt != "") && (m_Health > 0)) m_World->BroadcastSoundEffect(m_SoundHurt, (int)(GetPosX() * 8), (int)(GetPosY() * 8), (int)(GetPosZ() * 8), 1.0f, 0.8f);
- if (a_TDI.Attacker != NULL)
- {
- m_Target = a_TDI.Attacker;
- AddReference(m_Target);
- }
-}
-
-
-
-
-
-void cMonster::KilledBy(cEntity * a_Killer)
-{
- super::KilledBy(a_Killer);
- if (m_SoundHurt != "")
- {
- m_World->BroadcastSoundEffect(m_SoundDeath, (int)(GetPosX() * 8), (int)(GetPosY() * 8), (int)(GetPosZ() * 8), 1.0f, 0.8f);
- }
- m_DestroyTimer = 0;
-}
-
-
-
-
-
-//----State Logic
-
-const char *cMonster::GetState()
-{
- switch(m_EMState)
- {
- case IDLE: return "Idle";
- case ATTACKING: return "Attacking";
- case CHASING: return "Chasing";
- default: return "Unknown";
- }
-}
-
-
-
-
-
-// for debugging
-void cMonster::SetState(const AString & a_State)
-{
- if (a_State.compare("Idle") == 0)
- {
- m_EMState = IDLE;
- }
- else if (a_State.compare("Attacking") == 0)
- {
- m_EMState = ATTACKING;
- }
- else if (a_State.compare("Chasing") == 0)
- {
- m_EMState = CHASING;
- }
- else
- {
- LOGD("cMonster::SetState(): Invalid state");
- ASSERT(!"Invalid state");
- }
-}
-
-
-
-
-
-//Checks to see if EventSeePlayer should be fired
-//monster sez: Do I see the player
-void cMonster::CheckEventSeePlayer(void)
-{
- // TODO: Rewrite this to use cWorld's DoWithPlayers()
- cPlayer * Closest = FindClosestPlayer();
-
- if (Closest != NULL)
- {
- EventSeePlayer(Closest);
- }
-}
-
-
-
-
-
-void cMonster::CheckEventLostPlayer(void)
-{
- Vector3f pos;
- cTracer LineOfSight(GetWorld());
-
- if (m_Target != NULL)
- {
- pos = m_Target->GetPosition();
- if ((pos - GetPosition()).Length() > m_SightDistance || LineOfSight.Trace(GetPosition(),(pos - GetPosition()), (int)(pos - GetPosition()).Length()))
- {
- EventLosePlayer();
- }
- }
- else
- {
- EventLosePlayer();
- }
-}
-
-
-
-
-
-// What to do if player is seen
-// default to change state to chasing
-void cMonster::EventSeePlayer(cEntity * a_SeenPlayer)
-{
- m_Target = a_SeenPlayer;
- AddReference(m_Target);
-}
-
-
-
-
-
-void cMonster::EventLosePlayer(void)
-{
- Dereference(m_Target);
- m_Target = NULL;
- m_EMState = IDLE;
-}
-
-
-
-
-
-// What to do if in Idle State
-void cMonster::InStateIdle(float a_Dt)
-{
- idle_interval += a_Dt;
- if (idle_interval > 1)
- {
- // at this interval the results are predictable
- int rem = m_World->GetTickRandomNumber(6) + 1;
- // LOGD("Moving: int: %3.3f rem: %i",idle_interval,rem);
- idle_interval -= 1; // So nothing gets dropped when the server hangs for a few seconds
- Vector3f Dist;
- Dist.x = (float)(m_World->GetTickRandomNumber(10) - 5);
- Dist.z = (float)(m_World->GetTickRandomNumber(10) - 5);
- if ((Dist.SqrLength() > 2) && (rem >= 3))
- {
- m_Destination.x = (float)(GetPosX() + Dist.x);
- m_Destination.z = (float)(GetPosZ() + Dist.z);
- int PosY;
- if (m_World->TryGetHeight((int)m_Destination.x, (int)m_Destination.z, PosY))
- {
- m_Destination.y = (float)PosY + 1.2f;
- MoveToPosition(m_Destination);
- }
- }
- }
-}
-
-
-
-
-
-// What to do if in Chasing State
-// This state should always be defined in each child class
-void cMonster::InStateChasing(float a_Dt)
-{
- UNUSED(a_Dt);
-}
-
-
-
-
-
-// What to do if in Escaping State
-void cMonster::InStateEscaping(float a_Dt)
-{
- UNUSED(a_Dt);
-
- if (m_Target != NULL)
- {
- Vector3d newloc = GetPosition();
- newloc.x = (m_Target->GetPosition().x < newloc.x)? (newloc.x + m_SightDistance): (newloc.x - m_SightDistance);
- newloc.z = (m_Target->GetPosition().z < newloc.z)? (newloc.z + m_SightDistance): (newloc.z - m_SightDistance);
- MoveToPosition(newloc);
- }
- else
- {
- m_EMState = IDLE; // This shouldnt be required but just to be safe
- }
-}
-
-
-
-
-
-// Do attack here
-// a_Dt is passed so we can set attack rate
-void cMonster::Attack(float a_Dt)
-{
- m_AttackInterval += a_Dt * m_AttackRate;
- if ((m_Target != NULL) && (m_AttackInterval > 3.0))
- {
- // Setting this higher gives us more wiggle room for attackrate
- m_AttackInterval = 0.0;
- ((cPawn *)m_Target)->TakeDamage(*this);
- }
-}
-
-
-
-
-
-// Checks for Players close by and if they are visible return the closest
-cPlayer * cMonster::FindClosestPlayer(void)
-{
- return m_World->FindClosestPlayer(GetPosition(), m_SightDistance);
-}
-
-
-
-
-
-void cMonster::GetMonsterConfig(const AString & a_Name)
-{
- cRoot::Get()->GetMonsterConfig()->AssignAttributes(this, a_Name);
-}
-
-
-
-
-
-void cMonster::SetAttackRate(int ar)
-{
- m_AttackRate = (float)ar;
-}
-
-
-
-
-
-void cMonster::SetAttackRange(float ar)
-{
- m_AttackRange = ar;
-}
-
-
-
-
-
-void cMonster::SetAttackDamage(float ad)
-{
- m_AttackDamage = ad;
-}
-
-
-
-
-
-void cMonster::SetSightDistance(float sd)
-{
- m_SightDistance = sd;
-}
-
-
-
-
-
-void cMonster::AddRandomDropItem(cItems & a_Drops, unsigned int a_Min, unsigned int a_Max, short a_Item, short a_ItemHealth)
-{
- MTRand r1;
- int Count = r1.randInt() % (a_Max + 1 - a_Min) + a_Min;
- if (Count > 0)
- {
- a_Drops.push_back(cItem(a_Item, Count, a_ItemHealth));
- }
-}
-
-
-
-
-
-void cMonster::HandleDaylightBurning(cChunk & a_Chunk)
-{
- if (!m_BurnsInDaylight)
- {
- return;
- }
-
- int RelY = (int)floor(GetPosY());
- if ((RelY < 0) || (RelY >= cChunkDef::Height))
- {
- // Outside the world
- return;
- }
-
- int RelX = (int)floor(GetPosX()) - a_Chunk.GetPosX() * cChunkDef::Width;
- int RelZ = (int)floor(GetPosZ()) - a_Chunk.GetPosZ() * cChunkDef::Width;
- if (
- (a_Chunk.GetSkyLight(RelX, RelY, RelZ) == 15) && // In the daylight
- (a_Chunk.GetBlock(RelX, RelY, RelZ) != E_BLOCK_SOULSAND) && // Not on soulsand
- (GetWorld()->GetTimeOfDay() < (12000 + 1000)) && // It is nighttime
- !IsOnFire() // Not already burning
- )
- {
- // Burn for 100 ticks, then decide again
- StartBurning(100);
- }
-}
-
-
-
-