2012-06-14 09:06:06 -04:00
# pragma once
2013-08-19 05:39:13 -04:00
# include "../Item.h"
# include "../Vector3d.h"
# include "../Vector3f.h"
2012-06-14 09:06:06 -04:00
2013-02-27 05:02:06 -05:00
// Place this macro in the public section of each cEntity descendant class and you're done :)
2012-12-21 07:21:20 -05:00
# define CLASS_PROTODEF(classname) \
virtual bool IsA ( const char * a_ClassName ) const override \
{ \
return ( ( strcmp ( a_ClassName , # classname ) = = 0 ) | | super : : IsA ( a_ClassName ) ) ; \
} \
virtual const char * GetClass ( void ) const override \
{ \
return # classname ; \
} \
2013-02-02 18:55:29 -05:00
static const char * GetClassStatic ( void ) \
{ \
return # classname ; \
} \
2012-12-21 07:21:20 -05:00
virtual const char * GetParentClass ( void ) const override \
{ \
return super : : GetClass ( ) ; \
}
2012-06-14 09:06:06 -04:00
class cWorld ;
class cReferenceManager ;
class cClientHandle ;
2013-03-03 14:05:11 -05:00
class cPlayer ;
2013-04-13 17:02:10 -04:00
class cChunk ;
2012-06-14 09:06:06 -04:00
2013-07-01 06:39:56 -04:00
// tolua_begin
struct TakeDamageInfo
{
eDamageType DamageType ; // Where does the damage come from? Being hit / on fire / contact with cactus / ...
cEntity * Attacker ; // The attacking entity; valid only for dtAttack
int RawDamage ; // What damage would the receiver get without any armor. Usually: attacker mob type + weapons
int FinalDamage ; // What actual damage will be received. Usually: m_RawDamage minus armor
Vector3d Knockback ; // The amount and direction of knockback received from the damage
// TODO: Effects - list of effects that the hit is causing. Unknown representation yet
} ;
// tolua_end
2012-08-19 17:14:45 -04:00
// tolua_begin
class cEntity
{
2013-10-08 13:49:33 -04:00
public :
enum eEntityType
{
etEntity , // For all other types
etPlayer ,
etPickup ,
etMonster ,
etFallingBlock ,
etMinecart ,
etBoat ,
etTNT ,
etProjectile ,
// Common variations
etMob = etMonster , // DEPRECATED, use etMonster instead!
} ;
// tolua_end
2012-08-19 17:14:45 -04:00
enum
{
ENTITY_STATUS_HURT = 2 ,
ENTITY_STATUS_DEAD = 3 ,
ENTITY_STATUS_WOLF_TAMING = 6 ,
ENTITY_STATUS_WOLF_TAMED = 7 ,
ENTITY_STATUS_WOLF_SHAKING = 8 ,
ENTITY_STATUS_EATING_ACCEPTED = 9 ,
ENTITY_STATUS_SHEEP_EATING = 10 ,
2013-10-08 14:20:49 -04:00
ENTITY_STATUS_GOLEM_ROSING = 11 ,
ENTITY_STATUS_VILLAGER_HEARTS = 12 ,
ENTITY_STATUS_VILLAGER_ANGRY = 13 ,
ENTITY_STATUS_VILLAGER_HAPPY = 14 ,
ENTITY_STATUS_WITCH_MAGICKING = 15 ,
// It seems 16 (zombie conversion) is now done with metadata
ENTITY_STATUS_FIREWORK_EXPLODE = 17 ,
2012-08-19 17:14:45 -04:00
} ;
2013-07-01 06:39:56 -04:00
enum
{
FIRE_TICKS_PER_DAMAGE = 10 , ///< How many ticks to wait between damaging an entity when it stands in fire
FIRE_DAMAGE = 1 , ///< How much damage to deal when standing in fire
LAVA_TICKS_PER_DAMAGE = 10 , ///< How many ticks to wait between damaging an entity when it stands in lava
LAVA_DAMAGE = 5 , ///< How much damage to deal when standing in lava
BURN_TICKS_PER_DAMAGE = 20 , ///< How many ticks to wait between damaging an entity when it is burning
BURN_DAMAGE = 1 , ///< How much damage to deal when the entity is burning
BURN_TICKS = 200 , ///< How long to keep an entity burning after it has stood in lava / fire
} ;
cEntity ( eEntityType a_EntityType , double a_X , double a_Y , double a_Z , double a_Width , double a_Height ) ;
2012-08-19 17:14:45 -04:00
virtual ~ cEntity ( ) ;
2013-08-08 03:13:13 -04:00
/// Spawns the entity in the world; returns true if spawned, false if not (plugin disallowed)
virtual bool Initialize ( cWorld * a_World ) ;
2012-08-19 17:14:45 -04:00
2013-02-21 16:55:36 -05:00
// tolua_begin
2012-12-21 07:52:14 -05:00
eEntityType GetEntityType ( void ) const { return m_EntityType ; }
2013-10-13 07:47:55 -04:00
bool IsPlayer ( void ) const { return ( m_EntityType = = etPlayer ) ; }
bool IsPickup ( void ) const { return ( m_EntityType = = etPickup ) ; }
bool IsMob ( void ) const { return ( m_EntityType = = etMonster ) ; }
bool IsFallingBlock ( void ) const { return ( m_EntityType = = etFallingBlock ) ; }
bool IsMinecart ( void ) const { return ( m_EntityType = = etMinecart ) ; }
bool IsBoat ( void ) const { return ( m_EntityType = = etBoat ) ; }
bool IsTNT ( void ) const { return ( m_EntityType = = etTNT ) ; }
bool IsProjectile ( void ) const { return ( m_EntityType = = etProjectile ) ; }
2012-12-21 07:21:20 -05:00
/// 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 topmost class name for the object
virtual const char * GetClass ( void ) const ;
2013-03-01 14:33:41 -05:00
2013-02-02 18:55:29 -05:00
// Returns the class name of this class
static const char * GetClassStatic ( void ) ;
2012-12-21 07:21:20 -05:00
/// Returns the topmost class's parent class name for the object. cEntity returns an empty string (no parent).
virtual const char * GetParentClass ( void ) const ;
2012-06-14 09:06:06 -04:00
2012-12-21 05:59:59 -05:00
cWorld * GetWorld ( void ) const { return m_World ; }
2013-05-21 01:49:56 -04:00
double GetHeadYaw ( void ) const { return m_HeadYaw ; }
double GetHeight ( void ) const { return m_Height ; }
double GetMass ( void ) const { return m_Mass ; }
const Vector3d & GetPosition ( void ) const { return m_Pos ; }
double GetPosX ( void ) const { return m_Pos . x ; }
double GetPosY ( void ) const { return m_Pos . y ; }
double GetPosZ ( void ) const { return m_Pos . z ; }
const Vector3d & GetRot ( void ) const { return m_Rot ; }
2013-11-02 12:45:48 -04:00
double GetRotation ( void ) const { return m_Rot . x ; } // OBSOLETE, use GetYaw() instead
double GetYaw ( void ) const { return m_Rot . x ; }
2013-05-21 01:49:56 -04:00
double GetPitch ( void ) const { return m_Rot . y ; }
double GetRoll ( void ) const { return m_Rot . z ; }
2013-03-09 09:35:43 -05:00
Vector3d GetLookVector ( void ) const ;
2013-05-21 01:49:56 -04:00
const Vector3d & GetSpeed ( void ) const { return m_Speed ; }
2013-02-21 16:55:36 -05:00
double GetSpeedX ( void ) const { return m_Speed . x ; }
double GetSpeedY ( void ) const { return m_Speed . y ; }
double GetSpeedZ ( void ) const { return m_Speed . z ; }
2013-05-21 01:49:56 -04:00
double GetWidth ( void ) const { return m_Width ; }
2012-06-14 09:06:06 -04:00
2013-05-19 07:49:01 -04:00
int GetChunkX ( void ) const { return ( int ) floor ( m_Pos . x / cChunkDef : : Width ) ; }
int GetChunkZ ( void ) const { return ( int ) floor ( m_Pos . z / cChunkDef : : Width ) ; }
2012-12-21 05:59:59 -05:00
2013-04-02 02:48:31 -04:00
void SetHeadYaw ( double a_HeadYaw ) ;
2013-05-21 01:49:56 -04:00
void SetHeight ( double a_Height ) ;
2013-04-28 14:54:43 -04:00
void SetMass ( double a_Mass ) ;
2012-12-21 05:59:59 -05:00
void SetPosX ( double a_PosX ) ;
void SetPosY ( double a_PosY ) ;
void SetPosZ ( double a_PosZ ) ;
void SetPosition ( double a_PosX , double a_PosY , double a_PosZ ) ;
2013-08-27 13:56:54 -04:00
void SetPosition ( const Vector3d & a_Pos ) { SetPosition ( a_Pos . x , a_Pos . y , a_Pos . z ) ; }
2012-12-21 05:59:59 -05:00
void SetRot ( const Vector3f & a_Rot ) ;
2013-11-02 12:45:48 -04:00
void SetRotation ( double a_Rotation ) { SetYaw ( a_Rotation ) ; } // OBSOLETE, use SetYaw() instead
void SetYaw ( double a_Yaw ) ;
2013-03-09 09:35:43 -05:00
void SetPitch ( double a_Pitch ) ;
void SetRoll ( double a_Roll ) ;
void SetSpeed ( double a_SpeedX , double a_SpeedY , double a_SpeedZ ) ;
2013-04-13 17:02:10 -04:00
void SetSpeed ( const Vector3d & a_Speed ) { SetSpeed ( a_Speed . x , a_Speed . y , a_Speed . z ) ; }
2013-03-22 02:33:10 -04:00
void SetSpeedX ( double a_SpeedX ) ;
void SetSpeedY ( double a_SpeedY ) ;
void SetSpeedZ ( double a_SpeedZ ) ;
2013-05-21 01:49:56 -04:00
void SetWidth ( double a_Width ) ;
2013-03-03 14:05:11 -05:00
2013-03-23 00:33:47 -04:00
void AddPosX ( double a_AddPosX ) ;
void AddPosY ( double a_AddPosY ) ;
void AddPosZ ( double a_AddPosZ ) ;
void AddPosition ( double a_AddPosX , double a_AddPosY , double a_AddPosZ ) ;
void AddPosition ( const Vector3d & a_AddPos ) { AddPosition ( a_AddPos . x , a_AddPos . y , a_AddPos . z ) ; }
void AddSpeed ( double a_AddSpeedX , double a_AddSpeedY , double a_AddSpeedZ ) ;
void AddSpeed ( const Vector3d & a_AddSpeed ) { AddSpeed ( a_AddSpeed . x , a_AddSpeed . y , a_AddSpeed . z ) ; }
void AddSpeedX ( double a_AddSpeedX ) ;
void AddSpeedY ( double a_AddSpeedY ) ;
void AddSpeedZ ( double a_AddSpeedZ ) ;
2013-09-05 18:04:49 -04:00
void SteerVehicle ( float a_Forward , float a_Sideways ) ;
2013-03-09 09:35:43 -05:00
2013-04-13 17:02:10 -04:00
inline int GetUniqueID ( void ) const { return m_UniqueID ; }
inline bool IsDestroyed ( void ) const { return ! m_IsInitialized ; }
2012-06-14 09:06:06 -04:00
2013-06-25 02:36:59 -04:00
/// Schedules the entity for destroying; if a_ShouldBroadcast is set to true, broadcasts the DestroyEntity packet
void Destroy ( bool a_ShouldBroadcast = true ) ;
2012-06-14 09:06:06 -04:00
2013-07-01 06:39:56 -04:00
/// 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 ) ;
2013-09-03 04:20:56 -04:00
float GetGravity ( void ) const { return m_Gravity ; }
void SetGravity ( float a_Gravity ) { m_Gravity = a_Gravity ; }
2013-09-07 11:14:37 -04:00
/// Sets the rotation to match the speed vector (entity goes "face-forward")
void SetRotationFromSpeed ( void ) ;
/// Sets the pitch to match the speed vector (entity gies "face-forward")
void SetPitchFromSpeed ( void ) ;
2013-07-01 06:39:56 -04:00
// tolua_end
/// Makes this entity take damage specified in the a_TDI. The TDI is sent through plugins first, then applied
virtual void 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 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 ( ) ; }
2013-09-27 10:31:48 -04:00
/// Returns the currently equipped helmet; empty item if none
2013-07-01 06:39:56 -04:00
virtual cItem GetEquippedHelmet ( void ) const { return cItem ( ) ; }
2013-09-27 10:31:48 -04:00
/// Returns the currently equipped chestplate; empty item if none
2013-07-01 06:39:56 -04:00
virtual cItem GetEquippedChestplate ( void ) const { return cItem ( ) ; }
2013-09-27 10:31:48 -04:00
/// Returns the currently equipped leggings; empty item if none
2013-07-01 06:39:56 -04:00
virtual cItem GetEquippedLeggings ( void ) const { return cItem ( ) ; }
2013-09-27 10:31:48 -04:00
/// Returns the currently equipped boots; empty item if none
2013-07-01 06:39:56 -04:00
virtual cItem GetEquippedBoots ( void ) const { return cItem ( ) ; }
/// Called when the health drops below zero. a_Killer may be NULL (environmental damage)
virtual void KilledBy ( cEntity * a_Killer ) ;
/// Heals the specified amount of HPs
void Heal ( int a_HitPoints ) ;
2013-07-07 11:09:05 -04:00
/// Returns the health of this entity
2013-07-01 06:39:56 -04:00
int GetHealth ( void ) const { return m_Health ; }
2013-07-07 11:09:05 -04:00
/// Sets the health of this entity; doesn't broadcast any hurt animation
void SetHealth ( int a_Health ) ;
2013-04-13 17:02:10 -04:00
// tolua_end
2012-06-14 09:06:06 -04:00
2013-04-13 17:02:10 -04:00
virtual void Tick ( float a_Dt , cChunk & a_Chunk ) ;
2013-07-01 06:39:56 -04:00
/// Handles the physics of the entity - updates position based on speed, updates speed based on environment
2013-04-22 03:18:03 -04:00
virtual void HandlePhysics ( float a_Dt , cChunk & a_Chunk ) ;
2013-07-01 06:39:56 -04:00
/// Updates the state related to this entity being on fire
virtual void TickBurning ( cChunk & a_Chunk ) ;
2013-09-10 18:01:02 -04:00
/// Handles when the entity is in the void
virtual void TickInVoid ( cChunk & a_Chunk ) ;
2013-07-01 06:39:56 -04:00
/// 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 ; }
/// 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
2012-06-14 09:06:06 -04:00
2012-08-24 03:58:26 -04:00
/** Descendants override this function to send a command to the specified client to spawn the entity on the client.
To spawn on all eligible clients , use cChunkMap : : BroadcastSpawnEntity ( )
*/
2013-08-22 02:55:58 -04:00
virtual void SpawnOn ( cClientHandle & a_Client ) = 0 ;
2013-03-22 02:33:10 -04:00
2013-07-01 06:39:56 -04:00
// 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 ) ;
// tolua_end
2013-06-04 08:55:41 -04:00
/// Updates clients of changes in the entity.
2013-03-22 02:33:10 -04:00
virtual void BroadcastMovementUpdate ( const cClientHandle * a_Exclude = NULL ) ;
2012-06-14 09:06:06 -04:00
2013-03-03 14:05:11 -05:00
/// Attaches to the specified entity; detaches from any previous one first
void AttachTo ( cEntity * a_AttachTo ) ;
/// Detaches from the currently attached entity, if any
void Detach ( void ) ;
2013-06-04 08:55:41 -04:00
/// Makes sure head yaw is not over the specified range.
2013-04-02 02:48:31 -04:00
void WrapHeadYaw ( ) ;
2013-06-04 08:55:41 -04:00
/// Makes sure rotation is not over the specified range.
2012-06-14 09:06:06 -04:00
void WrapRotation ( ) ;
2013-03-22 02:33:10 -04:00
2013-06-04 08:55:41 -04:00
/// Makes speed is not over 20. Max speed is 20 blocks / second
2013-03-22 02:33:10 -04:00
void WrapSpeed ( ) ;
2012-08-28 17:59:49 -04:00
2013-03-01 14:33:41 -05:00
// tolua_begin
2013-10-09 16:02:59 -04:00
// COMMON metadata flags; descendants may override the defaults:
2013-07-01 06:39:56 -04:00
virtual bool IsOnFire ( void ) const { return ( m_TicksLeftBurning > 0 ) ; }
2012-08-28 17:59:49 -04:00
virtual bool IsCrouched ( void ) const { return false ; }
virtual bool IsRiding ( void ) const { return false ; }
virtual bool IsSprinting ( void ) const { return false ; }
virtual bool IsRclking ( void ) const { return false ; }
2013-10-08 14:20:49 -04:00
virtual bool IsInvisible ( void ) const { return false ; }
2013-03-01 14:33:41 -05:00
// tolua_end
2013-03-03 14:05:11 -05:00
/// Called when the specified player right-clicks this entity
virtual void OnRightClicked ( cPlayer & a_Player ) { } ;
2012-06-14 09:06:06 -04:00
2013-07-01 06:39:56 -04:00
/// Returns the list of drops for this pawn when it is killed. May check a_Killer for special handling (sword of looting etc.). Called from KilledBy().
virtual void GetDrops ( cItems & a_Drops , cEntity * a_Killer = NULL ) { }
2012-06-14 09:06:06 -04:00
protected :
static cCriticalSection m_CSCount ;
static int m_EntityCount ;
int m_UniqueID ;
2013-03-03 14:05:11 -05:00
2013-07-01 06:39:56 -04:00
int m_Health ;
int m_MaxHealth ;
2013-03-03 14:05:11 -05:00
/// The entity to which this entity is attached (vehicle), NULL if none
cEntity * m_AttachedTo ;
/// The entity which is attached to this entity (rider), NULL if none
cEntity * m_Attachee ;
2012-06-14 09:06:06 -04:00
cReferenceManager * m_Referencers ;
cReferenceManager * m_References ;
2013-04-13 17:02:10 -04:00
// Flags that signal that we haven't updated the clients with the latest.
2013-04-02 02:48:31 -04:00
bool m_bDirtyHead ;
2013-03-22 02:33:10 -04:00
bool m_bDirtyOrientation ;
2013-02-21 16:55:36 -05:00
bool m_bDirtyPosition ;
2013-03-22 02:33:10 -04:00
bool m_bDirtySpeed ;
2012-06-14 09:06:06 -04:00
2013-04-22 03:18:03 -04:00
bool m_bOnGround ;
float m_Gravity ;
2013-08-27 15:38:11 -04:00
2013-04-13 17:02:10 -04:00
// Last Position.
2013-03-22 02:33:10 -04:00
double m_LastPosX , m_LastPosY , m_LastPosZ ;
2013-04-13 17:02:10 -04:00
// This variables keep track of the last time a packet was sent
2013-03-22 02:33:10 -04:00
Int64 m_TimeLastTeleportPacket , m_TimeLastMoveReltPacket , m_TimeLastSpeedPacket ; // In ticks
2012-06-14 09:06:06 -04:00
2013-04-13 17:02:10 -04:00
bool m_IsInitialized ; // Is set to true when it's initialized, until it's destroyed (Initialize() till Destroy() )
2012-06-14 09:06:06 -04:00
eEntityType m_EntityType ;
2013-03-09 09:35:43 -05:00
cWorld * m_World ;
2012-08-28 17:59:49 -04:00
2013-07-01 06:39:56 -04:00
/// 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 ;
2013-09-10 18:01:02 -04:00
/// Time, in ticks, since the last damage dealt by the void. Reset to zero when moving out of the void.
int m_TicksSinceLastVoidDamage ;
2013-03-09 09:35:43 -05:00
virtual void Destroyed ( void ) { } // Called after the entity has been destroyed
void SetWorld ( cWorld * a_World ) { m_World = a_World ; }
2013-04-13 17:02:10 -04:00
2013-03-09 09:35:43 -05:00
friend class cReferenceManager ;
void AddReference ( cEntity * & a_EntityPtr ) ;
void ReferencedBy ( cEntity * & a_EntityPtr ) ;
void Dereference ( cEntity * & a_EntityPtr ) ;
2013-07-01 06:39:56 -04:00
2013-03-22 02:33:10 -04:00
private :
2013-07-01 06:39:56 -04:00
// Measured in degrees (MAX 360<36> )
2013-04-02 02:48:31 -04:00
double m_HeadYaw ;
2013-07-01 06:39:56 -04:00
// Measured in meter/second (m/s)
2013-03-22 02:33:10 -04:00
Vector3d m_Speed ;
2013-07-01 06:39:56 -04:00
// Measured in degrees (MAX 360<36> )
2013-03-22 02:33:10 -04:00
Vector3d m_Rot ;
2013-07-01 06:39:56 -04:00
/// Position of the entity's XZ center and Y bottom
2013-03-22 02:33:10 -04:00
Vector3d m_Pos ;
2013-07-01 06:39:56 -04:00
// Measured in meter / second
2013-04-22 03:18:03 -04:00
Vector3d m_WaterSpeed ;
2013-07-01 06:39:56 -04:00
2013-08-29 08:47:22 -04:00
// Measured in Kilograms (Kg)
double m_Mass ;
2013-07-01 06:39:56 -04:00
/// Width of the entity, in the XZ plane. Since entities are represented as cylinders, this is more of a diameter.
2013-05-21 01:49:56 -04:00
double m_Width ;
2013-07-01 06:39:56 -04:00
/// Height of the entity (Y axis)
2013-05-21 01:49:56 -04:00
double m_Height ;
2013-03-09 09:35:43 -05:00
} ; // tolua_export
2012-06-14 09:06:06 -04:00
typedef std : : list < cEntity * > cEntityList ;