diff options
author | Jinnaix <37972361+Jinnaix@users.noreply.github.com> | 2021-01-10 16:38:41 +0100 |
---|---|---|
committer | Shauren <shauren.trinity@gmail.com> | 2022-03-05 23:09:23 +0100 |
commit | 53eebf39f3d453ac5a4f18a9275983304b6dd2b8 (patch) | |
tree | eaa52295a66daf69262ed9647419f85973899a10 /src | |
parent | 6b242eee130f1ac405187a03cefaf595d857ad99 (diff) |
Scripts/Diremaul - Dire Maul crystal and forcefield fix (#25332)
* Scripts/Diremaul
Diremaul Crystal and Forcefield fix
* Apply suggestions from code review
Apply suggestions
Co-authored-by: MaxtorCoder <warsongkiller.s8@gmail.com>
* Fix stuff
* _private member
* use std array instead of c-arrays and standartized guid container namings
* Process feedback
* finalize
* blubb
* small changes
* whoops
* Process feedback
* Missing include
* Process feedback
* Apply suggestions from code review
Co-authored-by: Giacomo Pozzoni <giacomopoz@gmail.com>
* remove unused field
Co-authored-by: MaxtorCoder <warsongkiller.s8@gmail.com>
Co-authored-by: Ovah <dreadkiller@gmx.de>
Co-authored-by: Giacomo Pozzoni <giacomopoz@gmail.com>
(cherry picked from commit 26002c530f7183105bf3dcb33272bb0cf3322558)
Diffstat (limited to 'src')
-rw-r--r-- | src/server/scripts/Kalimdor/DireMaul/diremaul.h | 60 | ||||
-rw-r--r-- | src/server/scripts/Kalimdor/DireMaul/instance_dire_maul.cpp | 214 |
2 files changed, 272 insertions, 2 deletions
diff --git a/src/server/scripts/Kalimdor/DireMaul/diremaul.h b/src/server/scripts/Kalimdor/DireMaul/diremaul.h new file mode 100644 index 00000000000..923b26be422 --- /dev/null +++ b/src/server/scripts/Kalimdor/DireMaul/diremaul.h @@ -0,0 +1,60 @@ +/* + * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef DEF_DIREMAUL_H +#define DEF_DIREMAUL_H + +#include "CreatureAIImpl.h" + +#define DiremaulScriptName "instance_diremaul" +#define DataHeader "DM" + +enum DMDataTypes +{ + DATA_CRYSTAL_01 = 17, + DATA_CRYSTAL_02 = 18, + DATA_CRYSTAL_03 = 19, + DATA_CRYSTAL_04 = 20, + DATA_CRYSTAL_05 = 21, + DATA_FORCEFIELD = 22 +}; + +enum DMCreatureIds +{ + NPC_IMMOLTHAR = 11496, + NPC_TORTHELDRIN = 11486, + NPC_ARCANE_ABERRATION = 11480, + NPC_MANA_REMNANT = 11483 +}; + +enum DMGameobjectIds +{ + GO_FORCEFIELD = 179503, + GO_CRYSTAL_01 = 177259, + GO_CRYSTAL_02 = 177257, + GO_CRYSTAL_03 = 177258, + GO_CRYSTAL_04 = 179504, + GO_CRYSTAL_05 = 179505 +}; + +template <class AI, class T> +inline AI* GetDiremaulAI(T* obj) +{ + return GetInstanceAI<AI>(obj, DiremaulScriptName); +} + +#endif diff --git a/src/server/scripts/Kalimdor/DireMaul/instance_dire_maul.cpp b/src/server/scripts/Kalimdor/DireMaul/instance_dire_maul.cpp index 501c6a60307..8d81283871d 100644 --- a/src/server/scripts/Kalimdor/DireMaul/instance_dire_maul.cpp +++ b/src/server/scripts/Kalimdor/DireMaul/instance_dire_maul.cpp @@ -22,8 +22,12 @@ Without it, the party doing random dungeon won't get satchel of spoils and gets instead the deserter debuff. */ -#include "ScriptMgr.h" +#include "GameObject.h" #include "InstanceScript.h" +#include "Map.h" +#include "ScriptedCreature.h" +#include "ScriptMgr.h" +#include "diremaul.h" // Bosses (East) // 0 - Pusillin @@ -39,6 +43,12 @@ gets instead the deserter debuff. // 8 - Illyanna Ravenoak // 9 - Immol'thar // 10 - Prince Tortheldrin +// 17 - CRYSTAL_01 +// 18 - CRYSTAL_02 +// 19 - CRYSTAL_03 +// 20 - CRYSTAL_04 +// 21 - CRYSTAL_05 +// 22 - FORCEFIELD // North // 11 - Guard Mol'dar @@ -48,7 +58,15 @@ gets instead the deserter debuff. // 15 - Captain Kromcrush // 16 - King Gordok -uint8 const EncounterCount = 17; +uint8 const EncounterCount = 23; + +uint32 const CrystalMobs[2] = { NPC_ARCANE_ABERRATION, NPC_MANA_REMNANT }; + +enum Events +{ + EVENT_CRYSTAL_CREATURE_STORE = 1, + EVENT_CRYSTAL_CREATURE_CHECK = 2 +}; class instance_dire_maul : public InstanceMapScript { @@ -59,8 +77,200 @@ public: { instance_dire_maul_InstanceMapScript(InstanceMap* map) : InstanceScript(map) { + SetHeaders(DataHeader); SetBossNumber(EncounterCount); } + + void OnCreatureCreate(Creature* creature) override + { + switch (creature->GetEntry()) + { + case NPC_IMMOLTHAR: + _immoGUID = creature->GetGUID(); + // we make Immolthar non attackable, otherwise players with pets can pull him out of the forcefield + // TODO: this change isnt correct but since of today (13.09.2020) mmaps dont support doors + if (GetBossState(DATA_FORCEFIELD) != DONE) + creature->AddUnitFlag(UNIT_FLAG_NON_ATTACKABLE); + break; + default: + break; + } + } + + void OnGameObjectCreate(GameObject* go) override + { + InstanceScript::OnGameObjectCreate(go); + + switch (go->GetEntry()) + { + case GO_CRYSTAL_01: + _crystalGUIDs[0] = go->GetGUID(); + break; + case GO_CRYSTAL_02: + _crystalGUIDs[1] = go->GetGUID(); + break; + case GO_CRYSTAL_03: + _crystalGUIDs[2] = go->GetGUID(); + break; + case GO_CRYSTAL_04: + _crystalGUIDs[3] = go->GetGUID(); + break; + case GO_CRYSTAL_05: + _crystalGUIDs[4] = go->GetGUID(); + break; + case GO_FORCEFIELD: + _forcefieldGUID = go->GetGUID(); + if (GetBossState(DATA_FORCEFIELD) != DONE) + _events.ScheduleEvent(EVENT_CRYSTAL_CREATURE_STORE, 1s); + break; + default: + break; + } + } + + ObjectGuid GetGuidData(uint32 type) const override + { + switch (type) + { + case GO_CRYSTAL_01: + return _crystalGUIDs[0]; + case GO_CRYSTAL_02: + return _crystalGUIDs[1]; + case GO_CRYSTAL_03: + return _crystalGUIDs[2]; + case GO_CRYSTAL_04: + return _crystalGUIDs[3]; + case GO_CRYSTAL_05: + return _crystalGUIDs[4]; + case GO_FORCEFIELD: + return _forcefieldGUID; + case NPC_IMMOLTHAR: + return _immoGUID; + default: + break; + } + return ObjectGuid::Empty; + } + + void Update(uint32 diff) override + { + _events.Update(diff); + + while (uint32 eventId = _events.ExecuteEvent()) + { + switch (eventId) + { + case EVENT_CRYSTAL_CREATURE_STORE: + CrystalCreatureStore(); + _events.ScheduleEvent(EVENT_CRYSTAL_CREATURE_CHECK, 3s); + break; + case EVENT_CRYSTAL_CREATURE_CHECK: + CrystalCreatureCheck(); + if ((GetBossState(DATA_FORCEFIELD) != DONE)) + _events.ScheduleEvent(EVENT_CRYSTAL_CREATURE_CHECK, 1s); + break; + default: + break; + } + } + } + + void CrystalCreatureStore() + { + for (uint8 i = 0; i < 5; ++i) // we store creatures in a list for all 5 crystals + { + uint8 creatureCount = 0; + + if (GameObject* crystal = instance->GetGameObject(_crystalGUIDs[i])) + { + for (uint8 j = 0; j < 2; ++j) // once per creature type from CrystalMobs + { + std::list<Creature*> creatureList; + GetCreatureListWithEntryInGrid(creatureList, crystal, CrystalMobs[j], 30.0f); + for (std::list<Creature*>::iterator itr = creatureList.begin(); itr != creatureList.end(); ++itr) + { + _crystalCreatureGUIDs[i][creatureCount] = (*itr)->GetGUID(); + ++creatureCount; + } + } + } + } + } + + void CrystalCreatureCheck() + { + for (uint8 i = 0; i < _crystalGUIDs.size(); ++i) + { + bool _mobAlive = false; + GameObject* go = instance->GetGameObject(_crystalGUIDs[i]); + if (!go) + continue; + + if (go->GetGoState() == GO_STATE_READY) + { + for (uint8 j = 0; j < _crystalCreatureGUIDs[i].size(); ++j) + { + Creature* mob = instance->GetCreature(_crystalCreatureGUIDs[i][j]); + if (mob && mob->IsAlive()) + { + _mobAlive = true; + break; + } + } + } + + if (!_mobAlive && go->GetGoState() == GO_STATE_READY) // if all stored creatures are dead and go state is ready + { + HandleGameObject(ObjectGuid::Empty, false, go); + + switch (go->GetEntry()) + { + case GO_CRYSTAL_01: + SetBossState(DATA_CRYSTAL_01, DONE); + go->SetGoState(GO_STATE_ACTIVE); + break; + case GO_CRYSTAL_02: + SetBossState(DATA_CRYSTAL_02, DONE); + go->SetGoState(GO_STATE_ACTIVE); + break; + case GO_CRYSTAL_03: + SetBossState(DATA_CRYSTAL_03, DONE); + go->SetGoState(GO_STATE_ACTIVE); + break; + case GO_CRYSTAL_04: + SetBossState(DATA_CRYSTAL_04, DONE); + go->SetGoState(GO_STATE_ACTIVE); + break; + case GO_CRYSTAL_05: + SetBossState(DATA_CRYSTAL_05, DONE); + go->SetGoState(GO_STATE_ACTIVE); + break; + default: + break; + } + } + } + + if (GetBossState(DATA_CRYSTAL_01) == DONE && GetBossState(DATA_CRYSTAL_02) == DONE && GetBossState(DATA_CRYSTAL_03) == DONE && + GetBossState(DATA_CRYSTAL_04) == DONE && GetBossState(DATA_CRYSTAL_05) == DONE) + { + // if all crystals are done, we set encounter forcefield to done + SetBossState(DATA_FORCEFIELD, DONE); + // activate forcefield to make it disappear + if (GameObject* ffield = instance->GetGameObject(_forcefieldGUID)) + ffield->SetGoState(GO_STATE_ACTIVE); + // remove previously set non attackable flag + if (Creature* immo = instance->GetCreature(_immoGUID)) + immo->RemoveUnitFlag(UNIT_FLAG_NON_ATTACKABLE); + } + } + +protected: + EventMap _events; + std::array<ObjectGuid, 5> _crystalGUIDs; + std::array<std::array<ObjectGuid, 4>, 5> _crystalCreatureGUIDs; // 5 different Crystals, maximum of 4 Creatures + ObjectGuid _forcefieldGUID; + ObjectGuid _immoGUID; }; InstanceScript* GetInstanceScript(InstanceMap* map) const override |