From 34139a893779d45c5a1b2763eafc81d9a2f39c38 Mon Sep 17 00:00:00 2001 From: Mordred Date: Wed, 22 Dec 2021 00:40:11 +0100 Subject: [PATCH] Implemented a kill quest as a test again --- .../quest/subquest/gridania/SubFst034.cpp | 162 ++++++++++++++++++ src/world/Actor/BNpc.cpp | 9 +- src/world/Actor/BNpc.h | 3 + src/world/Manager/PlayerMgr.cpp | 4 +- .../Network/PacketWrappers/NpcSpawnPacket.h | 3 +- .../PacketWrappers/PlayerSpawnPacket.h | 2 +- src/world/Script/NativeScriptApi.cpp | 2 +- src/world/Script/ScriptMgr.cpp | 8 +- src/world/Script/ScriptMgr.h | 2 +- src/world/Territory/Territory.cpp | 6 +- 10 files changed, 189 insertions(+), 12 deletions(-) create mode 100644 src/scripts/quest/subquest/gridania/SubFst034.cpp diff --git a/src/scripts/quest/subquest/gridania/SubFst034.cpp b/src/scripts/quest/subquest/gridania/SubFst034.cpp new file mode 100644 index 00000000..52f3c7a3 --- /dev/null +++ b/src/scripts/quest/subquest/gridania/SubFst034.cpp @@ -0,0 +1,162 @@ +// 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: SubFst034_00128 +// Quest Name: Eggs over Queasy +// Quest ID: 65664 +// Start NPC: 1000421 +// End NPC: 1000449 + +using namespace Sapphire; + +class SubFst034 : public Sapphire::ScriptAPI::QuestScript +{ + private: + // Basic quest information + // Quest vars / flags used + // UI8AL + // UI8BH + + /// Countable Num: 8 Seq: 1 Event: 9 Listener: 43 + /// Countable Num: 1 Seq: 255 Event: 1 Listener: 1000449 + // 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 = 1000421; + static constexpr auto Actor1 = 1000449; + static constexpr auto Enemy0 = 43; + static constexpr auto Item0 = 2000062; + static constexpr auto Seq0Actor0 = 0; + static constexpr auto Seq2Actor1 = 1; + static constexpr auto Seq2Actor1Npctradeno = 99; + static constexpr auto Seq2Actor1Npctradeok = 100; + + public: + SubFst034() : Sapphire::ScriptAPI::QuestScript( 65664 ){}; + ~SubFst034() = default; + + ////////////////////////////////////////////////////////////////////// + // Event Handlers + void onTalk( World::Quest& quest, Entity::Player& player, uint64_t actorId ) override + { + switch( actorId ) + { + case Actor0: + { + Scene00000( quest, player ); + break; + } + case Actor1: + { + Scene00100( quest, player ); + break; + } + + } + } + + void onEventItem( World::Quest& quest, Entity::Player& player, uint64_t actorId ) override + { + } + + void onBNpcKill( World::Quest& quest, uint16_t nameId, uint32_t entityId, Entity::Player& player ) override + { + switch( nameId ) + { + case Enemy0: + { + uint8_t currCount = quest.getUI8AL(); + if( currCount + 1 >= 8 ) + { + eventMgr().sendEventNotice( player, getId(), 0, 3, 8, 8 ); + quest.setSeq( SeqFinish ); + } + else + { + quest.setUI8AL( currCount + 1 ); + eventMgr().sendEventNotice( player, getId(), 0, 3, currCount + 1, 8 ); + } + break; + } + } + } + + private: + ////////////////////////////////////////////////////////////////////// + // Available Scenes in this quest, not necessarly all are used + ////////////////////////////////////////////////////////////////////// + + void Scene00000( World::Quest& quest, Entity::Player& player ) + { + eventMgr().playQuestScene( player, getId(), 0, NONE, bindSceneReturn( &SubFst034::Scene00000Return ) ); + } + + void Scene00000Return( World::Quest& quest, Entity::Player& player, const Event::SceneResult& result ) + { + if( result.getResult( 0 ) == 1 ) // accept quest + { + quest.setSeq( Seq1 ); + } + + + } + + ////////////////////////////////////////////////////////////////////// + + void Scene00001( World::Quest& quest, Entity::Player& player ) + { + eventMgr().playQuestScene( player, getId(), 1, NONE, bindSceneReturn( &SubFst034::Scene00001Return ) ); + } + + void Scene00001Return( World::Quest& quest, Entity::Player& player, const Event::SceneResult& result ) + { + + + } + + ////////////////////////////////////////////////////////////////////// + + void Scene00099( World::Quest& quest, Entity::Player& player ) + { + eventMgr().playQuestScene( player, getId(), 99, NONE, bindSceneReturn( &SubFst034::Scene00099Return ) ); + } + + void Scene00099Return( World::Quest& quest, Entity::Player& player, const Event::SceneResult& result ) + { + + + } + + ////////////////////////////////////////////////////////////////////// + + void Scene00100( World::Quest& quest, Entity::Player& player ) + { + eventMgr().playQuestScene( player, getId(), 100, NONE, bindSceneReturn( &SubFst034::Scene00100Return ) ); + } + + void Scene00100Return( World::Quest& quest, Entity::Player& player, const Event::SceneResult& result ) + { + + if( result.getResult( 0 ) == 1 ) + { + player.finishQuest( getId(), result.getResult( 1 ) ); + } + + } + +}; + +EXPOSE_SCRIPT( SubFst034 ); \ No newline at end of file diff --git a/src/world/Actor/BNpc.cpp b/src/world/Actor/BNpc.cpp index 644f0d67..60db084b 100644 --- a/src/world/Actor/BNpc.cpp +++ b/src/world/Actor/BNpc.cpp @@ -57,6 +57,7 @@ Sapphire::Entity::BNpc::BNpc( uint32_t id, std::shared_ptr< Common::BNPCInstance { m_id = id; m_pInfo = pInfo; + m_layoutId = pInfo->instanceId; m_aggressionMode = pInfo->ActiveType; @@ -159,6 +160,7 @@ Sapphire::Entity::BNpc::BNpc( uint32_t id, std::shared_ptr< Common::BNPCInstance { m_id = id; m_pInfo = pInfo; + m_layoutId = pInfo->instanceId; m_aggressionMode = pInfo->ActiveType; @@ -741,7 +743,7 @@ void Sapphire::Entity::BNpc::onDeath() if( pPlayer ) { auto& playerMgr = Common::Service< World::Manager::PlayerMgr >::ref(); - playerMgr.onMobKill( *pPlayer, static_cast< uint16_t >( m_bNpcNameId ), m_id ); + playerMgr.onMobKill( *pPlayer, static_cast< uint16_t >( m_bNpcNameId ), getLayoutId() ); } } hateListClear(); @@ -955,3 +957,8 @@ BNpcType Sapphire::Entity::BNpc::getBNpcType() const { return m_bnpcType; } + +uint32_t Sapphire::Entity::BNpc::getLayoutId() const +{ + return m_layoutId; +} diff --git a/src/world/Actor/BNpc.h b/src/world/Actor/BNpc.h index d673e0c0..95d92ccf 100644 --- a/src/world/Actor/BNpc.h +++ b/src/world/Actor/BNpc.h @@ -125,6 +125,8 @@ namespace Sapphire::Entity Common::BNpcType getBNpcType() const; + uint32_t getLayoutId() const; + private: uint32_t m_bNpcBaseId; uint32_t m_bNpcNameId; @@ -140,6 +142,7 @@ namespace Sapphire::Entity uint32_t m_levelId; uint32_t m_rank; uint32_t m_boundInstanceId; + uint32_t m_layoutId; uint32_t m_flags; diff --git a/src/world/Manager/PlayerMgr.cpp b/src/world/Manager/PlayerMgr.cpp index e0d243a0..00502e9f 100644 --- a/src/world/Manager/PlayerMgr.cpp +++ b/src/world/Manager/PlayerMgr.cpp @@ -252,10 +252,10 @@ void PlayerMgr::onMountUpdate( Sapphire::Entity::Player& player, uint32_t mountI } } -void PlayerMgr::onMobKill( Sapphire::Entity::Player& player, uint16_t nameId, uint32_t entityId ) +void PlayerMgr::onMobKill( Sapphire::Entity::Player& player, uint16_t nameId, uint32_t layoutId ) { auto& scriptMgr = Common::Service< Scripting::ScriptMgr >::ref(); - scriptMgr.onBNpcKill( player, nameId, entityId ); + scriptMgr.onBNpcKill( player, nameId, layoutId ); if( player.isActionLearned( Common::UnlockEntry::HuntingLog ) ) { diff --git a/src/world/Network/PacketWrappers/NpcSpawnPacket.h b/src/world/Network/PacketWrappers/NpcSpawnPacket.h index c4a7a148..87bcadd2 100644 --- a/src/world/Network/PacketWrappers/NpcSpawnPacket.h +++ b/src/world/Network/PacketWrappers/NpcSpawnPacket.h @@ -33,6 +33,7 @@ namespace Sapphire::Network::Packets::WorldPackets::Server m_data.ClassJob = static_cast< uint8_t >( bnpc.getClass() ); //m_data.ActiveType = static_cast< uint8_t >( bnpc.getStatus() ); + m_data.LayoutId = bnpc.getLayoutId(); m_data.Hp = bnpc.getHp(); m_data.Mp = bnpc.getMp(); m_data.HpMax = bnpc.getMaxHp(); @@ -60,7 +61,7 @@ namespace Sapphire::Network::Packets::WorldPackets::Server m_data.MainTarget = bnpc.getTargetId(); // no idea ... m_data.spawnerId = Common::INVALID_GAME_OBJECT_ID64; m_data.ParentId = Common::INVALID_GAME_OBJECT_ID; - m_data.TriggerId = Common::INVALID_GAME_OBJECT_ID; + m_data.TriggerId = 0; m_data.ChannelingTarget = Common::INVALID_GAME_OBJECT_ID; m_data.OwnerId = Common::INVALID_GAME_OBJECT_ID; diff --git a/src/world/Network/PacketWrappers/PlayerSpawnPacket.h b/src/world/Network/PacketWrappers/PlayerSpawnPacket.h index c208222a..abbb31cb 100644 --- a/src/world/Network/PacketWrappers/PlayerSpawnPacket.h +++ b/src/world/Network/PacketWrappers/PlayerSpawnPacket.h @@ -103,7 +103,7 @@ namespace Sapphire::Network::Packets::WorldPackets::Server // 0x20 == spawn hidden to be displayed by the spawneffect control m_data.ActiveType = player.getStance(); - if( player.getZoningType() != Common::ZoneingType::None || player.getGmInvis() == true ) + if( player.getZoningType() != Common::ZoneingType::None || player.getGmInvis() ) { m_data.ActiveType |= static_cast< uint16_t >( Common::DisplayFlags::Invisible ); } diff --git a/src/world/Script/NativeScriptApi.cpp b/src/world/Script/NativeScriptApi.cpp index 352f41d8..d1969ca9 100644 --- a/src/world/Script/NativeScriptApi.cpp +++ b/src/world/Script/NativeScriptApi.cpp @@ -146,7 +146,7 @@ namespace Sapphire::ScriptAPI { } - void QuestScript::onBNpcKill( World::Quest& quest, uint16_t nameId, uint32_t entityId, Entity::Player& player ) + void QuestScript::onBNpcKill( World::Quest& quest, uint16_t nameId, uint32_t layoutId, Entity::Player& player ) { } diff --git a/src/world/Script/ScriptMgr.cpp b/src/world/Script/ScriptMgr.cpp index b2915b8f..d9ebdff8 100644 --- a/src/world/Script/ScriptMgr.cpp +++ b/src/world/Script/ScriptMgr.cpp @@ -185,9 +185,13 @@ bool Sapphire::Scripting::ScriptMgr::onTalk( Entity::Player& player, uint64_t ac auto questId = static_cast< uint16_t >( eventId ); if( player.hasQuest( eventId ) ) { + World::Quest preQ; auto questIdx = player.getQuestIndex( questId ); auto& quest = player.getQuestByIndex( questIdx ); + preQ = quest; script->onTalk( quest, player, actor ); + if( quest != preQ ) + player.updateQuest( quest ); } else { @@ -352,7 +356,7 @@ bool Sapphire::Scripting::ScriptMgr::onEventItem( Entity::Player& player, uint32 return false; } -bool Sapphire::Scripting::ScriptMgr::onBNpcKill( Entity::Player& player, uint16_t nameId, uint32_t entityId ) +bool Sapphire::Scripting::ScriptMgr::onBNpcKill( Entity::Player& player, uint16_t nameId, uint32_t layoutId ) { auto& eventMgr = Common::Service< World::Manager::EventMgr >::ref(); @@ -374,7 +378,7 @@ bool Sapphire::Scripting::ScriptMgr::onBNpcKill( Entity::Player& player, uint16_ World::Quest preQ = quest; - script->onBNpcKill( quest, nameId, entityId, player ); + script->onBNpcKill( quest, nameId, layoutId, player ); if( quest != preQ ) player.updateQuest( quest ); } diff --git a/src/world/Script/ScriptMgr.h b/src/world/Script/ScriptMgr.h index 04a62153..f93a341b 100644 --- a/src/world/Script/ScriptMgr.h +++ b/src/world/Script/ScriptMgr.h @@ -66,7 +66,7 @@ namespace Sapphire::Scripting bool onEventItem( Entity::Player& player, uint32_t eventItemId, uint32_t eventId, uint64_t targetId ); - bool onBNpcKill( Entity::Player& player, uint16_t nameId, uint32_t entityId ); + bool onBNpcKill( Entity::Player& player, uint16_t nameId, uint32_t lyoutId ); bool onEObjHit( Entity::Player& player, uint64_t actorId, uint32_t actionId ); diff --git a/src/world/Territory/Territory.cpp b/src/world/Territory/Territory.cpp index 28985e8f..32887e27 100644 --- a/src/world/Territory/Territory.cpp +++ b/src/world/Territory/Territory.cpp @@ -832,7 +832,7 @@ void Sapphire::Territory::updateSpawnPoints() if( !spawn.bnpcPtr && ( Util::getTimeSeconds() - spawn.timeOfDeath ) > spawn.infoPtr->PopInterval ) { auto& server = Common::Service< World::WorldServer >::ref(); - auto pBNpc = std::make_shared< Entity::BNpc >( spawn.infoPtr->instanceId, spawn.infoPtr, shared_from_this() ); + auto pBNpc = std::make_shared< Entity::BNpc >( getNextActorId(), spawn.infoPtr, shared_from_this() ); spawn.bnpcPtr = pBNpc; pushActor( pBNpc ); @@ -857,7 +857,7 @@ Sapphire::Entity::BNpcPtr Sapphire::Territory::createBNpcFromInstanceId( uint32_ if( infoPtr == m_bNpcBaseMap.end() ) return nullptr; - auto pBNpc = std::make_shared< Entity::BNpc >( infoPtr->second->instanceId, infoPtr->second, shared_from_this(), hp, bnpcType ); + auto pBNpc = std::make_shared< Entity::BNpc >( getNextActorId(), infoPtr->second, shared_from_this(), hp, bnpcType ); pushActor( pBNpc ); return pBNpc; @@ -867,7 +867,7 @@ Sapphire::Entity::BNpcPtr Sapphire::Territory::getActiveBNpcByInstanceId( uint32 { for( const auto& bnpcIt : m_bNpcMap ) { - if( bnpcIt.second->getId() == instanceId ) + if( bnpcIt.second->getLayoutId() == instanceId ) return bnpcIt.second; } return nullptr;