fix(Core/ZulGurub): Jin'do the Hexxer rewrite (#12233)

Co-authored-by: UltraNix <ultranix@users.noreply.github.com>
This commit is contained in:
Nefertumm
2022-07-09 18:36:51 -03:00
committed by GitHub
parent c63d70e95f
commit 9c09857b19
2 changed files with 244 additions and 217 deletions
@@ -0,0 +1,36 @@
--
DELETE FROM `spell_target_position` WHERE `id` = 24466;
INSERT INTO `spell_target_position` (`ID`, `EffectIndex`, `MapID`, `PositionX`, `PositionY`, `PositionZ`, `Orientation`) VALUES
(24466, 0, 309, -11582.9, -1251.15, 90, 5.04179);
UPDATE `creature` SET `spawntimesecs` = 20 WHERE `id1` = 14826;
UPDATE `creature_template` SET `AIName` = 'SmartAI' WHERE `entry` = 14826;
DELETE FROM `smart_scripts` WHERE (`entryorguid` = 14826) AND (`source_type` = 0) AND (`id` IN (0, 1));
INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `event_param5`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_param4`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES
(14826, 0, 0, 0, 6, 0, 100, 0, 0, 0, 0, 0, 0, 41, 5000, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 'Sacrificed Troll - On Just Died - Despawn In 5000 ms'),
(14826, 0, 1, 0, 11, 0, 100, 0, 0, 0, 0, 0, 0, 70, 0, 0, 0, 0, 0, 0, 9, 14826, 0, 100, 2, 0, 0, 0, 0, 'Sacrificed Troll - On Respawn - Respawn Closest Creature \'Sacrificed Troll\'');
SET @LEADERGUID := 49081;
DELETE FROM `creature_formations` WHERE `memberGUID` IN (@LEADERGUID, 49078, 49079, 49080, 49082, 49083, 49084, 49085, 49086, 49087);
INSERT INTO `creature_formations` (`leaderGUID`, `memberGUID`, `dist`, `angle`, `groupAI`) VALUES
(@LEADERGUID, @LEADERGUID, 0, 0, 3),
(@LEADERGUID, 49078, 0, 0, 3),
(@LEADERGUID, 49079, 0, 0, 3),
(@LEADERGUID, 49080, 0, 0, 3),
(@LEADERGUID, 49082, 0, 0, 3),
(@LEADERGUID, 49083, 0, 0, 3),
(@LEADERGUID, 49084, 0, 0, 3),
(@LEADERGUID, 49085, 0, 0, 3),
(@LEADERGUID, 49086, 0, 0, 3),
(@LEADERGUID, 49087, 0, 0, 3);
UPDATE `creature_template_spell` SET `Spell` = 24261 WHERE `CreatureID` = 15112 AND `Index` = 0;
DELETE FROM `spell_script_names` WHERE `ScriptName` IN ('spell_random_aggro', 'spell_delusions_of_jindo');
INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES
(23878, 'spell_random_aggro'),
(24306, 'spell_delusions_of_jindo');
UPDATE `creature_template` SET `speed_run` = 1.14286, `speed_walk` = 1.32 WHERE `entry` = 11380;
@@ -15,15 +15,10 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/* ScriptData
SDName: Boss_Jin'do the Hexxer
SD%Complete: 85
SDComment: Mind Control not working because of core bug. Shades visible for all.
SDCategory: Zul'Gurub
EndScriptData */
#include "ScriptMgr.h"
#include "ScriptedCreature.h"
#include "SpellScript.h"
#include "TaskScheduler.h"
#include "zulgurub.h"
enum Say
@@ -33,56 +28,45 @@ enum Say
enum Spells
{
SPELL_BRAINWASHTOTEM = 24262,
SPELL_POWERFULLHEALINGWARD = 24309,
SPELL_BRAIN_WASH_TOTEM = 24262,
SPELL_POWERFULL_HEALING_WARD = 24309,
SPELL_HEX = 24053,
SPELL_DELUSIONSOFJINDO = 24306,
SPELL_DELUSIONS_OF_JINDO = 24306,
SPELL_SUMMON_SHADE_OF_JINDO = 24308,
SPELL_BANISH = 24466,
//Healing Ward Spell
SPELL_HEAL = 24311,
//Shade of Jindo Spell
SPELL_SHADEOFJINDO_PASSIVE = 24307,
SPELL_SHADEOFJINDO_VISUAL = 24313,
SPELL_SHADOWSHOCK = 19460
SPELL_SHADE_OF_JINDO_PASSIVE = 24307,
SPELL_SHADE_OF_JINDO_VISUAL = 24313,
SPELL_SHADOW_SHOCK = 19460,
SPELL_RANDOM_AGGRO = 23878
};
enum Events
{
EVENT_BRAINWASHTOTEM = 1,
EVENT_POWERFULLHEALINGWARD = 2,
EVENT_BRAIN_WASH_TOTEM = 1,
EVENT_POWERFULL_HEALING_WARD = 2,
EVENT_HEX = 3,
EVENT_DELUSIONSOFJINDO = 4,
EVENT_DELUSIONS_OF_JINDO = 4,
EVENT_TELEPORT = 5
};
Position const TeleportLoc = {-11583.7783f, -1249.4278f, 77.5471f, 4.745f};
class boss_jindo : public CreatureScript
struct boss_jindo : public BossAI
{
public:
boss_jindo() : CreatureScript("boss_jindo") { }
boss_jindo(Creature* creature) : BossAI(creature, DATA_JINDO) { }
struct boss_jindoAI : public BossAI
void EnterCombat(Unit* who) override
{
boss_jindoAI(Creature* creature) : BossAI(creature, DATA_JINDO) { }
void Reset() override
{
_Reset();
}
void JustDied(Unit* /*killer*/) override
{
_JustDied();
}
void EnterCombat(Unit* /*who*/) override
{
_EnterCombat();
events.ScheduleEvent(EVENT_BRAINWASHTOTEM, 20000);
events.ScheduleEvent(EVENT_POWERFULLHEALINGWARD, 16000);
BossAI::EnterCombat(who);
events.ScheduleEvent(EVENT_BRAIN_WASH_TOTEM, 20000);
events.ScheduleEvent(EVENT_POWERFULL_HEALING_WARD, 16000);
events.ScheduleEvent(EVENT_HEX, 8000);
events.ScheduleEvent(EVENT_DELUSIONSOFJINDO, 10000);
events.ScheduleEvent(EVENT_DELUSIONS_OF_JINDO, 10000);
events.ScheduleEvent(EVENT_TELEPORT, 5000);
Talk(SAY_AGGRO);
}
@@ -103,6 +87,22 @@ public:
}
}
void EnterEvadeMode(EvadeReason evadeReason) override
{
if (_EnterEvadeMode(evadeReason))
{
me->AddUnitState(UNIT_STATE_EVADE);
Reset();
me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_DANCE);
me->m_Events.AddEventAtOffset([&]()
{
me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_NONE);
me->GetMotionMaster()->MoveTargetedHome();
}, 4s);
}
}
void UpdateAI(uint32 diff) override
{
if (!UpdateVictim())
@@ -117,65 +117,25 @@ public:
{
switch (eventId)
{
case EVENT_BRAINWASHTOTEM:
DoCast(me, SPELL_BRAINWASHTOTEM);
events.ScheduleEvent(EVENT_BRAINWASHTOTEM, urand(18000, 26000));
case EVENT_BRAIN_WASH_TOTEM:
DoCastSelf(SPELL_BRAIN_WASH_TOTEM);
events.ScheduleEvent(EVENT_BRAIN_WASH_TOTEM, urand(18000, 26000));
break;
case EVENT_POWERFULLHEALINGWARD:
DoCastSelf(SPELL_POWERFULLHEALINGWARD, true);
events.ScheduleEvent(EVENT_POWERFULLHEALINGWARD, urand(14000, 20000));
case EVENT_POWERFULL_HEALING_WARD:
DoCastSelf(SPELL_POWERFULL_HEALING_WARD, true);
events.ScheduleEvent(EVENT_POWERFULL_HEALING_WARD, urand(14000, 20000));
break;
case EVENT_HEX:
if (me->GetThreatMgr().getThreatList().size() > 1)
DoCastVictim(SPELL_HEX, true);
events.ScheduleEvent(EVENT_HEX, urand(12000, 20000));
break;
case EVENT_DELUSIONSOFJINDO: // HACK
// Casting the delusion curse with a shade so shade will attack the same target with the curse.
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0))
{
DoCast(target, SPELL_DELUSIONSOFJINDO);
Creature* Shade = me->SummonCreature(NPC_SHADE_OF_JINDO, target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000);
if (Shade)
Shade->AI()->AttackStart(target);
}
events.ScheduleEvent(EVENT_DELUSIONSOFJINDO, urand(4000, 12000));
case EVENT_DELUSIONS_OF_JINDO:
DoCastRandomTarget(SPELL_DELUSIONS_OF_JINDO);
events.ScheduleEvent(EVENT_DELUSIONS_OF_JINDO, urand(4000, 12000));
break;
case EVENT_TELEPORT: // Possible HACK
// Teleports a random player and spawns 9 Sacrificed Trolls to attack player
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0))
{
DoTeleportPlayer(target, TeleportLoc.m_positionX, TeleportLoc.m_positionY, TeleportLoc.m_positionZ, TeleportLoc.GetOrientation());
if (DoGetThreat(me->GetVictim()))
DoModifyThreatPercent(target, -100);
Creature* SacrificedTroll;
SacrificedTroll = me->SummonCreature(NPC_SACRIFICED_TROLL, TeleportLoc.m_positionX + 2, TeleportLoc.m_positionY, TeleportLoc.m_positionZ, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000);
if (SacrificedTroll)
SacrificedTroll->AI()->AttackStart(target);
SacrificedTroll = me->SummonCreature(NPC_SACRIFICED_TROLL, TeleportLoc.m_positionX - 2, TeleportLoc.m_positionY, TeleportLoc.m_positionZ, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000);
if (SacrificedTroll)
SacrificedTroll->AI()->AttackStart(target);
SacrificedTroll = me->SummonCreature(NPC_SACRIFICED_TROLL, TeleportLoc.m_positionX + 4, TeleportLoc.m_positionY, TeleportLoc.m_positionZ, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000);
if (SacrificedTroll)
SacrificedTroll->AI()->AttackStart(target);
SacrificedTroll = me->SummonCreature(NPC_SACRIFICED_TROLL, TeleportLoc.m_positionX - 4, TeleportLoc.m_positionY, TeleportLoc.m_positionZ, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000);
if (SacrificedTroll)
SacrificedTroll->AI()->AttackStart(target);
SacrificedTroll = me->SummonCreature(NPC_SACRIFICED_TROLL, TeleportLoc.m_positionX, TeleportLoc.m_positionY + 2, TeleportLoc.m_positionZ, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000);
if (SacrificedTroll)
SacrificedTroll->AI()->AttackStart(target);
SacrificedTroll = me->SummonCreature(NPC_SACRIFICED_TROLL, TeleportLoc.m_positionX, TeleportLoc.m_positionY - 2, TeleportLoc.m_positionZ, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000);
if (SacrificedTroll)
SacrificedTroll->AI()->AttackStart(target);
SacrificedTroll = me->SummonCreature(NPC_SACRIFICED_TROLL, TeleportLoc.m_positionX, TeleportLoc.m_positionY + 4, TeleportLoc.m_positionZ, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000);
if (SacrificedTroll)
SacrificedTroll->AI()->AttackStart(target);
SacrificedTroll = me->SummonCreature(NPC_SACRIFICED_TROLL, TeleportLoc.m_positionX, TeleportLoc.m_positionY - 4, TeleportLoc.m_positionZ, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000);
if (SacrificedTroll)
SacrificedTroll->AI()->AttackStart(target);
SacrificedTroll = me->SummonCreature(NPC_SACRIFICED_TROLL, TeleportLoc.m_positionX + 3, TeleportLoc.m_positionY, TeleportLoc.m_positionZ, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000);
if (SacrificedTroll)
SacrificedTroll->AI()->AttackStart(target);
}
case EVENT_TELEPORT:
DoCastRandomTarget(SPELL_BANISH);
events.ScheduleEvent(EVENT_TELEPORT, urand(15000, 23000));
break;
default:
@@ -188,114 +148,145 @@ public:
bool CanAIAttack(Unit const* target) const override
{
if (me->GetThreatMgr().getThreatList().size() > 1 && me->GetThreatMgr().getOnlineContainer().getMostHated()->getTarget() == target)
return !target->HasAura(SPELL_HEX);
}
};
CreatureAI* GetAI(Creature* creature) const override
{
return GetZulGurubAI<boss_jindoAI>(creature);
return true;
}
};
//Healing Ward
class npc_healing_ward : public CreatureScript
struct npc_healing_ward : public ScriptedAI
{
public:
npc_healing_ward()
: CreatureScript("npc_healing_ward")
npc_healing_ward(Creature* creature) : ScriptedAI(creature)
{
_instance = creature->GetInstanceScript();
}
struct npc_healing_wardAI : public ScriptedAI
{
npc_healing_wardAI(Creature* creature) : ScriptedAI(creature)
{
instance = creature->GetInstanceScript();
}
uint32 Heal_Timer;
InstanceScript* instance;
void Reset() override
{
Heal_Timer = 2000;
_scheduler.CancelAll();
}
void EnterCombat(Unit* /*who*/) override
{
_scheduler.
Schedule(2s, [this](TaskContext context)
{
Unit* pJindo = ObjectAccessor::GetUnit(*me, _instance->GetGuidData(DATA_JINDO));
if (pJindo)
DoCast(pJindo, SPELL_HEAL);
context.Repeat(3s);
});
}
void UpdateAI(uint32 diff) override
{
//Heal_Timer
if (Heal_Timer <= diff)
_scheduler.Update(diff, [this]
{
Unit* pJindo = ObjectAccessor::GetUnit(*me, instance->GetGuidData(DATA_JINDO));
if (pJindo)
DoCast(pJindo, SPELL_HEAL);
Heal_Timer = 3000;
}
else Heal_Timer -= diff;
DoMeleeAttackIfReady();
});
}
};
CreatureAI* GetAI(Creature* creature) const override
{
return GetZulGurubAI<npc_healing_wardAI>(creature);
}
private:
InstanceScript* _instance;
TaskScheduler _scheduler;
};
//Shade of Jindo
class npc_shade_of_jindo : public CreatureScript
struct npc_shade_of_jindo : public ScriptedAI
{
public:
npc_shade_of_jindo()
: CreatureScript("npc_shade_of_jindo")
npc_shade_of_jindo(Creature* creature) : ScriptedAI(creature) { }
void IsSummonedBy(Unit* /*summoner*/) override
{
DoZoneInCombat();
DoCastSelf(SPELL_SHADE_OF_JINDO_PASSIVE, true);
DoCastSelf(SPELL_SHADE_OF_JINDO_VISUAL, true);
DoCastAOE(SPELL_RANDOM_AGGRO, true);
}
struct npc_shade_of_jindoAI : public ScriptedAI
{
npc_shade_of_jindoAI(Creature* creature) : ScriptedAI(creature) { }
uint32 ShadowShock_Timer;
void Reset() override
{
ShadowShock_Timer = 1000;
DoCastSelf(SPELL_SHADEOFJINDO_PASSIVE, true);
DoCastSelf(SPELL_SHADEOFJINDO_VISUAL, true);
_scheduler.CancelAll();
_scheduler.
Schedule(1s, [this](TaskContext context)
{
DoCastAOE(SPELL_RANDOM_AGGRO, true);
context.Repeat();
});
}
void EnterCombat(Unit* /*who*/) override { }
void EnterCombat(Unit* /*who*/) override
{
_scheduler.
Schedule(1s, [this](TaskContext context)
{
DoCastVictim(SPELL_SHADOW_SHOCK);
context.Repeat(2s);
});
}
void UpdateAI(uint32 diff) override
{
//ShadowShock_Timer
if (ShadowShock_Timer <= diff)
_scheduler.Update(diff, [this]
{
DoCastVictim(SPELL_SHADOWSHOCK);
ShadowShock_Timer = 2000;
}
else ShadowShock_Timer -= diff;
DoMeleeAttackIfReady();
});
}
private:
TaskScheduler _scheduler;
};
class spell_random_aggro : public SpellScript
{
PrepareSpellScript(spell_random_aggro);
void HandleOnHit()
{
Unit* caster = GetCaster();
Unit* target = GetHitUnit();
if (!caster || !target || !caster->GetAI())
return;
caster->GetAI()->AttackStart(target);
}
void Register() override
{
OnHit += SpellHitFn(spell_random_aggro::HandleOnHit);
}
};
CreatureAI* GetAI(Creature* creature) const override
class spell_delusions_of_jindo : public SpellScript
{
return GetZulGurubAI<npc_shade_of_jindoAI>(creature);
PrepareSpellScript(spell_delusions_of_jindo);
bool Validate(SpellInfo const* /*spellInfo*/) override
{
return ValidateSpellInfo({ SPELL_SUMMON_SHADE_OF_JINDO });
}
void HandleOnHit()
{
Unit* caster = GetCaster();
if (caster)
caster->CastSpell(caster, SPELL_SUMMON_SHADE_OF_JINDO, true);
}
void Register() override
{
OnHit += SpellHitFn(spell_delusions_of_jindo::HandleOnHit);
}
};
void AddSC_boss_jindo()
{
new boss_jindo();
new npc_healing_ward();
new npc_shade_of_jindo();
RegisterZulGurubCreatureAI(boss_jindo);
RegisterZulGurubCreatureAI(npc_healing_ward);
RegisterZulGurubCreatureAI(npc_shade_of_jindo);
RegisterSpellScript(spell_random_aggro);
RegisterSpellScript(spell_delusions_of_jindo);
}