From 7e703393d2ee94aa35e269fa5e7cca826126fd0d Mon Sep 17 00:00:00 2001 From: Nefertumm Date: Mon, 13 Jun 2022 19:44:20 -0300 Subject: [PATCH] fix(Core/ZG): Multiple improvements to High Priestess Mar'li (#11647) --- .../rev_1651792914774493500.sql | 21 + .../EasternKingdoms/ZulGurub/boss_marli.cpp | 472 +++++++++++------- .../ZulGurub/instance_zulgurub.cpp | 12 +- .../EasternKingdoms/ZulGurub/zulgurub.h | 2 + 4 files changed, 314 insertions(+), 193 deletions(-) create mode 100644 data/sql/updates/pending_db_world/rev_1651792914774493500.sql diff --git a/data/sql/updates/pending_db_world/rev_1651792914774493500.sql b/data/sql/updates/pending_db_world/rev_1651792914774493500.sql new file mode 100644 index 000000000..15c565742 --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1651792914774493500.sql @@ -0,0 +1,21 @@ +-- +DELETE FROM `spell_dbc` WHERE `ID` = 24081; +INSERT INTO `spell_dbc` (`ID`, `Category`, `DispelType`, `Mechanic`, `Attributes`, `AttributesEx`, `AttributesEx2`, `AttributesEx3`, `AttributesEx4`, `AttributesEx5`, `AttributesEx6`, `AttributesEx7`, `ShapeshiftMask`, `unk_320_2`, `ShapeshiftExclude`, `unk_320_3`, `Targets`, `TargetCreatureType`, `RequiresSpellFocus`, `FacingCasterFlags`, `CasterAuraState`, `TargetAuraState`, `ExcludeCasterAuraState`, `ExcludeTargetAuraState`, `CasterAuraSpell`, `TargetAuraSpell`, `ExcludeCasterAuraSpell`, `ExcludeTargetAuraSpell`, `CastingTimeIndex`, `RecoveryTime`, `CategoryRecoveryTime`, `InterruptFlags`, `AuraInterruptFlags`, `ChannelInterruptFlags`, `ProcTypeMask`, `ProcChance`, `ProcCharges`, `MaxLevel`, `BaseLevel`, `SpellLevel`, `DurationIndex`, `PowerType`, `ManaCost`, `ManaCostPerLevel`, `ManaPerSecond`, `ManaPerSecondPerLevel`, `RangeIndex`, `Speed`, `ModalNextSpell`, `CumulativeAura`, `Totem_1`, `Totem_2`, `Reagent_1`, `Reagent_2`, `Reagent_3`, `Reagent_4`, `Reagent_5`, `Reagent_6`, `Reagent_7`, `Reagent_8`, `ReagentCount_1`, `ReagentCount_2`, `ReagentCount_3`, `ReagentCount_4`, `ReagentCount_5`, `ReagentCount_6`, `ReagentCount_7`, `ReagentCount_8`, `EquippedItemClass`, `EquippedItemSubclass`, `EquippedItemInvTypes`, `Effect_1`, `Effect_2`, `Effect_3`, `EffectDieSides_1`, `EffectDieSides_2`, `EffectDieSides_3`, `EffectRealPointsPerLevel_1`, `EffectRealPointsPerLevel_2`, `EffectRealPointsPerLevel_3`, `EffectBasePoints_1`, `EffectBasePoints_2`, `EffectBasePoints_3`, `EffectMechanic_1`, `EffectMechanic_2`, `EffectMechanic_3`, `ImplicitTargetA_1`, `ImplicitTargetA_2`, `ImplicitTargetA_3`, `ImplicitTargetB_1`, `ImplicitTargetB_2`, `ImplicitTargetB_3`, `EffectRadiusIndex_1`, `EffectRadiusIndex_2`, `EffectRadiusIndex_3`, `EffectAura_1`, `EffectAura_2`, `EffectAura_3`, `EffectAuraPeriod_1`, `EffectAuraPeriod_2`, `EffectAuraPeriod_3`, `EffectMultipleValue_1`, `EffectMultipleValue_2`, `EffectMultipleValue_3`, `EffectChainTargets_1`, `EffectChainTargets_2`, `EffectChainTargets_3`, `EffectItemType_1`, `EffectItemType_2`, `EffectItemType_3`, `EffectMiscValue_1`, `EffectMiscValue_2`, `EffectMiscValue_3`, `EffectMiscValueB_1`, `EffectMiscValueB_2`, `EffectMiscValueB_3`, `EffectTriggerSpell_1`, `EffectTriggerSpell_2`, `EffectTriggerSpell_3`, `EffectPointsPerCombo_1`, `EffectPointsPerCombo_2`, `EffectPointsPerCombo_3`, `EffectSpellClassMaskA_1`, `EffectSpellClassMaskA_2`, `EffectSpellClassMaskA_3`, `EffectSpellClassMaskB_1`, `EffectSpellClassMaskB_2`, `EffectSpellClassMaskB_3`, `EffectSpellClassMaskC_1`, `EffectSpellClassMaskC_2`, `EffectSpellClassMaskC_3`, `SpellVisualID_1`, `SpellVisualID_2`, `SpellIconID`, `ActiveIconID`, `SpellPriority`, `Name_Lang_enUS`, `Name_Lang_enGB`, `Name_Lang_koKR`, `Name_Lang_frFR`, `Name_Lang_deDE`, `Name_Lang_enCN`, `Name_Lang_zhCN`, `Name_Lang_enTW`, `Name_Lang_zhTW`, `Name_Lang_esES`, `Name_Lang_esMX`, `Name_Lang_ruRU`, `Name_Lang_ptPT`, `Name_Lang_ptBR`, `Name_Lang_itIT`, `Name_Lang_Unk`, `Name_Lang_Mask`, `NameSubtext_Lang_enUS`, `NameSubtext_Lang_enGB`, `NameSubtext_Lang_koKR`, `NameSubtext_Lang_frFR`, `NameSubtext_Lang_deDE`, `NameSubtext_Lang_enCN`, `NameSubtext_Lang_zhCN`, `NameSubtext_Lang_enTW`, `NameSubtext_Lang_zhTW`, `NameSubtext_Lang_esES`, `NameSubtext_Lang_esMX`, `NameSubtext_Lang_ruRU`, `NameSubtext_Lang_ptPT`, `NameSubtext_Lang_ptBR`, `NameSubtext_Lang_itIT`, `NameSubtext_Lang_Unk`, `NameSubtext_Lang_Mask`, `Description_Lang_enUS`, `Description_Lang_enGB`, `Description_Lang_koKR`, `Description_Lang_frFR`, `Description_Lang_deDE`, `Description_Lang_enCN`, `Description_Lang_zhCN`, `Description_Lang_enTW`, `Description_Lang_zhTW`, `Description_Lang_esES`, `Description_Lang_esMX`, `Description_Lang_ruRU`, `Description_Lang_ptPT`, `Description_Lang_ptBR`, `Description_Lang_itIT`, `Description_Lang_Unk`, `Description_Lang_Mask`, `AuraDescription_Lang_enUS`, `AuraDescription_Lang_enGB`, `AuraDescription_Lang_koKR`, `AuraDescription_Lang_frFR`, `AuraDescription_Lang_deDE`, `AuraDescription_Lang_enCN`, `AuraDescription_Lang_zhCN`, `AuraDescription_Lang_enTW`, `AuraDescription_Lang_zhTW`, `AuraDescription_Lang_esES`, `AuraDescription_Lang_esMX`, `AuraDescription_Lang_ruRU`, `AuraDescription_Lang_ptPT`, `AuraDescription_Lang_ptBR`, `AuraDescription_Lang_itIT`, `AuraDescription_Lang_Unk`, `AuraDescription_Lang_Mask`, `ManaCostPct`, `StartRecoveryCategory`, `StartRecoveryTime`, `MaxTargetLevel`, `SpellClassSet`, `SpellClassMask_1`, `SpellClassMask_2`, `SpellClassMask_3`, `MaxTargets`, `DefenseType`, `PreventionType`, `StanceBarOrder`, `EffectChainAmplitude_1`, `EffectChainAmplitude_2`, `EffectChainAmplitude_3`, `MinFactionID`, `MinReputation`, `RequiredAuraVision`, `RequiredTotemCategoryID_1`, `RequiredTotemCategoryID_2`, `RequiredAreasID`, `SchoolMask`, `RuneCostID`, `SpellMissileID`, `PowerDisplayID`, `EffectBonusMultiplier_1`, `EffectBonusMultiplier_2`, `EffectBonusMultiplier_3`, `SpellDescriptionVariableID`, `SpellDifficultyID`) VALUES +(24081, 0, 0, 0, 256, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 101, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 28, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 15041, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 'Summon Spawn of Mar\'li', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', 0, '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', 0, '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', 0, '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0); + +DELETE FROM `spell_script_names` WHERE `ScriptName` IN ('spell_hatch_eggs', 'spell_enveloping_webs', 'spell_marli_transform'); +INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES +(24083, 'spell_hatch_eggs'), +(24110, 'spell_enveloping_webs'), +(24084, 'spell_marli_transform'); + +DELETE FROM `creature_text` WHERE `CreatureID` = 15041; +DELETE FROM `creature_text` WHERE `CreatureID` = 14510 AND `GroupID` = 4; +INSERT INTO `creature_text` (`CreatureID`,`GroupID`,`ID`,`Text`,`Type`,`Language`,`Probability`,`Emote`,`Duration`,`Sound`,`BroadcastTextId`,`TextRange`,`comment`) VALUES +(15041, 0, 0, '%s is fully grown!', 16, 0, 100, 0, 0, 0, 10445, 0, 'Spawn of Mar\'li - EMOTE_FULL_GROWN'), +(14510, 4, 0, 'The brood shall not fall!', 14, 0, 100, 0, 0, 0, 10444, 0, 'Mar\'li - SAY_TRANSFORM_BACK'); + +DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId` = 13 AND `SourceEntry` IN (24082, 24083); +INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `SourceId`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `NegativeCondition`, `ErrorType`, `ErrorTextId`, `ScriptName`, `Comment`) VALUES +(13, 1, 24082, 0, 0, 31, 0, 5, 179985, 0, 0, 0, 0, '', 'Hatch Spider Egg targets Spider Egg'), +(13, 1, 24083, 0, 0, 31, 0, 5, 179985, 0, 0, 0, 0, '', 'Hatch Eggs targets Spider Egg'); diff --git a/src/server/scripts/EasternKingdoms/ZulGurub/boss_marli.cpp b/src/server/scripts/EasternKingdoms/ZulGurub/boss_marli.cpp index 140c99c23..6748979a8 100644 --- a/src/server/scripts/EasternKingdoms/ZulGurub/boss_marli.cpp +++ b/src/server/scripts/EasternKingdoms/ZulGurub/boss_marli.cpp @@ -15,45 +15,72 @@ * with this program. If not, see . */ -/* ScriptData -SDName: Boss_Marli -SD%Complete: 80 -SDComment: Charging healers and casters not working. Perhaps wrong Spell Timers. -SDCategory: Zul'Gurub -EndScriptData */ - +#include "GameObjectAI.h" +#include "SpellScript.h" #include "ScriptMgr.h" #include "ScriptedCreature.h" +#include "TaskScheduler.h" #include "zulgurub.h" enum Says { + // Mar'li SAY_AGGRO = 0, SAY_TRANSFORM = 1, SAY_SPIDER_SPAWN = 2, - SAY_DEATH = 3 + SAY_DEATH = 3, + SAY_TRANSFORM_BACK = 4, + + // Spawn of Mar'li + EMOTE_FULL_GROWN = 0 }; enum Spells { + // Spider form SPELL_CHARGE = 22911, - SPELL_ASPECT_OF_MARLI = 24686, // A stun spell - SPELL_ENVOLWINGWEB = 24110, + SPELL_ENVELOPING_WEB = 24110, + SPELL_CORROSIVE_POISON = 24111, + SPELL_POISON_SHOCK = 24112, + + //Troll form SPELL_POISON_VOLLEY = 24099, + SPELL_DRAIN_LIFE = 24300, + SPELL_ENLARGE = 24109, + SPELL_SPIDER_EGGS = 24082, + + // All SPELL_SPIDER_FORM = 24084, - // The Spider Spell - SPELL_LEVELUP = 24312 // Not right Spell. + SPELL_TRANSFORM_BACK = 24085, + SPELL_THRASH = 3391, + SPELL_HATCH_SPIDER_EGG = 24082, + SPELL_HATCH_EGGS = 24083, + + // Spawn of Mar'li + SPELL_GROWTH = 24086, + SPELL_FULL_GROWN = 24088 }; enum Events { - EVENT_SPAWN_START_SPIDERS = 1, // Phase 1 - EVENT_POISON_VOLLEY = 2, // Phase All - EVENT_SPAWN_SPIDER = 3, // Phase All - EVENT_CHARGE_PLAYER = 4, // Phase 3 - EVENT_ASPECT_OF_MARLI = 5, // Phase 2 - EVENT_TRANSFORM = 6, // Phase 2 - EVENT_TRANSFORM_BACK = 7 // Phase 3 + // Spider form + EVENT_CHARGE_PLAYER = 7, + EVENT_ENVELOPING_WEB = 8, + EVENT_CORROSIVE_POISON = 9, + EVENT_POISON_SHOCK = 10, + + // Troll form + EVENT_POISON_VOLLEY = 11, + EVENT_DRAIN_LIFE = 12, + EVENT_ENLARGE = 13, + + // All + EVENT_SPAWN_START_SPIDERS = 1, + EVENT_TRANSFORM = 2, + EVENT_TRANSFORM_BACK = 3, + EVENT_HATCH_SPIDER_EGG = 4, + EVENT_THRASH = 5, + EVENT_TALK_FIRST_SPIDERS = 6, }; enum Phases @@ -63,208 +90,269 @@ enum Phases PHASE_THREE = 3 }; -class boss_marli : public CreatureScript +enum Misc { -public: - boss_marli() : CreatureScript("boss_marli") { } + GO_SPIDER_EGGS = 179985, +}; - struct boss_marliAI : public BossAI +struct boss_marli : public BossAI +{ + boss_marli(Creature* creature) : BossAI(creature, DATA_MARLI) { } + + void Reset() override { - boss_marliAI(Creature* creature) : BossAI(creature, DATA_MARLI) { } + if (events.IsInPhase(PHASE_THREE)) + me->HandleStatModifier(UNIT_MOD_DAMAGE_MAINHAND, TOTAL_PCT, 35.0f, false); // hack - void Reset() override + std::list eggs; + me->GetGameObjectListWithEntryInGrid(eggs, GO_SPIDER_EGGS, DEFAULT_VISIBILITY_INSTANCE); + + for (auto const& egg : eggs) { - if (events.IsInPhase(PHASE_THREE)) - me->HandleStatModifier(UNIT_MOD_DAMAGE_MAINHAND, TOTAL_PCT, 35.0f, false); // hack - _Reset(); + egg->Respawn(); + egg->UpdateObjectVisibility(); } - void JustDied(Unit* /*killer*/) override + BossAI::Reset(); + } + + void JustDied(Unit* killer) override + { + BossAI::JustDied(killer); + Talk(SAY_DEATH); + } + + void EnterCombat(Unit* who) override + { + BossAI::EnterCombat(who); + events.ScheduleEvent(EVENT_SPAWN_START_SPIDERS, 1000, 0, PHASE_ONE); + Talk(SAY_AGGRO); + } + + void UpdateAI(uint32 diff) override + { + if (!UpdateVictim()) + return; + + events.Update(diff); + + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; + + while (uint32 eventId = events.ExecuteEvent()) { - _JustDied(); - Talk(SAY_DEATH); - } - - void EnterCombat(Unit* /*who*/) override - { - _EnterCombat(); - events.ScheduleEvent(EVENT_SPAWN_START_SPIDERS, 1000, 0, PHASE_ONE); - Talk(SAY_AGGRO); - } - - void UpdateAI(uint32 diff) override - { - if (!UpdateVictim()) - return; - - events.Update(diff); - - if (me->HasUnitState(UNIT_STATE_CASTING)) - return; - - while (uint32 eventId = events.ExecuteEvent()) + switch (eventId) { - switch (eventId) + case EVENT_SPAWN_START_SPIDERS: + events.ScheduleEvent(EVENT_TALK_FIRST_SPIDERS, 500, 0, PHASE_TWO); + DoCastAOE(SPELL_HATCH_EGGS); + events.ScheduleEvent(EVENT_TRANSFORM, 60000, 0, PHASE_TWO); + events.ScheduleEvent(EVENT_POISON_VOLLEY, 15000, 0, PHASE_TWO); + events.ScheduleEvent(EVENT_HATCH_SPIDER_EGG, 30000, 0, PHASE_TWO); + events.ScheduleEvent(EVENT_DRAIN_LIFE, 30000, 0, PHASE_TWO); + events.ScheduleEvent(EVENT_THRASH, urand(4000, 6000)); // all phases + events.ScheduleEvent(EVENT_ENLARGE, urand(10000, 20000), 0, PHASE_TWO); + events.SetPhase(PHASE_TWO); + break; + case EVENT_TALK_FIRST_SPIDERS: + Talk(SAY_SPIDER_SPAWN); + break; + case EVENT_POISON_VOLLEY: + DoCastVictim(SPELL_POISON_VOLLEY, true); + events.ScheduleEvent(EVENT_POISON_VOLLEY, urand(10000, 20000), 0, PHASE_TWO); + break; + case EVENT_HATCH_SPIDER_EGG: + DoCastSelf(SPELL_HATCH_SPIDER_EGG, true); + events.ScheduleEvent(EVENT_HATCH_SPIDER_EGG, 20000, 0, PHASE_TWO); + break; + case EVENT_DRAIN_LIFE: + DoCastRandomTarget(SPELL_DRAIN_LIFE); + events.ScheduleEvent(EVENT_DRAIN_LIFE, urand(20000, 50000), 0, PHASE_TWO); + break; + case EVENT_ENLARGE: { - case EVENT_SPAWN_START_SPIDERS: - - if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0)) - { - Talk(SAY_SPIDER_SPAWN); - Creature* Spider = me->SummonCreature(15041, target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000); - if (Spider) - Spider->AI()->AttackStart(target); - Spider = me->SummonCreature(15041, target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000); - if (Spider) - Spider->AI()->AttackStart(target); - Spider = me->SummonCreature(15041, target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000); - if (Spider) - Spider->AI()->AttackStart(target); - Spider = me->SummonCreature(15041, target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000); - if (Spider) - Spider->AI()->AttackStart(target); - } - events.ScheduleEvent(EVENT_ASPECT_OF_MARLI, 12000, 0, PHASE_TWO); - events.ScheduleEvent(EVENT_TRANSFORM, 45000, 0, PHASE_TWO); - events.ScheduleEvent(EVENT_POISON_VOLLEY, 15000); - events.ScheduleEvent(EVENT_SPAWN_SPIDER, 30000); - events.ScheduleEvent(EVENT_TRANSFORM, 45000, 0, PHASE_TWO); - events.SetPhase(PHASE_TWO); - break; - case EVENT_POISON_VOLLEY: - DoCastVictim(SPELL_POISON_VOLLEY, true); - events.ScheduleEvent(EVENT_POISON_VOLLEY, urand(10000, 20000)); - break; - case EVENT_ASPECT_OF_MARLI: - DoCastVictim(SPELL_ASPECT_OF_MARLI, true); - events.ScheduleEvent(EVENT_ASPECT_OF_MARLI, urand(13000, 18000), 0, PHASE_TWO); - break; - case EVENT_SPAWN_SPIDER: - if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0)) - { - Creature* Spider = me->SummonCreature(15041, target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000); - if (Spider) - Spider->AI()->AttackStart(target); - } - events.ScheduleEvent(EVENT_SPAWN_SPIDER, urand(12000, 17000)); - break; - case EVENT_TRANSFORM: - { - Talk(SAY_TRANSFORM); - DoCast(me, SPELL_SPIDER_FORM); // SPELL_AURA_TRANSFORM - /* - CreatureTemplate const* cinfo = me->GetCreatureTemplate(); - me->SetBaseWeaponDamage(BASE_ATTACK, MINDAMAGE, (cinfo->mindmg +((cinfo->mindmg/100) * 35))); - me->SetBaseWeaponDamage(BASE_ATTACK, MAXDAMAGE, (cinfo->maxdmg +((cinfo->maxdmg/100) * 35))); - me->UpdateDamagePhysical(BASE_ATTACK); - */ - me->HandleStatModifier(UNIT_MOD_DAMAGE_MAINHAND, TOTAL_PCT, 35.0f, true); // hack - DoCastVictim(SPELL_ENVOLWINGWEB); - if (DoGetThreat(me->GetVictim())) - DoModifyThreatPercent(me->GetVictim(), -100); - events.ScheduleEvent(EVENT_CHARGE_PLAYER, 1500, 0, PHASE_THREE); - events.ScheduleEvent(EVENT_TRANSFORM_BACK, 25000, 0, PHASE_THREE); - events.SetPhase(PHASE_THREE); - break; - } - case EVENT_CHARGE_PLAYER: - { - Unit* target = nullptr; - int i = 0; - while (i++ < 3) // max 3 tries to get a random target with power_mana - { - target = SelectTarget(SelectTargetMethod::Random, 1, 100, true); // not aggro leader - if (target && target->getPowerType() == POWER_MANA) - break; - } - if (target) - { - DoCast(target, SPELL_CHARGE); - AttackStart(target); - } - events.ScheduleEvent(EVENT_CHARGE_PLAYER, 8000, 0, PHASE_THREE); - break; - } - case EVENT_TRANSFORM_BACK: - { - me->RemoveAura(SPELL_SPIDER_FORM); - /* - CreatureTemplate const* cinfo = me->GetCreatureTemplate(); - me->SetBaseWeaponDamage(BASE_ATTACK, MINDAMAGE, (cinfo->mindmg +((cinfo->mindmg/100) * 1))); - me->SetBaseWeaponDamage(BASE_ATTACK, MAXDAMAGE, (cinfo->maxdmg +((cinfo->maxdmg/100) * 1))); - me->UpdateDamagePhysical(BASE_ATTACK); - */ - me->HandleStatModifier(UNIT_MOD_DAMAGE_MAINHAND, TOTAL_PCT, 35.0f, false); // hack - events.ScheduleEvent(EVENT_ASPECT_OF_MARLI, 12000, 0, PHASE_TWO); - events.ScheduleEvent(EVENT_TRANSFORM, 45000, 0, PHASE_TWO); - events.ScheduleEvent(EVENT_POISON_VOLLEY, 15000); - events.ScheduleEvent(EVENT_SPAWN_SPIDER, 30000); - events.ScheduleEvent(EVENT_TRANSFORM, urand(35000, 60000), 0, PHASE_TWO); - events.SetPhase(PHASE_TWO); - break; - } - default: - break; + std::list targets = DoFindFriendlyMissingBuff(100.f, SPELL_ENLARGE); + if (targets.size() > 0) + DoCast(*(targets.begin()), SPELL_ENLARGE); + events.ScheduleEvent(EVENT_ENLARGE, urand(20000, 40000), 0, PHASE_TWO); + break; } + case EVENT_TRANSFORM: + Talk(SAY_TRANSFORM); + DoCastSelf(SPELL_SPIDER_FORM, true); + me->HandleStatModifier(UNIT_MOD_DAMAGE_MAINHAND, TOTAL_PCT, 35.0f, true); // hack + events.ScheduleEvent(EVENT_ENVELOPING_WEB, 5000, 0, PHASE_THREE); + events.ScheduleEvent(EVENT_CHARGE_PLAYER, 6000, 0, PHASE_THREE); + events.ScheduleEvent(EVENT_CORROSIVE_POISON, 1000, 0, PHASE_THREE); + events.ScheduleEvent(EVENT_POISON_SHOCK, urand(5000, 10000), 0, PHASE_THREE); + events.ScheduleEvent(EVENT_TRANSFORM_BACK, 60000, 0, PHASE_THREE); + events.SetPhase(PHASE_THREE); + break; + case EVENT_ENVELOPING_WEB: + DoCastAOE(SPELL_ENVELOPING_WEB); + events.ScheduleEvent(EVENT_CHARGE_PLAYER, 500, 0, PHASE_THREE); + events.ScheduleEvent(EVENT_ENVELOPING_WEB, urand(15000, 20000), 0, PHASE_THREE); + break; + case EVENT_CHARGE_PLAYER: + { + Unit* target = SelectTarget(SelectTargetMethod::Random, 0, [this](Unit* target) -> bool + { + if (target->GetTypeId() != TYPEID_PLAYER || target->getPowerType() != Powers::POWER_MANA) + return false; + if (me->IsWithinMeleeRange(target) || me->GetVictim() == target) + return false; + return true; + }); + if (target) + { + DoCast(target, SPELL_CHARGE); + AttackStart(target); + } + break; + } + case EVENT_CORROSIVE_POISON: + DoCastVictim(SPELL_CORROSIVE_POISON); + events.ScheduleEvent(EVENT_CORROSIVE_POISON, urand(25000, 35000), 0, PHASE_THREE); + break; + case EVENT_POISON_SHOCK: + DoCastRandomTarget(SPELL_POISON_SHOCK); + events.ScheduleEvent(EVENT_POISON_SHOCK, 10000, 0, PHASE_THREE); + break; + case EVENT_TRANSFORM_BACK: + me->RemoveAura(SPELL_SPIDER_FORM); + DoCastSelf(SPELL_TRANSFORM_BACK, true); + Talk(SAY_TRANSFORM_BACK); + me->HandleStatModifier(UNIT_MOD_DAMAGE_MAINHAND, TOTAL_PCT, 35.0f, false); // hack + events.ScheduleEvent(EVENT_TRANSFORM, 60000, 0, PHASE_TWO); + events.ScheduleEvent(EVENT_POISON_VOLLEY, 15000, 0, PHASE_TWO); + events.ScheduleEvent(EVENT_HATCH_SPIDER_EGG, 30000, 0, PHASE_TWO); + events.ScheduleEvent(EVENT_DRAIN_LIFE, 30000, 0, PHASE_TWO); + events.ScheduleEvent(EVENT_ENLARGE, urand(10000, 20000), 0, PHASE_TWO); + events.SetPhase(PHASE_TWO); + break; + case EVENT_THRASH: + DoCastVictim(SPELL_THRASH); + events.ScheduleEvent(EVENT_THRASH, urand(10000, 20000)); + break; + default: + break; } - - DoMeleeAttackIfReady(); } - }; - CreatureAI* GetAI(Creature* creature) const override - { - return GetZulGurubAI(creature); + DoMeleeAttackIfReady(); } }; -// Spawn of Marli -class npc_spawn_of_marli : public CreatureScript +// Spawn of Mar'li +struct npc_spawn_of_marli : public ScriptedAI { -public: - npc_spawn_of_marli() : CreatureScript("npc_spawn_of_marli") { } + npc_spawn_of_marli(Creature* creature) : ScriptedAI(creature) { } - struct npc_spawn_of_marliAI : public ScriptedAI + void Reset() override { - npc_spawn_of_marliAI(Creature* creature) : ScriptedAI(creature) { } + _scheduler.CancelAll(); + } - uint32 LevelUp_Timer; - - void Reset() override + void EnterCombat(Unit* /*who*/) override + { + _scheduler.Schedule(4s, [this](TaskContext context) { - LevelUp_Timer = 3000; - } - - void EnterCombat(Unit* /*who*/) override - { - } - - void UpdateAI(uint32 diff) override - { - //Return since we have no target - if (!UpdateVictim()) - return; - - //LevelUp_Timer - if (LevelUp_Timer <= diff) + if (context.GetRepeatCounter() < 5) { - DoCast(me, SPELL_LEVELUP); - LevelUp_Timer = 3000; + DoCastSelf(SPELL_GROWTH); + context.Repeat(4s); } - else LevelUp_Timer -= diff; + else + { + Talk(EMOTE_FULL_GROWN); + DoCastSelf(SPELL_FULL_GROWN); + } + }); + } - DoMeleeAttackIfReady(); - } - }; - - CreatureAI* GetAI(Creature* creature) const override + void UpdateAI(uint32 diff) override { - return GetZulGurubAI(creature); + //Return since we have no target + if (!UpdateVictim()) + return; + + _scheduler.Update(diff, [this] + { + DoMeleeAttackIfReady(); + }); + } + +private: + TaskScheduler _scheduler; +}; + +// 24083 - Hatch Eggs +class spell_hatch_eggs : public SpellScript +{ + PrepareSpellScript(spell_hatch_eggs); + + void HandleObjectAreaTargetSelect(std::list& targets) + { + targets.sort(Acore::ObjectDistanceOrderPred(GetCaster())); + targets.resize(GetSpellInfo()->MaxAffectedTargets); + } + + void Register() override + { + OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_hatch_eggs::HandleObjectAreaTargetSelect, EFFECT_0, TARGET_GAMEOBJECT_DEST_AREA); + } +}; + +// 24110 - Enveloping Webs +class spell_enveloping_webs : public SpellScript +{ + PrepareSpellScript(spell_enveloping_webs); + + void HandleOnHit() + { + Unit* caster = GetCaster(); + Unit* hitUnit = GetHitUnit(); + if (caster && hitUnit && hitUnit->GetTypeId() == TYPEID_PLAYER) + { + caster->GetThreatMgr().modifyThreatPercent(hitUnit, -100); + } + } + + void Register() override + { + OnHit += SpellHitFn(spell_enveloping_webs::HandleOnHit); + } +}; + +// 24084 - Mar'li Transform +class spell_marli_transform : public AuraScript +{ + PrepareAuraScript(spell_marli_transform); + + void HandleApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + if (GetCaster() && GetCaster()->ToCreature()) + GetCaster()->ToCreature()->LoadEquipment(0, true); + } + + void HandleRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + if (GetCaster() && GetCaster()->ToCreature()) + GetCaster()->ToCreature()->LoadEquipment(1, true); + } + + void Register() override + { + OnEffectApply += AuraEffectApplyFn(spell_marli_transform::HandleApply, EFFECT_0, SPELL_AURA_TRANSFORM, AURA_EFFECT_HANDLE_REAL); + OnEffectRemove += AuraEffectRemoveFn(spell_marli_transform::HandleRemove, EFFECT_0, SPELL_AURA_TRANSFORM, AURA_EFFECT_HANDLE_REAL); } }; void AddSC_boss_marli() { - new boss_marli(); - new npc_spawn_of_marli(); + RegisterCreatureAI(boss_marli); + RegisterCreatureAI(npc_spawn_of_marli); + RegisterSpellScript(spell_hatch_eggs); + RegisterSpellScript(spell_enveloping_webs); + RegisterSpellScript(spell_marli_transform); } diff --git a/src/server/scripts/EasternKingdoms/ZulGurub/instance_zulgurub.cpp b/src/server/scripts/EasternKingdoms/ZulGurub/instance_zulgurub.cpp index eee9e00cb..dcffbd4ff 100644 --- a/src/server/scripts/EasternKingdoms/ZulGurub/instance_zulgurub.cpp +++ b/src/server/scripts/EasternKingdoms/ZulGurub/instance_zulgurub.cpp @@ -36,7 +36,8 @@ ObjectData const creatureData[] = { { NPC_HIGH_PRIEST_THEKAL, DATA_THEKAL }, { NPC_ZEALOT_LORKHAN, DATA_LORKHAN }, - { NPC_ZEALOT_ZATH, DATA_ZATH } + { NPC_ZEALOT_ZATH, DATA_ZATH }, + { NPC_PRIESTESS_MARLI, DATA_MARLI } }; class instance_zulgurub : public InstanceMapScript @@ -49,6 +50,7 @@ public: instance_zulgurub_InstanceMapScript(Map* map) : InstanceScript(map) { SetBossNumber(EncounterCount); + LoadObjectData(creatureData, nullptr); LoadDoorData(doorData); LoadObjectData(creatureData, nullptr); } @@ -71,7 +73,15 @@ public: case NPC_HAKKAR: _hakkarGUID = creature->GetGUID(); break; + case NPC_SPAWN_OF_MARLI: + if (Creature* marli = GetCreature(DATA_MARLI)) + { + marli->AI()->JustSummoned(creature); + } + break; } + + InstanceScript::OnCreatureCreate(creature); } void OnGameObjectCreate(GameObject* go) override diff --git a/src/server/scripts/EasternKingdoms/ZulGurub/zulgurub.h b/src/server/scripts/EasternKingdoms/ZulGurub/zulgurub.h index 79e40b4c4..4941fe85f 100644 --- a/src/server/scripts/EasternKingdoms/ZulGurub/zulgurub.h +++ b/src/server/scripts/EasternKingdoms/ZulGurub/zulgurub.h @@ -49,6 +49,8 @@ enum CreatureIds NPC_ZULIAN_PROWLER = 15101, // Arlokk Event NPC_ZEALOT_LORKHAN = 11347, NPC_ZEALOT_ZATH = 11348, + NPC_PRIESTESS_MARLI = 14510, + NPC_SPAWN_OF_MARLI = 15041, NPC_HIGH_PRIEST_THEKAL = 14509, NPC_JINDO_THE_HEXXER = 11380, NPC_NIGHTMARE_ILLUSION = 15163,