2012-06-14 09:06:06 -04:00
# pragma once
2013-08-19 05:39:13 -04:00
# include "../Entities/Pawn.h"
2012-09-23 16:53:08 -04:00
# include "../Defines.h"
# include "../BlockID.h"
2012-09-23 18:09:57 -04:00
# include "../Item.h"
2014-02-23 13:44:58 -05:00
# include "../Enchantments.h"
2014-09-17 13:40:10 -04:00
# include "MonsterTypes.h"
2012-06-14 09:06:06 -04:00
class cClientHandle ;
2013-08-16 04:48:19 -04:00
class cWorld ;
2012-06-14 09:06:06 -04:00
2015-04-29 12:24:14 -04:00
// Fwd: cPath
enum class ePathFinderStatus ;
class cPath ;
2012-06-14 09:06:06 -04:00
2012-12-21 06:04:08 -05:00
// tolua_begin
class cMonster :
public cPawn
{
typedef cPawn super ;
2012-06-14 09:06:06 -04:00
public :
2013-09-07 14:02:50 -04:00
enum eFamily
{
2014-07-17 16:15:34 -04:00
mfHostile = 0 , // Spider, Zombies ...
mfPassive = 1 , // Cows, Pigs
mfAmbient = 2 , // Bats
2014-12-18 13:30:32 -05:00
mfWater = 3 , // Squid, Guardian
2013-09-18 17:17:43 -04:00
2014-04-25 23:49:55 -04:00
mfNoSpawn ,
2014-07-17 16:15:34 -04:00
mfUnhandled , // Nothing. Be sure this is the last and the others are in order
2013-08-16 04:48:19 -04:00
} ;
2014-10-11 22:39:55 -04:00
2012-12-21 06:04:08 -05:00
// tolua_end
2014-10-11 22:39:55 -04:00
2013-10-20 07:25:56 -04:00
enum MState { ATTACKING , IDLE , CHASING , ESCAPING } m_EMState ;
2014-07-19 08:53:41 -04:00
enum MPersonality { PASSIVE , AGGRESSIVE , COWARDLY } m_EMPersonality ;
2014-10-11 22:39:55 -04:00
2012-12-22 04:39:13 -05:00
/** Creates the mob object.
2014-07-18 03:57:34 -04: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 04:39:13 -05:00
*/
2014-09-17 13:40:10 -04: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 09:06:06 -04:00
2014-07-22 18:36:13 -04:00
CLASS_PROTODEF ( cMonster )
2014-10-11 22:39:55 -04:00
2012-08-24 03:58:26 -04:00
virtual void SpawnOn ( cClientHandle & a_ClientHandle ) override ;
2012-06-14 09:06:06 -04:00
2015-01-11 16:12:26 -05:00
virtual void Tick ( std : : chrono : : milliseconds a_Dt , cChunk & a_Chunk ) override ;
2012-06-14 09:06:06 -04:00
2014-04-25 18:32:30 -04:00
virtual bool DoTakeDamage ( TakeDamageInfo & a_TDI ) override ;
2014-10-11 22:39:55 -04:00
2014-07-04 05:55:09 -04:00
virtual void KilledBy ( TakeDamageInfo & a_TDI ) override ;
2012-06-14 09:06:06 -04:00
2014-09-01 15:05:45 -04:00
virtual void OnRightClicked ( cPlayer & a_Player ) override ;
2014-07-17 16:15:34 -04:00
virtual void MoveToPosition ( const Vector3d & a_Position ) ; // tolua_export
2015-04-29 12:24:14 -04:00
virtual void StopMovingToPosition ( ) ;
2012-08-24 03:58:26 -04:00
virtual bool ReachedDestination ( void ) ;
2014-10-11 22:39:55 -04:00
2013-10-20 04:23:30 -04:00
// tolua_begin
2014-09-26 17:56:20 -04:00
eMonsterType GetMobType ( void ) const { return m_MobType ; }
2013-09-10 09:09:45 -04:00
eFamily GetMobFamily ( void ) const ;
2013-10-20 04:23:30 -04:00
// tolua_end
2014-10-11 22:39:55 -04:00
2013-04-13 17:02:10 -04:00
virtual void CheckEventSeePlayer ( void ) ;
virtual void EventSeePlayer ( cEntity * a_Player ) ;
2014-10-11 22:39:55 -04:00
2012-12-22 04:39:13 -05:00
/// Reads the monster configuration for the specified monster name and assigns it to this object.
void GetMonsterConfig ( const AString & a_Name ) ;
2014-10-11 22:39:55 -04:00
2014-06-08 21:44:20 -04:00
/** Returns whether this mob is undead (skeleton, zombie, etc.) */
2014-07-19 17:35:35 -04:00
virtual bool IsUndead ( void ) ;
2014-10-11 22:39:55 -04:00
2012-12-22 05:15:53 -05:00
virtual void EventLosePlayer ( void ) ;
2013-04-13 17:02:10 -04:00
virtual void CheckEventLostPlayer ( void ) ;
2014-10-11 22:39:55 -04:00
2015-01-16 09:38:21 -05: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-11 22:39:55 -04:00
int GetAttackRate ( ) { return static_cast < int > ( m_AttackRate ) ; }
2014-01-24 14:57:32 -05: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-11 22:39:55 -04:00
2014-02-23 13:44:58 -05: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-11 22:39:55 -04:00
2013-09-05 16:40:08 -04:00
/// Sets whether the mob burns in daylight. Only evaluated at next burn-decision tick
2013-09-17 15:57:35 -04:00
void SetBurnsInDaylight ( bool a_BurnsInDaylight ) { m_BurnsInDaylight = a_BurnsInDaylight ; }
2013-10-09 16:02:59 -04:00
2014-09-02 14:10:41 -04:00
double GetRelativeWalkSpeed ( void ) const { return m_RelativeWalkSpeed ; } // tolua_export
void SetRelativeWalkSpeed ( double a_WalkSpeed ) { m_RelativeWalkSpeed = a_WalkSpeed ; } // tolua_export
2014-08-30 06:44:54 -04:00
2013-10-09 16:02:59 -04: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-11 22:39:55 -04:00
2013-10-20 07:25:56 -04:00
// tolua_begin
2014-09-01 14:12:56 -04:00
/** Returns true if the monster has a custom name. */
bool HasCustomName ( void ) const { return ! m_CustomName . empty ( ) ; }
2014-09-02 13:20:59 -04:00
/** Gets the custom name of the monster. If no custom name is set, the function returns an empty string. */
2014-09-01 14:12:56 -04:00
const AString & GetCustomName ( void ) const { return m_CustomName ; }
2014-09-02 13:12:35 -04: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 14:12:56 -04: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 13:20:59 -04: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 14:12:56 -04:00
void SetCustomNameAlwaysVisible ( bool a_CustomNameAlwaysVisible ) ;
2014-11-29 09:20:44 -05:00
/** Translates MobType enum to a string, empty string if unknown */
2014-09-17 13:40:10 -04:00
static AString MobTypeToString ( eMonsterType a_MobType ) ;
2014-10-11 22:39:55 -04:00
2014-12-01 08:58:13 -05:00
/** Translates MobType enum to the vanilla name of the mob, empty string if unknown. */
2014-11-29 09:20:44 -05:00
static AString MobTypeToVanillaName ( eMonsterType a_MobType ) ;
/** Translates MobType string to the enum, mtInvalidType if not recognized */
2014-09-17 13:40:10 -04:00
static eMonsterType StringToMobType ( const AString & a_MobTypeName ) ;
2014-10-11 22:39:55 -04:00
2014-11-29 09:20:44 -05:00
/** Returns the mob family based on the type */
2014-09-17 13:40:10 -04:00
static eFamily FamilyFromType ( eMonsterType a_MobType ) ;
2013-10-20 08:00:45 -04:00
2014-11-29 09:20:44 -05:00
/** Returns the spawn delay (number of game ticks between spawn attempts) for the given mob family */
2013-10-24 10:45:13 -04:00
static int GetSpawnDelay ( cMonster : : eFamily a_MobFamily ) ;
2013-10-20 07:25:56 -04:00
// tolua_end
2014-10-11 22:39:55 -04:00
2013-10-20 07:25:56 -04:00
/** Creates a new object of the specified mob.
a_MobType is the type of the mob to be created
2013-11-10 15:48:12 -05:00
Asserts and returns null if mob type is not specified
2013-10-20 07:25:56 -04:00
*/
2014-09-17 13:40:10 -04:00
static cMonster * NewMonsterFromType ( eMonsterType a_MobType ) ;
2013-10-20 07:25:56 -04:00
2012-06-14 09:06:06 -04:00
protected :
2014-10-11 22:39:55 -04:00
2014-01-24 14:57:32 -05:00
/* ======= PATHFINDING ======= */
/** A pointer to the entity this mobile is aiming to reach */
2012-12-21 06:04:08 -05:00
cEntity * m_Target ;
2015-04-29 12:24:14 -04:00
cPath * m_Path ; // TODO unique ptr
ePathFinderStatus m_PathStatus ;
bool m_IsFollowingPath ;
/* If 0, will give up reaching the next m_Dest and will re-compute path. */
int m_GiveUpCounter ;
2014-01-24 14:57:32 -05:00
/** Coordinates of the next position that should be reached */
Vector3d m_Destination ;
/** Coordinates for the ultimate, final destination. */
Vector3d m_FinalDestination ;
/** Returns if the ultimate, final destination has been reached */
bool ReachedFinalDestination ( void ) ;
/** Stores if mobile is currently moving towards the ultimate, final destination */
bool m_bMovingToDestination ;
2014-10-11 22:39:55 -04:00
2014-11-15 15:45:57 -05: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 14:57:32 -05:00
int FindFirstNonAirBlockPosition ( double a_PosX , double a_PosZ ) ;
2014-11-15 15:45:57 -05:00
2014-01-25 09:42:26 -05:00
/** Returns if a monster can actually reach a given height by jumping or walking */
2014-01-24 16:55:04 -05:00
inline bool IsNextYPosReachable ( int a_PosY )
{
2014-01-25 09:42:26 -05:00
return (
2014-04-17 13:50:25 -04:00
( a_PosY < = POSY_TOINT ) | |
2014-01-25 09:42:26 -05:00
DoesPosYRequireJump ( a_PosY )
) ;
}
/** Returns if a monster can reach a given height by jumping */
inline bool DoesPosYRequireJump ( int a_PosY )
{
2014-04-17 13:50:25 -04:00
return ( ( a_PosY > POSY_TOINT ) & & ( a_PosY = = POSY_TOINT + 1 ) ) ;
2014-01-24 16:55:04 -05:00
}
2014-01-24 14:57:32 -05:00
/** A semi-temporary list to store the traversed coordinates during active pathfinding so we don't visit them again */
std : : vector < Vector3i > m_TraversedCoordinates ;
/** Returns if coordinate is in the traversed list */
bool IsCoordinateInTraversedList ( Vector3i a_Coords ) ;
/** Finds the next place to go
This is based on the ultimate , final destination and the current position , as well as the traversed coordinates , and any environmental hazards */
void TickPathFinding ( void ) ;
/** Finishes a pathfinding task, be it due to failure or something else */
2015-04-29 12:24:14 -04:00
void FinishPathFinding ( void ) ;
2014-01-24 14:57:32 -05:00
/** Sets the body yaw and head yaw/pitch based on next/ultimate destinations */
void SetPitchAndYawFromDestination ( void ) ;
2014-01-25 14:02:13 -05:00
/* =========================== */
/* ========= FALLING ========= */
2014-01-24 14:57:32 -05:00
2014-01-25 14:02:13 -05:00
virtual void HandleFalling ( void ) ;
int m_LastGroundHeight ;
/* =========================== */
2012-06-14 09:06:06 -04:00
2015-01-16 09:38:21 -05:00
std : : chrono : : milliseconds m_IdleInterval ;
std : : chrono : : milliseconds m_DestroyTimer ;
2012-06-14 09:06:06 -04:00
2014-09-17 13:40:10 -04:00
eMonsterType m_MobType ;
2014-09-01 14:12:56 -04:00
AString m_CustomName ;
bool m_CustomNameAlwaysVisible ;
2012-06-14 09:06:06 -04:00
2012-12-21 13:05:34 -05:00
AString m_SoundHurt ;
AString m_SoundDeath ;
2014-07-17 16:50:58 -04:00
float m_AttackRate ;
2014-01-24 14:57:32 -05:00
int m_AttackDamage ;
int m_AttackRange ;
2012-06-14 09:06:06 -04:00
float m_AttackInterval ;
2014-01-24 14:57:32 -05:00
int m_SightDistance ;
2014-10-11 22:39:55 -04:00
2014-02-23 13:44:58 -05:00
float m_DropChanceWeapon ;
float m_DropChanceHelmet ;
float m_DropChanceChestplate ;
float m_DropChanceLeggings ;
float m_DropChanceBoots ;
bool m_CanPickUpLoot ;
2015-04-29 12:24:14 -04:00
int m_TicksSinceLastDamaged ; // How many ticks ago we were last damaged by a player?
2014-10-11 22:39:55 -04:00
2014-01-24 16:55:04 -05:00
void HandleDaylightBurning ( cChunk & a_Chunk ) ;
2015-04-29 12:24:14 -04:00
bool WouldBurnAt ( Vector3d a_Location , cChunk & a_Chunk ) ;
2013-09-05 16:40:08 -04:00
bool m_BurnsInDaylight ;
2014-09-02 14:10:41 -04:00
double m_RelativeWalkSpeed ;
2014-08-30 06:44:54 -04:00
2014-02-23 13:44:58 -05:00
/** Adds a random number of a_Item between a_Min and a_Max to itemdrops a_Drops*/
2014-07-17 16:50:58 -04:00
void AddRandomDropItem ( cItems & a_Drops , unsigned int a_Min , unsigned int a_Max , short a_Item , short a_ItemHealth = 0 ) ;
2014-10-11 22:39:55 -04:00
2014-02-23 13:44:58 -05:00
/** Adds a item a_Item with the chance of a_Chance (in percent) to itemdrops a_Drops*/
2014-07-17 16:50:58 -04:00
void AddRandomUncommonDropItem ( cItems & a_Drops , float a_Chance , short a_Item , short a_ItemHealth = 0 ) ;
2014-10-11 22:39:55 -04:00
2014-02-23 13:44:58 -05: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 16:50:58 -04:00
void AddRandomRareDropItem ( cItems & a_Drops , cItems & a_Items , short a_LootingLevel ) ;
2014-10-11 22:39:55 -04:00
2014-02-24 09:38:38 -05: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 13:44:58 -05:00
void AddRandomArmorDropItem ( cItems & a_Drops , short a_LootingLevel ) ;
2014-10-11 22:39:55 -04:00
2014-02-24 09:38:38 -05: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 13:44:58 -05:00
void AddRandomWeaponDropItem ( cItems & a_Drops , short a_LootingLevel ) ;
2012-06-14 09:06:06 -04:00
2014-10-11 22:39:55 -04:00
} ; // tolua_export