diff --git a/src/scripts/action/common/ActionDye2472.cpp b/src/scripts/action/common/ActionDye2472.cpp index b1049a8d..0b3d33f7 100644 --- a/src/scripts/action/common/ActionDye2472.cpp +++ b/src/scripts/action/common/ActionDye2472.cpp @@ -3,12 +3,10 @@ #include #include -class ActionDye2472 : - public Sapphire::ScriptAPI::ActionScript +class ActionDye2472 : public Sapphire::ScriptAPI::ActionScript { public: - ActionDye2472() : - Sapphire::ScriptAPI::ActionScript( 2472 ) + ActionDye2472() : Sapphire::ScriptAPI::ActionScript( 2472 ) { } diff --git a/src/scripts/action/common/ActionGlamour2471.cpp b/src/scripts/action/common/ActionGlamour2471.cpp index 6599c96d..3629a7f4 100644 --- a/src/scripts/action/common/ActionGlamour2471.cpp +++ b/src/scripts/action/common/ActionGlamour2471.cpp @@ -3,12 +3,10 @@ #include #include -class ActionGlamour2471 : - public Sapphire::ScriptAPI::ActionScript +class ActionGlamour2471 : public Sapphire::ScriptAPI::ActionScript { public: - ActionGlamour2471() : - Sapphire::ScriptAPI::ActionScript( 2471 ) + ActionGlamour2471() : Sapphire::ScriptAPI::ActionScript( 2471 ) { } diff --git a/src/scripts/action/common/ActionReturn6.cpp b/src/scripts/action/common/ActionReturn6.cpp index 06841c94..22c0bac4 100644 --- a/src/scripts/action/common/ActionReturn6.cpp +++ b/src/scripts/action/common/ActionReturn6.cpp @@ -5,12 +5,10 @@ #include #include -class ActionReturn6 : - public Sapphire::ScriptAPI::ActionScript +class ActionReturn6 : public Sapphire::ScriptAPI::ActionScript { public: - ActionReturn6() : - Sapphire::ScriptAPI::ActionScript( 6 ) + ActionReturn6() : Sapphire::ScriptAPI::ActionScript( 6 ) { } diff --git a/src/scripts/action/common/ActionSprint3.cpp b/src/scripts/action/common/ActionSprint3.cpp index aea3c57f..82bf80fb 100644 --- a/src/scripts/action/common/ActionSprint3.cpp +++ b/src/scripts/action/common/ActionSprint3.cpp @@ -5,8 +5,7 @@ class ActionSprint3 : public Sapphire::ScriptAPI::ActionScript { public: - ActionSprint3() : - Sapphire::ScriptAPI::ActionScript( 3 ) + ActionSprint3() : Sapphire::ScriptAPI::ActionScript( 3 ) { } diff --git a/src/scripts/action/common/ActionTeleport5.cpp b/src/scripts/action/common/ActionTeleport5.cpp index 8f6d8d93..954ab746 100644 --- a/src/scripts/action/common/ActionTeleport5.cpp +++ b/src/scripts/action/common/ActionTeleport5.cpp @@ -5,12 +5,10 @@ using namespace Sapphire; -class ActionTeleport5 : - public Sapphire::ScriptAPI::ActionScript +class ActionTeleport5 : public Sapphire::ScriptAPI::ActionScript { public: - ActionTeleport5() : - Sapphire::ScriptAPI::ActionScript( 5 ) + ActionTeleport5() : Sapphire::ScriptAPI::ActionScript( 5 ) { } diff --git a/src/scripts/quest/ManFst303.cpp b/src/scripts/quest/ManFst303.cpp index 8cd58274..af46ad24 100644 --- a/src/scripts/quest/ManFst303.cpp +++ b/src/scripts/quest/ManFst303.cpp @@ -101,8 +101,7 @@ private: void Scene00001Return( World::Quest& quest, Entity::Player& player, const Event::SceneResult& result ) { - playerMgr().setGrandCompany( player, OrderOfTwinAdder ); - playerMgr().setGrandCompanyRank( player, OrderOfTwinAdder, 1 ); + player.setGrandCompany( OrderOfTwinAdder ); Scene00002( quest, player ); } diff --git a/src/world/Action/Action.cpp b/src/world/Action/Action.cpp index 69930322..a9a31ffb 100644 --- a/src/world/Action/Action.cpp +++ b/src/world/Action/Action.cpp @@ -23,6 +23,7 @@ #include "Network/PacketWrappers/ActorControlPacket.h" #include "Network/PacketWrappers/ActorControlSelfPacket.h" #include "Network/PacketWrappers/ActorControlTargetPacket.h" +#include "Network/Util/PlayerUtil.h" #include @@ -517,7 +518,8 @@ void Action::Action::buildEffects() return; } - playerMgr().onHudParamChanged( *m_pSource->getAsPlayer() ); + + Network::Util::Player::sendHudParam( *m_pSource->getAsPlayer() ); if( !hasLutEntry || m_hitActors.empty() ) { diff --git a/src/world/Actor/Player.cpp b/src/world/Actor/Player.cpp index d8fe7301..2161b2f2 100644 --- a/src/world/Actor/Player.cpp +++ b/src/world/Actor/Player.cpp @@ -34,6 +34,8 @@ #include "Network/PacketWrappers/EffectPacket1.h" #include "Network/PacketWrappers/InitZonePacket.h" +#include "Network/Util/PlayerUtil.h" + #include "Action/Action.h" #include "Math/CalcStats.h" @@ -261,7 +263,7 @@ void Player::addOnlineStatus( OnlineStatus status ) setOnlineStatusMask( newFlags ); - Service< World::Manager::PlayerMgr >::ref().onOnlineStatusChanged( *this, false ); + Network::Util::Player::sendOnlineStatus( *this ); } void Player::addOnlineStatus( const std::vector< Common::OnlineStatus >& status ) @@ -275,7 +277,7 @@ void Player::addOnlineStatus( const std::vector< Common::OnlineStatus >& status setOnlineStatusMask( newFlags ); - Service< World::Manager::PlayerMgr >::ref().onOnlineStatusChanged( *this, false ); + Network::Util::Player::sendOnlineStatus( *this ); } void Player::removeOnlineStatus( OnlineStatus status ) @@ -289,7 +291,7 @@ void Player::removeOnlineStatus( OnlineStatus status ) setOnlineStatusMask( newFlags ); setOnlineStatusCustomMask( newFlagsCustom ); - Service< World::Manager::PlayerMgr >::ref().onOnlineStatusChanged( *this, false ); + Network::Util::Player::sendOnlineStatus( *this ); } void Player::removeOnlineStatus( const std::vector< Common::OnlineStatus >& status ) @@ -306,7 +308,7 @@ void Player::removeOnlineStatus( const std::vector< Common::OnlineStatus >& stat setOnlineStatusMask( newFlags ); setOnlineStatusCustomMask( newFlagsCustom ); - Service< World::Manager::PlayerMgr >::ref().onOnlineStatusChanged( *this, false ); + Network::Util::Player::sendOnlineStatus( *this ); } void Player::calculateStats() @@ -394,11 +396,6 @@ bool Player::isAutoattackOn() const return m_bAutoattack; } -void Player::sendStats() -{ - Service< World::Manager::PlayerMgr >::ref().onStatsChanged( *this ); -} - bool Player::exitInstance() { auto& warpMgr = Common::Service< WarpMgr >::ref(); @@ -459,7 +456,7 @@ void Player::registerAetheryte( uint8_t aetheryteId ) Util::valueToFlagByteIndexValue( aetheryteId, value, index ); m_aetheryte[ index ] |= value; - server().queueForPlayer( getCharacterId(), makeActorControlSelf( getId(), LearnTeleport, aetheryteId, 1 ) ); + Network::Util::Player::sendActorControlSelf( *this, LearnTeleport, aetheryteId, 1 ); } bool Player::isAetheryteRegistered( uint8_t aetheryteId ) const @@ -476,48 +473,43 @@ Player::Discovery& Player::getDiscoveryBitmask() return m_discovery; } -void Player::discover( int16_t map_id, int16_t sub_id ) +void Player::discover( int16_t mapId, int16_t subId ) { - // map.exd field 12 -> index in one of the two discovery sections, if field 15 is false, need to use 2nd section - // section 1 starts at 0 - 2 bytes each - // section to starts at 320 - 4 bytes long - auto& exdData = Common::Service< Data::ExdData >::ref(); int32_t offset; - auto info = exdData.getRow< Excel::Map >( map_id ); + auto info = exdData.getRow< Excel::Map >( mapId ); if( !info ) { - PlayerMgr::sendDebug( *this, "discover(): Could not obtain map data for map_id == {0}", map_id ); + PlayerMgr::sendDebug( *this, "discover(): Could not obtain map data for map_id == {0}", mapId ); return; } - if( info->data().IsUint16Discovery ) - offset = 2 * info->data().DiscoveryIndex; + const auto& mapData = info->data(); + + if( mapData.IsUint16Discovery ) + offset = 2 * mapData.DiscoveryIndex; else - offset = 320 + 4 * info->data().DiscoveryIndex; + offset = 320 + 4 * mapData.DiscoveryIndex; - int32_t index = offset + sub_id / 8; - uint8_t bitIndex = sub_id % 8; + uint16_t index; + uint8_t value; + Util::valueToFlagByteIndexValue( subId, value, index ); - uint8_t value = 1 << bitIndex; - - m_discovery[ index ] |= value; + m_discovery[ offset + index ] |= value; uint16_t level = getLevel(); uint32_t exp = ( exdData.getRow< Excel::ParamGrow >( level )->data().NextExp * 5 / 100 ); - gainExp( exp ); // gain 10x additional EXP if entire map is completed - uint32_t mask = info->data().DiscoveryFlag; + uint32_t mask = mapData.DiscoveryFlag; uint32_t discoveredAreas; if( info->data().IsUint16Discovery ) { - discoveredAreas = ( m_discovery[ offset + 1 ] << 8 ) | - m_discovery[ offset ]; + discoveredAreas = ( m_discovery[ offset + 1 ] << 8 ) | m_discovery[ offset ]; } else { @@ -567,7 +559,7 @@ void Player::setRewardFlag( Common::UnlockEntry unlockId ) m_unlocks[ index ] |= value; - server().queueForPlayer( getCharacterId(), makeActorControlSelf( getId(), SetRewardFlag, unlock, 1 ) ); + Network::Util::Player::sendActorControlSelf( *this, SetRewardFlag, unlock, 1 ); } void Player::learnSong( uint8_t songId, uint32_t itemId ) @@ -629,18 +621,19 @@ void Player::gainExp( uint32_t amount ) amount = ( currentExp + amount - neededExpToLevel ) > neededExpToLevelPlus1 ? neededExpToLevelPlus1 - 1 : ( currentExp + amount - neededExpToLevel ); + if( level + 1 >= Common::MAX_PLAYER_LEVEL ) amount = 0; setExp( amount ); - Service< World::Manager::PlayerMgr >::ref().onGainExp( *this, amount ); levelUp(); } else { setExp( currentExp + amount ); - Service< World::Manager::PlayerMgr >::ref().onGainExp( *this, amount ); } + + Service< World::Manager::PlayerMgr >::ref().onGainExp( *this, amount ); } void Player::levelUp() @@ -654,12 +647,6 @@ void Player::levelUp() Service< World::Manager::MapMgr >::ref().updateQuests( *this ); } -void Player::sendHudParam() -{ - // todo: overrides are funky - Service< World::Manager::PlayerMgr >::ref().onHudParamChanged( *this ); -} - uint8_t Player::getLevel() const { auto& exdData = Common::Service< Data::ExdData >::ref(); @@ -673,10 +660,10 @@ uint8_t Player::getLevelSync() const return getLevel(); } -uint8_t Player::getLevelForClass( Common::ClassJob pClass ) const +uint8_t Player::getLevelForClass( Common::ClassJob classJobId ) const { auto& exdData = Common::Service< Data::ExdData >::ref(); - uint8_t classJobIndex = exdData.getRow< Excel::ClassJob >( static_cast< uint8_t >( pClass ) )->data().WorkIndex; + uint8_t classJobIndex = exdData.getRow< Excel::ClassJob >( static_cast< uint8_t >( classJobId ) )->data().WorkIndex; return static_cast< uint8_t >( m_classArray[ classJobIndex ] ); } @@ -728,8 +715,9 @@ void Player::setClassJob( Common::ClassJob classJob ) m_tp = 0; - Service< World::Manager::PlayerMgr >::ref().sendStatusUpdate( *this ); - Service< World::Manager::PlayerMgr >::ref().onClassChanged( *this ); + Network::Util::Player::sendStatusUpdate( *this ); + server().queueForPlayers( getInRangePlayerIds( true ), makeActorControl( getId(), ClassJobChange, 0x04 ) ); + Network::Util::Player::sendHudParam( *this ); Service< World::Manager::MapMgr >::ref().updateQuests( *this ); } @@ -825,7 +813,7 @@ void Player::despawn( Entity::PlayerPtr pTarget ) Logger::debug( "Despawning {0} for {1}", getName(), pTarget->getName() ); pPlayer->freePlayerSpawnId( getId() ); - server().queueForPlayer( pTarget->getCharacterId(), makeActorControlSelf( getId(), WarpStart, 0x04, getId(), 0x01 ) ); + Network::Util::Player::sendActorControlSelf( *this, WarpStart, 4, getId(), 1 ); } GameObjectPtr Player::lookupTargetById( uint64_t targetId ) @@ -850,14 +838,18 @@ void Player::setVoiceId( uint8_t voiceId ) m_voice = voiceId; } -void Player::setGc( uint8_t gc ) +void Player::setGrandCompany( uint8_t gc ) { m_gc = gc; + if( m_gcRank[ gc ] == 0 ) + m_gcRank[ gc ] = 1; + Network::Util::Player::sendGrandCompany( *this ); } -void Player::setGcRankAt( uint8_t index, uint8_t rank ) +void Player::setGrandCompanyRankAt( uint8_t index, uint8_t rank ) { m_gcRank[ index ] = rank; + Network::Util::Player::sendGrandCompany( *this ); } const Player::Condition& Player::getConditions() const @@ -942,7 +934,7 @@ Player::AetheryteList& Player::getAetheryteArray() void Player::setHomepoint( uint8_t aetheryteId ) { m_homePoint = aetheryteId; - server().queueForPlayer( getCharacterId(), makeActorControlSelf( getId(), SetHomepoint, aetheryteId ) ); + Network::Util::Player::sendActorControlSelf( *this, SetHomepoint, aetheryteId ); } /*! get homepoint */ @@ -991,7 +983,7 @@ void Player::unlockMount( uint32_t mountId ) m_mountGuide[ mount->data().MountOrder / 8 ] |= ( 1 << ( mount->data().MountOrder % 8 ) ); - server().queueForPlayer( getCharacterId(), makeActorControlSelf( getId(), Network::ActorControl::SetMountBitmask, mount->data().MountOrder, 1 ) ); + Network::Util::Player::sendActorControlSelf( *this, SetMountBitmask, mount->data().MountOrder, 1 ); } void Player::unlockCompanion( uint32_t companionId ) @@ -1008,7 +1000,7 @@ void Player::unlockCompanion( uint32_t companionId ) m_minionGuide[ index ] |= value; - server().queueForPlayer( getCharacterId(), makeActorControlSelf( getId(), Network::ActorControl::LearnCompanion, companionId, 1 ) ); + Network::Util::Player::sendActorControlSelf( *this, LearnCompanion, companionId, 1 ); } Player::MinionList& Player::getMinionGuideBitmask() @@ -1199,8 +1191,7 @@ void Player::setAchievementData( const Player::AchievementData& achievementData void Player::setMaxGearSets( uint8_t amount ) { m_equippedMannequin = amount; - - server().queueForPlayer( getCharacterId(), makeActorControlSelf( getId(), SetMaxGearSets, m_equippedMannequin ) ); + Network::Util::Player::sendActorControlSelf( *this, SetMaxGearSets, m_equippedMannequin ); } void Player::addGearSet() @@ -1222,14 +1213,15 @@ uint8_t Player::getMaxGearSets() const return m_equippedMannequin; } -void Player::setEquipDisplayFlags( uint16_t state ) +void Player::setConfigFlags( uint16_t state ) { - m_equipDisplayFlags = static_cast< uint8_t >( state ); + m_configFlags = static_cast< uint8_t >( state ); + Network::Util::Player::sendConfigFlags( *this ); } -uint8_t Player::getEquipDisplayFlags() const +uint8_t Player::getConfigFlags() const { - return m_equipDisplayFlags; + return m_configFlags; } void Player::setMount( uint32_t mountId ) @@ -1379,46 +1371,38 @@ bool Player::isDirectorInitialized() const return m_directorInitialized; } -void Player::sendTitleList() -{ - auto titleListPacket = makeZonePacket< FFXIVIpcTitleList >( getId() ); - memcpy( titleListPacket->data().TitleFlagsArray, getTitleList().data(), sizeof( titleListPacket->data().TitleFlagsArray ) ); - - server().queueForPlayer( getCharacterId(), titleListPacket ); -} - void Player::teleportQuery( uint16_t aetheryteId ) { auto& exdData = Common::Service< Data::ExdData >::ref(); // TODO: only register this action if enough gil is in possession auto targetAetheryte = exdData.getRow< Excel::Aetheryte >( aetheryteId ); - if( targetAetheryte ) + if( !targetAetheryte ) + return; + + auto fromAetheryte = exdData.getRow< Excel::Aetheryte >( exdData.getRow< Excel::TerritoryType >( getTerritoryTypeId() )->data().Aetheryte ); + + // calculate cost - does not apply for favorite points or homepoints neither checks for aether tickets + auto cost = static_cast< uint16_t > ( + ( std::sqrt( std::pow( fromAetheryte->data().CostPosX - targetAetheryte->data().CostPosX, 2 ) + + std::pow( fromAetheryte->data().CostPosY - targetAetheryte->data().CostPosY, 2 ) ) / 2 ) + 100 ); + + // cap at 999 gil + cost = std::min< uint16_t >( 999, cost ); + + bool insufficientGil = getCurrency( Common::CurrencyType::Gil ) < cost; + Network::Util::Player::sendActorControlSelf( *this, OnExecuteTelepo, insufficientGil ? 2 : 0, aetheryteId ); + + if( !insufficientGil ) { - auto fromAetheryte = exdData.getRow< Excel::Aetheryte >( - exdData.getRow< Excel::TerritoryType >( getTerritoryTypeId() )->data().Aetheryte ); - - // calculate cost - does not apply for favorite points or homepoints neither checks for aether tickets - auto cost = static_cast< uint16_t > ( - ( std::sqrt( std::pow( fromAetheryte->data().CostPosX - targetAetheryte->data().CostPosX, 2 ) + - std::pow( fromAetheryte->data().CostPosY - targetAetheryte->data().CostPosY, 2 ) ) / 2 ) + 100 ); - - // cap at 999 gil - cost = std::min< uint16_t >( 999, cost ); - - bool insufficientGil = getCurrency( Common::CurrencyType::Gil ) < cost; - server().queueForPlayer( getCharacterId(), makeActorControlSelf( getId(), OnExecuteTelepo, insufficientGil ? 2 : 0, aetheryteId ) ); - - if( !insufficientGil ) - { - m_teleportQuery.targetAetheryte = aetheryteId; - m_teleportQuery.cost = cost; - } - else - { - clearTeleportQuery(); - } + m_teleportQuery.targetAetheryte = aetheryteId; + m_teleportQuery.cost = cost; } + else + { + clearTeleportQuery(); + } + } Sapphire::Common::PlayerTeleportQuery Player::getTeleportQuery() const @@ -1483,8 +1467,7 @@ void Player::dyeItemFromDyeingInfo() insertInventoryItem( static_cast< Sapphire::Common::InventoryType >( itemToDyeContainer ), static_cast< uint16_t >( itemToDyeSlot ), itemToDye ); writeItem( itemToDye ); - auto dyePkt = makeActorControlSelf( getId(), DyeMsg, itemToDye->getId(), shouldDye, invalidateGearSet ); - server().queueForPlayer( getCharacterId(), dyePkt ); + Network::Util::Player::sendActorControlSelf( *this, DyeMsg, itemToDye->getId(), shouldDye, invalidateGearSet ); } void Player::setGlamouringInfo( uint32_t itemToGlamourContainer, uint32_t itemToGlamourSlot, uint32_t glamourBagContainer, uint32_t glamourBagSlot, bool shouldGlamour ) @@ -1538,15 +1521,9 @@ void Player::glamourItemFromGlamouringInfo() writeItem( itemToGlamour ); if( shouldGlamour ) - { - auto castGlamPkt = makeActorControlSelf( getId(), GlamourCastMsg, itemToGlamour->getId(), glamourToUse->getId(), invalidateGearSet ); - server().queueForPlayer( getCharacterId(), castGlamPkt ); - } + Network::Util::Player::sendActorControlSelf( *this, GlamourCastMsg, itemToGlamour->getId(), glamourToUse->getId(), invalidateGearSet ); else - { - auto dispelGlamPkt = makeActorControlSelf( getId(), GlamourRemoveMsg, itemToGlamour->getId(), invalidateGearSet ); - server().queueForPlayer( getCharacterId(), dispelGlamPkt ); - } + Network::Util::Player::sendActorControlSelf( *this, GlamourRemoveMsg, itemToGlamour->getId(), invalidateGearSet ); } void Player::resetObjSpawnIndex() @@ -1597,50 +1574,6 @@ Sapphire::Common::HuntingLogEntry& Player::getHuntingLogEntry( uint8_t index ) return m_huntingLogEntries[ index ]; } -void Player::sendHuntingLog() -{ - auto& exdData = Common::Service< Data::ExdData >::ref(); - uint8_t count = 0; - for( const auto& entry : m_huntingLogEntries ) - { - uint64_t completionFlag = 0; - auto huntPacket = makeZonePacket< FFXIVIpcMonsterNoteCategory >( getId() ); - - huntPacket->data().contextId = -1; - huntPacket->data().currentRank = entry.rank; - huntPacket->data().categoryIndex = count; - - for( int i = 1; i <= 10; ++i ) - { - auto index0 = i - 1; - bool allComplete = true; - auto monsterNoteId = ( count + 1 ) * 10000 + entry.rank * 10 + i; - - auto monsterNote = exdData.getRow< Excel::MonsterNote >( monsterNoteId ); - if( !monsterNote ) - continue; - - const auto huntEntry = entry.entries[ index0 ]; - for( int x = 0; x < 3; ++x ) - { - if( ( huntEntry[ x ] == monsterNote->data().NeededKills[ x ] ) && monsterNote->data().NeededKills[ x ] != 0 ) - completionFlag |= ( 1ull << ( index0 * 5 + x ) ); - else if( monsterNote->data().NeededKills[ x ] != 0 ) - allComplete = false; - } - - if( allComplete ) - completionFlag |= ( 1ull << ( index0 * 5 + 4 ) ); - - } - - memcpy( huntPacket->data().killCount, entry.entries, sizeof( entry.entries ) ); - huntPacket->data().completeFlags = completionFlag; - ++count; - server().queueForPlayer( getCharacterId(), huntPacket ); - } -} - void Player::updateHuntingLog( uint16_t id ) { std::vector< uint32_t > rankRewards{ 2500, 10000, 20000, 30000, 40000 }; @@ -1677,7 +1610,7 @@ void Player::updateHuntingLog( uint16_t id ) if( note1->data().Monster == id && logEntry.entries[ i - 1 ][ x ] < note->data().NeededKills[ x ] ) { logEntry.entries[ i - 1 ][ x ]++; - server().queueForPlayer( getCharacterId(), makeActorControlSelf( getId(), HuntingLogEntryUpdate, monsterNoteId, x, logEntry.entries[ i - 1 ][ x ] ) ); + Network::Util::Player::sendActorControlSelf( *this, HuntingLogEntryUpdate, monsterNoteId, x, logEntry.entries[ i - 1 ][ x ] ); logChanged = true; sectionChanged = true; } @@ -1686,7 +1619,7 @@ void Player::updateHuntingLog( uint16_t id ) } if( logChanged && sectionComplete && sectionChanged ) { - server().queueForPlayer( getCharacterId(), makeActorControlSelf( getId(), HuntingLogSectionFinish, monsterNoteId, i, 0 ) ); + Network::Util::Player::sendActorControlSelf( *this, HuntingLogSectionFinish, monsterNoteId, i, 0 ); gainExp( note->data().RewardExp ); } if( !sectionComplete ) @@ -1696,18 +1629,18 @@ void Player::updateHuntingLog( uint16_t id ) } if( logChanged && allSectionsComplete ) { - server().queueForPlayer( getCharacterId(), makeActorControlSelf( getId(), HuntingLogRankFinish, 4, 0, 0 ) ); + Network::Util::Player::sendActorControlSelf( *this, HuntingLogRankFinish, 4 ); gainExp( rankRewards[ logEntry.rank ] ); if( logEntry.rank < 4 ) { logEntry.rank++; memset( logEntry.entries, 0, 40 ); - server().queueForPlayer( getCharacterId(), makeActorControlSelf( getId(), HuntingLogRankUnlock, currentClassId, logEntry.rank + 1, 0 ) ); + Network::Util::Player::sendActorControlSelf( *this, HuntingLogRankUnlock, currentClassId, logEntry.rank + 1, 0 ); } } if( logChanged ) - sendHuntingLog(); + Network::Util::Player::sendHuntingLog( *this ); } void Player::setActiveLand( uint8_t land, uint8_t ward ) @@ -1779,19 +1712,14 @@ bool Player::checkAction() if( m_pCurrentAction->update() ) { if( m_pCurrentAction->isInterrupted() && m_pCurrentAction->getInterruptType() != Common::ActionInterruptType::DamageInterrupt ) - { - // we moved (or whatever not damage interrupt) so we don't want to execute queued cast m_pQueuedAction = nullptr; - } m_pCurrentAction = nullptr; if( hasQueuedAction() ) { PlayerMgr::sendDebug( *this, "Queued skill start: {0}", m_pQueuedAction->getId() ); if( m_pQueuedAction->hasCastTime() ) - { setCurrentAction( m_pQueuedAction ); - } m_pQueuedAction->start(); m_pQueuedAction = nullptr; } diff --git a/src/world/Actor/Player.h b/src/world/Actor/Player.h index 71e01d92..a73cfd9c 100644 --- a/src/world/Actor/Player.h +++ b/src/world/Actor/Player.h @@ -214,7 +214,7 @@ namespace Sapphire::Entity uint8_t getLevelSync() const; /*! returns the level of the provided class / job */ - uint8_t getLevelForClass( Common::ClassJob pClass ) const; + uint8_t getLevelForClass( Common::ClassJob classJobId ) const; /*! \return the first class of the player */ Common::ClassJob getFirstClass() const; @@ -288,10 +288,10 @@ namespace Sapphire::Entity void setVoiceId( uint8_t voiceId ); /*! set the grand company */ - void setGc( uint8_t gc ); + void setGrandCompany( uint8_t gc ); /*! set the grand company rank */ - void setGcRankAt( uint8_t index, uint8_t rank ); + void setGrandCompanyRankAt( uint8_t index, uint8_t rank ); /*! returns true if the player is currently in combat */ bool isInCombat() const; @@ -372,9 +372,6 @@ namespace Sapphire::Entity /*! change player's active title */ void setTitle( uint16_t titleId ); - /*! send the players title list */ - void sendTitleList(); - /*! get player's achievement data */ const AchievementData& getAchievementData() const; @@ -391,10 +388,10 @@ namespace Sapphire::Entity uint8_t getMaxGearSets() const; /*! change gear param state */ - void setEquipDisplayFlags( uint16_t state ); + void setConfigFlags( uint16_t state ); /*! get gear param state */ - uint8_t getEquipDisplayFlags() const; + uint8_t getConfigFlags() const; /*! mount the specified setMount and send the packets */ void setMount( uint32_t mountId ); @@ -414,9 +411,6 @@ namespace Sapphire::Entity void calculateStats() override; - void sendStats(); - - // Aetheryte / Action / Attribute bitmasks ////////////////////////////////////////////////////////////////////////////////////////////////////// /*! register aetheryte aetheryteId and send update */ @@ -438,7 +432,7 @@ namespace Sapphire::Entity uint8_t getHomepoint() const; /*! discover subarea subid fo map map_id, also send udpate packet */ - void discover( int16_t map_id, int16_t sub_id ); + void discover( int16_t mapId, int16_t subId ); /*! return a reference to the discovery bitmask array */ Discovery& getDiscoveryBitmask(); @@ -583,9 +577,6 @@ namespace Sapphire::Entity /*! send current models ( equipment ) */ void sendModel(); - /*! send status update */ - void sendHudParam() override; - /*! send the entire inventory sequence */ void sendInventory(); @@ -735,22 +726,13 @@ namespace Sapphire::Entity InvSlotPair getFreeContainerSlot( uint32_t containerId ); ItemPtr addItem( uint32_t catalogId, uint32_t quantity = 1, bool isHq = false, bool slient = false, bool canMerge = true ); - bool removeItem( uint32_t catalogId, uint32_t quantity = 1, bool isHq = false ); - 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, - uint16_t splitCount ); - + void splitItem( uint16_t fromInventoryId, uint16_t fromSlotId, uint16_t toInventoryId, uint16_t toSlot, 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 ); /*! calculate and return player ilvl based off equipped gear */ @@ -803,8 +785,6 @@ namespace Sapphire::Entity Common::HuntingLogEntry& getHuntingLogEntry( uint8_t index ); - void sendHuntingLog(); - void updateHuntingLog( uint16_t id ); uint64_t getPartyId() const; @@ -930,7 +910,7 @@ namespace Sapphire::Entity uint8_t m_gmRank{}; bool m_gmInvis{false}; - uint8_t m_equipDisplayFlags{}; + uint8_t m_configFlags{}; bool m_bInCombat; bool m_bLoadingComplete; diff --git a/src/world/Actor/PlayerInventory.cpp b/src/world/Actor/PlayerInventory.cpp index ca5bcdf7..b8a848f1 100644 --- a/src/world/Actor/PlayerInventory.cpp +++ b/src/world/Actor/PlayerInventory.cpp @@ -18,6 +18,7 @@ #include "Network/PacketWrappers/ActorControlSelfPacket.h" #include "Network/PacketWrappers/UpdateInventorySlotPacket.h" #include +#include #include "Manager/InventoryMgr.h" #include "Manager/ItemMgr.h" @@ -231,8 +232,8 @@ void Sapphire::Entity::Player::equipItem( Common::GearSetSlot equipSlotId, Item& { sendModel(); sendItemLevel(); - sendStats(); - sendHudParam(); + Network::Util::Player::sendBaseParams( *this ); + Network::Util::Player::sendHudParam( *this ); } } @@ -253,8 +254,8 @@ void Sapphire::Entity::Player::unequipItem( Common::GearSetSlot equipSlotId, Ite { sendModel(); sendItemLevel(); - sendStats(); - sendHudParam(); + Network::Util::Player::sendBaseParams( *this ); + Network::Util::Player::sendHudParam( *this ); } } @@ -635,7 +636,7 @@ Sapphire::ItemPtr Sapphire::Entity::Player::addItem( uint32_t catalogId, uint32_ // add the related armoury bag to the applicable bags and try and fill a free slot there before falling back to regular inventory // EXD TODO: wtf... - if( itemInfo->data().Slot > 0 && getEquipDisplayFlags() & StoreNewItemsInArmouryChest ) + if( itemInfo->data().Slot > 0 && getConfigFlags() & StoreNewItemsInArmouryChest ) { auto bag = World::Manager::ItemMgr::getCharaEquipSlotCategoryToArmoryId( itemInfo->data().Slot ); diff --git a/src/world/Actor/PlayerSql.cpp b/src/world/Actor/PlayerSql.cpp index 18633fb2..58d3123c 100644 --- a/src/world/Actor/PlayerSql.cpp +++ b/src/world/Actor/PlayerSql.cpp @@ -103,7 +103,7 @@ bool Sapphire::Entity::Player::loadFromDb( uint64_t characterId ) m_equippedMannequin = res->getUInt8( "EquippedMannequin" ); - m_equipDisplayFlags = res->getUInt8( "EquipDisplayFlags" ); + m_configFlags = res->getUInt8( "EquipDisplayFlags" ); m_pose = res->getUInt8( "Pose" ); @@ -467,7 +467,7 @@ void Sapphire::Entity::Player::updateDbChara() const stmt->setInt( 51, m_gmRank ); - stmt->setInt( 52, m_equipDisplayFlags ); + stmt->setInt( 52, m_configFlags ); std::vector< uint8_t > unlockVec( m_unlocks.size() ); memcpy( unlockVec.data(), m_unlocks.data(), m_unlocks.size() ); diff --git a/src/world/CMakeLists.txt b/src/world/CMakeLists.txt index 0151b5b2..632151e2 100644 --- a/src/world/CMakeLists.txt +++ b/src/world/CMakeLists.txt @@ -16,6 +16,7 @@ file( GLOB SERVER_SOURCE_FILES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} Manager/*.cpp Math/*.cpp Network/*.cpp + Network/Util/*.cpp Network/Handlers/*.cpp Network/PacketWrappers/*.cpp Script/*.cpp diff --git a/src/world/Manager/PlayerMgr.cpp b/src/world/Manager/PlayerMgr.cpp index ca7e1d9a..ef6ba585 100644 --- a/src/world/Manager/PlayerMgr.cpp +++ b/src/world/Manager/PlayerMgr.cpp @@ -32,6 +32,7 @@ #include #include #include +#include #include #include @@ -214,34 +215,6 @@ Sapphire::Entity::PlayerPtr PlayerMgr::syncPlayer( uint64_t characterId ) return pPlayer; } - - -void PlayerMgr::onOnlineStatusChanged( Entity::Player& player, bool updateProfile ) -{ - auto statusPacket = makeZonePacket< FFXIVIpcSetOnlineStatus >( player.getId() ); - statusPacket->data().onlineStatusFlags = player.getFullOnlineStatusMask(); - server().queueForPlayer( player.getCharacterId(), statusPacket ); - - if( updateProfile ) - { - auto searchInfoPacket = makeZonePacket< FFXIVIpcSetProfileResult >( player.getId()); - searchInfoPacket->data().OnlineStatus = player.getFullOnlineStatusMask(); - searchInfoPacket->data().Region = player.getSearchSelectRegion(); - strcpy( searchInfoPacket->data().SearchComment, player.getSearchMessage()); - server().queueForPlayer( player.getCharacterId(), searchInfoPacket ); - } - - server().queueForPlayers( player.getInRangePlayerIds( true ), - makeActorControl( player.getId(), SetStatusIcon, static_cast< uint8_t >( player.getOnlineStatus() ) ) ); -} - -void PlayerMgr::onEquipDisplayFlagsChanged( Entity::Player& player ) -{ - auto paramPacket = makeZonePacket< FFXIVIpcConfig >( player.getId() ); - paramPacket->data().flag = player.getEquipDisplayFlags(); - server().queueForPlayers( player.getInRangePlayerIds( true ), paramPacket ); -} - void PlayerMgr::onConditionChanged( Entity::Player& player, bool updateInRange ) { @@ -282,55 +255,6 @@ void PlayerMgr::onUnlockAchievement( Entity::Player& player, uint32_t achievemen server().queueForPlayer( player.getCharacterId(), makeActorControl( player.getId(), AchievementObtainMsg, achievementId ) ); } -void PlayerMgr::onStatsChanged( Entity::Player& player ) -{ - std::array< uint32_t, 50 > statParams{}; - std::fill( std::begin( statParams ), std::end( statParams ), 0 ); - - auto& exd = Common::Service< Data::ExdData >::ref(); - - // todo: this is no doubt slow as shit... - auto idList = exd.getIdList< Excel::BaseParam >(); - - for( const auto id : idList ) - { - auto row = exd.getRow< Excel::BaseParam >( id ); - if( !row ) - { - continue; - } - - if( row->data().PacketIndex < 0 ) - { - continue; - } - - statParams[ row->data().PacketIndex ] = player.getStatValue( static_cast< Common::BaseParam >( id ) ); - } - - auto statPacket = makeZonePacket< FFXIVIpcBaseParam >( player.getId() ); - memcpy( statPacket->data().Param, statParams.data(), sizeof( uint32_t ) * statParams.size() ); - server().queueForPlayer( player.getCharacterId(), statPacket ); -} - -void PlayerMgr::sendStatusUpdate( Entity::Player& player ) -{ - auto playerStatusUpdate = makeZonePacket< FFXIVIpcPlayerStatusUpdate >( player.getId() ); - playerStatusUpdate->data().ClassJob = static_cast< uint8_t >( player.getClass() ); - playerStatusUpdate->data().Lv = player.getLevel(); - playerStatusUpdate->data().Lv1 = player.getLevel(); - playerStatusUpdate->data().LvSync = 0; //player.getLevelSync(); - playerStatusUpdate->data().Exp = player.getExp(); - - server().queueForPlayer( player.getCharacterId(), playerStatusUpdate ); -} - -void PlayerMgr::onHudParamChanged( Entity::Player& player ) -{ - auto hudParamPacket = makeHudParam( player ); - server().queueForPlayer( player.getCharacterId(), hudParamPacket ); -} - void PlayerMgr::onRestingTick( Entity::Player& player ) { server().queueForPlayers( player.getInRangePlayerIds( true ), std::make_shared< RestingPacket >( player ) ); @@ -344,8 +268,8 @@ void PlayerMgr::sendItemLevel( Entity::Player& player ) void PlayerMgr::onLevelUp( Entity::Player& player ) { player.calculateStats(); - player.sendStats(); - player.sendHudParam(); + Network::Util::Player::sendBaseParams( player ); + Network::Util::Player::sendHudParam( player ); auto inRangePlayerIds = player.getInRangePlayerIds( true ); @@ -353,7 +277,7 @@ void PlayerMgr::onLevelUp( Entity::Player& player ) server().queueForPlayers( inRangePlayerIds, makeActorControl( player.getId(), LevelUpEffect, static_cast< uint8_t >( player.getClass() ), player.getLevel(), player.getLevel() - 1 ) ); - sendStatusUpdate( player ); + Network::Util::Player::sendStatusUpdate( player ); auto& achvMgr = Common::Service< World::Manager::AchievementMgr >::ref(); achvMgr.progressAchievementByType< Common::Achievement::Type::Classjob >( player, static_cast< uint32_t >( player.getClass() ) ); @@ -393,29 +317,6 @@ void PlayerMgr::onGearChanged( Entity::Player& player ) server().queueForPlayers( player.getInRangePlayerIds( true ), std::make_shared< ModelEquipPacket >( player ) ); } -void PlayerMgr::sendGrandCompany( Entity::Player& player ) -{ - auto gcAffPacket = makeZonePacket< FFXIVIpcGrandCompany >( player.getId() ); - gcAffPacket->data().ActiveCompanyId = player.getGc(); - gcAffPacket->data().MaelstromRank = player.getGcRankArray()[ 0 ]; - gcAffPacket->data().TwinAdderRank = player.getGcRankArray()[ 1 ]; - gcAffPacket->data().ImmortalFlamesRank = player.getGcRankArray()[ 2 ]; - - server().queueForPlayer( player.getCharacterId(), gcAffPacket ); -} - -void PlayerMgr::setGrandCompany( Entity::Player& player, uint8_t gc ) -{ - player.setGc( gc ); - sendGrandCompany( player ); -} - -void PlayerMgr::setGrandCompanyRank( Entity::Player& player, uint8_t gc, uint8_t rank ) -{ - player.setGcRankAt( gc, rank ); - sendGrandCompany( player ); -} - void PlayerMgr::onCompanionUpdate( Entity::Player& player, uint8_t companionId ) { auto& exdData = Common::Service< Data::ExdData >::ref(); @@ -425,7 +326,7 @@ void PlayerMgr::onCompanionUpdate( Entity::Player& player, uint8_t companionId ) return; player.setCompanion( companionId ); - server().queueForPlayers( player.getInRangePlayerIds( true ), makeActorControl( player.getId(), ActorControlType::ToggleCompanion, companionId ) ); + Network::Util::Player::sendActorControl( player.getInRangePlayerIds( true ), player, ToggleCompanion, companionId ); } void PlayerMgr::onMountUpdate( Entity::Player& player, uint32_t mountId ) @@ -434,15 +335,13 @@ void PlayerMgr::onMountUpdate( Entity::Player& player, uint32_t mountId ) auto inRangePlayerIds = player.getInRangePlayerIds( true ); if( mountId != 0 ) { - server().queueForPlayers( inRangePlayerIds, - makeActorControl( player.getId(), ActorControlType::SetStatus, static_cast< uint8_t >( Common::ActorStatus::Mounted ) ) ); - server().queueForPlayers( inRangePlayerIds, makeActorControlSelf( player.getId(), 0x39e, 12 ) ); + Network::Util::Player::sendActorControl( inRangePlayerIds, player, SetStatus, static_cast< uint8_t >( Common::ActorStatus::Mounted ) ); + Network::Util::Player::sendActorControlSelf( inRangePlayerIds, player, 0x39e, 12 ); } else { - server().queueForPlayers( inRangePlayerIds, - makeActorControl( player.getId(), ActorControlType::SetStatus, static_cast< uint8_t >( Common::ActorStatus::Idle ) ) ); - server().queueForPlayers( inRangePlayerIds, makeActorControlSelf( player.getId(), ActorControlType::Dismount, 1 ) ); + Network::Util::Player::sendActorControl( inRangePlayerIds, player, SetStatus, static_cast< uint8_t >( Common::ActorStatus::Idle ) ); + Network::Util::Player::sendActorControlSelf( inRangePlayerIds, player, Dismount, 1 ); } auto mountPacket = makeZonePacket< FFXIVIpcMount >( player.getId() ); @@ -501,12 +400,6 @@ void PlayerMgr::onHateListChanged( Entity::Player& player ) server().queueForPlayer( player.getCharacterId(), { hateListPacket, hateRankPacket } ); } -void PlayerMgr::onClassChanged( Entity::Player& player ) -{ - server().queueForPlayers( player.getInRangePlayerIds( true ), makeActorControl( player.getId(), ClassJobChange, 0x04 ) ); - onHudParamChanged( player ); -} - void PlayerMgr::sendLoginMessage( Entity::Player& player ) { auto motd = server().getConfig().motd; @@ -556,7 +449,7 @@ void PlayerMgr::onMoveZone( Sapphire::Entity::Player& player ) if( player.isLogin() ) { - server().queueForPlayer( player.getCharacterId(), makeActorControlSelf( player.getId(), SetConfigFlags, player.getEquipDisplayFlags(), 1 ) ); + server().queueForPlayer( player.getCharacterId(), makeActorControlSelf( player.getId(), SetConfigFlags, player.getConfigFlags(), 1 ) ); server().queueForPlayer( player.getCharacterId(), makeActorControlSelf( player.getId(), SetMaxGearSets, player.getMaxGearSets() ) ); } @@ -564,13 +457,13 @@ void PlayerMgr::onMoveZone( Sapphire::Entity::Player& player ) //setStateFlag( PlayerStateFlag::BetweenAreas ); //setStateFlag( PlayerStateFlag::BetweenAreas1 ); - player.sendHuntingLog(); + Network::Util::Player::sendHuntingLog( player ); if( player.isLogin() ) server().queueForPlayer( player.getCharacterId(), makePlayerSetup( player ) ); player.sendRecastGroups(); - player.sendStats(); + Network::Util::Player::sendBaseParams( player ); sendItemLevel( player ); if( player.isLogin() ) { @@ -621,7 +514,7 @@ void PlayerMgr::onMoveZone( Sapphire::Entity::Player& player ) auto &questMgr = Common::Service< World::Manager::QuestMgr >::ref(); questMgr.sendQuestsInfo( player ); - sendGrandCompany( player ); + Network::Util::Player::sendGrandCompany( player ); } } diff --git a/src/world/Manager/PlayerMgr.h b/src/world/Manager/PlayerMgr.h index dc35eeb7..d569a7cb 100644 --- a/src/world/Manager/PlayerMgr.h +++ b/src/world/Manager/PlayerMgr.h @@ -23,16 +23,8 @@ namespace Sapphire::World::Manager bool loadPlayers(); Entity::PlayerPtr syncPlayer( uint64_t characterId ); - void onOnlineStatusChanged( Sapphire::Entity::Player& player, bool updateProfile = true ); - - void onEquipDisplayFlagsChanged( Sapphire::Entity::Player& player ); - - void sendStatusUpdate( Sapphire::Entity::Player& player ); - void onUnlockAchievement( Sapphire::Entity::Player& player, uint32_t achievementId ); - void onHudParamChanged( Sapphire::Entity::Player& player ); - void onRestingTick( Sapphire::Entity::Player& player ); void sendItemLevel( Sapphire::Entity::Player& player ); @@ -63,17 +55,12 @@ namespace Sapphire::World::Manager void onUpdate( Sapphire::Entity::Player& player, uint64_t tickCount ); void onConditionChanged( Sapphire::Entity::Player& player, bool updateInRange ); - void onStatsChanged( Sapphire::Entity::Player& player ); void onAchievementListChanged( Sapphire::Entity::Player& player ); void onAchievementProgressChanged( Sapphire::Entity::Player& player, uint32_t achievementId ); void onGearChanged( Sapphire::Entity::Player& player ); - void sendGrandCompany( Sapphire::Entity::Player& player ); - void onClassChanged( Sapphire::Entity::Player& player ); void setCondition( Sapphire::Entity::Player& player, Common::PlayerCondition flag ); void removeCondition( Sapphire::Entity::Player& player, Common::PlayerCondition flag ); - void setGrandCompany( Sapphire::Entity::Player& player, uint8_t gc ); - void setGrandCompanyRank( Sapphire::Entity::Player& player, uint8_t gc, uint8_t rank ); //////////// Helpers diff --git a/src/world/Network/Handlers/GMCommandHandlers.cpp b/src/world/Network/Handlers/GMCommandHandlers.cpp index a92ae1b4..fe301a2e 100644 --- a/src/world/Network/Handlers/GMCommandHandlers.cpp +++ b/src/world/Network/Handlers/GMCommandHandlers.cpp @@ -422,18 +422,7 @@ void Sapphire::Network::GameConnection::gmCommandHandler( const Packets::FFXIVAR return; } - Service< World::Manager::PlayerMgr >::ref().setGrandCompany( player, static_cast< uint8_t >( param1 ) ); - - // if we're changing them to a GC, check if they have a rank and if not, set it to the lowest rank - if( param1 > 0 ) - { - auto gcRankIdx = static_cast< uint8_t >( param1 ) - 1; - if( targetPlayer->getGcRankArray()[ gcRankIdx ] == 0 ) - { - player.setGcRankAt( static_cast< uint8_t >( gcRankIdx ), 1 ); - } - } - + player.setGrandCompany( static_cast< uint8_t >( param1 ) ); PlayerMgr::sendServerNotice( player, "GC for {0} was set to {1}", targetPlayer->getName(), targetPlayer->getGc()); break; } @@ -447,7 +436,7 @@ void Sapphire::Network::GameConnection::gmCommandHandler( const Packets::FFXIVAR return; } - Service< World::Manager::PlayerMgr >::ref().setGrandCompanyRank( player, static_cast< uint8_t >( gcId ), static_cast< uint8_t >( param1 ) ); + player.setGrandCompanyRankAt( static_cast< uint8_t >( gcId ), static_cast< uint8_t >( param1 ) ); PlayerMgr::sendServerNotice( player, "GC Rank for {0} for GC {1} was set to {2}", targetPlayer->getName(), targetPlayer->getGc(), targetPlayer->getGcRankArray()[ targetPlayer->getGc() - 1 ] ); break; diff --git a/src/world/Network/Handlers/PacketCommandHandler.cpp b/src/world/Network/Handlers/PacketCommandHandler.cpp index 6e69dd4d..192c5af7 100644 --- a/src/world/Network/Handlers/PacketCommandHandler.cpp +++ b/src/world/Network/Handlers/PacketCommandHandler.cpp @@ -16,6 +16,7 @@ #include "Network/PacketWrappers/ActorControlPacket.h" #include "Network/PacketWrappers/ActorControlTargetPacket.h" #include "Network/PacketWrappers/MoveActorPacket.h" +#include "Network/Util/PlayerUtil.h" #include "Action/Action.h" @@ -492,7 +493,7 @@ void Sapphire::Network::GameConnection::commandHandler( const Packets::FFXIVARR_ } case PacketCommand::TITLE_LIST: // Get title list { - player.sendTitleList(); + Network::Util::Player::sendTitleList( player ); break; } case PacketCommand::SET_HOWTO: // Update howtos seen diff --git a/src/world/Network/Handlers/PacketHandlers.cpp b/src/world/Network/Handlers/PacketHandlers.cpp index d49d8c0f..19057acb 100644 --- a/src/world/Network/Handlers/PacketHandlers.cpp +++ b/src/world/Network/Handlers/PacketHandlers.cpp @@ -254,8 +254,8 @@ void Sapphire::Network::GameConnection::configHandler( const Packets::FFXIVARR_P { const auto packet = ZoneChannelPacket< Client::FFXIVIpcConfig >( inPacket ); - player.setEquipDisplayFlags( packet.data().flag ); - PlayerMgr().onEquipDisplayFlagsChanged( player ); + player.setConfigFlags( packet.data().flag ); + } void Sapphire::Network::GameConnection::zoneJumpHandler( const Packets::FFXIVARR_PACKET_RAW& inPacket, Entity::Player& player ) diff --git a/src/world/Network/PacketWrappers/ActorControlSelfPacket.h b/src/world/Network/PacketWrappers/ActorControlSelfPacket.h index 80972b56..f0c17d3c 100644 --- a/src/world/Network/PacketWrappers/ActorControlSelfPacket.h +++ b/src/world/Network/PacketWrappers/ActorControlSelfPacket.h @@ -27,8 +27,7 @@ namespace Sapphire::Network::Packets::WorldPackets::Server }; private: - void initialize( uint16_t category, uint32_t param1, uint32_t param2, uint32_t param3, uint32_t param4, - uint32_t param5 ) + void initialize( uint16_t category, uint32_t param1, uint32_t param2, uint32_t param3, uint32_t param4, uint32_t param5 ) { m_data.padding = 0; m_data.category = category; diff --git a/src/world/Network/PacketWrappers/PlayerSpawnPacket.h b/src/world/Network/PacketWrappers/PlayerSpawnPacket.h index 6192a274..5dae5202 100644 --- a/src/world/Network/PacketWrappers/PlayerSpawnPacket.h +++ b/src/world/Network/PacketWrappers/PlayerSpawnPacket.h @@ -115,22 +115,22 @@ namespace Sapphire::Network::Packets::WorldPackets::Server m_data.Flag |= static_cast< uint16_t >( Common::DisplayFlags::Invisible ); } - if( player.getEquipDisplayFlags() & Sapphire::Common::EquipDisplayFlags::HideHead ) + if( player.getConfigFlags() & Sapphire::Common::EquipDisplayFlags::HideHead ) { m_data.Flag |= static_cast< uint16_t >( Common::DisplayFlags::HideHead ); } - if( player.getEquipDisplayFlags() & Sapphire::Common::EquipDisplayFlags::HideWeapon ) + if( player.getConfigFlags() & Sapphire::Common::EquipDisplayFlags::HideWeapon ) { m_data.Flag |= static_cast< uint16_t >( Common::DisplayFlags::HideWeapon ); } - if( player.getEquipDisplayFlags() & Sapphire::Common::EquipDisplayFlags::Visor ) + if( player.getConfigFlags() & Sapphire::Common::EquipDisplayFlags::Visor ) { m_data.Flag |= static_cast< uint16_t >( Common::DisplayFlags::Visor ); } - if( !( player.getEquipDisplayFlags() & Sapphire::Common::EquipDisplayFlags::HideLegacyMark ) ) + if( !( player.getConfigFlags() & Sapphire::Common::EquipDisplayFlags::HideLegacyMark ) ) { m_data.Customize[ 0xC ] = m_data.Customize[ 0xC ] | 1 << 7; } diff --git a/src/world/Network/Util/PlayerUtil.cpp b/src/world/Network/Util/PlayerUtil.cpp new file mode 100644 index 00000000..2ec305cd --- /dev/null +++ b/src/world/Network/Util/PlayerUtil.cpp @@ -0,0 +1,162 @@ +#include "PlayerUtil.h" + +#include + +#include + +#include +#include +#include +#include +#include +#include + +using namespace Sapphire; +using namespace Sapphire::World::Manager; +using namespace Sapphire::Network; +using namespace Sapphire::Network::Util::Player; +using namespace Sapphire::Network::Packets; +using namespace Sapphire::Network::Packets::WorldPackets::Server; +using namespace Sapphire::Network::ActorControl; + +void Util::Player::sendConfigFlags( Entity::Player& player ) +{ + auto paramPacket = makeZonePacket< FFXIVIpcConfig >( player.getId() ); + paramPacket->data().flag = player.getConfigFlags(); + server().queueForPlayers( player.getInRangePlayerIds( true ), paramPacket ); +} + +void Util::Player::sendOnlineStatus( Entity::Player& player ) +{ + auto statusPacket = makeZonePacket< FFXIVIpcSetOnlineStatus >( player.getId() ); + statusPacket->data().onlineStatusFlags = player.getFullOnlineStatusMask(); + server().queueForPlayer( player.getCharacterId(), statusPacket ); + + server().queueForPlayers( player.getInRangePlayerIds( true ), + makeActorControl( player.getId(), SetStatusIcon, static_cast< uint8_t >( player.getOnlineStatus() ) ) ); +} + +void Util::Player::sendBaseParams( Entity::Player& player ) +{ + std::array< uint32_t, 50 > statParams{}; + std::fill( std::begin( statParams ), std::end( statParams ), 0 ); + + auto& exd = Common::Service< Data::ExdData >::ref(); + auto idList = exd.getIdList< Excel::BaseParam >(); + + for( const auto id : idList ) + { + auto row = exd.getRow< Excel::BaseParam >( id ); + if( !row ) + continue; + if( row->data().PacketIndex < 0 ) + continue; + statParams[ row->data().PacketIndex ] = player.getStatValue( static_cast< Common::BaseParam >( id ) ); + } + + auto statPacket = makeZonePacket< FFXIVIpcBaseParam >( player.getId() ); + memcpy( statPacket->data().Param, statParams.data(), sizeof( uint32_t ) * statParams.size() ); + server().queueForPlayer( player.getCharacterId(), statPacket ); +} + +void Util::Player::sendHudParam( Entity::Player& player ) +{ + auto hudParamPacket = makeHudParam( player ); + server().queueForPlayer( player.getCharacterId(), hudParamPacket ); +} + +void Util::Player::sendStatusUpdate( Entity::Player& player ) +{ + auto playerStatusUpdate = makeZonePacket< FFXIVIpcPlayerStatusUpdate >( player.getId() ); + playerStatusUpdate->data().ClassJob = static_cast< uint8_t >( player.getClass() ); + playerStatusUpdate->data().Lv = player.getLevel(); + playerStatusUpdate->data().Lv1 = player.getLevel(); + playerStatusUpdate->data().LvSync = 0; //player.getLevelSync(); + playerStatusUpdate->data().Exp = player.getExp(); + + server().queueForPlayer( player.getCharacterId(), playerStatusUpdate ); +} + +void Util::Player::sendHuntingLog( Entity::Player& player ) +{ + auto& exdData = Common::Service< Data::ExdData >::ref(); + for( auto entryCount = 0; entryCount < Common::ARRSIZE_MONSTERNOTE; ++entryCount ) + { + auto& entry = player.getHuntingLogEntry( entryCount ); + uint64_t completionFlag = 0; + auto huntPacket = makeZonePacket< FFXIVIpcMonsterNoteCategory >( player.getId() ); + + huntPacket->data().contextId = -1; + huntPacket->data().currentRank = entry.rank; + huntPacket->data().categoryIndex = entryCount; + + for( int i = 1; i <= 10; ++i ) + { + auto index0 = i - 1; + bool allComplete = true; + auto monsterNoteId = ( entryCount + 1 ) * 10000 + entry.rank * 10 + i; + + auto monsterNote = exdData.getRow< Excel::MonsterNote >( monsterNoteId ); + if( !monsterNote ) + continue; + + const auto huntEntry = entry.entries[ index0 ]; + for( int x = 0; x < 3; ++x ) + { + if( ( huntEntry[ x ] == monsterNote->data().NeededKills[ x ] ) && monsterNote->data().NeededKills[ x ] != 0 ) + completionFlag |= ( 1ull << ( index0 * 5 + x ) ); + else if( monsterNote->data().NeededKills[ x ] != 0 ) + allComplete = false; + } + + if( allComplete ) + completionFlag |= ( 1ull << ( index0 * 5 + 4 ) ); + + } + + memcpy( huntPacket->data().killCount, entry.entries, sizeof( entry.entries ) ); + huntPacket->data().completeFlags = completionFlag; + server().queueForPlayer( player.getCharacterId(), huntPacket ); + } +} + +void Util::Player::sendActorControlSelf( Entity::Player& player, uint16_t category, uint32_t param1, uint32_t param2, uint32_t param3, + uint32_t param4, uint32_t param5 ) +{ + server().queueForPlayer( player.getCharacterId(), makeActorControlSelf( player.getId(), category, param1, param2, param3, param4, param5 ) ); +} + +void Util::Player::sendActorControlSelf( const std::set< uint64_t >& characterIds, Entity::Player& player, uint16_t category, uint32_t param1, + uint32_t param2, uint32_t param3, uint32_t param4, uint32_t param5 ) +{ + server().queueForPlayers( characterIds, makeActorControlSelf( player.getId(), category, param1, param2, param3, param4, param5 ) ); +} + +void Util::Player::sendActorControl( Entity::Player& player, uint16_t category, uint32_t param1, uint32_t param2, uint32_t param3, uint32_t param4 ) +{ + server().queueForPlayer( player.getCharacterId(), makeActorControl( player.getId(), category, param1, param2, param3, param4 ) ); +} + +void Util::Player::sendActorControl( const std::set< uint64_t >& characterIds, Entity::Player& player, uint16_t category, uint32_t param1, + uint32_t param2, uint32_t param3, uint32_t param4 ) +{ + server().queueForPlayers( characterIds, makeActorControl( player.getId(), category, param1, param2, param3, param4 ) ); +} + +void Util::Player::sendTitleList( Entity::Player& player ) +{ + auto titleListPacket = makeZonePacket< FFXIVIpcTitleList >( player.getId() ); + memcpy( titleListPacket->data().TitleFlagsArray, player.getTitleList().data(), sizeof( titleListPacket->data().TitleFlagsArray ) ); + server().queueForPlayer( player.getCharacterId(), titleListPacket ); +} + +void Util::Player::sendGrandCompany( Entity::Player& player ) +{ + auto gcAffPacket = makeZonePacket< FFXIVIpcGrandCompany >( player.getId() ); + gcAffPacket->data().ActiveCompanyId = player.getGc(); + gcAffPacket->data().MaelstromRank = player.getGcRankArray()[ 0 ]; + gcAffPacket->data().TwinAdderRank = player.getGcRankArray()[ 1 ]; + gcAffPacket->data().ImmortalFlamesRank = player.getGcRankArray()[ 2 ]; + + server().queueForPlayer( player.getCharacterId(), gcAffPacket ); +} \ No newline at end of file diff --git a/src/world/Network/Util/PlayerUtil.h b/src/world/Network/Util/PlayerUtil.h new file mode 100644 index 00000000..5a8d3335 --- /dev/null +++ b/src/world/Network/Util/PlayerUtil.h @@ -0,0 +1,32 @@ +#pragma once + +#include +#include +#include +#include "Forwards.h" + +namespace Sapphire::Network::Util::Player +{ + void sendConfigFlags( Entity::Player& player ); + void sendOnlineStatus( Entity::Player& player ); + void sendBaseParams( Entity::Player& player ); + void sendHudParam( Entity::Player& player ); + void sendStatusUpdate( Entity::Player& player ); + + void sendHuntingLog( Entity::Player& player ); + void sendTitleList( Entity::Player& player ); + + void sendGrandCompany( Entity::Player& player ); + + void sendActorControlSelf( Entity::Player& player, uint16_t category, uint32_t param1 = 0, uint32_t param2 = 0, uint32_t param3 = 0, + uint32_t param4 = 0, uint32_t param5 = 0 ); + + void sendActorControlSelf( const std::set< uint64_t >& characterIds, Entity::Player& player, uint16_t category, uint32_t param1 = 0, + uint32_t param2 = 0, uint32_t param3 = 0, uint32_t param4 = 0, uint32_t param5 = 0 ); + + void sendActorControl( Entity::Player& player, uint16_t category, uint32_t param1 = 0, uint32_t param2 = 0, uint32_t param3 = 0, uint32_t param4 = 0 ); + + void sendActorControl( const std::set< uint64_t >& characterIds, Entity::Player& player, uint16_t category, uint32_t param1 = 0, uint32_t param2 = 0, + uint32_t param3 = 0, uint32_t param4 = 0 ); + +} \ No newline at end of file