Improved endermen code a little

master
Tiger Wang 2014-08-01 22:05:40 +01:00
parent 941a182d8a
commit c865fc8ca5
4 changed files with 57 additions and 21 deletions

View File

@ -44,7 +44,7 @@ MaxHealth=10
AttackRange=2.0
AttackRate=1
AttackDamage=4.0
SightDistance=25.0
SightDistance=64.0
MaxHealth=40
[ZombiePigman]

View File

@ -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;
}

View File

@ -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;

View File

@ -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!!
}
}