/*
* 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 _PLAYER_H
#define _PLAYER_H
struct BGScore;
class Channel;
class Creature;
class Battleground;
class TaxiPath;
class GameObject;
class Transporter;
class Corpse;
class Guild;
class Pet;
class Charter;
struct LevelInfo;
#define myabs(a) (a<0)?(-a):a
#define MAX_PET_NO 3
#define PLAYER_NORMAL_RUN_SPEED 7.0
#define MONSTER_NORMAL_RUN_SPEED 8.0
#define PLAYER_NORMAL_SWIM_SPEED 4.722222
#define PLAYER_NORMAL_FLIGHT_SPEED 7.0
#define PLAYER_HONORLESS_TARGET_SPELL 2479
//====================================================================
// Inventory
// Holds the display id and item type id for objects in
// a character's inventory
//====================================================================
enum Classes
{
WARRIOR = 1,
PALADIN = 2,
HUNTER = 3,
ROGUE = 4,
PRIEST = 5,
SHAMAN = 7,
MAGE = 8,
WARLOCK = 9,
DRUID = 11,
};
enum Races
{
RACE_HUMAN = 1,
RACE_ORC = 2,
RACE_DWARF = 3,
RACE_NIGHTELF = 4,
RACE_UNDEAD = 5,
RACE_TAUREN = 6,
RACE_GNOME = 7,
RACE_TROLL = 8,
RACE_BLOODELF = 10,
RACE_DRAENEI = 11,
};
enum PlayerStatus
{
NONE = 0,
TRANSFER_PENDING = 1,
};
enum RankTitles
{
PVPTITLE_NONE = 0x0,
PVPTITLE_PRIVATE = 0x02,
PVPTITLE_CORPORAL = 0x04,
PVPTITLE_SERGEANT = 0x08,
PVPTITLE_MASTER_SERGEANT = 0x10,
PVPTITLE_SERGEANT_MAJOR = 0x20,
PVPTITLE_KNIGHT = 0x40,
PVPTITLE_KNIGHT_LIEUTENANT = 0x80,
PVPTITLE_KNIGHT_CAPTAIN = 0x100,
PVPTITLE_KNIGHT_CHAMPION = 0x200,
PVPTITLE_LIEUTENANT_COMMANDER = 0x400,
PVPTITLE_COMMANDER = 0x800,
PVPTITLE_MARSHAL = 0x1000,
PVPTITLE_FIELD_MARSHAL = 0x2000,
PVPTITLE_GRAND_MARSHAL = 0x4000,
PVPTITLE_SCOUT = 0x8000,
PVPTITLE_GRUNT = 0x10000,
PVPTITLE_HSERGEANT = 0x20000,
PVPTITLE_SENIOR_SERGEANT = 0x40000,
PVPTITLE_FIRST_SERGEANT = 0x80000,
PVPTITLE_STONE_GUARD = 0x100000,
PVPTITLE_BLOOD_GUARD = 0x200000,
PVPTITLE_LEGIONNAIRE = 0x400000,
PVPTITLE_CENTURION = 0x800000,
PVPTITLE_CHAMPION = 0x1000000,
PVPTITLE_LIEUTENANT_GENERAL = 0x2000000,
PVPTITLE_GENERAL = 0x4000000,
PVPTITLE_WARLORD = 0x8000000,
PVPTITLE_HIGH_WARLORD = 0x10000000,
};
enum PvPAreaStatus
{
AREA_ALLIANCE = 1,
AREA_HORDE = 2,
AREA_CONTESTED = 3,
AREA_PVPARENA = 4,
};
enum PlayerMovementType
{
MOVE_ROOT = 1,
MOVE_UNROOT = 2,
MOVE_WATER_WALK = 3,
MOVE_LAND_WALK = 4,
};
enum PlayerSpeedType
{
RUN = 1,
RUNBACK = 2,
SWIM = 3,
SWIMBACK = 4,
WALK = 5,
FLY = 6,
};
enum Standing
{
STANDING_HATED,
STANDING_HOSTILE,
STANDING_UNFRIENDLY,
STANDING_NEUTRAL,
STANDING_FRIENDLY,
STANDING_HONORED,
STANDING_REVERED,
STANDING_EXALTED
};
enum PlayerFlags
{
PLAYER_FLAG_PARTY_LEADER = 0x01,
PLAYER_FLAG_AFK = 0x02,
PLAYER_FLAG_DND = 0x04,
PLAYER_FLAG_GM = 0x08,
PLAYER_FLAG_DEATH_WORLD_ENABLE = 0x10,
PLAYER_FLAG_RESTING = 0x20,
PLAYER_FLAG_UNKNOWN1 = 0x40,
PLAYER_FLAG_FREE_FOR_ALL_PVP = 0x80,
PLAYER_FLAG_UNKNOWN2 = 0x100,
PLAYER_FLAG_PVP_TOGGLE = 0x200,
PLAYER_FLAG_NOHELM = 0x400,
PLAYER_FLAG_NOCLOAK = 0x800,
PLAYER_FLAG_NEED_REST_3_HOURS = 0x1000,
PLAYER_FLAG_NEED_REST_5_HOURS = 0x2000,
};
struct spells
{
uint16 spellId;
uint16 slotId;
};
#pragma pack(push,1)
struct ActionButton
{
uint16 Action;
uint8 Type;
uint8 Misc;
};
#pragma pack(pop)
struct CreateInfo_ItemStruct
{
uint32 protoid;
uint8 slot;
uint32 amount;
};
struct CreateInfo_SkillStruct
{
uint32 skillid;
uint32 currentval;
uint32 maxval;
};
struct CreateInfo_ActionBarStruct
{
uint32 button;
uint32 action;
uint32 type;
uint32 misc;
};
struct PlayerCreateInfo{
uint8 index;
uint8 race;
uint32 factiontemplate;
uint8 class_;
uint32 mapId;
uint32 zoneId;
float positionX;
float positionY;
float positionZ;
uint16 displayId;
uint8 strength;
uint8 ability;
uint8 stamina;
uint8 intellect;
uint8 spirit;
uint32 health;
uint32 mana;
uint32 rage;
uint32 focus;
uint32 energy;
uint32 attackpower;
float mindmg;
float maxdmg;
std::list items;
std::list skills;
std::list actionbars;
std::list spell_list;
//uint32 item[10];
//uint8 item_slot[10];
//uint16 spell[10];
};
struct DamageSplit
{
Player* caster;
Aura* aura;
uint32 miscVal;
union
{
uint32 damage;
float damagePCT;
};
};
struct LoginAura
{
uint32 id;
uint32 dur;
};
/*
Exalted 1,000 Access to racial mounts. Capped at 999.7
Revered 21,000 Heroic mode keys for Outland dungeons
Honored 12,000 10% discount from faction vendors
Friendly 6,000
Neutral 3,000
Unfriendly 3,000 Cannot buy, sell or interact.
Hostile 3,000 You will always be attacked on sight
Hated 36,000
*/
enum FactionRating
{
HATED,
HOSTILE,
UNFRIENDLY,
NEUTRAL,
FRIENDLY,
HONORED,
REVERED,
EXALTED
};
struct FactionReputation
{
int32 standing;
uint8 flag;
int32 baseStanding;
inline int32 CalcStanding() { return standing - baseStanding; }
inline bool Positive() { return standing >= 0; }
FactionRating CalcRating()
{
register long st=CalcStanding();
if(st>=42000)
return EXALTED;
if(st>=21000)
return REVERED;
if(st>=9000)
return HONORED;
if(st>=3000)
return FRIENDLY;
if(st>=0)
return NEUTRAL;
if(st>-3000)
return UNFRIENDLY;
if(st>-6000)
return HOSTILE;
return HATED;
}
};
struct PlayerInfo
{
uint64 guid;
uint32 acct;
std::string name;
uint32 race;
uint32 gender;
uint32 cl;
uint32 team;
//guild stuff
uint32 Rank;//guild rank
std::string publicNote;
std::string officerNote;
time_t lastOnline;
uint32 lastZone;
uint32 lastLevel;
Group * m_Group;
uint8 subGroup;
};
struct PlayerPet
{
string name;
uint32 entry;
string fields;
uint32 xp;
bool active;
uint32 number;
uint32 level;
uint32 happiness;
uint32 happinessupdate;
string actionbar;
bool summon;
uint32 autocastspell;
uint32 loyaltypts;
uint32 loyaltyupdate;
char loyaltylvl;
};
enum MeetingStoneQueueStatus
{
MEETINGSTONE_STATUS_NONE = 0,
MEETINGSTONE_STATUS_JOINED_MEETINGSTONE_QUEUE_FOR = 1,
MEETINGSTONE_STATUS_PARTY_MEMBER_LEFT_LFG = 2,
MEETINGSTONE_STATUS_PARTY_MEMBER_REMOVED_PARTY_REMOVED = 3,
MEETINGSTONE_STATUS_LOOKING_FOR_NEW_PARTY_IN_QUEUE = 4,
MEETINGSTONE_STATUS_NONE_UNK = 5,
};
enum ItemPushResultTypes
{
ITEM_PUSH_TYPE_LOOT = 0x00000000,
ITEM_PUSH_TYPE_RECEIVE = 0x00000001,
ITEM_PUSH_TYPE_CREATE = 0x00000002,
};
struct WeaponModifier
{
uint32 wclass;
uint32 subclass;
float value;
};
struct PetActionBar
{
uint32 spell[10];
};
struct ItemCooldown
{
uint16 SpellID;
uint16 ItemEntry;
uint16 SpellCategory; //this maybe got from spell id, maybe saved for speed
uint32 CooldownTimeStamp;
uint32 Cooldown;
};
struct classScriptOverride
{
uint32 id;
uint32 effect;
uint32 aura;
uint32 damage;
bool percent;
};
class Spell;
class Item;
class Container;
class WorldSession;
class ItemInterface;
class GossipMenu;
struct TaxiPathNode;
#define RESTSTATE_RESTED 1
#define RESTSTATE_NORMAL 2
#define RESTSTATE_TIRED100 3
#define RESTSTATE_TIRED50 4
#define RESTSTATE_EXHAUSTED 5
#define UNDERWATERSTATE_NONE 0
#define UNDERWATERSTATE_SWIMMING 1
#define UNDERWATERSTATE_UNDERWATER 2
#define UNDERWATERSTATE_RECOVERING 4
#define UNDERWATERSTATE_TAKINGDAMAGE 8
#define UNDERWATERSTATE_FATIGUE 16
#define UNDERWATERSTATE_LAVA 32
#define UNDERWATERSTATE_SLIME 64
enum TRADE_STATUS
{
TRADE_STATUS_PLAYER_BUSY = 0x00,
TRADE_STATUS_PROPOSED = 0x01,
TRADE_STATUS_INITIATED = 0x02,
TRADE_STATUS_CANCELLED = 0x03,
TRADE_STATUS_ACCEPTED = 0x04,
TRADE_STATUS_ALREADY_TRADING = 0x05,
TRADE_STATUS_PLAYER_NOT_FOUND = 0x06,
TRADE_STATUS_STATE_CHANGED = 0x07,
TRADE_STATUS_COMPLETE = 0x08,
TRADE_STATUS_UNACCEPTED = 0x09,
TRADE_STATUS_TOO_FAR_AWAY = 0x0A,
TRADE_STATUS_WRONG_FACTION = 0x0B,
TRADE_STATUS_FAILED = 0x0C,
TRADE_STATUS_DEAD = 0x0D,
TRADE_STATUS_PETITION = 0x0E,
TRADE_STATUS_PLAYER_IGNORED = 0x0F,
};
enum TRADE_DATA
{
TRADE_GIVE = 0x00,
TRADE_RECEIVE = 0x01,
};
enum DUEL_STATUS
{
DUEL_STATUS_OUTOFBOUNDS,
DUEL_STATUS_INBOUNDS
};
enum DUEL_STATE
{
DUEL_STATE_REQUESTED,
DUEL_STATE_STARTED,
DUEL_STATE_FINISHED
};
enum DUEL_WINNER
{
DUEL_WINNER_KNOCKOUT,
DUEL_WINNER_RETREAT,
};
#define PLAYER_ATTACK_TIMEOUT_INTERVAL 5000
#define PLAYER_FORCED_RESURECT_INTERVAL 360000 // 1000*60*6= 6 minutes
struct PlayerSkill
{
skilllineentry * Skill;
uint32 CurrentValue;
uint32 MaximumValue;
uint32 BonusValue;
float GetSkillUpChance();
void Reset(uint32 Id);
};
//====================================================================
// Player
// Class that holds every created character on the server.
//
// TODO: Attach characters to user accounts
//====================================================================
typedef std::set SpellSet;
typedef std::set ItemCooldownSet;
typedef std::list ScriptOverrideList;
typedef std::set SaveSet;
typedef std::map SpellCooldownHolderMap;
typedef std::map SplineMap;
typedef std::map SpellOverrideMap;
typedef std::map SpellOverrideExtraAuraMap;
typedef std::map ReputationMap;
typedef std::map SoloSpells;
typedef std::map >StrikeSpellMap;
typedef std::map StrikeSpellDmgMap;
typedef std::map SkillMap;
typedef std::set ReferenceSet;
class SERVER_DECL Player : public Unit
{
friend class WorldSession;
friend class Pet;
protected:
SkillMap m_skills;
ReferenceSet m_references;
public:
/************************************************************************/
/* Reference System */
/************************************************************************/
inline void AddReference(Player ** ptr) { m_references.insert(ptr); *ptr = this; }
inline void RemoveReference(Player ** ptr) { m_references.erase(ptr); *ptr = NULL; }
/************************************************************************/
/* Skill System */
/************************************************************************/
void _AdvanceSkillLine(uint32 SkillLine, uint32 Count = 1);
void _AddSkillLine(uint32 SkillLine, uint32 Current, uint32 Max);
uint32 _GetSkillLineMax(uint32 SkillLine);
uint32 _GetSkillLineCurrent(uint32 SkillLine, bool IncludeBonus = true);
void _RemoveSkillLine(uint32 SkillLine);
void _UpdateMaxSkillCounts();
void _ModifySkillBonus(uint32 SkillLine, int32 Delta);
void _ModifySkillBonusByType(uint32 SkillType, int32 Delta);
bool _HasSkillLine(uint32 SkillLine);
void RemoveSpellsFromLine(uint32 skill_line);
void _RemoveAllSkills();
void _RemoveLanguages();
void _AddLanguages(bool All);
void _AdvanceAllSkills(uint32 count);
void _ModifySkillMaximum(uint32 SkillLine, uint32 NewMax);
protected:
void _UpdateSkillFields();
public:
Player ( uint32 high, uint32 low );
~Player ( );
bool ok_to_remove;
PlayerInfo * m_playerInfo;
void AddToWorld();
void RemoveFromWorld();
bool Create ( WorldPacket &data );
void Update( uint32 time );
void BuildEnumData( WorldPacket * p_data );
void BuildFlagUpdateForNonGroupSet(uint32 index, uint32 flag);
std::string m_afk_reason;
void SetAFKReason(std::string reason) { m_afk_reason = reason; };
inline const char* GetName() { return m_name.c_str(); }
inline std::string* GetNameString() { return &m_name; }
void Die();
//void KilledMonster(uint32 entry, const uint64 &guid);
void GiveXP(uint32 xp, const uint64 &guid, bool allowbonus); // to stop rest xp being given
void ModifyBonuses(uint32 type,int32 val);
std::map m_wratings;
/************************************************************************/
/* Taxi */
/************************************************************************/
inline TaxiPath* GetTaxiPath() { return m_CurrentTaxiPath; }
inline bool GetTaxiState() { return m_onTaxi; }
const uint32& GetTaximask( uint8 index ) const { return m_taximask[index]; }
void LoadTaxiMask(const char* data);
void TaxiStart(TaxiPath* path, uint32 modelid, uint32 start_node);
void JumpToEndTaxiNode(TaxiPath * path);
void EventDismount(uint32 money, float x, float y, float z);
void EventTaxiInterpolate();
inline void SetTaxiState (bool state) { m_onTaxi = state; }
inline void SetTaximask (uint8 index, uint32 value ) { m_taximask[index] = value; }
inline void SetTaxiPath (TaxiPath *path) { m_CurrentTaxiPath = path; }
inline void SetTaxiPos() {m_taxi_pos_x = m_position.x; m_taxi_pos_y = m_position.y; m_taxi_pos_z = m_position.z;}
inline void UnSetTaxiPos() {m_taxi_pos_x = 0; m_taxi_pos_y = 0; m_taxi_pos_z = 0; }
// Taxi related variables
vector m_taxiPaths;
TaxiPath* m_CurrentTaxiPath;
uint32 taxi_model_id;
uint32 lastNode;
uint32 m_taxi_ride_time;
uint32 m_taximask[8];
float m_taxi_pos_x;
float m_taxi_pos_y;
float m_taxi_pos_z;
bool m_onTaxi;
/************************************************************************/
/* Quests */
/************************************************************************/
bool HasQuests()
{
for(int i = 0; i < 25; ++i)
{
if(m_questlog[i] != 0)
return true;
}
return false;
}
int32 GetOpenQuestSlot();
QuestLogEntry* GetQuestLogForEntry(uint32 quest);
inline QuestLogEntry*GetQuestLogInSlot(uint32 slot) { return m_questlog[slot]; }
inline uint64 GetQuestSharer() { return m_questSharer; }
inline void SetQuestSharer(uint64 guid) { m_questSharer = guid; }
void SetQuestLogSlot(QuestLogEntry *entry, uint32 slot);
inline void PushToRemovedQuests(uint32 questid) { m_removequests.insert(questid);}
void AddToFinishedQuests(uint32 quest_id);
void EventTimedQuestExpire(Quest *qst, QuestLogEntry *qle, uint32 log_slot);
bool HasFinishedQuest(uint32 quest_id);
bool HasQuestForItem(uint32 itemid);
bool CanFinishQuest(Quest* qst);
//Quest related variables
QuestLogEntry* m_questlog[25];
std::set m_QuestGOInProgress;
std::set m_removequests;
std::set m_finishedQuests;
uint64 m_questSharer;
uint32 timed_quest_slot;
/************************************************************************/
/* Stun Immobilize */
/************************************************************************/
void SetTriggerStunOrImmobilize(uint32 newtrigger,uint32 new_chance)
{
trigger_on_stun = newtrigger;
trigger_on_stun_chance = new_chance;
}
void EventStunOrImmobilize(Unit *proc_target);
void EventPortToGM(Player *p);
inline uint32 GetTeam() { return m_team; }
inline bool IsInFeralForm()
{
int s = GetShapeShift();
if(!s)return false;
//Fight forms that do not use player's weapon
if(s==1 || s == 5 || s == 8)
return true;
else
return false;
}
void CalcDamage();
uint32 GetMainMeleeDamage(uint32 AP_owerride); //i need this for windfury
const uint64& GetSelection( ) const { return m_curSelection; }
const uint64& GetTarget( ) const { return m_curTarget; }
void SetSelection(const uint64 &guid) { m_curSelection = guid; }
void SetTarget(const uint64 &guid) { m_curTarget = guid; }
/************************************************************************/
/* Spells */
/************************************************************************/
bool HasSpell(uint32 spell);
bool HasDeletedSpell(uint32 spell);
uint32 GetMaxLearnedSpellLevel(uint32 spell);
void smsg_InitialSpells();
void addSpell(uint32 spell_idy);
void removeSpellByHashName(uint32 hash);
bool removeSpell(uint32 SpellID, bool MoveToDeleted, bool SupercededSpell, uint32 SupercededSpellID);
// PLEASE DO NOT INLINE!
void AddOnStrikeSpell(SpellEntry* sp, uint32 delay)
{
m_onStrikeSpells.insert( map< SpellEntry*, pair >::value_type( sp, make_pair( delay, 0 ) ) );
}
void RemoveOnStrikeSpell(SpellEntry *sp)
{
m_onStrikeSpells.erase(sp);
}
void AddOnStrikeSpellDamage(uint32 spellid, uint32 mindmg, uint32 maxdmg)
{
OnHitSpell sp;
sp.spellid = spellid;
sp.mindmg = mindmg;
sp.maxdmg = maxdmg;
m_onStrikeSpellDmg[spellid] = sp;
}
void RemoveOnStrikeSpellDamage(uint32 spellid)
{
m_onStrikeSpellDmg.erase(spellid);
}
//Spells variables
StrikeSpellMap m_onStrikeSpells;
StrikeSpellDmgMap m_onStrikeSpellDmg;
SpellOverrideMap mSpellOverrideMap;
SpellSet m_SSSPecificSpells;
SpellSet mSpells;
SpellSet mDeletedSpells;
/************************************************************************/
/* Actionbar */
/************************************************************************/
void setAction(uint8 button, uint16 action, uint8 type, uint8 misc);
void SendInitialActions();
bool m_actionsDirty;
/************************************************************************/
/* Reputation */
/************************************************************************/
void ModStanding(uint32 Faction, int32 Value);
int32 GetStanding(uint32 Faction);
int32 GetBaseStanding(uint32 Faction);
void SetStanding(uint32 Faction, int32 Value);
void SetAtWar(uint32 Faction, bool Set);
bool IsAtWar(uint32 Faction);
Standing GetStandingRank(uint32 Faction);
bool IsHostileBasedOnReputation(FactionDBC * dbc);
void UpdateInrangeSetsBasedOnReputation();
void Reputation_OnKilledUnit(Unit * pUnit, bool InnerLoop);
void Reputation_OnTalk(FactionDBC * dbc);
static Standing GetReputationRankFromStanding(int32 Standing_);
/************************************************************************/
/* Factions */
/************************************************************************/
void smsg_InitialFactions();
uint32 GetFactionId();
// factions variables
int32 pctReputationMod;
/************************************************************************/
/* PVP */
/************************************************************************/
inline uint8 GetPVPRank()
{
return (uint8)((GetUInt32Value(PLAYER_BYTES_3) >> 24) & 0xFF);
}
inline void SetPVPRank(int newrank)
{
SetUInt32Value(PLAYER_BYTES_3, ((GetUInt32Value(PLAYER_BYTES_3) & 0x00FFFFFF) | (uint8(newrank) << 24)));
}
/************************************************************************/
/* Groups */
/************************************************************************/
void SetInviter(uint64 pInviter) { m_GroupInviter = pInviter; }
uint64 GetInviter() { return m_GroupInviter; }
inline bool InGroup() { return (m_Group != NULL && !m_GroupInviter); }
bool IsGroupLeader()
{
if(m_Group != NULL)
{
if(m_Group->GetLeader() == this)
return true;
}
return false;
}
inline int HasBeenInvited() { return m_GroupInviter != 0; }
inline Group* GetGroup() { return m_Group; }
inline void SetGroup(Group* grp) { m_Group = grp; }
inline uint32 GetSubGroup() { return m_SubGroup; }
inline void SetSubGroup(uint32 group) { m_SubGroup = group; }
bool IsGroupMember(Player *plyr);
inline bool IsBanned() { return ((m_banned > 0) ? true : false); }
inline void SetBanned() { m_banned = 4;}
inline void SetBanned(string Reason) { m_banned = 4; m_banreason = Reason;}
inline void UnSetBanned() { m_banned = 0; }
inline string GetBanReason() {return m_banreason;}
/************************************************************************/
/* Guilds */
/************************************************************************/
inline bool IsInGuild() {return (bool)GetUInt32Value(PLAYER_GUILDID);}
inline uint32 GetGuildId() { return m_uint32Values[PLAYER_GUILDID]; }
void SetGuildId(uint32 guildId);
inline uint32 GetGuildRank() { return m_uint32Values[PLAYER_GUILDRANK]; }
void SetGuildRank(uint32 guildRank) { SetUInt32Value(PLAYER_GUILDRANK, guildRank); }
uint64 GetGuildInvitersGuid() { return m_invitersGuid; }
void SetGuildInvitersGuid( uint64 guid ) { m_invitersGuid = guid; }
void UnSetGuildInvitersGuid() { m_invitersGuid = 0; }
/************************************************************************/
/* Duel */
/************************************************************************/
void RequestDuel(Player *pTarget);
void DuelBoundaryTest();
void EndDuel(uint8 WinCondition);
void DuelCountdown();
void SetDuelStatus(uint8 status) { m_duelStatus = status; }
inline uint8 GetDuelStatus() { return m_duelStatus; }
void SetDuelState(uint8 state) { m_duelState = state; }
inline uint8 GetDuelState() { return m_duelState; }
// duel variables
Player* DuelingWith;
/************************************************************************/
/* Trade */
/************************************************************************/
void SendTradeUpdate(void);
inline void ResetTradeVariables()
{
mTradeGold = 0;
memset(&mTradeItems, 0, sizeof(Item*) * 8);
mTradeStatus = 0;
mTradeTarget = 0;
}
/************************************************************************/
/* Pets */
/************************************************************************/
inline void SetSummon(Pet *pet) { m_Summon = pet; }
inline Pet* GetSummon(void) { return m_Summon; }
uint32 GeneratePetNumber(void);
void RemovePlayerPet(uint32 pet_number);
inline void AddPlayerPet(PlayerPet* pet, uint32 index) { m_Pets[index] = pet; }
inline PlayerPet* GetPlayerPet(uint32 idx)
{
std::map::iterator itr = m_Pets.find(idx);
if(itr != m_Pets.end()) return itr->second;
else
return NULL;
}
void SpawnPet(uint32 pet_number);
void DespawnPet();
uint32 GetFirstPetNumber(void)
{
if(m_Pets.size() == 0) return 0;
std::map::iterator itr = m_Pets.begin();
return itr->first;
}
inline PlayerPet* GetFirstPet(void) { return GetPlayerPet(GetFirstPetNumber()); }
inline void SetStableSlotCount(uint8 count) { m_StableSlotCount = count; }
inline uint8 GetStableSlotCount(void) { return m_StableSlotCount; }
/************************************************************************/
/* Item Interface */
/************************************************************************/
inline ItemInterface* GetItemInterface() { return m_ItemInterface; } // Player Inventory Item storage
inline void ApplyItemMods(Item *item, int8 slot, bool apply,bool justdrokedown=false) { _ApplyItemMods(item, slot, apply,justdrokedown); }
// item interface variables
ItemInterface * m_ItemInterface;
/************************************************************************/
/* Loot */
/************************************************************************/
inline const uint64& GetLootGUID() const { return m_lootGuid; }
inline void SetLootGUID(const uint64 &guid) { m_lootGuid = guid; }
void SendLoot(uint64 guid,uint8 loot_type);
// loot variables
uint64 m_lootGuid;
uint64 m_currentLoot;
bool bShouldHaveLootableOnCorpse;
/************************************************************************/
/* World Session */
/************************************************************************/
inline WorldSession* GetSession() const { return m_session; }
void SetSession(WorldSession *s) { m_session = s; }
void SetBindPoint(float x, float y, float z, uint32 m, uint32 v) { m_bind_pos_x = x; m_bind_pos_y = y; m_bind_pos_z = z; m_bind_mapid = m; m_bind_zoneid = v;}
void SendDelayedPacket(WorldPacket *data, bool bDeleteOnSend)
{
if(data == NULL) return;
if(GetSession() != NULL) GetSession()->SendPacket(data);
if(bDeleteOnSend) delete data;
}
float offhand_dmg_mod;
float GetSpellTimeMod(uint32 id);
int GetSpellDamageMod(uint32 id);
int32 GetSpellManaMod(uint32 id);
// Talents
// These functions build a specific type of A9 packet
uint32 __fastcall BuildCreateUpdateBlockForPlayer( ByteBuffer *data, Player *target );
void DestroyForPlayer( Player *target ) const;
std::list loginauras;
std::set OnMeleeAuras;
/************************************************************************/
/* Player loading and savings */
/* Serialize character to db */
/************************************************************************/
void SaveToDB(bool bNewCharacter);
void SaveAuras(stringstream&);
bool LoadFromDB(uint32 guid);
void LoadFromDB_Light(Field *fields, uint32 guid);
void LoadPropertiesFromDB();
void LoadNamesFromDB(uint32 guid);
void DeleteFromDB();
bool m_FirstLogin;
/************************************************************************/
/* Death system */
/************************************************************************/
void SpawnCorpseBody();
void SpawnCorpseBones();
void CreateCorpse();
void KillPlayer();
void ResurrectPlayer();
void BuildPlayerRepop();
void RepopRequestedPlayer();
void DeathDurabilityLoss(double percent);
void RepopAtGraveyard(float ox, float oy, float oz, uint32 mapid);
/************************************************************************/
/* Movement system */
/************************************************************************/
void SetMovement(uint8 pType, uint32 flag);
void SetPlayerSpeed(uint8 SpeedType, float value);
float GetPlayerSpeed(){return m_runSpeed;}
uint8 m_currentMovement;
bool m_isMoving;
//Invisibility stuff
bool m_isGmInvisible;
/************************************************************************/
/* Channel stuff */
/************************************************************************/
void JoinedChannel(Channel *c);
void LeftChannel(Channel *c);
void CleanupChannels();
//Attack stuff
void EventAttackStart();
void EventAttackStop();
void EventAttackUpdateSpeed() { }
void EventDeath();
//Note:ModSkillLine -> value+=amt;ModSkillMax -->value=amt; --wierd
float GetSkillUpChance(uint32 id);
//inline std::listgetSkillLines() { return m_skilllines; }
float SpellCrtiticalStrikeRatingBonus;
float SpellHasteRatingBonus;
void UpdateAttackSpeed();
void UpdateChances();
void UpdateStats();
void UpdateHit(int32 hit);
bool canCast(SpellEntry *m_spellInfo);
inline float GetBlockFromSpell() { return m_blockfromspell; }
inline float GetSpellCritFromSpell() { return m_spellcritfromspell; }
inline float GetHitFromMeleeSpell() { return m_hitfrommeleespell; }
inline float GetHitFromSpell() { return m_hitfromspell; }
inline float GetParryFromSpell() { return m_parryfromspell; }
inline float GetDodgeFromSpell() { return m_dodgefromspell; }
void SetBlockFromSpell(float value) { m_blockfromspell = value; }
void SetSpellCritFromSpell(float value) { m_spellcritfromspell = value; }
void SetParryFromSpell(float value) { m_parryfromspell = value; }
void SetDodgeFromSpell(float value) { m_dodgefromspell = value; }
void SetHitFromMeleeSpell(float value) { m_hitfrommeleespell = value; }
void SetHitFromSpell(float value) { m_hitfromspell = value; }
inline uint32 GetHealthFromSpell() { return m_healthfromspell; }
inline uint32 GetManaFromSpell() { return m_manafromspell; }
void SetHealthFromSpell(uint32 value) { m_healthfromspell = value;}
void SetManaFromSpell(uint32 value) { m_manafromspell = value;}
uint32 CalcTalentResetCost(uint32 resetnum);
void SendTalentResetConfirm();
uint32 GetTalentResetTimes() { return m_talentresettimes; }
inline void SetTalentResetTimes(uint32 value) { m_talentresettimes = value; }
void SetPlayerStatus(uint8 pStatus) { m_status = pStatus; }
inline uint8 GetPlayerStatus() { return m_status; }
const float& GetBindPositionX( ) const { return m_bind_pos_x; }
const float& GetBindPositionY( ) const { return m_bind_pos_y; }
const float& GetBindPositionZ( ) const { return m_bind_pos_z; }
const uint32& GetBindMapId( ) const { return m_bind_mapid; }
const uint32& GetBindZoneId( ) const { return m_bind_zoneid; }
inline uint8 GetShapeShift()
{
return GetByte(UNIT_FIELD_BYTES_1,2);
}
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;
//do not exit combat just because we are trying to delay attack (for whatever reason, like spellcasting)
if(!sEventMgr.HasEvent(this,EVENT_ATTACK_TIMEOUT)) //do not add excesive attack events
sEventMgr.AddEvent(this,&Player::EventAttackStop,EVENT_ATTACK_TIMEOUT,time+PLAYER_ATTACK_TIMEOUT_INTERVAL,1,0); //attack timeout on no attack after 5 seconds
else sEventMgr.ModifyEventTimeLeft(this,EVENT_ATTACK_TIMEOUT,time+PLAYER_ATTACK_TIMEOUT_INTERVAL,true);
}
inline void delayAttackTimer(int32 delay)
{
if(!delay)
return;
m_attackTimer += delay;
m_attackTimer_1 += delay;
if (delay > 0)
{
if(sEventMgr.HasEvent(this,EVENT_ATTACK_TIMEOUT))
{
sEventMgr.ModifyEventTimeLeft(this,EVENT_ATTACK_TIMEOUT,delay+PLAYER_ATTACK_TIMEOUT_INTERVAL,true);
}
}
}
void SetShapeShift(uint8 ss);
uint32 m_furorChance;
//Showing Units WayPoints
AIInterface* waypointunit;
void SaveGuild();
uint32 m_nextSave;
//Tutorials
uint32 GetTutorialInt(uint32 intId );
void SetTutorialInt(uint32 intId, uint32 value);
//Base stats calculations
//void CalcBaseStats();
// Rest
void AddRestXP(uint32 amount);
uint32 SubtractRestXP(uint32 amount);
uint32 CalculateRestXP(uint32 seconds);
uint32 m_lastRestUpdate;
void EventPlayerRest();
void ApplyPlayerRestState(bool apply);
void UpdateRestState();
//falling?
uint32 m_fallTime;
bool bSafeFall;
// Gossip
GossipMenu* CurrentGossipMenu;
void CleanupGossipMenu();
void Gossip_Complete();
void Gossip_SendPOI(float X, float Y, uint32 Icon, uint32 Flags, uint32 Data, const char* Name);
int m_lifetapbonus;
uint32 m_lastShotTime;
bool m_bUnlimitedBreath;
uint32 m_UnderwaterTime;
uint32 m_UnderwaterState;
uint32 m_SwimmingTime;
uint32 m_BreathDamageTimer;
// Visible objects
bool CanSee(Object* obj);
inline bool IsVisible(Object* pObj) { return !(m_visibleObjects.find(pObj) == m_visibleObjects.end()); }
void AddInRangeObject(Object* pObj);
void OnRemoveInRangeObject(Object* pObj);
void ClearInRangeSet();
inline void AddVisibleObject(Object* pObj) { m_visibleObjects.insert(pObj); }
inline void RemoveVisibleObject(Object* pObj) { m_visibleObjects.erase(pObj); }
inline void RemoveVisibleObject(InRangeSet::iterator itr) { m_visibleObjects.erase(itr); }
inline InRangeSet::iterator FindVisible(Object * obj) { return m_visibleObjects.find(obj); }
inline void RemoveIfVisible(Object * obj)
{
InRangeSet::iterator itr = m_visibleObjects.find(obj);
if(itr == m_visibleObjects.end())
return;
m_visibleObjects.erase(obj);
PushOutOfRange(obj->GetNewGUID());
}
inline bool GetVisibility(Object * obj, InRangeSet::iterator *itr)
{
*itr = m_visibleObjects.find(obj);
return ((*itr) != m_visibleObjects.end());
}
inline InRangeSet::iterator GetVisibleSetBegin() { return m_visibleObjects.begin(); }
inline InRangeSet::iterator GetVisibleSetEnd() { return m_visibleObjects.end(); }
//Transporters
bool m_lockTransportVariables;
uint64 m_TransporterGUID;
float m_TransporterX;
float m_TransporterY;
float m_TransporterZ;
float m_TransporterO;
float m_TransporterUnk;
// Misc
void EventCannibalize(uint32 amount);
void EventReduceDrunk(bool full);
bool m_AllowAreaTriggerPort;
void EventAllowTiggerPort(bool enable);
int32 m_rangedattackspeedmod;
int32 m_meleeattackspeedmod;
uint32 m_modblockvalue;
void SendInitialLogonPackets();
void Reset_Spells();
void Reset_Talents();
void Reset_ToLevel1();
// Battlegrounds xD
CBattleground * m_bg;
CBattleground * m_pendingBattleground;
uint32 m_bgEntryPointMap;
float m_bgEntryPointX;
float m_bgEntryPointY;
float m_bgEntryPointZ;
float m_bgEntryPointO;
int32 m_bgEntryPointInstance;
bool m_bgHasFlag;
bool m_bgIsQueued;
uint32 m_bgQueueType;
uint32 m_bgQueueInstanceId;
void EventRepeatSpell();
void EventCastRepeatedSpell(uint32 spellid, Unit *target);
bool CanShootRangedWeapon(uint32 spellid, Unit *target, bool autoshot);
uint32 m_AutoShotDuration;
uint32 m_AutoShotAttackTimer;
bool m_onAutoShot;
uint64 m_AutoShotTarget;
float m_AutoShotStartX;
float m_AutoShotStartY;
float m_AutoShotStartZ;
SpellEntry *m_AutoShotSpell;
void _InitialReputation();
void EventActivateGameObject(GameObject* obj);
void EventDeActivateGameObject(GameObject* obj);
void UpdateNearbyGameObjects();
void CalcResistance(uint32 type);
inline float res_M_crit_get(){return m_resist_critical[0];}
inline void res_M_crit_set(float newvalue){m_resist_critical[0]=newvalue;}
inline float res_R_crit_get(){return m_resist_critical[1];}
inline void res_R_crit_set(float newvalue){m_resist_critical[1]=newvalue;}
uint32 FlatResistanceModifierPos[7];
uint32 FlatResistanceModifierNeg[7];
uint32 BaseResistanceModPctPos[7];
uint32 BaseResistanceModPctNeg[7];
uint32 ResistanceModPctPos[7];
uint32 ResistanceModPctNeg[7];
float m_resist_critical[2];//when we are a victim we can have talents to decrease chance for critical hit. This is a negative value and it's added to critchances
float m_resist_hit[3]; // 0 = melee; 1= ranged; 2=spells
float SpellDmgDoneByInt[7];
float SpellHealDoneByInt[7];
float SpellDmgDoneBySpr[7];
float SpellHealDoneBySpr[7];
uint32 m_modphyscritdmgPCT;
uint32 m_RootedCritChanceBonus;
uint32 m_ModInterrMRegenPCT;
float m_RegenManaOnSpellResist;
uint32 FlatStatModPos[5];
uint32 FlatStatModNeg[5];
uint32 StatModPctPos[5];
uint32 StatModPctNeg[5];
uint32 TotalStatModPctPos[5];
uint32 TotalStatModPctNeg[5];
int32 IncreaseDamageByType[12]; //mod dmg by creature type
float IncreaseDamageByTypePCT[12];
float IncreaseCricticalByTypePCT[12];
int32 DetectedRange;
float PctIgnoreRegenModifier;
uint32 m_retainedrage;
/*
union {
float mRatingToPct[37];
uint32 mRatingToPoint[37]; //block, skill.. cant be decimal values
};
*/
inline uint32* GetPlayedtime() { return m_playedtime; };
void CalcStat(uint32 t);
float CalcRating(uint32 t);
void RecalcAllRatings();
void RegenerateMana(float RegenPct);
void RegenerateHealth(bool inCombat);
void RegenerateEnergy(float RegenPct);
void LooseRage();
uint32 SoulStone;
uint32 SoulStoneReciever;
void removeSoulStone();
bool bReincarnation;
map damagedone;
map tocritchance;
uint32 Seal;
uint32 judgespell;
bool cannibalize;
uint8 cannibalizeCount;
int32 rageFromDamageDealt;
// GameObject commands
GameObject *m_GM_SelectedGO;
void _Relocate(uint32 mapid,const LocationVector & v, bool sendpending, bool force_new_world);
void AddItemsToWorld();
void RemoveItemsFromWorld();
uint32 m_ShapeShifted;
uint32 m_MountSpellId;
inline bool IsMounted() {return m_MountSpellId; }
bool bHasBindDialogOpen;
bool bGMTagOn;
uint32 TrackingSpell;
void _EventCharmAttack();
void _Kick();
void Kick(uint32 delay = 0);
void SoftDisconnect();
uint32 m_KickDelay;
Unit * m_CurrentCharm;
Transporter * m_CurrentTransporter;
Object * GetSummonedObject () {return m_SummonedObject;};
void SetSummonedObject (Object * t_SummonedObject) {m_SummonedObject = t_SummonedObject;};
uint32 roll;
void AddRecoverCooldown(SpellEntry * spellInfo);
void AddCooldown(uint32 spell,uint32 time);
void AddCategoryCooldown(uint32 cat, uint32 time);
void AddGlobalCooldown(uint32 time);
uint32 GetGlobalCooldown() { return GlobalCooldown; }
void SetGlobalCooldown(uint32 time) { GlobalCooldown = time; }
void ClearCooldownsOnLine(uint32 skill_line, uint32 called_from);
void ClearCooldownForSpell(uint32 spell_id);
bool bProcessPending;
Mutex _bufferS;
void PushUpdateData(ByteBuffer *data, uint32 updatecount);
void PushCreationData(ByteBuffer *data, uint32 updatecount);
void PushOutOfRange(const WoWGuid & guid);
void ProcessPendingUpdates();
bool __fastcall CompressAndSendUpdateBuffer(uint32 size, const uint8* update_buffer);
void ClearAllPendingUpdates();
uint32 GetArmorProficiency() { return armor_proficiency; }
uint32 GetWeaponProficiency() { return weapon_proficiency; }
void ResetHeartbeatCoords();
float _lastHeartbeatX;
float _lastHeartbeatY;
float _lastHeartbeatZ;
uint32 _lastHeartbeatTime;
void AddSplinePacket(uint64 guid, ByteBuffer* packet);
ByteBuffer* GetAndRemoveSplinePacket(uint64 guid);
void ClearSplinePackets();
bool ExitInstance();
void SaveEntryPoint(uint32 mapId);
bool CooldownCheat;
bool CastTimeCheat;
bool GodModeCheat;
bool PowerCheat;
bool FlyCheat;
void ZoneUpdate(uint32 ZoneId);
inline uint32 GetAreaID() { return m_AreaID; }
void SetAreaID(uint32 area) { m_AreaID = area; }
std::string Lfgcomment;
uint16 LfgDungeonId[3];
uint8 LfgType[3];
bool m_Autojoin;
bool m_AutoAddMem;
void StopMirrorTimer(uint32 Type);
BGScore m_bgScore;
void UpdateChanceFields();
//Honor Variables
uint32 m_honorToday;
uint32 m_honorYesterday;
uint32 m_honorPoints;
uint32 m_killsToday;
uint32 m_killsYesterday;
uint32 m_killsLifetime;
bool m_honorless;
uint32 m_lastSeenWeather;
set