From 9f03682258d949b3b6ddd4fedec93977dedbadde Mon Sep 17 00:00:00 2001 From: STRWarrior Date: Thu, 29 May 2014 13:34:38 +0200 Subject: Enderman attacks a player if he's looking at him. --- src/Mobs/Enderman.cpp | 90 +++++++++++++++++++++++++++++++++++++++++++++++++++ src/Mobs/Enderman.h | 1 + 2 files changed, 91 insertions(+) (limited to 'src') diff --git a/src/Mobs/Enderman.cpp b/src/Mobs/Enderman.cpp index becc99a86..bd5ed85f1 100644 --- a/src/Mobs/Enderman.cpp +++ b/src/Mobs/Enderman.cpp @@ -2,6 +2,66 @@ #include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules #include "Enderman.h" +#include "../Entities/Player.h" + + + + +/////////////////////////////////////////////////////////////////////////// +// cPlayerLookCheck +class cPlayerLookCheck : + public cPlayerListCallback +{ +public: + cPlayerLookCheck(Vector3d a_EndermanPos) : + m_EndermanPos(a_EndermanPos), + m_Player(NULL) + { + } + + virtual bool Item(cPlayer * a_Player) override + { + // Don't check players who are in creative gamemode. + if (a_Player->IsGameModeCreative()) + { + return false; + } + + Vector3d Direction = m_EndermanPos - a_Player->GetPosition(); + + // Don't check players who are more then 64 blocks away. + if (Direction.SqrLength() > 64) + { + return false; + } + + // Don't check if the player has a pumpkin on his head. + if (a_Player->GetEquippedHelmet().m_ItemType == E_BLOCK_PUMPKIN) + { + return false; + } + + Direction.Normalize(); + + Vector3d LookVector = a_Player->GetLookVector(); + LookVector.Normalize(); + + if ((Direction - LookVector).SqrLength() > 0.02) + { + return false; + } + + // TODO: Don't attack the player if there is a wall between the player and the enderman. + m_Player = a_Player; + return true; + } + + cPlayer * GetPlayer(void) const {return m_Player;} + bool HasFoundPlayer(void) const {return (m_Player != NULL);} +protected: + cPlayer * m_Player; + Vector3d m_EndermanPos; +} ; @@ -32,3 +92,33 @@ void cEnderman::GetDrops(cItems & a_Drops, cEntity * a_Killer) +void cEnderman::Tick(float a_Dt, cChunk & a_Chunk) +{ + super::Tick(a_Dt, a_Chunk); + + if (m_Target != NULL) + { + return; + } + + cPlayerLookCheck Callback(GetPosition()); + if (!m_World->ForEachPlayer(Callback)) + { + return; + } + + if (!Callback.HasFoundPlayer()) + { + return; + } + + m_bIsScreaming = true; + m_Target = Callback.GetPlayer(); + + m_World->BroadcastEntityMetadata(*this); +} + + + + + diff --git a/src/Mobs/Enderman.h b/src/Mobs/Enderman.h index 32e40e70b..be6e7bdf4 100644 --- a/src/Mobs/Enderman.h +++ b/src/Mobs/Enderman.h @@ -18,6 +18,7 @@ public: CLASS_PROTODEF(cEnderman); virtual void GetDrops(cItems & a_Drops, cEntity * a_Killer = NULL) override; + virtual void Tick(float a_Dt, cChunk & a_Chunk) override; bool IsScreaming(void) const {return m_bIsScreaming; } BLOCKTYPE GetCarriedBlock(void) const {return CarriedBlock; } -- cgit v1.2.3 From 806130a967685b0708b51afc576df09d70d47d79 Mon Sep 17 00:00:00 2001 From: STRWarrior Date: Thu, 29 May 2014 14:00:12 +0200 Subject: Swapped m_Player and m_EndermanPos --- src/Mobs/Enderman.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/Mobs/Enderman.cpp b/src/Mobs/Enderman.cpp index bd5ed85f1..40782d0b0 100644 --- a/src/Mobs/Enderman.cpp +++ b/src/Mobs/Enderman.cpp @@ -14,8 +14,8 @@ class cPlayerLookCheck : { public: cPlayerLookCheck(Vector3d a_EndermanPos) : - m_EndermanPos(a_EndermanPos), - m_Player(NULL) + m_Player(NULL), + m_EndermanPos(a_EndermanPos) { } -- cgit v1.2.3 From 5d4f70a7a52e986343bddde2104f07c797c574c9 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Wed, 4 Jun 2014 09:19:55 +0100 Subject: Improved Enderman code --- src/Mobs/Enderman.cpp | 45 ++++++++++++++++++++++++++++++++------------- src/Mobs/Enderman.h | 3 ++- 2 files changed, 34 insertions(+), 14 deletions(-) (limited to 'src') diff --git a/src/Mobs/Enderman.cpp b/src/Mobs/Enderman.cpp index 40782d0b0..416b541ed 100644 --- a/src/Mobs/Enderman.cpp +++ b/src/Mobs/Enderman.cpp @@ -3,6 +3,7 @@ #include "Enderman.h" #include "../Entities/Player.h" +#include "../Tracer.h" @@ -51,13 +52,19 @@ public: return false; } - // TODO: Don't attack the player if there is a wall between the player and the enderman. + cTracer LineOfSight(a_Player->GetWorld()); + if (LineOfSight.Trace(m_EndermanPos, Direction, (int)Direction.Length())) + { + // No direct line of sight + return false; + } + m_Player = a_Player; return true; } - cPlayer * GetPlayer(void) const {return m_Player;} - bool HasFoundPlayer(void) const {return (m_Player != NULL);} + cPlayer * GetPlayer(void) const { return m_Player; } + protected: cPlayer * m_Player; Vector3d m_EndermanPos; @@ -92,33 +99,45 @@ void cEnderman::GetDrops(cItems & a_Drops, cEntity * a_Killer) -void cEnderman::Tick(float a_Dt, cChunk & a_Chunk) -{ - super::Tick(a_Dt, a_Chunk); - +void cEnderman::CheckEventSeePlayer() +{ if (m_Target != NULL) { return; } cPlayerLookCheck Callback(GetPosition()); - if (!m_World->ForEachPlayer(Callback)) + if (m_World->ForEachPlayer(Callback)) { return; } + + ASSERT(Callback.GetPlayer() != NULL); - if (!Callback.HasFoundPlayer()) + int CX, CZ; + cChunkDef::BlockToChunk(POSX_TOINT, POSZ_TOINT, CX, CZ); + if (!GetWorld()->IsChunkLighted(CX, CZ)) { + GetWorld()->QueueLightChunk(CX, CZ); return; } - m_bIsScreaming = true; - m_Target = Callback.GetPlayer(); - - m_World->BroadcastEntityMetadata(*this); + if ((GetWorld()->GetBlockSkyLight(POSX_TOINT, POSY_TOINT, POSZ_TOINT) - GetWorld()->GetSkyDarkness() < 15) && !Callback.GetPlayer()->IsGameModeCreative()) + { + super::EventSeePlayer(Callback.GetPlayer()); + m_EMState = CHASING; + m_bIsScreaming = true; + GetWorld()->BroadcastEntityMetadata(*this); + } } +void cEnderman::EventLosePlayer() +{ + super::EventLosePlayer(); + m_bIsScreaming = false; + GetWorld()->BroadcastEntityMetadata(*this); +} \ No newline at end of file diff --git a/src/Mobs/Enderman.h b/src/Mobs/Enderman.h index be6e7bdf4..044b40511 100644 --- a/src/Mobs/Enderman.h +++ b/src/Mobs/Enderman.h @@ -18,7 +18,8 @@ public: CLASS_PROTODEF(cEnderman); virtual void GetDrops(cItems & a_Drops, cEntity * a_Killer = NULL) override; - virtual void Tick(float a_Dt, cChunk & a_Chunk) override; + virtual void CheckEventSeePlayer(void) override; + virtual void EventLosePlayer(void) override; bool IsScreaming(void) const {return m_bIsScreaming; } BLOCKTYPE GetCarriedBlock(void) const {return CarriedBlock; } -- cgit v1.2.3 From 0690788cdfefbec3c74057e0b60d9f5aae935303 Mon Sep 17 00:00:00 2001 From: worktycho Date: Wed, 4 Jun 2014 14:16:24 +0100 Subject: Replaced strange algebra with dot product. 10 degrees is a completely arbitary constant I pulled from nowhere. Feel free to adjust this value. --- src/Mobs/Enderman.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/Mobs/Enderman.cpp b/src/Mobs/Enderman.cpp index 416b541ed..d26639a75 100644 --- a/src/Mobs/Enderman.cpp +++ b/src/Mobs/Enderman.cpp @@ -42,12 +42,14 @@ public: return false; } - Direction.Normalize(); Vector3d LookVector = a_Player->GetLookVector(); - LookVector.Normalize(); + double dot = Direction.Dot(LookVector); - if ((Direction - LookVector).SqrLength() > 0.02) + // 0.09 rad ~ 5 degrees. + // If the players crosshars are 10 degrees from the line linking the endermen + // It counts as looking. + if (dot > cos(0.09)) { return false; } @@ -140,4 +142,4 @@ void cEnderman::EventLosePlayer() super::EventLosePlayer(); m_bIsScreaming = false; GetWorld()->BroadcastEntityMetadata(*this); -} \ No newline at end of file +} -- cgit v1.2.3 From afda11a495de5b48ad17334da0e3f3b801d02f9b Mon Sep 17 00:00:00 2001 From: worktycho Date: Mon, 30 Jun 2014 19:33:10 +0100 Subject: Changed comment --- src/Mobs/Enderman.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/Mobs/Enderman.cpp b/src/Mobs/Enderman.cpp index d26639a75..6b7a22757 100644 --- a/src/Mobs/Enderman.cpp +++ b/src/Mobs/Enderman.cpp @@ -47,7 +47,7 @@ public: double dot = Direction.Dot(LookVector); // 0.09 rad ~ 5 degrees. - // If the players crosshars are 10 degrees from the line linking the endermen + // If the players crosshair is within 5 degrees of the endermen // It counts as looking. if (dot > cos(0.09)) { -- cgit v1.2.3 From 5daeba7e887ecf15b2facd3801f424a5bfcaa2e6 Mon Sep 17 00:00:00 2001 From: STRWarrior Date: Wed, 30 Jul 2014 13:59:47 +0200 Subject: Removed lighting code in cEnderman::CheckEventSeePlayer --- src/Mobs/Enderman.cpp | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) (limited to 'src') diff --git a/src/Mobs/Enderman.cpp b/src/Mobs/Enderman.cpp index 6b7a22757..9c1cb7ce3 100644 --- a/src/Mobs/Enderman.cpp +++ b/src/Mobs/Enderman.cpp @@ -116,15 +116,7 @@ void cEnderman::CheckEventSeePlayer() ASSERT(Callback.GetPlayer() != NULL); - int CX, CZ; - cChunkDef::BlockToChunk(POSX_TOINT, POSZ_TOINT, CX, CZ); - if (!GetWorld()->IsChunkLighted(CX, CZ)) - { - GetWorld()->QueueLightChunk(CX, CZ); - return; - } - - if ((GetWorld()->GetBlockSkyLight(POSX_TOINT, POSY_TOINT, POSZ_TOINT) - GetWorld()->GetSkyDarkness() < 15) && !Callback.GetPlayer()->IsGameModeCreative()) + if (!Callback.GetPlayer()->IsGameModeCreative()) { super::EventSeePlayer(Callback.GetPlayer()); m_EMState = CHASING; -- cgit v1.2.3 From c4e6a1423506c253974c7512a4b9b854a1e41b54 Mon Sep 17 00:00:00 2001 From: STRWarrior Date: Wed, 30 Jul 2014 19:18:11 +0200 Subject: Added lighting code and added comments --- src/Mobs/Enderman.cpp | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) (limited to 'src') diff --git a/src/Mobs/Enderman.cpp b/src/Mobs/Enderman.cpp index 9c1cb7ce3..f1f366d3b 100644 --- a/src/Mobs/Enderman.cpp +++ b/src/Mobs/Enderman.cpp @@ -116,6 +116,23 @@ 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)) + { + m_World->QueueLightChunk(ChunkX, ChunkZ); + return; + } + + // Enderman only attack if the skylight is higher than 6 + if (m_World->GetBlockSkyLight(POSX_TOINT, POSY_TOINT, POSZ_TOINT) <= 7) + { + // TODO: Teleport the enderman to a random spot. + return; + } + if (!Callback.GetPlayer()->IsGameModeCreative()) { super::EventSeePlayer(Callback.GetPlayer()); -- cgit v1.2.3 From ffd6797fe106c805646e2acfe5320594cc59ece4 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Thu, 31 Jul 2014 18:17:21 +0100 Subject: Comment suggestions --- src/Mobs/Enderman.cpp | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/Mobs/Enderman.cpp b/src/Mobs/Enderman.cpp index f1f366d3b..a32e4e175 100644 --- a/src/Mobs/Enderman.cpp +++ b/src/Mobs/Enderman.cpp @@ -22,7 +22,7 @@ public: virtual bool Item(cPlayer * a_Player) override { - // Don't check players who are in creative gamemode. + // Don't check players who are in creative gamemode if (a_Player->IsGameModeCreative()) { return false; @@ -30,13 +30,13 @@ public: Vector3d Direction = m_EndermanPos - a_Player->GetPosition(); - // Don't check players who are more then 64 blocks away. + // Don't check players who are more then 64 blocks away if (Direction.SqrLength() > 64) { return false; } - // Don't check if the player has a pumpkin on his head. + // Don't check if the player has a pumpkin on his head if (a_Player->GetEquippedHelmet().m_ItemType == E_BLOCK_PUMPKIN) { return false; @@ -46,9 +46,8 @@ public: Vector3d LookVector = a_Player->GetLookVector(); double dot = Direction.Dot(LookVector); - // 0.09 rad ~ 5 degrees. - // If the players crosshair is within 5 degrees of the endermen - // It counts as looking. + // 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)) { return false; @@ -119,17 +118,17 @@ void cEnderman::CheckEventSeePlayer() int ChunkX, ChunkZ; cChunkDef::BlockToChunk(POSX_TOINT, POSZ_TOINT, ChunkX, ChunkZ); - // Check if the chunk the enderman is in is lit. + // Check if the chunk the enderman is in is lit if (!m_World->IsChunkLighted(ChunkX, ChunkZ)) { m_World->QueueLightChunk(ChunkX, ChunkZ); return; } - // Enderman only attack if the skylight is higher than 6 + // 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. + // TODO: Teleport the enderman to a random spot return; } -- cgit v1.2.3