/* * Ascent MMORPG Server * Copyright (C) 2005-2007 Ascent Team * * 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 3 of the License, or * 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, see . * */ #ifndef __UNIT_H #define __UNIT_H class AIInterface; class DynamicObject; #define MAX_AURAS 56 // 40 buff slots, 16 debuff slots. #define MAX_POSITIVE_AURAS 40 // ? #define MAX_PASSIVE_AURAS 192 // grep: i mananged to break this.. :p seems we need more bool SERVER_DECL Rand(float); #define UF_TARGET_DIED 1 #define UF_ATTACKING 2 // this unit is attacking it's selection #define SPELL_GROUPS 32//maximum possible is 32, may be less #define UNIT_TYPE_HUMANOID_BIT (1 << (HUMANOID-1)) //should get computed by precompiler ;) class Aura; class Spell; class AIInterface; class GameObject; struct CreatureInfo; struct FactionTemplateDBC; struct FactionDBC; typedef struct { uint32 damage_type; int32 full_damage; uint32 resisted_damage; }dealdamage; struct ReflectSpellSchool { uint32 spellId; int32 school; int32 chance; }; typedef struct { uint32 spellid; uint64 caster;//not yet in use int32 amt; }Absorb; typedef std::list SchoolAbsorb; typedef struct { uint32 spellid; uint32 mindmg; uint32 maxdmg; } OnHitSpell; struct AreaAura { uint32 auraid; Unit* caster; }; enum DeathState { ALIVE = 0, // Unit is alive and well JUST_DIED, // Unit has JUST died CORPSE, // Unit has died but remains in the world as a corpse DEAD // Unit is dead and his corpse is gone from the world }; #define HIGHEST_FACTION = 46 enum Factions { FACTION_BLOODSAIL_BUCCANEERS, FACTION_BOOTY_BAY, FACTION_GELKIS_CLAN_CENTAUR, FACTION_MAGRAM_CLAN_CENTAUR, FACTION_THORIUM_BROTHERHOOD, FACTION_RAVENHOLDT, FACTION_SYNDICATE, FACTION_GADGETZAN, FACTION_WILDHAMMER_CLAN, FACTION_RATCHET, FACTION_UNK1, FACTION_UNK2, FACTION_UNK3, FACTION_ARGENT_DAWN, FACTION_ORGRIMMAR, FACTION_DARKSPEAR_TROLLS, FACTION_THUNDER_BLUFF, FACTION_UNDERCITY, FACTION_GNOMEREGAN_EXILES, FACTION_STORMWIND, FACTION_IRONFORGE, FACTION_DARNASSUS, FACTION_LEATHERWORKING_DRAGON, FACTION_LEATHERWORKING_ELEMENTAL, FACTION_LEATHERWORKING_TRIBAL, FACTION_ENGINEERING_GNOME, FACTION_ENGINEERING_GOBLIN, FACTION_WINTERSABER_TRAINERS, FACTION_EVERLOOK, FACTION_BLACKSMITHING_ARMOR, FACTION_BLACKSMITHING_WEAPON, FACTION_BLACKSMITHING_AXE, FACTION_BLACKSMITHING_SWORD, FACTION_BLACKSMITHING_HAMMER, FACTION_CAER_DARROW, FACTION_TIMBERMAW_FURBOLGS, FACTION_CENARION_CIRCLE, FACTION_SHATTERSPEAR_TROLLS, FACTION_RAVASAUR_TRAINERS, FACTION_BATTLEGROUND_NEUTRAL, FACTION_STORMPIKE_GUARDS, FACTION_FROSTWOLF_CLAN, FACTION_HYDRAXIAN_WATERLORDS, FACTION_MORO_GAI, FACTION_SHEN_DRALAR, FACTION_SILVERWING_SENTINELS, FACTION_WARSONG_OUTRIDERS }; typedef enum { TEXTEMOTE_AGREE = 1, TEXTEMOTE_AMAZE = 2, TEXTEMOTE_ANGRY = 3, TEXTEMOTE_APOLOGIZE = 4, TEXTEMOTE_APPLAUD = 5, TEXTEMOTE_BASHFUL = 6, TEXTEMOTE_BECKON = 7, TEXTEMOTE_BEG = 8, TEXTEMOTE_BITE = 9, TEXTEMOTE_BLEED = 10, TEXTEMOTE_BLINK = 11, TEXTEMOTE_BLUSH = 12, TEXTEMOTE_BONK = 13, TEXTEMOTE_BORED = 14, TEXTEMOTE_BOUNCE = 15, TEXTEMOTE_BRB = 16, TEXTEMOTE_BOW = 17, TEXTEMOTE_BURP = 18, TEXTEMOTE_BYE = 19, TEXTEMOTE_CACKLE = 20, TEXTEMOTE_CHEER = 21, TEXTEMOTE_CHICKEN = 22, TEXTEMOTE_CHUCKLE = 23, TEXTEMOTE_CLAP = 24, TEXTEMOTE_CONFUSED = 25, TEXTEMOTE_CONGRATULATE = 26, TEXTEMOTE_COUGH = 27, TEXTEMOTE_COWER = 28, TEXTEMOTE_CRACK = 29, TEXTEMOTE_CRINGE = 30, TEXTEMOTE_CRY = 31, TEXTEMOTE_CURIOUS = 32, TEXTEMOTE_CURTSEY = 33, TEXTEMOTE_DANCE = 34, TEXTEMOTE_DRINK = 35, TEXTEMOTE_DROOL = 36, TEXTEMOTE_EAT = 37, TEXTEMOTE_EYE = 38, TEXTEMOTE_FART = 39, TEXTEMOTE_FIDGET = 40, TEXTEMOTE_FLEX = 41, TEXTEMOTE_FROWN = 42, TEXTEMOTE_GASP = 43, TEXTEMOTE_GAZE = 44, TEXTEMOTE_GIGGLE = 45, TEXTEMOTE_GLARE = 46, TEXTEMOTE_GLOAT = 47, TEXTEMOTE_GREET = 48, TEXTEMOTE_GRIN = 49, TEXTEMOTE_GROAN = 50, TEXTEMOTE_GROVEL = 51, TEXTEMOTE_GUFFAW = 52, TEXTEMOTE_HAIL = 53, TEXTEMOTE_HAPPY = 54, TEXTEMOTE_HELLO = 55, TEXTEMOTE_HUG = 56, TEXTEMOTE_HUNGRY = 57, TEXTEMOTE_KISS = 58, TEXTEMOTE_KNEEL = 59, TEXTEMOTE_LAUGH = 60, TEXTEMOTE_LAYDOWN = 61, TEXTEMOTE_MASSAGE = 62, TEXTEMOTE_MOAN = 63, TEXTEMOTE_MOON = 64, TEXTEMOTE_MOURN = 65, TEXTEMOTE_NO = 66, TEXTEMOTE_NOD = 67, TEXTEMOTE_NOSEPICK = 68, TEXTEMOTE_PANIC = 69, TEXTEMOTE_PEER = 70, TEXTEMOTE_PLEAD = 71, TEXTEMOTE_POINT = 72, TEXTEMOTE_POKE = 73, TEXTEMOTE_PRAY = 74, TEXTEMOTE_ROAR = 75, TEXTEMOTE_ROFL = 76, TEXTEMOTE_RUDE = 77, TEXTEMOTE_SALUTE = 78, TEXTEMOTE_SCRATCH = 79, TEXTEMOTE_SEXY = 80, TEXTEMOTE_SHAKE = 81, TEXTEMOTE_SHOUT = 82, TEXTEMOTE_SHRUG = 83, TEXTEMOTE_SHY = 84, TEXTEMOTE_SIGH = 85, TEXTEMOTE_SIT = 86, TEXTEMOTE_SLEEP = 87, TEXTEMOTE_SNARL = 88, TEXTEMOTE_SPIT = 89, TEXTEMOTE_STARE = 90, TEXTEMOTE_SURPRISED = 91, TEXTEMOTE_SURRENDER = 92, TEXTEMOTE_TALK = 93, TEXTEMOTE_TALKEX = 94, TEXTEMOTE_TALKQ = 95, TEXTEMOTE_TAP = 96, TEXTEMOTE_THANK = 97, TEXTEMOTE_THREATEN = 98, TEXTEMOTE_TIRED = 99, TEXTEMOTE_VICTORY = 100, TEXTEMOTE_WAVE = 101, TEXTEMOTE_WELCOME = 102, TEXTEMOTE_WHINE = 103, TEXTEMOTE_WHISTLE = 104, TEXTEMOTE_WORK = 105, TEXTEMOTE_YAWN = 106, TEXTEMOTE_BOGGLE = 107, TEXTEMOTE_CALM = 108, TEXTEMOTE_COLD = 109, TEXTEMOTE_COMFORT = 110, TEXTEMOTE_CUDDLE = 111, TEXTEMOTE_DUCK = 112, TEXTEMOTE_INSULT = 113, TEXTEMOTE_INTRODUCE = 114, TEXTEMOTE_JK = 115, TEXTEMOTE_LICK = 116, TEXTEMOTE_LISTEN = 117, TEXTEMOTE_LOST = 118, TEXTEMOTE_MOCK = 119, TEXTEMOTE_PONDER = 120, TEXTEMOTE_POUNCE = 121, TEXTEMOTE_PRAISE = 122, TEXTEMOTE_PURR = 123, TEXTEMOTE_PUZZLE = 124, TEXTEMOTE_RAISE = 125, TEXTEMOTE_READY = 126, TEXTEMOTE_SHIMMY = 127, TEXTEMOTE_SHIVER = 128, TEXTEMOTE_SHOO = 129, TEXTEMOTE_SLAP = 130, TEXTEMOTE_SMIRK = 131, TEXTEMOTE_SNIFF = 132, TEXTEMOTE_SNUB = 133, TEXTEMOTE_SOOTHE = 134, TEXTEMOTE_STINK = 135, TEXTEMOTE_TAUNT = 136, TEXTEMOTE_TEASE = 137, TEXTEMOTE_THIRSTY = 138, TEXTEMOTE_VETO = 139, TEXTEMOTE_SNICKER = 140, TEXTEMOTE_STAND = 141, TEXTEMOTE_TICKLE = 142, TEXTEMOTE_VIOLIN = 143, TEXTEMOTE_SMILE = 163, TEXTEMOTE_RASP = 183, TEXTEMOTE_PITY = 203, TEXTEMOTE_GROWL = 204, TEXTEMOTE_BARK = 205, TEXTEMOTE_SCARED = 223, TEXTEMOTE_FLOP = 224, TEXTEMOTE_LOVE = 225, TEXTEMOTE_MOO = 226, TEXTEMOTE_COMMEND = 243, TEXTEMOTE_JOKE = 329 } TextEmoteType; typedef enum { EMOTE_ONESHOT_NONE = 0, EMOTE_ONESHOT_TALK = 1, //DNR EMOTE_ONESHOT_BOW = 2, EMOTE_ONESHOT_WAVE = 3, //DNR EMOTE_ONESHOT_CHEER = 4, //DNR EMOTE_ONESHOT_EXCLAMATION = 5, //DNR EMOTE_ONESHOT_QUESTION = 6, EMOTE_ONESHOT_EAT = 7, EMOTE_STATE_DANCE = 10, EMOTE_ONESHOT_LAUGH = 11, EMOTE_STATE_SLEEP = 12, EMOTE_STATE_SIT = 13, EMOTE_ONESHOT_RUDE = 14, //DNR EMOTE_ONESHOT_ROAR = 15, //DNR EMOTE_ONESHOT_KNEEL = 16, EMOTE_ONESHOT_KISS = 17, EMOTE_ONESHOT_CRY = 18, EMOTE_ONESHOT_CHICKEN = 19, EMOTE_ONESHOT_BEG = 20, EMOTE_ONESHOT_APPLAUD = 21, EMOTE_ONESHOT_SHOUT = 22, //DNR EMOTE_ONESHOT_FLEX = 23, EMOTE_ONESHOT_SHY = 24, //DNR EMOTE_ONESHOT_POINT = 25, //DNR EMOTE_STATE_STAND = 26, EMOTE_STATE_READYUNARMED = 27, EMOTE_STATE_WORK = 28, EMOTE_STATE_POINT = 29, //DNR EMOTE_STATE_NONE = 30, EMOTE_ONESHOT_WOUND = 33, EMOTE_ONESHOT_WOUNDCRITICAL = 34, EMOTE_ONESHOT_ATTACKUNARMED = 35, EMOTE_ONESHOT_ATTACK1H = 36, EMOTE_ONESHOT_ATTACK2HTIGHT = 37, EMOTE_ONESHOT_ATTACK2HLOOSE = 38, EMOTE_ONESHOT_PARRYUNARMED = 39, EMOTE_ONESHOT_PARRYSHIELD = 43, EMOTE_ONESHOT_READYUNARMED = 44, EMOTE_ONESHOT_READY1H = 45, EMOTE_ONESHOT_READYBOW = 48, EMOTE_ONESHOT_SPELLPRECAST = 50, EMOTE_ONESHOT_SPELLCAST = 51, EMOTE_ONESHOT_BATTLEROAR = 53, EMOTE_ONESHOT_SPECIALATTACK1H = 54, EMOTE_ONESHOT_KICK = 60, EMOTE_ONESHOT_ATTACKTHROWN = 61, EMOTE_STATE_STUN = 64, EMOTE_STATE_DEAD = 65, EMOTE_ONESHOT_SALUTE = 66, EMOTE_STATE_KNEEL = 68, EMOTE_STATE_USESTANDING = 69, EMOTE_ONESHOT_WAVE_NOSHEATHE = 70, EMOTE_ONESHOT_CHEER_NOSHEATHE = 71, EMOTE_ONESHOT_EAT_NOSHEATHE = 92, EMOTE_STATE_STUN_NOSHEATHE = 93, EMOTE_ONESHOT_DANCE = 94, EMOTE_ONESHOT_SALUTE_NOSHEATH = 113, EMOTE_STATE_USESTANDING_NOSHEATHE = 133, EMOTE_ONESHOT_LAUGH_NOSHEATHE = 153, EMOTE_STATE_WORK_NOSHEATHE = 173, EMOTE_STATE_SPELLPRECAST = 193, EMOTE_ONESHOT_READYRIFLE = 213, EMOTE_STATE_READYRIFLE = 214, EMOTE_STATE_WORK_NOSHEATHE_MINING = 233, EMOTE_STATE_WORK_NOSHEATHE_CHOPWOOD= 234, EMOTE_zzOLDONESHOT_LIFTOFF = 253, EMOTE_ONESHOT_LIFTOFF = 254, EMOTE_ONESHOT_YES = 273, //DNR EMOTE_ONESHOT_NO = 274, //DNR EMOTE_ONESHOT_TRAIN = 275, //DNR EMOTE_ONESHOT_LAND = 293, EMOTE_STATE_AT_EASE = 313, EMOTE_STATE_READY1H = 333, EMOTE_STATE_SPELLKNEELSTART = 353, EMOTE_STATE_SUBMERGED = 373, EMOTE_ONESHOT_SUBMERGE = 374, EMOTE_STATE_READY2H = 375, EMOTE_STATE_READYBOW = 376, EMOTE_ONESHOT_MOUNTSPECIAL = 377, EMOTE_STATE_TALK = 378, EMOTE_STATE_FISHING = 379, EMOTE_ONESHOT_FISHING = 380, EMOTE_ONESHOT_LOOT = 381, EMOTE_STATE_WHIRLWIND = 382, EMOTE_STATE_DROWNED = 383, EMOTE_STATE_HOLD_BOW = 384, EMOTE_STATE_HOLD_RIFLE = 385, EMOTE_STATE_HOLD_THROWN = 386, EMOTE_ONESHOT_DROWN = 387, EMOTE_ONESHOT_STOMP = 388, EMOTE_ONESHOT_ATTACKOFF = 389, EMOTE_ONESHOT_ATTACKOFFPIERCE = 390, EMOTE_STATE_ROAR = 391, EMOTE_STATE_LAUGH = 392, EMOTE_ONESHOT_CREATURE_SPECIAL = 393, EMOTE_ONESHOT_JUMPANDRUN = 394, EMOTE_ONESHOT_JUMPEND = 395, EMOTE_ONESHOT_TALK_NOSHEATHE = 396, EMOTE_ONESHOT_POINT_NOSHEATHE = 397, EMOTE_STATE_CANNIBALIZE = 398, EMOTE_ONESHOT_JUMPSTART = 399, EMOTE_STATE_DANCESPECIAL = 400, EMOTE_ONESHOT_DANCESPECIAL = 401, EMOTE_ONESHOT_CUSTOMSPELL01 = 402, EMOTE_ONESHOT_CUSTOMSPELL02 = 403, EMOTE_ONESHOT_CUSTOMSPELL03 = 404, EMOTE_ONESHOT_CUSTOMSPELL04 = 405, EMOTE_ONESHOT_CUSTOMSPELL05 = 406, EMOTE_ONESHOT_CUSTOMSPELL06 = 407, EMOTE_ONESHOT_CUSTOMSPELL07 = 408, EMOTE_ONESHOT_CUSTOMSPELL08 = 409, EMOTE_ONESHOT_CUSTOMSPELL09 = 410, EMOTE_ONESHOT_CUSTOMSPELL10 = 411, EMOTE_STATE_EXCLAIM = 412, } EmoteType; enum StandState { STANDSTATE_STAND = 0, STANDSTATE_SIT = 1, STANDSTATE_SIT_CHAIR = 2, STANDSTATE_SLEEP = 3, STANDSTATE_SIT_LOW_CHAIR = 4, STANDSTATE_SIT_MEDIUM_CHAIR = 5, STANDSTATE_SIT_HIGH_CHAIR = 6, STANDSTATE_DEAD = 7, STANDSTATE_KNEEL = 8 }; enum UnitFieldBytes1 { U_FIELD_BYTES_ANIMATION_FROZEN = 0x01, }; enum UnitFieldBytes2 { U_FIELD_BYTES_HIDE_POS_AURAS = 0x01, }; enum UnitFieldFlags { // = 0x01 // = 0x02, U_FIELD_FLAG_LOCK_PLAYER = 0x04, U_FIELD_FLAG_PLAYER_CONTROLLED = 0x08, // = 0x10 // = 0x20 U_FIELD_FLAG_PLUS_MOB = 0x40, // = 0x80 U_FIELD_FLAG_UNIT_UNTACKABLE_SELECT = 0x100, // = 0x200, U_FIELD_ANIMATION_LOOTING = 0x400, U_FIELD_SELF_RES = 0x800, U_FIELD_FLAG_PVP = 0x1000, U_FIELD_FLAG_MOUNT_SIT = 0x2000, U_FIELD_FLAG_DEAD = 0x4000, // = 0x8000 U_FIELD_FLAG_ALIVE = 0x10000, // = 0x20000, U_FIELD_FLAG_NO_ROTATE = 0x40000, U_FIELD_FLAG_ATTACK_ANIMATION = 0x80000, U_FIELD_FLAG_UNIT_UNTACKABLE_SELECT_2 = 0x100000, //AI, UNIT can attack non players. // = 0x200000, // = 0x400000, // = 0x800000, U_FIELD_FLAG_PLAYER_CONTROLLED_CREATURE = 0x1000000, U_FIELD_FLAG_UNIT_UNTACKABLE_NO_SELECT = 0x2000000, //AI, UNIT cant attack any unit, no name is displayed U_FIELD_FLAG_SKINNABLE = 0x4000000, U_FIELD_FLAG_MAKE_CHAR_UNTOUCHABLE = 0x8000000, U_FIELD_FLAG_WEAPON_OFF = 0x40000000, }; enum UnitDynamicFlags { U_DYN_FLAG_LOOTABLE = 0x01, U_DYN_FLAG_UNIT_TRACKABLE = 0x02, U_DYN_FLAG_TAGGED_BY_OTHER = 0x04, U_DYN_FLAG_TAPPED_BY_PLAYER = 0x08, U_DYN_FLAG_PLAYER_INFO = 0x10, U_DYN_FLAG_DEAD = 0x20, }; enum DamageFlags { DAMAGE_FLAG_MELEE = 1, DAMAGE_FLAG_HOLY = 2, DAMAGE_FLAG_FIRE = 4, DAMAGE_FLAG_NATURE = 8, DAMAGE_FLAG_FROST = 16, DAMAGE_FLAG_SHADOW = 32, DAMAGE_FLAG_ARCANE = 64 }; enum DamageType { MELEE, DUALWIELD, RANGED, }; enum VisualState { ATTACK = 1, DODGE, PARRY, INTERRUPT, BLOCK, EVADE, IMMUNE, DEFLECT }; enum HitStatus { HITSTATUS_HITANIMATION = 0x02, HITSTATUS_DUALWIELD = 0x04, HITSTATUS_MISS = 0x10, HITSTATUS_ABSORBED = 0x20, HITSTATUS_RESIST = 0x40, HITSTATUS_CRICTICAL = 0x80, HITSTATUS_GLANCING = 0x4000, HITSTATUS_CRUSHINGBLOW = 0x8000, HITSTATUS_NOACTION = 0x10000, HITSTATUS_SWINGNOHITSOUND = 0x80000 // as in miss? }; enum INVISIBILTY_FLAG { INVISIBILTY_FLAG_NONE, INVISIBILTY_FLAG_UNIT_SPIRIT, INVISIBILTY_FLAG_UNK_SPIRIT, INVISIBILTY_FLAG_TRAP, INVISIBILTY_FLAG_QUEST_INVISIBILITY, INVISIBILTY_FLAG_GHOSTS, INVISIBILTY_FLAG_UNK1, INVISIBILTY_FLAG_UNK2, INVISIBILTY_FLAG_SHADOWMOON_GHOSTWORLD, INVISIBILTY_FLAG_NETHERSTORM_UNK, INVISIBILTY_FLAG_TOTAL }; enum FIELD_PADDING//Since this field isnt used you can expand it for you needs { PADDING_NONE, PADDING_INVISIBILTY_UNIT_SPIRIT, PADDING_INVISIBILTY_UNK_SPIRIT, PADDING_INVISIBILTY_TRAP, PADDING_INVISIBILTY_QUEST_INVISIBILITY, PADDING_INVISIBILTY_GHOSTS, PADDING_INVISIBILTY_TOTAL }; struct AuraCheckResponse { uint32 Error; uint32 Misc; }; enum AURA_CHECK_RESULT { AURA_CHECK_RESULT_NONE = 1, AURA_CHECK_RESULT_HIGHER_BUFF_PRESENT = 2, AURA_CHECK_RESULT_LOWER_BUFF_PRESENT = 3, }; typedef std::set AttackerSet; typedef std::list ProcTriggerSpellOnSpellList; //==================================================================== // Unit // Base object for Players and Creatures //==================================================================== class SERVER_DECL Unit : public Object { public: virtual ~Unit ( ); friend class AIInterface; friend class Aura; virtual void Update( uint32 time ); virtual void AddToWorld(); virtual void RemoveFromWorld(); virtual void OnPushToWorld(); inline void setAttackTimer(int32 time, bool offhand) { if(!time) time = offhand ? m_uint32Values[UNIT_FIELD_BASEATTACKTIME_01] : m_uint32Values[UNIT_FIELD_BASEATTACKTIME]; time += (time*modAttackTimeIncreasePCT)/100; if(offhand) m_attackTimer_1 = getMSTime() + time; else m_attackTimer = getMSTime() + time; } inline bool isAttackReady(bool offhand) const { if(!offhand) return getMSTime() >= m_attackTimer; else return getMSTime() >= m_attackTimer_1; } inline void SetDuelWield(bool enabled) { m_duelWield = enabled; } bool __fastcall canReachWithAttack(Unit *pVictim); // void StrikeWithAbility(Unit *pVictim,Spell*spell,uint32 addspelldmg,uint32 damage_type); /// State flags are server-only flags to help me know when to do stuff, like die, or attack inline void addStateFlag(uint32 f) { m_state |= f; }; inline bool hasStateFlag(uint32 f) { return (m_state & f ? true : false); } inline void clearStateFlag(uint32 f) { m_state &= ~f; }; /// Stats inline uint32 getLevel() { return m_uint32Values[ UNIT_FIELD_LEVEL ]; }; inline uint8 getRace() { return ((uint8)m_uint32Values[ UNIT_FIELD_BYTES_0]); } inline uint8 getClass() { return GetByte(UNIT_FIELD_BYTES_0,1); } inline void setRace(uint8 race) { SetByte(UNIT_FIELD_BYTES_0,0,race); } inline void setClass(uint8 class_) { SetByte(UNIT_FIELD_BYTES_0,1, class_ ); } inline uint32 getClassMask() { return 1 << (getClass() - 1); } inline uint32 getRaceMask() { return 1 << (getRace() - 1); } inline uint8 getGender() { return GetByte(UNIT_FIELD_BYTES_0,2); } inline void setGender(uint8 gender) { SetByte(UNIT_FIELD_BYTES_0,2,gender); } inline uint8 getStandState() { return ((uint8)m_uint32Values[UNIT_FIELD_BYTES_1]); } //// Combat // void DealDamage(Unit *pVictim, uint32 damage, uint32 targetEvent, uint32 unitEvent, uint32 spellId = 0); // to stop from falling, etc //void AttackerStateUpdate(Unit *pVictim,uint32 damage_type);//0-melee,1-offhand(dual wield),2-ranged void Strike(Unit *pVictim,uint32 damage_type,SpellEntry *ability,int32 add_damage,int32 pct_dmg_mod,uint32,bool); // void PeriodicAuraLog(Unit *pVictim, SpellEntry* spellID, uint32 damage, uint32 damageType); //void SpellNonMeleeDamageLog(Unit *pVictim, uint32 spellID, uint32 damage); uint32 m_procCounter; void HandleProc(uint32 flag, Unit* Victim, SpellEntry* CastingSpell,uint32 dmg=-1); void HandleProcDmgShield(uint32 flag, Unit* Victim);//almost the same as handleproc :P // void HandleProcSpellOnSpell(Unit* Victim,uint32 damage,bool critical);//nasty, some spells proc other spells int32 GetAP(); int32 GetRAP(); void CastSpell(Unit* Target, uint32 SpellID, bool triggered); void CastSpell(Unit* Target, SpellEntry* Sp, bool triggered); void CastSpell(uint64 targetGuid, uint32 SpellID, bool triggered); void CastSpell(uint64 targetGuid, SpellEntry* Sp, bool triggered); void CastSpellAoF(float x,float y,float z,SpellEntry* Sp, bool triggered); void EventCastSpell(Unit * Target, SpellEntry * Sp); bool isCasting(); void CalculateResistanceReduction(Unit *pVictim,dealdamage *dmg) ; void RegenerateHealth(); void RegeneratePower(bool isinterrupted); inline void setHRegenTimer(uint32 time) {m_H_regenTimer = time; } inline void setPRegenTimer(uint32 time) {m_P_regenTimer = time; } inline void setPIRegenTimer(uint32 time) {m_P_I_regenTimer = time; } void DeMorph(); uint32 ManaShieldAbsorb(uint32 dmg); void smsg_AttackStart(Unit* pVictim); void smsg_AttackStop(Unit* pVictim); void smsg_AttackStop(uint64 victimGuid); bool IsDazed(); // Stealth inline uint32 GetStealthLevel() { return m_stealthLevel+ 5* m_uint32Values[UNIT_FIELD_LEVEL]; } inline int32 GetStealthDetect() { return 5 * getLevel() + m_stealthDetectBonus; } inline uint32 GetStealthDetectBonus() { return m_stealthDetectBonus; } inline void SetStealth(uint32 id) { m_stealth = id; } inline bool IsStealth() { return (bool)m_stealth; } bool HasAura(uint32 visualid);//not spell id!!! bool HasActiveAura(uint32 spelllid); bool HasActiveAura(uint32 spelllid,uint64); uint16 InvisibilityDetectBonus[INVISIBILTY_FLAG_TOTAL]; inline uint32 GetInvisibiltyDetection(INVISIBILTY_FLAG flag) { return getLevel() + InvisibilityDetectBonus[flag] - 1; } void GiveGroupXP(Unit *pVictim, Player *PlayerInGroup); /// Combat / Death Status inline bool isAlive() { return m_deathState == ALIVE; }; inline bool isDead() { return m_deathState !=ALIVE; }; virtual void setDeathState(DeathState s) { m_deathState = s; }; DeathState getDeathState() { return m_deathState; } void OnDamageTaken(); //! Add Aura to unit void AddAura(Aura *aur); //! Remove aura from unit bool RemoveAura(Aura *aur); bool RemoveAura(uint32 spellId); bool RemoveAura(uint32 spellId,uint64 guid); bool RemoveAuraByNameHash(uint32 namehash);//required to remove weaker instances of a spell bool RemoveAuraPosByNameHash(uint32 namehash);//required to remove weaker instances of a spell bool RemoveAuraNegByNameHash(uint32 namehash);//required to remove weaker instances of a spell bool RemoveAuras(uint32 * SpellIds); void EventRemoveAura(uint32 SpellId) { RemoveAura(SpellId); } //! Remove all auras void RemoveAllAuras(); void RemoveAllAuraType(uint32 auratype);//ex:to remove morph spells bool RemoveAllAuraByNameHash(uint32 namehash);//required to remove weaker instances of a spell bool RemoveAllPosAuraByNameHash(uint32 namehash);//required to remove weaker instances of a spell bool RemoveAllNegAuraByNameHash(uint32 namehash);//required to remove weaker instances of a spell void RemoveNegativeAuras(); void RemoveAllAreaAuras(); // Temporary remove all auras // Find auras Aura* FindAura(uint32 spellId); Aura* FindAura(uint32 spellId, uint64 guid); bool SetAurDuration(uint32 spellId,Unit* caster,uint32 duration); bool SetAurDuration(uint32 spellId,uint32 duration); void DropAurasOnDeath(); void castSpell(Spell * pSpell); void InterruptSpell(); Unit* create_guardian(uint32 guardian_entry,uint32 duration,float angle);//guardians are temporary spawn that will inherit master faction and will folow them. Apart from that they have their own mind uint32 m_addDmgOnce; Creature *m_TotemSlots[4]; uint32 m_ObjectSlots[4]; uint32 m_triggerSpell; uint32 m_triggerDamage; uint32 m_canMove; // Spell Effect Variables uint16 m_silenced; std::list m_damageShields; std::list m_reflectSpellSchool; std::list m_procSpells; // std::map m_procSpellonSpell; //index is namehash std::map m_chargeSpells; inline void SetOnMeleeSpell(uint32 spell ) { m_meleespell = spell; } inline uint32 GetOnMeleeSpell() { return m_meleespell; } // Spell Crit float spellcritperc; // AIInterface AIInterface *GetAIInterface() { return m_aiInterface; } void WipeHateList(); void WipeTargetList(); inline void setAItoUse(bool value){m_useAI = value;} int32 GetThreatModifyer() { return m_threatModifyer; } void ModThreatModifyer(int32 mod) { m_threatModifyer += mod; } int32 GetGeneratedThreatModifyer() { return m_generatedThreatModifyer; } void ModGeneratedThreatModifyer(int32 mod) { m_generatedThreatModifyer += mod; } // DK:Affect inline uint32 IsPacified() { return m_pacified; } inline uint32 IsStunned() { return m_stunned; } inline uint32 GetResistChanceMod() { return m_resistChance; } inline void SetResistChanceMod(uint32 amount) { m_resistChance=amount; } inline uint16 HasNoInterrupt() { return m_noInterrupt; } bool setDetectRangeMod(uint64 guid, int32 amount); void unsetDetectRangeMod(uint64 guid); int32 getDetectRangeMod(uint64 guid); void RemoveBySpecialType(uint32 id,uint64 guid); Loot loot; uint32 SchoolCastPrevent[7]; int32 GetDamageDoneMod(uint32 school); float GetDamageDonePctMod(uint32 school); float DamageDoneModPCT[7]; int32 DamageTakenMod[7]; float DamageTakenPctMod[7]; float DamageTakenPctModOnHP; int32 RangedDamageTaken; void CalcDamage(); float BaseDamage[2]; float BaseOffhandDamage[2]; float BaseRangedDamage[2]; std::set VampEmbCaster; uint64 VampTchCaster; void VampiricEmbrace(uint32 dmg,Unit* tgt); void VampiricTouch(uint32 dmg,Unit* tgt); SchoolAbsorb Absorbs[7]; uint32 AbsorbDamage(uint32 School,uint32 * dmg);//returns amt of absorbed dmg, decreases dmg by absorbed value int32 RAPvModifier; int32 APvModifier; uint64 stalkedby; uint32 dispels[10]; bool trackStealth; uint32 MechanicsDispels[27]; float MechanicsResistancesPCT[27]; int32 modAttackTimeIncreasePCT; int32 RangedDamageTakenPct; //SM int32 * SM_CriticalChance;//flat int32 * SM_FDur;//flat int32 * SM_PDur;//pct int32 * SM_PRadius;//pct int32 * SM_FRadius;//flat int32 * SM_PRange;//pct int32 * SM_FRange;//flat int32 * SM_PCastTime;//pct int32 * SM_FCastTime;//flat int32 * SM_PCriticalDamage; int32 * SM_PDOT;//pct int32 * SM_FDOT;//flat int32 * SM_FEffectBonus;//flat int32 * SM_PEffectBonus;//pct int32 * SM_FDamageBonus;//flat int32 * SM_PDamageBonus;//pct int32 * SM_PDummy;//pct int32 * SM_FDummy;//flat int32 * SM_FResist;//flat int32 * SM_PAPBonus;//pct int32 * SM_PCost; int32 * SM_FCost; int32 * SM_PNonInterrupt; int32 * SM_PJumpReduce; int32 * SM_FSpeedMod; int32 * SM_FAdditionalTargets; int32 * SM_FPenalty;//flat int32 * SM_PPenalty;//Pct int32 * SM_PCooldownTime; int32 * SM_FCooldownTime; int32 * SM_FChanceOfSuccess; //Events void Emote (EmoteType emote); void EventAddEmote(EmoteType emote, uint32 time); void EmoteExpire(); inline void setEmoteState(uint8 emote) { m_emoteState = emote; }; inline uint32 GetOldEmote() { return m_oldEmote; } void EventSummonPetExpire(); void EventAurastateExpire(uint32 aurastateflag){RemoveFlag(UNIT_FIELD_AURASTATE,aurastateflag);} //hmm this looks like so not necesary :S void EventHealthChangeSinceLastUpdate(); void SetStandState (uint8 standstate); inline StandState GetStandState() { uint32 bytes1 = GetUInt32Value (UNIT_FIELD_BYTES_1); return StandState (uint8 (bytes1)); } void SendChatMessage(uint8 type, uint32 lang, const char *msg); void SendChatMessageAlternateEntry(uint32 entry, uint8 type, uint32 lang, const char * msg); void RegisterPeriodicChatMessage(uint32 delay, uint32 msgid, std::string message, bool sendnotify); void DelayedChatMessage(uint32 delay, uint32 msgid, std::string message, bool sendnotify); void SendNotifyToNearby(uint32 msgid); void SendNotifyToNearbyCreature(uint32 msgid, uint32 entryid); inline int GetHealthPct() { return (int)(GetUInt32Value(UNIT_FIELD_HEALTH) * 100 / GetUInt32Value(UNIT_FIELD_MAXHEALTH)); }; inline int GetManaPct() { return (int)(GetUInt32Value(UNIT_FIELD_POWER1) * 100 / GetUInt32Value(UNIT_FIELD_MAXPOWER1)); }; uint32 GetResistance(uint32 type); //Pet inline void SetIsPet(bool chck) { m_isPet = chck; } inline AttackerSet::iterator GetAttackersetBegin() { return m_attackers.begin(); } inline AttackerSet::iterator GetAttackersetEnd() { return m_attackers.end(); } inline int GetAttackersetSize() { return m_attackers.size(); } inline uint64 getAttackTarget() { return m_attackTarget; } inline bool IsBeingAttackedBy(Unit *pUnit) { return m_attackers.count(pUnit->GetGUID()) > 0; } virtual bool isInCombat() { return (m_attackers.size() > 0 || m_attackTarget != 0); } //In-Range virtual void AddInRangeObject(Object* pObj); virtual void OnRemoveInRangeObject(Object* pObj); void ClearInRangeSet(); inline Spell * GetCurrentSpell(){return m_currentSpell;} inline void SetCurrentSpell(Spell* cSpell) { m_currentSpell = cSpell; } uint32 m_CombatUpdateTimer; // Attacker stuff void addAttacker(Unit *pUnit); void removeAttacker(Unit *pUnit); void setAttackTarget(Unit* pUnit); void clearAttackers(bool bFromOther); inline void setcanperry(bool newstatus){can_parry=newstatus;} std::map tmpAura; uint32 BaseResistance[7]; //there are resistances for silence, fear, mechanics .... uint32 BaseStats[5]; int32 HealDoneMod[7]; int32 HealDonePctMod[7]; int32 HealTakenMod[7]; float HealTakenPctMod[7]; uint32 SchoolImmunityList[7]; float SpellCritChanceSchool[7]; int32 PowerCostMod[7]; float PowerCostPctMod[7]; int32 AttackerSpellCritChanceMod[7]; uint32 SpellDelayResist[7]; int32 CreatureAttackPowerMod[12]; int32 CreatureRangedAttackPowerMod[12]; float PctRegenModifier;//1.0 by default float PctPowerRegenModifier[4]; inline uint32 GetPowerType(){ return (GetUInt32Value(UNIT_FIELD_BYTES_0)>> 24);} void RemoveSoloAura(uint32 type); void RemoveAurasByInterruptFlag(uint32 flag); void RemoveAurasByInterruptFlagButSkip(uint32 flag, uint32 skip); // Auras Modifiers int32 m_pacified; int32 m_interruptRegen; int32 m_resistChance; int32 m_powerRegenPCT; int32 m_stunned; bool m_invisible; int32 m_extraattacks; int32 m_extrastriketargets; //std::set m_onStrikeSpells; int32 m_noInterrupt; uint32 m_sleep; uint32 m_rooted; bool disarmed; uint64 m_detectRangeGUID[5]; int32 m_detectRangeMOD[5]; // Affect Speed int32 m_speedModifier; int32 m_slowdown; map< uint32, int32 > speedReductionMap; bool GetSpeedDecrease(); int32 m_mountedspeedModifier; int32 m_flyspeedModifier; void UpdateSpeed(bool delay = false); void EnableFlight(bool delay = false); void DisableFlight(bool delay = false); // Escort Quests //uint32 m_escortquestid; //uint32 m_escortupdatetimer; //bool bHasEscortQuest; //bool bEscortActive; //bool bStopAtEndOfWaypoints; //bool bReturnOnDie; //Player *q_AttachedPlayer; //uint16 m_escortStartWP; //uint16 m_escortEndWP; /*void InitializeEscortQuest(uint32 questid, bool stopatend, bool returnondie); void EscortSetStartWP(uint32 wp); void EscortSetEndWP(uint32 wp); void StartEscortQuest(); void PauseEscortQuest(); void EndEscortQuest();*/ void MoveToWaypoint(uint32 wp_id); void PlaySoundToSet(uint32 sound_entry); void PlaySpellVisual(uint64 target, uint32 spellVisual); bool m_isPet; uint32 m_stealth; Aura* m_auras[MAX_AURAS+MAX_PASSIVE_AURAS]; int32 m_modlanguage; Creature *critterPet; Creature *summonPet; inline uint32 GetCharmTempVal() { return m_charmtemp; } inline void SetCharmTempVal(uint32 val) { m_charmtemp = val; } set m_SpellList; inline void DisableAI() { m_useAI = false; } inline void EnableAI() { m_useAI = true; } inline void SetPowerType(uint8 type) { SetByte(UNIT_FIELD_BYTES_0,3,type); } inline bool IsSpiritHealer() { switch(GetEntry()) { case 6491: // Spirit Healer case 13116: // Alliance Spirit Guide case 13117: // Horde Spirit Guide { return true; }break; } return false; } void Root(); void Root(uint32 time); void Unroot(); void SetFacing(float newo);//only working if creature is idle void RemoveAurasByBuffType(uint32 buff_type, uint64 guid); bool HasAurasOfBuffType(uint32 buff_type, uint64 guid); bool HasAurasWithNameHash(uint32 name_hash); bool HasNegativeAuraWithNameHash(uint32 name_hash); //just to reduce search range in some cases bool HasNegativeAura(uint32 spell_id); //just to reduce search range in some cases AuraCheckResponse AuraCheck(uint32 name_hash, uint32 rank); AuraCheckResponse AuraCheck(uint32 name_hash, uint32 rank, Aura* aur); uint16 m_diminishCount[23]; uint8 m_diminishAuraCount[23]; uint16 m_diminishTimer[23]; bool m_diminishActive; void SetDiminishTimer(uint32 index) { m_diminishTimer[index] = 15000; } DynamicObject * dynObj; uint32 AddAuraVisual(uint32 spellid, uint32 count, bool positive); void SetAuraSlotLevel(uint32 slot, bool positive); void RemoveAuraVisual(uint32 spellid, uint32 count); bool HasVisibleAura(uint32 spellid); //! returns: aura stack count uint32 ModAuraStackCount(uint32 slot, int32 count); uint8 m_auraStackCount[MAX_AURAS]; void RemoveAurasOfSchool(uint32 School, bool Positive); SpellEntry * pLastSpell; bool bProcInUse; bool bInvincible; Player * m_redirectSpellPackets; void UpdateVisibility(); //solo target auras uint32 polySpell; uint16 m_invisibityFlag; // uint32 fearSpell; protected: Unit (); uint32 m_meleespell; void _UpdateSpells(uint32 time); uint32 m_H_regenTimer; uint32 m_P_regenTimer; uint32 m_P_I_regenTimer; //PowerInterruptedRegenTimer. uint32 m_state; // flags for keeping track of some states uint32 m_attackTimer; // timer for attack uint32 m_attackTimer_1; bool m_duelWield; /// Combat DeathState m_deathState; // Stealth uint32 m_stealthLevel; uint32 m_stealthDetectBonus; // DK:pet //uint32 m_pet_state; //uint32 m_pet_action; // Spell currently casting Spell * m_currentSpell; // AI AIInterface *m_aiInterface; bool m_useAI; bool can_parry;//will be enabled by block spell int32 m_threatModifyer; int32 m_generatedThreatModifyer; // float getDistance( float Position1X, float Position1Y, float Position2X, float Position2Y ); int32 m_manashieldamt; uint32 m_manaShieldId; // Quest emote uint8 m_emoteState; uint32 m_oldEmote; uint32 m_charmtemp; AttackerSet m_attackers; uint64 m_attackTarget; }; #endif