From ec4209c57f7e8b07bf69c7ee5260d3df71bdaf31 Mon Sep 17 00:00:00 2001 From: GokuWeedLord Date: Sat, 16 Dec 2017 12:13:45 +1100 Subject: [PATCH] add some gridania quests and move some constants into ScriptObject --- scripts/native/ScriptObject.h | 83 +++++++ scripts/native/quest/ManFst001.cpp | 106 +++++++++ scripts/native/quest/ManFst002.cpp | 225 ++++++++++++++++++ .../quest/subquest/gridania/SubFst001.cpp | 86 +++++++ .../quest/subquest/gridania/SubFst010.cpp | 58 +++++ .../Server_Zone/Script/ScriptManager.cpp | 3 +- 6 files changed, 559 insertions(+), 2 deletions(-) create mode 100644 scripts/native/quest/ManFst001.cpp create mode 100644 scripts/native/quest/ManFst002.cpp create mode 100644 scripts/native/quest/subquest/gridania/SubFst001.cpp create mode 100644 scripts/native/quest/subquest/gridania/SubFst010.cpp diff --git a/scripts/native/ScriptObject.h b/scripts/native/ScriptObject.h index 6691f474..17da1520 100644 --- a/scripts/native/ScriptObject.h +++ b/scripts/native/ScriptObject.h @@ -7,5 +7,88 @@ #include #include +enum EventFlags +{ + NONE = 0, + NO_DEFAULT_CAMERA = 0x00000001, + FADE_OUT = 0x00000002, + INVIS_ENPC = 0x00000004, + INVIS_EOBJ = 0x00000008, + INVIS_BNPC = 0x00000010, + INVIS_OTHER_PC = 0x00000020, + INVIS_PARTY_PC = 0x00000040, + INVIS_PARTY_BUDDY = 0x10000000, + INVIS_GATHERING_POINT = 0x00000080, + INVIS_AETHERYTE = 0x00000100, + INVIS_TREASURE = 0x00000200, + CONDITION_CUTSCENE = 0x00000400, + HIDE_UI = 0x00000800, + INVIS_ALL = 0xF80003FC, + AUTO_LOC_CAMERA = 0x00001000, + HIDE_HOTBAR = 0x00002000, + INVINCIBLE = 0x00004000, + SILENT_ENTER_TERRI_ENV = 0x00008000, + SILENT_ENTER_TERRI_BGM = 0x00010000, + SILENT_ENTER_TERRI_SE = 0x00020000, + SILENT_ENTER_TERRI_ALL = 0x00038000, + DISABLE_SKIP = 0x00080000, + HIDE_FESTIVAL = 0x00200000, + DISABLE_STEALTH = 0x00400000, + ROLLBACK_HIDE_UI = 0x00800000, + LOCK_HUD = 0x01000000, + LOCK_HOTBAR = 0x02000000, + DISABLE_CANCEL_EMOTE = 0x04000000, + INVIS_AOE = 0x08000000, + INVIS_ALLIANCE_PC = 0x20000000, + INVIS_ALLIANCE_BUDDY = 0x40000000, + INVIS_COMPANION = 0x80000000, + SET_BASE = 0xF8400EFB, + SET_INVIS_BASE = 0xF8400FFF, + SET_EOBJ_BASE = 0xF8400EF3 +}; + +enum EventTypes +{ + EVENT_TALK = 1, + EVENT_EMOTE = 2, + EVENT_DISTANCE_BELOW = 3, + EVENT_DISTANCE_OVER = 4, + EVENT_BATTLE_REWARD = 5, + EVENT_CRAFT = 6, + EVENT_NEST = 7, + EVENT_EVENT_ITEM = 8, + EVENT_DROP = 9, + EVENT_WITHIN_RANGE = 10, + EVENT_OUTSIDE_RANGE = 11, + EVENT_GAME_START = 12, + EVENT_GAME_PROGRESS = 13, + EVENT_ENTER_TERRITORY = 15, + EVENT_GAME_COME_BACK = 17, + EVENT_ACTION_RESULT = 18, + EVENT_MATERIA_CRAFT = 19, + EVENT_FISHING = 20, + EVENT_UI = 21, + EVENT_HOUSING = 22, + EVENT_SAY = 23, + EVENT_TABLE_GAME = 24 +}; + +enum EventFinishState +{ + UNLOCK = 1, + KEEPLOCK = 0 +}; + +enum DamageType +{ + STD_DAMAGE = 0X03, + STD_HEAL = 0X04, + STD_MP_LOSS = 0X0A, + STD_MP_GAIN = 0X0B, + STD_TP_LOSS = 0X0C, + STD_TP_GAIN = 0X0D +}; + + #endif //SAPPHIRE_SCRIPTOBJECT_H diff --git a/scripts/native/quest/ManFst001.cpp b/scripts/native/quest/ManFst001.cpp new file mode 100644 index 00000000..5603657b --- /dev/null +++ b/scripts/native/quest/ManFst001.cpp @@ -0,0 +1,106 @@ +#include "../ScriptObject.h" + +// Quest Script: ManFst001_00039 +// Quest Name: Coming to Gridania +// Quest ID: 65575 +// Start NPC: 1001148 +// End NPC: 1001140 + +#define SEQ_0 0 +#define SEQ_FINISH 255 + +#define RewardExpFactor 50 +#define RewardGil 103 + +#define ACTOR0 1001148 +#define ACTOR1 1001140 +#define CUT_EVENT 29 +#define EOBJECT0 2001659 +#define EOBJECT1 2001660 +#define EOBJECT7 2616477 +#define EVENT_ACTION_SEARCH 1 +#define HOWTO_QUEST_ACCEPT 12 +#define HOWTO_QUEST_ANNOUNCE 2 +#define HOWTO_REWARD 11 +#define HOWTO_TODO 3 +#define OPENING_EVENT_HANDLER 1245186 +#define SEQ_2_ACTOR1 2 + +class ManFst001 : public EventScript +{ +private: + void Scene00000( Entity::Player& player ) + { + auto callback = [&]( Entity::Player& player, uint32_t eventId, uint16_t param1, uint16_t param2, uint16_t param3 ) + { + if( param2 == 1 ) // accept quest + { + player.setOpeningSequence( 2 ); + Scene00001( player ); + } + }; + + player.eventPlay( getId(), 0, HIDE_HOTBAR, 0, 0, callback ); + } + + void Scene00001( Entity::Player& player ) + { + auto callback = [&]( Entity::Player& player, uint32_t eventId, uint16_t param1, uint16_t param2, uint16_t param3 ) + { + Scene00002( player ); + }; + + player.eventPlay( getId(), 1, 0xF8482EFB, 0, 0, callback ); + } + + void Scene00002( Entity::Player& player ) + { + auto callback = [&]( Entity::Player& player, uint32_t eventId, uint16_t param1, uint16_t param2, uint16_t param3 ) + { + player.updateQuest( getId(), SEQ_FINISH ); + + player.eventPlay( OPENING_EVENT_HANDLER, 0x1E, HIDE_HOTBAR | NO_DEFAULT_CAMERA, 0, 0 ); + }; + + player.eventPlay( getId(), 2, 0, 0, 0, callback ); + } + + void Scene00004( Entity::Player& player ) + { + auto callback = [&]( Entity::Player& player, uint32_t eventId, uint16_t param1, uint16_t param2, uint16_t param3 ) + { + Scene00005( player ); + }; + + player.eventPlay( getId(), 4, 0x2c02, 0, 0, callback ); + } + + void Scene00005( Entity::Player& player ) + { + auto callback = [&]( Entity::Player& player, uint32_t eventId, uint16_t param1, uint16_t param2, uint16_t param3 ) + { + if( param2 == 1 ) + { + if( player.giveQuestRewards( getId(), 0 ) ) + player.finishQuest( getId() ); + } + }; + + player.eventPlay( getId(), 5, INVIS_OTHER_PC, 0, 0, callback ); + } + +public: + ManFst001() : EventScript( "ManFst001", 65575 ) {} + + void onTalk( uint32_t eventId, Entity::Player& player, uint64_t actorId ) override + { + auto actor = Event::mapEventActorToRealActor( static_cast< uint32_t >( actorId ) ); + + if( actor == ACTOR0 ) + Scene00000( player ); + else if( actor == ACTOR1 ) + Scene00004( player ); + } +}; + +EXPORT_SCRIPTOBJECT( ManFst001 ) \ No newline at end of file diff --git a/scripts/native/quest/ManFst002.cpp b/scripts/native/quest/ManFst002.cpp new file mode 100644 index 00000000..9857ba60 --- /dev/null +++ b/scripts/native/quest/ManFst002.cpp @@ -0,0 +1,225 @@ +#include "../ScriptObject.h" + +// Quest Script: ManFst002_00124 +// Quest Name: Close to Home +// Quest ID: 65660 +// Start NPC: 1001140 +// End NPC: 1000100 + +class ManFst002 : public EventScript +{ +private: + + static constexpr auto SEQ_0 = 0; + static constexpr auto SEQ_1 = 1; + static constexpr auto SEQ_FINISH = 255; + //this.SEQ_OFFER = ?; + + // Quest rewards + static constexpr auto RewardExpFactor = 100; + static constexpr auto RewardGil = 107; + + // Entities found in the script data of the quest + // some of these may be useful + static constexpr auto ACTOR0 = 1001140; + static constexpr auto ACTOR1 = 2; + static constexpr auto ACTOR2 = 1000251; + static constexpr auto ACTOR20 = 1000159; + static constexpr auto ACTOR3 = 1000768; + static constexpr auto ACTOR4 = 1000100; + static constexpr auto BIND_ACTOR0 = 6229224; + static constexpr auto HOW_TO_DESION = 13; + static constexpr auto HOW_TO_MAP_AND_NAVI = 4; + static constexpr auto ITEM0 = 2000074; + static constexpr auto LOC_ACTOR0 = 1003159; + static constexpr auto LOC_MARKER_01 = 2153091; + static constexpr auto LOC_MARKER_02 = 2153104; + static constexpr auto LOC_MARKER_03 = 2153111; + static constexpr auto LOC_MARKER_04 = 2154539; + static constexpr auto LOC_MARKER_05 = 2154540; + static constexpr auto LOC_MARKER_06 = 2154541; + static constexpr auto LOC_MARKER_07 = 2210446; + static constexpr auto LOC_MARKER_08 = 2210454; + static constexpr auto LOC_MARKER_09 = 2210461; + static constexpr auto LOC_MOTION0 = 799; + static constexpr auto POPRANGE0 = 2280858; + static constexpr auto REWARD_DESION = 1; + static constexpr auto SEQ_0_ACTOR0 = 0; + static constexpr auto SEQ_0_ACTOR0_LQ = 50; + static constexpr auto SEQ_1_ACTOR0 = 4; + static constexpr auto SEQ_1_ACTOR1 = 1; + static constexpr auto SEQ_1_ACTOR1_WAIT = 51; + static constexpr auto SEQ_1_ACTOR2 = 2; + static constexpr auto SEQ_1_ACTOR3 = 3; + static constexpr auto SEQ_1_ACTOR3_NPCTRADENO = 99; + static constexpr auto SEQ_1_ACTOR3_NPCTRADEOK = 100; + static constexpr auto SEQ_2_ACTOR4 = 5; + static constexpr auto TERRITORYTYPE0 = 132; + static constexpr auto UNLOCK_DESION = 14; + + + void checkQuestCompletion( Entity::Player& player, uint32_t varIdx ) + { + if( varIdx == 3 ) + player.sendQuestMessage( getId(), 1, 0, 0, 0 ); + else if( varIdx == 2 ) + player.sendQuestMessage( getId(), 2, 0, 0, 0 ); + else + player.sendQuestMessage( getId(), 0, 0, 0, 0 ); + + auto var_attuned = player.getQuestUI8AL( static_cast< uint16_t >( getId() ) ); + auto var_class = player.getQuestUI8BH( static_cast< uint16_t >( getId() ) ); + auto var_trade = player.getQuestUI8BL( static_cast< uint16_t >( getId() ) ); + + if( var_attuned == 1 && var_class == 1 && var_trade == 1 ) + player.updateQuest( getId(), SEQ_FINISH ); + } + + void Scene00000( Entity::Player& player ) + { + auto callback = [&]( Entity::Player& player, uint32_t eventId, uint16_t param1, uint16_t param2, uint16_t param3 ) + { + if( param2 == 1 ) // accept quest + Scene00050( player ); + }; + + player.eventPlay( getId(), 0, HIDE_HOTBAR, 0, 0, callback ); + } + + void Scene00001( Entity::Player& player ) + { + auto callback = [&]( Entity::Player& player, uint32_t eventId, uint16_t param1, uint16_t param2, uint16_t param3 ) + { + player.setQuestUI8AL( getId(), 1 ); + checkQuestCompletion( player, 0 ); + }; + + player.eventPlay( getId(), 1, 0x0EFB, 0, 0, callback ); + } + + void Scene00002( Entity::Player& player ) + { + auto callback = [&]( Entity::Player& player, uint32_t eventId, uint16_t param1, uint16_t param2, uint16_t param3 ) + { + player.setQuestUI8BH( getId(), 1 ); + checkQuestCompletion( player, 3 ); + }; + + player.eventPlay( getId(), 2, 0, 0, 0, callback ); + } + + void Scene00003( Entity::Player& player ) + { + auto callback = [&]( Entity::Player& player, uint32_t eventId, uint16_t param1, uint16_t param2, uint16_t param3 ) + { + if( param2 == 1 ) + Scene00100( player ); + else + Scene00099( player ); + }; + + player.eventPlay( getId(), 3, 0, 0, 0, callback ); + } + + void Scene00004( Entity::Player& player ) + { + player.eventPlay( getId(), 4, 0, 0, 0 ); + } + + void Scene00005( Entity::Player& player ) + { + auto callback = [&]( Entity::Player& player, uint32_t eventId, uint16_t param1, uint16_t param2, uint16_t param3 ) + { + if( param2 == 1 ) // finish quest + { + if( player.giveQuestRewards( getId(), 0 ) ) + player.finishQuest( getId() ); + } + }; + + player.eventPlay( getId(), 5, FADE_OUT | CONDITION_CUTSCENE | HIDE_UI, 0, 0, callback ); + } + + void Scene00050( Entity::Player& player ) + { + auto callback = [&]( Entity::Player& player, uint32_t eventId, uint16_t param1, uint16_t param2, uint16_t param3 ) + { + // on quest accept + player.updateQuest( getId(), 1 ); + player.setQuestUI8CH( getId(), 1 ); // receive key item + + // teleport to real gridania + player.forceZoneing( 132 ); + }; + + player.eventPlay( getId(), 50, FADE_OUT | CONDITION_CUTSCENE | HIDE_UI, 0, 0, callback ); + } + + void Scene00051( Entity::Player& player ) + { + auto callback = [&]( Entity::Player& player, uint32_t eventId, uint16_t param1, uint16_t param2, uint16_t param3 ) + { + Scene00001( player ); + }; + + player.eventPlay( getId(), 51, 0, 0, 0, callback ); + } + + void Scene00099( Entity::Player& player ) + { + auto callback = [&]( Entity::Player& player, uint32_t eventId, uint16_t param1, uint16_t param2, uint16_t param3 ) + { + Scene00004( player ); + }; + + player.eventPlay( getId(), 99, 0, 0, 0, callback ); + } + + void Scene00100( Entity::Player& player ) + { + auto callback = [&]( Entity::Player& player, uint32_t eventId, uint16_t param1, uint16_t param2, uint16_t param3 ) + { + player.setQuestUI8CH( getId(), 0 ); // remove traded key item + player.setQuestUI8BL( getId(), 1 ); + + checkQuestCompletion( player, 2 ); + }; + + player.eventPlay( getId(), 100, 0x0EFB, 0, 0, callback ); + } + +public: + ManFst002() : EventScript( "ManFst002", 65621 ) {} + + void onTalk( uint32_t eventId, Entity::Player& player, uint64_t actorId ) override + { + auto actor = Event::mapEventActorToRealActor( static_cast< uint32_t >( actorId ) ); + + if( actor == ACTOR0 ) + Scene00000( player ); + else if( actor == ACTOR1 ) + { + // attune + auto event = [&]( Entity::Player& player, uint32_t eventId, uint64_t additional ) + { + player.sendQuestMessage( 0x050002, 0, 1, 0, 0 ); + player.registerAetheryte( 2 ); + player.learnAction( 1 ); + + Scene00051( player ); + }; + + player.eventActionStart( 0x050002, 0x13, event, nullptr, 0x050002 ); + + player.unlock(); + } + else if( actor == ACTOR2 ) + Scene00002( player ); + else if( actor == ACTOR3 ) + Scene00003( player ); + else if( actor == ACTOR4 ) + Scene00005( player ); + } +}; + +EXPORT_SCRIPTOBJECT( ManFst002 ) \ No newline at end of file diff --git a/scripts/native/quest/subquest/gridania/SubFst001.cpp b/scripts/native/quest/subquest/gridania/SubFst001.cpp new file mode 100644 index 00000000..4b5a31a2 --- /dev/null +++ b/scripts/native/quest/subquest/gridania/SubFst001.cpp @@ -0,0 +1,86 @@ +#include "../../../ScriptObject.h" + +// Quest Script: SubFst001_00024 +// Quest Name: Coarse Correspondence +// Quest ID: 65560 +// Start NPC: 1000206 +// End NPC: 1000233 + +class SubFst001 : public EventScript +{ +private: + static constexpr auto SEQ_0 = 0; + static constexpr auto SEQ_FINISH = 255; + static constexpr auto ACTOR0 = 1000206; + static constexpr auto ACTOR1 = 1000233; + static constexpr auto ITEM0 = 2000079; + static constexpr auto SEQ_0_ACTOR0 = 0; + static constexpr auto SEQ_1_ACTOR1 = 1; + static constexpr auto SEQ_1_ACTOR1_NPCTRADENO = 99; + static constexpr auto SEQ_1_ACTOR1_NPCTRADEOK = 100; + + void Scene00000( Entity::Player& player ) + { + auto callback = [&]( Entity::Player& player, uint32_t eventId, uint16_t param1, uint16_t param2, uint16_t param3 ) + { + if( param2 == 1 ) // accept quest + { + player.setQuestUI8AL( getId(), 1 ); + player.setQuestUI8BH( getId(), 1 ); + player.updateQuest( getId(), SEQ_FINISH ); + } + }; + + player.eventPlay( getId(), 0, NONE, callback ); + } + + void Scene00001( Entity::Player& player ) + { + player.eventPlay( getId(), 1, NONE ); + } + + void Scene00099( Entity::Player& player ) + { + player.eventPlay( getId(), 99, NONE ); + } + + void Scene00100( Entity::Player& player ) + { + auto callback = [&]( Entity::Player& player, uint32_t eventId, uint16_t param1, uint16_t param2, uint16_t param3 ) + { + if( param2 == 1 ) // accept quest + { + if( player.giveQuestRewards( getId(), 0 ) ) + player.finishQuest( getId() ); + } + }; + + player.eventPlay( getId(), 100, NONE, callback ); + } + + +public: + SubFst001() : EventScript( "SubFst001", 65560 ) {} + + void onTalk( uint32_t eventId, Entity::Player& player, uint64_t actorId ) override + { + auto actor = Event::mapEventActorToRealActor( static_cast< uint32_t >( actorId ) ); + + if( actor == ACTOR0 ) + { + if( !player.hasQuest( getId() ) ) + Scene00000( player ); + else + Scene00001( player ); + } + else if( actor == ACTOR1 ) + { + if( !player.hasQuest( getId() ) ) + Scene00099( player ); + else + Scene00100( player ); + } + } +}; + +EXPORT_SCRIPTOBJECT( SubFst001 ) \ No newline at end of file diff --git a/scripts/native/quest/subquest/gridania/SubFst010.cpp b/scripts/native/quest/subquest/gridania/SubFst010.cpp new file mode 100644 index 00000000..6883fae6 --- /dev/null +++ b/scripts/native/quest/subquest/gridania/SubFst010.cpp @@ -0,0 +1,58 @@ +#include "../../../ScriptObject.h" + +// Quest Script: SubFst010_00001 +// Quest Name: A Good Adventurer Is Hard to Find +// Quest ID: 65537 +// Start NPC: 1000146 +// End NPC: 1000195 + +class SubFst010 : public EventScript +{ +private: + static constexpr auto SEQ_0 = 0; + static constexpr auto SEQ_FINISH = 255; + static constexpr auto ACTOR0 = 1000146; + static constexpr auto ACTOR1 = 1000195; + static constexpr auto SEQ_0_ACTOR0 = 0; + static constexpr auto SEQ_1_ACTOR1 = 1; + + void Scene00000( Entity::Player& player ) + { + auto callback = [&]( Entity::Player& player, uint32_t eventId, uint16_t param1, uint16_t param2, uint16_t param3 ) + { + if( param2 == 1 ) // accept quest + player.updateQuest( getId(), SEQ_FINISH ); + }; + + player.eventPlay( getId(), 0, NONE, callback ); + } + + void Scene00001( Entity::Player& player ) + { + auto callback = [&]( Entity::Player& player, uint32_t eventId, uint16_t param1, uint16_t param2, uint16_t param3 ) + { + if( param2 == 1 ) // finish quest + { + if( player.giveQuestRewards( getId(), 0 ) ) + player.finishQuest( getId() ); + } + }; + + player.eventPlay( getId(), 1, NONE, callback ); + } + +public: + SubFst010() : EventScript( "SubFst010", 65537 ) {} + + void onTalk( uint32_t eventId, Entity::Player& player, uint64_t actorId ) override + { + auto actor = Event::mapEventActorToRealActor( static_cast< uint32_t >( actorId ) ); + + if( actor == ACTOR0 ) + Scene00000( player ); + else if( actor == ACTOR1 ) + Scene00001( player ); + } +}; + +EXPORT_SCRIPTOBJECT( SubFst010 ) \ No newline at end of file diff --git a/src/servers/Server_Zone/Script/ScriptManager.cpp b/src/servers/Server_Zone/Script/ScriptManager.cpp index 039c59be..93210400 100644 --- a/src/servers/Server_Zone/Script/ScriptManager.cpp +++ b/src/servers/Server_Zone/Script/ScriptManager.cpp @@ -120,7 +120,6 @@ void Core::Scripting::ScriptManager::loadDir( const std::string& dirname, std::s files.insert( i.string() ); } } - } void Core::Scripting::ScriptManager::onPlayerFirstEnterWorld( Entity::Player& player ) @@ -185,7 +184,7 @@ bool Core::Scripting::ScriptManager::onTalk( Entity::Player& player, uint64_t ac auto questInfo = g_exdData.getQuestInfo( eventId ); if ( questInfo ) { - player.sendUrgent( "Quest not implemented: " + questInfo->name ); + player.sendUrgent( "Quest not implemented: " + questInfo->name + " (" + questInfo->name_intern + ")" ); } }