diff --git a/deps/datReader/Exd/Structs.h b/deps/datReader/Exd/Structs.h index 6bb0feda..cdcb3f21 100644 --- a/deps/datReader/Exd/Structs.h +++ b/deps/datReader/Exd/Structs.h @@ -3339,6 +3339,7 @@ namespace Excel struct SwitchTalk { SwitchTalkCaseStruct TalkCase[16]; + uint32_t Unknown1; }; /* 362351 */ diff --git a/src/scripts/common/FcTalk.cpp b/src/scripts/common/FcTalk.cpp new file mode 100644 index 00000000..65c3efc6 --- /dev/null +++ b/src/scripts/common/FcTalk.cpp @@ -0,0 +1,48 @@ +#include +#include + +#include + +using namespace Sapphire; + +class FcTalk : + public Sapphire::ScriptAPI::EventScript +{ +public: + FcTalk() : + Sapphire::ScriptAPI::EventScript( 0x001F0000 ) + { + } + + void onTalk( uint32_t eventId, Entity::Player& player, uint64_t actorId ) override + { + auto& exdData = Common::Service< Data::ExdData >::ref(); + auto switchTalk = exdData.getRow< Excel::SwitchTalk >( eventId ); + uint32_t talkEvent = 0; + + if( !switchTalk ) + return; + + for( auto entry = 15; entry >= 0; entry-- ) + { + auto caseCondition = switchTalk->data().TalkCase[ entry ].CaseCondition; + + if( ( caseCondition >> 16 ) == Event::EventHandler::EventHandlerType::Quest && player.isQuestCompleted( caseCondition ) ) + { + talkEvent = switchTalk->data().TalkCase[ entry ].Talk; + break; + } + else + { + talkEvent = switchTalk->data().TalkCase[ 0 ].Talk; + } + } + + if( talkEvent == 0 ) + return; + + eventMgr().playScene( player, talkEvent, 0, HIDE_HOTBAR | NO_DEFAULT_CAMERA, { 0 }, nullptr ); + } +}; + +EXPOSE_SCRIPT( FcTalk ); \ No newline at end of file diff --git a/src/scripts/common/SmallTalk.cpp b/src/scripts/common/SmallTalk.cpp new file mode 100644 index 00000000..67dadd1d --- /dev/null +++ b/src/scripts/common/SmallTalk.cpp @@ -0,0 +1,21 @@ +#include +#include + +using namespace Sapphire; + +class SmallTalk : + public Sapphire::ScriptAPI::EventScript +{ +public: + SmallTalk() : + Sapphire::ScriptAPI::EventScript( 0x000B0000 ) + { + } + + void onTalk( uint32_t eventId, Entity::Player& player, uint64_t actorId ) override + { + eventMgr().playScene( player, eventId, 0, HIDE_HOTBAR, { 0 }, nullptr ); + } +}; + +EXPOSE_SCRIPT( SmallTalk ); \ No newline at end of file diff --git a/src/scripts/instances/dungeons/Sastasha.cpp b/src/scripts/instances/dungeons/Sastasha.cpp index 6b0a1bcc..736e1795 100644 --- a/src/scripts/instances/dungeons/Sastasha.cpp +++ b/src/scripts/instances/dungeons/Sastasha.cpp @@ -29,8 +29,7 @@ private: enum Variables : uint8_t { - Coral, - ObtainedKey + Coral }; enum Sequence : uint8_t @@ -38,7 +37,8 @@ private: Seq1 = 1, Seq2 = 3, Seq3 = 7, - Seq4 = 15, + Seq4 = 23, + Seq5 = 31, SeqFinish = 255 }; @@ -210,7 +210,7 @@ public: [ & ]( Entity::Player& player, uint32_t eventId, uint64_t additional ) { eobj.setPermissionInvisibility( 1 ); - instance.setCustomVar( ObtainedKey, true ); + instance.setVar( 0, Seq4 ); instance.sendEventLogMessage( player, instance, 2031, { 2000512 } ); }, nullptr, getId() ); @@ -223,7 +223,7 @@ public: [ & ]( Entity::Player& player, uint32_t eventId, uint64_t additional ) { eobj.setPermissionInvisibility( 1 ); - instance.setVar( 0, Seq4 ); + instance.setVar( 0, Seq5 ); instance.sendEventLogMessage( player, instance, 2031, { 2000513 } ); denn = instance.createBNpcFromInstanceId( 3978771, 1000, Common::BNpcType::Enemy ); }, @@ -231,8 +231,8 @@ public: } // Open the door if the right key has been obtained - if( ( eobj.getName() == "Captainsquarters" && instance.getCustomVar( ObtainedKey ) ) || - ( eobj.getName() == "WaveriderGate" && instance.getDirectorVar( 0 ) == Seq4 ) ) + if( ( eobj.getName() == "Captainsquarters" && instance.getDirectorVar( 0 ) == Seq4 ) || + ( eobj.getName() == "WaveriderGate" && instance.getDirectorVar( 0 ) == Seq5 ) ) { eventMgr().playScene( player, eventId, 1, HIDE_HOTBAR, { 1 }, [ & ]( Entity::Player& player, const Event::SceneResult& result ) diff --git a/src/world/Actor/Player.h b/src/world/Actor/Player.h index df7fea04..02d0db58 100644 --- a/src/world/Actor/Player.h +++ b/src/world/Actor/Player.h @@ -107,6 +107,8 @@ namespace Sapphire::Entity /*! remove a given quest */ void removeQuest( uint16_t questId ); + bool isQuestCompleted( uint32_t questId ); + /*! add a quest to the completed quests mask */ void updateQuestsCompleted( uint32_t questId ); diff --git a/src/world/Actor/PlayerQuest.cpp b/src/world/Actor/PlayerQuest.cpp index c0409141..1cade20b 100644 --- a/src/world/Actor/PlayerQuest.cpp +++ b/src/world/Actor/PlayerQuest.cpp @@ -152,6 +152,16 @@ void Sapphire::Entity::Player::updateQuestsCompleted( uint32_t questId ) m_questCompleteFlags[ index ] |= value; } +bool Sapphire::Entity::Player::isQuestCompleted( uint32_t questId ) +{ + uint8_t index = questId / 8; + uint8_t bitIndex = ( questId ) % 8; + + uint8_t value = 0x80 >> bitIndex; + + return m_questCompleteFlags[ index ] & value; +} + void Sapphire::Entity::Player::removeQuestsCompleted( uint32_t questId ) { uint8_t index = questId / 8; diff --git a/src/world/Manager/EventMgr.cpp b/src/world/Manager/EventMgr.cpp index 412d32da..62d325cf 100644 --- a/src/world/Manager/EventMgr.cpp +++ b/src/world/Manager/EventMgr.cpp @@ -136,6 +136,11 @@ std::string EventMgr::getEventName( uint32_t eventId ) }*/ //return unknown + "GilShop"; } + + case Event::EventHandler::EventHandlerType::FcTalk: + { + return "FcTalk"; + } default: { return unknown;