/* EQ2Emulator: Everquest II Server Emulator Copyright (C) 2007 EQ2EMulator Development Team (http://www.eq2emulator.net) This file is part of EQ2Emulator. EQ2Emulator 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 (at your option) any later version. EQ2Emulator 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 EQ2Emulator. If not, see . */ #ifndef __EQ2_PLAYER__ #define __EQ2_PLAYER__ #include "Entity.h" #include "Items/Items.h" #include "Factions.h" #include "Skills.h" #include "Quests.h" #include "MutexMap.h" #include "Guilds/Guild.h" #include "Collections/Collections.h" #include "Recipes/Recipe.h" #include "Titles.h" #include "Languages.h" #include "Achievements/Achievements.h" #include #include #define CF_COMBAT_EXPERIENCE_ENABLED 0 #define CF_ENABLE_CHANGE_LASTNAME 1 #define CF_FOOD_AUTO_CONSUME 2 #define CF_DRINK_AUTO_CONSUME 3 #define CF_AUTO_ATTACK 4 #define CF_RANGED_AUTO_ATTACK 5 #define CF_QUEST_EXPERIENCE_ENABLED 6 #define CF_CHASE_CAMERA_MAYBE 7 #define CF_100 8 #define CF_200 9 #define CF_IS_SITTING 10 /*CAN'T CAST OR ATTACK*/ #define CF_800 11 #define CF_ANONYMOUS 12 #define CF_ROLEPLAYING 13 #define CF_AFK 14 #define CF_LFG 15 #define CF_LFW 16 #define CF_HIDE_HOOD 17 #define CF_HIDE_HELM 18 #define CF_SHOW_ILLUSION 19 #define CF_ALLOW_DUEL_INVITES 20 #define CF_ALLOW_TRADE_INVITES 21 #define CF_ALLOW_GROUP_INVITES 22 #define CF_ALLOW_RAID_INVITES 23 #define CF_ALLOW_GUILD_INVITES 24 #define CF_2000000 25 #define CF_4000000 26 #define CF_DEFENSE_SKILLS_AT_MAX_QUESTIONABLE 27 #define CF_SHOW_GUILD_HERALDRY 28 #define CF_SHOW_CLOAK 29 #define CF_IN_PVP 30 #define CF_IS_HATED 31 #define CF2_1 32 #define CF2_2 33 #define CF2_4 34 #define CF2_ALLOW_LON_INVITES 35 #define CF2_SHOW_RANGED 36 #define CF2_ALLOW_VOICE_INVITES 37 #define CF2_CHARACTER_BONUS_EXPERIENCE_ENABLED 38 #define CF2_80 39 #define CF2_100 40 /* hide achievments*/ #define CF2_200 41 #define CF2_400 42 #define CF2_800 43 /* enable facebook updates*/ #define CF2_1000 44 /* enable twitter updates*/ #define CF2_2000 45 /* enable eq2 player updates */ #define CF2_4000 46 /*eq2 players, link to alt chars */ #define CF2_8000 47 #define CF2_10000 48 #define CF2_20000 49 #define CF2_40000 50 #define CF2_80000 51 #define CF2_100000 52 #define CF2_200000 53 #define CF2_400000 54 #define CF2_800000 55 #define CF2_1000000 56 #define CF2_2000000 57 #define CF2_4000000 58 #define CF2_8000000 59 #define CF2_10000000 60 #define CF2_20000000 61 #define CF2_40000000 62 #define CF2_80000000 63 #define CF_MAXIMUM_FLAG 63 #define CF_HIDE_STATUS 49 /* !!FORTESTING ONLY!! */ #define CF_GM_HIDDEN 50 /* !!FOR TESTING ONLY!! */ #define UPDATE_ACTIVITY_FALLING 0 #define UPDATE_ACTIVITY_RUNNING 128 #define UPDATE_ACTIVITY_RIDING_BOAT 256 #define UPDATE_ACTIVITY_JUMPING 1024 #define UPDATE_ACTIVITY_IN_WATER_ABOVE 6144 #define UPDATE_ACTIVITY_IN_WATER_BELOW 6272 #define UPDATE_ACTIVITY_SITING 6336 #define UPDATE_ACTIVITY_DROWNING 14464 #define UPDATE_ACTIVITY_DROWNING2 14336 #define NUM_MAINTAINED_EFFECTS 30 #define NUM_SPELL_EFFECTS 45 /* Character History Type Defines */ #define HISTORY_TYPE_NONE 0 #define HISTORY_TYPE_DEATH 1 #define HISTORY_TYPE_DISCOVERY 2 #define HISTORY_TYPE_XP 3 /* Spell Status */ #define SPELL_STATUS_QUEUE 4 #define SPELL_STATUS_LOCK 66 /* Character History Sub Type Defines */ #define HISTORY_SUBTYPE_NONE 0 #define HISTORY_SUBTYPE_ADVENTURE 1 #define HISTORY_SUBTYPE_TRADESKILL 2 #define HISTORY_SUBTYPE_QUEST 3 #define HISTORY_SUBTYPE_AA 4 #define HISTORY_SUBTYPE_ITEM 5 #define HISTORY_SUBTYPE_LOCATION 6 /// Character history data, should match the `character_history` table in the DB struct HistoryData { int32 Value; int32 Value2; char Location[200]; int32 EventID; int32 EventDate; }; /// History set through the LUA system struct LUAHistory { int32 Value; int32 Value2; bool SaveNeeded; }; struct SpellBookEntry{ int32 spell_id; int8 tier; int32 type; sint32 slot; int32 recast_available; int8 status; int16 recast; int32 timer; bool save_needed; Player* player; bool visible; }; #define QUICKBAR_NORMAL 1 #define QUICKBAR_INV_SLOT 2 #define QUICKBAR_MACRO 3 #define QUICKBAR_TEXT_CMD 4 #define QUICKBAR_ITEM 6 #define EXP_DISABLED_STATE 0 #define EXP_ENABLED_STATE 1 #define MELEE_COMBAT_STATE 16 #define RANGE_COMBAT_STATE 32 struct QuickBarItem{ bool deleted; int32 hotbar; int32 slot; int32 type; int16 icon; int16 icon_type; int32 id; int8 tier; int32 unique_id; EQ2_16BitString text; }; struct LoginAppearances { bool deleted; int16 equip_type; int8 red; int8 green; int8 blue; int8 h_red; int8 h_green; int8 h_blue; bool update_needed; }; class PlayerLoginAppearance { public: PlayerLoginAppearance() { appearanceList = new map; } ~PlayerLoginAppearance() { } void AddEquipmentToUpdate(int8 slot_id, LoginAppearances* equip) { //LoginAppearances data; //data.equip_type = equip->equip_type; //appearanceList[slot_id] = data; } void DeleteEquipmentFromUpdate(int8 slot_id, LoginAppearances* equip) { //LoginAppearances data; //data.deleted = equip->deleted; //data.update_needed = true; //appearanceList[slot_id] = data; } void RemoveEquipmentUpdates() { appearanceList->clear(); safe_delete(appearanceList); } private: map* appearanceList; }; struct InstanceData{ int32 db_id; int32 instance_id; int32 zone_id; int8 zone_instance_type; string zone_name; int32 last_success_timestamp; int32 last_failure_timestamp; int32 success_lockout_time; int32 failure_lockout_time; }; class CharacterInstances { public: CharacterInstances(); ~CharacterInstances(); ///Adds an instance data to the player with the given data ///The unique id for this record in the database ///The id of the instance ///The success timestamp ///The failure timestamp ///The lockout time, in secs, for completing the instance ///The lockout time, in secs, for failing the instance ///The id of the zone ///The type of instance of the zone ///The name of the zone void AddInstance(int32 db_id, int32 instance_id, int32 last_success_timestamp, int32 last_failure_timestamp, int32 success_lockout_time, int32 failure_lockout_time, int32 zone_id, int8 zone_instancetype, string zone_name); ///Clears all instance data void RemoveInstances(); ///Removes the instace with the given zone id ///The zone id of the instance to remove ///True if the instance was found and removed bool RemoveInstanceByZoneID(int32 zone_id); ///Removes the instance with the given instance id ///the instance id of the instance to remove ///True if instance was found and removed bool RemoveInstanceByInstanceID(int32 instance_id); ///Gets the instance with the given zone id ///The zone id of the instance to get ///InstanceData* of the instance record for the given zone id InstanceData* FindInstanceByZoneID(int32 zone_id); ///Gets the instance with the given database id ///The database id of the instance to get ///InstanceData* of the instance record for the given database id InstanceData* FindInstanceByDBID(int32 db_id); ///Gets the instance with the given instance id ///The instance id of the instance to get ///InstanceData* of the instance record for the given instance id InstanceData* FindInstanceByInstanceID(int32 instance_id); ///Gets a list of all the lockout instances vector GetLockoutInstances(); ///Gets a list of all the persistent instances vector GetPersistentInstances(); ///Check the timers for the instances ///player we are checking the timers for void ProcessInstanceTimers(Player* player); ///Gets the total number of instances int32 GetInstanceCount(); private: vector instanceList; Mutex m_instanceList; }; class Player; struct PlayerGroup; struct GroupMemberInfo; struct Statistic; struct Mail; class PlayerInfo { public: ~PlayerInfo(); PlayerInfo(Player* in_player); EQ2Packet* serialize(int16 version, int16 modifyPos = 0, int32 modifyValue = 0); PacketStruct* serialize2(int16 version); EQ2Packet* serialize3(PacketStruct* packet, int16 version); EQ2Packet* serializePet(int16 version); void CalculateXPPercentages(); void CalculateTSXPPercentages(); void SetHouseZone(int32 id); void SetBindZone(int32 id); void SetBindX(float x); void SetBindY(float y); void SetBindZ(float z); void SetBindHeading(float heading); void SetAccountAge(int16 days); int32 GetHouseZoneID(); int32 GetBindZoneID(); float GetBindZoneX(); float GetBindZoneY(); float GetBindZoneZ(); float GetBindZoneHeading(); float GetBoatX() { return boat_x_offset; } float GetBoatY() { return boat_y_offset; } float GetBoatZ() { return boat_z_offset; } int32 GetBoatSpawn(); void SetBoatX(float x) { boat_x_offset = x; } void SetBoatY(float y) { boat_y_offset = y; } void SetBoatZ(float z) { boat_z_offset = z; } void SetBoatSpawn(Spawn* boat); void RemoveOldPackets(); private: int32 house_zone_id; int32 bind_zone_id; float bind_x; float bind_y; float bind_z; float bind_heading; uchar* changes; uchar* orig_packet; uchar* pet_changes; uchar* pet_orig_packet; InfoStruct* info_struct; Player* player; float boat_x_offset; float boat_y_offset; float boat_z_offset; int32 boat_spawn; }; class PlayerControlFlags{ public: PlayerControlFlags(); ~PlayerControlFlags(); void SetPlayerControlFlag(int8 param, int8 param_value, bool is_active); bool ControlFlagsChanged(); void SendControlFlagUpdates(Client* client); private: bool flags_changed; map > flag_changes; map > current_flags; Mutex MControlFlags; Mutex MFlagChanges; }; class Player : public Entity{ public: Player(); virtual ~Player(); EQ2Packet* serialize(Player* player, int16 version); //int8 GetMaxArtLevel(){ return info->GetInfo()->max_art_level; } //int8 GetArtLevel(){ return info->GetInfo()->art_level; } Client* GetClient() { return client; } void SetClient(Client* client) { this->client = client; } PlayerInfo* GetPlayerInfo(); void SetCharSheetChanged(bool val); bool GetCharSheetChanged(); void AddFriend(const char* name, bool save); bool IsFriend(const char* name); void RemoveFriend(const char* name); map* GetFriends(); void AddIgnore(const char* name, bool save); bool IsIgnored(const char* name); void RemoveIgnore(const char* name); map* GetIgnoredPlayers(); // JA: POI Discoveries map >* GetPlayerDiscoveredPOIs(); void AddPlayerDiscoveredPOI(int32 location_id); // EQ2Packet* Move(float x, float y, float z, int16 version, float heading = -1.0f); /*void SetMaxArtLevel(int8 new_max){ max_art_level = new_max; } void SetArtLevel(int8 new_lvl){ art_level = new_lvl; }*/ bool WasSentSpawn(int32 spawn_id); bool NeedsSpawnResent(Spawn* spawn); void SetSideSpeed(float side_speed, bool updateFlags = true) { SetPos(&appearance.pos.SideSpeed, side_speed, updateFlags); } float GetSideSpeed() { return appearance.pos.SideSpeed; } int8 GetTutorialStep() { return tutorial_step; } void SetTutorialStep(int8 val) { tutorial_step = val; } void AddMaintainedSpell(LuaSpell* spell); void AddSpellEffect(LuaSpell* spell); void RemoveMaintainedSpell(LuaSpell* spell); void RemoveSpellEffect(LuaSpell* spell); bool HasActiveMaintainedSpell(Spell* spell, Spawn* target); bool HasActiveSpellEffect(Spell* spell, Spawn* target); void AddQuickbarItem(int32 bar, int32 slot, int32 type, int16 icon, int16 icon_type, int32 id, int8 tier, int32 unique_id, const char* text, bool update = true); void RemoveQuickbarItem(int32 bar, int32 slot, bool update = true); void MoveQuickbarItem(int32 id, int32 new_slot); void ClearQuickbarItems(); PlayerItemList* GetPlayerItemList(); PlayerItemList item_list; PlayerSkillList skill_list; Skill* GetSkillByName(const char* name, bool check_update = false); PlayerSkillList* GetSkills(); bool DamageEquippedItems(int8 amount = 10, Client* client = 0); vector EquipItem(int16 index, int16 version, int8 slot_id = 255); bool CanEquipItem(Item* item); void SetEquippedItemAppearances(); vector UnequipItem(int16 index, sint32 bag_id, int8 slot, int16 version); int8 ConvertSlotToClient(int8 slot, int16 version); int8 ConvertSlotFromClient(int8 slot, int16 version); EQ2Packet* SwapEquippedItems(int8 slot1, int8 slot2, int16 version); EQ2Packet* RemoveInventoryItem(int8 bag_slot, int8 slot); EQ2Packet* SendInventoryUpdate(int16 version); EQ2Packet* SendBagUpdate(int32 bag_unique_id, int16 version); void SendQuestRequiredSpawns(int32 quest_id); void SendHistoryRequiredSpawns(int32 event_id); map* GetItemList(); map* GetBankItemList(); vector* GetEquippedItemList(); Quest* SetStepComplete(int32 quest_id, int32 step); Quest* AddStepProgress(int32 quest_id, int32 step, int32 progress); int32 GetStepProgress(int32 quest_id, int32 step_id); bool AddItem(Item* item); bool AddItemToBank(Item* item); int16 GetSpellSlotMappingCount(); int16 GetSpellPacketCount(); Quest* GetQuest(int32 quest_id); bool GetQuestStepComplete(int32 quest_id, int32 step_id); int16 GetQuestStep(int32 quest_id); int16 GetTaskGroupStep(int32 quest_id); int8 GetSpellTier(int32 id); void SetSpellStatus(Spell* spell, int8 status); void RemoveSpellStatus(Spell* spell, int8 status); EQ2Packet* GetSpellBookUpdatePacket(int16 version); EQ2Packet* GetSpellSlotMappingPacket(int16 version); int32 GetCharacterID(); void SetCharacterID(int32 new_id); EQ2Packet* GetQuickbarPacket(int16 version); vector* GetQuickbar(); bool UpdateQuickbarNeeded(); void ResetQuickbarNeeded(); void set_character_flag(int flag); void reset_character_flag(int flag); void toggle_character_flag(int flag); bool get_character_flag(int flag); void AddCoins(int64 val); bool RemoveCoins(int64 val); /// Checks to see if the player has the given amount of coins /// Amount of coins to check /// True if the player has enough coins bool HasCoins(int64 val); void AddSkill(int32 skill_id, int16 current_val, int16 max_val, bool save_needed = false); void RemoveSkillFromDB(Skill* skill, bool save = false); void AddSpellBookEntry(int32 spell_id, int8 tier, sint32 slot, int32 type, int32 timer, bool save_needed = false); SpellBookEntry* GetSpellBookSpell(int32 spell_id); vector* GetSpellsSaveNeeded(); sint32 GetFreeSpellBookSlot(int32 type); /// Get a vector of spell ids for all spells in the spell book for the given skill /// The id of the skill to check /// A vector of int32's of the spell id's vector GetSpellBookSpellIDBySkill(int32 skill_id); EQ2Packet* MoveInventoryItem(sint32 to_bag_id, int16 from_index, int8 new_slot, int8 charges, int16 version = 1); bool IsPlayer(){ return true; } MaintainedEffects* GetFreeMaintainedSpellSlot(); MaintainedEffects* GetMaintainedSpell(int32 id); MaintainedEffects* GetMaintainedSpellBySlot(int8 slot); MaintainedEffects* GetMaintainedSpells(); SpellEffects* GetFreeSpellEffectSlot(); SpellEffects* GetSpellEffects(); int32 GetCoinsCopper(); int32 GetCoinsSilver(); int32 GetCoinsGold(); int32 GetCoinsPlat(); int32 GetBankCoinsCopper(); int32 GetBankCoinsSilver(); int32 GetBankCoinsGold(); int32 GetBankCoinsPlat(); float GetXPVitality(); float GetTSXPVitality(); bool AdventureXPEnabled(); bool TradeskillXPEnabled(); void SetNeededXP(int32 val); void SetNeededXP(); void SetXP(int32 val); void SetNeededTSXP(int32 val); void SetNeededTSXP(); void SetTSXP(int32 val); int32 GetNeededXP(); int32 GetXPDebt(); int32 GetXP(); int32 GetNeededTSXP(); int32 GetTSXP(); bool AddXP(int32 xp_amount); bool AddTSXP(int32 xp_amount); bool DoubleXPEnabled(); float CalculateXP(Spawn* victim); float CalculateTSXP(int8 level); void InCombat(bool val, bool range = false); void PrepareIncomingMovementPacket(int32 len, uchar* data, int16 version); uchar* GetMovementPacketData(){ return movement_packet; } void AddSpawnInfoPacketForXOR(int32 spawn_id, uchar* packet, int16 packet_size); uchar* GetSpawnInfoPacketForXOR(int32 spawn_id); void AddSpawnVisPacketForXOR(int32 spawn_id, uchar* packet, int16 packet_size); uchar* GetSpawnVisPacketForXOR(int32 spawn_id); void AddSpawnPosPacketForXOR(int32 spawn_id, uchar* packet, int16 packet_size); uchar* GetSpawnPosPacketForXOR(int32 spawn_id); uchar* GetTempInfoPacketForXOR(); uchar* GetTempVisPacketForXOR(); uchar* GetTempPosPacketForXOR(); uchar* SetTempInfoPacketForXOR(int16 size); uchar* SetTempVisPacketForXOR(int16 size); uchar* SetTempPosPacketForXOR(int16 size); int32 GetTempInfoXorSize() { return info_xor_size; } int32 GetTempVisXorSize() { return vis_xor_size; } int32 GetTempPosXorSize() { return pos_xor_size; } bool CheckPlayerInfo(); void CalculateLocation(); void SetSpawnDeleteTime(int32 id, int32 time); int32 GetSpawnDeleteTime(int32 id); void ClearEverything(); bool IsFullyLoggedIn(); void SetFullyLoggedIn(bool val); bool IsResurrecting(); void SetResurrecting(bool val); int8 GetArrowColor(int8 spawn_level); int8 GetTSArrowColor(int8 level); Spawn* GetSpawnByIndex(int16 index); int16 GetIndexForSpawn(Spawn* spawn); bool WasSpawnRemoved(Spawn* spawn); void RemoveSpawn(Spawn* spawn); void ClearRemovedSpawn(Spawn* spawn); bool ShouldSendSpawn(Spawn* spawn); Client* client = 0; Spawn* GetSpawnWithPlayerID(int32 id){ Spawn* spawn = 0; index_mutex.readlock(__FUNCTION__, __LINE__); if (player_spawn_id_map.count(id) > 0) spawn = player_spawn_id_map[id]; index_mutex.releasereadlock(__FUNCTION__, __LINE__); return spawn; } int32 GetIDWithPlayerSpawn(Spawn* spawn){ int32 id = 0; index_mutex.readlock(__FUNCTION__, __LINE__); if (player_spawn_reverse_id_map.count(spawn) > 0) id = player_spawn_reverse_id_map[spawn]; index_mutex.releasereadlock(__FUNCTION__, __LINE__); return id; } void SetSpawnMap(Spawn* spawn) { index_mutex.writelock(__FUNCTION__, __LINE__); spawn_id += 1; int32 tmp_id = spawn_id; player_spawn_id_map[tmp_id] = spawn; if(player_spawn_reverse_id_map.count(spawn)) player_spawn_reverse_id_map.erase(spawn); player_spawn_reverse_id_map.insert(make_pair(spawn,tmp_id)); index_mutex.releasewritelock(__FUNCTION__, __LINE__); } void SetSpawnMapIndex(Spawn* spawn, int16 index) { index_mutex.writelock(__FUNCTION__, __LINE__); if (player_spawn_map.count(index)) player_spawn_map[index] = spawn; else player_spawn_map[index] = spawn; index_mutex.releasewritelock(__FUNCTION__, __LINE__); } int16 SetSpawnMapAndIndex(Spawn* spawn) { int16 new_index = 0; index_mutex.writelock(__FUNCTION__, __LINE__); spawn_index += 1; if (spawn_index == 255) spawn_index += 1; //just so we dont have to worry about overloading new_index = spawn_index; if (player_spawn_index_map.count(spawn)) player_spawn_index_map.erase(spawn); player_spawn_index_map.insert(make_pair(spawn,new_index)); if (player_spawn_map.count(new_index)) player_spawn_map[new_index] = spawn; else player_spawn_map.insert(make_pair(new_index, spawn)); index_mutex.releasewritelock(__FUNCTION__, __LINE__); return new_index; } PacketStruct* GetQuestJournalPacket(bool all_quests, int16 version, int32 crc, int32 current_quest_id, bool updated = true); void RemoveQuest(int32 id, bool delete_quest); vector* CheckQuestsChatUpdate(Spawn* spawn); vector* CheckQuestsItemUpdate(Item* item); vector* CheckQuestsLocationUpdate(); vector* CheckQuestsKillUpdate(Spawn* spawn,bool update = true); vector* CheckQuestsSpellUpdate(Spell* spell); void CheckQuestsCraftUpdate(Item* item, int32 qty); void CheckQuestsHarvestUpdate(Item* item, int32 qty); vector* CheckQuestsFailures(); bool CheckQuestRemoveFlag(Spawn* spawn); int8 CheckQuestFlag(Spawn* spawn); bool CheckQuestRequired(Spawn* spawn); void AddQuestRequiredSpawn(Spawn* spawn, int32 quest_id); void AddHistoryRequiredSpawn(Spawn* spawn, int32 event_id); int16 spawn_index; int32 spawn_id; int8 tutorial_step; map*> player_spawn_quests_required; map*> player_spawn_history_required; Mutex m_playerSpawnQuestsRequired; Mutex m_playerSpawnHistoryRequired; Quest* GetCompletedQuest(int32 quest_id); void AddCompletedQuest(Quest* quest); map pending_quests; map player_quests; map* GetPlayerQuests(); map* GetCompletedPlayerQuests(); void LockQuests(); void UnlockQuests(); void SetFactionValue(int32 faction_id, sint32 value){ factions.SetFactionValue(faction_id, value); } PlayerFaction* GetFactions(){ return &factions; } vector GetQuestIDs(); map macro_icons; bool HasPendingLootItems(int32 id); bool HasPendingLootItem(int32 id, int32 item_id); vector* GetPendingLootItems(int32 id); void RemovePendingLootItem(int32 id, int32 item_id); void RemovePendingLootItems(int32 id); void AddPendingLootItems(int32 id, vector* items); bool HasSpell(int32 spell_id, int8 tier = 255, bool include_higher_tiers = false); bool HasRecipeBook(int32 recipe_id); void AddPlayerStatistic(int32 stat_id, sint32 stat_value, int32 stat_date); void UpdatePlayerStatistic(int32 stat_id, sint32 stat_value, bool overwrite = false); sint64 GetPlayerStatisticValue(int32 stat_id); void WritePlayerStatistics(); //PlayerGroup* GetGroup(); void SetGroup(PlayerGroup* group); bool IsGroupMember(Entity* player); void SetGroupInformation(PacketStruct* packet); void ResetSavedSpawns(); bool IsReturningFromLD(); void SetReturningFromLD(bool val); bool CheckLevelStatus(int16 new_level); int16 GetLastMovementActivity(); void DestroyQuests(); string GetAwayMessage() const { return away_message; } void SetAwayMessage(string val) { away_message = val; } void SetRangeAttack(bool val); bool GetRangeAttack(); ZoneServer* GetGroupMemberInZone(int32 zone_id); bool AddMail(Mail* mail); MutexMap* GetMail(); Mail* GetMail(int32 mail_id); void DeleteMail(bool from_database = false); void DeleteMail(int32 mail_id, bool from_database = false); CharacterInstances* GetCharacterInstances() { return &character_instances; } void SetIsTracking(bool val) { is_tracking = val; } bool GetIsTracking() const { return is_tracking; } void SetBiography(string new_biography) { biography = new_biography; } string GetBiography() const { return biography; } void SetPlayerAdventureClass(int8 new_class); void SetGuild(Guild* new_guild) { guild = new_guild; } Guild* GetGuild() { return guild; } void AddSkillBonus(int32 spell_id, int32 skill_id, float value); SkillBonus* GetSkillBonus(int32 spell_id); virtual void RemoveSkillBonus(int32 spell_id); virtual bool CanSeeInvis(Entity* target); bool CheckChangeInvisHistory(Entity* target); void UpdateTargetInvisHistory(int32 targetID, bool canSeeStatus); void RemoveTargetInvisHistory(int32 targetID); bool HasFreeBankSlot(); int8 FindFreeBankSlot(); PlayerCollectionList * GetCollectionList() { return &collection_list; } PlayerRecipeList * GetRecipeList() { return &recipe_list; } PlayerRecipeBookList * GetRecipeBookList() { return &recipebook_list; } PlayerAchievementList * GetAchievementList() { return &achievement_list; } PlayerAchievementUpdateList * GetAchievementUpdateList() { return &achievement_update_list; } void SetPendingCollectionReward(Collection *collection) { pending_collection_reward = collection; } Collection * GetPendingCollectionReward() { return pending_collection_reward; } void AddPendingSelectableItemReward(int32 source_id, Item* item) { if (pending_selectable_item_rewards.count(source_id) == 0) pending_selectable_item_rewards[source_id] = vector(); pending_selectable_item_rewards[source_id].push_back(item); } void AddPendingItemReward(Item* item) { pending_item_rewards.push_back(item); } bool HasPendingItemRewards() { return (pending_item_rewards.size() > 0 || pending_selectable_item_rewards.size() > 0); } vector GetPendingItemRewards() { return pending_item_rewards; } map GetPendingSelectableItemReward(int32 item_id) { //since the client sends the selected item id, we need to have the associated source and remove all of them. Yes, there is an edge case if multiple sources have the same Item in them, but limited on what the client sends (just a single item id) map ret; if (pending_selectable_item_rewards.size() > 0) { map>::iterator map_itr; for (map_itr = pending_selectable_item_rewards.begin(); map_itr != pending_selectable_item_rewards.end(); map_itr++) { vector::iterator itr; for (itr = map_itr->second.begin(); itr != map_itr->second.end(); itr++) { if ((*itr)->details.item_id == item_id) { ret[map_itr->first] = *itr; break; } } if (ret.size() > 0) break; } } return map(); } void ClearPendingSelectableItemRewards(int32 source_id, bool all = false) { if (pending_selectable_item_rewards.size() > 0) { map>::iterator map_itr; if (all) { for (map_itr = pending_selectable_item_rewards.begin(); map_itr != pending_selectable_item_rewards.end(); map_itr++) { vector::iterator itr; for (itr = map_itr->second.begin(); itr != map_itr->second.end(); itr++) { safe_delete(*itr); } } pending_selectable_item_rewards.clear(); } else { if (pending_selectable_item_rewards.count(source_id) > 0) { vector::iterator itr; for (itr = pending_selectable_item_rewards[source_id].begin(); itr != pending_selectable_item_rewards[source_id].end(); itr++) { safe_delete(*itr); } pending_selectable_item_rewards.erase(source_id); } } } } void ClearPendingItemRewards() { //the client doesn't send any reference to where the pending rewards came from, so if they collect one, we should just them all of them at once if (pending_item_rewards.size() > 0) { vector::iterator itr; for (itr = pending_item_rewards.begin(); itr != pending_item_rewards.end(); itr++) { safe_delete(*itr); } pending_item_rewards.clear(); } } void RemoveSpellBookEntry(int32 spell_id, bool remove_passives_from_list = true); void ResortSpellBook(int32 sort_by, int32 order, int32 pattern, int32 maxlvl_only, int32 book_type); static bool SortSpellEntryByName(SpellBookEntry* s1, SpellBookEntry* s2); static bool SortSpellEntryByCategory(SpellBookEntry* s1, SpellBookEntry* s2); static bool SortSpellEntryByLevel(SpellBookEntry* s1, SpellBookEntry* s2); static bool SortSpellEntryByNameReverse(SpellBookEntry* s1, SpellBookEntry* s2); static bool SortSpellEntryByCategoryReverse(SpellBookEntry* s1, SpellBookEntry* s2); static bool SortSpellEntryByLevelReverse(SpellBookEntry* s1, SpellBookEntry* s2); int8 GetSpellSlot(int32 spell_id); void AddTitle(int32 title_id, const char *name, int8 prefix, bool save_needed = false); void AddAAEntry(int16 template_id, int8 tab_id, int32 aa_id, int16 order, int8 treeid); PlayerTitlesList* GetPlayerTitles() { return &player_titles_list; } void AddLanguage(int32 id, const char *name, bool save_needed = false); PlayerLanguagesList* GetPlayerLanguages() { return &player_languages_list; } bool HasLanguage(int32 id); bool HasLanguage(const char* name); bool CanReceiveQuest(int32 quest_id); float GetBoatX() { if (info) return info->GetBoatX(); return 0; } float GetBoatY() { if (info) return info->GetBoatY(); return 0; } float GetBoatZ() { if (info) return info->GetBoatZ(); return 0; } int32 GetBoatSpawn() { if (info) return info->GetBoatSpawn(); return 0; } void SetBoatX(float x) { if (info) info->SetBoatX(x); } void SetBoatY(float y) { if (info) info->SetBoatY(y); } void SetBoatZ(float z) { if (info) info->SetBoatZ(z); } void SetBoatSpawn(Spawn* boat) { if (info) info->SetBoatSpawn(boat); } Mutex* GetGroupBuffMutex(); void SetPendingDeletion(bool val) { pending_deletion = val; } bool GetPendingDeletion() { return pending_deletion; } float GetPosPacketSpeed() { return pos_packet_speed; } bool ControlFlagsChanged(); void SetPlayerControlFlag(int8 param, int8 param_value, bool is_active); void SendControlFlagUpdates(Client* client); /// Casts all the passive spells for the player, only call after zoning is complete. void ApplyPassiveSpells(); /// Removes all passive spell effects from the player and clears the passive list void RemoveAllPassives(); /// Gets the current recipie ID int32 GetCurrentRecipe() { return current_recipe; } /// Sets the current recipie ID /// Id of the new recipe void SetCurrentRecipe(int32 val) { current_recipe = val; } /// Reset the pet window info void ResetPetInfo(); void ProcessCombat(); /* Character history stuff */ /// Adds a new history event to the player /// The history type /// The history sub type /// The first history value /// The second history value void UpdatePlayerHistory(int8 type, int8 subtype, int32 value, int32 value2 = 0); /// Checks to see if the player has discovered the location /// The ID of the location to check /// True if the player has discovered the location bool DiscoveredLocation(int32 locationID); /// Load the players history from the database /// The history type /// The history sub type /// The history data void LoadPlayerHistory(int8 type, int8 subtype, HistoryData* hd); /// Save the player's history to the database void SaveHistory(); /* New functions for spell locking and unlocking*/ /// Lock all Spells, Combat arts, and Abilities (not trade skill spells) void LockAllSpells(); /// Unlocks all Spells, Combat arts, and Abilities (not trade skill spells) void UnlockAllSpells(bool modify_recast = false); /// Locks the given spell as well as all spells with a shared timer void LockSpell(Spell* spell, int16 recast); /// Unlocks the given spell as well as all spells with shared timers void UnlockSpell(Spell* spell); /// Locks all ts spells and unlocks all normal spells void LockTSSpells(); /// Unlocks all ts spells and locks all normal spells void UnlockTSSpells(); /// Queue the given spell void QueueSpell(Spell* spell); /// Unqueue the given spell void UnQueueSpell(Spell* spell); ///Get all the spells the player has with the given id vector GetSpellBookSpellsByTimer(int32 timerID); PacketStruct* GetQuestJournalPacket(Quest* quest, int16 version, int32 crc, bool updated = true); void SetSpawnInfoStruct(PacketStruct* packet) { safe_delete(spawn_info_struct); spawn_info_struct = packet; } void SetSpawnVisStruct(PacketStruct* packet) { safe_delete(spawn_vis_struct); spawn_vis_struct = packet; } void SetSpawnPosStruct(PacketStruct* packet) { safe_delete(spawn_pos_struct); spawn_pos_struct = packet; } void SetSpawnHeaderStruct(PacketStruct* packet) { safe_delete(spawn_header_struct); spawn_header_struct = packet; } void SetSpawnFooterStruct(PacketStruct* packet) { safe_delete(spawn_footer_struct); spawn_footer_struct = packet; } void SetSignFooterStruct(PacketStruct* packet) { safe_delete(sign_footer_struct); sign_footer_struct = packet; } void SetWidgetFooterStruct(PacketStruct* packet) { safe_delete(widget_footer_struct); widget_footer_struct = packet; } PacketStruct* GetSpawnInfoStruct() { return spawn_info_struct; } PacketStruct* GetSpawnVisStruct() { return spawn_vis_struct; } PacketStruct* GetSpawnPosStruct() { return spawn_pos_struct; } PacketStruct* GetSpawnHeaderStruct() { return spawn_header_struct; } PacketStruct* GetSpawnFooterStruct() { return spawn_footer_struct; } PacketStruct* GetSignFooterStruct() { return sign_footer_struct; } PacketStruct* GetWidgetFooterStruct() { return widget_footer_struct; } Mutex info_mutex; Mutex pos_mutex; Mutex vis_mutex; Mutex index_mutex; void SetTempMount(int32 id) { tmp_mount_model = id; } int32 GetTempMount() { return tmp_mount_model; } void SetTempMountColor(EQ2_Color* color) { tmp_mount_color = *color; } EQ2_Color GetTempMountColor() { return tmp_mount_color; } void SetTempMountSaddleColor(EQ2_Color* color) { tmp_mount_saddle_color = *color; } EQ2_Color GetTempMountSaddleColor() { return tmp_mount_saddle_color; } void LoadLUAHistory(int32 event_id, LUAHistory* history); void SaveLUAHistory(); void UpdateLUAHistory(int32 event_id, int32 value, int32 value2); LUAHistory* GetLUAHistory(int32 event_id); bool HasGMVision() { return gm_vision; } void SetGMVision(bool val) { gm_vision = val; } AppearanceData SavedApp; CharFeatures SavedFeatures; bool custNPC; Entity* custNPCTarget; // bot index, spawn id map SpawnedBots; private: bool range_attack; int16 last_movement_activity; bool returning_from_ld; PlayerGroup* group; float test_x; float test_y; float test_z; int32 test_time; map > pending_loot_items; Mutex MSpellsBook; Mutex MRecipeBook; Mutex MPlayerQuests; map current_quest_flagged; PlayerFaction factions; map completed_quests; bool charsheet_changed; map spawn_vis_packet_list; map spawn_info_packet_list; map spawn_pos_packet_list; uchar* movement_packet; uchar* old_movement_packet; uchar* spell_orig_packet; uchar* spell_xor_packet; int16 spell_count; //float speed; int16 target_id; Spawn* combat_target; int32 char_id; bool quickbar_updated; bool fully_logged_in; bool resurrecting; PlayerInfo* info; vector spells; vector quickbar_items; map statistics; void RemovePlayerStatistics(); map friend_list; map ignore_list; bool pending_deletion; float pos_packet_speed; PlayerControlFlags control_flags; map target_invis_history; // JA: POI Discoveries map > players_poi_list; // Jabantiz: Passive spell list, just stores spell id's vector passive_spells; /// Adds a new passive spell to the list /// Spell id to add /// Tier of spell to add void AddPassiveSpell(int32 id, int8 tier); /// Removes a passive spell from the list /// Spell id to remove /// Tier of spell to remove /// Remove the spell from this players passive list, default true void RemovePassive(int32 id, int8 tier, bool remove_from_list = true); CharacterInstances character_instances; string away_message; string biography; MutexMap mail_list; bool is_tracking; Guild* guild; PlayerCollectionList collection_list; Collection * pending_collection_reward; vector pending_item_rewards; map> pending_selectable_item_rewards; PlayerTitlesList player_titles_list; PlayerRecipeList recipe_list; PlayerLanguagesList player_languages_list; PlayerRecipeBookList recipebook_list; PlayerAchievementList achievement_list; PlayerAchievementUpdateList achievement_update_list; // Need to keep track of the recipe the player is crafting as not all crafting packets have this info int32 current_recipe; void HandleHistoryNone(int8 subtype, int32 value, int32 value2); void HandleHistoryDeath(int8 subtype, int32 value, int32 value2); void HandleHistoryDiscovery(int8 subtype, int32 value, int32 value2); void HandleHistoryXP(int8 subtype, int32 value, int32 value2); /// void ModifySpellStatus(SpellBookEntry* spell, sint16 value, bool modify_recast = true, int16 recast = 0); void AddSpellStatus(SpellBookEntry* spell, sint16 value, bool modify_recast = true, int16 recast = 0); void RemoveSpellStatus(SpellBookEntry* spell, sint16 value, bool modify_recast = true, int16 recast = 0); void InitXPTable(); map m_levelXPReq; //The following variables are for serializing spawn packets PacketStruct* spawn_pos_struct; PacketStruct* spawn_info_struct; PacketStruct* spawn_vis_struct; PacketStruct* spawn_header_struct; PacketStruct* spawn_footer_struct; PacketStruct* sign_footer_struct; PacketStruct* widget_footer_struct; uchar* spawn_tmp_vis_xor_packet; uchar* spawn_tmp_pos_xor_packet; uchar* spawn_tmp_info_xor_packet; int32 vis_xor_size; int32 pos_xor_size; int32 info_xor_size; // Character history, map > > map > > m_characterHistory; map m_charLuaHistory; Mutex mLUAHistory; int32 tmp_mount_model; EQ2_Color tmp_mount_color; EQ2_Color tmp_mount_saddle_color; bool gm_vision; map player_spawn_index_map; map player_spawn_map; map player_spawn_id_map; map player_spawn_reverse_id_map; map player_removed_spawns; }; #pragma pack() #endif