1
0

Merge pull request #2593 from cuberite/enderegg

Destroy an ender crystal when hit by an egg.
This commit is contained in:
Julian Laubstein 2015-11-05 18:10:19 +01:00
commit 056822845d
2 changed files with 103 additions and 92 deletions

View File

@ -84,16 +84,16 @@ public:
etFloater,
etItemFrame,
etPainting,
// Common variations
etMob = etMonster, // DEPRECATED, use etMonster instead!
} ;
// tolua_end
enum eEntityStatus
{
// TODO: Investiagate 0, 1, and 5 as Wiki.vg is not certain
// TODO: Investigate 0, 1, and 5 as Wiki.vg is not certain
// Entity becomes coloured red
esGenericHurt = 2,
@ -127,26 +127,26 @@ public:
// Informs client to explode a firework based on its metadata
esFireworkExploding = 17,
} ;
static const int FIRE_TICKS_PER_DAMAGE = 10; ///< Ticks to wait between damaging an entity when it stands in fire
static const int FIRE_DAMAGE = 1; ///< Damage to deal when standing in fire
static const int LAVA_TICKS_PER_DAMAGE = 10; ///< Ticks to wait between damaging an entity when it stands in lava
static const int LAVA_DAMAGE = 5; ///< Damage to deal when standing in lava
static const int BURN_TICKS_PER_DAMAGE = 20; ///< Ticks to wait between damaging an entity when it is burning
static const int BURN_DAMAGE = 1; ///< Damage to deal when the entity is burning
static const int BURN_TICKS = 200; ///< Ticks to keep an entity burning after it has stood in lava / fire
static const int MAX_AIR_LEVEL = 300; ///< Maximum air an entity can have
static const int DROWNING_TICKS = 20; ///< Number of ticks per heart of damage
static const int VOID_BOUNDARY = -46; ///< Y position to begin applying void damage
static const int FALL_DAMAGE_HEIGHT = 4; ///< Y difference after which fall damage is applied
/** Special ID that is considered an "invalid value", signifying no entity. */
static const UInt32 INVALID_ID = 0; // Exported to Lua in ManualBindings.cpp, ToLua doesn't parse initialized constants.
cEntity(eEntityType a_EntityType, double a_X, double a_Y, double a_Z, double a_Width, double a_Height);
virtual ~cEntity();
@ -155,9 +155,9 @@ public:
virtual bool Initialize(cWorld & a_World);
// tolua_begin
eEntityType GetEntityType(void) const { return m_EntityType; }
bool IsEnderCrystal(void) const { return (m_EntityType == etEnderCrystal); }
bool IsPlayer (void) const { return (m_EntityType == etPlayer); }
bool IsPickup (void) const { return (m_EntityType == etPickup); }
@ -172,16 +172,16 @@ public:
bool IsFloater (void) const { return (m_EntityType == etFloater); }
bool IsItemFrame (void) const { return (m_EntityType == etItemFrame); }
bool IsPainting (void) const { return (m_EntityType == etPainting); }
/** Returns true if the entity is of the specified class or a subclass (cPawn's IsA("cEntity") returns true) */
virtual bool IsA(const char * a_ClassName) const;
/** Returns the class name of this class */
static const char * GetClassStatic(void);
/** Returns the topmost class name for the object */
virtual const char * GetClass(void) const;
/** Returns the topmost class's parent class name for the object. cEntity returns an empty string (no parent). */
virtual const char * GetParentClass(void) const;
@ -203,7 +203,7 @@ public:
double GetSpeedY (void) const { return m_Speed.y; }
double GetSpeedZ (void) const { return m_Speed.z; }
double GetWidth (void) const { return m_Width; }
int GetChunkX(void) const { return FloorC(m_Position.x / cChunkDef::Width); }
int GetChunkZ(void) const { return FloorC(m_Position.z / cChunkDef::Width); }
@ -221,21 +221,21 @@ public:
/** Sets the speed of the entity, measured in m / sec */
void SetSpeed(double a_SpeedX, double a_SpeedY, double a_SpeedZ);
/** Sets the speed of the entity, measured in m / sec */
void SetSpeed(const Vector3d & a_Speed) { SetSpeed(a_Speed.x, a_Speed.y, a_Speed.z); }
/** Sets the speed in the X axis, leaving the other speed components intact. Measured in m / sec. */
void SetSpeedX(double a_SpeedX);
/** Sets the speed in the Y axis, leaving the other speed components intact. Measured in m / sec. */
void SetSpeedY(double a_SpeedY);
/** Sets the speed in the Z axis, leaving the other speed components intact. Measured in m / sec. */
void SetSpeedZ(double a_SpeedZ);
void SetWidth (double a_Width);
void AddPosX (double a_AddPosX) { AddPosition(a_AddPosX, 0, 0); }
void AddPosY (double a_AddPosY) { AddPosition(0, a_AddPosY, 0); }
void AddPosZ (double a_AddPosZ) { AddPosition(0, 0, a_AddPosZ); }
@ -246,7 +246,7 @@ public:
void AddSpeedX (double a_AddSpeedX);
void AddSpeedY (double a_AddSpeedY);
void AddSpeedZ (double a_AddSpeedZ);
virtual void HandleSpeedFromAttachee(float a_Forward, float a_Sideways);
void SteerVehicle(float a_Forward, float a_Sideways);
@ -258,60 +258,60 @@ public:
/** Makes this pawn take damage from an attack by a_Attacker. Damage values are calculated automatically and DoTakeDamage() called */
void TakeDamage(cEntity & a_Attacker);
/** Makes this entity take the specified damage. The final damage is calculated using current armor, then DoTakeDamage() called */
void TakeDamage(eDamageType a_DamageType, cEntity * a_Attacker, int a_RawDamage, double a_KnockbackAmount);
/** Makes this entity take the specified damage. The values are packed into a TDI, knockback calculated, then sent through DoTakeDamage() */
void TakeDamage(eDamageType a_DamageType, cEntity * a_Attacker, int a_RawDamage, int a_FinalDamage, double a_KnockbackAmount);
float GetGravity(void) const { return m_Gravity; }
void SetGravity(float a_Gravity) { m_Gravity = a_Gravity; }
float GetAirDrag(void) const { return m_AirDrag; }
void SetAirDrag(float a_AirDrag) { m_AirDrag = a_AirDrag; }
/** Sets the rotation to match the speed vector (entity goes "face-forward") */
void SetYawFromSpeed(void);
/** Sets the pitch to match the speed vector (entity gies "face-forward") */
void SetPitchFromSpeed(void);
// tolua_end
/** Makes this entity take damage specified in the a_TDI.
The TDI is sent through plugins first, then applied.
If it returns false, the entity hasn't receive any damage. */
virtual bool DoTakeDamage(TakeDamageInfo & a_TDI);
// tolua_begin
/** Returns the hitpoints that this pawn can deal to a_Receiver using its equipped items */
virtual int GetRawDamageAgainst(const cEntity & a_Receiver);
/** Returns whether armor will protect against the passed damage type */
virtual bool ArmorCoversAgainst(eDamageType a_DamageType);
/** Returns the hitpoints out of a_RawDamage that the currently equipped armor would cover */
virtual int GetArmorCoverAgainst(const cEntity * a_Attacker, eDamageType a_DamageType, int a_RawDamage);
/** Returns the knockback amount that the currently equipped items would cause to a_Receiver on a hit */
virtual double GetKnockbackAmountAgainst(const cEntity & a_Receiver);
/** Returns the curently equipped weapon; empty item if none */
virtual cItem GetEquippedWeapon(void) const { return cItem(); }
/** Returns the currently equipped helmet; empty item if none */
virtual cItem GetEquippedHelmet(void) const { return cItem(); }
/** Returns the currently equipped chestplate; empty item if none */
virtual cItem GetEquippedChestplate(void) const { return cItem(); }
/** Returns the currently equipped leggings; empty item if none */
virtual cItem GetEquippedLeggings(void) const { return cItem(); }
/** Returns the currently equipped boots; empty item if none */
virtual cItem GetEquippedBoots(void) const { return cItem(); }
@ -323,20 +323,20 @@ public:
/** Heals the specified amount of HPs */
virtual void Heal(int a_HitPoints);
/** Returns the health of this entity */
int GetHealth(void) const { return m_Health; }
/** Sets the health of this entity; doesn't broadcast any hurt animation */
void SetHealth(int a_Health);
// tolua_end
virtual void Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk);
/** Handles the physics of the entity - updates position based on speed, updates speed based on environment */
virtual void HandlePhysics(std::chrono::milliseconds a_Dt, cChunk & a_Chunk);
/** Updates the state related to this entity being on fire */
virtual void TickBurning(cChunk & a_Chunk);
@ -347,34 +347,34 @@ public:
Returns true if MoveToWorld() was called, false if not
*/
virtual bool DetectPortal(void);
/** Handles when the entity is in the void */
virtual void TickInVoid(cChunk & a_Chunk);
/** Called when the entity starts burning */
virtual void OnStartedBurning(void);
/** Called when the entity finishes burning */
virtual void OnFinishedBurning(void);
// tolua_begin
/** Sets the maximum value for the health */
void SetMaxHealth(int a_MaxHealth);
int GetMaxHealth(void) const { return m_MaxHealth; }
/** Sets whether the entity is fireproof */
void SetIsFireproof(bool a_IsFireproof);
virtual bool IsFireproof(void) const { return m_IsFireproof; }
/** Puts the entity on fire for the specified amount of ticks */
void StartBurning(int a_TicksLeftBurning);
/** Stops the entity from burning, resets all burning timers */
void StopBurning(void);
// tolua_end
/** Descendants override this function to send a command to the specified client to spawn the entity on the client.
@ -382,10 +382,10 @@ public:
virtual void SpawnOn(cClientHandle & a_Client) = 0;
// tolua_begin
/** Teleports to the entity specified */
virtual void TeleportToEntity(cEntity & a_Entity);
/** Teleports to the coordinates specified */
virtual void TeleportToCoords(double a_PosX, double a_PosY, double a_PosZ);
@ -399,7 +399,7 @@ public:
/** Moves entity to specified world, taking a world name */
bool MoveToWorld(const AString & a_WorldName, bool a_ShouldSendRespawn = true);
// tolua_end
virtual bool DoMoveToWorld(cWorld * a_World, bool a_ShouldSendRespawn, Vector3d a_NewPosition);
@ -409,16 +409,16 @@ public:
/** Sets the world the entity will be leaving */
void SetWorldTravellingFrom(cWorld * a_World) { m_WorldTravellingFrom = a_World; }
/** Updates clients of changes in the entity. */
virtual void BroadcastMovementUpdate(const cClientHandle * a_Exclude = nullptr);
/** Attaches to the specified entity; detaches from any previous one first */
void AttachTo(cEntity * a_AttachTo);
/** Detaches from the currently attached entity, if any */
virtual void Detach(void);
/** Makes sure head yaw is not over the specified range. */
void WrapHeadYaw();
@ -427,9 +427,9 @@ public:
/** Makes speed is not over 20. Max speed is 20 blocks / second */
void WrapSpeed();
// tolua_begin
// COMMON metadata flags; descendants may override the defaults:
virtual bool IsOnFire (void) const {return (m_TicksLeftBurning > 0); }
virtual bool IsCrouched (void) const {return false; }
@ -449,7 +449,7 @@ public:
/** Gets number of ticks this entity has existed for */
long int GetTicksAlive(void) const { return m_TicksAlive; }
/** Gets the invulnerable ticks from the entity */
int GetInvulnerableTicks(void) const { return m_InvulnerableTicks; }
@ -458,9 +458,9 @@ public:
/** Returns whether the entity is on ground or not */
virtual bool IsOnGround(void) const { return m_bOnGround; }
// tolua_end
/** Called when the specified player right-clicks this entity */
virtual void OnRightClicked(cPlayer & a_Player) {}
@ -488,7 +488,7 @@ protected:
static cCriticalSection m_CSCount;
static UInt32 m_EntityCount;
/** Measured in meters / second (m / s) */
Vector3d m_Speed;
@ -496,33 +496,33 @@ protected:
Always nonzero (a zero UniqueID (cEntity::INVALID_ID) is used for error reporting).
Note that the UniqueID is not persisted through storage. */
UInt32 m_UniqueID;
int m_Health;
int m_MaxHealth;
/** The entity to which this entity is attached (vehicle), nullptr if none */
cEntity * m_AttachedTo;
/** The entity which is attached to this entity (rider), nullptr if none */
cEntity * m_Attachee;
/** Stores whether head yaw has been set manually */
bool m_bDirtyHead;
/** Stores whether our yaw / pitch / roll (body orientation) has been set manually */
bool m_bDirtyOrientation;
/** Stores whether we have sent a Velocity packet with a speed of zero (no speed) to the client
Ensures that said packet is sent only once */
bool m_bHasSentNoSpeed;
/** Stores if the entity is on the ground */
bool m_bOnGround;
/** Stores gravity that is applied to an entity every tick
For realistic effects, this should be negative. For spaaaaaaace, this can be zero or even positive */
float m_Gravity;
/** Stores the air drag that is applied to the entity every tick, measured in speed ratio per tick
Acts as air friction and slows down flight
Will be interpolated if the server tick rate varies
@ -540,7 +540,7 @@ protected:
cWorld * m_WorldTravellingFrom;
eEntityType m_EntityType;
cWorld * m_World;
/** State variables for ScheduleMoveToWorld. */
@ -548,25 +548,25 @@ protected:
bool m_WorldChangeSetPortalCooldown;
cWorld * m_NewWorld;
Vector3d m_NewWorldPosition;
/** Whether the entity is capable of taking fire or lava damage. */
bool m_IsFireproof;
/** Time, in ticks, since the last damage dealt by being on fire. Valid only if on fire (IsOnFire()) */
int m_TicksSinceLastBurnDamage;
/** Time, in ticks, since the last damage dealt by standing in lava. Reset to zero when moving out of lava. */
int m_TicksSinceLastLavaDamage;
/** Time, in ticks, since the last damage dealt by standing in fire. Reset to zero when moving out of fire. */
int m_TicksSinceLastFireDamage;
/** Time, in ticks, until the entity extinguishes its fire */
int m_TicksLeftBurning;
/** Time, in ticks, since the last damage dealt by the void. Reset to zero when moving out of the void. */
int m_TicksSinceLastVoidDamage;
/** If an entity is currently swimming in or submerged under water */
bool m_IsSwimming, m_IsSubmerged;
@ -576,7 +576,7 @@ protected:
/** Portal delay timer and cooldown boolean data */
sPortalCooldownData m_PortalCooldownData;
/** The number of ticks this entity has been alive for */
long int m_TicksAlive;
@ -584,7 +584,7 @@ protected:
/** Does the actual speed-setting. The default implementation just sets the member variable value;
overrides can provide further processing, such as forcing players to move at the given speed. */
virtual void DoSetSpeed(double a_SpeedX, double a_SpeedY, double a_SpeedZ);
virtual void Destroyed(void) {} // Called after the entity has been destroyed
/** Applies friction to an entity
@ -594,33 +594,33 @@ protected:
/** Called in each tick to handle air-related processing i.e. drowning */
virtual void HandleAir(void);
/** Called once per tick to set IsSwimming and IsSubmerged */
virtual void SetSwimState(cChunk & a_Chunk);
private:
/** Measured in degrees, [-180, +180) */
double m_HeadYaw;
/** Measured in degrees, [-180, +180) */
Vector3d m_Rot;
/** Position of the entity's XZ center and Y bottom */
Vector3d m_Position;
/** Last position sent to client via the Relative Move or Teleport packets (not Velocity)
Only updated if cEntity::BroadcastMovementUpdate() is called! */
Vector3d m_LastSentPosition;
/** Measured in meter / second */
Vector3d m_WaterSpeed;
/** Measured in Kilograms (Kg) */
double m_Mass;
/** Width of the entity, in the XZ plane. Since entities are represented as cylinders, this is more of a diameter. */
double m_Width;
/** Height of the entity (Y axis) */
double m_Height;

View File

@ -21,7 +21,7 @@ cThrownEggEntity::cThrownEggEntity(cEntity * a_Creator, double a_X, double a_Y,
void cThrownEggEntity::OnHitSolidBlock(const Vector3d & a_HitPos, eBlockFace a_HitFace)
{
TrySpawnChicken(a_HitPos);
m_DestroyTimer = 2;
}
@ -32,11 +32,18 @@ void cThrownEggEntity::OnHitSolidBlock(const Vector3d & a_HitPos, eBlockFace a_H
void cThrownEggEntity::OnHitEntity(cEntity & a_EntityHit, const Vector3d & a_HitPos)
{
int TotalDamage = 0;
// TODO: If entity is Ender Crystal, destroy it
// If entity is an Ender Dragon or Ender Crystal, it is damaged.
if (
(a_EntityHit.IsMob() && (static_cast<cMonster &>(a_EntityHit).GetMobType() == mtEnderDragon)) ||
a_EntityHit.IsEnderCrystal()
)
{
TotalDamage = 1;
}
TrySpawnChicken(a_HitPos);
a_EntityHit.TakeDamage(dtRangedAttack, this, TotalDamage, 1);
m_DestroyTimer = 5;
}
@ -79,3 +86,7 @@ void cThrownEggEntity::TrySpawnChicken(const Vector3d & a_HitPos)
m_World->SpawnMob(a_HitPos.x, a_HitPos.y, a_HitPos.z, mtChicken, false);
}
}