Cuberite
A lightweight, fast and extensible game server for Minecraft
Creeper.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 "Creeper.h"
5 #include "../World.h"
6 #include "../Entities/ProjectileEntity.h"
7 #include "../Entities/Player.h"
8 
9 
10 
11 
12 
14  Super("Creeper", mtCreeper, "entity.creeper.hurt", "entity.creeper.death", "entity.creeper.ambient", 0.6f, 1.7f),
15  m_bIsBlowing(false),
16  m_bIsCharged(false),
17  m_BurnedWithFlintAndSteel(false),
18  m_ExplodingTimer(0)
19 {
20 }
21 
22 
23 
24 
25 
26 void cCreeper::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk)
27 {
28  Super::Tick(a_Dt, a_Chunk);
29  if (!IsTicking())
30  {
31  // The base class tick destroyed us
32  return;
33  }
34 
35  if (((GetTarget() == nullptr) || !TargetIsInRange()) && !m_BurnedWithFlintAndSteel)
36  {
37  if (m_bIsBlowing)
38  {
39  m_ExplodingTimer = 0;
40  m_bIsBlowing = false;
42  }
43  }
44  else
45  {
46  if (m_bIsBlowing)
47  {
48  m_ExplodingTimer += 1;
49  }
50 
51  if ((m_ExplodingTimer == 30) && (GetHealth() > 0.0)) // only explode when not already dead
52  {
53  m_World->DoExplosionAt((m_bIsCharged ? 5 : 3), GetPosX(), GetPosY(), GetPosZ(), false, esMonster, this);
54  Destroy(); // Just in case we aren't killed by the explosion
55  }
56  }
57 }
58 
59 
60 
61 
62 
63 void cCreeper::GetDrops(cItems & a_Drops, cEntity * a_Killer)
64 {
65  if (m_ExplodingTimer == 30)
66  {
67  // Exploded creepers drop naught but charred flesh, which Minecraft doesn't have
68  return;
69  }
70 
71  unsigned int LootingLevel = 0;
72  if (a_Killer != nullptr)
73  {
75  }
76  AddRandomDropItem(a_Drops, 0, 2 + LootingLevel, E_ITEM_GUNPOWDER);
77 
78  // If the creeper was killed by a skeleton, add a random music disc drop:
79  if (
80  (a_Killer != nullptr) &&
81  a_Killer->IsProjectile() &&
82  ((static_cast<cProjectileEntity *>(a_Killer))->GetCreatorUniqueID() != cEntity::INVALID_ID))
83  {
84  auto ProjectileCreatorCallback = [](cEntity & a_Entity)
85  {
86  return (
87  a_Entity.IsMob() &&
88  ((static_cast<cMonster &>(a_Entity)).GetMobType() == mtSkeleton)
89  );
90  };
91 
92  if (GetWorld()->DoWithEntityByID(static_cast<cProjectileEntity *>(a_Killer)->GetCreatorUniqueID(), ProjectileCreatorCallback))
93  {
94  AddRandomDropItem(a_Drops, 1, 1, static_cast<short>(m_World->GetTickRandomNumber(11) + E_ITEM_FIRST_DISC));
95  }
96  }
97 }
98 
99 
100 
101 
102 
104 {
105  if (!Super::DoTakeDamage(a_TDI))
106  {
107  return false;
108  }
109 
110  if (a_TDI.DamageType == dtLightning)
111  {
112  m_bIsCharged = true;
113  }
114 
116  return true;
117 }
118 
119 
120 
121 
122 
123 bool cCreeper::Attack(std::chrono::milliseconds a_Dt)
124 {
125  UNUSED(a_Dt);
126 
127  if (!m_bIsBlowing)
128  {
129  m_World->BroadcastSoundEffect("entity.creeper.primed", GetPosition(), 1.f, (0.75f + (static_cast<float>((GetUniqueID() * 23) % 32)) / 64));
130  m_bIsBlowing = true;
132 
133  return true;
134  }
135  return false;
136 }
137 
138 
139 
140 
141 
143 {
144  Super::OnRightClicked(a_Player);
145 
147  {
148  if (!a_Player.IsGameModeCreative())
149  {
150  a_Player.UseEquippedItem();
151  }
152  m_World->BroadcastSoundEffect("entity.creeper.primed", GetPosition(), 1.f, (0.75f + (static_cast<float>((GetUniqueID() * 23) % 32)) / 64));
153  m_bIsBlowing = true;
156  }
157 }
@ E_ITEM_FIRST_DISC
Definition: BlockType.h:505
@ E_ITEM_GUNPOWDER
Definition: BlockType.h:333
@ E_ITEM_FLINT_AND_STEEL
Definition: BlockType.h:303
@ esMonster
Definition: Defines.h:313
@ dtLightning
Definition: Defines.h:248
#define UNUSED
Definition: Globals.h:72
@ mtSkeleton
Definition: MonsterTypes.h:59
@ mtCreeper
Definition: MonsterTypes.h:21
Definition: Chunk.h:36
unsigned int GetLevel(int a_EnchantmentID) const
Returns the level for the specified enchantment; 0 if not stored.
eDamageType DamageType
Definition: Entity.h:61
Definition: Entity.h:76
bool IsProjectile(void) const
Definition: Entity.h:168
static const UInt32 INVALID_ID
Special ID that is considered an "invalid value", signifying no entity.
Definition: Entity.h:128
bool IsTicking(void) const
Returns true if the entity is valid and ticking.
Definition: Entity.cpp:2259
double GetPosX(void) const
Definition: Entity.h:195
cWorld * m_World
Definition: Entity.h:624
double GetPosZ(void) const
Definition: Entity.h:197
UInt32 GetUniqueID(void) const
Definition: Entity.h:253
void Destroy()
Destroys the entity, schedules it for memory freeing and broadcasts the DestroyEntity packet.
Definition: Entity.cpp:243
double GetPosY(void) const
Definition: Entity.h:196
virtual cItem GetEquippedWeapon(void) const
Returns the curently equipped weapon; empty item if none.
Definition: Entity.h:333
float GetHealth(void) const
Returns the health of this entity.
Definition: Entity.h:367
const Vector3d & GetPosition(void) const
Exported in ManualBindings.
Definition: Entity.h:297
cWorld * GetWorld(void) const
Definition: Entity.h:190
Definition: Player.h:29
const cItem & GetEquippedItem(void) const
Definition: Player.h:162
bool IsGameModeCreative(void) const
Returns true if the player is in Creative mode, either explicitly, or by inheriting from current worl...
Definition: Player.cpp:1025
void UseEquippedItem(short a_Damage=1)
Damage the player's equipped item by a_Damage, possibly less if the equipped item is enchanted.
Definition: Player.cpp:2033
UInt32 GetCreatorUniqueID(void) const
Returns the unique ID of the entity who created this projectile May return an ID <0.
cEnchantments m_Enchantments
Definition: Item.h:166
short m_ItemType
Definition: Item.h:163
This class bridges a vector of cItem for safe access via Lua.
Definition: Item.h:215
virtual void Tick(std::chrono::milliseconds a_Dt, cChunk &a_Chunk) override
virtual void Tick(std::chrono::milliseconds a_Dt, cChunk &a_Chunk) override
Definition: Creeper.cpp:26
virtual void OnRightClicked(cPlayer &a_Player) override
Called when the specified player right-clicks this entity.
Definition: Creeper.cpp:142
virtual bool Attack(std::chrono::milliseconds a_Dt) override
Try to perform attack returns true if attack was deemed successful (hit player, fired projectile,...
Definition: Creeper.cpp:123
virtual void GetDrops(cItems &a_Drops, cEntity *a_Killer=nullptr) override
Returns the list of drops for this pawn when it is killed.
Definition: Creeper.cpp:63
bool m_bIsBlowing
Definition: Creeper.h:33
bool m_BurnedWithFlintAndSteel
Definition: Creeper.h:33
int m_ExplodingTimer
Definition: Creeper.h:34
cCreeper()
Definition: Creeper.cpp:13
bool m_bIsCharged
Definition: Creeper.h:33
virtual bool DoTakeDamage(TakeDamageInfo &a_TDI) override
Makes this entity take damage specified in the a_TDI.
Definition: Creeper.cpp:103
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:1518
cPawn * GetTarget()
Returns the current target.
Definition: Monster.cpp:1243
virtual bool DoTakeDamage(TakeDamageInfo &a_TDI) override
Makes this entity take damage specified in the a_TDI.
Definition: Monster.cpp:572
virtual void OnRightClicked(cPlayer &a_Player) override
Called when the specified player right-clicks this entity.
Definition: Monster.cpp:697
bool TargetIsInRange(void)
Returns whether or not the target is close enough for attack.
Definition: Monster.h:276
virtual void DoExplosionAt(double a_ExplosionSize, double a_BlockX, double a_BlockY, double a_BlockZ, bool a_CanCauseFire, eExplosionSource a_Source, void *a_SourceData) override
Does an explosion with the specified strength at the specified coordinates.
Definition: World.cpp:1384
virtual void BroadcastEntityMetadata(const cEntity &a_Entity, const cClientHandle *a_Exclude=nullptr) override
int GetTickRandomNumber(int a_Range)
Returns a random number in range [0 .
Definition: World.cpp:2978
bool DoWithEntityByID(UInt32 a_UniqueID, cEntityCallback a_Callback)
Calls the callback if the entity with the specified ID is found, with the entity object as the callba...
Definition: World.cpp:2464
virtual void BroadcastSoundEffect(const AString &a_SoundName, Vector3d a_Position, float a_Volume, float a_Pitch, const cClientHandle *a_Exclude=nullptr) override