diff --git a/src/common/Network/PacketDef/Ipcs.h b/src/common/Network/PacketDef/Ipcs.h index 254186fc..b212d056 100644 --- a/src/common/Network/PacketDef/Ipcs.h +++ b/src/common/Network/PacketDef/Ipcs.h @@ -165,6 +165,7 @@ namespace Sapphire::Network::Packets // nb: see #565 on github UpdateRetainerItemSalePrice = 0x019F, // updated 5.0 + RetainerInformation = 0x0169, // updated 5.25 SetLevelSync = 0x1186, // not updated for 4.4, not sure what it is anymore diff --git a/src/common/Network/PacketDef/Zone/ServerZoneDef.h b/src/common/Network/PacketDef/Zone/ServerZoneDef.h index a60dad20..f941f744 100644 --- a/src/common/Network/PacketDef/Zone/ServerZoneDef.h +++ b/src/common/Network/PacketDef/Zone/ServerZoneDef.h @@ -2021,6 +2021,25 @@ namespace Sapphire::Network::Packets::Server char otherName[32]; }; + + struct FFXIVIpcRetainerInformation : FFXIVIpcBasePacket< RetainerInformation > + { + uint8_t unknown0[8]; + uint64_t retainerId; + uint8_t hireOrder; + uint8_t itemCount; + uint8_t unknown5[2]; + uint32_t gil; + uint8_t sellingCount; + uint8_t cityId; + uint8_t classJob; + uint8_t level; + uint8_t unknown11[4]; + uint32_t retainerTask; + uint32_t retainerTaskComplete; + uint8_t unknown14; + char retainerName[20]; + }; struct FFXIVIpcCharaVisualEffect : FFXIVIpcBasePacket< CharaVisualEffect > { diff --git a/src/scripts/quest/classquest/ClsLnc000.cpp b/src/scripts/quest/classquest/LNC/ClsLnc000.cpp similarity index 100% rename from src/scripts/quest/classquest/ClsLnc000.cpp rename to src/scripts/quest/classquest/LNC/ClsLnc000.cpp diff --git a/src/scripts/quest/subquest/gridania/SubFst002.cpp b/src/scripts/quest/subquest/gridania/SubFst002.cpp index 1ed0fc15..7713deff 100644 --- a/src/scripts/quest/subquest/gridania/SubFst002.cpp +++ b/src/scripts/quest/subquest/gridania/SubFst002.cpp @@ -43,7 +43,7 @@ private: { if( result.param2 == 1 ) // finish quest { - if( player.giveQuestRewards( getId(), 0 ) ) + if( player.giveQuestRewards( getId(), result.param3 ) ) player.finishQuest( getId() ); } }; diff --git a/src/scripts/quest/subquest/gridania/SubFst007.cpp b/src/scripts/quest/subquest/gridania/SubFst007.cpp new file mode 100644 index 00000000..533e5d73 --- /dev/null +++ b/src/scripts/quest/subquest/gridania/SubFst007.cpp @@ -0,0 +1,134 @@ +#include +#include "Manager/EventMgr.h" +#include +#include + +using namespace Sapphire; + +// Quest Script: SubFst007_00031 +// Quest Name: Essential Oil +// Quest ID: 65567 +// Start NPC: 1000705 +// End NPC: 1000705 + +class SubFst007 : public Sapphire::ScriptAPI::EventScript +{ + private: + // Basic quest information + // Quest vars / flags used + // GetQuestUI8AL + // GetQuestUI8BH + + // Steps in this quest ( 0 is before accepting, + // 1 is first, 255 means ready for turning it in + enum Sequence : uint8_t + { + Seq0 = 0, + Seq1 = 1, + SeqFinish = 255, + }; + + // Quest rewards + static constexpr auto RewardExpFactor = 100; + uint32_t RewardItemOptional[3] = { 3530, 3531, 5823 }; + uint32_t RewardItemOptionalCount[3] = { 1, 1, 3 }; + + // Entities found in the script data of the quest + static constexpr auto Actor0 = 1000705; + static constexpr auto Enemy0 = 49; + static constexpr auto Item0 = 2000098; + static constexpr auto Seq0Actor0 = 0; + static constexpr auto Seq2Actor0 = 1; + static constexpr auto Seq2Actor0Npctradeno = 99; + static constexpr auto Seq2Actor0Npctradeok = 100; + + public: + SubFst007() : Sapphire::ScriptAPI::EventScript( 65567 ){}; + ~SubFst007(){}; + + ////////////////////////////////////////////////////////////////////// + // Event Handlers + void onTalk( uint32_t eventId, Entity::Player& player, uint64_t actorId ) override + { + auto pEventMgr = Common::Service< World::Manager::EventMgr >::ref(); + auto actor = pEventMgr.mapEventActorToRealActor( static_cast( actorId ) ); + + if ( actor == Actor0 && !player.hasQuest( getId() ) ) + { + Scene00000( player ); + } + if ( actor == Actor0 && player.getQuestSeq( getId() ) == SeqFinish ) + { + Scene00001( player ); + } + } + + void onBNpcKill( uint32_t npcId, Entity::Player& player ) + { + if ( npcId != Enemy0 ) + return; + + auto currentKC = player.getQuestUI8AL( getId() ); + + if ( currentKC + 1 >= 6 ) + { + player.setQuestUI8AL( getId(), currentKC + 1 ); + player.setQuestUI8BH( getId(), currentKC + 1 ); + player.sendQuestMessage( getId(), 0, 2, currentKC + 1, 6 ); + player.updateQuest( getId(), SeqFinish ); + } + else + { + player.sendQuestMessage( getId(), 0, 2, currentKC + 1, 6 ); + player.setQuestUI8AL( getId(), currentKC + 1 ); + player.setQuestUI8BH( getId(), currentKC + 1 ); + } + } + + private: + ////////////////////////////////////////////////////////////////////// + // Available Scenes in this quest, not necessarly all are used + void Scene00000( Entity::Player& player ) + { + player.playScene( getId(), 0, HIDE_HOTBAR, + [&]( Entity::Player& player, const Event::SceneResult& result ) + { + if( result.param2 == 1 ) + player.updateQuest( getId(), Seq1 ); + } ); + } + + void Scene00001( Entity::Player& player ) + { + player.playScene( getId(), 1, HIDE_HOTBAR, + [&]( Entity::Player& player, const Event::SceneResult& result ) + { + result.param2 == 1 ? Scene00100( player ) : Scene00099( player ); + } ); + } + + void Scene00099( Entity::Player& player ) + { + player.playScene( getId(), 99, HIDE_HOTBAR, + [&]( Entity::Player& player, const Event::SceneResult& result ) + { + } ); + } + + void Scene00100( Entity::Player& player ) + { + player.playScene( getId(), 100, HIDE_HOTBAR, + [&]( Entity::Player& player, const Event::SceneResult& result ) + { + if ( result.param2 == 1 ) + { + if ( player.giveQuestRewards( getId(), result.param3 ) ) + { + player.finishQuest( getId() ); + } + } + } ); + } +}; + +EXPOSE_SCRIPT(SubFst007); \ No newline at end of file diff --git a/src/scripts/quest/subquest/gridania/SubFst008.cpp b/src/scripts/quest/subquest/gridania/SubFst008.cpp index 93bc374a..ad00c64c 100644 --- a/src/scripts/quest/subquest/gridania/SubFst008.cpp +++ b/src/scripts/quest/subquest/gridania/SubFst008.cpp @@ -93,6 +93,7 @@ private: [ & ]( Entity::Player& player, const Event::SceneResult& result ) { player.setQuestUI8BH( getId(), 1 ); + player.sendQuestMessage( getId(), 0, 0, 0, 0 ); player.updateQuest( getId(), SeqFinish ); } ); } @@ -102,14 +103,7 @@ private: player.playScene( getId(), 2, HIDE_HOTBAR, [ & ]( Entity::Player& player, const Event::SceneResult& result ) { - if( result.param2 == 1 ) - { - Scene00100( player ); - } - else - { - Scene00099( player ); - } + result.param2 == 1 ? Scene00100( player ) : Scene00099( player ); } ); } @@ -131,7 +125,7 @@ private: { if( player.giveQuestRewards( getId(), 0 ) ) { - player.setQuestUI8BH( getId(), 0 ); + player.setQuestUI8BH( getId(), result.param3 ); player.finishQuest( getId() ); } } diff --git a/src/scripts/quest/subquest/gridania/SubFst011.cpp b/src/scripts/quest/subquest/gridania/SubFst011.cpp index 42bb9db7..63c37934 100644 --- a/src/scripts/quest/subquest/gridania/SubFst011.cpp +++ b/src/scripts/quest/subquest/gridania/SubFst011.cpp @@ -11,8 +11,6 @@ using namespace Sapphire; // Start NPC: 1000195 // End NPC: 1000195 -//NEED TEST KILLCREDIT - class SubFst011 : public Sapphire::ScriptAPI::EventScript { @@ -67,15 +65,12 @@ public: if( npcId != Enemy0 ) return; - auto currentKC = player.getQuestUI8AL( getId() ) + 1; + auto currentKC = player.getQuestUI8AL( getId() ); + player.setQuestUI8AL( getId(), currentKC + 1 ); + player.sendQuestMessage( getId(), 0, 2, currentKC + 1, 6 ); - if( currentKC >= 6 ) + if( currentKC + 1 >= 6 ) player.updateQuest( getId(), SeqFinish ); - else - { - player.setQuestUI8AL( getId(), currentKC ); - player.sendQuestMessage( getId(), 0, 2, currentKC, 6 ); - } } private: @@ -99,7 +94,7 @@ private: { if( result.param2 == 1 ) { - if( player.giveQuestRewards( getId(), 0 ) ) + if( player.giveQuestRewards( getId(), result.param3 ) ) { player.finishQuest( getId() ); } diff --git a/src/scripts/quest/subquest/gridania/SubFst014.cpp b/src/scripts/quest/subquest/gridania/SubFst014.cpp index 02908da6..8eff7725 100644 --- a/src/scripts/quest/subquest/gridania/SubFst014.cpp +++ b/src/scripts/quest/subquest/gridania/SubFst014.cpp @@ -63,7 +63,7 @@ public: { Scene00000( player ); } - else if( actor == Actor0 ) + else if( actor == Actor0 && player.getQuestSeq( getId() ) == SeqFinish ) { Scene00007( player ); } @@ -131,15 +131,13 @@ private: auto currentCC = player.getQuestUI8AL( getId() ); player.sendQuestMessage( getId(), 0, 2, currentCC + 1, 6 ); + player.setQuestUI8AL( getId(), currentCC + 1 ); + player.setQuestUI8BH( getId(), currentCC + 1 ); - if( currentCC + 1 >= 6 ) + if ( currentCC + 1 >= 6 ) { player.updateQuest( getId(), SeqFinish ); } - else - { - player.setQuestUI8AL( getId(), currentCC + 1 ); - } } void Scene00000( Entity::Player& player ) @@ -211,14 +209,10 @@ private: player.playScene( getId(), 7, HIDE_HOTBAR, [ & ]( Entity::Player& player, const Event::SceneResult& result ) { - if( result.param2 == 1 ) + if ( result.param2 == 1 ) { Scene00088( player ); } - else - { - Scene00087( player ); - } } ); } @@ -227,7 +221,6 @@ private: player.playScene( getId(), 87, HIDE_HOTBAR, [ & ]( Entity::Player& player, const Event::SceneResult& result ) { - player.playScene( getId(), 87, 0, 0, 0 ); } ); } @@ -236,13 +229,9 @@ private: player.playScene( getId(), 88, HIDE_HOTBAR, [ & ]( Entity::Player& player, const Event::SceneResult& result ) { - if( result.param2 == 1 ) + if ( player.giveQuestRewards( getId(), 0 ) ) { - if( player.giveQuestRewards( getId(), 0 ) ) - { - player.setQuestUI8AL( getId(), 0 ); - player.finishQuest( getId() ); - } + player.finishQuest( getId() ); } } ); } diff --git a/src/scripts/quest/subquest/gridania/SubFst021.cpp b/src/scripts/quest/subquest/gridania/SubFst021.cpp new file mode 100644 index 00000000..eac5b435 --- /dev/null +++ b/src/scripts/quest/subquest/gridania/SubFst021.cpp @@ -0,0 +1,112 @@ +// This is an automatically generated C++ script template +// Content needs to be added by hand to make it function +// In order for this script to be loaded, move it to the correct folder in /scripts/ + +#include +#include "Manager/EventMgr.h" +#include +#include + +// Quest Script: SubFst021_00095 +// Quest Name: Hematophagic Harassment +// Quest ID: 65631 +// Start NPC: 1000640 +// End NPC: 1000640 + +using namespace Sapphire; + +class SubFst021 : public Sapphire::ScriptAPI::EventScript +{ + private: + // Basic quest information + // Quest vars / flags used + // GetQuestUI8AL + + // Steps in this quest ( 0 is before accepting, + // 1 is first, 255 means ready for turning it in + enum Sequence : uint8_t + { + Seq0 = 0, + Seq1 = 1, + SeqFinish = 255, + }; + + // Entities found in the script data of the quest + static constexpr auto Actor0 = 1000640; + static constexpr auto Enemy0 = 118; //136; <- WRONG INFO + + public: + SubFst021() : Sapphire::ScriptAPI::EventScript( 65631 ){}; + ~SubFst021(){}; + + ////////////////////////////////////////////////////////////////////// + // Event Handlers + void onTalk( uint32_t eventId, Entity::Player& player, uint64_t actorId ) override + { + auto& eventMgr = Common::Service< World::Manager::EventMgr >::ref(); + auto actor = eventMgr.mapEventActorToRealActor( static_cast< uint32_t >( actorId ) ); + + if ( actor == Actor0 && !player.hasQuest( getId() ) ) + Scene00000( player ); + if ( actor == Actor0 && player.getQuestSeq( getId() ) == SeqFinish ) + Scene00002( player ); + } + + void onBNpcKill( uint32_t npcId, Entity::Player& player ) override + { + if ( npcId != Enemy0 ) + return; + + auto credit = player.getQuestUI8AL( getId() ); + if ( credit + 1 >= 6 ) + { + player.setQuestUI8AL( getId(), credit + 1 ); + player.sendQuestMessage( getId(), 0, 2, credit + 1, 6 ); + player.updateQuest( getId(), SeqFinish ); + } + else + { + player.setQuestUI8AL( getId(), credit + 1 ); + player.sendQuestMessage( getId(), 0, 2, credit + 1, 6 ); + } + } + + private: + ////////////////////////////////////////////////////////////////////// + // Available Scenes in this quest, not necessarly all are used + void Scene00000( Entity::Player& player ) + { + player.playScene( getId(), 0, HIDE_HOTBAR, + [&]( Entity::Player& player, const Event::SceneResult& result ) + { + if ( result.param2 == 1 ) + { + Scene00001( player ); + } + } ); + } + + void Scene00001( Entity::Player& player ) + { + player.playScene( getId(), 1, HIDE_HOTBAR, + [&]( Entity::Player& player, const Event::SceneResult& result ) + { + player.updateQuest( getId(), Seq1 ); + } ); + } + + void Scene00002( Entity::Player& player ) + { + player.playScene( getId(), 2, HIDE_HOTBAR, + [&]( Entity::Player& player, const Event::SceneResult& result ) + { + if ( result.param2 == 1 ) + if ( player.giveQuestRewards( getId(), result.param3 ) ) + { + player.finishQuest( getId() ); + } + } ); + } +}; + +EXPOSE_SCRIPT( SubFst021 ); \ No newline at end of file diff --git a/src/scripts/quest/subquest/gridania/SubFst025.cpp b/src/scripts/quest/subquest/gridania/SubFst025.cpp new file mode 100644 index 00000000..9c4176c9 --- /dev/null +++ b/src/scripts/quest/subquest/gridania/SubFst025.cpp @@ -0,0 +1,134 @@ +// This is an automatically generated C++ script template +// Content needs to be added by hand to make it function +// In order for this script to be loaded, move it to the correct folder in /scripts/ + +#include +#include "Manager/EventMgr.h" +#include +#include + +// Quest Script: SubFst025_00103 +// Quest Name: Death to the Bean Thieves +// Quest ID: 65639 +// Start NPC: 1000627 +// End NPC: 1000656 + +using namespace Sapphire; + +class SubFst025 : public Sapphire::ScriptAPI::EventScript +{ + private: + // Basic quest information + // Quest vars / flags used + // GetQuestUI8AL + // GetQuestUI8BH + + // Steps in this quest ( 0 is before accepting, + // 1 is first, 255 means ready for turning it in + enum Sequence : uint8_t + { + Seq0 = 0, + Seq1 = 1, + SeqFinish = 255, + }; + + // Entities found in the script data of the quest + static constexpr auto Actor0 = 1000627; + static constexpr auto Actor1 = 1000656; + static constexpr auto Enemy0 = 5; + static constexpr auto Item0 = 2000075; + + public: + SubFst025() : Sapphire::ScriptAPI::EventScript( 65639 ){}; + ~SubFst025() {}; + + ////////////////////////////////////////////////////////////////////// + // Event Handlers + void onTalk( uint32_t eventId, Entity::Player& player, uint64_t actorId ) override + { + auto& eventMgr = Common::Service< World::Manager::EventMgr >::ref(); + auto actor = eventMgr.mapEventActorToRealActor( static_cast< uint32_t >( actorId ) ); + + if ( actor == Actor0 && !player.hasQuest( getId() ) ) + Scene00000( player ); + if ( actor == Actor1 && player.getQuestSeq( getId() ) == SeqFinish ) + Scene00002( player ); + } + + void onBNpcKill( uint32_t npcId, Entity::Player& player ) override + { + if ( npcId != Enemy0 ) + return; + + auto credit = player.getQuestUI8AL( getId() ); + + if ( credit + 1 >= 6 ) + { + player.sendQuestMessage( getId(), 0, 2, credit + 1, 6 ); + player.setQuestUI8BH( getId(), credit + 1 ); + player.updateQuest( getId(), SeqFinish ); + } + else + { + player.setQuestUI8AL( getId(), credit + 1 ); + player.setQuestUI8BH( getId(), credit + 1 ); + player.sendQuestMessage( getId(), 0, 2, credit + 1, 6 ); + } + + } + + private: + ////////////////////////////////////////////////////////////////////// + // Available Scenes in this quest, not necessarly all are used + void Scene00000( Entity::Player& player ) + { + player.playScene( getId(), 0, HIDE_HOTBAR, + [&]( Entity::Player& player, const Event::SceneResult& result ) + { + if ( result.param2 == 1 ) + Scene00001( player ); + } ); + } + + void Scene00001( Entity::Player& player ) + { + player.playScene( getId(), 1, HIDE_HOTBAR, + [&]( Entity::Player& player, const Event::SceneResult& result ) + { + player.updateQuest( getId(), Seq1 ); + } ); + } + + void Scene00002( Entity::Player& player ) + { + player.playScene( getId(), 2, HIDE_HOTBAR, + [&]( Entity::Player& player, const Event::SceneResult& result ) + { + if ( result.param2 == 1 ) + Scene00003( player ); + } ); + } + + void Scene00003( Entity::Player& player ) + { + player.playScene( getId(), 3, HIDE_HOTBAR, + [&]( Entity::Player& player, const Event::SceneResult& result ) + { + if ( result.param2 == 1 ) + if ( player.giveQuestRewards( getId(), result.param3 ) ) + { + player.finishQuest( getId() ); + } + } ); + } + + void Scene00004( Entity::Player& player ) + { + player.playScene( getId(), 4, HIDE_HOTBAR, + [&]( Entity::Player& player, const Event::SceneResult& result ) + { + } ); + } +}; + +EXPOSE_SCRIPT( SubFst025 ); \ No newline at end of file diff --git a/src/scripts/quest/subquest/gridania/SubFst026.cpp b/src/scripts/quest/subquest/gridania/SubFst026.cpp index 8351ea51..13a835e4 100644 --- a/src/scripts/quest/subquest/gridania/SubFst026.cpp +++ b/src/scripts/quest/subquest/gridania/SubFst026.cpp @@ -11,8 +11,6 @@ using namespace Sapphire; // Start NPC: 1000629 // End NPC: 1000629 -//NEED TEST KILLCREDIT - class SubFst026 : public Sapphire::ScriptAPI::EventScript { @@ -55,28 +53,27 @@ public: auto actor = pEventMgr.mapEventActorToRealActor( static_cast< uint32_t >( actorId ) ); if( actor == Actor0 && !player.hasQuest( getId() ) ) - { Scene00000( player ); - } else if( actor == Actor0 && player.getQuestSeq( getId() ) == SeqFinish ) - { Scene00001( player ); - } } - void onMobKill( Entity::Player& player, uint64_t npcId ) + void onBNpcKill( uint32_t npcId, Entity::Player& player ) override { if( npcId != Enemy0 ) return; - auto currentKC = player.getQuestUI8AL( getId() ) + 1; + auto currentKC = player.getQuestUI8AL( getId() ); - if( currentKC >= 6 ) + if ( currentKC + 1 >= 6 ) + { + player.sendQuestMessage( getId(), 0, 2, currentKC + 1, 6 ); player.updateQuest( getId(), SeqFinish ); + } else { - player.setQuestUI8AL( getId(), currentKC ); - player.sendQuestMessage( getId(), 0, 2, currentKC, 6 ); + player.setQuestUI8AL( getId(), currentKC + 1 ); + player.sendQuestMessage( getId(), 0, 2, currentKC + 1, 6 ); } } diff --git a/src/scripts/quest/subquest/gridania/SubFst037.cpp b/src/scripts/quest/subquest/gridania/SubFst037.cpp new file mode 100644 index 00000000..73ca87cb --- /dev/null +++ b/src/scripts/quest/subquest/gridania/SubFst037.cpp @@ -0,0 +1,146 @@ +// This is an automatically generated C++ script template +// Content needs to be added by hand to make it function +// In order for this script to be loaded, move it to the correct folder in /scripts/ + +#include +#include "Manager/EventMgr.h" +#include +#include + +// Quest Script: SubFst037_00174 +// Quest Name: No Quarter Given +// Quest ID: 65710 +// Start NPC: 1000612 +// End NPC: 1000612 + +using namespace Sapphire; + +class SubFst037 : public Sapphire::ScriptAPI::EventScript +{ + private: + // Basic quest information + // Quest vars / flags used + // GetQuestUI8AL + // GetQuestUI8BH + // GetQuestUI8BL + + // Steps in this quest ( 0 is before accepting, + // 1 is first, 255 means ready for turning it in + enum Sequence : uint8_t + { + Seq0 = 0, + Seq1 = 1, + SeqFinish = 255, + }; + + // Entities found in the script data of the quest + static constexpr auto Actor0 = 1000612; + static constexpr auto Enemy0 = 192; //743; <- WRONG INFO + static constexpr auto Enemy1 = 193; //744; <- WRONG INFO + static constexpr auto Enemy2 = 194; //745; <- WRONG INFO + + public: + SubFst037() : Sapphire::ScriptAPI::EventScript( 65710 ){}; + ~SubFst037() {}; + + ////////////////////////////////////////////////////////////////////// + // Event Handlers + void onTalk( uint32_t eventId, Entity::Player& player, uint64_t actorId ) override + { + auto& eventMgr = Common::Service< World::Manager::EventMgr >::ref(); + auto actor = eventMgr.mapEventActorToRealActor( static_cast< uint32_t >( actorId ) ); + + if ( actor == Actor0 && !player.hasQuest( getId() ) ) + Scene00000( player ); + if ( actor == Actor0 && player.getQuestSeq( getId() ) == SeqFinish ) + Scene00002( player ); + } + + void onBNpcKill( uint32_t npcId, Entity::Player& player ) override + { + auto credit = 0; + + switch( npcId ) + { + case Enemy0: + { + credit = player.getQuestUI8AL( getId() ); + + player.setQuestUI8AL( getId() , credit + 1 ); + if( credit + 1 <= 2 ) + player.sendQuestMessage( getId() , 0, 2, credit + 1, 2 ); + + break; + } + case Enemy1: + { + credit = player.getQuestUI8BH( getId() ); + + player.setQuestUI8BH( getId() , credit + 1 ); + if ( credit + 1 <= 2 ) + player.sendQuestMessage( getId() , 1, 2, credit + 1, 2 ); + + break; + } + case Enemy2: + { + credit = player.getQuestUI8BL( getId() ); + + player.setQuestUI8BL( getId() , credit + 1 ); + if ( credit + 1 <= 2 ) + player.sendQuestMessage( getId() , 2, 2, credit + 1, 2 ); + + break; + } + } + + checkQuestCompletion( player ); + } + + void checkQuestCompletion( Entity::Player& player ) + { + auto credit192 = player.getQuestUI8AL( getId() ); + auto credit193 = player.getQuestUI8BH( getId() ); + auto credit194 = player.getQuestUI8BL( getId() ); + + if ( credit192 >= 2 && credit193 >= 2 && credit194 >= 2 ) + player.updateQuest( getId() , SeqFinish ); + } + + private: + ////////////////////////////////////////////////////////////////////// + // Available Scenes in this quest, not necessarly all are used + void Scene00000( Entity::Player& player ) + { + player.playScene( getId(), 0, HIDE_HOTBAR, + [&]( Entity::Player& player, const Event::SceneResult& result ) + { + if ( result.param2 == 1 ) + Scene00001( player ); + } ); + } + + void Scene00001( Entity::Player& player ) + { + player.playScene( getId(), 1, HIDE_HOTBAR, + [&]( Entity::Player& player, const Event::SceneResult& result ) + { + player.updateQuest( getId() , Seq1 ); + } ); + } + + void Scene00002( Entity::Player& player ) + { + player.playScene( getId(), 2, HIDE_HOTBAR, + [&]( Entity::Player& player, const Event::SceneResult& result ) + { + if( result.param2 == 1 ) + if ( player.giveQuestRewards( getId() , result.param3 ) ) + { + player.finishQuest( getId() ); + } + } ); + } +}; + +EXPOSE_SCRIPT( SubFst037 ); \ No newline at end of file diff --git a/src/scripts/quest/subquest/gridania/SubFst041.cpp b/src/scripts/quest/subquest/gridania/SubFst041.cpp index 8c3512e4..4cede8e6 100644 --- a/src/scripts/quest/subquest/gridania/SubFst041.cpp +++ b/src/scripts/quest/subquest/gridania/SubFst041.cpp @@ -11,8 +11,6 @@ using namespace Sapphire; // Start NPC: 1000432 // End NPC: 1000411 -//NEED TEST KILLCREDIT - class SubFst041 : public Sapphire::ScriptAPI::EventScript { @@ -38,7 +36,7 @@ private: // Entities found in the script data of the quest static constexpr auto Actor0 = 1000432; static constexpr auto Actor1 = 1000411; - static constexpr auto Enemy0 = 159; + static constexpr auto Enemy0 = 197; //159; WRONG INFO static constexpr auto Item0 = 2000142; static constexpr auto Seq0Actor0 = 0; static constexpr auto Seq2Actor1 = 1; @@ -61,28 +59,30 @@ public: auto actor = pEventMgr.mapEventActorToRealActor( static_cast< uint32_t >( actorId ) ); if( actor == Actor0 ) - { Scene00000( player ); - } if( actor == Actor1 ) - { Scene00001( player ); - } } - void onMobKill( Entity::Player& player, uint64_t npcId ) + void onBNpcKill( uint32_t npcId, Entity::Player& player ) override { if( npcId != Enemy0 ) return; - auto currentKC = player.getQuestUI8BH( getId() ) + 1; + auto currentKC = player.getQuestUI8BH( getId() ); - if( currentKC >= 6 ) + if ( currentKC + 1 >= 4 ) + { + player.setQuestUI8AL( getId(), currentKC + 1 ); + player.setQuestUI8BH( getId(), currentKC + 1 ); + player.sendQuestMessage( getId(), 1, 0, 0, 0 ); player.updateQuest( getId(), SeqFinish ); + } else { - player.setQuestUI8BH( getId(), currentKC ); - player.sendQuestMessage( getId(), 0, 2, currentKC, 6 ); + player.setQuestUI8AL( getId(), currentKC + 1 ); + player.setQuestUI8BH( getId(), currentKC + 1 ); + player.sendQuestMessage( getId(), 0, 2, currentKC + 1, 4 ); } } diff --git a/src/scripts/quest/subquest/gridania/SubFst042.cpp b/src/scripts/quest/subquest/gridania/SubFst042.cpp new file mode 100644 index 00000000..d8883f36 --- /dev/null +++ b/src/scripts/quest/subquest/gridania/SubFst042.cpp @@ -0,0 +1,100 @@ +#include +#include +#include +#include + +using namespace Sapphire; + +// Quest Script: SubFst042_00198 +// Quest Name: Butcher of Greentear +// Quest ID: 65734 +// Start NPC: 1000685 +// End NPC: 1000685 + +class SubFst042 : public Sapphire::ScriptAPI::EventScript +{ +private: + // Basic quest information + // Quest vars / flags used + // GetQuestUI8AL + + enum Sequence : uint8_t + { + Seq0 = 0, + Seq1 = 1, + SeqFinish = 255, + }; + + // Quest rewards + static constexpr auto RewardExpFactor = 200; + uint32_t RewardItemOptional[3] = { 4092, 4091, 5824 }; + uint32_t RewardItemOptionalCount[3] = { 1, 1, 1 }; + + // Entities found in the script data of the quest + static constexpr auto Actor0 = 1000685; + static constexpr auto Enemy0 = 14; + static constexpr auto Seq0Actor0 = 0; + static constexpr auto Seq2Actor0 = 1; + +public: + SubFst042() : Sapphire::ScriptAPI::EventScript( 65734 ){}; + ~SubFst042(){}; + + void onTalk( uint32_t eventId, Entity::Player& player, uint64_t actorId ) override + { + auto& pEventMgr = Common::Service< World::Manager::EventMgr >::ref(); + auto actor = pEventMgr.mapEventActorToRealActor( static_cast( actorId ) ); + + if ( actor == Actor0 && !player.hasQuest( getId() ) ) + { + Scene00000( player ); + } + else if ( actor == Actor0 && player.getQuestSeq( getId() ) == SeqFinish ) + { + Scene00001( player ); + } + } + + void onBNpcKill( uint32_t npcId, Entity::Player& player ) override + { + if ( npcId != Enemy0 ) + return; + + auto currentKC = player.getQuestUI8AL( getId() ) + 1; + + if ( currentKC >= 6 ) + player.updateQuest( getId(), SeqFinish ); + else + { + player.setQuestUI8AL( getId(), currentKC ); + player.sendQuestMessage( getId(), 0, 2, currentKC, 6 ); + } + } + +private: + + void Scene00000( Entity::Player& player ) + { + player.playScene( getId(), 0, HIDE_HOTBAR, + [&]( Entity::Player& player, const Event::SceneResult& result ) + { + if ( result.param2 == 1 ) + player.updateQuest( getId(), 1 ); + } ); + } + + void Scene00001( Entity::Player& player ) + { + player.playScene( getId(), 0, HIDE_HOTBAR, + [&]( Entity::Player& player, const Event::SceneResult& result ) + { + if ( result.param2 == 1 ) + { + if ( player.giveQuestRewards( getId(), 0 ) ) + player.finishQuest( getId() ); + } + } ); + } +}; + +EXPOSE_SCRIPT( SubFst042 ); \ No newline at end of file diff --git a/src/scripts/quest/subquest/gridania/SubFst043.cpp b/src/scripts/quest/subquest/gridania/SubFst043.cpp new file mode 100644 index 00000000..c48c0736 --- /dev/null +++ b/src/scripts/quest/subquest/gridania/SubFst043.cpp @@ -0,0 +1,184 @@ +// This is an automatically generated C++ script template +// Content needs to be added by hand to make it function +// In order for this script to be loaded, move it to the correct folder in /scripts/ + +#include +#include "Manager/EventMgr.h" +#include +#include + +// Quest Script: SubFst043_00199 +// Quest Name: A Clear Sign +// Quest ID: 65735 +// Start NPC: 1000172 +// End NPC: 1000627 + +using namespace Sapphire; + +class SubFst043 : public Sapphire::ScriptAPI::EventScript +{ + private: + // Basic quest information + // Quest vars / flags used + // GetQuestBitFlag8 + // GetQuestUI8AL + + // Steps in this quest ( 0 is before accepting, + // 1 is first, 255 means ready for turning it in + enum Sequence : uint8_t + { + Seq0 = 0, + Seq1 = 1, + SeqFinish = 255, + }; + + // Entities found in the script data of the quest + static constexpr auto Actor0 = 1000172; + static constexpr auto Actor1 = 1000627; + static constexpr auto Eobject0 = 2000143; + static constexpr auto Eobject1 = 2000144; + static constexpr auto EventActionProcessMiddle = 16; + static constexpr auto Seq0Actor0 = 0; + static constexpr auto Seq1Eobject0 = 1; + static constexpr auto Seq1Eobject0Eventactionno = 99; + static constexpr auto Seq1Eobject0Eventactionok = 100; + static constexpr auto Seq1Eobject1 = 2; + static constexpr auto Seq1Eobject1Eventactionno = 97; + static constexpr auto Seq1Eobject1Eventactionok = 98; + static constexpr auto Seq2Actor1 = 3; + + public: + SubFst043() : Sapphire::ScriptAPI::EventScript( 65735 ){}; + ~SubFst043() {}; + + ////////////////////////////////////////////////////////////////////// + // Event Handlers + void onTalk( uint32_t eventId, Entity::Player& player, uint64_t actorId ) override + { + auto& eventMgr = Common::Service< World::Manager::EventMgr >::ref(); + auto actor = eventMgr.mapEventActorToRealActor( static_cast< uint32_t >( actorId ) ); + + if ( actor == Actor0 ) + Scene00000( player ); + else if (actor == Actor1 && player.getQuestSeq( getId() ) == SeqFinish ) + Scene00003( player ); + else if ( actor == Eobject0 ) + player.eventActionStart( getId(), EventActionProcessMiddle, + [&]( Entity::Player& player, uint32_t eventId, uint64_t additional ) + { + Scene00001( player ); + }, + nullptr, eventId ); + else if ( actor == Eobject1 ) + player.eventActionStart( getId(), EventActionProcessMiddle, + [&]( Entity::Player& player, uint32_t eventId, uint64_t additional ) + { + Scene00002( player ); + }, + nullptr, eventId ); + } + + void checkQuestCompletion( Entity::Player& player ) + { + auto credit = player.getQuestUI8AL( getId() ); + + if ( credit + 1 >= 2 ) + { + player.setQuestUI8AL( getId(), credit + 1 ); + player.sendQuestMessage( getId(), 0, 2, credit + 1, 2 ); + player.updateQuest( getId(), SeqFinish ); + } + else + { + player.setQuestUI8AL( getId(), credit + 1 ); + player.sendQuestMessage( getId(), 0, 2, credit + 1, 2 ); + } + } + + private: + ////////////////////////////////////////////////////////////////////// + // Available Scenes in this quest, not necessarly all are used + void Scene00000( Entity::Player& player ) + { + player.playScene( getId(), 0, HIDE_HOTBAR, + [&]( Entity::Player& player, const Event::SceneResult& result ) + { + if ( result.param2 == 1 ) + { + player.updateQuest( getId(), Seq1 ); + } + } ); + } + + void Scene00001( Entity::Player& player ) + { + player.playScene( getId(), 1, HIDE_HOTBAR, + [&]( Entity::Player& player, const Event::SceneResult& result ) + { + Scene00100( player ); + } ); + } + + void Scene00002( Entity::Player& player ) + { + player.playScene( getId(), 2, HIDE_HOTBAR, + [&]( Entity::Player& player, const Event::SceneResult& result ) + { + Scene00098( player ); + } ); + } + + void Scene00003( Entity::Player& player ) + { + player.playScene( getId(), 3, HIDE_HOTBAR, + [&]( Entity::Player& player, const Event::SceneResult& result ) + { + if ( result.param2 == 1 ) + { + if ( player.giveQuestRewards( getId(), 0 ) ) + { + player.setQuestUI8BH( getId(), 0 ); + player.finishQuest( getId() ); + } + } + }); + } + + void Scene00097( Entity::Player& player ) + { + player.playScene( getId(), 97, HIDE_HOTBAR, + [&]( Entity::Player& player, const Event::SceneResult& result ) + { + } ); + } + + void Scene00098( Entity::Player& player ) + { + player.playScene( getId(), 98, HIDE_HOTBAR, + [&]( Entity::Player& player, const Event::SceneResult& result ) + { + checkQuestCompletion( player ); + player.setQuestBitFlag8( getId(), 2, true ); + } ); + } + + void Scene00099( Entity::Player& player ) + { + player.playScene( getId(), 99, HIDE_HOTBAR, + [&]( Entity::Player& player, const Event::SceneResult& result ) + { + } ); + } + + void Scene00100( Entity::Player& player ) + { + player.playScene( getId(), 100, HIDE_HOTBAR, + [&]( Entity::Player& player, const Event::SceneResult& result ) + { + checkQuestCompletion( player ); + player.setQuestBitFlag8( getId(), 1, true ); + } ); + } +}; + +EXPOSE_SCRIPT( SubFst043 ); \ No newline at end of file diff --git a/src/scripts/quest/subquest/gridania/SubFst046.cpp b/src/scripts/quest/subquest/gridania/SubFst046.cpp new file mode 100644 index 00000000..69ce3802 --- /dev/null +++ b/src/scripts/quest/subquest/gridania/SubFst046.cpp @@ -0,0 +1,150 @@ +// This is an automatically generated C++ script template +// Content needs to be added by hand to make it function +// In order for this script to be loaded, move it to the correct folder in /scripts/ + +#include +#include "Manager/EventMgr.h" +#include +#include + +// Quest Script: SubFst046_00210 +// Quest Name: Idle Initiatives +// Quest ID: 65746 +// Start NPC: 1000408 +// End NPC: 1000408 + +using namespace Sapphire; + +class SubFst046 : + public Sapphire::ScriptAPI::EventScript +{ + private: + // Basic quest information + // Quest vars / flags used + // GetQuestBitFlag8 + // GetQuestUI8AL + + // Steps in this quest ( 0 is before accepting, + // 1 is first, 255 means ready for turning it in + enum Sequence : uint8_t + { + Seq0 = 0, + Seq1 = 1, + SeqFinish = 255, + }; + + // Entities found in the script data of the quest + static constexpr auto ActionTimelineEventBaseIdle = 783; + static constexpr auto Actor0 = 1000408; + static constexpr auto Actor1 = 1000792; + static constexpr auto Actor2 = 1000793; + static constexpr auto Actor3 = 1000794; + static constexpr auto Seq0Actor0 = 0; + static constexpr auto Seq1Actor1 = 1; + static constexpr auto Seq1Actor2 = 2; + static constexpr auto Seq1Actor3 = 3; + static constexpr auto Seq2Actor0 = 4; + + public: + SubFst046() : Sapphire::ScriptAPI::EventScript( 65746 ){}; + ~SubFst046() {}; + + ////////////////////////////////////////////////////////////////////// + // Event Handlers + void onTalk( uint32_t eventId, Entity::Player& player, uint64_t actorId ) override + { + auto& eventMgr = Common::Service< World::Manager::EventMgr >::ref(); + auto actor = eventMgr.mapEventActorToRealActor( static_cast< uint32_t >( actorId ) ); + + if ( actor == Actor0 && !player.hasQuest( getId() ) ) + Scene00000( player ); + if ( actor == Actor1 ) + Scene00001( player ); + if ( actor == Actor2 ) + Scene00002( player ); + if ( actor == Actor3 ) + Scene00003( player ); + if ( actor == Actor0 && player.getQuestSeq( getId() ) == SeqFinish ) + Scene00004( player ); + } + + void checkQuestCompletion( Entity::Player& player ) + { + auto credit = player.getQuestUI8AL( getId() ); + + if ( credit + 1 >= 3 ) + { + player.setQuestUI8AL( getId(), credit + 1 ); + player.sendQuestMessage( getId(), 0, 0, credit + 1, 3 ); + player.updateQuest( getId(), SeqFinish ); + } + else + { + player.setQuestUI8AL( getId(), credit + 1 ); + player.sendQuestMessage( getId(), 0, 0, credit + 1, 3 ); + } + } + + private: + ////////////////////////////////////////////////////////////////////// + // Available Scenes in this quest, not necessarly all are used + void Scene00000( Entity::Player& player ) + { + player.playScene( getId(), 0, HIDE_HOTBAR, + [ & ]( Entity::Player& player, const Event::SceneResult& result ) + { + if ( result.param2 == 1 ) + { + player.updateQuest( getId(), Seq1 ); + } + } ); + } + + void Scene00001( Entity::Player& player ) + { + player.playScene( getId(), 1, HIDE_HOTBAR, + [ & ]( Entity::Player& player, const Event::SceneResult& result ) + { + checkQuestCompletion( player ); + player.setQuestBitFlag8( getId(), 1, true ); + } ); + } + + void Scene00002( Entity::Player& player ) + { + player.playScene( getId(), 2, HIDE_HOTBAR, + [ & ]( Entity::Player& player, const Event::SceneResult& result ) + { + checkQuestCompletion( player ); + player.setQuestBitFlag8( getId(), 2, true ); + } ); + } + + void Scene00003( Entity::Player& player ) + { + player.playScene( getId(), 3, HIDE_HOTBAR, + [ & ]( Entity::Player& player, const Event::SceneResult& result ) + { + checkQuestCompletion( player ); + player.setQuestBitFlag8( getId(), 3, true ); + } ); + } + + void Scene00004( Entity::Player& player ) + { + player.playScene( getId(), 4, HIDE_HOTBAR, + [ & ]( Entity::Player& player, const Event::SceneResult& result ) + { + if ( result.param2 == 1 ) + { + if ( player.giveQuestRewards( getId(), 0 ) ) + { + player.setQuestUI8BH( getId(), 0 ); + player.finishQuest( getId() ); + } + } + } ); + } +}; + +EXPOSE_SCRIPT( SubFst046 ); \ No newline at end of file diff --git a/src/scripts/quest/subquest/gridania/SubFst048.cpp b/src/scripts/quest/subquest/gridania/SubFst048.cpp new file mode 100644 index 00000000..1dc1c172 --- /dev/null +++ b/src/scripts/quest/subquest/gridania/SubFst048.cpp @@ -0,0 +1,144 @@ +// This is an automatically generated C++ script template +// Content needs to be added by hand to make it function +// In order for this script to be loaded, move it to the correct folder in /scripts/ + +#include +#include "Manager/EventMgr.h" +#include +#include + +// Quest Script: SubFst048_00375 +// Quest Name: Not a Material Girl +// Quest ID: 65911 +// Start NPC: 1000742 +// End NPC: 1000742 + +using namespace Sapphire; + +class SubFst048 : public Sapphire::ScriptAPI::EventScript +{ + private: + // Basic quest information + // Quest vars / flags used + // GetQuestBitFlag8 + // GetQuestUI8AL + + // Steps in this quest ( 0 is before accepting, + // 1 is first, 255 means ready for turning it in + enum Sequence : uint8_t + { + Seq0 = 0, + Seq1 = 1, + SeqFinish = 255, + }; + + // Entities found in the script data of the quest + static constexpr auto Actor0 = 1000742; + static constexpr auto Actor1 = 1000474; + static constexpr auto Actor2 = 1000476; + static constexpr auto Actor3 = 1000483; + static constexpr auto Seq0Actor0 = 0; + static constexpr auto Seq1Actor1 = 1; + static constexpr auto Seq1Actor2 = 2; + static constexpr auto Seq1Actor3 = 3; + static constexpr auto Seq2Actor0 = 4; + + public: + SubFst048() : Sapphire::ScriptAPI::EventScript( 65911 ){}; + ~SubFst048() {}; + + ////////////////////////////////////////////////////////////////////// + // Event Handlers + void onTalk( uint32_t eventId, Entity::Player& player, uint64_t actorId ) override + { + auto& eventMgr = Common::Service< World::Manager::EventMgr >::ref(); + auto actor = eventMgr.mapEventActorToRealActor( static_cast< uint32_t >( actorId ) ); + + if ( actor == Actor0 && !player.hasQuest( getId() ) ) + Scene00000( player ); + if ( actor == Actor0 && player.getQuestSeq( getId() ) == SeqFinish ) + Scene00004( player ); + if ( actor == Actor1 ) + Scene00001( player ); + if ( actor == Actor2 ) + Scene00002( player ); + if ( actor == Actor3 ) + Scene00003( player ); + } + + void checkQuestCompletion( Entity::Player& player ) + { + auto credit = player.getQuestUI8AL( getId() ); + + if ( credit + 1 >= 3 ) + { + player.setQuestUI8AL( getId(), credit + 1 ); + player.sendQuestMessage( getId(), 0, 2, credit + 1, 3 ); + player.updateQuest( getId(), SeqFinish ); + } + else + { + player.setQuestUI8AL( getId(), credit + 1 ); + player.sendQuestMessage( getId(), 0, 2, credit + 1, 3 ); + } + } + + + private: + ////////////////////////////////////////////////////////////////////// + // Available Scenes in this quest, not necessarly all are used + void Scene00000( Entity::Player& player ) + { + player.playScene( getId(), 0, HIDE_HOTBAR, + [&]( Entity::Player& player, const Event::SceneResult& result ) + { + if ( result.param2 == 1 ) + player.updateQuest( getId(), Seq1 ); + } ); + } + + void Scene00001( Entity::Player& player ) + { + player.playScene( getId(), 1, HIDE_HOTBAR, + [&]( Entity::Player& player, const Event::SceneResult& result ) + { + checkQuestCompletion( player ); + player.setQuestBitFlag8( getId(), 1, true ); + } ); + } + + void Scene00002( Entity::Player& player ) + { + player.playScene( getId(), 2, HIDE_HOTBAR, + [&]( Entity::Player& player, const Event::SceneResult& result ) + { + checkQuestCompletion( player ); + player.setQuestBitFlag8( getId(), 2, true ); + } ); + } + + void Scene00003( Entity::Player& player ) + { + player.playScene( getId(), 3, HIDE_HOTBAR, + [&]( Entity::Player& player, const Event::SceneResult& result ) + { + checkQuestCompletion( player ); + player.setQuestBitFlag8( getId(), 3, true ); + } ); + } + + void Scene00004( Entity::Player& player ) + { + player.playScene( getId(), 4, HIDE_HOTBAR, + [&]( Entity::Player& player, const Event::SceneResult& result ) + { + if( result.param2 == 1 ) + if ( player.giveQuestRewards( getId(), result.param3 ) ) + { + player.finishQuest( getId() ); + } + } ); + } +}; + +EXPOSE_SCRIPT( SubFst048 ); \ No newline at end of file diff --git a/src/world/Actor/Player.cpp b/src/world/Actor/Player.cpp index 09c29cfa..77434e14 100644 --- a/src/world/Actor/Player.cpp +++ b/src/world/Actor/Player.cpp @@ -2015,7 +2015,7 @@ void Sapphire::Entity::Player::dyeItemFromDyeingInfo() // TODO: subtract/remove dye used insertInventoryItem( static_cast< Sapphire::Common::InventoryType >( itemToDyeContainer ), static_cast< uint16_t >( itemToDyeSlot ), itemToDye ); - writeItem( itemToDye ); + updateItemDb( itemToDye ); } void Sapphire::Entity::Player::resetObjSpawnIndex() diff --git a/src/world/Actor/Player.h b/src/world/Actor/Player.h index 3d371594..162b55eb 100644 --- a/src/world/Actor/Player.h +++ b/src/world/Actor/Player.h @@ -920,8 +920,6 @@ namespace Sapphire::Entity using InvSlotPair = std::pair< uint16_t, int8_t >; using InvSlotPairVec = std::vector< InvSlotPair >; - ItemPtr createItem( uint32_t catalogId, uint32_t quantity = 1 ); - bool loadInventory(); InvSlotPairVec getSlotsOfItemsInInventory( uint32_t catalogId ); @@ -956,7 +954,11 @@ namespace Sapphire::Entity void writeInventory( Common::InventoryType type ); - void writeItem( ItemPtr pItem ) const; + ItemPtr createTempItem( uint32_t catalogId, uint32_t quantity = 1 ); + + void updateItemDb( ItemPtr pItem ) const; + + void writeItemDb( ItemPtr pItem ) const; void deleteItemDb( ItemPtr pItem ) const; diff --git a/src/world/Actor/PlayerInventory.cpp b/src/world/Actor/PlayerInventory.cpp index 9d5c3656..f94d0237 100644 --- a/src/world/Actor/PlayerInventory.cpp +++ b/src/world/Actor/PlayerInventory.cpp @@ -306,13 +306,13 @@ void Sapphire::Entity::Player::addCurrency( CurrencyType type, uint32_t amount, if( !currItem ) { // TODO: map currency type to itemid - currItem = createItem( 1 ); + currItem = createTempItem( 1 ); m_storageMap[ Currency ]->setItem( slot, currItem ); } uint32_t currentAmount = currItem->getStackSize(); currItem->setStackSize( currentAmount + amount ); - writeItem( currItem ); + updateItemDb( currItem ); updateContainer( Currency, slot, currItem ); @@ -352,7 +352,7 @@ void Sapphire::Entity::Player::removeCurrency( Common::CurrencyType type, uint32 currItem->setStackSize( 0 ); else currItem->setStackSize( currentAmount - amount ); - writeItem( currItem ); + updateItemDb( currItem ); auto invUpdate = std::make_shared< UpdateInventorySlotPacket >( getId(), static_cast< uint8_t >( type ) - 1, @@ -369,7 +369,7 @@ void Sapphire::Entity::Player::addCrystal( Common::CrystalType type, uint32_t am if( !currItem ) { // TODO: map currency type to itemid - currItem = createItem( static_cast< uint8_t >( type ) + 1 ); + currItem = createTempItem( static_cast< uint8_t >( type ) + 1 ); m_storageMap[ Crystal ]->setItem( static_cast< uint8_t >( type ) - 1, currItem ); } @@ -377,7 +377,7 @@ void Sapphire::Entity::Player::addCrystal( Common::CrystalType type, uint32_t am currItem->setStackSize( currentAmount + amount ); - writeItem( currItem ); + updateItemDb( currItem ); writeInventory( Crystal ); @@ -417,7 +417,7 @@ void Sapphire::Entity::Player::removeCrystal( Common::CrystalType type, uint32_t else currItem->setStackSize( currentAmount - amount ); - writeItem( currItem ); + updateItemDb( currItem ); auto invUpdate = std::make_shared< UpdateInventorySlotPacket >( getId(), static_cast< uint8_t >( type ) - 1, @@ -523,8 +523,11 @@ void Sapphire::Entity::Player::writeInventory( InventoryType type ) db.execute( query ); } -void Sapphire::Entity::Player::writeItem( Sapphire::ItemPtr pItem ) const +void Sapphire::Entity::Player::updateItemDb( Sapphire::ItemPtr pItem ) const { + if( pItem->getUId() == 0 ) + writeItemDb( pItem ); + auto& db = Common::Service< Db::DbWorkerPool< Db::ZoneDbConnection > >::ref(); auto stmt = db.getPreparedStatement( Db::CHARA_ITEMGLOBAL_UP ); @@ -540,6 +543,9 @@ void Sapphire::Entity::Player::writeItem( Sapphire::ItemPtr pItem ) const void Sapphire::Entity::Player::deleteItemDb( Sapphire::ItemPtr item ) const { + if( item->getUId() == 0 ) + return; + auto& db = Common::Service< Db::DbWorkerPool< Db::ZoneDbConnection > >::ref(); auto stmt = db.getPreparedStatement( Db::CHARA_ITEMGLOBAL_DELETE ); @@ -619,7 +625,7 @@ Sapphire::ItemPtr Sapphire::Entity::Player::addItem( ItemPtr itemToAdd, bool sil itemToAdd->setStackSize( 0 ); item->setStackSize( newStackSize ); - writeItem( item ); + updateItemDb( item ); if( !silent ) { @@ -662,6 +668,8 @@ Sapphire::ItemPtr Sapphire::Entity::Player::addItem( ItemPtr itemToAdd, bool sil if( !foundFreeSlot ) return nullptr; + writeItemDb( itemToAdd ); + auto storage = m_storageMap[ freeBagSlot.first ]; storage->setItem( freeBagSlot.second, itemToAdd ); @@ -696,7 +704,7 @@ Sapphire::ItemPtr Sapphire::Entity::Player::addItem( uint32_t catalogId, uint32_ { if( catalogId == 0 ) return nullptr; - auto item = createItem( catalogId, quantity ); + auto item = createTempItem( catalogId, quantity ); item->setHq( isHq ); return addItem( item, silent, canMerge, sendLootMessage ); } @@ -799,7 +807,7 @@ void Sapphire::Entity::Player::splitItem( uint16_t fromInventoryId, uint8_t from updateContainer( fromInventoryId, fromSlotId, fromItem ); updateContainer( toInventoryId, toSlot, newItem ); - writeItem( fromItem ); + updateItemDb( fromItem ); } void Sapphire::Entity::Player::mergeItem( uint16_t fromInventoryId, uint8_t fromSlotId, @@ -826,14 +834,14 @@ void Sapphire::Entity::Player::mergeItem( uint16_t fromInventoryId, uint8_t from else { fromItem->setStackSize( stackOverflow ); - writeItem( fromItem ); + updateItemDb( fromItem ); + updateContainer( fromInventoryId, fromSlotId, fromItem ); } toItem->setStackSize( stackSize ); - writeItem( toItem ); + updateItemDb( toItem ); - updateContainer( fromInventoryId, fromSlotId, fromItem ); updateContainer( toInventoryId, toSlot, toItem ); } diff --git a/src/world/Actor/PlayerSql.cpp b/src/world/Actor/PlayerSql.cpp index fa95db98..aa6032c0 100644 --- a/src/world/Actor/PlayerSql.cpp +++ b/src/world/Actor/PlayerSql.cpp @@ -627,11 +627,9 @@ void Sapphire::Entity::Player::insertQuest( uint16_t questId, uint8_t index, uin db.execute( stmt ); } -Sapphire::ItemPtr Sapphire::Entity::Player::createItem( uint32_t catalogId, uint32_t quantity ) +Sapphire::ItemPtr Sapphire::Entity::Player::createTempItem( uint32_t catalogId, uint32_t quantity ) { auto& exdData = Common::Service< Data::ExdDataGenerated >::ref(); - auto& db = Common::Service< Db::DbWorkerPool< Db::ZoneDbConnection > >::ref(); - auto& itemMgr = Common::Service< World::Manager::ItemMgr >::ref(); auto itemInfo = exdData.get< Sapphire::Data::Item >( catalogId ); @@ -641,22 +639,32 @@ Sapphire::ItemPtr Sapphire::Entity::Player::createItem( uint32_t catalogId, uint if( !itemInfo ) return nullptr; - uint8_t flags = 0; - - ItemPtr pItem = make_Item( itemMgr.getNextUId(), catalogId ); + ItemPtr pItem = make_Item( 0, catalogId ); pItem->setStackSize( quantity ); - db.execute( "INSERT INTO charaglobalitem ( CharacterId, itemId, catalogId, stack, flags ) VALUES ( " + - std::to_string( getId() ) + ", " + - std::to_string( pItem->getUId() ) + ", " + - std::to_string( pItem->getId() ) + ", " + - std::to_string( quantity ) + ", " + - std::to_string( flags ) + ");" ); - return pItem; } +void Sapphire::Entity::Player::writeItemDb( Sapphire::ItemPtr pItem ) const +{ + if( pItem->getUId() == 0 ) + { + auto& db = Common::Service< Db::DbWorkerPool< Db::ZoneDbConnection > >::ref(); + auto& itemMgr = Common::Service< World::Manager::ItemMgr >::ref(); + + uint8_t flags = 0; + pItem->setUId( itemMgr.getNextUId() ); + std::string sql = "INSERT INTO charaglobalitem ( CharacterId, itemId, catalogId, stack, flags ) VALUES ( " + + std::to_string( getId() ) + ", " + + std::to_string( pItem->getUId() ) + ", " + + std::to_string( pItem->getId() ) + ", " + + std::to_string( pItem->getStackSize() ) + ", " + + std::to_string( flags ) + ");"; + db.directExecute( sql ); + } +} + bool Sapphire::Entity::Player::loadInventory() { auto& itemMgr = Common::Service< World::Manager::ItemMgr >::ref();