mirror of
https://github.com/TrinityCore/TrinityCore.git
synced 2026-01-16 07:30:42 +01:00
Merge pull request #13008 from mik1893/onyxia
Scripts/Onyxia Lair: small rework
This commit is contained in:
2
sql/updates/world/2014_09_01_01_world_onyxia.sql
Normal file
2
sql/updates/world/2014_09_01_01_world_onyxia.sql
Normal file
@@ -0,0 +1,2 @@
|
||||
UPDATE creature_template SET InhabitType = 5 WHERE entry = 10184;
|
||||
UPDATE creature_template SET InhabitType = 5 WHERE entry = 36538;
|
||||
@@ -111,6 +111,7 @@ static OnyxMove MoveData[8]=
|
||||
Position const MiddleRoomLocation = {-23.6155f, -215.357f, -55.7344f, 0.0f};
|
||||
|
||||
Position const Phase2Location = {-80.924f, -214.299f, -82.942f, 0.0f};
|
||||
Position const Phase2Floating = { -80.924f, -214.299f, -57.942f, 0.0f };
|
||||
|
||||
Position const SpawnLocations[3]=
|
||||
{
|
||||
@@ -128,7 +129,7 @@ public:
|
||||
|
||||
struct boss_onyxiaAI : public BossAI
|
||||
{
|
||||
boss_onyxiaAI(Creature* creature) : BossAI(creature, DATA_ONYXIA), Summons(me)
|
||||
boss_onyxiaAI(Creature* creature) : BossAI(creature, DATA_ONYXIA)
|
||||
{
|
||||
Reset();
|
||||
}
|
||||
@@ -138,16 +139,16 @@ public:
|
||||
if (!IsCombatMovementAllowed())
|
||||
SetCombatMovement(true);
|
||||
|
||||
_Reset();
|
||||
|
||||
Phase = PHASE_START;
|
||||
MovePoint = urand(0, 5);
|
||||
PointData = GetMoveData();
|
||||
Summons.DespawnAll();
|
||||
SummonWhelpCount = 0;
|
||||
IsMoving = false;
|
||||
|
||||
instance->SetBossState(DATA_ONYXIA, NOT_STARTED);
|
||||
instance->SetData(DATA_ONYXIA_PHASE, Phase);
|
||||
instance->DoStopTimedAchievement(ACHIEVEMENT_TIMED_TYPE_EVENT, ACHIEV_TIMED_START_EVENT);
|
||||
instance->DoStopTimedAchievement(ACHIEVEMENT_TIMED_TYPE_EVENT, ACHIEV_TIMED_START_EVENT);
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* /*who*/) override
|
||||
@@ -155,20 +156,15 @@ public:
|
||||
Talk(SAY_AGGRO);
|
||||
me->SetInCombatWithZone();
|
||||
|
||||
events.ScheduleEvent(EVENT_FLAME_BREATH, urand (10000, 20000));
|
||||
events.ScheduleEvent(EVENT_TAIL_SWEEP, urand (15000, 20000));
|
||||
events.ScheduleEvent(EVENT_CLEAVE, urand (2000, 5000));
|
||||
events.ScheduleEvent(EVENT_WING_BUFFET, urand (10000, 20000));
|
||||
events.Reset();
|
||||
|
||||
events.ScheduleEvent(EVENT_FLAME_BREATH, urand(10000, 20000));
|
||||
events.ScheduleEvent(EVENT_TAIL_SWEEP, urand(15000, 20000));
|
||||
events.ScheduleEvent(EVENT_CLEAVE, urand(2000, 5000));
|
||||
events.ScheduleEvent(EVENT_WING_BUFFET, urand(10000, 20000));
|
||||
|
||||
instance->SetBossState(DATA_ONYXIA, IN_PROGRESS);
|
||||
instance->DoStartTimedAchievement(ACHIEVEMENT_TIMED_TYPE_EVENT, ACHIEV_TIMED_START_EVENT);
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*killer*/) override
|
||||
{
|
||||
instance->SetBossState(DATA_ONYXIA, DONE);
|
||||
|
||||
Summons.DespawnAll();
|
||||
instance->DoStartTimedAchievement(ACHIEVEMENT_TIMED_TYPE_EVENT, ACHIEV_TIMED_START_EVENT);
|
||||
}
|
||||
|
||||
void JustSummoned(Creature* summoned) override
|
||||
@@ -186,13 +182,9 @@ public:
|
||||
summoned->setActive(true);
|
||||
break;
|
||||
}
|
||||
Summons.Summon(summoned);
|
||||
summons.Summon(summoned);
|
||||
}
|
||||
|
||||
void SummonedCreatureDespawn(Creature* summon) override
|
||||
{
|
||||
Summons.Despawn(summon);
|
||||
}
|
||||
|
||||
void KilledUnit(Unit* /*victim*/) override
|
||||
{
|
||||
@@ -231,22 +223,43 @@ public:
|
||||
}
|
||||
break;
|
||||
case 9:
|
||||
me->GetMotionMaster()->MoveChase(me->GetVictim());
|
||||
events.ScheduleEvent(EVENT_BELLOWING_ROAR, 1000);
|
||||
me->SetCanFly(false);
|
||||
me->SetDisableGravity(false);
|
||||
me->RemoveByteFlag(UNIT_FIELD_BYTES_1, 3, UNIT_BYTE1_FLAG_ALWAYS_STAND | UNIT_BYTE1_FLAG_HOVER);
|
||||
if (Creature* trigger = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_TRIGGER_GUID)))
|
||||
me->Kill(trigger);
|
||||
me->SetReactState(REACT_AGGRESSIVE);
|
||||
// tank selection based on phase one. If tank is not there i take nearest one
|
||||
if (Unit* tank = ObjectAccessor::GetUnit(*me, instance->GetData64(DATA_TANK_GUID)))
|
||||
me->GetMotionMaster()->MoveChase(tank);
|
||||
else if (Unit* newtarget = SelectTarget(SELECT_TARGET_NEAREST, 0))
|
||||
me->GetMotionMaster()->MoveChase(newtarget);
|
||||
events.ScheduleEvent(EVENT_BELLOWING_ROAR, 5000);
|
||||
events.ScheduleEvent(EVENT_FLAME_BREATH, urand(10000, 20000));
|
||||
events.ScheduleEvent(EVENT_TAIL_SWEEP, urand(15000, 20000));
|
||||
events.ScheduleEvent(EVENT_CLEAVE, urand(2000, 5000));
|
||||
events.ScheduleEvent(EVENT_WING_BUFFET, urand(15000, 30000));
|
||||
break;
|
||||
case 10:
|
||||
me->SetCanFly(true);
|
||||
me->GetMotionMaster()->MovePoint(11, Phase2Location.GetPositionX(), Phase2Location.GetPositionY(), Phase2Location.GetPositionZ()+25);
|
||||
me->SetDisableGravity(true);
|
||||
me->SetByteFlag(UNIT_FIELD_BYTES_1, 3, UNIT_BYTE1_FLAG_ALWAYS_STAND | UNIT_BYTE1_FLAG_HOVER);
|
||||
me->SetFacingTo(me->GetOrientation() + float(M_PI));
|
||||
if (Creature * trigger = me->SummonCreature(NPC_TRIGGER, MiddleRoomLocation, TEMPSUMMON_CORPSE_DESPAWN))
|
||||
instance->SetData64(DATA_TRIGGER_GUID, trigger->GetGUID());
|
||||
me->GetMotionMaster()->MoveTakeoff(11, Phase2Floating);
|
||||
me->SetSpeed(MOVE_FLIGHT, 1.0f);
|
||||
Talk(SAY_PHASE_2_TRANS);
|
||||
instance->SetData(DATA_ONYXIA_PHASE, Phase);
|
||||
events.ScheduleEvent(EVENT_WHELP_SPAWN, 5000);
|
||||
events.ScheduleEvent(EVENT_LAIR_GUARD, 15000);
|
||||
events.ScheduleEvent(EVENT_DEEP_BREATH, 75000);
|
||||
events.ScheduleEvent(EVENT_MOVEMENT, 10000);
|
||||
events.ScheduleEvent(EVENT_FIREBALL, 18000);
|
||||
break;
|
||||
case 11:
|
||||
if (PointData)
|
||||
me->GetMotionMaster()->MovePoint(PointData->LocId, PointData->fX, PointData->fY, PointData->fZ);
|
||||
me->GetMotionMaster()->Clear(false);
|
||||
me->GetMotionMaster()->MoveIdle();
|
||||
break;
|
||||
default:
|
||||
@@ -272,13 +285,13 @@ public:
|
||||
(Spell->Id >= 22267 && Spell->Id <= 22268)) &&
|
||||
(target->GetTypeId() == TYPEID_PLAYER))
|
||||
{
|
||||
instance->SetData(DATA_SHE_DEEP_BREATH_MORE, FAIL);
|
||||
instance->SetData(DATA_SHE_DEEP_BREATH_MORE, FAIL);
|
||||
}
|
||||
}
|
||||
|
||||
OnyxMove* GetMoveData()
|
||||
{
|
||||
uint8 MaxCount = sizeof(MoveData)/sizeof(OnyxMove);
|
||||
uint8 MaxCount = sizeof(MoveData) / sizeof(OnyxMove);
|
||||
|
||||
for (uint8 i = 0; i < MaxCount; ++i)
|
||||
{
|
||||
@@ -291,9 +304,9 @@ public:
|
||||
|
||||
void SetNextRandomPoint()
|
||||
{
|
||||
uint8 MaxCount = sizeof(MoveData)/sizeof(OnyxMove);
|
||||
uint8 MaxCount = sizeof(MoveData) / sizeof(OnyxMove);
|
||||
|
||||
uint8 iTemp = urand(0, MaxCount-1);
|
||||
uint8 iTemp = urand(0, MaxCount - 1);
|
||||
|
||||
if (iTemp >= MovePoint)
|
||||
++iTemp;
|
||||
@@ -312,15 +325,13 @@ public:
|
||||
//Specific to PHASE_START || PHASE_END
|
||||
if (Phase == PHASE_START)
|
||||
{
|
||||
if (HealthBelowPct(60))
|
||||
if (HealthBelowPct(65))
|
||||
{
|
||||
SetCombatMovement(false);
|
||||
Phase = PHASE_BREATH;
|
||||
events.ScheduleEvent(EVENT_DEEP_BREATH, 85000);
|
||||
events.ScheduleEvent(EVENT_MOVEMENT, 14000);
|
||||
events.ScheduleEvent(EVENT_FIREBALL, 15000);
|
||||
events.ScheduleEvent(EVENT_LAIR_GUARD, 60000);
|
||||
events.ScheduleEvent(EVENT_WHELP_SPAWN, 60000);
|
||||
instance->SetData64(DATA_TANK_GUID, me->GetVictim()->GetGUID());
|
||||
me->SetReactState(REACT_PASSIVE);
|
||||
me->AttackStop();
|
||||
me->GetMotionMaster()->MovePoint(10, Phase2Location);
|
||||
return;
|
||||
}
|
||||
@@ -347,19 +358,19 @@ public:
|
||||
}
|
||||
case EVENT_FLAME_BREATH: // Phase PHASE_START and PHASE_END
|
||||
DoCastVictim(SPELL_FLAME_BREATH);
|
||||
events.ScheduleEvent(EVENT_FLAME_BREATH, urand (10000, 20000));
|
||||
events.ScheduleEvent(EVENT_FLAME_BREATH, urand(10000, 20000));
|
||||
break;
|
||||
case EVENT_TAIL_SWEEP: // Phase PHASE_START and PHASE_END
|
||||
DoCastAOE(SPELL_TAIL_SWEEP);
|
||||
events.ScheduleEvent(EVENT_TAIL_SWEEP, urand (15000, 20000));
|
||||
events.ScheduleEvent(EVENT_TAIL_SWEEP, urand(15000, 20000));
|
||||
break;
|
||||
case EVENT_CLEAVE: // Phase PHASE_START and PHASE_END
|
||||
DoCastVictim(SPELL_CLEAVE);
|
||||
events.ScheduleEvent(EVENT_CLEAVE, urand (2000, 5000));
|
||||
events.ScheduleEvent(EVENT_CLEAVE, urand(2000, 5000));
|
||||
break;
|
||||
case EVENT_WING_BUFFET: // Phase PHASE_START and PHASE_END
|
||||
DoCastVictim(SPELL_WING_BUFFET);
|
||||
events.ScheduleEvent(EVENT_WING_BUFFET, urand (15000, 30000));
|
||||
events.ScheduleEvent(EVENT_WING_BUFFET, urand(15000, 30000));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@@ -374,15 +385,18 @@ public:
|
||||
Phase = PHASE_END;
|
||||
instance->SetData(DATA_ONYXIA_PHASE, PHASE_END);
|
||||
Talk(SAY_PHASE_3_TRANS);
|
||||
|
||||
SetCombatMovement(true);
|
||||
me->SetCanFly(false);
|
||||
IsMoving = false;
|
||||
me->GetMotionMaster()->MovePoint(9, me->GetHomePosition());
|
||||
Position const pos = me->GetHomePosition();
|
||||
me->GetMotionMaster()->MovePoint(9, pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ() + 12.0f);
|
||||
events.ScheduleEvent(EVENT_BELLOWING_ROAR, 30000);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!me->isMoving())
|
||||
if (Creature* trigger = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_TRIGGER_GUID)))
|
||||
me->SetFacingToObject(trigger);
|
||||
|
||||
events.Update(diff);
|
||||
|
||||
while (uint32 eventId = events.ExecuteEvent())
|
||||
@@ -398,8 +412,10 @@ public:
|
||||
Talk(EMOTE_BREATH);
|
||||
if (PointData) /// @todo: In what cases is this null? What should we do?
|
||||
DoCast(me, PointData->SpellId);
|
||||
events.ScheduleEvent(EVENT_DEEP_BREATH, 70000);
|
||||
events.ScheduleEvent(EVENT_DEEP_BREATH, 75000);
|
||||
}
|
||||
else
|
||||
events.ScheduleEvent(EVENT_DEEP_BREATH, 1000);
|
||||
break;
|
||||
case EVENT_MOVEMENT: // Phase PHASE_BREATH
|
||||
if (!IsMoving && !(me->HasUnitState(UNIT_STATE_CASTING)))
|
||||
@@ -414,18 +430,21 @@ public:
|
||||
IsMoving = true;
|
||||
events.ScheduleEvent(EVENT_MOVEMENT, 25000);
|
||||
}
|
||||
else
|
||||
events.ScheduleEvent(EVENT_MOVEMENT, 500);
|
||||
break;
|
||||
case EVENT_FIREBALL: // Phase PHASE_BREATH
|
||||
if (me->GetMotionMaster()->GetCurrentMovementGeneratorType() != POINT_MOTION_TYPE)
|
||||
if (!IsMoving)
|
||||
{
|
||||
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
|
||||
DoCast(target, SPELL_FIREBALL);
|
||||
|
||||
events.ScheduleEvent(EVENT_FIREBALL, 8000);
|
||||
}
|
||||
else
|
||||
events.ScheduleEvent(EVENT_FIREBALL, 1000);
|
||||
break;
|
||||
case EVENT_LAIR_GUARD: // Phase PHASE_BREATH
|
||||
me->SummonCreature(NPC_LAIRGUARD, SpawnLocations[2], TEMPSUMMON_CORPSE_DESPAWN);
|
||||
me->SummonCreature(NPC_LAIRGUARD, SpawnLocations[2], TEMPSUMMON_CORPSE_DESPAWN);
|
||||
events.ScheduleEvent(EVENT_LAIR_GUARD, 30000);
|
||||
break;
|
||||
case EVENT_WHELP_SPAWN: // Phase PHASE_BREATH
|
||||
@@ -437,7 +456,7 @@ public:
|
||||
events.ScheduleEvent(EVENT_WHELP_SPAWN, 90000);
|
||||
}
|
||||
else
|
||||
events.ScheduleEvent(EVENT_WHELP_SPAWN, 500);
|
||||
events.ScheduleEvent(EVENT_WHELP_SPAWN, 500);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@@ -447,7 +466,6 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
SummonList Summons;
|
||||
OnyxMove* PointData;
|
||||
uint8 Phase;
|
||||
uint8 MovePoint;
|
||||
|
||||
@@ -53,6 +53,8 @@ public:
|
||||
SetBossNumber(EncounterCount);
|
||||
|
||||
onyxiaGUID = 0;
|
||||
triggerGUID = 0;
|
||||
tankGUID = 0;
|
||||
onyxiaLiftoffTimer = 0;
|
||||
manyWhelpsCounter = 0;
|
||||
eruptTimer = 0;
|
||||
@@ -181,6 +183,12 @@ public:
|
||||
FloorEruptionGUIDQueue.push(data);
|
||||
eruptTimer = 2500;
|
||||
break;
|
||||
case DATA_TRIGGER_GUID:
|
||||
triggerGUID = data;
|
||||
break;
|
||||
case DATA_TANK_GUID:
|
||||
tankGUID = data;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -190,6 +198,13 @@ public:
|
||||
{
|
||||
case NPC_ONYXIA:
|
||||
return onyxiaGUID;
|
||||
break;
|
||||
case DATA_TRIGGER_GUID:
|
||||
return triggerGUID;
|
||||
break;
|
||||
case DATA_TANK_GUID:
|
||||
return tankGUID;
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -298,6 +313,8 @@ public:
|
||||
std::map<uint64, uint32> FloorEruptionGUID[2];
|
||||
std::queue<uint64> FloorEruptionGUIDQueue;
|
||||
uint64 onyxiaGUID;
|
||||
uint64 triggerGUID;
|
||||
uint64 tankGUID;
|
||||
uint32 onyxiaLiftoffTimer;
|
||||
uint32 manyWhelpsCounter;
|
||||
uint32 eruptTimer;
|
||||
|
||||
@@ -35,7 +35,9 @@ enum Data32
|
||||
enum Data64
|
||||
{
|
||||
DATA_ONYXIA_GUID = 0,
|
||||
DATA_FLOOR_ERUPTION_GUID = 1
|
||||
DATA_FLOOR_ERUPTION_GUID = 1,
|
||||
DATA_TRIGGER_GUID = 2,
|
||||
DATA_TANK_GUID = 3
|
||||
};
|
||||
|
||||
enum OnyxiaPhases
|
||||
@@ -49,7 +51,8 @@ enum CreatureIds
|
||||
{
|
||||
NPC_WHELP = 11262,
|
||||
NPC_LAIRGUARD = 36561,
|
||||
NPC_ONYXIA = 10184
|
||||
NPC_ONYXIA = 10184,
|
||||
NPC_TRIGGER = 14495
|
||||
};
|
||||
|
||||
enum GameObjectIds
|
||||
|
||||
Reference in New Issue
Block a user