1
Fork 0
mirror of https://github.com/SapphireServer/Sapphire.git synced 2025-04-30 08:07:46 +00:00
sapphire/src/world/Actor/Player.h

991 lines
29 KiB
C
Raw Normal View History

#pragma once
2017-08-08 13:53:47 +02:00
2018-09-24 09:03:29 -04:00
#include "ForwardsZone.h"
2017-08-08 13:53:47 +02:00
2018-03-06 22:22:19 +01:00
#include <Common.h>
#include <Util/SpawnIndexAllocator.h>
2019-01-05 12:32:10 +01:00
#include <spdlog/fmt/fmt.h>
#include <optional>
2017-08-08 13:53:47 +02:00
#include "Chara.h"
#include "Quest/Quest.h"
2018-01-09 23:50:54 +01:00
#include "Event/EventHandler.h"
2017-08-08 13:53:47 +02:00
#include <map>
#include <queue>
2019-03-26 00:04:27 +01:00
#include <array>
2017-08-08 13:53:47 +02:00
namespace Sapphire::Entity
2017-08-08 13:53:47 +02:00
{
2018-10-28 21:53:21 +01:00
struct QueuedZoning
{
2018-10-28 21:53:21 +01:00
uint16_t m_targetZone;
Common::FFXIVARR_POSITION3 m_targetPosition;
float m_targetRotation;
uint64_t m_queueTime;
QueuedZoning( uint16_t targetZone, const Common::FFXIVARR_POSITION3& targetPosition,
uint64_t queuedTime, float targetRotation ) :
m_targetZone( targetZone ),
m_targetPosition( targetPosition ),
m_queueTime( queuedTime ),
m_targetRotation( targetRotation )
{
}
};
/** Class representing the Player
* Inheriting from Actor
*
*/
class Player : public Chara
{
public:
using TitleList = std::array< uint8_t, 48 >;
using HowToList = std::array< uint8_t, 34 >;
using MinionList = std::array< uint8_t, 40 >;
using MountList = std::array< uint8_t, 22 >;
using QuestComplete = std::array< uint8_t, 476 >;
using Discovery = std::array< uint8_t, 400 >;
using AetheryteList = std::array< uint8_t, 21 >;
using UnlockList = std::array< uint8_t, 64 >;
using OrchestrionList = std::array< uint8_t, 40 >;
using StateFlags = std::array< uint8_t, 12 >;
using ClassList = std::array< uint16_t, 28 >;
using ExpList = std::array< uint32_t, 28 >;
2018-10-28 21:53:21 +01:00
/*! Contructor */
2020-03-01 01:00:57 +11:00
Player();
2018-10-28 21:53:21 +01:00
/*! Destructor */
~Player();
2018-10-28 21:53:21 +01:00
void autoAttack( CharaPtr pTarget ) override;
2018-10-28 21:53:21 +01:00
// EventHandlers
//////////////////////////////////////////////////////////////////////////////////////////////////////
2018-10-28 21:53:21 +01:00
/*! add an event to the event array */
void addEvent( Event::EventHandlerPtr pEvent );
2018-10-28 21:53:21 +01:00
/*! retrieve an event from the event array */
Event::EventHandlerPtr getEvent( uint32_t eventId ) const;
2018-10-28 21:53:21 +01:00
/*! get number of active events */
size_t getEventCount();
2018-10-28 21:53:21 +01:00
/*! remove an event from the event array */
void removeEvent( uint32_t eventId );
2018-10-28 21:53:21 +01:00
/*! return the eventlist */
std::map< uint32_t, Event::EventHandlerPtr >& getEventListRef();
2018-10-28 21:53:21 +01:00
// Events
//////////////////////////////////////////////////////////////////////////////////////////////////////
2018-10-28 21:53:21 +01:00
/*! Event to be called on update tick */
void onTick() override;
2018-10-28 21:53:21 +01:00
/*! Event to be called upon player death */
void onDeath() override;
2018-10-28 21:53:21 +01:00
/*! Event called on every session iteration */
void update( uint64_t tickCount ) override;
2022-01-02 22:32:17 +01:00
void setLastAttack( uint64_t tickCount );
2018-10-28 21:53:21 +01:00
// Quest
//////////////////////////////////////////////////////////////////////////////////////////////////////
/*! load data for currently active quests */
bool loadActiveQuests();
2018-10-28 21:53:21 +01:00
/*! update quest ( register it as active quest if new ) */
void updateQuest( const World::Quest& quest );
2018-10-28 21:53:21 +01:00
/*! return true if quest is currently active */
bool hasQuest( uint32_t questId );
std::optional< World::Quest > getQuest( uint32_t questId );
2018-10-28 21:53:21 +01:00
/*! return the index of a given quest in the players quest list */
int8_t getQuestIndex( uint16_t questId );
World::Quest& getQuestByIndex( uint16_t questId );
int16_t getQuestTracking( uint8_t index ) const;
2018-10-28 21:53:21 +01:00
/*! finish a given quest */
void finishQuest( uint16_t questId, uint32_t optionalChoice = 0 );
2018-10-28 21:53:21 +01:00
/*! finish a given quest */
void unfinishQuest( uint16_t questId );
2018-10-28 21:53:21 +01:00
/*! remove a given quest */
void removeQuest( uint16_t questId );
2018-10-28 21:53:21 +01:00
/*! add a quest to the completed quests mask */
void updateQuestsCompleted( uint32_t questId );
2018-10-28 21:53:21 +01:00
/*! remove a quest from the completed quest mask */
void removeQuestsCompleted( uint32_t questId );
2018-10-28 21:53:21 +01:00
/*! get the curent opening sequence */
uint8_t getOpeningSequence() const;
2018-10-28 21:53:21 +01:00
/*! set te current opening sequence */
void setOpeningSequence( uint8_t seq );
std::array< World::Quest, 30 >& getQuestArrayRef();
QuestComplete& getQuestCompleteFlags();
// Inventory / Item / Currency / Shop
2018-10-28 21:53:21 +01:00
//////////////////////////////////////////////////////////////////////////////////////////////////////
/*! equip an item to a specified slot */
void equipItem( Common::GearSetSlot equipSlotId, Item& item, bool sendModel );
2018-10-28 21:53:21 +01:00
/*! remove an item from an equipment slot */
void unequipItem( Common::GearSetSlot equipSlotId, Item& item, bool sendModel );
2018-10-28 21:53:21 +01:00
/*! equip a weapon, possibly forcing a job change */
void equipWeapon( const Item& item );
2018-10-28 21:53:21 +01:00
/*! equip a soul crystal, possibly forcing a job change*/
void equipSoulCrystal( const Item& item );
2018-10-28 21:53:21 +01:00
/*! unequip a soul crystal, returning to the base class*/
void unequipSoulCrystal();
2018-10-28 21:53:21 +01:00
/*! get player ilvl */
uint16_t getItemLevel() const;
2018-10-28 21:53:21 +01:00
/*! send player ilvl */
void sendItemLevel();
2018-10-28 21:53:21 +01:00
/*! get the current main hand model */
uint64_t getModelMainWeapon() const;
2018-10-28 21:53:21 +01:00
/*! get the current off hand model */
uint64_t getModelSubWeapon() const;
2018-10-28 21:53:21 +01:00
/*! get the current system hand model */
uint64_t getModelSystemWeapon() const;
2018-10-28 21:53:21 +01:00
/*! return a const pointer to the model array */
const uint32_t* getModelArray() const;
2018-10-28 21:53:21 +01:00
/*! return the equipment model in a specified equipment slot */
uint32_t getModelForSlot( Common::GearModelSlot slot );
2018-10-28 21:53:21 +01:00
/*! add amount to the currency of type */
void addCurrency( Common::CurrencyType type, uint32_t amount );
2018-10-28 21:53:21 +01:00
/*! remove amount from the currency of type */
void removeCurrency( Common::CurrencyType type, uint32_t amount );
2018-10-28 21:53:21 +01:00
/*! return the current amount of crystals of type */
uint32_t getCrystal( uint8_t type ) const;
void updateModels( Common::GearSetSlot equipSlotId, const Sapphire::Item& item );
2018-09-17 22:52:57 +02:00
2018-10-28 21:53:21 +01:00
Common::GearModelSlot equipSlotToModelSlot( Common::GearSetSlot slot );
2018-09-17 22:52:57 +02:00
bool getFreeInventoryContainerSlot( Inventory::InventoryContainerPair& containerPair ) const;
void insertInventoryItem( Common::InventoryType type, uint16_t slot, const Sapphire::ItemPtr item );
2018-10-28 21:53:21 +01:00
/*!
* Collect real item handins from container
* @param itemIds a vector of each catalog id to collect
* @return true if all items were handed in
*/
bool collectHandInItems( std::vector< uint32_t > itemIds );
void addSoldItem( uint32_t itemId, uint8_t stackSize );
std::deque< std::pair< uint32_t, uint8_t > > *getSoldItems();
void clearSoldItems();
2018-10-28 21:53:21 +01:00
// Class / Job / Exp
//////////////////////////////////////////////////////////////////////////////////////////////////////
/*! returns the level of the currently active class / job */
uint8_t getLevel() const override;
/*! returns the level sync of current active class / job */
uint8_t getLevelSync() const;
2018-10-28 21:53:21 +01:00
/*! returns the level of the provided class / job */
uint8_t getLevelForClass( Common::ClassJob pClass ) const;
2018-10-28 21:53:21 +01:00
/*! returns if the classjob is unlocked */
bool isClassJobUnlocked( Common::ClassJob classJob ) const;
2018-10-28 21:53:21 +01:00
/*! returns the exp of the currently active class / job */
uint32_t getExp() const;
2018-10-28 21:53:21 +01:00
/*! sets the exp of the currently active class / job */
void setExp( uint32_t amount );
2018-10-28 21:53:21 +01:00
/*! adds exp to the currently active class / job */
void gainExp( uint32_t amount );
2018-10-28 21:53:21 +01:00
/*! gain a level on the currently active class / job */
void levelUp();
2018-10-28 21:53:21 +01:00
/*! set level on the currently active class / job to given level */
void setLevel( uint8_t level );
2018-10-28 21:53:21 +01:00
/*! set level on the provided class / job to given level */
void setLevelForClass( uint8_t level, Common::ClassJob classjob );
2018-10-28 21:53:21 +01:00
/*! change class or job to given class / job */
void setClassJob( Common::ClassJob classJob );
2018-10-28 21:53:21 +01:00
/*! returns a pointer to the class array */
ClassList& getClassArray();
2018-10-28 21:53:21 +01:00
/*! returns a pointer to the exp array */
ExpList& getExpArray();
2018-10-28 21:53:21 +01:00
// Base Look / Stats / Params
//////////////////////////////////////////////////////////////////////////////////////////////////////
/*! return the birth day */
uint8_t getBirthDay() const;
2018-10-28 21:53:21 +01:00
/*! return the birth month */
uint8_t getBirthMonth() const;
2018-10-28 21:53:21 +01:00
/*! return the guardian diety Id */
uint8_t getGuardianDeity() const;
2018-10-28 21:53:21 +01:00
/*! get look at specified index */
uint8_t getLookAt( uint8_t index ) const;
2018-10-28 21:53:21 +01:00
/*! return the race */
uint8_t getRace() const;
2018-10-28 21:53:21 +01:00
/*! return gender 0 male, 1 female */
uint8_t getGender() const;
2018-10-28 21:53:21 +01:00
/*! return the id of the home town */
uint8_t getStartTown() const;
2018-10-28 21:53:21 +01:00
/*! return the voice id */
uint8_t getVoiceId() const;
2018-10-28 21:53:21 +01:00
/*! return the grand company */
uint8_t getGc() const;
2018-10-28 21:53:21 +01:00
/*! return the grand company rank */
const std::array< uint8_t, 3 >& getGcRankArray() const;
2018-10-28 21:53:21 +01:00
/*! set look at index */
void setLookAt( uint8_t index, uint8_t value );
2018-10-28 21:53:21 +01:00
/*! set the voice Id */
void setVoiceId( uint8_t voiceId );
2018-10-28 21:53:21 +01:00
/*! set the grand company */
void setGc( uint8_t gc );
2018-10-28 21:53:21 +01:00
/*! set the grand company rank */
void setGcRankAt( uint8_t index, uint8_t rank );
2018-10-28 21:53:21 +01:00
/*! returns true if the player is currently in combat */
bool isInCombat() const;
2018-10-28 21:53:21 +01:00
/*! sets players combat state */
void setInCombat( bool mode );
2018-10-28 21:53:21 +01:00
/*! return current online status depending on current state / activity */
Common::OnlineStatus getOnlineStatus() const;
2018-10-28 21:53:21 +01:00
/*! sets the players zone, initiating a zoning process */
void setZone( uint32_t zoneId );
2018-10-28 21:53:21 +01:00
/*! sets the players instance & initiates zoning process */
bool setInstance( uint32_t instanceContentId );
2018-10-28 21:53:21 +01:00
/*! sets the players instance & initiates zoning process */
bool setInstance( const TerritoryPtr& instance );
/*! sets the players instance & initiates zoning process */
bool setInstance( const Sapphire::TerritoryPtr& instance, Sapphire::Common::FFXIVARR_POSITION3 pos );
2018-10-28 21:53:21 +01:00
/*! returns the player to their position before zoning into an instance */
bool exitInstance();
/*! gets the players territoryTypeId */
uint32_t getPrevTerritoryTypeId() const;
2018-10-28 21:53:21 +01:00
void forceZoneing( uint32_t zoneId );
2018-10-28 21:53:21 +01:00
/*! return player to preset homepoint */
void returnToHomepoint();
2018-10-28 21:53:21 +01:00
/*! change position, sends update too */
void changePosition( float x, float y, float z, float o );
/*! return the characterId */
uint64_t getCharacterId() const;
2018-10-28 21:53:21 +01:00
/*! return max hp */
uint32_t getMaxHp();
2018-10-28 21:53:21 +01:00
/*! return max mp */
uint32_t getMaxMp();
2018-10-28 21:53:21 +01:00
/*! return a players total play time */
uint32_t getPlayTime() const;
2018-10-28 21:53:21 +01:00
/*! return true if the player has "new adventurere" status */
bool isNewAdventurer() const;
2018-10-28 21:53:21 +01:00
/*! change the players "new adventurere" status */
void setNewAdventurer( bool state );
2018-10-28 21:53:21 +01:00
/*! sets the list of current online status */
void setOnlineStatusMask( uint64_t status );
/*! sets the list of current online status */
void setOnlineStatusCustomMask( uint64_t status );
/*! returns the current online status */
uint64_t getOnlineStatusCustomMask() const;
void addOnlineStatus( Common::OnlineStatus status );
void addOnlineStatus( const std::vector< Common::OnlineStatus >& status );
void removeOnlineStatus( Common::OnlineStatus status );
void removeOnlineStatus( const std::vector< Common::OnlineStatus >& status );
2018-10-28 21:53:21 +01:00
/*! returns the current online status */
uint64_t getOnlineStatusMask() const;
uint64_t getFullOnlineStatusMask() const;
2018-10-28 21:53:21 +01:00
/*! perform a teleport of a specified type ( teleport,return,aethernet ) */
void teleport( uint16_t aetheryteId, uint8_t type = 1 );
2018-10-28 21:53:21 +01:00
/*! query teleport of a specified type */
2019-02-08 21:20:53 +11:00
void teleportQuery( uint16_t aetheryteId );
Common::PlayerTeleportQuery getTeleportQuery() const;
void clearTeleportQuery();
2020-03-16 01:35:49 -07:00
void setDyeingInfo( uint32_t itemToDyeContainer, uint32_t itemToDyeSlot, uint32_t dyeBagContainer, uint32_t dyeBagSlot );
void dyeItemFromDyeingInfo();
2018-10-28 21:53:21 +01:00
/*! prepares zoning / fades out the screen */
void prepareZoning( uint16_t targetZone, bool fadeOut, uint8_t fadeOutTime = 0, uint16_t animation = 0 );
2018-10-28 21:53:21 +01:00
/*! get player's title list (available titles) */
TitleList& getTitleList();
2018-10-28 21:53:21 +01:00
/*! get player's active title */
uint16_t getTitle() const;
2018-10-28 21:53:21 +01:00
/*! add title to player title list */
void addTitle( uint16_t titleId );
2018-10-28 21:53:21 +01:00
/*! change player's active title */
void setTitle( uint16_t titleId );
2018-10-28 21:53:21 +01:00
/*! send the players title list */
void sendTitleList();
2018-10-28 21:53:21 +01:00
/*! change gear param state */
void setEquipDisplayFlags( uint16_t state );
2018-10-28 21:53:21 +01:00
/*! get gear param state */
uint8_t getEquipDisplayFlags() const;
/*! mount the specified setMount and send the packets */
void setMount( uint32_t mountId );
void setCompanion( uint16_t id );
uint16_t getCurrentCompanion() const;
/*! get the current setMount */
uint8_t getCurrentMount() const;
2018-10-28 21:53:21 +01:00
/*! set current persistent emote */
void setPersistentEmote( uint32_t emoteId );
2018-10-28 21:53:21 +01:00
/*! get current persistent emote */
uint32_t getPersistentEmote() const;
2018-10-28 21:53:21 +01:00
void calculateStats() override;
2018-10-28 21:53:21 +01:00
void sendStats();
2018-10-28 21:53:21 +01:00
// Aetheryte / Action / Attribute bitmasks
//////////////////////////////////////////////////////////////////////////////////////////////////////
/*! register aetheryte aetheryteId and send update */
void registerAetheryte( uint8_t aetheryteId );
2018-10-28 21:53:21 +01:00
/*! check if aetheryte is already registered */
bool isAetheryteRegistered( uint8_t aetheryteId ) const;
2018-10-28 21:53:21 +01:00
/*! return a const pointer to the aetheryte unlock bitmask array */
uint8_t getAetheryteMaskAt( uint8_t index ) const;
2018-10-28 21:53:21 +01:00
/*! return a pointer to the aetheryte unlock bitmask array */
AetheryteList& getAetheryteArray();
2018-10-28 21:53:21 +01:00
/*! set homepoint */
void setHomepoint( uint8_t aetheryteId );
2018-10-28 21:53:21 +01:00
/*! get homepoint */
uint8_t getHomepoint() const;
2018-10-28 21:53:21 +01:00
/*! discover subarea subid fo map map_id, also send udpate packet */
void discover( int16_t map_id, int16_t sub_id );
2018-10-28 21:53:21 +01:00
/*! return a pointer to the discovery bitmask array */
Discovery& getDiscoveryBitmask();
2018-10-28 21:53:21 +01:00
/*! helper/debug function to reset all discovered areas */
void resetDiscovery();
2018-10-28 21:53:21 +01:00
/*! get a pointer to the howto bitmask array */
HowToList& getHowToArray();
2018-10-28 21:53:21 +01:00
/*! update bitmask for how-to's seen */
void updateHowtosSeen( uint32_t howToId );
2018-10-28 21:53:21 +01:00
/*! learn an action / update the unlock bitmask. */
void learnAction( Common::UnlockEntry unlockId );
2018-10-28 21:53:21 +01:00
/*! learn a song / update the unlock bitmask. */
void learnSong( uint8_t songId, uint32_t itemId );
2018-10-28 21:53:21 +01:00
/*! check if an action is already unlocked in the bitmask. */
bool isActionLearned( Common::UnlockEntry unlockId ) const;
2018-10-28 21:53:21 +01:00
/*! return a const pointer to the unlock bitmask array */
const UnlockList& getUnlockBitmask() const;
2018-10-28 21:53:21 +01:00
/*! return a const pointer to the orchestrion bitmask array */
const OrchestrionList& getOrchestrionBitmask() const;
/*! return a const pointer to the setMount guide bitmask array */
MountList& getMountGuideBitmask();
2021-08-30 10:16:05 +02:00
2020-01-05 17:09:27 +09:00
bool checkAction() override;
bool hasQueuedAction() const;
void setQueuedAction( World::Action::ActionPtr pAction );
void setLastActionTick( uint64_t tick );
uint64_t getLastActionTick() const;
void setRecastGroup( uint8_t index, float time );
float getRecastGroup( uint8_t index ) const;
void sendRecastGroups();
void resetRecastGroups();
2018-10-28 21:53:21 +01:00
// Spawn handling
//////////////////////////////////////////////////////////////////////////////////////////////////////
/*! initialize the spawnId queue */
void initSpawnIdQueue();
2018-10-28 21:53:21 +01:00
/*! get the spawn id mapped to a specific actorId */
uint8_t getSpawnIdForActorId( uint32_t actorId );
2018-10-28 21:53:21 +01:00
/*! frees the spawnId assigned to the given actor */
void freePlayerSpawnId( uint32_t actorId );
2018-10-28 21:53:21 +01:00
/*! checks if the given spawn id is valid */
bool isActorSpawnIdValid( uint8_t spawnId );
2018-10-28 21:53:21 +01:00
/*! send spawn packets to pTarget */
void spawn( PlayerPtr pTarget ) override;
2018-10-28 21:53:21 +01:00
/*! send despawn packets to pTarget */
void despawn( PlayerPtr pTarget ) override;
2018-10-28 21:53:21 +01:00
// Player State Handling
//////////////////////////////////////////////////////////////////////////////////////////////////////
/* return a const pointer to the state flag array */
const StateFlags& getStateFlags() const;
2018-10-28 21:53:21 +01:00
/* set a specified state flag */
void setStateFlag( Common::PlayerStateFlag flag );
2018-10-28 21:53:21 +01:00
/* set a specified state flag */
void setStateFlags( std::vector< Common::PlayerStateFlag > flags );
2018-10-28 21:53:21 +01:00
/* check if a specified flag is set */
bool hasStateFlag( Common::PlayerStateFlag flag ) const;
2018-10-28 21:53:21 +01:00
/* reset a specified flag */
void unsetStateFlag( Common::PlayerStateFlag flag );
2018-10-28 21:53:21 +01:00
/*! return the userlevel */
uint8_t getUserLevel() const;
2018-10-28 21:53:21 +01:00
// Player Database Handling
//////////////////////////////////////////////////////////////////////////////////////////////////////
/*! generate the update sql based on update flags */
void updateSql();
/*! initialize player data from db, by character id */
bool loadFromDb( uint64_t characterId );
/*! unload player from logout */
void unload();
2018-10-28 21:53:21 +01:00
/*! load active class data */
bool loadClassData();
2018-10-28 21:53:21 +01:00
/*! load search info */
bool loadSearchInfo();
2019-03-26 00:04:27 +01:00
/*! load hunting log entries */
bool loadHuntingLog();
/*! load friendlist */
2021-12-13 22:36:29 -03:00
bool loadFriendList();
/*! load blacklist */
bool loadBlacklist();
/*! update latest sync with db */
bool syncLastDBWrite();
/*! get latest db write timestamp */
uint64_t getLastDBWrite() const;
2018-10-28 21:53:21 +01:00
// Player Network Handling
//////////////////////////////////////////////////////////////////////////////////////////////////////
/*! send current models ( equipment ) */
void sendModel();
2018-10-28 21:53:21 +01:00
/*! send active state flags */
void sendStateFlags( bool updateInRange = true );
2018-10-28 21:53:21 +01:00
/*! send status update */
void sendStatusUpdate() override;
2018-10-28 21:53:21 +01:00
/*! send the entire inventory sequence */
void sendInventory();
2018-10-28 21:53:21 +01:00
/*! returns true if loading is complete ( 0x69 has been received ) */
bool isLoadingComplete() const;
2018-10-28 21:53:21 +01:00
/*! set the loading complete bool */
void setLoadingComplete( bool bComplete );
2018-10-28 21:53:21 +01:00
/*! mark this player for zoning, notify worldserver */
void performZoning( uint16_t zoneId, const Common::FFXIVARR_POSITION3& pos, float rotation );
2018-10-28 21:53:21 +01:00
/*! return true if the player is marked for zoning */
bool isMarkedForZoning() const;
2018-10-28 21:53:21 +01:00
void sendZoneInPackets( uint32_t param1, uint32_t param2, uint32_t param3, uint32_t param4, bool pSetStatus );
2018-10-28 21:53:21 +01:00
void finishZoning();
2018-10-28 21:53:21 +01:00
void sendZonePackets();
2018-10-28 21:53:21 +01:00
Common::ZoneingType getZoningType() const;
2018-10-28 21:53:21 +01:00
void setZoningType( Common::ZoneingType zoneingType );
2018-10-28 21:53:21 +01:00
void setSearchInfo( uint8_t selectRegion, uint8_t selectClass, const char* searchMessage );
2018-10-28 21:53:21 +01:00
const char* getSearchMessage() const;
2018-10-28 21:53:21 +01:00
uint8_t getSearchSelectRegion() const;
2018-10-28 21:53:21 +01:00
uint8_t getSearchSelectClass() const;
2018-10-28 21:53:21 +01:00
bool isDirectorInitialized() const;
2018-10-28 21:53:21 +01:00
void setDirectorInitialized( bool isInitialized );
2018-11-07 11:59:59 +01:00
// Housing Handling
//////////////////////////////////////////////////////////////////////////////////////////////////////
2018-12-21 22:23:49 +11:00
void setLandFlags( uint8_t permissionSet, uint32_t landFlags, Common::LandIdent ident );
2018-11-07 11:59:59 +01:00
2018-11-27 23:12:26 +11:00
void sendLandFlags();
void sendLandFlagsSlot( Common::LandFlagsSlot slot );
2018-11-07 11:59:59 +01:00
2018-10-28 21:53:21 +01:00
// Player Battle Handling
//////////////////////////////////////////////////////////////////////////////////////////////////////
void initHateSlotQueue();
void hateListAdd( const BNpc &bnpc );
void hateListRemove( const BNpc &bnpc );
2019-01-19 22:56:07 +01:00
bool hateListHasEntry( const BNpc &bnpc );
const std::map< uint32_t, uint8_t >& getActorIdToHateSlotMap();
Sapphire::Entity::GameObjectPtr lookupTargetById( uint64_t targetId );
2018-10-28 21:53:21 +01:00
bool isLogin() const;
2018-10-28 21:53:21 +01:00
void setIsLogin( bool bIsLogin );
uint32_t getPrevTerritoryId() const;
2018-10-28 21:53:21 +01:00
uint8_t getGmRank() const;
2018-10-28 21:53:21 +01:00
void setGmRank( uint8_t rank );
2018-10-28 21:53:21 +01:00
bool getGmInvis() const;
2018-10-28 21:53:21 +01:00
void setGmInvis( bool invis );
2018-10-28 21:53:21 +01:00
bool isActingAsGm() const;
2018-10-28 21:53:21 +01:00
uint8_t getMode() const;
2018-10-28 21:53:21 +01:00
void setMode( uint8_t mode );
2018-10-28 21:53:21 +01:00
void setAutoattack( bool mode );
2018-10-28 21:53:21 +01:00
bool isAutoattackOn() const;
void onMobAggro( const BNpc& bnpc );
void onMobDeaggro( const BNpc& bnpc );
2019-01-19 22:56:07 +01:00
2018-10-28 21:53:21 +01:00
// Content Finder handling
//////////////////////////////////////////////////////////////////////////////////////////////////////
/*! Get an unix time when the player can register into content finder again. */
uint32_t getCFPenaltyTimestamp() const;
2018-10-28 21:53:21 +01:00
/*! Set an unix time when the player can register into content finder again. */
void setCFPenaltyTimestamp( uint32_t timestamp );
2018-10-28 21:53:21 +01:00
uint32_t getCFPenaltyMinutes() const;
2018-10-28 21:53:21 +01:00
void setCFPenaltyMinutes( uint32_t minutes );
2018-10-28 21:53:21 +01:00
void setEorzeaTimeOffset( uint64_t timestamp );
//////////////////////////////////////////////////////////////////////////////////////////////////////
2018-10-28 21:53:21 +01:00
// Database
void updateDbAllQuests() const;
void deleteDbQuest( uint16_t questId ) const;
void insertDbQuest( uint16_t questId, uint8_t index, uint8_t seq ) const;
void insertDbQuest( const World::Quest& quest, uint8_t index ) const;
2018-10-28 21:53:21 +01:00
void updateDbSearchInfo() const;
2018-10-28 21:53:21 +01:00
void updateDbClass() const;
void insertDbClass( const uint8_t classJobIndex, uint8_t level = 1 ) const;
void updateDbMonsterNote();
void updateDbFriendList();
2021-12-13 22:36:29 -03:00
void updateDbBlacklist();
void updateDbChara() const;
///////////////////////////////////////////////////////////////////////////////////////////////////
void setMarkedForRemoval( bool removal = true );
2018-10-28 21:53:21 +01:00
bool isMarkedForRemoval() const;
2018-10-28 21:53:21 +01:00
void setOnEnterEventDone( bool isDone );
2018-10-28 21:53:21 +01:00
bool isOnEnterEventDone() const;
2018-10-28 21:53:21 +01:00
/*! gets the next available obj count */
uint8_t getNextObjSpawnIndexForActorId( uint32_t actorId );
2018-10-28 21:53:21 +01:00
/*! resets the players obj count */
void resetObjSpawnIndex();
2018-10-28 21:53:21 +01:00
/*! frees an obj count to be used by another eobj */
void freeObjSpawnIndexForActorId( uint32_t actorId );
2018-10-28 21:53:21 +01:00
/*! checks if a spawn index is valid */
bool isObjSpawnIndexValid( uint8_t index );
2018-10-28 21:53:21 +01:00
// Inventory Handling
//////////////////////////////////////////////////////////////////////////////////////////////////////
void initInventory();
2018-10-28 21:53:21 +01:00
using InvSlotPair = std::pair< uint16_t, int8_t >;
using InvSlotPairVec = std::vector< InvSlotPair >;
ItemPtr createItem( uint32_t catalogId, uint32_t quantity = 1 );
2018-10-28 21:53:21 +01:00
bool loadInventory();
2018-10-28 21:53:21 +01:00
InvSlotPairVec getSlotsOfItemsInInventory( uint32_t catalogId );
2018-10-28 21:53:21 +01:00
InvSlotPair getFreeBagSlot();
Sapphire::ItemPtr addItem( uint32_t catalogId, uint32_t quantity = 1, bool isHq = false, bool slient = false, bool canMerge = true );
void moveItem( uint16_t fromInventoryId, uint16_t fromSlotId, uint16_t toInventoryId, uint16_t toSlot );
void swapItem( uint16_t fromInventoryId, uint16_t fromSlotId, uint16_t toInventoryId, uint16_t toSlot );
void discardItem( uint16_t fromInventoryId, uint16_t fromSlotId );
void splitItem( uint16_t fromInventoryId, uint16_t fromSlotId, uint16_t toInventoryId, uint16_t toSlot,
2018-10-28 21:53:21 +01:00
uint16_t splitCount );
void mergeItem( uint16_t fromInventoryId, uint16_t fromSlotId, uint16_t toInventoryId, uint16_t toSlot );
ItemPtr getItemAt( uint16_t containerId, uint16_t slotId );
bool updateContainer( uint16_t storageId, uint16_t slotId, ItemPtr pItem );
2018-10-28 21:53:21 +01:00
/*! calculate and return player ilvl based off equipped gear */
uint16_t calculateEquippedGearItemLevel();
ItemPtr getEquippedWeapon();
2018-10-28 21:53:21 +01:00
/*! return the current amount of currency of type */
uint32_t getCurrency( Common::CurrencyType type );
2018-10-28 21:53:21 +01:00
void writeInventory( Common::InventoryType type );
void writeItem( ItemPtr pItem ) const;
2018-10-28 21:53:21 +01:00
void deleteItemDb( ItemPtr pItem ) const;
2018-10-28 21:53:21 +01:00
/*! return the crystal amount of currency of type */
uint32_t getCrystal( Common::CrystalType type );
2018-10-28 21:53:21 +01:00
/*! add amount to the crystal of type */
void addCrystal( Common::CrystalType type, uint32_t amount );
2018-10-28 21:53:21 +01:00
/*! remove amount from the crystals of type */
void removeCrystal( Common::CrystalType type, uint32_t amount );
2018-10-28 21:53:21 +01:00
bool isObtainable( uint32_t catalogId, uint8_t quantity );
uint32_t getNextInventorySequence();
2018-12-30 17:44:03 +11:00
bool findFirstItemWithId( uint32_t catalogId, Inventory::InventoryContainerPair& location );
uint16_t getFreeSlotsInBags();
2018-11-10 19:00:13 +01:00
void setActiveLand( uint8_t land, uint8_t ward );
Common::ActiveLand getActiveLand() const;
Sapphire::ItemPtr dropInventoryItem( Common::InventoryType storageId, uint8_t slotId );
2018-12-26 18:11:18 +11:00
2020-04-24 19:24:04 +09:00
//////////////////////////////////////////////////////////////////////////////////////////////////////
using FriendListIDVec = std::array< uint64_t, 200 >;
using FriendListDataVec = std::array< Common::HierarchyData, 200 >;
2021-12-13 22:36:29 -03:00
using BlacklistIDVec = std::array< uint64_t, 200 >;
2019-03-26 00:04:27 +01:00
Common::HuntingLogEntry& getHuntingLogEntry( uint8_t index );
2018-11-10 19:00:13 +01:00
void sendHuntingLog();
void updateHuntingLog( uint16_t id );
uint64_t getPartyId() const;
void setPartyId( uint64_t partyId );
FriendListIDVec& getFriendListID();
FriendListDataVec& getFriendListData();
2021-12-13 22:36:29 -03:00
BlacklistIDVec& getBlacklistID();
uint64_t m_lastMoveTime{};
uint8_t m_lastMoveflag{};
void setFalling( bool state, const Common::FFXIVARR_POSITION3& pos, bool ignoreDamage = false );
bool isFalling() const;
// todo: sort this requestkey pcsearch mess
void setLastPcSearchResult( std::vector< uint32_t > result );
std::vector< uint32_t >& getLastPcSearchResult();
const Common::FFXIVARR_POSITION3& getPrevPos() const;
float getPrevRot() const;
2018-10-28 21:53:21 +01:00
private:
/*! queue a packet for the player */
void queuePacket( Network::Packets::FFXIVPacketBasePtr pPacket );
using InventoryMap = std::map< uint16_t, Sapphire::ItemContainerPtr >;
2017-08-08 13:53:47 +02:00
uint64_t m_lastDBWrite;
2018-10-28 21:53:21 +01:00
bool m_bIsLogin;
2017-08-08 13:53:47 +02:00
uint64_t m_characterId; // This id will be the name of the folder for character settings in "My Games"
2017-08-08 13:53:47 +02:00
uint8_t m_mode{};
2017-08-08 13:53:47 +02:00
// falling logic
bool m_falling;
Common::FFXIVARR_POSITION3 m_initialFallPos{};
2018-10-28 21:53:21 +01:00
bool m_markedForRemoval;
2018-10-28 21:53:21 +01:00
bool m_directorInitialized;
2018-10-28 21:53:21 +01:00
bool m_onEnterEventDone;
2018-02-24 23:53:32 +01:00
uint32_t m_inventorySequence{};
2020-01-05 17:09:27 +09:00
World::Action::ActionPtr m_pQueuedAction;
uint64_t m_lastActionTick;
float m_recast[80]{};
float m_recastMax[80]{};
2018-10-28 21:53:21 +01:00
InventoryMap m_storageMap;
Common::FFXIVARR_POSITION3 m_prevPos{};
uint32_t m_prevTerritoryTypeId{};
uint32_t m_prevTerritoryId{};
float m_prevRot{};
uint8_t m_voice{};
2018-10-28 21:53:21 +01:00
uint64_t m_modelMainWeapon;
uint64_t m_modelSubWeapon;
uint64_t m_modelSystemWeapon{};
bool m_bNewGame{};
uint8_t m_guardianDeity{};
uint8_t m_birthDay{};
uint8_t m_birthMonth{};
2018-10-28 21:53:21 +01:00
struct RetainerInfo
{
uint32_t retainerId;
char retainerName[32];
uint32_t createUnixTime;
bool isActive;
bool isRename;
uint8_t status;
} m_retainerInfo[8]{};
uint16_t m_activeTitle{};
TitleList m_titleList{};
HowToList m_howTo{};
MinionList m_minions{};
MountList m_mountGuide{};
QuestComplete m_questCompleteFlags{};
Discovery m_discovery{};
AetheryteList m_aetheryte{};
UnlockList m_unlocks{};
OrchestrionList m_orchestrion{};
ClassList m_classArray{};
ExpList m_expArray{};
StateFlags m_stateFlags{};
2018-10-28 21:53:21 +01:00
uint8_t m_homePoint;
uint8_t m_startTown;
uint16_t m_townWarpFstFlags;
uint32_t m_playTime;
uint8_t m_openingSequence{0};
2018-10-28 21:53:21 +01:00
uint16_t m_itemLevel{0};
2018-10-28 21:53:21 +01:00
std::map< uint32_t, Event::EventHandlerPtr > m_eventHandlerMap;
std::queue< uint8_t > m_freeHateSlotQueue; // queue with "hate slots" free to be assigned
std::map< uint32_t, uint8_t > m_actorIdTohateSlotMap;
std::array< World::Quest, 30 > m_quests;
std::array< int16_t, 5 > m_questTracking{};
2018-10-28 21:53:21 +01:00
uint8_t m_gmRank{};
bool m_gmInvis{false};
2018-10-28 21:53:21 +01:00
uint8_t m_equipDisplayFlags{};
2018-10-28 21:53:21 +01:00
bool m_bInCombat;
bool m_bLoadingComplete;
bool m_bAutoattack;
Common::ZoneingType m_zoningType;
bool m_bMarkedForZoning;
bool m_bNewAdventurer{};
2018-10-28 21:53:21 +01:00
uint64_t m_onlineStatus;
uint64_t m_onlineStatusCustom;
2018-10-28 21:53:21 +01:00
std::shared_ptr< QueuedZoning > m_queuedZoneing;
// search info
char m_searchMessage[193]{}; // searchmessage to show in profile
uint8_t m_searchSelectRegion{}; // regions selected to show up in profile
uint8_t m_searchSelectClass{}; // class selected to show up in profile
// shop info
std::deque< std::pair< uint32_t, uint8_t > > m_soldItems;
2018-10-28 21:53:21 +01:00
2018-11-07 11:59:59 +01:00
// housing info
Common::CharaLandData m_charaLandData[2]{};
2018-11-10 19:00:13 +01:00
Common::ActiveLand m_activeLand{};
2018-11-07 11:59:59 +01:00
2018-10-28 21:53:21 +01:00
// gc info
uint8_t m_gc{};
std::array< uint8_t, 3 > m_gcRank{};
2018-10-28 21:53:21 +01:00
// content finder info
uint32_t m_cfPenaltyUntil{}; // unix time
2018-10-28 21:53:21 +01:00
uint16_t m_companionId{};
2018-10-28 21:53:21 +01:00
uint32_t m_mount;
uint32_t m_emoteMode;
Common::PlayerTeleportQuery m_teleportQuery{};
2019-02-08 21:20:53 +11:00
struct PlayerDyeingInfo
{
uint32_t itemToDyeContainer;
uint32_t itemToDyeSlot;
uint32_t dyeBagContainer;
uint32_t dyeBagSlot;
} m_dyeingInfo{};
Common::Util::SpawnIndexAllocator< uint8_t > m_objSpawnIndexAllocator;
Common::Util::SpawnIndexAllocator< uint8_t > m_actorSpawnIndexAllocator;
2019-03-26 00:04:27 +01:00
std::array< Common::HuntingLogEntry, 12 > m_huntingLogEntries{};
FriendListIDVec m_friendList{};
FriendListDataVec m_friendInviteList{};
2021-12-13 22:36:29 -03:00
BlacklistIDVec m_blacklist{};
uint64_t m_partyId;
std::vector< uint32_t > m_lastPcSearch;
2017-08-08 13:53:47 +02:00
bool addQuest( const World::Quest& quest );
void addQuestTracking( uint8_t idx );
void removeQuestTracking( int8_t idx );
int8_t getFreeQuestSlot();
};
2017-08-08 13:53:47 +02:00
}