mirror of
https://github.com/mod-playerbots/azerothcore-wotlk.git
synced 2026-01-16 18:40:28 +00:00
fix(Scripts/Stratholme): Rewrite Jarien and Sothos fight (#9391)
This commit is contained in:
@@ -0,0 +1,355 @@
|
||||
/*
|
||||
* This file is part of the AzerothCore 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 Affero General Public License as published by the
|
||||
* Free Software Foundation; either version 3 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 Affero 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/>.
|
||||
*/
|
||||
|
||||
#include "ScriptMgr.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "stratholme.h"
|
||||
#include "TaskScheduler.h"
|
||||
|
||||
enum Texts
|
||||
{
|
||||
// Sothos
|
||||
SAY_SOTHOS_ON_SUMMON_0 = 0,
|
||||
SAY_SOTHOS_ON_SUMMON_1 = 1,
|
||||
EMOTE_SOTHOS_VENGEANCE = 2,
|
||||
|
||||
// Jarien
|
||||
SAY_JARIEN_ON_SUMMON_0 = 0,
|
||||
SAY_JARIEN_ON_SUMMON_1 = 1,
|
||||
SAY_JARIEN_ON_SUMMON_2 = 2,
|
||||
EMOTE_JARIEN_VENGEANCE = 3,
|
||||
|
||||
// Spirit
|
||||
SAY_SPIRIT_BOTH_DEAD = 0
|
||||
};
|
||||
|
||||
enum Spells
|
||||
{
|
||||
// Jarien
|
||||
SPELL_MORTAL_STRIKE = 16856,
|
||||
SPELL_SHADOW_SHOCK = 22575,
|
||||
SPELL_CRIPPLE = 20812,
|
||||
SPELL_CLEAVE = 15284,
|
||||
|
||||
// Sothos
|
||||
SPELL_SHIELD_CHARGE = 15749,
|
||||
SPELL_SHIELD_SLAM = 15655,
|
||||
SPELL_SHIELD_BLOCK = 12169,
|
||||
SPELL_SHADOW_BOLT = 27646,
|
||||
SPELL_FEAR = 27641,
|
||||
|
||||
// Both
|
||||
SPELL_VENGEANCE = 27650
|
||||
};
|
||||
|
||||
enum Phases
|
||||
{
|
||||
PHASE_TALK = 0,
|
||||
PHASE_FIGHT
|
||||
};
|
||||
|
||||
enum Actions
|
||||
{
|
||||
ACTION_PARTNER_DEAD = 0
|
||||
};
|
||||
|
||||
const Position heirloomsPosition = { 3423.389893f, -3055.571045f, 136.49837f, 5.707379f };
|
||||
|
||||
void HandleBothDead(Creature* creature, bool jarien, Unit* killer)
|
||||
{
|
||||
// Spirit talk
|
||||
if (jarien)
|
||||
{
|
||||
if (Creature* spirit = creature->FindNearestCreature(NPC_SPIRIT_OF_JARIEN, 100.f))
|
||||
{
|
||||
spirit->AttackStop();
|
||||
spirit->SetReactState(REACT_PASSIVE);
|
||||
spirit->AI()->Talk(SAY_SPIRIT_BOTH_DEAD);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (Creature* spirit = creature->FindNearestCreature(NPC_SPIRIT_OF_SOTHOS, 100.f))
|
||||
{
|
||||
spirit->AttackStop();
|
||||
spirit->SetReactState(REACT_PASSIVE);
|
||||
spirit->AI()->Talk(SAY_SPIRIT_BOTH_DEAD);
|
||||
}
|
||||
}
|
||||
|
||||
// chest spawn
|
||||
if (GameObject* chest = killer->SummonGameObject(GO_JARIEN_AND_SOTHOS_HEIRLOOMS, heirloomsPosition.GetPositionX(), heirloomsPosition.GetPositionY(), heirloomsPosition.GetPositionZ(), heirloomsPosition.GetOrientation(), 0.f, 0.f, 0.f, 0.f, 0))
|
||||
{
|
||||
chest->setActive(true);
|
||||
chest->SetGoState(GO_STATE_READY);
|
||||
chest->SetLootState(GO_READY);
|
||||
chest->SetUInt32Value(GAMEOBJECT_FACTION, 35);
|
||||
}
|
||||
}
|
||||
|
||||
struct boss_jarien : public BossAI
|
||||
{
|
||||
boss_jarien(Creature* creature) : BossAI(creature, DATA_JARIEN)
|
||||
{
|
||||
_scheduler.SetValidator([this]
|
||||
{
|
||||
return !me->HasUnitState(UNIT_STATE_CASTING);
|
||||
});
|
||||
|
||||
_talked = false;
|
||||
_phase = PHASE_TALK;
|
||||
}
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
_scheduler.CancelAll();
|
||||
_phase = _talked ? PHASE_FIGHT : PHASE_TALK;
|
||||
if (_sothosDied)
|
||||
{
|
||||
if (Creature* sothos = me->FindNearestCreature(NPC_SOTHOS, 200.f, false))
|
||||
{
|
||||
sothos->Respawn();
|
||||
}
|
||||
}
|
||||
_sothosDied = false;
|
||||
_Reset();
|
||||
}
|
||||
|
||||
void IsSummonedBy(Unit* /*summoner*/) override
|
||||
{
|
||||
me->SetReactState(REACT_PASSIVE);
|
||||
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
|
||||
Talk(SAY_JARIEN_ON_SUMMON_0);
|
||||
|
||||
_scheduler.Schedule(6s, [this](TaskContext /*context*/)
|
||||
{
|
||||
Talk(SAY_JARIEN_ON_SUMMON_1);
|
||||
})
|
||||
.Schedule(12s, [this](TaskContext /*context*/)
|
||||
{
|
||||
Talk(SAY_JARIEN_ON_SUMMON_2);
|
||||
_talked = true;
|
||||
_phase = PHASE_FIGHT;
|
||||
me->SetReactState(REACT_AGGRESSIVE);
|
||||
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
|
||||
});
|
||||
}
|
||||
|
||||
void JustDied(Unit* killer) override
|
||||
{
|
||||
_JustDied();
|
||||
if (Creature * sothos = me->FindNearestCreature(NPC_SOTHOS, 200.f))
|
||||
{
|
||||
sothos->AI()->DoAction(ACTION_PARTNER_DEAD);
|
||||
}
|
||||
|
||||
me->SummonCreature(NPC_SPIRIT_OF_JARIEN, me->GetPosition());
|
||||
|
||||
if (_sothosDied)
|
||||
{
|
||||
HandleBothDead(me, true, killer);
|
||||
}
|
||||
}
|
||||
|
||||
void DoAction(int32 action) override
|
||||
{
|
||||
if (action == ACTION_PARTNER_DEAD)
|
||||
{
|
||||
me->SetFullHealth();
|
||||
DoCastSelf(SPELL_VENGEANCE);
|
||||
Talk(EMOTE_JARIEN_VENGEANCE);
|
||||
_sothosDied = true;
|
||||
}
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* /*who*/) override
|
||||
{
|
||||
_EnterCombat();
|
||||
_scheduler.Schedule(5s, [this](TaskContext context)
|
||||
{
|
||||
DoCastVictim(SPELL_SHADOW_SHOCK);
|
||||
context.Repeat(10s, 12s);
|
||||
})
|
||||
.Schedule(3s, [this](TaskContext context)
|
||||
{
|
||||
DoCastVictim(SPELL_CLEAVE);
|
||||
context.Repeat(10s);
|
||||
})
|
||||
.Schedule(11s, [this](TaskContext context)
|
||||
{
|
||||
DoCastRandomTarget(SPELL_CRIPPLE);
|
||||
context.Repeat(30s);
|
||||
})
|
||||
.Schedule(10s, [this](TaskContext context)
|
||||
{
|
||||
DoCastVictim(SPELL_MORTAL_STRIKE);
|
||||
context.Repeat(15s);
|
||||
});
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
if (!UpdateVictim() && _phase != PHASE_TALK)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_scheduler.Update(diff, [this]
|
||||
{
|
||||
DoMeleeAttackIfReady();
|
||||
});
|
||||
}
|
||||
|
||||
protected:
|
||||
TaskScheduler _scheduler;
|
||||
uint8 _phase;
|
||||
bool _talked;
|
||||
bool _sothosDied;
|
||||
};
|
||||
|
||||
struct boss_sothos : public BossAI
|
||||
{
|
||||
boss_sothos(Creature* creature) : BossAI(creature, DATA_SOTHOS)
|
||||
{
|
||||
_scheduler.SetValidator([this]
|
||||
{
|
||||
return !me->HasUnitState(UNIT_STATE_CASTING);
|
||||
});
|
||||
|
||||
_talked = false;
|
||||
_phase = PHASE_TALK;
|
||||
}
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
_scheduler.CancelAll();
|
||||
_phase = _talked ? PHASE_FIGHT : PHASE_TALK;
|
||||
if (_jarienDied)
|
||||
{
|
||||
if (Creature* jarien = me->FindNearestCreature(NPC_JARIEN, 200.f, false))
|
||||
{
|
||||
jarien->Respawn();
|
||||
}
|
||||
}
|
||||
_jarienDied = false;
|
||||
_Reset();
|
||||
}
|
||||
|
||||
void IsSummonedBy(Unit* /*summoner*/) override
|
||||
{
|
||||
me->SetReactState(REACT_PASSIVE);
|
||||
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
|
||||
|
||||
_scheduler.Schedule(12s, [this](TaskContext /*context*/)
|
||||
{
|
||||
_talked = true;
|
||||
_phase = PHASE_FIGHT;
|
||||
me->SetReactState(REACT_AGGRESSIVE);
|
||||
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
|
||||
})
|
||||
.Schedule(3s, [this](TaskContext /*context*/)
|
||||
{
|
||||
Talk(SAY_SOTHOS_ON_SUMMON_0);
|
||||
})
|
||||
.Schedule(9s, [this](TaskContext /*context*/)
|
||||
{
|
||||
Talk(SAY_SOTHOS_ON_SUMMON_1);
|
||||
});
|
||||
}
|
||||
|
||||
void JustDied(Unit* killer) override
|
||||
{
|
||||
_JustDied();
|
||||
if (Creature* jarien = me->FindNearestCreature(NPC_JARIEN, 200.f))
|
||||
{
|
||||
jarien->AI()->DoAction(ACTION_PARTNER_DEAD);
|
||||
}
|
||||
|
||||
me->SummonCreature(NPC_SPIRIT_OF_SOTHOS, me->GetPosition());
|
||||
|
||||
if (_jarienDied)
|
||||
{
|
||||
HandleBothDead(me, false, killer);
|
||||
}
|
||||
}
|
||||
|
||||
void DoAction(int32 action) override
|
||||
{
|
||||
if (action == ACTION_PARTNER_DEAD)
|
||||
{
|
||||
me->SetFullHealth();
|
||||
DoCastSelf(SPELL_VENGEANCE);
|
||||
Talk(EMOTE_SOTHOS_VENGEANCE);
|
||||
_jarienDied = true;
|
||||
}
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* /*who*/) override
|
||||
{
|
||||
_EnterCombat();
|
||||
_scheduler.Schedule(10s, [this](TaskContext context)
|
||||
{
|
||||
DoCastAOE(SPELL_FEAR);
|
||||
context.Repeat(18s, 20s);
|
||||
})
|
||||
.Schedule(9s, [this](TaskContext context)
|
||||
{
|
||||
DoCastAOE(SPELL_SHADOW_BOLT);
|
||||
context.Repeat(10s, 11s);
|
||||
})
|
||||
.Schedule(15s, [this](TaskContext context)
|
||||
{
|
||||
DoCastRandomTarget(SPELL_SHIELD_CHARGE);
|
||||
context.Repeat();
|
||||
})
|
||||
.Schedule(3s, [this](TaskContext context)
|
||||
{
|
||||
DoCastSelf(SPELL_SHIELD_BLOCK);
|
||||
context.Repeat(10s, 12s);
|
||||
})
|
||||
.Schedule(4s, [this](TaskContext context)
|
||||
{
|
||||
DoCastVictim(SPELL_SHIELD_SLAM);
|
||||
context.Repeat(14s);
|
||||
});
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
if (!UpdateVictim() && _phase != PHASE_TALK)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_scheduler.Update(diff, [this]
|
||||
{
|
||||
DoMeleeAttackIfReady();
|
||||
});
|
||||
}
|
||||
|
||||
protected:
|
||||
TaskScheduler _scheduler;
|
||||
uint8 _phase;
|
||||
bool _talked;
|
||||
bool _jarienDied;
|
||||
};
|
||||
|
||||
void AddSC_boss_jarien_and_sothos()
|
||||
{
|
||||
RegisterStratholmeCreatureAI(boss_jarien);
|
||||
RegisterStratholmeCreatureAI(boss_sothos);
|
||||
}
|
||||
@@ -33,6 +33,8 @@ enum DataTypes
|
||||
|
||||
DATA_BARON_RUN_NONE = 0,
|
||||
DATA_BARON_RUN_GATE = 1,
|
||||
DATA_JARIEN = 2,
|
||||
DATA_SOTHOS = 3
|
||||
};
|
||||
|
||||
enum CreatureIds
|
||||
@@ -47,6 +49,10 @@ enum CreatureIds
|
||||
NPC_PLAGUED_RAT = 10441,
|
||||
NPC_PLAGUED_INSECT = 10461,
|
||||
NPC_PLAGUED_MAGGOT = 10536,
|
||||
NPC_JARIEN = 16101,
|
||||
NPC_SOTHOS = 16102,
|
||||
NPC_SPIRIT_OF_JARIEN = 16103,
|
||||
NPC_SPIRIT_OF_SOTHOS = 16104
|
||||
};
|
||||
|
||||
enum GameobjectIds
|
||||
@@ -64,6 +70,7 @@ enum GameobjectIds
|
||||
GO_PORT_TRAP_GATE_2 = 175350, // Gate trap scarlet side
|
||||
GO_PORT_TRAP_GATE_3 = 175355, // Gate trap undead side
|
||||
GO_PORT_TRAP_GATE_4 = 175354,
|
||||
GO_JARIEN_AND_SOTHOS_HEIRLOOMS = 181083
|
||||
};
|
||||
|
||||
enum MiscIds
|
||||
@@ -98,4 +105,6 @@ inline AI* GetStratholmeAI(T* obj)
|
||||
return GetInstanceAI<AI>(obj, StratholmeScriptName);
|
||||
}
|
||||
|
||||
#define RegisterStratholmeCreatureAI(ai_name) RegisterCreatureAIWithFactory(ai_name, GetStratholmeAI)
|
||||
|
||||
#endif
|
||||
|
||||
@@ -100,6 +100,7 @@ void AddSC_boss_darkmaster_gandling();
|
||||
void AddSC_instance_scholomance(); //Scholomance
|
||||
void AddSC_instance_shadowfang_keep(); //Shadowfang keep
|
||||
void AddSC_boss_baroness_anastari();
|
||||
void AddSC_boss_jarien_and_sothos();
|
||||
void AddSC_instance_stratholme(); //Stratholme
|
||||
void AddSC_instance_sunken_temple(); //Sunken Temple
|
||||
void AddSC_instance_sunwell_plateau(); //Sunwell Plateau
|
||||
@@ -242,6 +243,7 @@ void AddEasternKingdomsScripts()
|
||||
AddSC_instance_scholomance(); //Scholomance
|
||||
AddSC_instance_shadowfang_keep(); //Shadowfang keep
|
||||
AddSC_boss_baroness_anastari();
|
||||
AddSC_boss_jarien_and_sothos();
|
||||
AddSC_instance_stratholme(); //Stratholme
|
||||
AddSC_instance_sunken_temple(); //Sunken Temple
|
||||
AddSC_instance_sunwell_plateau(); //Sunwell Plateau
|
||||
|
||||
Reference in New Issue
Block a user