server/src/game/Creature.h
VladimirMangos 872d791ca6 [7335] Implement active objects support.
Active objects triggrering grid loading and updating around self like players.
It can be used for event long run movements or escoring quest travels.
Also can be used for proper implementation far vision spells.
Currently only creatures can be activated by function call (from script) cr->SetActiveObjectState(true);
Please avoid lot amount active objects in same time use. Existance active objects support isn't meaning
that each rabbit must be active creature.

Also added independent grid unloading locks for explicit unloading lock,
lock for used by instance copied grids, lock counter for actiove object spawn grids locks.
Last case required for prevent double spawn active creature walk far away from spawn point.
2009-02-25 13:44:49 +03:00

685 lines
25 KiB
C++

/*
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef MANGOSSERVER_CREATURE_H
#define MANGOSSERVER_CREATURE_H
#include "Common.h"
#include "Unit.h"
#include "UpdateMask.h"
#include "ItemPrototype.h"
#include "LootMgr.h"
#include "Database/DatabaseEnv.h"
#include "Cell.h"
#include <list>
struct SpellEntry;
class CreatureAI;
class Quest;
class Player;
class WorldSession;
enum Gossip_Option
{
GOSSIP_OPTION_NONE = 0, //UNIT_NPC_FLAG_NONE = 0,
GOSSIP_OPTION_GOSSIP = 1, //UNIT_NPC_FLAG_GOSSIP = 1,
GOSSIP_OPTION_QUESTGIVER = 2, //UNIT_NPC_FLAG_QUESTGIVER = 2,
GOSSIP_OPTION_VENDOR = 3, //UNIT_NPC_FLAG_VENDOR = 4,
GOSSIP_OPTION_TAXIVENDOR = 4, //UNIT_NPC_FLAG_TAXIVENDOR = 8,
GOSSIP_OPTION_TRAINER = 5, //UNIT_NPC_FLAG_TRAINER = 16,
GOSSIP_OPTION_SPIRITHEALER = 6, //UNIT_NPC_FLAG_SPIRITHEALER = 32,
GOSSIP_OPTION_SPIRITGUIDE = 7, //UNIT_NPC_FLAG_SPIRITGUIDE = 64,
GOSSIP_OPTION_INNKEEPER = 8, //UNIT_NPC_FLAG_INNKEEPER = 128,
GOSSIP_OPTION_BANKER = 9, //UNIT_NPC_FLAG_BANKER = 256,
GOSSIP_OPTION_PETITIONER = 10, //UNIT_NPC_FLAG_PETITIONER = 512,
GOSSIP_OPTION_TABARDDESIGNER = 11, //UNIT_NPC_FLAG_TABARDDESIGNER = 1024,
GOSSIP_OPTION_BATTLEFIELD = 12, //UNIT_NPC_FLAG_BATTLEFIELDPERSON = 2048,
GOSSIP_OPTION_AUCTIONEER = 13, //UNIT_NPC_FLAG_AUCTIONEER = 4096,
GOSSIP_OPTION_STABLEPET = 14, //UNIT_NPC_FLAG_STABLE = 8192,
GOSSIP_OPTION_ARMORER = 15, //UNIT_NPC_FLAG_ARMORER = 16384,
GOSSIP_OPTION_UNLEARNTALENTS = 16, //UNIT_NPC_FLAG_TRAINER (bonus option for GOSSIP_OPTION_TRAINER)
GOSSIP_OPTION_UNLEARNPETSKILLS = 17 //UNIT_NPC_FLAG_TRAINER (bonus option for GOSSIP_OPTION_TRAINER)
};
enum Gossip_Guard
{
GOSSIP_GUARD_BANK = 32,
GOSSIP_GUARD_RIDE = 33,
GOSSIP_GUARD_GUILD = 34,
GOSSIP_GUARD_INN = 35,
GOSSIP_GUARD_MAIL = 36,
GOSSIP_GUARD_AUCTION = 37,
GOSSIP_GUARD_WEAPON = 38,
GOSSIP_GUARD_STABLE = 39,
GOSSIP_GUARD_BATTLE = 40,
GOSSIP_GUARD_SPELLTRAINER = 41,
GOSSIP_GUARD_SKILLTRAINER = 42
};
enum Gossip_Guard_Spell
{
GOSSIP_GUARD_SPELL_WARRIOR = 64,
GOSSIP_GUARD_SPELL_PALADIN = 65,
GOSSIP_GUARD_SPELL_HUNTER = 66,
GOSSIP_GUARD_SPELL_ROGUE = 67,
GOSSIP_GUARD_SPELL_PRIEST = 68,
GOSSIP_GUARD_SPELL_UNKNOWN1 = 69,
GOSSIP_GUARD_SPELL_SHAMAN = 70,
GOSSIP_GUARD_SPELL_MAGE = 71,
GOSSIP_GUARD_SPELL_WARLOCK = 72,
GOSSIP_GUARD_SPELL_UNKNOWN2 = 73,
GOSSIP_GUARD_SPELL_DRUID = 74
};
enum Gossip_Guard_Skill
{
GOSSIP_GUARD_SKILL_ALCHEMY = 80,
GOSSIP_GUARD_SKILL_BLACKSMITH = 81,
GOSSIP_GUARD_SKILL_COOKING = 82,
GOSSIP_GUARD_SKILL_ENCHANT = 83,
GOSSIP_GUARD_SKILL_FIRSTAID = 84,
GOSSIP_GUARD_SKILL_FISHING = 85,
GOSSIP_GUARD_SKILL_HERBALISM = 86,
GOSSIP_GUARD_SKILL_LEATHER = 87,
GOSSIP_GUARD_SKILL_MINING = 88,
GOSSIP_GUARD_SKILL_SKINNING = 89,
GOSSIP_GUARD_SKILL_TAILORING = 90,
GOSSIP_GUARD_SKILL_ENGINERING = 91
};
struct GossipOption
{
uint32 Id;
uint32 GossipId;
uint32 NpcFlag;
uint32 Icon;
uint32 Action;
uint32 BoxMoney;
bool Coded;
std::string OptionText;
std::string BoxText;
};
enum CreatureFlagsExtra
{
CREATURE_FLAG_EXTRA_INSTANCE_BIND = 0x00000001, // creature kill bind instance with killer and killer's group
CREATURE_FLAG_EXTRA_CIVILIAN = 0x00000002, // not aggro (ignore faction/reputation hostility)
CREATURE_FLAG_EXTRA_NO_PARRY = 0x00000004, // creature can't parry
CREATURE_FLAG_EXTRA_NO_PARRY_HASTEN = 0x00000008, // creature can't counter-attack at parry
CREATURE_FLAG_EXTRA_NO_BLOCK = 0x00000010, // creature can't block
CREATURE_FLAG_EXTRA_NO_CRUSH = 0x00000020, // creature can't do crush attacks
CREATURE_FLAG_EXTRA_NO_XP_AT_KILL = 0x00000040, // creature kill not provide XP
CREATURE_FLAG_EXTRA_INVISIBLE = 0x00000080, // creature is always invisible for player (mostly trigger creatures)
};
// 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
// from `creature_template` table
struct CreatureInfo
{
uint32 Entry;
uint32 HeroicEntry;
uint32 DisplayID_A;
uint32 DisplayID_A2;
uint32 DisplayID_H;
uint32 DisplayID_H2;
char* Name;
char* SubName;
char* IconName;
uint32 minlevel;
uint32 maxlevel;
uint32 minhealth;
uint32 maxhealth;
uint32 minmana;
uint32 maxmana;
uint32 armor;
uint32 faction_A;
uint32 faction_H;
uint32 npcflag;
float speed;
float scale;
uint32 rank;
float mindmg;
float maxdmg;
uint32 dmgschool;
uint32 attackpower;
uint32 baseattacktime;
uint32 rangeattacktime;
uint32 unit_flags; // enum UnitFlags mask values
uint32 dynamicflags;
uint32 family; // enum CreatureFamily values (optional)
uint32 trainer_type;
uint32 trainer_spell;
uint32 classNum;
uint32 race;
float minrangedmg;
float maxrangedmg;
uint32 rangedattackpower;
uint32 type; // enum CreatureType values
uint32 type_flags; // enum CreatureTypeFlags mask values
uint32 lootid;
uint32 pickpocketLootId;
uint32 SkinLootId;
int32 resistance1;
int32 resistance2;
int32 resistance3;
int32 resistance4;
int32 resistance5;
int32 resistance6;
uint32 spells[CREATURE_MAX_SPELLS];
uint32 PetSpellDataId;
uint32 mingold;
uint32 maxgold;
char const* AIName;
uint32 MovementType;
uint32 InhabitType;
bool RacialLeader;
bool RegenHealth;
uint32 equipmentId;
uint32 MechanicImmuneMask;
uint32 flags_extra;
uint32 ScriptID;
// helpers
SkillType GetRequiredLootSkill() const
{
if(type_flags & CREATURE_TYPEFLAGS_HERBLOOT)
return SKILL_HERBALISM;
else if(type_flags & CREATURE_TYPEFLAGS_MININGLOOT)
return SKILL_MINING;
else if(type_flags & CREATURE_TYPEFLAGS_ENGINEERLOOT)
return SKILL_ENGINERING;
else
return SKILL_SKINNING; // normal case
}
bool isTameable() const
{
return type == CREATURE_TYPE_BEAST && family != 0 && (type_flags & CREATURE_TYPEFLAGS_TAMEABLE);
}
};
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
{
uint32 id; // entry in creature_template
uint16 mapid;
uint16 phaseMask;
uint32 displayid;
int32 equipmentId;
float posX;
float posY;
float posZ;
float orientation;
uint32 spawntimesecs;
float spawndist;
uint32 currentwaypoint;
uint32 curhealth;
uint32 curmana;
bool is_dead;
uint8 movementType;
uint8 spawnMask;
};
struct CreatureDataAddonAura
{
uint16 spell_id;
uint8 effect_idx;
};
// from `creature_addon` table
struct CreatureDataAddon
{
uint32 guidOrEntry;
uint32 mount;
uint32 bytes0;
uint32 bytes1;
uint32 bytes2;
uint32 emote;
uint32 move_flags;
CreatureDataAddonAura const* auras; // loaded as char* "spell1 eff1 spell2 eff2 ... "
};
struct CreatureModelInfo
{
uint32 modelid;
float bounding_radius;
float combat_reach;
uint8 gender;
uint32 modelid_other_gender;
};
enum InhabitTypeValues
{
INHABIT_GROUND = 1,
INHABIT_WATER = 2,
INHABIT_AIR = 4,
INHABIT_ANYWHERE = INHABIT_GROUND | INHABIT_WATER | INHABIT_AIR
};
// 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;
return m_items[slot];
}
bool Empty() const { return m_items.empty(); }
uint8 GetItemCount() const { return m_items.size(); }
void AddItem( uint32 item, uint32 maxcount, uint32 ptime, uint32 ExtendedCost)
{
m_items.push_back(new VendorItem(item, maxcount, ptime, ExtendedCost));
}
bool RemoveItem( uint32 item_id );
VendorItem const* FindItem(uint32 item_id) const;
size_t FindItemSlot(uint32 item_id) const;
void Clear()
{
for (VendorItemList::iterator itr = m_items.begin(); itr != m_items.end(); ++itr)
delete (*itr);
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 255 // Limitation in item count field size in SMSG_LIST_INVENTORY
class MANGOS_DLL_SPEC Creature : public Unit
{
CreatureAI *i_AI;
public:
explicit Creature();
virtual ~Creature();
void AddToWorld();
void RemoveFromWorld();
bool Create (uint32 guidlow, Map *map, uint32 phaseMask, uint32 Entry, uint32 team, 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 m_equipmentId; }
bool isPet() const { return m_isPet; }
bool isVehicle() const { return m_isVehicle; }
void SetCorpseDelay(uint32 delay) { m_corpseDelay = delay; }
bool isTotem() const { return m_isTotem; }
bool isRacialLeader() const { return GetCreatureInfo()->RacialLeader; }
bool isCivilian() const { return GetCreatureInfo()->flags_extra & CREATURE_FLAG_EXTRA_CIVILIAN; }
bool canWalk() const { return GetCreatureInfo()->InhabitType & INHABIT_GROUND; }
bool canSwim() const { return GetCreatureInfo()->InhabitType & INHABIT_WATER; }
bool canFly() const { return GetCreatureInfo()->InhabitType & INHABIT_AIR; }
///// TODO RENAME THIS!!!!!
bool isCanTrainingOf(Player* player, bool msg) const;
bool isCanInteractWithBattleMaster(Player* player, bool msg) const;
bool isCanTrainingAndResetTalentsOf(Player* pPlayer) const;
bool IsOutOfThreatArea(Unit* pVictim) const;
bool IsImmunedToSpell(SpellEntry const* spellInfo);
// redefine Unit::IsImmunedToSpell
bool IsImmunedToSpellEffect(SpellEntry const* spellInfo, uint32 index) const;
// redefine Unit::IsImmunedToSpellEffect
bool isElite() const
{
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;
bool AIM_Initialize();
void AI_SendMoveToPacket(float x, float y, float z, uint32 time, uint32 MovementFlags, uint8 type);
CreatureAI* AI() { return 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();
void UpdateResistances(uint32 school);
void UpdateArmor();
void UpdateMaxHealth();
void UpdateMaxPower(Powers power);
void UpdateAttackPowerAndDamage(bool ranged = false);
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; }
CreatureDataAddon const* GetCreatureAddon() const;
std::string GetScriptName();
uint32 GetScriptId();
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();
GossipOption const* GetGossipOption( uint32 id ) const;
void addGossipOption(GossipOption const& gso) { m_goptions.push_back(gso); }
void setEmoteState(uint8 emote) { m_emoteState = emote; };
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); }
// 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;
float GetAttackDistance(Unit const* pl) const;
void CallAssistance();
void SetNoCallAssistance(bool val) { m_AlreadyCallAssistance = val; }
bool CanAssistTo(const Unit* u, const Unit* enemy) 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* pl) const;
void RemoveCorpse();
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();
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; }
uint32 m_groupLootTimer; // (msecs)timer used for group loot
uint64 lootingGroupLeaderGUID; // used to find group which is looting corpse
void SendZoneUnderAttackMessage(Player* attacker);
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; }
virtual uint32 GetPetAutoSpellOnPos(uint8 pos) const
{
if (pos >= CREATURE_MAX_SPELLS || m_charmInfo->GetCharmSpell(pos)->active != ACT_ENABLED)
return 0;
else
return m_charmInfo->GetCharmSpell(pos)->spellId;
}
void SetCombatStartPosition(float x, float y, float z) { CombatStartX = x; CombatStartY = y; CombatStartZ = z; }
void GetCombatStartPosition(float &x, float &y, float &z) { x = CombatStartX; y = CombatStartY; z = CombatStartZ; }
uint32 GetGlobalCooldown() const { return m_GlobalCooldown; }
void SetDeadByDefault (bool death_state) { m_isDeadByDefault = death_state; }
bool isActiveObject() const { return m_isActiveObject; }
void SetActiveObjectState(bool on);
protected:
bool CreateFromProto(uint32 guidlow,uint32 Entry,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);
static float _GetDamageMod(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;
uint8 m_emoteState;
bool m_isPet; // set only in Pet::Pet
bool m_isVehicle; // set only in Vehicle::Vehicle
bool m_isTotem; // set only in Totem::Totem
void RegenerateMana();
void RegenerateHealth();
MovementGeneratorType m_defaultMovementType;
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_regenHealth;
bool m_AI_locked;
bool m_isDeadByDefault;
SpellSchoolMask m_meleeDamageSchoolMask;
uint32 m_originalEntry;
float CombatStartX;
float CombatStartY;
float CombatStartZ;
private:
GridReference<Creature> m_gridRef;
CreatureInfo const* m_creatureInfo; // in heroic mode can different from ObjMgr::GetCreatureTemplate(GetEntry())
bool m_isActiveObject;
};
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