2012-06-14 13:06:06 +00:00
# pragma once
2013-08-19 09:39:13 +00:00
# include "../Entities/Pawn.h"
2012-09-23 20:53:08 +00:00
# include "../Defines.h"
# include "../BlockID.h"
2012-09-23 22:09:57 +00:00
# include "../Item.h"
2014-02-23 18:44:58 +00:00
# include "../Enchantments.h"
2014-09-17 17:40:10 +00:00
# include "MonsterTypes.h"
2012-06-14 13:06:06 +00:00
class cClientHandle ;
2013-08-16 08:48:19 +00:00
class cWorld ;
2012-06-14 13:06:06 +00:00
2015-04-29 16:24:14 +00:00
// Fwd: cPath
enum class ePathFinderStatus ;
class cPath ;
2012-06-14 13:06:06 +00:00
2012-12-21 11:04:08 +00:00
// tolua_begin
class cMonster :
public cPawn
{
typedef cPawn super ;
2012-06-14 13:06:06 +00:00
public :
2013-09-07 18:02:50 +00:00
enum eFamily
{
2014-07-17 20:15:34 +00:00
mfHostile = 0 , // Spider, Zombies ...
mfPassive = 1 , // Cows, Pigs
mfAmbient = 2 , // Bats
2014-12-18 18:30:32 +00:00
mfWater = 3 , // Squid, Guardian
2013-09-18 21:17:43 +00:00
2014-04-26 03:49:55 +00:00
mfNoSpawn ,
2014-07-17 20:15:34 +00:00
mfUnhandled , // Nothing. Be sure this is the last and the others are in order
2013-08-16 08:48:19 +00:00
} ;
2014-10-12 02:39:55 +00:00
2012-12-21 11:04:08 +00:00
// tolua_end
2014-10-12 02:39:55 +00:00
2013-10-20 11:25:56 +00:00
enum MState { ATTACKING , IDLE , CHASING , ESCAPING } m_EMState ;
2014-07-19 12:53:41 +00:00
enum MPersonality { PASSIVE , AGGRESSIVE , COWARDLY } m_EMPersonality ;
2014-10-12 02:39:55 +00:00
2012-12-22 09:39:13 +00:00
/** Creates the mob object.
2014-07-18 07:57:34 +00:00
If a_ConfigName is not empty , the configuration is loaded using GetMonsterConfig ( )
a_MobType is the type of the mob ( also used in the protocol ( http : //wiki.vg/Entities#Mobs 2012_12_22))
a_SoundHurt and a_SoundDeath are assigned into m_SoundHurt and m_SoundDeath , respectively
2012-12-22 09:39:13 +00:00
*/
2014-09-17 17:40:10 +00:00
cMonster ( const AString & a_ConfigName , eMonsterType a_MobType , const AString & a_SoundHurt , const AString & a_SoundDeath , double a_Width , double a_Height ) ;
2012-06-14 13:06:06 +00:00
2014-07-22 22:36:13 +00:00
CLASS_PROTODEF ( cMonster )
2014-10-12 02:39:55 +00:00
2012-08-24 07:58:26 +00:00
virtual void SpawnOn ( cClientHandle & a_ClientHandle ) override ;
2012-06-14 13:06:06 +00:00
2015-01-11 21:12:26 +00:00
virtual void Tick ( std : : chrono : : milliseconds a_Dt , cChunk & a_Chunk ) override ;
2012-06-14 13:06:06 +00:00
2014-04-25 22:32:30 +00:00
virtual bool DoTakeDamage ( TakeDamageInfo & a_TDI ) override ;
2014-10-12 02:39:55 +00:00
2014-07-04 09:55:09 +00:00
virtual void KilledBy ( TakeDamageInfo & a_TDI ) override ;
2012-06-14 13:06:06 +00:00
2014-09-01 19:05:45 +00:00
virtual void OnRightClicked ( cPlayer & a_Player ) override ;
2015-05-03 17:56:37 +00:00
/** Engage pathfinder and tell it to calculate a path to a given position, and move the mobile accordingly
Currently , the mob will only start moving to a new position after the position it is currently going to is reached . */
2014-07-17 20:15:34 +00:00
virtual void MoveToPosition ( const Vector3d & a_Position ) ; // tolua_export
2014-10-12 02:39:55 +00:00
2013-10-20 08:23:30 +00:00
// tolua_begin
2014-09-26 21:56:20 +00:00
eMonsterType GetMobType ( void ) const { return m_MobType ; }
2013-09-10 13:09:45 +00:00
eFamily GetMobFamily ( void ) const ;
2013-10-20 08:23:30 +00:00
// tolua_end
2014-10-12 02:39:55 +00:00
2013-04-13 21:02:10 +00:00
virtual void CheckEventSeePlayer ( void ) ;
virtual void EventSeePlayer ( cEntity * a_Player ) ;
2014-10-12 02:39:55 +00:00
2012-12-22 09:39:13 +00:00
/// Reads the monster configuration for the specified monster name and assigns it to this object.
void GetMonsterConfig ( const AString & a_Name ) ;
2014-10-12 02:39:55 +00:00
2014-06-09 01:44:20 +00:00
/** Returns whether this mob is undead (skeleton, zombie, etc.) */
2014-07-19 21:35:35 +00:00
virtual bool IsUndead ( void ) ;
2014-10-12 02:39:55 +00:00
2012-12-22 10:15:53 +00:00
virtual void EventLosePlayer ( void ) ;
2013-04-13 21:02:10 +00:00
virtual void CheckEventLostPlayer ( void ) ;
2014-10-12 02:39:55 +00:00
2015-01-16 14:38:21 +00:00
virtual void InStateIdle ( std : : chrono : : milliseconds a_Dt ) ;
virtual void InStateChasing ( std : : chrono : : milliseconds a_Dt ) ;
virtual void InStateEscaping ( std : : chrono : : milliseconds a_Dt ) ;
2014-10-12 02:39:55 +00:00
int GetAttackRate ( ) { return static_cast < int > ( m_AttackRate ) ; }
2014-01-24 19:57:32 +00:00
void SetAttackRate ( float a_AttackRate ) { m_AttackRate = a_AttackRate ; }
void SetAttackRange ( int a_AttackRange ) { m_AttackRange = a_AttackRange ; }
void SetAttackDamage ( int a_AttackDamage ) { m_AttackDamage = a_AttackDamage ; }
void SetSightDistance ( int a_SightDistance ) { m_SightDistance = a_SightDistance ; }
2014-10-12 02:39:55 +00:00
2014-02-23 18:44:58 +00:00
float GetDropChanceWeapon ( ) { return m_DropChanceWeapon ; }
float GetDropChanceHelmet ( ) { return m_DropChanceHelmet ; }
float GetDropChanceChestplate ( ) { return m_DropChanceChestplate ; }
float GetDropChanceLeggings ( ) { return m_DropChanceLeggings ; }
float GetDropChanceBoots ( ) { return m_DropChanceBoots ; }
bool CanPickUpLoot ( ) { return m_CanPickUpLoot ; }
void SetDropChanceWeapon ( float a_DropChanceWeapon ) { m_DropChanceWeapon = a_DropChanceWeapon ; }
void SetDropChanceHelmet ( float a_DropChanceHelmet ) { m_DropChanceHelmet = a_DropChanceHelmet ; }
void SetDropChanceChestplate ( float a_DropChanceChestplate ) { m_DropChanceChestplate = a_DropChanceChestplate ; }
void SetDropChanceLeggings ( float a_DropChanceLeggings ) { m_DropChanceLeggings = a_DropChanceLeggings ; }
void SetDropChanceBoots ( float a_DropChanceBoots ) { m_DropChanceBoots = a_DropChanceBoots ; }
void SetCanPickUpLoot ( bool a_CanPickUpLoot ) { m_CanPickUpLoot = a_CanPickUpLoot ; }
2014-10-12 02:39:55 +00:00
2013-09-05 20:40:08 +00:00
/// Sets whether the mob burns in daylight. Only evaluated at next burn-decision tick
2013-09-17 19:57:35 +00:00
void SetBurnsInDaylight ( bool a_BurnsInDaylight ) { m_BurnsInDaylight = a_BurnsInDaylight ; }
2013-10-09 20:02:59 +00:00
2014-09-02 18:10:41 +00:00
double GetRelativeWalkSpeed ( void ) const { return m_RelativeWalkSpeed ; } // tolua_export
void SetRelativeWalkSpeed ( double a_WalkSpeed ) { m_RelativeWalkSpeed = a_WalkSpeed ; } // tolua_export
2014-08-30 10:44:54 +00:00
2013-10-09 20:02:59 +00:00
// Overridables to handle ageable mobs
virtual bool IsBaby ( void ) const { return false ; }
virtual bool IsTame ( void ) const { return false ; }
virtual bool IsSitting ( void ) const { return false ; }
2014-10-12 02:39:55 +00:00
2013-10-20 11:25:56 +00:00
// tolua_begin
2014-09-01 18:12:56 +00:00
/** Returns true if the monster has a custom name. */
bool HasCustomName ( void ) const { return ! m_CustomName . empty ( ) ; }
2014-09-02 17:20:59 +00:00
/** Gets the custom name of the monster. If no custom name is set, the function returns an empty string. */
2014-09-01 18:12:56 +00:00
const AString & GetCustomName ( void ) const { return m_CustomName ; }
2014-09-02 17:12:35 +00:00
/** Sets the custom name of the monster. You see the name over the monster.
If you want to disable the custom name , simply set an empty string . */
2014-09-01 18:12:56 +00:00
void SetCustomName ( const AString & a_CustomName ) ;
/** Is the custom name of this monster always visible? If not, you only see the name when you sight the mob. */
bool IsCustomNameAlwaysVisible ( void ) const { return m_CustomNameAlwaysVisible ; }
/** Sets the custom name visiblity of this monster.
2014-09-02 17:20:59 +00:00
If it ' s false , you only see the name when you sight the mob . If it ' s true , you always see the custom name . */
2014-09-01 18:12:56 +00:00
void SetCustomNameAlwaysVisible ( bool a_CustomNameAlwaysVisible ) ;
2014-11-29 14:20:44 +00:00
/** Translates MobType enum to a string, empty string if unknown */
2014-09-17 17:40:10 +00:00
static AString MobTypeToString ( eMonsterType a_MobType ) ;
2014-10-12 02:39:55 +00:00
2014-12-01 13:58:13 +00:00
/** Translates MobType enum to the vanilla name of the mob, empty string if unknown. */
2014-11-29 14:20:44 +00:00
static AString MobTypeToVanillaName ( eMonsterType a_MobType ) ;
/** Translates MobType string to the enum, mtInvalidType if not recognized */
2014-09-17 17:40:10 +00:00
static eMonsterType StringToMobType ( const AString & a_MobTypeName ) ;
2014-10-12 02:39:55 +00:00
2014-11-29 14:20:44 +00:00
/** Returns the mob family based on the type */
2014-09-17 17:40:10 +00:00
static eFamily FamilyFromType ( eMonsterType a_MobType ) ;
2013-10-20 12:00:45 +00:00
2014-11-29 14:20:44 +00:00
/** Returns the spawn delay (number of game ticks between spawn attempts) for the given mob family */
2013-10-24 14:45:13 +00:00
static int GetSpawnDelay ( cMonster : : eFamily a_MobFamily ) ;
2013-10-20 11:25:56 +00:00
// tolua_end
2014-10-12 02:39:55 +00:00
2013-10-20 11:25:56 +00:00
/** Creates a new object of the specified mob.
a_MobType is the type of the mob to be created
2013-11-10 20:48:12 +00:00
Asserts and returns null if mob type is not specified
2013-10-20 11:25:56 +00:00
*/
2014-09-17 17:40:10 +00:00
static cMonster * NewMonsterFromType ( eMonsterType a_MobType ) ;
2013-10-20 11:25:56 +00:00
2012-06-14 13:06:06 +00:00
protected :
2014-10-12 02:39:55 +00:00
2014-01-24 19:57:32 +00:00
/** A pointer to the entity this mobile is aiming to reach */
2012-12-21 11:04:08 +00:00
cEntity * m_Target ;
2015-04-29 16:24:14 +00:00
cPath * m_Path ; // TODO unique ptr
2015-05-03 17:56:37 +00:00
/** Stores if mobile is currently moving towards the ultimate, final destination */
2015-04-29 16:24:14 +00:00
bool m_IsFollowingPath ;
2015-05-03 17:56:37 +00:00
2015-05-05 07:04:41 +00:00
/* If 0, will give up reaching the next m_NextWayPointPosition and will re-compute path. */
2015-04-29 16:24:14 +00:00
int m_GiveUpCounter ;
2015-05-05 07:04:41 +00:00
int m_TicksSinceLastPathReset ;
2015-05-03 17:56:37 +00:00
2014-01-24 19:57:32 +00:00
/** Coordinates of the next position that should be reached */
2015-05-05 07:04:41 +00:00
Vector3d m_NextWayPointPosition ;
2015-05-03 17:56:37 +00:00
2014-01-24 19:57:32 +00:00
/** Coordinates for the ultimate, final destination. */
Vector3d m_FinalDestination ;
2014-10-12 02:39:55 +00:00
2015-05-05 07:04:41 +00:00
/** Coordinates for the ultimate, final destination last given to the pathfinder. */
Vector3d m_PathFinderDestination ;
2014-11-15 20:45:57 +00:00
/** Finds the lowest non-air block position (not the highest, as cWorld::GetHeight does)
If current Y is nonsolid , goes down to try to find a solid block , then returns that + 1
If current Y is solid , goes up to find first nonsolid block , and returns that .
If no suitable position is found , returns cChunkDef : : Height . */
2014-01-24 19:57:32 +00:00
int FindFirstNonAirBlockPosition ( double a_PosX , double a_PosZ ) ;
2014-11-15 20:45:57 +00:00
2015-05-03 17:56:37 +00:00
/** Returns if the ultimate, final destination has been reached */
bool ReachedFinalDestination ( void ) { return ( ( m_FinalDestination - GetPosition ( ) ) . SqrLength ( ) < ( m_AttackRange * m_AttackRange ) ) ; }
2015-05-05 07:04:41 +00:00
/** Returns if the intermediate waypoint of m_NextWayPointPosition has been reached */
bool ReachedNextWaypoint ( void ) { return ( ( m_NextWayPointPosition - GetPosition ( ) ) . SqrLength ( ) < 0.25 ) ; }
2015-05-03 17:56:37 +00:00
2014-01-25 14:42:26 +00:00
/** Returns if a monster can reach a given height by jumping */
inline bool DoesPosYRequireJump ( int a_PosY )
{
2014-04-17 17:50:25 +00:00
return ( ( a_PosY > POSY_TOINT ) & & ( a_PosY = = POSY_TOINT + 1 ) ) ;
2014-01-24 21:55:04 +00:00
}
2014-01-24 19:57:32 +00:00
2015-05-05 07:04:41 +00:00
/** Finds the next place to go by calculating a path and setting the m_NextWayPointPosition variable for the next block to head to
2015-05-03 17:56:37 +00:00
This is based on the ultimate , final destination and the current position , as well as the A * algorithm , and any environmental hazards
2015-05-05 07:04:41 +00:00
Returns if a path is ready , and therefore if the mob should move to m_NextWayPointPosition
2015-05-03 17:56:37 +00:00
*/
bool TickPathFinding ( cChunk & a_Chunk ) ;
2015-05-06 14:23:07 +00:00
/** Move in a straight line to the next waypoint in the path, will jump if needed. */
2015-05-03 17:56:37 +00:00
void MoveToWayPoint ( cChunk & a_Chunk ) ;
2014-01-24 19:57:32 +00:00
2015-05-06 14:23:07 +00:00
/** Ensures the destination is not buried underground or under water. Also ensures the destination is not in the air.
Only the Y coordinate of m_FinalDestination might be changed .
1. If m_FinalDestination is the position of a water block , m_FinalDestination ' s Y will be modified to point to the heighest water block in the pool in the current column .
2. If m_FinalDestination is the position of a solid , m_FinalDestination ' s Y will be modified to point to the first airblock above the solid in the current column .
3. If m_FinalDestination is the position of an air block , Y will keep decreasing until hitting either a solid or water .
Now either 1 or 2 is performed . */
bool EnsureProperDestination ( cChunk & a_Chunk ) ;
2015-05-03 17:56:37 +00:00
/** Resets a pathfinding task, be it due to failure or something else
Resets the pathfinder . If m_IsFollowingPath is true , TickPathFinding starts a brand new path .
Should only be called by the pathfinder , cMonster : : Tick or StopMovingToPosition . */
2015-05-01 17:34:24 +00:00
void ResetPathFinding ( void ) ;
2015-05-03 17:56:37 +00:00
/** Stops pathfinding
Calls ResetPathFinding and sets m_IsFollowingPath to false */
void StopMovingToPosition ( ) ;
2015-05-09 07:25:09 +00:00
/** Sets the body yaw and head yaw / pitch based on next / ultimate destinations */
2014-01-24 19:57:32 +00:00
void SetPitchAndYawFromDestination ( void ) ;
2014-01-25 19:02:13 +00:00
virtual void HandleFalling ( void ) ;
int m_LastGroundHeight ;
2015-05-02 18:22:28 +00:00
int m_JumpCoolDown ;
2014-01-25 19:02:13 +00:00
2015-01-16 14:38:21 +00:00
std : : chrono : : milliseconds m_IdleInterval ;
std : : chrono : : milliseconds m_DestroyTimer ;
2012-06-14 13:06:06 +00:00
2014-09-17 17:40:10 +00:00
eMonsterType m_MobType ;
2014-09-01 18:12:56 +00:00
AString m_CustomName ;
bool m_CustomNameAlwaysVisible ;
2012-06-14 13:06:06 +00:00
2012-12-21 18:05:34 +00:00
AString m_SoundHurt ;
AString m_SoundDeath ;
2014-07-17 20:50:58 +00:00
float m_AttackRate ;
2014-01-24 19:57:32 +00:00
int m_AttackDamage ;
int m_AttackRange ;
2012-06-14 13:06:06 +00:00
float m_AttackInterval ;
2014-01-24 19:57:32 +00:00
int m_SightDistance ;
2014-10-12 02:39:55 +00:00
2014-02-23 18:44:58 +00:00
float m_DropChanceWeapon ;
float m_DropChanceHelmet ;
float m_DropChanceChestplate ;
float m_DropChanceLeggings ;
float m_DropChanceBoots ;
bool m_CanPickUpLoot ;
2015-04-29 16:24:14 +00:00
int m_TicksSinceLastDamaged ; // How many ticks ago we were last damaged by a player?
2014-10-12 02:39:55 +00:00
2015-05-01 17:34:24 +00:00
void HandleDaylightBurning ( cChunk & a_Chunk , bool WouldBurn ) ;
2015-04-29 16:24:14 +00:00
bool WouldBurnAt ( Vector3d a_Location , cChunk & a_Chunk ) ;
2013-09-05 20:40:08 +00:00
bool m_BurnsInDaylight ;
2014-09-02 18:10:41 +00:00
double m_RelativeWalkSpeed ;
2014-08-30 10:44:54 +00:00
2014-02-23 18:44:58 +00:00
/** Adds a random number of a_Item between a_Min and a_Max to itemdrops a_Drops*/
2014-07-17 20:50:58 +00:00
void AddRandomDropItem ( cItems & a_Drops , unsigned int a_Min , unsigned int a_Max , short a_Item , short a_ItemHealth = 0 ) ;
2014-10-12 02:39:55 +00:00
2014-02-23 18:44:58 +00:00
/** Adds a item a_Item with the chance of a_Chance (in percent) to itemdrops a_Drops*/
2014-07-17 20:50:58 +00:00
void AddRandomUncommonDropItem ( cItems & a_Drops , float a_Chance , short a_Item , short a_ItemHealth = 0 ) ;
2014-10-12 02:39:55 +00:00
2014-02-23 18:44:58 +00:00
/** Adds one rare item out of the list of rare items a_Items modified by the looting level a_LootingLevel(I-III or custom) to the itemdrop a_Drops*/
2014-07-17 20:50:58 +00:00
void AddRandomRareDropItem ( cItems & a_Drops , cItems & a_Items , short a_LootingLevel ) ;
2014-10-12 02:39:55 +00:00
2014-02-24 14:38:38 +00:00
/** Adds armor that is equipped with the chance saved in m_DropChance[...] (this will be greter than 1 if piccked up or 0.085 + (0.01 per LootingLevel) if born with) to the drop*/
2014-02-23 18:44:58 +00:00
void AddRandomArmorDropItem ( cItems & a_Drops , short a_LootingLevel ) ;
2014-10-12 02:39:55 +00:00
2014-02-24 14:38:38 +00:00
/** Adds weapon that is equipped with the chance saved in m_DropChance[...] (this will be greter than 1 if piccked up or 0.085 + (0.01 per LootingLevel) if born with) to the drop*/
2014-02-23 18:44:58 +00:00
void AddRandomWeaponDropItem ( cItems & a_Drops , short a_LootingLevel ) ;
2012-06-14 13:06:06 +00:00
2014-10-12 02:39:55 +00:00
} ; // tolua_export