mirror of
https://github.com/TrinityCore/TrinityCore.git
synced 2026-01-17 08:00:48 +01:00
Merge branch 'Treeston-3.3.5-heigan' into 3.3.5
This commit is contained in:
7
sql/updates/world/2015_10_10_01_world.sql
Normal file
7
sql/updates/world/2015_10_10_01_world.sql
Normal file
@@ -0,0 +1,7 @@
|
||||
--
|
||||
UPDATE `creature_text` SET `probability`=20 WHERE `entry`=15936 AND `groupid`=1;
|
||||
|
||||
DELETE FROM `creature_text` WHERE `entry`=15936 AND `groupid` IN (4,5);
|
||||
INSERT INTO `creature_text` (`entry`,`groupid`,`id`,`text`,`type`,`probability`,`BroadcastTextId`,`TextRange`,`comment`) VALUES
|
||||
(15936,4,0,"%s teleports and begins to channel a spell!",41,100,32332,3,"Heigan EMOTE_DANCE"),
|
||||
(15936,5,0,"%s rushes to attack once more!",41,100,32333,3,"Heigan EMOTE_DANCE_END");
|
||||
@@ -21,36 +21,42 @@
|
||||
#include "naxxramas.h"
|
||||
#include "Player.h"
|
||||
|
||||
enum Heigan
|
||||
enum Spells
|
||||
{
|
||||
SPELL_DECREPIT_FEVER = 29998, // 25-man: 55011
|
||||
SPELL_SPELL_DISRUPTION = 29310,
|
||||
SPELL_PLAGUE_CLOUD = 29350,
|
||||
SPELL_DECREPIT_FEVER = 29998, // 25-man: 55011
|
||||
SPELL_SPELL_DISRUPTION = 29310,
|
||||
SPELL_PLAGUE_CLOUD = 29350,
|
||||
SPELL_TELEPORT_SELF = 30211,
|
||||
};
|
||||
|
||||
SAY_AGGRO = 0,
|
||||
SAY_SLAY = 1,
|
||||
SAY_TAUNT = 2,
|
||||
SAY_DEATH = 3
|
||||
enum Yells
|
||||
{
|
||||
SAY_AGGRO = 0,
|
||||
SAY_SLAY = 1,
|
||||
SAY_TAUNT = 2,
|
||||
SAY_DEATH = 3,
|
||||
|
||||
EMOTE_DANCE = 4,
|
||||
EMOTE_DANCE_END = 5,
|
||||
};
|
||||
|
||||
enum Events
|
||||
{
|
||||
EVENT_NONE,
|
||||
EVENT_DISRUPT,
|
||||
EVENT_DISRUPT = 1,
|
||||
EVENT_FEVER,
|
||||
EVENT_ERUPT,
|
||||
EVENT_PHASE,
|
||||
EVENT_DANCE,
|
||||
EVENT_DANCE_END
|
||||
};
|
||||
|
||||
enum Phases
|
||||
{
|
||||
PHASE_FIGHT = 1,
|
||||
PHASE_DANCE,
|
||||
PHASE_DANCE
|
||||
};
|
||||
|
||||
enum Misc
|
||||
{
|
||||
ACTION_SAFETY_DANCE_FAIL = 1,
|
||||
DATA_SAFETY_DANCE = 19962139
|
||||
};
|
||||
|
||||
@@ -66,39 +72,25 @@ public:
|
||||
|
||||
struct boss_heiganAI : public BossAI
|
||||
{
|
||||
boss_heiganAI(Creature* creature) : BossAI(creature, BOSS_HEIGAN)
|
||||
{
|
||||
eruptSection = 0;
|
||||
eruptDirection = false;
|
||||
safetyDance = false;
|
||||
phase = PHASE_FIGHT;
|
||||
}
|
||||
boss_heiganAI(Creature* creature) : BossAI(creature, BOSS_HEIGAN), eruptSection(0), eruptDirection(false), safetyDance(false) { }
|
||||
|
||||
uint32 eruptSection;
|
||||
bool eruptDirection;
|
||||
bool safetyDance;
|
||||
Phases phase;
|
||||
void Reset() override
|
||||
{
|
||||
me->SetReactState(REACT_AGGRESSIVE);
|
||||
_Reset();
|
||||
}
|
||||
|
||||
void KilledUnit(Unit* who) override
|
||||
{
|
||||
if (!(rand32() % 5))
|
||||
Talk(SAY_SLAY);
|
||||
Talk(SAY_SLAY);
|
||||
|
||||
if (who->GetTypeId() == TYPEID_PLAYER)
|
||||
safetyDance = false;
|
||||
}
|
||||
|
||||
void SetData(uint32 id, uint32 data) override
|
||||
{
|
||||
if (id == DATA_SAFETY_DANCE)
|
||||
safetyDance = data ? true : false;
|
||||
}
|
||||
|
||||
uint32 GetData(uint32 type) const override
|
||||
{
|
||||
if (type == DATA_SAFETY_DANCE)
|
||||
return safetyDance ? 1 : 0;
|
||||
|
||||
return 0;
|
||||
return (type == DATA_SAFETY_DANCE && safetyDance) ? 1u : 0u;
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*killer*/) override
|
||||
@@ -111,35 +103,14 @@ public:
|
||||
{
|
||||
_EnterCombat();
|
||||
Talk(SAY_AGGRO);
|
||||
EnterPhase(PHASE_FIGHT);
|
||||
safetyDance = true;
|
||||
}
|
||||
|
||||
void EnterPhase(Phases newPhase)
|
||||
{
|
||||
phase = newPhase;
|
||||
events.Reset();
|
||||
|
||||
eruptSection = 3;
|
||||
if (phase == PHASE_FIGHT)
|
||||
{
|
||||
events.ScheduleEvent(EVENT_DISRUPT, urand(10000, 25000));
|
||||
events.ScheduleEvent(EVENT_FEVER, urand(15000, 20000));
|
||||
events.ScheduleEvent(EVENT_PHASE, 90000);
|
||||
events.ScheduleEvent(EVENT_ERUPT, 15000);
|
||||
me->GetMotionMaster()->MoveChase(me->GetVictim());
|
||||
}
|
||||
else
|
||||
{
|
||||
float x, y, z, o;
|
||||
me->GetHomePosition(x, y, z, o);
|
||||
me->NearTeleportTo(x, y, z, o - (float(M_PI) / 2));
|
||||
me->GetMotionMaster()->Clear();
|
||||
me->GetMotionMaster()->MoveIdle();
|
||||
me->SetTarget(ObjectGuid::Empty);
|
||||
DoCastAOE(SPELL_PLAGUE_CLOUD);
|
||||
events.ScheduleEvent(EVENT_PHASE, 45000);
|
||||
events.ScheduleEvent(EVENT_ERUPT, 8000);
|
||||
}
|
||||
events.ScheduleEvent(EVENT_DISRUPT, urand(15 * IN_MILLISECONDS, 20 * IN_MILLISECONDS), 0, PHASE_FIGHT);
|
||||
events.ScheduleEvent(EVENT_FEVER, urand(10 * IN_MILLISECONDS, 20 * IN_MILLISECONDS), 0, PHASE_FIGHT);
|
||||
events.ScheduleEvent(EVENT_DANCE, 90 * IN_MILLISECONDS, 0, PHASE_FIGHT);
|
||||
events.ScheduleEvent(EVENT_ERUPT, 15 * IN_MILLISECONDS, 0, PHASE_FIGHT);
|
||||
|
||||
safetyDance = true;
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
@@ -155,15 +126,36 @@ public:
|
||||
{
|
||||
case EVENT_DISRUPT:
|
||||
DoCastAOE(SPELL_SPELL_DISRUPTION);
|
||||
events.ScheduleEvent(EVENT_DISRUPT, urand(5000, 10000));
|
||||
events.ScheduleEvent(EVENT_DISRUPT, 11 * IN_MILLISECONDS);
|
||||
break;
|
||||
case EVENT_FEVER:
|
||||
DoCastAOE(SPELL_DECREPIT_FEVER);
|
||||
events.ScheduleEvent(EVENT_FEVER, urand(20000, 25000));
|
||||
events.ScheduleEvent(EVENT_FEVER, urand(20 * IN_MILLISECONDS, 25 * IN_MILLISECONDS));
|
||||
break;
|
||||
case EVENT_PHASE:
|
||||
/// @todo Add missing texts for both phase switches
|
||||
EnterPhase(phase == PHASE_FIGHT ? PHASE_DANCE : PHASE_FIGHT);
|
||||
case EVENT_DANCE:
|
||||
events.SetPhase(PHASE_DANCE);
|
||||
Talk(SAY_TAUNT);
|
||||
Talk(EMOTE_DANCE);
|
||||
eruptSection = 3;
|
||||
me->SetReactState(REACT_PASSIVE);
|
||||
me->AttackStop();
|
||||
me->StopMoving();
|
||||
DoCast(SPELL_TELEPORT_SELF);
|
||||
DoCastAOE(SPELL_PLAGUE_CLOUD);
|
||||
events.ScheduleEvent(EVENT_DANCE_END, 45 * IN_MILLISECONDS, 0, PHASE_DANCE);
|
||||
events.ScheduleEvent(EVENT_ERUPT, 10 * IN_MILLISECONDS);
|
||||
break;
|
||||
case EVENT_DANCE_END:
|
||||
events.SetPhase(PHASE_FIGHT);
|
||||
Talk(EMOTE_DANCE_END);
|
||||
eruptSection = 3;
|
||||
events.ScheduleEvent(EVENT_DISRUPT, urand(10, 25) * IN_MILLISECONDS, 0, PHASE_FIGHT);
|
||||
events.ScheduleEvent(EVENT_FEVER, urand(15, 20) * IN_MILLISECONDS, 0, PHASE_FIGHT);
|
||||
events.ScheduleEvent(EVENT_DANCE, 90 * IN_MILLISECONDS, 0, PHASE_FIGHT);
|
||||
events.ScheduleEvent(EVENT_ERUPT, 15 * IN_MILLISECONDS, 0, PHASE_FIGHT);
|
||||
me->CastStop();
|
||||
me->SetReactState(REACT_AGGRESSIVE);
|
||||
DoZoneInCombat();
|
||||
break;
|
||||
case EVENT_ERUPT:
|
||||
instance->SetData(DATA_HEIGAN_ERUPT, eruptSection);
|
||||
@@ -176,13 +168,22 @@ public:
|
||||
|
||||
eruptDirection ? ++eruptSection : --eruptSection;
|
||||
|
||||
events.ScheduleEvent(EVENT_ERUPT, phase == PHASE_FIGHT ? 10000 : 3000);
|
||||
if (events.IsInPhase(PHASE_DANCE))
|
||||
events.ScheduleEvent(EVENT_ERUPT, 3 * IN_MILLISECONDS, 0, PHASE_DANCE);
|
||||
else
|
||||
events.ScheduleEvent(EVENT_ERUPT, 10 * IN_MILLISECONDS, 0, PHASE_FIGHT);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
private:
|
||||
uint32 eruptSection;
|
||||
bool eruptDirection;
|
||||
|
||||
bool safetyDance; // is achievement still possible? (= no player deaths yet)
|
||||
};
|
||||
|
||||
};
|
||||
@@ -205,7 +206,7 @@ class spell_heigan_eruption : public SpellScriptLoader
|
||||
if (GetHitDamage() >= int32(GetHitPlayer()->GetHealth()))
|
||||
if (InstanceScript* instance = caster->GetInstanceScript())
|
||||
if (Creature* Heigan = ObjectAccessor::GetCreature(*caster, instance->GetGuidData(DATA_HEIGAN)))
|
||||
Heigan->AI()->SetData(DATA_SAFETY_DANCE, 0);
|
||||
Heigan->AI()->KilledUnit(GetHitPlayer());
|
||||
}
|
||||
|
||||
void Register() override
|
||||
@@ -223,9 +224,7 @@ class spell_heigan_eruption : public SpellScriptLoader
|
||||
class achievement_safety_dance : public AchievementCriteriaScript
|
||||
{
|
||||
public:
|
||||
achievement_safety_dance() : AchievementCriteriaScript("achievement_safety_dance")
|
||||
{
|
||||
}
|
||||
achievement_safety_dance() : AchievementCriteriaScript("achievement_safety_dance") { }
|
||||
|
||||
bool OnCheck(Player* /*player*/, Unit* target) override
|
||||
{
|
||||
|
||||
@@ -78,12 +78,13 @@ ObjectData const objectData[] =
|
||||
{ 0, 0, }
|
||||
};
|
||||
|
||||
float const HeiganPos[2] = { 2796.0f, -3707.0f };
|
||||
// from P2 teleport spell stored target
|
||||
float const HeiganPos[2] = { 2793.86f, -3707.38f };
|
||||
float const HeiganEruptionSlope[3] =
|
||||
{
|
||||
(-3685.0f - HeiganPos[1]) / (2724.0f - HeiganPos[0]),
|
||||
(-3647.0f - HeiganPos[1]) / (2749.0f - HeiganPos[0]),
|
||||
(-3637.0f - HeiganPos[1]) / (2771.0f - HeiganPos[0])
|
||||
(-3703.303223f - HeiganPos[1]) / (2777.494141f - HeiganPos[0]), // between right center and far right
|
||||
(-3696.948242f - HeiganPos[1]) / (2785.624268f - HeiganPos[0]), // between left and right halves
|
||||
(-3691.880615f - HeiganPos[1]) / (2790.280029f - HeiganPos[0]) // between far left and left center
|
||||
};
|
||||
|
||||
// 0 H x
|
||||
@@ -246,7 +247,6 @@ class instance_naxxramas : public InstanceMapScript
|
||||
if (go->GetGOInfo()->displayId == 6785 || go->GetGOInfo()->displayId == 1287)
|
||||
{
|
||||
uint32 section = GetEruptionSection(go->GetPositionX(), go->GetPositionY());
|
||||
|
||||
HeiganEruptionGUID[section].erase(go->GetGUID());
|
||||
return;
|
||||
}
|
||||
@@ -552,7 +552,7 @@ class instance_naxxramas : public InstanceMapScript
|
||||
// This Function is called in CheckAchievementCriteriaMeet and CheckAchievementCriteriaMeet is called before SetBossState(bossId, DONE),
|
||||
// so to check if all bosses are done the checker must exclude 1 boss, the last done, if there is at most 1 encouter in progress when is
|
||||
// called this function then all bosses are done. The one boss that check is the boss that calls this function, so it is dead.
|
||||
bool AreAllEncoutersDone()
|
||||
bool AreAllEncountersDone()
|
||||
{
|
||||
uint32 numBossAlive = 0;
|
||||
for (uint32 i = 0; i < EncounterCount; ++i)
|
||||
@@ -589,7 +589,7 @@ class instance_naxxramas : public InstanceMapScript
|
||||
case 13239: // Loatheb
|
||||
case 13240: // Thaddius
|
||||
case 7617: // Kel'Thuzad
|
||||
if (AreAllEncoutersDone() && !playerDied)
|
||||
if (AreAllEncountersDone() && !playerDied)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user