Cuberite
A lightweight, fast and extensible game server for Minecraft
Enderman.cpp
Go to the documentation of this file.
1 
2 #include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
3 
4 #include "Enderman.h"
5 #include "../Entities/Player.h"
6 #include "../LineBlockTracer.h"
7 
8 
9 
10 
12 // cPlayerLookCheck
14 {
15 public:
16  cPlayerLookCheck(Vector3d a_EndermanPos, int a_SightDistance) :
17  m_Player(nullptr),
18  m_EndermanPos(a_EndermanPos),
19  m_SightDistance(a_SightDistance)
20  {
21  }
22 
23  bool operator () (cPlayer & a_Player)
24  {
25  // Don't check players who cannot be targeted
26  if (!a_Player.CanMobsTarget())
27  {
28  return false;
29  }
30 
31  // Don't check players who are more than SightDistance (64) blocks away
32  auto Direction = m_EndermanPos - a_Player.GetPosition();
33  if (Direction.Length() > m_SightDistance)
34  {
35  return false;
36  }
37 
38  // Don't check if the player has a pumpkin on his head
40  {
41  return false;
42  }
43 
44  // If the player's crosshair is within 5 degrees of the enderman, it counts as looking
45  auto LookVector = a_Player.GetLookVector();
46  auto dot = Direction.Dot(LookVector);
47  if (dot <= cos(0.09)) // 0.09 rad ~ 5 degrees
48  {
49  return false;
50  }
51 
52  // TODO: Check if endermen are angered through water in Vanilla
54  {
55  // No direct line of sight
56  return false;
57  }
58 
59  m_Player = &a_Player;
60  return true;
61  }
62 
63  cPlayer * GetPlayer(void) const { return m_Player; }
64 
65 protected:
69 } ;
70 
71 
72 
73 
74 
76  super("Enderman", mtEnderman, "entity.endermen.hurt", "entity.endermen.death", 0.5, 2.9),
77  m_bIsScreaming(false),
78  m_CarriedBlock(E_BLOCK_AIR),
79  m_CarriedMeta(0)
80 {
81 }
82 
83 
84 
85 
86 
87 void cEnderman::GetDrops(cItems & a_Drops, cEntity * a_Killer)
88 {
89  unsigned int LootingLevel = 0;
90  if (a_Killer != nullptr)
91  {
93  }
94  AddRandomDropItem(a_Drops, 0, 1 + LootingLevel, E_ITEM_ENDER_PEARL);
95 }
96 
97 
98 
99 
100 
102 {
103  if (GetTarget() != nullptr)
104  {
105  return;
106  }
107 
109  if (m_World->ForEachPlayer(Callback))
110  {
111  return;
112  }
113 
114  ASSERT(Callback.GetPlayer() != nullptr);
115 
116  if (!CheckLight())
117  {
118  // Insufficient light for enderman to become aggravated
119  // TODO: Teleport to a suitable location
120  return;
121  }
122 
123  if (!Callback.GetPlayer()->CanMobsTarget())
124  {
125  return;
126  }
127 
128  // Target the player
129  cMonster::EventSeePlayer(Callback.GetPlayer(), a_Chunk);
130  m_EMState = CHASING;
131  m_bIsScreaming = true;
133 }
134 
135 
136 
137 
138 
140 {
142  if (!CheckLight())
143  {
144  EventLosePlayer();
145  }
146 }
147 
148 
149 
150 
151 
153 {
155  m_bIsScreaming = false;
157 }
158 
159 
160 
161 
162 
164 {
165  int ChunkX, ChunkZ;
167 
168  // Check if the chunk the enderman is in is lit
169  if (!m_World->IsChunkLighted(ChunkX, ChunkZ))
170  {
171  m_World->QueueLightChunk(ChunkX, ChunkZ);
172  return true;
173  }
174 
175  // Enderman only attack if the skylight is lower or equal to 8
177  {
178  return false;
179  }
180 
181  return true;
182 }
183 
184 
185 
186 
187 
188 void cEnderman::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk)
189 {
190  super::Tick(a_Dt, a_Chunk);
191  if (!IsTicking())
192  {
193  // The base class tick destroyed us
194  return;
195  }
196 
197  // Take damage when wet, drowning damage seems to be most appropriate
198  if (
200  (GetWorld()->IsWeatherWetAtXYZ(GetPosition().Floor()) || IsInWater())
201  )
202  {
203  EventLosePlayer();
204  TakeDamage(dtDrowning, nullptr, 1, 0);
205  // TODO teleport to a safe location
206  }
207 }
NIBBLETYPE GetBlockSkyLight(Vector3i a_BlockPos)
Returns the sky light value at the specified block position.
Definition: World.cpp:1891
T Dot(const Vector3< T > &a_Rhs) const
Definition: Vector3.h:105
virtual void Tick(std::chrono::milliseconds a_Dt, cChunk &a_Chunk) override
virtual void BroadcastEntityMetadata(const cEntity &a_Entity, const cClientHandle *a_Exclude=nullptr) override
cWorld * m_World
Definition: Entity.h:620
static bool IsValidHeight(int a_Height)
Validates a height-coordinate.
Definition: ChunkDef.h:212
virtual void CheckEventSeePlayer(cChunk &a_Chunk) override
Definition: Enderman.cpp:101
Definition: Player.h:27
cPawn * GetTarget()
Returns the current target.
Definition: Monster.cpp:1120
cPlayer * GetPlayer(void) const
Definition: Enderman.cpp:63
virtual void Tick(std::chrono::milliseconds a_Dt, cChunk &a_Chunk) override
Definition: Enderman.cpp:188
void AddRandomDropItem(cItems &a_Drops, unsigned int a_Min, unsigned int a_Max, short a_Item, short a_ItemHealth=0)
Adds a random number of a_Item between a_Min and a_Max to itemdrops a_Drops.
Definition: Monster.cpp:1215
Vector3d m_EndermanPos
Definition: Enderman.cpp:67
virtual void GetDrops(cItems &a_Drops, cEntity *a_Killer=nullptr) override
Returns the list of drops for this pawn when it is killed.
Definition: Enderman.cpp:87
unsigned int GetLevel(int a_EnchantmentID) const
Returns the level for the specified enchantment; 0 if not stored.
virtual bool IsInWater(void) const
Returns true if any part of the entity is in a water block.
Definition: Entity.h:500
cEnderman(void)
Definition: Enderman.cpp:75
static bool LineOfSightTrace(cWorld &a_World, const Vector3d &a_Start, const Vector3d &a_End, int a_Sight)
Returns true if the two positions are within line of sight (not obscured by blocks).
Definition: Chunk.h:49
cPlayer * m_Player
Definition: Enderman.cpp:66
enum cMonster::MState m_EMState
int m_SightDistance
Definition: Monster.h:275
static void BlockToChunk(int a_X, int a_Z, int &a_ChunkX, int &a_ChunkZ)
Converts absolute block coords to chunk coords:
Definition: ChunkDef.h:234
virtual void CheckEventLostPlayer(void)
Definition: Monster.cpp:726
cEnchantments m_Enchantments
Definition: Item.h:212
virtual void EventLosePlayer(void)
Definition: Monster.cpp:757
virtual void CheckEventLostPlayer(void) override
Definition: Enderman.cpp:139
Vector3d GetLookVector(void) const
Definition: Entity.cpp:2209
Direction
bool IsTicking(void) const
Returns true if the entity is valid and ticking.
Definition: Entity.cpp:2201
NIBBLETYPE GetSkyDarkness()
Get the current darkness level based on the time.
Definition: World.h:1077
#define POSX_TOINT
Definition: Entity.h:29
#define POSY_TOINT
Definition: Entity.h:30
bool IsChunkLighted(int a_ChunkX, int a_ChunkZ)
Definition: World.cpp:2961
#define ASSERT(x)
Definition: Globals.h:335
void TakeDamage(cEntity &a_Attacker)
Makes this pawn take damage from an attack by a_Attacker.
Definition: Entity.cpp:269
virtual void EventLosePlayer(void) override
Definition: Enderman.cpp:152
virtual void EventSeePlayer(cPlayer *a_Player, cChunk &a_Chunk)
Definition: Monster.cpp:747
virtual cItem GetEquippedWeapon(void) const
Returns the curently equipped weapon; empty item if none.
Definition: Entity.h:346
Definition: Entity.h:73
void QueueLightChunk(int a_ChunkX, int a_ChunkZ, std::unique_ptr< cChunkCoordCallback > a_Callback={})
Queues a chunk for lighting; a_Callback is called after the chunk is lighted.
Definition: World.cpp:2952
virtual cItem GetEquippedHelmet(void) const override
Returns the currently equipped helmet; empty item if none.
Definition: Player.h:63
const Vector3d & GetPosition(void) const
Exported in ManualBindings.
Definition: Entity.h:307
bool CanMobsTarget(void) const
Returns true if the player can be targeted by Mobs.
Definition: Player.cpp:1296
bool CheckLight(void)
Returns if the current sky light level is sufficient for the enderman to become aggravated.
Definition: Enderman.cpp:163
bool m_bIsScreaming
Definition: Enderman.h:35
#define POSZ_TOINT
Definition: Entity.h:31
short m_ItemType
Definition: Item.h:209
bool operator()(cPlayer &a_Player)
Definition: Enderman.cpp:23
cPlayerLookCheck(Vector3d a_EndermanPos, int a_SightDistance)
Definition: Enderman.cpp:16
cWorld * GetWorld(void) const
Definition: Entity.h:201
This class bridges a vector of cItem for safe access via Lua.
Definition: Item.h:234
virtual bool ForEachPlayer(cPlayerListCallback a_Callback) override
Calls the callback for each player in the list; returns true if all players processed, false if the callback aborted by returning true.
Definition: World.cpp:2549