diff options
-rw-r--r-- | sql/updates/world/2014_09_07_05_world_sai.sql (renamed from sql/updates/world/2014_09_07_04_world_sai.sql) | 0 | ||||
-rw-r--r-- | sql/updates/world/2014_09_07_06_world_sai.sql | 6 | ||||
-rw-r--r-- | src/server/scripts/EasternKingdoms/AlteracValley/boss_balinda.cpp | 215 |
3 files changed, 94 insertions, 127 deletions
diff --git a/sql/updates/world/2014_09_07_04_world_sai.sql b/sql/updates/world/2014_09_07_05_world_sai.sql index 104e9d3d015..104e9d3d015 100644 --- a/sql/updates/world/2014_09_07_04_world_sai.sql +++ b/sql/updates/world/2014_09_07_05_world_sai.sql diff --git a/sql/updates/world/2014_09_07_06_world_sai.sql b/sql/updates/world/2014_09_07_06_world_sai.sql new file mode 100644 index 00000000000..fded7b73948 --- /dev/null +++ b/sql/updates/world/2014_09_07_06_world_sai.sql @@ -0,0 +1,6 @@ +SET @ENTRY := 25040; -- Greater Water Elemental
+UPDATE `creature_template` SET `AIName` = 'SmartAI', `ScriptName` = '' WHERE `entry` = @ENTRY;
+DELETE FROM `smart_scripts` WHERE `entryorguid` = @ENTRY AND `source_type` = 0;
+INSERT INTO `smart_scripts` (`entryorguid`, `source_type`, `id`, `link`, `event_type`, `event_phase_mask`, `event_chance`, `event_flags`, `event_param1`, `event_param2`, `event_param3`, `event_param4`, `action_type`, `action_param1`, `action_param2`, `action_param3`, `action_param4`, `action_param5`, `action_param6`, `target_type`, `target_param1`, `target_param2`, `target_param3`, `target_x`, `target_y`, `target_z`, `target_o`, `comment`) VALUES
+(@ENTRY, 0, 1, 0, 0, 0, 100, 0, 3000, 3000, 5000, 5000, 11, 46983, 64, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 'Greater Water Elemental - In Combat - Cast Waterbolt');
+
diff --git a/src/server/scripts/EasternKingdoms/AlteracValley/boss_balinda.cpp b/src/server/scripts/EasternKingdoms/AlteracValley/boss_balinda.cpp index 8bc969e9020..4aaf364eea7 100644 --- a/src/server/scripts/EasternKingdoms/AlteracValley/boss_balinda.cpp +++ b/src/server/scripts/EasternKingdoms/AlteracValley/boss_balinda.cpp @@ -23,19 +23,16 @@ enum Spells SPELL_ARCANE_EXPLOSION = 46608, SPELL_CONE_OF_COLD = 38384, SPELL_FIREBALL = 46988, - SPELL_FROSTBOLT = 46987 + SPELL_FROSTBOLT = 46987, + SPELL_SUMMON_WATER_ELEMENTAL = 45067, + SPELL_ICEBLOCK = 46604 }; -enum Yells +enum Texts { - YELL_AGGRO = 0, - YELL_EVADE = 1, - YELL_SALVATION = 2, -}; - -enum Creatures -{ - NPC_WATER_ELEMENTAL = 25040 + SAY_AGGRO = 0, + SAY_EVADE = 1, + SAY_SALVATION = 2, }; enum Action @@ -43,64 +40,15 @@ enum Action ACTION_BUFF_YELL = -30001 // shared from Battleground }; -enum WaterElementalSpells -{ - SPELL_WATERBOLT = 46983 -}; - -class npc_water_elemental : public CreatureScript +enum Events { -public: - npc_water_elemental() : CreatureScript("npc_water_elemental") { } - - struct npc_water_elementalAI : public ScriptedAI - { - npc_water_elementalAI(Creature* creature) : ScriptedAI(creature) - { - waterBoltTimer = 3 * IN_MILLISECONDS; - resetTimer = 5 * IN_MILLISECONDS; - balindaGUID = 0; - } - - uint32 waterBoltTimer; - uint64 balindaGUID; - uint32 resetTimer; - - void Reset() override - { - waterBoltTimer = 3 * IN_MILLISECONDS; - resetTimer = 5 * IN_MILLISECONDS; - balindaGUID = 0; - } - - void UpdateAI(uint32 diff) override - { - if (!UpdateVictim()) - return; - - if (waterBoltTimer < diff) - { - DoCastVictim(SPELL_WATERBOLT); - waterBoltTimer = 5 * IN_MILLISECONDS; - } else waterBoltTimer -= diff; - - // check if creature is not outside of building - if (resetTimer < diff) - { - if (Creature* pBalinda = ObjectAccessor::GetCreature(*me, balindaGUID)) - if (me->GetDistance2d(pBalinda->GetHomePosition().GetPositionX(), pBalinda->GetHomePosition().GetPositionY()) > 50) - EnterEvadeMode(); - resetTimer = 5 * IN_MILLISECONDS; - } else resetTimer -= diff; - - DoMeleeAttackIfReady(); - } - }; - - CreatureAI* GetAI(Creature* creature) const override - { - return new npc_water_elementalAI(creature); - } + // Balinda + EVENT_ARCANE_EXPLOSION = 1, + EVENT_CONE_OF_COLD, + EVENT_FIREBOLT, + EVENT_FROSTBOLT, + EVENT_SUMMON_WATER_ELEMENTAL, + EVENT_CHECK_RESET, // Checks if Balinda or the Water Elemental are outside of building. }; class boss_balinda : public CreatureScript @@ -117,23 +65,10 @@ public: void Initialize() { - arcaneExplosionTimer = urand(5 * IN_MILLISECONDS, 15 * IN_MILLISECONDS); - coneOfColdTimer = 8 * IN_MILLISECONDS; - fireBoltTimer = 1 * IN_MILLISECONDS; - frostboltTimer = 4 * IN_MILLISECONDS; - resetTimer = 5 * IN_MILLISECONDS; - waterElementalTimer = 0; + WaterElementalGUID = 0; + HasCastIceblock = false; } - uint32 arcaneExplosionTimer; - uint32 coneOfColdTimer; - uint32 fireBoltTimer; - uint32 frostboltTimer; - uint32 resetTimer; - uint32 waterElementalTimer; - - SummonList summons; - void Reset() override { Initialize(); @@ -143,22 +78,28 @@ public: void EnterCombat(Unit* /*who*/) override { - Talk(YELL_AGGRO); - } - - void JustRespawned() override - { - Reset(); + Talk(SAY_AGGRO); + events.ScheduleEvent(EVENT_ARCANE_EXPLOSION, urand(5 * IN_MILLISECONDS, 15 * IN_MILLISECONDS)); + events.ScheduleEvent(EVENT_CONE_OF_COLD, 8 * IN_MILLISECONDS); + events.ScheduleEvent(EVENT_FIREBOLT, 1 * IN_MILLISECONDS); + events.ScheduleEvent(EVENT_FROSTBOLT, 4 * IN_MILLISECONDS); + events.ScheduleEvent(EVENT_SUMMON_WATER_ELEMENTAL, 3 * IN_MILLISECONDS); + events.ScheduleEvent(EVENT_CHECK_RESET, 5 * IN_MILLISECONDS); } void JustSummoned(Creature* summoned) override { - ENSURE_AI(npc_water_elemental::npc_water_elementalAI, summoned->AI())->balindaGUID = me->GetGUID(); summoned->AI()->AttackStart(SelectTarget(SELECT_TARGET_RANDOM, 0, 50, true)); summoned->setFaction(me->getFaction()); + WaterElementalGUID = summoned->GetGUID(); summons.Summon(summoned); } + void SummonedCreatureDespawn(Creature* summoned) override + { + summons.Despawn(summoned); + } + void JustDied(Unit* /*killer*/) override { summons.DespawnAll(); @@ -167,7 +108,16 @@ public: void DoAction(int32 actionId) override { if (actionId == ACTION_BUFF_YELL) - Talk(YELL_AGGRO); + Talk(SAY_AGGRO); + } + + void DamageTaken(Unit* /*attacker*/, uint32& damage) override + { + if (me->HealthBelowPctDamaged(40, damage) && !HasCastIceblock) + { + DoCast(SPELL_ICEBLOCK); + HasCastIceblock = true; + } } void UpdateAI(uint32 diff) override @@ -175,50 +125,62 @@ public: if (!UpdateVictim()) return; - if (waterElementalTimer < diff) - { - if (summons.empty()) - me->SummonCreature(NPC_WATER_ELEMENTAL, 0, 0, 0, 0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 45 * IN_MILLISECONDS); - waterElementalTimer = 50 * IN_MILLISECONDS; - } else waterElementalTimer -= diff; - - if (arcaneExplosionTimer < diff) - { - DoCastVictim(SPELL_ARCANE_EXPLOSION); - arcaneExplosionTimer = urand(5 * IN_MILLISECONDS, 15 * IN_MILLISECONDS); - } else arcaneExplosionTimer -= diff; - - if (coneOfColdTimer < diff) - { - DoCastVictim(SPELL_CONE_OF_COLD); - coneOfColdTimer = urand(10 * IN_MILLISECONDS, 20 * IN_MILLISECONDS); - } else coneOfColdTimer -= diff; - - if (fireBoltTimer < diff) - { - DoCastVictim(SPELL_FIREBALL); - fireBoltTimer = urand(5 * IN_MILLISECONDS, 9 * IN_MILLISECONDS); - } else fireBoltTimer -= diff; + events.Update(diff); - if (frostboltTimer < diff) - { - DoCastVictim(SPELL_FROSTBOLT); - frostboltTimer = urand(4 * IN_MILLISECONDS, 12 * IN_MILLISECONDS); - } else frostboltTimer -= diff; + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; - // check if creature is not outside of building - if (resetTimer < diff) + while (uint32 eventId = events.ExecuteEvent()) { - if (me->GetDistance2d(me->GetHomePosition().GetPositionX(), me->GetHomePosition().GetPositionY()) > 50) + switch (eventId) { - EnterEvadeMode(); - Talk(YELL_EVADE); + case EVENT_ARCANE_EXPLOSION: + DoCastVictim(SPELL_ARCANE_EXPLOSION); + events.ScheduleEvent(EVENT_ARCANE_EXPLOSION, urand(5 * IN_MILLISECONDS, 15 * IN_MILLISECONDS)); + break; + case EVENT_CONE_OF_COLD: + DoCastVictim(SPELL_CONE_OF_COLD); + events.ScheduleEvent(EVENT_CONE_OF_COLD, urand(10 * IN_MILLISECONDS, 20 * IN_MILLISECONDS)); + break; + case EVENT_FIREBOLT: + DoCastVictim(SPELL_FIREBALL); + events.ScheduleEvent(EVENT_FIREBOLT, urand(5 * IN_MILLISECONDS, 9 * IN_MILLISECONDS)); + break; + case EVENT_FROSTBOLT: + DoCastVictim(SPELL_FROSTBOLT); + events.ScheduleEvent(EVENT_FROSTBOLT, urand(4 * IN_MILLISECONDS, 12 * IN_MILLISECONDS)); + break; + case EVENT_SUMMON_WATER_ELEMENTAL: + if (summons.empty()) + DoCast(SPELL_SUMMON_WATER_ELEMENTAL); + events.ScheduleEvent(EVENT_SUMMON_WATER_ELEMENTAL, 50 * IN_MILLISECONDS); + break; + case EVENT_CHECK_RESET: + if (me->GetDistance2d(me->GetHomePosition().GetPositionX(), me->GetHomePosition().GetPositionY()) > 50) + { + EnterEvadeMode(); + Talk(SAY_EVADE); + } + if (Creature* elemental = ObjectAccessor::GetCreature(*me, WaterElementalGUID)) + if (elemental->GetDistance2d(me->GetHomePosition().GetPositionX(), me->GetHomePosition().GetPositionY()) > 50) + elemental->AI()->EnterEvadeMode(); + events.ScheduleEvent(EVENT_CHECK_RESET, 5 * IN_MILLISECONDS); + break; + default: + break; } - resetTimer = 5 * IN_MILLISECONDS; - } else resetTimer -= diff; + } DoMeleeAttackIfReady(); } + + private: + EventMap events; + SummonList summons; + + uint64 WaterElementalGUID; + + bool HasCastIceblock; }; CreatureAI* GetAI(Creature* creature) const override @@ -230,5 +192,4 @@ public: void AddSC_boss_balinda() { new boss_balinda; - new npc_water_elemental; } |