From b2ce49135e474285eda9f806a0eea038ac0e2ee5 Mon Sep 17 00:00:00 2001 From: Skjalf <47818697+Nyeriah@users.noreply.github.com> Date: Wed, 3 Nov 2021 19:43:03 -0300 Subject: [PATCH] =?UTF-8?q?feat(Core/Scripting):=20implement=20OnlyOnceAre?= =?UTF-8?q?aTrigger=20&=20Zul'Gurub's=20in=E2=80=A6=20(#8850)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Treeston --- .../rev_1635649346761519900.sql | 7 +++++ src/server/game/Entities/Object/Object.cpp | 2 +- src/server/game/Entities/Object/Object.h | 2 +- src/server/game/Instances/InstanceScript.h | 6 ++++ src/server/game/Scripting/ScriptMgr.cpp | 31 +++++++++++++++++++ src/server/game/Scripting/ScriptMgr.h | 13 ++++++++ .../EasternKingdoms/ZulGurub/boss_hakkar.cpp | 29 +++++++++++++++++ .../ZulGurub/instance_zulgurub.cpp | 6 ++++ .../EasternKingdoms/ZulGurub/zulgurub.h | 3 +- 9 files changed, 96 insertions(+), 3 deletions(-) create mode 100644 data/sql/updates/pending_db_world/rev_1635649346761519900.sql diff --git a/data/sql/updates/pending_db_world/rev_1635649346761519900.sql b/data/sql/updates/pending_db_world/rev_1635649346761519900.sql new file mode 100644 index 000000000..4888d3687 --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1635649346761519900.sql @@ -0,0 +1,7 @@ +INSERT INTO `version_db_world` (`sql_rev`) VALUES ('1635649346761519900'); + +DELETE FROM `areatrigger_scripts` WHERE `entry` = 3957; +INSERT INTO `areatrigger_scripts` (`entry`, `ScriptName`) VALUES +(3957, 'at_zulgurub_entrance_speech'); + +UPDATE `creature_text` SET `TextRange` = 3 WHERE `CreatureID` = 14834 AND `GroupID` = 3 AND `ID` = 0; diff --git a/src/server/game/Entities/Object/Object.cpp b/src/server/game/Entities/Object/Object.cpp index 0137e7bb9..4c546d7aa 100644 --- a/src/server/game/Entities/Object/Object.cpp +++ b/src/server/game/Entities/Object/Object.cpp @@ -1101,7 +1101,7 @@ void WorldObject::RemoveFromWorld() Object::RemoveFromWorld(); } -InstanceScript* WorldObject::GetInstanceScript() +InstanceScript* WorldObject::GetInstanceScript() const { Map* map = GetMap(); return map->IsDungeon() ? map->ToInstanceMap()->GetInstanceScript() : nullptr; diff --git a/src/server/game/Entities/Object/Object.h b/src/server/game/Entities/Object/Object.h index 85d425704..8aab8cdd4 100644 --- a/src/server/game/Entities/Object/Object.h +++ b/src/server/game/Entities/Object/Object.h @@ -853,7 +853,7 @@ public: [[nodiscard]] bool IsOutdoors() const; LiquidData const& GetLiquidData() const; - InstanceScript* GetInstanceScript(); + InstanceScript* GetInstanceScript() const; [[nodiscard]] std::string const& GetName() const { return m_name; } void SetName(std::string const& newname) { m_name = newname; } diff --git a/src/server/game/Instances/InstanceScript.h b/src/server/game/Instances/InstanceScript.h index 859bb4a4f..07e12b4c0 100644 --- a/src/server/game/Instances/InstanceScript.h +++ b/src/server/game/Instances/InstanceScript.h @@ -242,6 +242,11 @@ public: uint32 GetEncounterCount() const { return bosses.size(); } + // Only used by areatriggers that inherit from OnlyOnceAreaTriggerScript + void MarkAreaTriggerDone(uint32 id) { _activatedAreaTriggers.insert(id); } + void ResetAreaTriggerDone(uint32 id) { _activatedAreaTriggers.erase(id); } + bool IsAreaTriggerDone(uint32 id) const { return _activatedAreaTriggers.find(id) != _activatedAreaTriggers.end(); } + // Allows to perform particular actions virtual void DoAction(int32 /*action*/) {} protected: @@ -272,6 +277,7 @@ private: ObjectInfoMap _gameObjectInfo; ObjectGuidMap _objectGuids; uint32 completedEncounters; // completed encounter mask, bit indexes are DungeonEncounter.dbc boss numbers, used for packets + std::unordered_set _activatedAreaTriggers; }; #endif diff --git a/src/server/game/Scripting/ScriptMgr.cpp b/src/server/game/Scripting/ScriptMgr.cpp index e74b2b51e..d7ce992aa 100644 --- a/src/server/game/Scripting/ScriptMgr.cpp +++ b/src/server/game/Scripting/ScriptMgr.cpp @@ -21,6 +21,7 @@ #include "DatabaseEnv.h" #include "DBCStores.h" #include "GossipDef.h" +#include "InstanceScript.h" #include "ObjectMgr.h" #include "OutdoorPvPMgr.h" #include "Player.h" @@ -3239,6 +3240,36 @@ AreaTriggerScript::AreaTriggerScript(const char* name) ScriptRegistry::AddScript(this); } +bool OnlyOnceAreaTriggerScript::OnTrigger(Player* player, AreaTrigger const* trigger) +{ + uint32 const triggerId = trigger->entry; + if (InstanceScript* instance = player->GetInstanceScript()) + { + if (instance->IsAreaTriggerDone(triggerId)) + { + return true; + } + else + { + instance->MarkAreaTriggerDone(triggerId); + } + } + return _OnTrigger(player, trigger); +} + +void OnlyOnceAreaTriggerScript::ResetAreaTriggerDone(InstanceScript* script, uint32 triggerId) +{ + script->ResetAreaTriggerDone(triggerId); +} + +void OnlyOnceAreaTriggerScript::ResetAreaTriggerDone(Player const* player, AreaTrigger const* trigger) +{ + if (InstanceScript* instance = player->GetInstanceScript()) + { + ResetAreaTriggerDone(instance, trigger->entry); + } +} + BattlegroundScript::BattlegroundScript(const char* name) : ScriptObject(name) { diff --git a/src/server/game/Scripting/ScriptMgr.h b/src/server/game/Scripting/ScriptMgr.h index 0b5cae72b..466337e82 100644 --- a/src/server/game/Scripting/ScriptMgr.h +++ b/src/server/game/Scripting/ScriptMgr.h @@ -552,6 +552,19 @@ public: [[nodiscard]] virtual bool OnTrigger(Player* /*player*/, AreaTrigger const* /*trigger*/) { return false; } }; +class OnlyOnceAreaTriggerScript : public AreaTriggerScript +{ + using AreaTriggerScript::AreaTriggerScript; + +public: + [[nodiscard]] bool OnTrigger(Player* /*player*/, AreaTrigger const* /*trigger*/) override; + +protected: + virtual bool _OnTrigger(Player* /*player*/, AreaTrigger const* /*trigger*/) = 0; + void ResetAreaTriggerDone(InstanceScript* /*instance*/, uint32 /*triggerId*/); + void ResetAreaTriggerDone(Player const* /*player*/, AreaTrigger const* /*trigger*/); +}; + class BattlegroundScript : public ScriptObject { protected: diff --git a/src/server/scripts/EasternKingdoms/ZulGurub/boss_hakkar.cpp b/src/server/scripts/EasternKingdoms/ZulGurub/boss_hakkar.cpp index 23903871e..dbca29f5f 100644 --- a/src/server/scripts/EasternKingdoms/ZulGurub/boss_hakkar.cpp +++ b/src/server/scripts/EasternKingdoms/ZulGurub/boss_hakkar.cpp @@ -24,6 +24,7 @@ Category: Zul'Gurub #include "ScriptedCreature.h" #include "ScriptMgr.h" +#include "Player.h" #include "zulgurub.h" enum Says @@ -175,7 +176,35 @@ public: } }; +class at_zulgurub_entrance_speech : public OnlyOnceAreaTriggerScript +{ +public: + at_zulgurub_entrance_speech() : OnlyOnceAreaTriggerScript("at_zulgurub_entrance_speech") {} + + bool _OnTrigger(Player* player, const AreaTrigger* /*at*/) override + { + if (InstanceScript* instance = player->GetInstanceScript()) + { + // Instance map's enormous, Hakkar's GRID is not loaded by the time players enter. + // Without this, the creature never says anything, because it doesn't load in time. + player->GetMap()->LoadGrid(-11783.99f, -1655.27f); + + if (Creature* hakkar = ObjectAccessor::GetCreature(*player, instance->GetGuidData(DATA_HAKKAR))) + { + hakkar->setActive(true); + if (hakkar->GetAI()) + { + hakkar->AI()->Talk(SAY_PROTECT_ALTAR); + } + } + return false; + } + return false; + } +}; + void AddSC_boss_hakkar() { new boss_hakkar(); + new at_zulgurub_entrance_speech(); } diff --git a/src/server/scripts/EasternKingdoms/ZulGurub/instance_zulgurub.cpp b/src/server/scripts/EasternKingdoms/ZulGurub/instance_zulgurub.cpp index 159a5ea9d..3a2bcab66 100644 --- a/src/server/scripts/EasternKingdoms/ZulGurub/instance_zulgurub.cpp +++ b/src/server/scripts/EasternKingdoms/ZulGurub/instance_zulgurub.cpp @@ -73,6 +73,9 @@ public: case NPC_ARLOKK: _arlokkGUID = creature->GetGUID(); break; + case NPC_HAKKAR: + _hakkarGUID = creature->GetGUID(); + break; } } @@ -123,6 +126,8 @@ public: return _arlokkGUID; case GO_GONG_OF_BETHEKK: return _goGongOfBethekkGUID; + case DATA_HAKKAR: + return _hakkarGUID; } return ObjectGuid::Empty; @@ -181,6 +186,7 @@ public: ObjectGuid _vilebranchSpeakerGUID; ObjectGuid _arlokkGUID; ObjectGuid _goGongOfBethekkGUID; + ObjectGuid _hakkarGUID; }; InstanceScript* GetInstanceScript(InstanceMap* map) const override diff --git a/src/server/scripts/EasternKingdoms/ZulGurub/zulgurub.h b/src/server/scripts/EasternKingdoms/ZulGurub/zulgurub.h index 2e08f269a..00a8e20cb 100644 --- a/src/server/scripts/EasternKingdoms/ZulGurub/zulgurub.h +++ b/src/server/scripts/EasternKingdoms/ZulGurub/zulgurub.h @@ -57,7 +57,8 @@ enum CreatureIds NPC_MANDOKIR = 11382, // Mandokir Event NPC_OHGAN = 14988, // Mandokir Event NPC_VILEBRANCH_SPEAKER = 11391, // Mandokir Event - NPC_CHAINED_SPIRT = 15117 // Mandokir Event + NPC_CHAINED_SPIRT = 15117, // Mandokir Event + NPC_HAKKAR = 14834 }; enum GameobjectIds