diff --git a/src/common/Network/CommonActorControl.h b/src/common/Network/CommonActorControl.h index 3b96f952..2f8775c0 100644 --- a/src/common/Network/CommonActorControl.h +++ b/src/common/Network/CommonActorControl.h @@ -269,6 +269,10 @@ enum ClientTriggerType AchievementComp = 0x203, AchievementCatChat = 0x206, + QuestJournalUpdateQuestVisibility = 0x2BE, + QuestJournalClosed = 0x2BF, + + AbandonQuest = 0x320, DirectorInitFinish = 0x321, diff --git a/src/servers/Scripts/quest/subquest/gridania/SubFst029.cpp b/src/servers/Scripts/quest/subquest/gridania/SubFst029.cpp index b81f82ee..a38eb63e 100644 --- a/src/servers/Scripts/quest/subquest/gridania/SubFst029.cpp +++ b/src/servers/Scripts/quest/subquest/gridania/SubFst029.cpp @@ -36,29 +36,24 @@ private: static constexpr auto Seq1Actor0Npctradeok = 100; public: - SubFst029() : - EventScript( 65708 ) - { - }; + SubFst029() : EventScript( 65708 ) + {}; ~SubFst029() - { - }; + {}; void onTalk( uint32_t eventId, Entity::Player& player, uint64_t actorId ) override { auto actor = Event::mapEventActorToRealActor( static_cast< uint32_t >( actorId ) ); - //NOT SAFE - CRASH - - /*if( actor == SubFst029::Actor0 && !player.hasQuest( getId() ) ) + if( actor == SubFst029::Actor0 && !player.hasQuest( getId() ) ) { Scene00000( player ); } if( actor == SubFst029::Actor0 && player.getQuestSeq ( getId() ) == 255 ) { Scene00001( player ); - }*/ + } } private: @@ -80,7 +75,7 @@ private: player.playScene( getId(), 1, HIDE_HOTBAR, [ & ]( Entity::Player& player, const Event::SceneResult& result ) { - if( result.param2 == 1 ) + if( result.param2 == 1 && player.collectHandInItems( { Ritem0 } ) ) { Scene00100( player ); } diff --git a/src/servers/sapphire_zone/Actor/Player.h b/src/servers/sapphire_zone/Actor/Player.h index 43376fc7..328cee2a 100644 --- a/src/servers/sapphire_zone/Actor/Player.h +++ b/src/servers/sapphire_zone/Actor/Player.h @@ -360,6 +360,13 @@ public: /*! return the current amount of crystals of type */ uint32_t getCrystal( uint8_t type ) const; + /*! + * Collect real item handins from container + * @param itemIds a vector of each catalog id to collect + * @return true if all items were handed in + */ + bool collectHandInItems( std::vector< uint32_t > itemIds ); + // Class / Job / Exp ////////////////////////////////////////////////////////////////////////////////////////////////////// /*! returns the level of the currently active class / job */ diff --git a/src/servers/sapphire_zone/Actor/PlayerInventory.cpp b/src/servers/sapphire_zone/Actor/PlayerInventory.cpp index 52d7f943..07a95123 100644 --- a/src/servers/sapphire_zone/Actor/PlayerInventory.cpp +++ b/src/servers/sapphire_zone/Actor/PlayerInventory.cpp @@ -781,3 +781,37 @@ uint8_t Core::Entity::Player::getFreeSlotsInBags() } return slots; } + +bool Core::Entity::Player::collectHandInItems( std::vector< uint32_t > itemIds ) +{ + // todo: figure out how the game gets the required stack count + auto& container = m_storageMap[HandIn]; + + std::vector< uint8_t > foundItems; + + auto itemMap = container->getItemMap(); + + for( auto& item : itemMap ) + { + for( auto needle : itemIds ) + { + if( item.second->getId() == needle ) + { + foundItems.push_back( item.first ); + break; + } + } + } + + // couldn't find all the items required + if( foundItems.size() != itemIds.size() ) + return false; + + // remove items + for( auto item : foundItems ) + { + container->removeItem( item ); + } + + return true; +} diff --git a/src/servers/sapphire_zone/Network/Handlers/ClientTriggerHandler.cpp b/src/servers/sapphire_zone/Network/Handlers/ClientTriggerHandler.cpp index 3282d68d..84406000 100644 --- a/src/servers/sapphire_zone/Network/Handlers/ClientTriggerHandler.cpp +++ b/src/servers/sapphire_zone/Network/Handlers/ClientTriggerHandler.cpp @@ -256,6 +256,10 @@ void Core::Network::GameConnection::clientTriggerHandler( const Packets::FFXIVAR player.exitInstance(); break; } + case ClientTriggerType::AbandonQuest: + { + player.removeQuest( static_cast< uint16_t >( param1 ) ); + } default: