From c865fc8ca501e7405da2ce8353628373e4526053 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Fri, 1 Aug 2014 22:05:40 +0100 Subject: [PATCH] Improved endermen code a little --- MCServer/monsters.ini | 2 +- src/Mobs/Enderman.cpp | 68 +++++++++++++++++++++++++++++++------------ src/Mobs/Enderman.h | 4 +++ src/Mobs/Monster.cpp | 4 ++- 4 files changed, 57 insertions(+), 21 deletions(-) diff --git a/MCServer/monsters.ini b/MCServer/monsters.ini index b631fc1a9..d29b01d8f 100644 --- a/MCServer/monsters.ini +++ b/MCServer/monsters.ini @@ -44,7 +44,7 @@ MaxHealth=10 AttackRange=2.0 AttackRate=1 AttackDamage=4.0 -SightDistance=25.0 +SightDistance=64.0 MaxHealth=40 [ZombiePigman] diff --git a/src/Mobs/Enderman.cpp b/src/Mobs/Enderman.cpp index a32e4e175..1dc73d654 100644 --- a/src/Mobs/Enderman.cpp +++ b/src/Mobs/Enderman.cpp @@ -14,9 +14,10 @@ class cPlayerLookCheck : public cPlayerListCallback { public: - cPlayerLookCheck(Vector3d a_EndermanPos) : + cPlayerLookCheck(Vector3d a_EndermanPos, int a_SightDistance) : m_Player(NULL), - m_EndermanPos(a_EndermanPos) + m_EndermanPos(a_EndermanPos), + m_SightDistance(a_SightDistance) { } @@ -30,8 +31,8 @@ public: Vector3d Direction = m_EndermanPos - a_Player->GetPosition(); - // Don't check players who are more then 64 blocks away - if (Direction.SqrLength() > 64) + // Don't check players who are more then SightDistance (64) blocks away + if (Direction.Length() > m_SightDistance) { return false; } @@ -48,7 +49,7 @@ public: // 0.09 rad ~ 5 degrees // If the player's crosshair is within 5 degrees of the enderman, it counts as looking - if (dot > cos(0.09)) + if (dot <= cos(0.09)) { return false; } @@ -69,6 +70,7 @@ public: protected: cPlayer * m_Player; Vector3d m_EndermanPos; + int m_SightDistance; } ; @@ -107,7 +109,7 @@ void cEnderman::CheckEventSeePlayer() return; } - cPlayerLookCheck Callback(GetPosition()); + cPlayerLookCheck Callback(GetPosition(), m_SightDistance); if (m_World->ForEachPlayer(Callback)) { return; @@ -115,20 +117,10 @@ void cEnderman::CheckEventSeePlayer() ASSERT(Callback.GetPlayer() != NULL); - int ChunkX, ChunkZ; - cChunkDef::BlockToChunk(POSX_TOINT, POSZ_TOINT, ChunkX, ChunkZ); - - // Check if the chunk the enderman is in is lit - if (!m_World->IsChunkLighted(ChunkX, ChunkZ)) + if (!CheckLight()) { - m_World->QueueLightChunk(ChunkX, ChunkZ); - return; - } - - // Enderman only attack if the skylight is higher than 7 - if (m_World->GetBlockSkyLight(POSX_TOINT, POSY_TOINT, POSZ_TOINT) <= 7) - { - // TODO: Teleport the enderman to a random spot + // Insufficient light for enderman to become aggravated + // TODO: Teleport to a suitable location return; } @@ -140,6 +132,19 @@ void cEnderman::CheckEventSeePlayer() GetWorld()->BroadcastEntityMetadata(*this); } } + + + + + +void cEnderman::CheckEventLostPlayer(void) +{ + super::CheckEventLostPlayer(); + if (!CheckLight()) + { + EventLosePlayer(); + } +} @@ -151,3 +156,28 @@ void cEnderman::EventLosePlayer() m_bIsScreaming = false; GetWorld()->BroadcastEntityMetadata(*this); } + + + + + +bool cEnderman::CheckLight() +{ + int ChunkX, ChunkZ; + cChunkDef::BlockToChunk(POSX_TOINT, POSZ_TOINT, ChunkX, ChunkZ); + + // Check if the chunk the enderman is in is lit + if (!m_World->IsChunkLighted(ChunkX, ChunkZ)) + { + m_World->QueueLightChunk(ChunkX, ChunkZ); + return true; + } + + // Enderman only attack if the skylight is lower or equal to 8 + if (m_World->GetBlockSkyLight(POSX_TOINT, POSY_TOINT, POSZ_TOINT) - GetWorld()->GetSkyDarkness() > 8) + { + return false; + } + + return true; +} diff --git a/src/Mobs/Enderman.h b/src/Mobs/Enderman.h index da857ee09..4583746e7 100644 --- a/src/Mobs/Enderman.h +++ b/src/Mobs/Enderman.h @@ -19,12 +19,16 @@ public: virtual void GetDrops(cItems & a_Drops, cEntity * a_Killer = NULL) override; virtual void CheckEventSeePlayer(void) override; + virtual void CheckEventLostPlayer(void) override; virtual void EventLosePlayer(void) override; bool IsScreaming(void) const {return m_bIsScreaming; } BLOCKTYPE GetCarriedBlock(void) const {return CarriedBlock; } NIBBLETYPE GetCarriedMeta(void) const {return CarriedMeta; } + /** Returns if the current sky light level is sufficient for the enderman to become aggravated */ + bool CheckLight(void); + private: bool m_bIsScreaming; diff --git a/src/Mobs/Monster.cpp b/src/Mobs/Monster.cpp index 622a67816..94df991a3 100644 --- a/src/Mobs/Monster.cpp +++ b/src/Mobs/Monster.cpp @@ -276,7 +276,9 @@ void cMonster::Tick(float a_Dt, cChunk & a_Chunk) if (DoesPosYRequireJump((int)floor(m_Destination.y))) { m_bOnGround = false; - AddSpeedY(5.2); // Jump!! + + // TODO: Change to AddSpeedY once collision detection is fixed - currently, mobs will go into blocks attempting to jump without a teleport + AddPosY(1.2); // Jump!! } }