diff options
author | Machiavelli <machiavelli.trinity@gmail.com> | 2011-06-21 01:15:43 +0200 |
---|---|---|
committer | Machiavelli <machiavelli.trinity@gmail.com> | 2011-06-21 01:15:43 +0200 |
commit | acb47d719c00b550bfb72c8e71dcee9ed0d96a7c (patch) | |
tree | fd020b314ee5bf2448d540d67a5f8c2cfcd47e95 | |
parent | 508fcd3eb3f7e66da9e2d994069176601d48f5ee (diff) |
Scripts/Ulduar/XT002:
- Fix heart phase triggering if boss recovered health from scrapbots previously
- Fix scrapbot enter vehicle visual
- Allover cleanup and codestyle appliance
-rwxr-xr-x | src/server/game/Entities/Unit/Unit.cpp | 3 | ||||
-rw-r--r-- | src/server/scripts/Northrend/Ulduar/ulduar/boss_xt002.cpp | 422 |
2 files changed, 211 insertions, 214 deletions
diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index 104fec5e892..8c7536babd4 100755 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -5832,9 +5832,6 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, AuraEffect* trigger // Todo: Check if this amount is blizzlike vehicleBase->ModifyHealth(int32(vehicleBase->CountPctFromMaxHealth(1))); - - // Despawns the scrapbot - ToCreature()->DespawnOrUnsummon(); break; } } diff --git a/src/server/scripts/Northrend/Ulduar/ulduar/boss_xt002.cpp b/src/server/scripts/Northrend/Ulduar/ulduar/boss_xt002.cpp index 2ce3d98a79b..8b9fee2f72d 100644 --- a/src/server/scripts/Northrend/Ulduar/ulduar/boss_xt002.cpp +++ b/src/server/scripts/Northrend/Ulduar/ulduar/boss_xt002.cpp @@ -100,6 +100,7 @@ enum Events EVENT_ENERGY_ORB, EVENT_DISPOSE_HEART, EVENT_ENRAGE, + EVENT_ENTER_HARD_MODE, }; enum Timers @@ -139,12 +140,15 @@ enum Creatures enum Actions { - ACTION_ENTER_HARD_MODE = 0, + ACTION_ENTER_HARD_MODE, }; enum XT002Data { - DATA_TRANSFERED_HEALTH = 0, + DATA_TRANSFERED_HEALTH, + DATA_HARD_MODE, + DATA_HEALTH_RECOVERED, + DATA_GRAVITY_BOMB_CASUALTY, }; enum Yells @@ -188,29 +192,15 @@ class boss_xt002 : public CreatureScript { } - // Achievement related - bool HealthRecovered; // Did a scrapbot recover XT-002's health during the encounter? - bool HardMode; // Are we in hard mode? Or: was the heart killed during phase 2? - bool GravityBombCasualty; // Did someone die because of Gravity Bomb damage? - - uint8 _phase; - uint8 _heartExposed; - - uint32 transferHealth; - bool enterHardMode; - - void Reset() { _Reset(); me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); - HealthRecovered = false; - GravityBombCasualty = false; - HardMode = false; - - enterHardMode = false; + _healthRecovered = false; + _gravityBombCasualty = false; + _hardMode = false; _phase = 1; _heartExposed = 0; @@ -243,31 +233,7 @@ class boss_xt002 : public CreatureScript switch (action) { case ACTION_ENTER_HARD_MODE: - if (!HardMode) - { - HardMode = true; - - // Enter hard mode - enterHardMode = true; - - // set max health - me->SetFullHealth(); - - // Get his heartbreak buff - me->CastSpell(me, RAID_MODE(SPELL_HEARTBREAK_10, SPELL_HEARTBREAK_25), true); - - me->AddLootMode(LOOT_MODE_HARD_MODE_1); - } - break; - } - } - - void SetData(uint32 id, uint32 value) - { - switch(id) - { - case DATA_TRANSFERED_HEALTH: - transferHealth = value; + events.ScheduleEvent(EVENT_ENTER_HARD_MODE, 1); break; } } @@ -281,12 +247,11 @@ class boss_xt002 : public CreatureScript { DoScriptText(SAY_DEATH, me); _JustDied(); - } void DamageTaken(Unit* /*attacker*/, uint32& /*damage*/) { - if (!HardMode && _phase == 1 && !HealthAbovePct(100 - 25 * (_heartExposed+1))) + if (!_hardMode && _phase == 1 && !HealthAbovePct(100 - 25 * (_heartExposed+1))) ExposeHeart(); } @@ -297,12 +262,6 @@ class boss_xt002 : public CreatureScript events.Update(diff); - if (enterHardMode) - { - SetPhaseOne(); - enterHardMode = false; - } - if (me->HasUnitState(UNIT_STAT_CASTING)) return; @@ -334,22 +293,64 @@ class boss_xt002 : public CreatureScript DoScriptText(SAY_BERSERK, me); DoCast(me, SPELL_ENRAGE); break; + case EVENT_ENTER_HARD_MODE: + me->SetFullHealth(); + DoCast(me, RAID_MODE(SPELL_HEARTBREAK_10, SPELL_HEARTBREAK_25), true); + me->AddLootMode(LOOT_MODE_HARD_MODE_1); + _hardMode = true; + SetPhaseOne(); + break; } } - if (_phase == 1) + if (_phase == 1) DoMeleeAttackIfReady(); } void PassengerBoarded(Unit* who, int8 /*seatId*/, bool apply) { if (apply && who->GetEntry() == NPC_XS013_SCRAPBOT) - HealthRecovered = true; + { + // Need this so we can properly determine when to expose heart again in damagetaken hook + if (me->GetHealthPct() > (25 * (4 - _heartExposed))) + ++_heartExposed; + + _healthRecovered = true; + } + } + + uint32 GetData(uint32 type) + { + switch (type) + { + case DATA_HARD_MODE: + return _hardMode ? 1 : 0; + case DATA_HEALTH_RECOVERED: + return _healthRecovered ? 1 : 0; + case DATA_GRAVITY_BOMB_CASUALTY: + return _gravityBombCasualty ? 1 : 0; + } + + return 0; + } + + void SetData(uint32 type, uint32 data) + { + switch (type) + { + case DATA_TRANSFERED_HEALTH: + _transferHealth = data; + break; + case DATA_GRAVITY_BOMB_CASUALTY: + _gravityBombCasualty = (data > 0) ? true : false; + break; + } } void ExposeHeart() { - //Make untargetable + DoScriptText(SAY_HEART_OPENED, me); + DoCast(SPELL_SUBMERGE); // WIll make creature untargetable me->AttackStop(); me->SetReactState(REACT_PASSIVE); @@ -362,10 +363,8 @@ class boss_xt002 : public CreatureScript heart->CastSpell(heart, SPELL_HEART_HEAL_TO_FULL, true); heart->CastSpell(heart, SPELL_EXPOSED_HEART, false); // Channeled - //heart->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PET_IN_COMBAT | UNIT_FLAG_UNK_15 | UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_UNK_29); heart->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE); - - } + } events.CancelEvent(EVENT_SEARING_LIGHT); events.CancelEvent(EVENT_GRAVITY_BOMB); @@ -377,8 +376,6 @@ class boss_xt002 : public CreatureScript // Phase 2 has officially started _phase = 2; _heartExposed++; - - DoScriptText(SAY_HEART_OPENED, me); } void SetPhaseOne() @@ -401,19 +398,27 @@ class boss_xt002 : public CreatureScript heart->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE); heart->RemoveAurasDueToSpell(SPELL_EXPOSED_HEART); - if (!HardMode) + if (!_hardMode) { - if (!transferHealth) - transferHealth = (heart->GetMaxHealth() - heart->GetHealth()); + if (!_transferHealth) + _transferHealth = (heart->GetMaxHealth() - heart->GetHealth()); - me->ModifyHealth(-((int32)transferHealth)); + me->ModifyHealth(-((int32)_transferHealth)); } } + + private: + // Achievement related + bool _healthRecovered; // Did a scrapbot recover XT-002's health during the encounter? + bool _hardMode; // Are we in hard mode? Or: was the heart killed during phase 2? + bool _gravityBombCasualty; // Did someone die because of Gravity Bomb damage? + + uint8 _phase; + uint8 _heartExposed; + uint32 _transferHealth; }; }; -typedef boss_xt002::boss_xt002_AI XT002AI; - /*------------------------------------------------------- * * XT-002 HEART @@ -421,41 +426,41 @@ typedef boss_xt002::boss_xt002_AI XT002AI; *///---------------------------------------------------- class mob_xt002_heart : public CreatureScript { -public: - mob_xt002_heart() : CreatureScript("mob_xt002_heart") { } - - CreatureAI* GetAI(Creature* pCreature) const - { - return new mob_xt002_heartAI(pCreature); - } + public: + mob_xt002_heart() : CreatureScript("mob_xt002_heart") { } - struct mob_xt002_heartAI : public ScriptedAI - { - mob_xt002_heartAI(Creature* pCreature) : ScriptedAI(pCreature) + CreatureAI* GetAI(Creature* pCreature) const { - m_pInstance = pCreature->GetInstanceScript(); - me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_MOVE | UNIT_FLAG_STUNNED | UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE); - me->SetReactState(REACT_PASSIVE); + return new mob_xt002_heartAI(pCreature); } - InstanceScript* m_pInstance; - uint32 _damageTaken; - - void DamageTaken(Unit* /*pDone*/, uint32 &damage) + struct mob_xt002_heartAI : public ScriptedAI { - Creature* XT002 = me->GetCreature(*me, m_pInstance->GetData64(BOSS_XT002)); - if (!XT002 || !XT002->AI()) - return; + mob_xt002_heartAI(Creature* pCreature) : ScriptedAI(pCreature) + { + _instance = pCreature->GetInstanceScript(); + me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_MOVE | UNIT_FLAG_STUNNED | UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE); + me->SetReactState(REACT_PASSIVE); + } - if (damage >= me->GetHealth()) + void DamageTaken(Unit* /*pDone*/, uint32 &damage) { - XT002->AI()->SetData(DATA_TRANSFERED_HEALTH, me->GetMaxHealth()); - XT002->AI()->DoAction(ACTION_ENTER_HARD_MODE); - damage = 0; + Creature* xt002 = me->GetCreature(*me, _instance->GetData64(BOSS_XT002)); + if (!xt002 || !xt002->AI()) + return; + + if (damage >= me->GetHealth()) + { + xt002->AI()->SetData(DATA_TRANSFERED_HEALTH, me->GetMaxHealth()); + xt002->AI()->DoAction(ACTION_ENTER_HARD_MODE); + damage = 0; + } } - } - }; + private: + InstanceScript* _instance; + uint32 _damageTaken; + }; }; /*------------------------------------------------------- @@ -477,35 +482,41 @@ class mob_scrapbot : public CreatureScript { mob_scrapbotAI(Creature* pCreature) : ScriptedAI(pCreature) { - Instance = me->GetInstanceScript(); + _instance = me->GetInstanceScript(); } - InstanceScript* Instance; - uint32 RangeCheckTimer; - void Reset() { me->SetReactState(REACT_PASSIVE); - RangeCheckTimer = 500; + _rangeCheckTimer = 500; - if (Creature* pXT002 = me->GetCreature(*me, Instance->GetData64(BOSS_XT002))) + if (Creature* pXT002 = me->GetCreature(*me, _instance->GetData64(BOSS_XT002))) me->GetMotionMaster()->MoveFollow(pXT002, 0.0f, 0.0f); } void UpdateAI(const uint32 diff) { - if (RangeCheckTimer <= diff) + if (_rangeCheckTimer <= diff) { - if (Creature* pXT002 = me->GetCreature(*me, Instance->GetData64(BOSS_XT002))) + if (Creature* xt002 = me->GetCreature(*me, _instance->GetData64(BOSS_XT002))) { - if (me->IsWithinMeleeRange(pXT002)) - DoCast(pXT002, SPELL_SCRAPBOT_RIDE_VEHICLE); + if (me->IsWithinMeleeRange(xt002)) + { + DoCast(xt002, SPELL_SCRAPBOT_RIDE_VEHICLE); + // Unapply vehicle aura again + xt002->RemoveAurasDueToSpell(SPELL_SCRAPBOT_RIDE_VEHICLE); + me->DespawnOrUnsummon(); + } } } else - RangeCheckTimer -= diff; + _rangeCheckTimer -= diff; } + + private: + InstanceScript* _instance; + uint32 _rangeCheckTimer; }; }; @@ -516,76 +527,76 @@ class mob_scrapbot : public CreatureScript *///---------------------------------------------------- class mob_pummeller : public CreatureScript { -public: - mob_pummeller() : CreatureScript("mob_pummeller") { } - - CreatureAI* GetAI(Creature* pCreature) const - { - return new mob_pummellerAI(pCreature); - } + public: + mob_pummeller() : CreatureScript("mob_pummeller") { } - struct mob_pummellerAI : public ScriptedAI - { - mob_pummellerAI(Creature* pCreature) : ScriptedAI(pCreature) + CreatureAI* GetAI(Creature* pCreature) const { - Instance = pCreature->GetInstanceScript(); + return new mob_pummellerAI(pCreature); } - InstanceScript* Instance; - uint32 uiArcingSmashTimer; - uint32 uiTrampleTimer; - uint32 uiUppercutTimer; - - void Reset() + struct mob_pummellerAI : public ScriptedAI { - uiArcingSmashTimer = TIMER_ARCING_SMASH; - uiTrampleTimer = TIMER_TRAMPLE; - uiUppercutTimer = TIMER_UPPERCUT; - - if (Creature* pXT002 = me->GetCreature(*me, Instance->GetData64(BOSS_XT002))) + mob_pummellerAI(Creature* pCreature) : ScriptedAI(pCreature) { - Position pos; - pXT002->GetPosition(&pos); - me->GetMotionMaster()->MovePoint(0, pos); + _instance = pCreature->GetInstanceScript(); } - } - void UpdateAI(const uint32 diff) - { - if (!UpdateVictim()) - return; - - if (me->IsWithinMeleeRange(me->getVictim())) + void Reset() { - if (uiArcingSmashTimer <= diff) - { - DoCast(me->getVictim(), SPELL_ARCING_SMASH); - uiArcingSmashTimer = TIMER_ARCING_SMASH; - } - else - uiArcingSmashTimer -= diff; + _arcingSmashTimer = TIMER_ARCING_SMASH; + _trampleTimer = TIMER_TRAMPLE; + _uppercutTimer = TIMER_UPPERCUT; - if (uiTrampleTimer <= diff) + if (Creature* xt002 = me->GetCreature(*me, _instance->GetData64(BOSS_XT002))) { - DoCast(me->getVictim(), SPELL_TRAMPLE); - uiTrampleTimer = TIMER_TRAMPLE; + Position pos; + xt002->GetPosition(&pos); + me->GetMotionMaster()->MovePoint(0, pos); } - else - uiTrampleTimer -= diff; + } + + void UpdateAI(const uint32 diff) + { + if (!UpdateVictim()) + return; - if (uiUppercutTimer <= diff) + if (me->IsWithinMeleeRange(me->getVictim())) { - DoCast(me->getVictim(), SPELL_UPPERCUT); - uiUppercutTimer = TIMER_UPPERCUT; + if (_arcingSmashTimer <= diff) + { + DoCast(me->getVictim(), SPELL_ARCING_SMASH); + _arcingSmashTimer = TIMER_ARCING_SMASH; + } + else + _arcingSmashTimer -= diff; + + if (_trampleTimer <= diff) + { + DoCast(me->getVictim(), SPELL_TRAMPLE); + _trampleTimer = TIMER_TRAMPLE; + } + else + _trampleTimer -= diff; + + if (_uppercutTimer <= diff) + { + DoCast(me->getVictim(), SPELL_UPPERCUT); + _uppercutTimer = TIMER_UPPERCUT; + } + else + _uppercutTimer -= diff; } - else - uiUppercutTimer -= diff; - } - DoMeleeAttackIfReady(); - } - }; + DoMeleeAttackIfReady(); + } + private: + InstanceScript* _instance; + uint32 _arcingSmashTimer; + uint32 _trampleTimer; + uint32 _uppercutTimer; + }; }; /*------------------------------------------------------- @@ -666,10 +677,10 @@ class mob_boombot : public CreatureScript damage = 0; - // Visual only seems to work if the instant kill event is delayed + // Visual only seems to work if the instant kill event is delayed or the spell itself is delayed // Casting done from player and caster source has the same targetinfo flags, // so that can't be the issue - // See InstantKillEvent class + // See BoomEvent class // Schedule 1s delayed me->m_Events.AddEvent(new BoomEvent(me), me->m_Events.CalculateTime(1*IN_MILLISECONDS)); } @@ -697,47 +708,45 @@ class mob_boombot : public CreatureScript *///---------------------------------------------------- class mob_life_spark : public CreatureScript { -public: - mob_life_spark() : CreatureScript("mob_life_spark") { } - - CreatureAI* GetAI(Creature* pCreature) const - { - return new mob_life_sparkAI(pCreature); - } + public: + mob_life_spark() : CreatureScript("mob_life_spark") { } - struct mob_life_sparkAI : public ScriptedAI - { - mob_life_sparkAI(Creature* pCreature) : ScriptedAI(pCreature) + CreatureAI* GetAI(Creature* pCreature) const { - m_pInstance = pCreature->GetInstanceScript(); + return new mob_life_sparkAI(pCreature); } - InstanceScript* m_pInstance; - uint32 uiShockTimer; - - void Reset() + struct mob_life_sparkAI : public ScriptedAI { - DoCast(me, RAID_MODE(SPELL_STATIC_CHARGED_10, SPELL_STATIC_CHARGED_25)); - uiShockTimer = 0; // first one is immediate. - } + mob_life_sparkAI(Creature* pCreature) : ScriptedAI(pCreature) + { + } - void UpdateAI(const uint32 diff) - { - if (!UpdateVictim()) - return; + void Reset() + { + DoCast(me, RAID_MODE(SPELL_STATIC_CHARGED_10, SPELL_STATIC_CHARGED_25)); + _shockTimer = 0; // first one is immediate. + } - if (uiShockTimer <= diff) + void UpdateAI(const uint32 diff) { - if (me->IsWithinMeleeRange(me->getVictim())) + if (!UpdateVictim()) + return; + + if (_shockTimer <= diff) { - DoCast(me->getVictim(), SPELL_SHOCK); - uiShockTimer = TIMER_SHOCK; + if (me->IsWithinMeleeRange(me->getVictim())) + { + DoCast(me->getVictim(), SPELL_SHOCK); + _shockTimer = TIMER_SHOCK; + } } + else _shockTimer -= diff; } - else uiShockTimer -= diff; - } - }; + private: + uint32 _shockTimer; + }; }; class spell_xt002_searing_light_spawn_life_spark : public SpellScriptLoader @@ -811,8 +820,8 @@ class spell_xt002_gravity_bomb_aura : public SpellScriptLoader return; if (aurEff->GetAmount() >= int32(owner->GetHealth())) - if (XT002AI* xt002AI = CAST_AI(XT002AI, xt002->GetAI())) - xt002AI->GravityBombCasualty = true; + if (xt002->GetAI()) + xt002->GetAI()->SetData(DATA_GRAVITY_BOMB_CASUALTY, 1); } void Register() @@ -844,8 +853,8 @@ class spell_xt002_gravity_bomb_damage : public SpellScriptLoader return; if (GetHitDamage() >= int32(GetHitUnit()->GetHealth())) - if (XT002AI* xt002AI = CAST_AI(XT002AI, GetCaster()->GetAI())) - xt002AI->GravityBombCasualty = true; + if (caster->GetAI()) + caster->GetAI()->SetData(DATA_GRAVITY_BOMB_CASUALTY, 1); } void Register() @@ -1008,12 +1017,12 @@ class spell_xt002_stand : public SpellScriptLoader void HandleScript(SpellEffIndex /*eff*/) { - Unit* caster = GetCaster(); - if (!caster) + Unit* target = GetTargetUnit(); + if (!target) return; - caster->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_UNK_0 | UNIT_FLAG_NOT_SELECTABLE); - caster->SetByteValue(UNIT_FIELD_BYTES_1, 0, UNIT_STAND_STATE_STAND); + target->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_UNK_0 | UNIT_FLAG_NOT_SELECTABLE); + target->SetByteValue(UNIT_FIELD_BYTES_1, 0, UNIT_STAND_STATE_STAND); } void Register() @@ -1035,13 +1044,10 @@ class achievement_nerf_engineering : public AchievementCriteriaScript bool OnCheck(Player* /*source*/, Unit* target) { - if (!target) + if (!target || target->GetAI()) return false; - - if (XT002AI* xt002AI = CAST_AI(XT002AI, target->GetAI())) - return !xt002AI->HealthRecovered; - - return false; + + return !(target->GetAI()->GetData(DATA_HEALTH_RECOVERED)); } }; @@ -1052,13 +1058,10 @@ class achievement_heartbreaker : public AchievementCriteriaScript bool OnCheck(Player* /*source*/, Unit* target) { - if (!target) + if (!target || target->GetAI()) return false; - if (XT002AI* xt002AI = CAST_AI(XT002AI, target->GetAI())) - return xt002AI->HardMode; - - return false; + return target->GetAI()->GetData(DATA_HARD_MODE); } }; @@ -1069,13 +1072,10 @@ class achievement_nerf_gravity_bombs : public AchievementCriteriaScript bool OnCheck(Player* source, Unit* target) { - if (!target) + if (!target || target->GetAI()) return false; - if (XT002AI* xt002AI = CAST_AI(XT002AI, target->GetAI())) - return !xt002AI->GravityBombCasualty; - - return false; + return !(target->GetAI()->GetData(DATA_GRAVITY_BOMB_CASUALTY)); } }; |