From 6c8124373c93b8a1e621eee913873d5c963c38ca Mon Sep 17 00:00:00 2001 From: Mordred Date: Sun, 7 Apr 2019 13:27:56 +0200 Subject: [PATCH 1/4] Changed the way players are being iterated for updating, some questbattle additions --- .../instances/questbattles/ChasingShadows.cpp | 6 ++++ src/world/Actor/Player.cpp | 5 +++ src/world/Actor/Player.h | 4 +++ src/world/Actor/PlayerSql.cpp | 1 + src/world/Manager/DebugCommandMgr.cpp | 20 +++++++++++ src/world/Network/GameConnection.cpp | 1 + src/world/Script/NativeScriptApi.cpp | 5 +++ src/world/Script/NativeScriptApi.h | 2 ++ src/world/Script/ScriptMgr.cpp | 13 ++++++++ src/world/Script/ScriptMgr.h | 2 ++ src/world/Territory/Cell.cpp | 2 +- src/world/Territory/Cell.h | 2 +- src/world/Territory/QuestBattle.cpp | 30 +++++++++++++++++ src/world/Territory/QuestBattle.h | 5 +++ src/world/Territory/Zone.cpp | 33 +++++++++---------- src/world/Territory/Zone.h | 3 -- src/world/Util/ActorFilter.cpp | 2 +- 17 files changed, 112 insertions(+), 24 deletions(-) diff --git a/src/scripts/instances/questbattles/ChasingShadows.cpp b/src/scripts/instances/questbattles/ChasingShadows.cpp index 01324df4..91fe7d9c 100644 --- a/src/scripts/instances/questbattles/ChasingShadows.cpp +++ b/src/scripts/instances/questbattles/ChasingShadows.cpp @@ -52,6 +52,12 @@ public: } + void onDutyComplete( QuestBattle& instance, Entity::Player& player ) override + { + player.updateQuest( instance.getQuestId(), 2 ); + player.exitInstance(); + } + }; EXPOSE_SCRIPT( ChasingShadows ); \ No newline at end of file diff --git a/src/world/Actor/Player.cpp b/src/world/Actor/Player.cpp index 77b7dd0c..b37943b7 100644 --- a/src/world/Actor/Player.cpp +++ b/src/world/Actor/Player.cpp @@ -2102,3 +2102,8 @@ void Sapphire::Entity::Player::updateHuntingLog( uint16_t id ) sendHuntingLog(); } +Sapphire::World::SessionPtr Sapphire::Entity::Player::getSession() +{ + return m_pSession; +} + diff --git a/src/world/Actor/Player.h b/src/world/Actor/Player.h index 314c055e..b7becacb 100644 --- a/src/world/Actor/Player.h +++ b/src/world/Actor/Player.h @@ -972,6 +972,8 @@ namespace Sapphire::Entity void updateHuntingLog( uint16_t id ); + World::SessionPtr getSession(); + ////////////////////////////////////////////////////////////////////////////////////////////////////// uint64_t m_lastMoveTime; @@ -982,6 +984,8 @@ namespace Sapphire::Entity uint32_t m_lastWrite; uint32_t m_lastPing; + World::SessionPtr m_pSession; + bool m_bIsLogin; uint64_t m_contentId; // This id will be the name of the folder for character settings in "My Games" diff --git a/src/world/Actor/PlayerSql.cpp b/src/world/Actor/PlayerSql.cpp index 1fe30904..784c970b 100644 --- a/src/world/Actor/PlayerSql.cpp +++ b/src/world/Actor/PlayerSql.cpp @@ -31,6 +31,7 @@ bool Sapphire::Entity::Player::load( uint32_t charId, World::SessionPtr pSession { auto pDb = m_pFw->get< Db::DbWorkerPool< Db::ZoneDbConnection > >(); auto pTeriMgr = m_pFw->get< TerritoryMgr >(); + m_pSession = pSession; const std::string char_id_str = std::to_string( charId ); diff --git a/src/world/Manager/DebugCommandMgr.cpp b/src/world/Manager/DebugCommandMgr.cpp index 27000355..c4ac0789 100644 --- a/src/world/Manager/DebugCommandMgr.cpp +++ b/src/world/Manager/DebugCommandMgr.cpp @@ -1030,6 +1030,26 @@ void Sapphire::World::Manager::DebugCommandMgr::questBattle( char* data, Entity: else player.sendDebug( "Failed to create instance with id#{0}", contentFinderConditionId ); } + else if( subCommand == "complete" ) + { + + auto instance = std::dynamic_pointer_cast< QuestBattle >( player.getCurrentZone() ); + if( !instance ) + return; + + instance->success(); + + } + else if( subCommand == "fail" ) + { + + auto instance = std::dynamic_pointer_cast< QuestBattle >( player.getCurrentZone() ); + if( !instance ) + return; + + instance->fail(); + + } else if( subCommand == "createzone" || subCommand == "crz" ) { uint32_t zoneId; diff --git a/src/world/Network/GameConnection.cpp b/src/world/Network/GameConnection.cpp index 103051f5..1f16ae03 100644 --- a/src/world/Network/GameConnection.cpp +++ b/src/world/Network/GameConnection.cpp @@ -222,6 +222,7 @@ void Sapphire::Network::GameConnection::handleZonePacket( Sapphire::Network::Pac else { Logger::debug( "[{0}] Undefined Zone IPC : Unknown ( {1:04X} )", m_pSession->getId(), opcode ); + Logger::debug( "Dump:\n{0}", Util::binaryToHexDump( const_cast< uint8_t* >( &pPacket.data[ 0 ] ), pPacket.segHdr.size ) ); } diff --git a/src/world/Script/NativeScriptApi.cpp b/src/world/Script/NativeScriptApi.cpp index 33fcfb60..661a1923 100644 --- a/src/world/Script/NativeScriptApi.cpp +++ b/src/world/Script/NativeScriptApi.cpp @@ -201,6 +201,11 @@ namespace Sapphire::ScriptAPI { } + void QuestBattleScript::onDutyComplete( Sapphire::QuestBattle& instance, Entity::Player& player ) + { + + } + void QuestBattleScript::onPlayerSetup( Sapphire::QuestBattle& instance, Entity::Player& player ) { } diff --git a/src/world/Script/NativeScriptApi.h b/src/world/Script/NativeScriptApi.h index 073a5d63..7a2f5ba5 100644 --- a/src/world/Script/NativeScriptApi.h +++ b/src/world/Script/NativeScriptApi.h @@ -239,6 +239,8 @@ namespace Sapphire::ScriptAPI public: explicit QuestBattleScript( uint32_t questBattleId ); + virtual void onDutyComplete( Sapphire::QuestBattle& instance, Entity::Player& player ); + virtual void onPlayerSetup( Sapphire::QuestBattle& instance, Entity::Player& player ); virtual void onInit( Sapphire::QuestBattle& instance ); diff --git a/src/world/Script/ScriptMgr.cpp b/src/world/Script/ScriptMgr.cpp index 260f196a..e6e71352 100644 --- a/src/world/Script/ScriptMgr.cpp +++ b/src/world/Script/ScriptMgr.cpp @@ -516,3 +516,16 @@ Sapphire::Scripting::NativeScriptMgr& Sapphire::Scripting::ScriptMgr::getNativeS { return *m_nativeScriptMgr; } + +bool +Sapphire::Scripting::ScriptMgr::onDutyComplete( Sapphire::QuestBattlePtr instance, Sapphire::Entity::Player& player ) +{ + auto script = m_nativeScriptMgr->getScript< Sapphire::ScriptAPI::QuestBattleScript >( instance->getDirectorId() ); + if( script ) + { + script->onDutyComplete( *instance, player ); + return true; + } + + return false; +} diff --git a/src/world/Script/ScriptMgr.h b/src/world/Script/ScriptMgr.h index ce05c052..e333a39f 100644 --- a/src/world/Script/ScriptMgr.h +++ b/src/world/Script/ScriptMgr.h @@ -109,6 +109,8 @@ namespace Sapphire::Scripting bool onInstanceEnterTerritory( QuestBattlePtr instance, Entity::Player& player, uint32_t eventId, uint16_t param1, uint16_t param2 ); + bool onDutyComplete( QuestBattlePtr instance, Entity::Player& player ); + bool loadDir( const std::string& dirname, std::set< std::string >& files, const std::string& ext ); NativeScriptMgr& getNativeScriptHandler(); diff --git a/src/world/Territory/Cell.cpp b/src/world/Territory/Cell.cpp index 2ac8da95..d4ea8bf0 100644 --- a/src/world/Territory/Cell.cpp +++ b/src/world/Territory/Cell.cpp @@ -39,7 +39,7 @@ void Sapphire::Cell::addActor( Entity::ActorPtr pAct ) m_actors.insert( pAct ); } -void Sapphire::Cell::removeActor( Entity::ActorPtr pAct ) +void Sapphire::Cell::removeActorFromCell( Entity::ActorPtr pAct ) { if( pAct->isPlayer() ) --m_playerCount; diff --git a/src/world/Territory/Cell.h b/src/world/Territory/Cell.h index f414451a..c1cf413d 100644 --- a/src/world/Territory/Cell.h +++ b/src/world/Territory/Cell.h @@ -36,7 +36,7 @@ public: void addActor( Entity::ActorPtr pAct ); - void removeActor( Entity::ActorPtr pAct ); + void removeActorFromCell( Entity::ActorPtr pAct ); bool hasActor( Entity::ActorPtr pAct ) { diff --git a/src/world/Territory/QuestBattle.cpp b/src/world/Territory/QuestBattle.cpp index 227d82ba..097266c6 100644 --- a/src/world/Territory/QuestBattle.cpp +++ b/src/world/Territory/QuestBattle.cpp @@ -333,3 +333,33 @@ void Sapphire::QuestBattle::clearDirector( Entity::Player& player ) // remove "bound by duty" state player.unsetStateFlag( PlayerStateFlag::BoundByDuty ); } + +void Sapphire::QuestBattle::success() +{ + + m_pPlayer->eventStart( m_pPlayer->getId(), getDirectorId(), Event::EventHandler::GameProgress, 1, 0 ); + m_pPlayer->playScene( getDirectorId(), 60001, 0x40000, + [ & ]( Entity::Player& player, const Event::SceneResult& result ) + { + player.eventFinish( getDirectorId(), 1 ); + player.eventStart( player.getId(), getDirectorId(), Event::EventHandler::GameProgress, 1, 0 ); + player.playScene( getDirectorId(), 6, HIDE_HOTBAR | NO_DEFAULT_CAMERA, + [ & ]( Entity::Player& player, const Event::SceneResult& result ) + { + player.eventFinish( getDirectorId(), 1 ); + auto pScriptMgr = m_pFw->get< Scripting::ScriptMgr >(); + pScriptMgr->onDutyComplete( getAsQuestBattle(), *m_pPlayer ); + } ); + + } ); +} + +void Sapphire::QuestBattle::fail() +{ + +} + +uint32_t Sapphire::QuestBattle::getQuestId() const +{ + return m_pBattleDetails->quest; +} diff --git a/src/world/Territory/QuestBattle.h b/src/world/Territory/QuestBattle.h index 67495c65..4667d5ce 100644 --- a/src/world/Territory/QuestBattle.h +++ b/src/world/Territory/QuestBattle.h @@ -61,6 +61,11 @@ namespace Sapphire void endEventCutscene(); + uint32_t getQuestId() const; + + void fail(); + void success(); + void clearDirector( Entity::Player& player ); Event::Director::DirectorState getState() const; diff --git a/src/world/Territory/Zone.cpp b/src/world/Territory/Zone.cpp index be66bcc4..2632cf2e 100644 --- a/src/world/Territory/Zone.cpp +++ b/src/world/Territory/Zone.cpp @@ -234,9 +234,6 @@ void Sapphire::Zone::pushActor( Entity::ActorPtr pActor ) auto pPlayer = pActor->getAsPlayer(); auto pServerZone = m_pFw->get< World::ServerMgr >(); - auto pSession = pServerZone->getSession( pPlayer->getId() ); - if( pSession ) - m_sessionSet.insert( pSession ); m_playerMap[ pPlayer->getId() ] = pPlayer; updateCellActivity( cx, cy, 2 ); } @@ -259,7 +256,7 @@ void Sapphire::Zone::removeActor( Entity::ActorPtr pActor ) Cell* pCell = getCellPtr( cx, cy ); if( pCell && pCell->hasActor( pActor ) ) - pCell->removeActor( pActor ); + pCell->removeActorFromCell( pActor ); if( pActor->isPlayer() ) { @@ -459,26 +456,22 @@ bool Sapphire::Zone::update( uint64_t tickCount ) void Sapphire::Zone::updateSessions( uint64_t tickCount, bool changedWeather ) { // update sessions in this zone - for( auto it = m_sessionSet.begin(); it != m_sessionSet.end(); ++it ) + for( auto it = m_playerMap.begin(); it != m_playerMap.end(); ++it ) { - auto pSession = *it; + auto pPlayer = it->second; - if( !pSession ) + if( !pPlayer ) { - it = m_sessionSet.erase( it ); - continue; + m_playerMap.erase( it ); + return; } - auto pPlayer = pSession->getPlayer(); - // this session is not linked to this area anymore, remove it from zone session list if( ( !pPlayer->getCurrentZone() ) || ( pPlayer->getCurrentZone() != shared_from_this() ) ) { - removeActor( pSession->getPlayer() ); - - it = m_sessionSet.erase( it ); - continue; + removeActor( pPlayer ); + return; } m_lastUpdate = tickCount; @@ -488,11 +481,15 @@ void Sapphire::Zone::updateSessions( uint64_t tickCount, bool changedWeather ) auto weatherChangePacket = makeZonePacket< FFXIVIpcWeatherChange >( pPlayer->getId() ); weatherChangePacket->data().weatherId = static_cast< uint8_t >( m_currentWeather ); weatherChangePacket->data().delay = 5.0f; - pSession->getPlayer()->queuePacket( weatherChangePacket ); + pPlayer->queuePacket( weatherChangePacket ); } // perform session duties - pSession->update(); + pPlayer->getSession()->update(); + + // this session is not linked to this area anymore, remove it from zone session list + if( ( !pPlayer->getCurrentZone() ) || ( pPlayer->getCurrentZone() != shared_from_this() ) ) + return; } } @@ -599,7 +596,7 @@ void Sapphire::Zone::updateActorPosition( Entity::Actor& actor ) if( pOldCell ) { - pOldCell->removeActor( actor.shared_from_this() ); + pOldCell->removeActorFromCell( actor.shared_from_this() ); } pCell->addActor( actor.shared_from_this() ); diff --git a/src/world/Territory/Zone.h b/src/world/Territory/Zone.h index bd91d0be..88927be5 100644 --- a/src/world/Territory/Zone.h +++ b/src/world/Territory/Zone.h @@ -21,7 +21,6 @@ namespace Sapphire class ZonePosition; - using SessionSet = std::set< World::SessionPtr >; using FestivalPair = std::pair< uint16_t, uint16_t >; namespace Data @@ -44,8 +43,6 @@ namespace Sapphire std::unordered_map< int32_t, Entity::BNpcPtr > m_bNpcMap; std::unordered_map< int32_t, Entity::EventObjectPtr > m_eventObjects; - SessionSet m_sessionSet; - Common::Weather m_currentWeather; Common::Weather m_weatherOverride; std::map< uint8_t, int32_t > m_weatherRateMap; diff --git a/src/world/Util/ActorFilter.cpp b/src/world/Util/ActorFilter.cpp index ec7fee56..db5ab81a 100644 --- a/src/world/Util/ActorFilter.cpp +++ b/src/world/Util/ActorFilter.cpp @@ -14,7 +14,7 @@ Sapphire::World::Util::ActorFilterInRange::ActorFilterInRange( Common::FFXIVARR_ bool Sapphire::World::Util::ActorFilterInRange::conditionApplies( const Entity::Actor& actor ) { return Sapphire::Util::distance( m_startPos.x, m_startPos.y, m_startPos.z, - actor.getPos().x, actor.getPos().y, actor.getPos().z ) <= m_range; + actor.getPos().x, actor.getPos().y, actor.getPos().z ) <= m_range; } /////////////////////////////////////////////////////////////////////////////////////////////////////// From e4b919e319825d65d6134a01a0fde4571c9fcb17 Mon Sep 17 00:00:00 2001 From: Mordred Date: Sun, 7 Apr 2019 16:01:53 +0200 Subject: [PATCH 2/4] Show svent on questbattle completion, remove inactive questbattle instances --- src/scripts/quest/ManFst005.cpp | 15 ++++- src/world/Manager/TerritoryMgr.cpp | 57 ++++++++++++++----- src/world/Manager/TerritoryMgr.h | 10 +++- .../Housing/HousingInteriorTerritory.cpp | 7 --- .../Housing/HousingInteriorTerritory.h | 3 - src/world/Territory/Zone.cpp | 11 +++- src/world/Territory/Zone.h | 4 ++ 7 files changed, 77 insertions(+), 30 deletions(-) diff --git a/src/scripts/quest/ManFst005.cpp b/src/scripts/quest/ManFst005.cpp index 963f6a26..c54f1f14 100644 --- a/src/scripts/quest/ManFst005.cpp +++ b/src/scripts/quest/ManFst005.cpp @@ -69,6 +69,14 @@ class ManFst005 : public Sapphire::ScriptAPI::EventScript Scene00002( player ); } + void onEnterTerritory( Entity::Player& player, uint32_t eventId, uint16_t param1, uint16_t param2 ) override + { + if( player.getQuestSeq( eventId ) == Seq2 ) + { + Scene00005( player ); + } + } + private: ////////////////////////////////////////////////////////////////////// // Available Scenes in this quest, not necessarly all are used @@ -129,9 +137,14 @@ class ManFst005 : public Sapphire::ScriptAPI::EventScript void Scene00005( Entity::Player& player ) { - player.playScene( getId(), 5, HIDE_HOTBAR, + player.playScene( getId(), 5, NO_DEFAULT_CAMERA | CONDITION_CUTSCENE | SILENT_ENTER_TERRI_ENV | + HIDE_HOTBAR | SILENT_ENTER_TERRI_BGM | SILENT_ENTER_TERRI_SE | + DISABLE_STEALTH | 0x00100000 | LOCK_HUD | LOCK_HOTBAR | + // todo: wtf is 0x00100000 + DISABLE_CANCEL_EMOTE, [ & ]( Entity::Player& player, const Event::SceneResult& result ) { + player.updateQuest( result.eventId, Seq3 ); } ); } diff --git a/src/world/Manager/TerritoryMgr.cpp b/src/world/Manager/TerritoryMgr.cpp index c288868f..f02429d8 100644 --- a/src/world/Manager/TerritoryMgr.cpp +++ b/src/world/Manager/TerritoryMgr.cpp @@ -189,7 +189,7 @@ bool Sapphire::World::Manager::TerritoryMgr::createDefaultTerritories() InstanceIdToZonePtrMap instanceMap; instanceMap[ guid ] = pZone; - m_instanceIdToZonePtrMap[ guid ] = pZone; + m_guIdToZonePtrMap[ guid ] = pZone; m_territoryTypeIdToInstanceGuidMap[ territoryTypeId ] = instanceMap; m_zoneSet.insert( { pZone } ); @@ -235,7 +235,7 @@ bool Sapphire::World::Manager::TerritoryMgr::createHousingTerritories() InstanceIdToZonePtrMap instanceMap; instanceMap[ guid ] = pHousingZone; - m_instanceIdToZonePtrMap[ guid ] = pHousingZone; + m_guIdToZonePtrMap[ guid ] = pHousingZone; m_territoryTypeIdToInstanceGuidMap[ territoryTypeId ][ guid ] = pHousingZone; m_landSetIdToZonePtrMap[ pHousingZone->getLandSetId() ] = pHousingZone; m_zoneSet.insert( { pHousingZone } ); @@ -266,7 +266,7 @@ Sapphire::ZonePtr Sapphire::World::Manager::TerritoryMgr::createTerritoryInstanc auto pZone = make_Zone( territoryTypeId, getNextInstanceId(), pTeri->name, pPlaceName->name, framework() ); pZone->init(); - m_instanceIdToZonePtrMap[ pZone->getGuId() ] = pZone; + m_guIdToZonePtrMap[ pZone->getGuId() ] = pZone; m_territoryTypeIdToInstanceGuidMap[ pZone->getTerritoryTypeId() ][ pZone->getGuId() ] = pZone; m_zoneSet.insert( { pZone } ); @@ -305,8 +305,8 @@ Sapphire::ZonePtr Sapphire::World::Manager::TerritoryMgr::createQuestBattle( uin pTeri->name, pQuestInfo->name, questBattleId, framework() ); pZone->init(); - m_instanceContentIdToInstanceMap[ questBattleId ][ pZone->getGuId() ] = pZone; - m_instanceIdToZonePtrMap[ pZone->getGuId() ] = pZone; + m_questBattleIdToInstanceMap[ questBattleId ][ pZone->getGuId() ] = pZone; + m_guIdToZonePtrMap[ pZone->getGuId() ] = pZone; m_instanceZoneSet.insert( pZone ); return pZone; @@ -340,7 +340,7 @@ Sapphire::ZonePtr Sapphire::World::Manager::TerritoryMgr::createInstanceContent( pZone->init(); m_instanceContentIdToInstanceMap[ instanceContentId ][ pZone->getGuId() ] = pZone; - m_instanceIdToZonePtrMap[ pZone->getGuId() ] = pZone; + m_guIdToZonePtrMap[ pZone->getGuId() ] = pZone; m_instanceZoneSet.insert( pZone ); return pZone; @@ -413,19 +413,19 @@ Sapphire::ZonePtr Sapphire::World::Manager::TerritoryMgr::findOrCreateHousingInt zone->init(); m_landIdentToZonePtrMap[ ident ] = zone; - m_instanceIdToZonePtrMap[ zone->getGuId() ] = zone; + m_guIdToZonePtrMap[ zone->getGuId() ] = zone; m_zoneSet.insert( { zone } ); return zone; } -bool Sapphire::World::Manager::TerritoryMgr::removeTerritoryInstance( uint32_t instanceId ) +bool Sapphire::World::Manager::TerritoryMgr::removeTerritoryInstance( uint32_t guId ) { ZonePtr pZone; - if( ( pZone = getInstanceZonePtr( instanceId ) ) == nullptr ) + if( ( pZone = getInstanceZonePtr( guId ) ) == nullptr ) return false; - m_instanceIdToZonePtrMap.erase( pZone->getGuId() ); + m_guIdToZonePtrMap.erase( pZone->getGuId() ); m_instanceZoneSet.erase( pZone ); m_zoneSet.erase( pZone ); @@ -438,14 +438,13 @@ bool Sapphire::World::Manager::TerritoryMgr::removeTerritoryInstance( uint32_t i else m_territoryTypeIdToInstanceGuidMap[ pZone->getTerritoryTypeId() ].erase( pZone->getGuId() ); - return true; } -Sapphire::ZonePtr Sapphire::World::Manager::TerritoryMgr::getInstanceZonePtr( uint32_t instanceId ) const +Sapphire::ZonePtr Sapphire::World::Manager::TerritoryMgr::getInstanceZonePtr( uint32_t guId ) const { - auto it = m_instanceIdToZonePtrMap.find( instanceId ); - if( it == m_instanceIdToZonePtrMap.end() ) + auto it = m_guIdToZonePtrMap.find( guId ); + if( it == m_guIdToZonePtrMap.end() ) return nullptr; return it->second; @@ -532,9 +531,37 @@ void Sapphire::World::Manager::TerritoryMgr::updateTerritoryInstances( uint64_t else it++; } + + // remove internal house zones with nobody in them + for( auto it = m_questBattleIdToInstanceMap.begin(); it != m_questBattleIdToInstanceMap.end(); ++it ) + { + for( auto inIt = it->second.begin(); inIt != it->second.end(); ) + { + auto zone = std::dynamic_pointer_cast< QuestBattle >( inIt->second ); + if( !zone ) + continue; + + auto diff = std::difftime( tickCount, zone->getLastActivityTime() ); + + // todo: make this timeout configurable, though should be pretty relaxed in any case + if( diff > 6000 ) + { + Logger::info( "Removing QuestBattle#{0} - has been inactive for 60 seconds", zone->getGuId() ); + + // remove zone from maps + m_instanceZoneSet.erase( zone ); + m_guIdToZonePtrMap.erase( zone->getGuId() ); + inIt = m_questBattleIdToInstanceMap[ zone->getQuestBattleId() ].erase( inIt ); + } + else + inIt++; + } + + } } -Sapphire::World::Manager::TerritoryMgr::InstanceIdList Sapphire::World::Manager::TerritoryMgr::getInstanceContentIdList( uint16_t instanceContentId ) const +Sapphire::World::Manager::TerritoryMgr::InstanceIdList + Sapphire::World::Manager::TerritoryMgr::getInstanceContentIdList( uint16_t instanceContentId ) const { std::vector< uint32_t > idList; auto zoneMap = m_instanceContentIdToInstanceMap.find( instanceContentId ); diff --git a/src/world/Manager/TerritoryMgr.h b/src/world/Manager/TerritoryMgr.h index e0d8dbae..22354fe4 100644 --- a/src/world/Manager/TerritoryMgr.h +++ b/src/world/Manager/TerritoryMgr.h @@ -111,10 +111,10 @@ namespace Sapphire::World::Manager ZonePtr findOrCreateHousingInterior( const Common::LandIdent landIdent ); /*! removes instance by instanceId, return true if successful */ - bool removeTerritoryInstance( uint32_t territoryTypeId ); + bool removeTerritoryInstance( uint32_t guId ); /*! returns a ZonePtr to the instance or nullptr if not found */ - ZonePtr getInstanceZonePtr( uint32_t instanceId ) const; + ZonePtr getInstanceZonePtr( uint32_t guId ) const; /*! returns the cached detail of a territory, nullptr if not found */ Data::TerritoryTypePtr getTerritoryDetail( uint32_t territoryTypeId ) const; @@ -165,6 +165,7 @@ namespace Sapphire::World::Manager using LandSetIdToZonePtrMap = std::unordered_map< uint32_t, ZonePtr >; using TerritoryTypeIdToInstanceMap = std::unordered_map< uint16_t, InstanceIdToZonePtrMap >; using InstanceContentIdToInstanceMap = std::unordered_map< uint16_t, InstanceIdToZonePtrMap >; + using QuestBattleIdToInstanceMap = std::unordered_map< uint16_t, InstanceIdToZonePtrMap >; using PlayerIdToInstanceIdMap = std::unordered_map< uint32_t, uint32_t >; using PositionMap = std::unordered_map< int32_t, ZonePositionPtr >; using InstanceIdList = std::vector< uint32_t >; @@ -182,8 +183,11 @@ namespace Sapphire::World::Manager /*! map holding actual instances of InstanceContent */ InstanceContentIdToInstanceMap m_instanceContentIdToInstanceMap; + /*! map holding actual instances of InstanceContent */ + QuestBattleIdToInstanceMap m_questBattleIdToInstanceMap; + /*! flat map for easier lookup of instances by guid */ - InstanceIdToZonePtrMap m_instanceIdToZonePtrMap; + InstanceIdToZonePtrMap m_guIdToZonePtrMap; /*! map holding positions for zonelines */ PositionMap m_territoryPositionMap; diff --git a/src/world/Territory/Housing/HousingInteriorTerritory.cpp b/src/world/Territory/Housing/HousingInteriorTerritory.cpp index 761efeed..7ffa045c 100644 --- a/src/world/Territory/Housing/HousingInteriorTerritory.cpp +++ b/src/world/Territory/Housing/HousingInteriorTerritory.cpp @@ -39,7 +39,6 @@ Sapphire::World::Territory::Housing::HousingInteriorTerritory::HousingInteriorTe Zone( territoryTypeId, guId, internalName, contentName, pFw ), m_landIdent( ident ) { - m_lastActivityTime = 0; } Housing::HousingInteriorTerritory::~HousingInteriorTerritory() = default; @@ -105,13 +104,7 @@ void Sapphire::World::Territory::Housing::HousingInteriorTerritory::onPlayerZone void Sapphire::World::Territory::Housing::HousingInteriorTerritory::onUpdate( uint64_t tickCount ) { - if( m_playerMap.size() > 0 ) - m_lastActivityTime = tickCount; -} -uint64_t Sapphire::World::Territory::Housing::HousingInteriorTerritory::getLastActivityTime() const -{ - return m_lastActivityTime; } const Common::LandIdent Sapphire::World::Territory::Housing::HousingInteriorTerritory::getLandIdent() const diff --git a/src/world/Territory/Housing/HousingInteriorTerritory.h b/src/world/Territory/Housing/HousingInteriorTerritory.h index b108d4e4..3993ba39 100644 --- a/src/world/Territory/Housing/HousingInteriorTerritory.h +++ b/src/world/Territory/Housing/HousingInteriorTerritory.h @@ -21,8 +21,6 @@ namespace Sapphire::World::Territory::Housing void onPlayerZoneIn( Entity::Player& player ) override; void onUpdate( uint64_t tickCount ) override; - uint64_t getLastActivityTime() const; - const Common::LandIdent getLandIdent() const; void updateHousingObjects(); @@ -34,7 +32,6 @@ namespace Sapphire::World::Territory::Housing private: Common::LandIdent m_landIdent; - uint64_t m_lastActivityTime; std::array< Sapphire::Common::HousingObject, 400 > m_housingObjects; }; diff --git a/src/world/Territory/Zone.cpp b/src/world/Territory/Zone.cpp index 2632cf2e..b4fa93c1 100644 --- a/src/world/Territory/Zone.cpp +++ b/src/world/Territory/Zone.cpp @@ -69,7 +69,8 @@ Sapphire::Zone::Zone( uint16_t territoryTypeId, uint32_t guId, m_nextEObjId( 0x400D0000 ), m_nextActorId( 0x500D0000 ), m_pFw( pFw ), - m_lastUpdate( 0 ) + m_lastUpdate( 0 ), + m_lastActivityTime( Util::getTimeMs() ) { auto pExdData = m_pFw->get< Data::ExdDataGenerated >(); m_guId = guId; @@ -439,6 +440,10 @@ void Sapphire::Zone::updateBNpcs( uint64_t tickCount ) } +uint64_t Sapphire::Zone::getLastActivityTime() const +{ + return m_lastActivityTime; +} bool Sapphire::Zone::update( uint64_t tickCount ) { @@ -450,6 +455,10 @@ bool Sapphire::Zone::update( uint64_t tickCount ) onUpdate( tickCount ); updateSpawnPoints(); + + if( m_playerMap.size() > 0 ) + m_lastActivityTime = tickCount; + return true; } diff --git a/src/world/Territory/Zone.h b/src/world/Territory/Zone.h index 88927be5..699c24ae 100644 --- a/src/world/Territory/Zone.h +++ b/src/world/Territory/Zone.h @@ -50,6 +50,8 @@ namespace Sapphire int64_t m_lastMobUpdate; int64_t m_lastUpdate; + uint64_t m_lastActivityTime; + FestivalPair m_currentFestival; std::shared_ptr< Data::TerritoryType > m_territoryTypeInfo; @@ -81,6 +83,8 @@ namespace Sapphire std::shared_ptr< Data::TerritoryType > getTerritoryTypeInfo() const; + uint64_t getLastActivityTime() const; + virtual bool init(); virtual void loadCellCache(); From c7023fb6a3bb36938f93ce99139b6c5bcf76d485 Mon Sep 17 00:00:00 2001 From: Mordred Date: Sun, 7 Apr 2019 23:42:24 +0200 Subject: [PATCH 3/4] Move questbattle opening scene into the script --- src/scripts/instances/questbattles/ChasingShadows.cpp | 8 ++++++-- src/world/Manager/TerritoryMgr.cpp | 4 ++-- src/world/Territory/QuestBattle.cpp | 9 +-------- 3 files changed, 9 insertions(+), 12 deletions(-) diff --git a/src/scripts/instances/questbattles/ChasingShadows.cpp b/src/scripts/instances/questbattles/ChasingShadows.cpp index 91fe7d9c..6398411f 100644 --- a/src/scripts/instances/questbattles/ChasingShadows.cpp +++ b/src/scripts/instances/questbattles/ChasingShadows.cpp @@ -49,13 +49,17 @@ public: void onEnterTerritory( QuestBattle& instance, Entity::Player& player, uint32_t eventId, uint16_t param1, uint16_t param2 ) override { - + player.playScene( instance.getDirectorId(), 1, + NO_DEFAULT_CAMERA | CONDITION_CUTSCENE | SILENT_ENTER_TERRI_ENV | + HIDE_HOTBAR | SILENT_ENTER_TERRI_BGM | SILENT_ENTER_TERRI_SE | + DISABLE_STEALTH | 0x00100000 | LOCK_HUD | LOCK_HOTBAR | + // todo: wtf is 0x00100000 + DISABLE_CANCEL_EMOTE, 0 ); } void onDutyComplete( QuestBattle& instance, Entity::Player& player ) override { player.updateQuest( instance.getQuestId(), 2 ); - player.exitInstance(); } }; diff --git a/src/world/Manager/TerritoryMgr.cpp b/src/world/Manager/TerritoryMgr.cpp index f02429d8..d80bff60 100644 --- a/src/world/Manager/TerritoryMgr.cpp +++ b/src/world/Manager/TerritoryMgr.cpp @@ -520,7 +520,7 @@ void Sapphire::World::Manager::TerritoryMgr::updateTerritoryInstances( uint64_t auto diff = std::difftime( tickCount, zone->getLastActivityTime() ); // todo: make this timeout configurable, though should be pretty relaxed in any case - if( diff > 6000 ) + if( diff > 60000 ) { Logger::info( "Removing HousingInteriorTerritory#{0} - has been inactive for 60 seconds", zone->getGuId() ); @@ -544,7 +544,7 @@ void Sapphire::World::Manager::TerritoryMgr::updateTerritoryInstances( uint64_t auto diff = std::difftime( tickCount, zone->getLastActivityTime() ); // todo: make this timeout configurable, though should be pretty relaxed in any case - if( diff > 6000 ) + if( diff > 60000 ) { Logger::info( "Removing QuestBattle#{0} - has been inactive for 60 seconds", zone->getGuId() ); diff --git a/src/world/Territory/QuestBattle.cpp b/src/world/Territory/QuestBattle.cpp index 097266c6..68a9fb3f 100644 --- a/src/world/Territory/QuestBattle.cpp +++ b/src/world/Territory/QuestBattle.cpp @@ -315,14 +315,6 @@ Sapphire::QuestBattle::onEnterTerritory( Entity::Player& player, uint32_t eventI { auto pScriptMgr = m_pFw->get< Scripting::ScriptMgr >(); pScriptMgr->onInstanceEnterTerritory( getAsQuestBattle(), player, eventId, param1, param2 ); - - // TODO: this may or may not be correct for questbattles - player.playScene( getDirectorId(), 1, NO_DEFAULT_CAMERA | CONDITION_CUTSCENE | SILENT_ENTER_TERRI_ENV | - HIDE_HOTBAR | SILENT_ENTER_TERRI_BGM | SILENT_ENTER_TERRI_SE | - DISABLE_STEALTH | 0x00100000 | LOCK_HUD | LOCK_HOTBAR | - // todo: wtf is 0x00100000 - DISABLE_CANCEL_EMOTE, 0 ); - } void Sapphire::QuestBattle::clearDirector( Entity::Player& player ) @@ -349,6 +341,7 @@ void Sapphire::QuestBattle::success() player.eventFinish( getDirectorId(), 1 ); auto pScriptMgr = m_pFw->get< Scripting::ScriptMgr >(); pScriptMgr->onDutyComplete( getAsQuestBattle(), *m_pPlayer ); + player.exitInstance(); } ); } ); From 8d6f80b357d2d4c2f63f6c801d1ff82d90a2bdf0 Mon Sep 17 00:00:00 2001 From: Mordred Date: Sun, 7 Apr 2019 23:59:33 +0200 Subject: [PATCH 4/4] Shortcut adde for questbattle command --- src/world/Manager/DebugCommandMgr.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/world/Manager/DebugCommandMgr.cpp b/src/world/Manager/DebugCommandMgr.cpp index c4ac0789..f65bf4f9 100644 --- a/src/world/Manager/DebugCommandMgr.cpp +++ b/src/world/Manager/DebugCommandMgr.cpp @@ -60,6 +60,7 @@ Sapphire::World::Manager::DebugCommandMgr::DebugCommandMgr( FrameworkPtr pFw ) : registerCommand( "script", &DebugCommandMgr::script, "Server script utilities.", 1 ); registerCommand( "instance", &DebugCommandMgr::instance, "Instance utilities", 1 ); registerCommand( "questbattle", &DebugCommandMgr::questBattle, "Quest battle utilities", 1 ); + registerCommand( "qb", &DebugCommandMgr::questBattle, "Quest battle utilities", 1 ); registerCommand( "housing", &DebugCommandMgr::housing, "Housing utilities", 1 ); }