diff options
author | Warpten <vertozor@gmail.com> | 2015-05-15 15:48:35 +0200 |
---|---|---|
committer | Warpten <vertozor@gmail.com> | 2015-05-15 15:49:07 +0200 |
commit | 1447875cac0fefd58ae3ad27e6b3fa2134a714c0 (patch) | |
tree | ed0c9adf1f9e34b9094c8478b56d2b926bfdc4ac | |
parent | 18e4ab6911468b829b0fc768e532a770263c3717 (diff) |
Scripts/RubySanctum: Updates to Halion.
* Fixed Living Embers not spawning.
* Meteor Strike is now randomized.
-rw-r--r-- | sql/updates/world/2015_05_15_00_world.sql | 15 | ||||
-rw-r--r-- | src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/boss_halion.cpp | 191 |
2 files changed, 164 insertions, 42 deletions
diff --git a/sql/updates/world/2015_05_15_00_world.sql b/sql/updates/world/2015_05_15_00_world.sql new file mode 100644 index 00000000000..3c96f23c970 --- /dev/null +++ b/sql/updates/world/2015_05_15_00_world.sql @@ -0,0 +1,15 @@ +UPDATE `creature_template` SET `ScriptName`="npc_meteor_strike_flame" WHERE `entry`=40055; + +DELETE FROM `spell_script_names` WHERE `spell_id`=75880 OR `ScriptName`="spell_halion_spawn_living_embers"; +INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES +(75880, "spell_halion_spawn_living_embers"); + +DELETE FROM `spelleffect_dbc` WHERE `EffectSpellId` IN (75880, 75881); +SET @MaxEffectEntry := (SELECT MAX(Id) + 1 FROM `spelleffect_dbc`); +INSERT INTO `spelleffect_dbc` (`Id`, `EffectSpellId`, `EffectIndex`, `Effect`, `EffectImplicitTargetA`, `EffectImplicitTargetB`, `EffectRadiusIndex`, `EffectRadiusIndexMax`, `EffectMiscValue`, `EffectMiscValueB`) VALUES +(@MaxEffectEntry + 0, 75880, 0, 77, 22, 7, 12, 12, 0, 0), +(@MaxEffectEntry + 1, 75881, 0, 28, 18, 0, 12, 12, 40055, 64); + +DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId`=13 AND `SourceEntry`=75880; +INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `Comment`) VALUES +(13, 1, 75880, 31, 0, 3, 40055, "Spawn Living Embers can only target Meteor Strike (Flame)"); diff --git a/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/boss_halion.cpp b/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/boss_halion.cpp index f1c4c22527b..840de70c22a 100644 --- a/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/boss_halion.cpp +++ b/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/boss_halion.cpp @@ -25,14 +25,6 @@ #include "ruby_sanctum.h" #include "Player.h" -/* ScriptData -SDName: ruby_sanctum -SDAuthors: Kaelima, Warpten -SD%Complete: 90% -SDComment: Based on Kaelima's initial work (half of it). Corporeality handling is a pure guess, we lack info. -SDCategory: Chamber of Aspects -EndScriptData */ - enum Texts { // Shared @@ -86,6 +78,8 @@ enum Spells // Living Inferno SPELL_BLAZING_AURA = 75885, + SPELL_SPAWN_LIVING_EMBERS = 75880, + SPELL_SUMMON_LIVING_EMBER = 75881, // Halion Controller SPELL_COSMETIC_FIRE_PILLAR = 76006, @@ -142,7 +136,7 @@ enum Events EVENT_CHECK_CORPOREALITY = 14, EVENT_SHADOW_PULSARS_SHOOT = 15, EVENT_TRIGGER_BERSERK = 16, - EVENT_TWILIGHT_MENDING = 17 + EVENT_TWILIGHT_MENDING = 17, }; enum Actions @@ -155,7 +149,13 @@ enum Actions ACTION_MONITOR_CORPOREALITY = 3, // Orb Carrier - ACTION_SHOOT = 4 + ACTION_SHOOT = 4, + + // Living Inferno + ACTION_SUMMON_LIVING_EMBERS = 5, + + // Meteor Flame + ACTION_SUMMON_FLAME = 6 }; enum Phases @@ -173,7 +173,8 @@ enum Misc DATA_MATERIAL_DAMAGE_TAKEN = 2, DATA_STACKS_DISPELLED = 3, DATA_FIGHT_PHASE = 4, - DATA_EVADE_METHOD = 5 + DATA_EVADE_METHOD = 5, + DATA_SPAWNED_FLAMES = 6, }; enum OrbCarrierSeats @@ -702,7 +703,7 @@ class npc_halion_controller : public CreatureScript // The IsInCombat() check is needed because that check should be false when Halion is // not engaged, while it would return true without as UpdateVictim() checks for // combat state. - if (!(_events.IsInPhase(PHASE_INTRO)) && me->IsInCombat() && !UpdateVictim()) + if (!_events.IsInPhase(PHASE_INTRO) && me->IsInCombat() && !UpdateVictim()) { EnterEvadeMode(); return; @@ -893,8 +894,6 @@ class npc_halion_controller : public CreatureScript } }; -typedef npc_halion_controller::npc_halion_controllerAI controllerAI; - class npc_orb_carrier : public CreatureScript { public: @@ -996,7 +995,7 @@ class npc_meteor_strike_initial : public CreatureScript if (!owner) return; - // Let Halion Controller count as summoner + // Let Controller count as summoner if (Creature* controller = ObjectAccessor::GetCreature(*me, _instance->GetGuidData(DATA_HALION_CONTROLLER))) controller->AI()->JustSummoned(me); @@ -1006,11 +1005,13 @@ class npc_meteor_strike_initial : public CreatureScript if (HalionAI* halionAI = CAST_AI(HalionAI, owner->AI())) { Position const* ownerPos = halionAI->GetMeteorStrikePosition(); + // Adjust randomness between 0 and pi. + float randomAdjustment = frand(static_cast<float>(M_PI / 14), static_cast<float>(13 * M_PI / 14)); float angle[4]; angle[0] = me->GetAngle(ownerPos); - angle[1] = me->GetAngle(ownerPos) - static_cast<float>(M_PI/2); - angle[2] = me->GetAngle(ownerPos) - static_cast<float>(-M_PI/2); - angle[3] = me->GetAngle(ownerPos) - static_cast<float>(M_PI); + angle[1] = angle[0] - randomAdjustment; + angle[2] = angle[0] + randomAdjustment; + angle[3] = angle[0] - static_cast<float>(M_PI); _meteorList.clear(); for (uint8 i = 0; i < 4; i++) @@ -1019,7 +1020,10 @@ class npc_meteor_strike_initial : public CreatureScript me->SetOrientation(angle[i]); Position newPos = me->GetNearPosition(10.0f, 0.0f); // Exact distance if (Creature* meteor = me->SummonCreature(NPC_METEOR_STRIKE_NORTH + i, newPos, TEMPSUMMON_TIMED_DESPAWN, 30000)) + { + meteor->SetOrientation(angle[i]); _meteorList.push_back(meteor); + } } } } @@ -1045,11 +1049,8 @@ class npc_meteor_strike : public CreatureScript struct npc_meteor_strikeAI : public ScriptedAI { npc_meteor_strikeAI(Creature* creature) : ScriptedAI(creature), - _instance(creature->GetInstanceScript()) + _instance(creature->GetInstanceScript()), _spawnCount(0) { - _range = 5.0f; - _spawnCount = 0; - SetCombatMovement(false); } @@ -1063,41 +1064,48 @@ class npc_meteor_strike : public CreatureScript } } - void IsSummonedBy(Unit* /*summoner*/) override + void IsSummonedBy(Unit* summoner) override { // Let Halion Controller count as summoner. if (Creature* controller = ObjectAccessor::GetCreature(*me, _instance->GetGuidData(DATA_HALION_CONTROLLER))) controller->AI()->JustSummoned(me); } - void UpdateAI(uint32 diff) override + void SetData(uint32 dataType, uint32 dataCount) override { - if (_spawnCount > 5) - return; + if (dataType == DATA_SPAWNED_FLAMES) + _spawnCount += dataCount; + } - _events.Update(diff); + uint32 GetData(uint32 dataType) override + { + if (dataType == DATA_SPAWNED_FLAMES) + return _spawnCount; + return 0; + } + void UpdateAI(uint32 diff) override + { + _events.Update(diff); if (_events.ExecuteEvent() == EVENT_SPAWN_METEOR_FLAME) { - Position pos = me->GetNearPosition( _range, 0.0f); - + Position pos = me->GetNearPosition(5.0f, 0.0f); if (Creature* flame = me->SummonCreature(NPC_METEOR_STRIKE_FLAME, pos, TEMPSUMMON_TIMED_DESPAWN, 25000)) { if (Creature* controller = ObjectAccessor::GetCreature(*me, _instance->GetGuidData(DATA_HALION_CONTROLLER))) controller->AI()->JustSummoned(flame); - flame->CastSpell(flame, SPELL_METEOR_STRIKE_FIRE_AURA_2, true); - ++_spawnCount; + flame->SetOrientation(me->GetOrientation()); + + flame->AI()->SetGUID(GetGUID()); + flame->AI()->DoAction(ACTION_SUMMON_FLAME); } - _range += 5.0f; - _events.ScheduleEvent(EVENT_SPAWN_METEOR_FLAME, 800); } } private: InstanceScript* _instance; EventMap _events; - float _range; uint8 _spawnCount; }; @@ -1107,6 +1115,70 @@ class npc_meteor_strike : public CreatureScript } }; +class npc_meteor_strike_flame : public CreatureScript +{ + public: + npc_meteor_strike_flame() : CreatureScript("npc_meteor_strike_flame") { } + + struct npc_meteor_strike_flameAI : public ScriptedAI + { + npc_meteor_strikeAI(Creature* creature) : ScriptedAI(creature), + _instance(creature->GetInstanceScript()) + { + SetCombatMovement(false); + } + + void SetGUID(ObjectGuid guid, int32 id /* = 0 */) + { + _rootOwnerGuid = guid; + } + + void DoAction(int32 action) override + { + if (action != ACTION_SUMMON_FLAME || _rootOwnerGuid.IsEmpty()) + return; + + me->CastSpell(me, SPELL_METEOR_STRIKE_FIRE_AURA_2, true); + + Creature* meteorStrike = ObjectAccessor::GetCreature(*me, _rootOwnerGuid); + if (!meteorStrike || meteorStrike->AI()->GetData(DATA_SPAWNED_FLAMES) > 5) + return; + + me->SetOrientation(me->GetOrientation() + frand(static_cast<float>(-M_PI / 16), static_cast<float>(M_PI / 16))); + Position pos = me->GetNearPosition(5.0f, 0.0f); + + if (Creature* flame = me->SummonCreature(NPC_METEOR_STRIKE_FLAME, pos, TEMPSUMMON_TIMED_DESPAWN, 25000)) + { + if (Creature* controller = ObjectAccessor::GetCreature(*me, _instance->GetGuidData(DATA_HALION_CONTROLLER))) + controller->AI()->JustSummoned(flame); + + flame->AI()->SetGUID(_rootOwnerGuid); + meteorStrike->AI()->SetData(DATA_SPAWNED_FLAMES, 1); + } + } + + void IsSummonedBy(Unit* /*summoner*/) override + { + // Let Halion Controller count as summoner. + if (Creature* controller = ObjectAccessor::GetCreature(*me, _instance->GetGuidData(DATA_HALION_CONTROLLER))) + controller->AI()->JustSummoned(me); + } + + void UpdateAI(uint32 diff) override { } + void EnterEvadeMode() override { } + + private: + InstanceScript* _instance; + EventMap _events; + ObjectGuid _rootOwnerGuid = ObjectGuid::Empty; + }; + + CreatureAI* GetAI(Creature* creature) const override + { + return GetRubySanctumAI<npc_meteor_strike_flameAI>(creature); + } +}; + class npc_combustion_consumption : public CreatureScript { public: @@ -1119,26 +1191,23 @@ class npc_combustion_consumption : public CreatureScript { SetCombatMovement(false); - switch (me->GetEntry()) + switch (creature->GetEntry()) { case NPC_COMBUSTION: _explosionSpell = SPELL_FIERY_COMBUSTION_EXPLOSION; _damageSpell = SPELL_COMBUSTION_DAMAGE_AURA; - me->SetPhaseMask(0x01, true); + creature->SetPhaseMask(IsHeroic() ? 0x21 : 0x01, true); break; case NPC_CONSUMPTION: _explosionSpell = SPELL_SOUL_CONSUMPTION_EXPLOSION; _damageSpell = SPELL_CONSUMPTION_DAMAGE_AURA; - me->SetPhaseMask(0x20, true); + creature->SetPhaseMask(IsHeroic() ? 0x21 : 0x20, true); break; default: // Should never happen _explosionSpell = 0; _damageSpell = 0; break; } - - if (IsHeroic()) - me->SetPhaseMask(0x01 | 0x20, true); } void IsSummonedBy(Unit* summoner) override @@ -1160,7 +1229,7 @@ class npc_combustion_consumption : public CreatureScript me->CastCustomSpell(SPELL_SCALE_AURA, SPELLVALUE_AURA_STACK, stackAmount, me); DoCast(me, _damageSpell); - int32 damage = 1200 + (stackAmount * 1290); // Needs more researches. + int32 damage = 1200 + (stackAmount * 1290); // Needs more research. summoner->CastCustomSpell(_explosionSpell, SPELLVALUE_BASE_POINT0, damage, summoner); } @@ -1193,6 +1262,10 @@ class npc_living_inferno : public CreatureScript me->SetInCombatWithZone(); me->CastSpell(me, SPELL_BLAZING_AURA, true); + // SMSG_SPELL_GO for the living ember stuff isn't even sent to the client - Blizzard on drugs. + if (me->GetMap()->GetDifficultyID() == DIFFICULTY_25_HC) + me->CastSpell(me, SPELL_SPAWN_LIVING_EMBERS, true); + if (InstanceScript* instance = me->GetInstanceScript()) if (Creature* controller = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_HALION_CONTROLLER))) controller->AI()->JustSummoned(me); @@ -1210,7 +1283,6 @@ class npc_living_inferno : public CreatureScript } }; -//! Need sniff data class npc_living_ember : public CreatureScript { public: @@ -1738,12 +1810,46 @@ class spell_halion_summon_exit_portals : public SpellScriptLoader } }; +class spell_halion_spawn_living_embers : public SpellScriptLoader +{ + public: + spell_halion_spawn_living_embers() : SpellScriptLoader("spell_halion_spawn_living_embers") { } + + class spell_halion_spawn_living_embers_SpellScript : public SpellScript + { + PrepareSpellScript(spell_halion_spawn_living_embers_SpellScript); + + void SelectMeteorFlames(std::list<WorldObject*>& unitList) + { + if (!unitList.empty()) + Trinity::Containers::RandomResizeList(unitList, 10); + } + + void HandleScript(SpellEffIndex /* effIndex */) + { + GetHitUnit()->CastSpell(GetHitUnit(), SPELL_SUMMON_LIVING_EMBER, true); + } + + void Register() override + { + OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_halion_spawn_living_embers_SpellScript::SelectMeteorFlames, EFFECT_0, TARGET_UNIT_SRC_AREA_ENTRY); + OnEffectHitTarget += SpellEffectFn(spell_halion_spawn_living_embers_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + } + }; + + SpellScript* GetSpellScript() const override + { + return new spell_halion_spawn_living_embers_SpellScript(); + } +}; + void AddSC_boss_halion() { new boss_halion(); new boss_twilight_halion(); new npc_halion_controller(); + new npc_meteor_strike_flame(); new npc_meteor_strike_initial(); new npc_meteor_strike(); new npc_combustion_consumption(); @@ -1765,4 +1871,5 @@ void AddSC_boss_halion() new spell_halion_twilight_phasing(); new spell_halion_twilight_cutter(); new spell_halion_clear_debuffs(); + new spell_halion_spawn_living_embers(); } |