diff --git a/src/world/Action/ActionResultBuilder.cpp b/src/world/Action/ActionResultBuilder.cpp index cf073683..db0da0cb 100644 --- a/src/world/Action/ActionResultBuilder.cpp +++ b/src/world/Action/ActionResultBuilder.cpp @@ -171,6 +171,7 @@ std::shared_ptr< FFXIVPacketBase > ActionResultBuilder::createActionResultPacket break; } + m_actorResultsMap.clear(); return actionResult; } else // use Effect for single target diff --git a/src/world/Actor/Player.cpp b/src/world/Actor/Player.cpp index 76bb6e27..4a1a50f3 100644 --- a/src/world/Actor/Player.cpp +++ b/src/world/Actor/Player.cpp @@ -563,6 +563,11 @@ void Player::setRewardFlag( Common::UnlockEntry unlockId ) Network::Util::Packet::sendActorControlSelf( *this, getId(), SetRewardFlag, unlock, 1 ); } +void Player::fillRewardFlags() +{ + memset( m_unlocks.data(), 0xFF, m_unlocks.size() ); +} + void Player::setBorrowAction( uint8_t slot, uint32_t action ) { if( slot > Common::ARRSIZE_BORROWACTION ) @@ -1815,6 +1820,9 @@ void Player::setFalling( bool state, const Common::FFXIVARR_POSITION3& pos, bool takeDamage( damage ); } Network::Util::Packet::sendActorControl( getInRangePlayerIds( true ), getId(), SetFallDamage, damage ); + // todo: this used to work without refreshing the entire UI state + // does 3.x use some sort of fall integrity? + Network::Util::Packet::sendHudParam( *this ); } } } diff --git a/src/world/Actor/Player.h b/src/world/Actor/Player.h index a68ad613..4ebea855 100644 --- a/src/world/Actor/Player.h +++ b/src/world/Actor/Player.h @@ -441,6 +441,9 @@ namespace Sapphire::Entity /*! learn an action / update the unlock bitmask. */ void setRewardFlag( Common::UnlockEntry unlockId ); + /*! helper/debug function to fill unlock bitmask */ + void fillRewardFlags(); + void setBorrowAction( uint8_t slot, uint32_t action ); BorrowAction& getBorrowAction(); diff --git a/src/world/Manager/DebugCommandMgr.cpp b/src/world/Manager/DebugCommandMgr.cpp index aaf583be..ec8d09e5 100644 --- a/src/world/Manager/DebugCommandMgr.cpp +++ b/src/world/Manager/DebugCommandMgr.cpp @@ -11,6 +11,7 @@ #include #include #include +#include #include #include "DebugCommand/DebugCommand.h" @@ -159,6 +160,7 @@ void DebugCommandMgr::help( char* data, Entity::Player& player, std::shared_ptr< void DebugCommandMgr::set( char* data, Entity::Player& player, std::shared_ptr< DebugCommand > command ) { auto& server = Sapphire::Common::Service< Sapphire::World::WorldServer >::ref(); + auto& playerMgr = Common::Service< PlayerMgr >::ref(); auto& terriMgr = Common::Service< TerritoryMgr >::ref(); auto pCurrentZone = terriMgr.getTerritoryByGuId( player.getTerritoryId() ); @@ -233,7 +235,8 @@ void DebugCommandMgr::set( char* data, Entity::Player& player, std::shared_ptr< else if( subCommand == "discovery_reset" ) { player.resetDiscovery(); - server.queueForPlayer( player.getCharacterId(), std::make_shared< PlayerSetupPacket >( player ) ); + player.setIsLogin( true ); + playerMgr.onMoveZone( player ); } else if( subCommand == "classjob" ) { @@ -385,6 +388,7 @@ void DebugCommandMgr::set( char* data, Entity::Player& player, std::shared_ptr< void DebugCommandMgr::add( char* data, Entity::Player& player, std::shared_ptr< DebugCommand > command ) { auto& terriMgr = Common::Service< TerritoryMgr >::ref(); + auto& playerMgr = Common::Service< PlayerMgr >::ref(); auto pCurrentZone = terriMgr.getTerritoryByGuId( player.getTerritoryId() ); std::string subCommand; @@ -525,6 +529,13 @@ void DebugCommandMgr::add( char* data, Entity::Player& player, std::shared_ptr< sscanf( params.c_str(), "%d", &id ); player.setRewardFlag( static_cast< Common::UnlockEntry >( id ) ); } + else if( subCommand == "unlockall" ) + { + player.fillRewardFlags(); + + player.setIsLogin( true ); + playerMgr.onMoveZone( player ); + } else if( subCommand == "effect" ) { uint16_t param1; diff --git a/src/world/Manager/MapMgr.cpp b/src/world/Manager/MapMgr.cpp index f7a18a40..fb660315 100644 --- a/src/world/Manager/MapMgr.cpp +++ b/src/world/Manager/MapMgr.cpp @@ -35,11 +35,24 @@ using namespace Sapphire::World::Manager; bool MapMgr::loadQuests() { auto& exdData = Common::Service< Data::ExdData >::ref(); + auto questList = exdData.getRows< Excel::Quest >(); + auto eNpcList = exdData.getRows< Excel::ENpcBase >(); + auto eObjList = exdData.getRows< Excel::EObj >(); for( auto& [ id, questExdData ] : questList ) { - m_quests.emplace( id, std::move( questExdData ) ); + m_questCacheMap.emplace( id, std::move( questExdData ) ); + } + + for( auto& [ id, eNpcExdData ] : eNpcList ) + { + m_eNpcCacheMap.emplace( id, std::move( eNpcExdData ) ); + } + + for( auto& [ id, eObjExdData ] : eObjList ) + { + m_eObjCacheMap.emplace( id, std::move( eObjExdData ) ); } return true; @@ -58,12 +71,12 @@ void MapMgr::updateAll( Entity::Player& player ) for( const auto& eventNpc : *eventNpcs ) { - auto eNpc = exdData.getRow< Excel::ENpcBase >( eventNpc.second->data.enpcId ); - if( !eNpc ) + auto eNpcIt = m_eNpcCacheMap.find( eventNpc.second->data.enpcId ); + if( eNpcIt == std::end( m_eNpcCacheMap ) ) continue; - auto eNpcData = eNpc->data().EventHandler; - for( int npcEvent = 0; npcEvent < 32; npcEvent++ ) + auto eNpcData = eNpcIt->second->data().EventHandler; + for( auto npcEvent = 0; npcEvent < 32; ++npcEvent ) { auto npcData = eNpcData[ npcEvent ].EventHandler; @@ -80,7 +93,7 @@ void MapMgr::updateAll( Entity::Player& player ) { case EventHandler::EventHandlerType::Quest: { - auto& quest = m_quests[ npcData ]->data(); + auto& quest = m_questCacheMap[ npcData ]->data(); if( quest.Client == eventNpc.second->data.enpcId ) { @@ -102,7 +115,7 @@ void MapMgr::updateAll( Entity::Player& player ) { if( guildLeve.NeedGrandCompanyRank > 0 && player.getGc() != 0 ) { - for( int8_t i = 0; i < 3; i++ ) + for( int8_t i = 0; i < 3; ++i ) { if( player.getGcRankArray()[ i ] >= guildLeve.NeedGrandCompanyRank ) { @@ -162,11 +175,11 @@ void MapMgr::updateAll( Entity::Player& player ) for( const auto& eventObj : *eventObjs ) { - auto eObj = exdData.getRow< Excel::EObj >( eventObj.second->data.BaseId ); - if( !eObj ) - return; + auto eObjIt = m_eObjCacheMap.find( eventObj.second->data.BaseId ); + if( eObjIt == std::end( m_eObjCacheMap ) ) + continue; - auto eObjData = eObj->data(); + auto eObjData = eObjIt->second->data(); EventData eventData; eventData.handlerId = eObjData.EventHandler; eventData.layoutId = eventObj.first; @@ -175,7 +188,7 @@ void MapMgr::updateAll( Entity::Player& player ) if( eventHandlerType == EventHandler::EventHandlerType::Quest ) { - auto& quest = m_quests[ eObjData.EventHandler ]->data(); + auto& quest = m_questCacheMap[ eObjData.EventHandler ]->data(); if( quest.Client == eventObj.second->data.BaseId ) { @@ -200,13 +213,13 @@ void MapMgr::updateQuests( Entity::Player& player ) for( const auto& eventNpc : *eventNpcs ) { - auto eNpc = exdData.getRow< Excel::ENpcBase >( eventNpc.second->data.enpcId ); - if( !eNpc ) + auto eNpcIt = m_eNpcCacheMap.find( eventNpc.second->data.enpcId ); + if( eNpcIt == std::end( m_eNpcCacheMap ) ) continue; - auto eNpcData = eNpc->data().EventHandler; + auto eNpcData = eNpcIt->second->data().EventHandler; - for( int npcEvent = 0; npcEvent < 32; npcEvent++ ) + for( auto npcEvent = 0; npcEvent < 32; ++npcEvent ) { auto npcData = eNpcData[ npcEvent ].EventHandler; @@ -221,7 +234,7 @@ void MapMgr::updateQuests( Entity::Player& player ) if( eventHandlerType == EventHandler::EventHandlerType::Quest ) { - auto& quest = m_quests[ npcData ]->data(); + auto& quest = m_questCacheMap[ npcData ]->data(); if( quest.Client == eventNpc.second->data.enpcId ) { @@ -237,11 +250,11 @@ void MapMgr::updateQuests( Entity::Player& player ) for( const auto& eventObj : *eventObjs ) { - auto eObj = exdData.getRow< Excel::EObj >( eventObj.second->data.BaseId ); - if( !eObj ) - return; + auto eObjIt = m_eObjCacheMap.find( eventObj.second->data.BaseId ); + if( eObjIt == std::end( m_eObjCacheMap ) ) + continue; - auto eObjData = eObj->data(); + auto eObjData = eObjIt->second->data(); EventData eventData; eventData.handlerId = eObjData.EventHandler; eventData.layoutId = eventObj.first; @@ -250,7 +263,7 @@ void MapMgr::updateQuests( Entity::Player& player ) if( eventHandlerType == EventHandler::EventHandlerType::Quest ) { - auto& quest = m_quests[ eObjData.EventHandler ]->data(); + auto& quest = m_questCacheMap[ eObjData.EventHandler ]->data(); if( quest.Client == eventObj.second->data.BaseId ) { @@ -267,7 +280,7 @@ void MapMgr::insertQuest( Entity::Player& player, uint32_t questId, uint32_t lay auto& exdData = Common::Service< Data::ExdData >::ref(); auto& scriptMgr = Common::Service< Scripting::ScriptMgr >::ref(); - auto& quest = m_quests[ questId ]->data(); + auto& quest = m_questCacheMap[ questId ]->data(); if( isQuestVisible( player, questId, quest ) ) { @@ -307,7 +320,7 @@ bool MapMgr::isQuestAvailable( Entity::Player& player, uint32_t questId, Excel:: if( quest.InstanceContentOperator == 1 ) { - for( int32_t i = 0; i < 3; i++ ) + for( int32_t i = 0; i < 3; ++i ) { if( quest.InstanceContent[ i ] == 0 ) continue; @@ -319,7 +332,7 @@ bool MapMgr::isQuestAvailable( Entity::Player& player, uint32_t questId, Excel:: } else if( quest.InstanceContentOperator == 2 ) { - for( int32_t i = 0; i < 3; i++ ) + for( int32_t i = 0; i < 3; ++i ) { if( quest.InstanceContent[ i ] == 0 ) continue; @@ -396,7 +409,7 @@ bool MapMgr::isQuestVisible( Entity::Player& player, uint32_t questId, Excel::Qu if( quest.PrevQuestOperator == 1 ) { - for( int32_t i = 0; i < 3; i++ ) + for( auto i = 0; i < 3; ++i ) { if( quest.PrevQuest[ i ] == 0 ) continue; @@ -419,7 +432,7 @@ bool MapMgr::isQuestVisible( Entity::Player& player, uint32_t questId, Excel::Qu } else if( quest.PrevQuestOperator == 2 ) { - for( int32_t i = 0; i < 3; i++ ) + for( auto i = 0; i < 3; ++i ) { if( quest.PrevQuest[ i ] == 0 ) continue; @@ -434,7 +447,7 @@ bool MapMgr::isQuestVisible( Entity::Player& player, uint32_t questId, Excel::Qu if( quest.ExcludeQuestOperator == 1 ) { - for( int32_t i = 0; i < 2; i++ ) + for( auto i = 0; i < 2; ++i ) { if( quest.ExcludeQuest[ i ] == 0 ) continue; @@ -448,7 +461,7 @@ bool MapMgr::isQuestVisible( Entity::Player& player, uint32_t questId, Excel::Qu } else if( quest.ExcludeQuestOperator == 2 ) { - for( int32_t i = 0; i < 2; i++ ) + for( auto i = 0; i < 2; ++i ) { if( quest.ExcludeQuest[ i ] == 0 ) continue; @@ -475,7 +488,7 @@ bool MapMgr::isQuestVisible( Entity::Player& player, uint32_t questId, Excel::Qu { auto classJobCategory = exdData.getRow< Excel::ClassJobCategory >( quest.ClassJob )->data().ClassJob; - for( int32_t i = 1; i <= Common::CLASSJOB_TOTAL; i++ ) + for( auto i = 1; i <= Common::CLASSJOB_TOTAL; ++i ) { if( i == Common::CLASSJOB_TOTAL ) return false; @@ -494,13 +507,14 @@ bool MapMgr::isQuestVisible( Entity::Player& player, uint32_t questId, Excel::Qu } // TODO: I think this changed in 3.x to be for all relics, more research is needed. - for( int32_t i = 0; i < Common::CLASSJOB_TOTAL; i++ ) + // todo: fix this inner j loop + for( auto i = 0; i < Common::CLASSJOB_TOTAL; ++i ) { auto classJob = exdData.getRow< Excel::ClassJob >( i ); if( classJob->data().ARRRelicQuestId == questId ) { - for( int32_t j = 0; i < Common::CLASSJOB_TOTAL; i++ ) + for( auto j = 0; i < Common::CLASSJOB_TOTAL; ++i ) { classJob = exdData.getRow< Excel::ClassJob >( i ); diff --git a/src/world/Manager/MapMgr.h b/src/world/Manager/MapMgr.h index 6981ecf0..c23500e4 100644 --- a/src/world/Manager/MapMgr.h +++ b/src/world/Manager/MapMgr.h @@ -11,6 +11,8 @@ namespace Sapphire::World::Manager { using QuestMap = std::unordered_map< uint32_t, std::shared_ptr< Excel::ExcelStruct< Excel::Quest > > >; + using EObjDataCache = std::unordered_map< uint32_t, std::shared_ptr< Excel::ExcelStruct< Excel::EObj > > >; + using ENpcDataCache = std::unordered_map< uint32_t, std::shared_ptr< Excel::ExcelStruct< Excel::ENpcBase > > >; class MapMgr { @@ -64,8 +66,11 @@ namespace Sapphire::World::Manager }; using EventSet = std::multiset< EventData, less >; + - QuestMap m_quests; + QuestMap m_questCacheMap; + ENpcDataCache m_eNpcCacheMap; + EObjDataCache m_eObjCacheMap; void insertQuest( Entity::Player& player, uint32_t questId, uint32_t layoutId, EventSet& mapData ); diff --git a/src/world/Network/Handlers/GMCommandHandlers.cpp b/src/world/Network/Handlers/GMCommandHandlers.cpp index a0076141..58dfa845 100644 --- a/src/world/Network/Handlers/GMCommandHandlers.cpp +++ b/src/world/Network/Handlers/GMCommandHandlers.cpp @@ -253,7 +253,7 @@ void Sapphire::Network::GameConnection::gmCommandHandler( const Packets::FFXIVAR } case GmCommand::Kill: { - targetActor->getAsChara()->takeDamage( 9999999 ); + targetActor->getAsChara()->takeDamage( 0xFFFFFFFF ); PlayerMgr::sendServerNotice( player, "Killed {0}", targetActor->getId()); break; }