aboutsummaryrefslogtreecommitdiff
path: root/src/game/Creature.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/game/Creature.h')
-rw-r--r--src/game/Creature.h128
1 files changed, 128 insertions, 0 deletions
diff --git a/src/game/Creature.h b/src/game/Creature.h
index f66d485d183..5fbe4a07a28 100644
--- a/src/game/Creature.h
+++ b/src/game/Creature.h
@@ -17,8 +17,10 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
+
#ifndef TRINITYCORE_CREATURE_H
#define TRINITYCORE_CREATURE_H
+
#include "Common.h"
#include "Unit.h"
#include "UpdateMask.h"
@@ -26,13 +28,17 @@
#include "LootMgr.h"
#include "Database/DatabaseEnv.h"
#include "Cell.h"
+
#include <list>
+
struct SpellEntry;
+
class CreatureAI;
class Quest;
class Player;
class WorldSession;
class CreatureGroup;
+
enum Gossip_Option
{
GOSSIP_OPTION_NONE = 0, //UNIT_NPC_FLAG_NONE = 0,
@@ -56,6 +62,7 @@ enum Gossip_Option
GOSSIP_OPTION_LEARNDUALSPEC = 18, //UNIT_NPC_FLAG_TRAINER (bonus option for GOSSIP_OPTION_TRAINER)
GOSSIP_OPTION_OUTDOORPVP = 19 //added by code (option for outdoor pvp creatures)
};
+
enum Gossip_Guard
{
GOSSIP_GUARD_BANK = 32,
@@ -70,6 +77,7 @@ enum Gossip_Guard
GOSSIP_GUARD_SPELLTRAINER = 41,
GOSSIP_GUARD_SKILLTRAINER = 42
};
+
enum Gossip_Guard_Spell
{
GOSSIP_GUARD_SPELL_WARRIOR = 64,
@@ -84,6 +92,7 @@ enum Gossip_Guard_Spell
GOSSIP_GUARD_SPELL_UNKNOWN2 = 73,
GOSSIP_GUARD_SPELL_DRUID = 74
};
+
enum Gossip_Guard_Skill
{
GOSSIP_GUARD_SKILL_ALCHEMY = 80,
@@ -99,6 +108,7 @@ enum Gossip_Guard_Skill
GOSSIP_GUARD_SKILL_TAILORING = 90,
GOSSIP_GUARD_SKILL_ENGINERING = 91
};
+
enum GossipOptionIcon
{
GOSSIP_ICON_CHAT = 0, //white chat bubble
@@ -113,6 +123,7 @@ enum GossipOptionIcon
GOSSIP_ICON_BATTLE = 9, //two swords
GOSSIP_ICON_DOT = 10 //yellow dot
};
+
struct GossipOption
{
uint32 Id;
@@ -125,6 +136,7 @@ struct GossipOption
std::string OptionText;
std::string BoxText;
};
+
enum CreatureFlagsExtra
{
CREATURE_FLAG_EXTRA_INSTANCE_BIND = 0x00000001, // creature kill bind instance with killer and killer's group
@@ -141,13 +153,16 @@ enum CreatureFlagsExtra
CREATURE_FLAG_EXTRA_NO_CRIT = 0x00020000, // creature can't do critical strikes
CREATURE_FLAG_EXTRA_NO_SKILLGAIN = 0x00040000, // creature won't increase weapon skills
};
+
// GCC have alternative #pragma pack(N) syntax and old gcc version not support pack(push,N), also any gcc version not support it at some platform
#if defined( __GNUC__ )
#pragma pack(1)
#else
#pragma pack(push,1)
#endif
+
#define MAX_KILL_CREDIT 2
+
// from `creature_template` table
struct CreatureInfo
{
@@ -223,6 +238,7 @@ struct CreatureInfo
uint32 ScriptID;
uint32 GetRandomValidModelId() const;
uint32 GetFirstValidModelId() const;
+
// helpers
SkillType GetRequiredLootSkill() const
{
@@ -235,33 +251,40 @@ struct CreatureInfo
else
return SKILL_SKINNING; // normal case
}
+
bool isTameable(bool exotic) const
{
if(type != CREATURE_TYPE_BEAST || family == 0 || (type_flags & CREATURE_TYPEFLAGS_TAMEABLE)==0)
return false;
+
// if can tame exotic then can tame any temable
return exotic || (type_flags & CREATURE_TYPEFLAGS_EXOTIC)==0;
}
};
+
struct CreatureLocale
{
std::vector<std::string> Name;
std::vector<std::string> SubName;
};
+
struct NpcOptionLocale
{
std::vector<std::string> OptionText;
std::vector<std::string> BoxText;
};
+
struct PointOfInterestLocale
{
std::vector<std::string> IconName;
};
+
struct EquipmentInfo
{
uint32 entry;
uint32 equipentry[3];
};
+
// from `creature` table
struct CreatureData
{
@@ -285,11 +308,13 @@ struct CreatureData
uint8 spawnMask;
bool dbData;
};
+
struct CreatureDataAddonAura
{
uint32 spell_id;
uint8 effect_idx;
};
+
// from `creature_addon` table
struct CreatureDataAddon
{
@@ -302,6 +327,7 @@ struct CreatureDataAddon
uint32 move_flags;
CreatureDataAddonAura const* auras; // loaded as char* "spell1 eff1 spell2 eff2 ... "
};
+
struct CreatureModelInfo
{
uint32 modelid;
@@ -310,6 +336,7 @@ struct CreatureModelInfo
uint8 gender;
uint32 modelid_other_gender;
};
+
enum InhabitTypeValues
{
INHABIT_GROUND = 1,
@@ -317,6 +344,7 @@ enum InhabitTypeValues
INHABIT_AIR = 4,
INHABIT_ANYWHERE = INHABIT_GROUND | INHABIT_WATER | INHABIT_AIR
};
+
// Enums used by StringTextData::Type (CreatureEventAI)
enum ChatType
{
@@ -328,6 +356,7 @@ enum ChatType
CHAT_TYPE_BOSS_WHISPER = 5,
CHAT_TYPE_ZONE_YELL = 6
};
+
//Selection method used by SelectTarget (CreatureEventAI)
enum AttackingTarget
{
@@ -340,26 +369,31 @@ enum AttackingTarget
ATTACKING_TARGET_BOTTOMAGGRO_PLAYER, //Selects targets from bottom aggro to top (player only)
*/
};
+
// GCC have alternative #pragma pack() syntax and old gcc version not support pack(pop), also any gcc version not support it at some platform
#if defined( __GNUC__ )
#pragma pack()
#else
#pragma pack(pop)
#endif
+
// Vendors
struct VendorItem
{
VendorItem(uint32 _item, uint32 _maxcount, uint32 _incrtime, uint32 _ExtendedCost)
: item(_item), maxcount(_maxcount), incrtime(_incrtime), ExtendedCost(_ExtendedCost) {}
+
uint32 item;
uint32 maxcount; // 0 for infinity item amount
uint32 incrtime; // time for restore items amount if maxcount != 0
uint32 ExtendedCost;
};
typedef std::vector<VendorItem*> VendorItemList;
+
struct VendorItemData
{
VendorItemList m_items;
+
VendorItem* GetItem(uint32 slot) const
{
if(slot>=m_items.size()) return NULL;
@@ -374,6 +408,7 @@ struct VendorItemData
bool RemoveItem( uint32 item_id );
VendorItem const* FindItem(uint32 item_id) const;
size_t FindItemSlot(uint32 item_id) const;
+
void Clear()
{
for (VendorItemList::const_iterator itr = m_items.begin(); itr != m_items.end(); ++itr)
@@ -381,62 +416,84 @@ struct VendorItemData
m_items.clear();
}
};
+
struct VendorItemCount
{
explicit VendorItemCount(uint32 _item, uint32 _count)
: itemId(_item), count(_count), lastIncrementTime(time(NULL)) {}
+
uint32 itemId;
uint32 count;
time_t lastIncrementTime;
};
+
typedef std::list<VendorItemCount> VendorItemCounts;
+
struct TrainerSpell
{
TrainerSpell() : spell(0), spellCost(0), reqSkill(0), reqSkillValue(0), reqLevel(0), learnedSpell(0) {}
+
TrainerSpell(uint32 _spell, uint32 _spellCost, uint32 _reqSkill, uint32 _reqSkillValue, uint32 _reqLevel, uint32 _learnedspell)
: spell(_spell), spellCost(_spellCost), reqSkill(_reqSkill), reqSkillValue(_reqSkillValue), reqLevel(_reqLevel), learnedSpell(_learnedspell)
{}
+
uint32 spell;
uint32 spellCost;
uint32 reqSkill;
uint32 reqSkillValue;
uint32 reqLevel;
uint32 learnedSpell;
+
// helpers
bool IsCastable() const { return learnedSpell != spell; }
};
+
typedef UNORDERED_MAP<uint32 /*spellid*/, TrainerSpell> TrainerSpellMap;
+
struct TrainerSpellData
{
TrainerSpellData() : trainerType(0) {}
+
TrainerSpellMap spellList;
uint32 trainerType; // trainer type based at trainer spells, can be different from creature_template value.
// req. for correct show non-prof. trainers like weaponmaster, allowed values 0 and 2.
TrainerSpell const* Find(uint32 spell_id) const;
void Clear() { spellList.clear(); }
};
+
typedef std::list<GossipOption> GossipOptionList;
+
typedef std::map<uint32,time_t> CreatureSpellCooldowns;
+
// max different by z coordinate for creature aggro reaction
#define CREATURE_Z_ATTACK_RANGE 3
+
#define MAX_VENDOR_ITEMS 150 // Limitation in 3.x.x item count in SMSG_LIST_INVENTORY
+
class TRINITY_DLL_SPEC Creature : public Unit
{
public:
+
explicit Creature();
virtual ~Creature();
+
void AddToWorld();
void RemoveFromWorld();
+
void DisappearAndDie();
+
bool Create(uint32 guidlow, Map *map, uint32 phaseMask, uint32 Entry, uint32 vehId, uint32 team, float x, float y, float z, float ang, const CreatureData *data = NULL);
bool LoadCreaturesAddon(bool reload = false);
void SelectLevel(const CreatureInfo *cinfo);
void LoadEquipment(uint32 equip_entry, bool force=false);
+
uint32 GetDBTableGUIDLow() const { return m_DBTableGuid; }
char const* GetSubName() const { return GetCreatureInfo()->SubName; }
+
void Update( uint32 time ); // overwrited Unit::Update
void GetRespawnCoord(float &x, float &y, float &z, float* ori = NULL, float* dist =NULL) const;
uint32 GetEquipmentId() const { return GetCreatureInfo()->equipmentId; }
+
void SetCorpseDelay(uint32 delay) { m_corpseDelay = delay; }
bool isRacialLeader() const { return GetCreatureInfo()->RacialLeader; }
bool isCivilian() const { return GetCreatureInfo()->flags_extra & CREATURE_FLAG_EXTRA_CIVILIAN; }
@@ -460,33 +517,45 @@ class TRINITY_DLL_SPEC Creature : public Unit
{
if(isPet())
return false;
+
uint32 rank = GetCreatureInfo()->rank;
return rank != CREATURE_ELITE_NORMAL && rank != CREATURE_ELITE_RARE;
}
+
bool isWorldBoss() const
{
if(isPet())
return false;
+
return GetCreatureInfo()->rank == CREATURE_ELITE_WORLDBOSS;
}
+
uint32 getLevelForTarget(Unit const* target) const; // overwrite Unit::getLevelForTarget for boss level support
+
bool IsInEvadeMode() const { return hasUnitState(UNIT_STAT_EVADE); }
+
bool AIM_Initialize(CreatureAI* ai = NULL);
void Motion_Initialize();
+
void AI_SendMoveToPacket(float x, float y, float z, uint32 time, uint32 MovementFlags, uint8 type);
CreatureAI * AI() const { return (CreatureAI*)i_AI; }
+
uint32 GetShieldBlockValue() const //dunno mob block value
{
return (getLevel()/2 + uint32(GetStat(STAT_STRENGTH)/20));
}
+
SpellSchoolMask GetMeleeDamageSchoolMask() const { return m_meleeDamageSchoolMask; }
void SetMeleeDamageSchool(SpellSchools school) { m_meleeDamageSchoolMask = SpellSchoolMask(1 << school); }
+
void _AddCreatureSpellCooldown(uint32 spell_id, time_t end_time);
void _AddCreatureCategoryCooldown(uint32 category, time_t apply_time);
void AddCreatureSpellCooldown(uint32 spellid);
bool HasSpellCooldown(uint32 spell_id) const;
bool HasCategoryCooldown(uint32 spell_id) const;
+
bool HasSpell(uint32 spellID) const;
+
bool UpdateEntry(uint32 entry, uint32 team=ALLIANCE, const CreatureData* data=NULL);
bool UpdateStats(Stats stat);
bool UpdateAllStats();
@@ -498,56 +567,72 @@ class TRINITY_DLL_SPEC Creature : public Unit
void UpdateDamagePhysical(WeaponAttackType attType);
uint32 GetCurrentEquipmentId() { return m_equipmentId; }
float GetSpellDamageMod(int32 Rank);
+
VendorItemData const* GetVendorItems() const;
uint32 GetVendorItemCurrentCount(VendorItem const* vItem);
uint32 UpdateVendorItemCurrentCount(VendorItem const* vItem, uint32 used_count);
+
TrainerSpellData const* GetTrainerSpells() const;
+
CreatureInfo const *GetCreatureInfo() const { return m_creatureInfo; }
CreatureData const *GetCreatureData() const { return m_creatureData; }
CreatureDataAddon const* GetCreatureAddon() const;
+
std::string GetAIName() const;
std::string GetScriptName() const;
uint32 GetScriptId() const;
+
void prepareGossipMenu( Player *pPlayer, uint32 gossipid = 0 );
void sendPreparedGossip( Player* player );
void OnGossipSelect(Player* player, uint32 option);
void OnPoiSelect(Player* player, GossipOption const *gossip);
+
uint32 GetGossipTextId(uint32 action, uint32 zoneid);
uint32 GetNpcTextId();
void LoadGossipOptions();
void ResetGossipOptions();
GossipOption const* GetGossipOption( uint32 id ) const;
void addGossipOption(GossipOption const& gso) { m_goptions.push_back(gso); }
+
void Say(int32 textId, uint32 language, uint64 TargetGuid) { MonsterSay(textId,language,TargetGuid); }
void Yell(int32 textId, uint32 language, uint64 TargetGuid) { MonsterYell(textId,language,TargetGuid); }
void TextEmote(int32 textId, uint64 TargetGuid, bool IsBossEmote = false) { MonsterTextEmote(textId,TargetGuid,IsBossEmote); }
void Whisper(int32 textId, uint64 receiver, bool IsBossWhisper = false) { MonsterWhisper(textId,receiver,IsBossWhisper); }
void YellToZone(int32 textId, uint32 language, uint64 TargetGuid) { MonsterYellToZone(textId,language,TargetGuid); }
+
// overwrite WorldObject function for proper name localization
const char* GetNameForLocaleIdx(int32 locale_idx) const;
+
void setDeathState(DeathState s); // overwrite virtual Unit::setDeathState
bool FallGround();
+
bool LoadFromDB(uint32 guid, Map *map);
void SaveToDB();
// overwrited in Pet
virtual void SaveToDB(uint32 mapid, uint8 spawnMask, uint32 phaseMask);
virtual void DeleteFromDB(); // overwrited in Pet
+
Loot loot;
bool lootForPickPocketed;
bool lootForBody;
Player *GetLootRecipient() const;
bool hasLootRecipient() const { return m_lootRecipient!=0; }
+
void SetLootRecipient (Unit* unit);
void AllLootRemovedFromCorpse();
+
SpellEntry const *reachWithSpellAttack(Unit *pVictim);
SpellEntry const *reachWithSpellCure(Unit *pVictim);
+
uint32 m_spells[CREATURE_MAX_SPELLS];
CreatureSpellCooldowns m_CreatureSpellCooldowns;
CreatureSpellCooldowns m_CreatureCategoryCooldowns;
uint32 m_GlobalCooldown;
+
bool canSeeOrDetect(Unit const* u, bool detect, bool inVisibleList = false, bool is3dDistance = true) const;
bool canStartAttack(Unit const* u, bool force) const;
float GetAttackDistance(Unit const* pl) const;
+
Unit* SelectNearestTarget(float dist = 0) const;
void DoFleeToGetAssistance();
void CallForHelp(float fRadius);
@@ -557,33 +642,47 @@ class TRINITY_DLL_SPEC Creature : public Unit
bool HasSearchedAssistance() { return m_AlreadySearchedAssistance; }
bool CanAssistTo(const Unit* u, const Unit* enemy, bool checkfaction = true) const;
bool _IsTargetAcceptable(const Unit* target) const;
+
MovementGeneratorType GetDefaultMovementType() const { return m_defaultMovementType; }
void SetDefaultMovementType(MovementGeneratorType mgt) { m_defaultMovementType = mgt; }
+
// for use only in LoadHelper, Map::Add Map::CreatureCellRelocation
Cell const& GetCurrentCell() const { return m_currentCell; }
void SetCurrentCell(Cell const& cell) { m_currentCell = cell; }
+
bool IsVisibleInGridForPlayer(Player const* pl) const;
+
void RemoveCorpse();
bool isDeadByDefault() const { return m_isDeadByDefault; };
+
void ForcedDespawn();
+
time_t const& GetRespawnTime() const { return m_respawnTime; }
time_t GetRespawnTimeEx() const;
void SetRespawnTime(uint32 respawn) { m_respawnTime = respawn ? time(NULL) + respawn : 0; }
void Respawn(bool force = false);
void SaveRespawnTime();
+
uint32 GetRespawnDelay() const { return m_respawnDelay; }
void SetRespawnDelay(uint32 delay) { m_respawnDelay = delay; }
+
float GetRespawnRadius() const { return m_respawnradius; }
void SetRespawnRadius(float dist) { m_respawnradius = dist; }
+
// Linked Creature Respawning System
time_t GetLinkedCreatureRespawnTime() const;
const CreatureData* GetLinkedRespawnCreatureData() const;
+
uint32 m_groupLootTimer; // (msecs)timer used for group loot
uint64 lootingGroupLeaderGUID; // used to find group which is looting corpse
+
void SendZoneUnderAttackMessage(Player* attacker);
+
void SetInCombatWithZone();
+
bool hasQuest(uint32 quest_id) const;
bool hasInvolvedQuest(uint32 quest_id) const;
+
GridReference<Creature> &GetGridRef() { return m_gridRef; }
bool isRegeneratingHealth() { return m_regenHealth; }
virtual uint8 GetPetAutoSpellSize() const { return CREATURE_MAX_SPELLS; }
@@ -594,19 +693,26 @@ class TRINITY_DLL_SPEC Creature : public Unit
else
return m_charmInfo->GetCharmSpell(pos)->GetAction();
}
+
void SetHomePosition(float x, float y, float z, float o) { m_homePosition.Relocate(x, y, z, o); }
void SetHomePosition(const Position &pos) { m_homePosition.Relocate(pos);}
void GetHomePosition(float &x, float &y, float &z, float &ori) { m_homePosition.GetPosition(x, y, z, ori); }
+
uint32 GetGlobalCooldown() const { return m_GlobalCooldown; }
+
uint32 GetWaypointPath(){return m_path_id;}
void LoadPath(uint32 pathid) { m_path_id = pathid; }
+
uint32 GetCurrentWaypointID(){return m_waypointID;}
void UpdateWaypointID(uint32 wpID){m_waypointID = wpID;}
+
void SearchFormation();
CreatureGroup *GetFormation() {return m_formation;}
void SetFormation(CreatureGroup *formation) {m_formation = formation;}
+
Unit *SelectVictim();
void SetDeadByDefault (bool death_state) {m_isDeadByDefault = death_state;}
+
void SetDisableReputationGain(bool disable) { DisableReputationGain = disable; }
bool IsReputationGainDisabled() { return DisableReputationGain; }
bool IsDamageEnoughForLootingAndReward() { return m_PlayerDamageReq == 0; }
@@ -617,26 +723,36 @@ class TRINITY_DLL_SPEC Creature : public Unit
}
void ResetPlayerDamageReq() { m_PlayerDamageReq = GetHealth() / 2; }
uint32 m_PlayerDamageReq;
+
void SetOriginalEntry(uint32 entry) { m_originalEntry = entry; }
+
static float _GetDamageMod(int32 Rank);
+
float m_SightDistance, m_CombatDistance;
protected:
bool CreateFromProto(uint32 guidlow, uint32 Entry, uint32 vehId, uint32 team, const CreatureData *data = NULL);
bool InitEntry(uint32 entry, uint32 team=ALLIANCE, const CreatureData* data=NULL);
+
// vendor items
VendorItemCounts m_vendorItemCounts;
+
void _RealtimeSetCreatureInfo();
+
static float _GetHealthMod(int32 Rank);
+
uint32 m_lootMoney;
uint64 m_lootRecipient;
+
/// Timers
uint32 m_deathTimer; // (msecs)timer for death or corpse disappearance
time_t m_respawnTime; // (secs) time of next respawn
uint32 m_respawnDelay; // (secs) delay between corpse disappearance and respawning
uint32 m_corpseDelay; // (secs) delay between death and corpse disappearance
float m_respawnradius;
+
bool m_gossipOptionLoaded;
GossipOptionList m_goptions;
+
ReactStates m_reactState; // for AI, not charmInfo
void RegenerateMana();
void RegenerateHealth();
@@ -645,36 +761,48 @@ class TRINITY_DLL_SPEC Creature : public Unit
Cell m_currentCell; // store current cell where creature listed
uint32 m_DBTableGuid; ///< For new or temporary creatures is 0 for saved it is lowguid
uint32 m_equipmentId;
+
bool m_AlreadyCallAssistance;
bool m_AlreadySearchedAssistance;
bool m_regenHealth;
bool m_AI_locked;
bool m_isDeadByDefault;
+
SpellSchoolMask m_meleeDamageSchoolMask;
uint32 m_originalEntry;
+
Position m_homePosition;
+
bool DisableReputationGain;
+
CreatureInfo const* m_creatureInfo; // in heroic mode can different from ObjMgr::GetCreatureTemplate(GetEntry())
CreatureData const* m_creatureData;
+
private:
//WaypointMovementGenerator vars
uint32 m_waypointID;
uint32 m_path_id;
+
//Formation var
CreatureGroup *m_formation;
+
GridReference<Creature> m_gridRef;
};
+
class AssistDelayEvent : public BasicEvent
{
public:
AssistDelayEvent(const uint64& victim, Unit& owner) : BasicEvent(), m_victim(victim), m_owner(owner) { }
+
bool Execute(uint64 e_time, uint32 p_time);
void AddAssistant(const uint64& guid) { m_assistants.push_back(guid); }
private:
AssistDelayEvent();
+
uint64 m_victim;
std::list<uint64> m_assistants;
Unit& m_owner;
};
+
#endif