aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMislav Blažević <krofnica996@gmail.com>2012-12-20 14:30:52 +0100
committerMislav Blažević <krofnica996@gmail.com>2012-12-20 17:00:00 +0100
commitd38dfa82e02846b33b5e0690cf50b2ebe422bdc9 (patch)
tree145aa4466fe2b0a4047bc8bff348a40aad413e22 /src
parent04a3939a23ea7d8a50200eb461215e06d5365332 (diff)
Script/AQ: Rewrite Skeram
Add spell_target_position for Skeram Viscidus cosmetic fix Cosmetic fix Cosmetic fix .sql
Diffstat (limited to 'src')
-rw-r--r--src/server/scripts/Kalimdor/TempleOfAhnQiraj/boss_skeram.cpp369
-rw-r--r--src/server/scripts/Kalimdor/TempleOfAhnQiraj/boss_viscidus.cpp2
2 files changed, 138 insertions, 233 deletions
diff --git a/src/server/scripts/Kalimdor/TempleOfAhnQiraj/boss_skeram.cpp b/src/server/scripts/Kalimdor/TempleOfAhnQiraj/boss_skeram.cpp
index 99a304e3726..cc351c83324 100644
--- a/src/server/scripts/Kalimdor/TempleOfAhnQiraj/boss_skeram.cpp
+++ b/src/server/scripts/Kalimdor/TempleOfAhnQiraj/boss_skeram.cpp
@@ -16,284 +16,189 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-/* ScriptData
-SDName: Boss_Skeram
-SD%Complete: 75
-SDComment: Mind Control buggy.
-SDCategory: Temple of Ahn'Qiraj
-EndScriptData */
-
#include "ScriptMgr.h"
#include "ScriptedCreature.h"
#include "temple_of_ahnqiraj.h"
-#include "Group.h"
-#include "Player.h"
-enum Skeram
+enum Yells
{
SAY_AGGRO = 0,
SAY_SLAY = 1,
SAY_SPLIT = 2,
SAY_DEATH = 3,
+};
- SPELL_ARCANE_EXPLOSION = 25679,
+enum Spells
+{
+ SPELL_ARCANE_EXPLOSION = 26192,
SPELL_EARTH_SHOCK = 26194,
SPELL_TRUE_FULFILLMENT = 785,
- SPELL_BLINK = 28391
+ SPELL_INITIALIZE_IMAGE = 3730,
+ SPELL_SUMMON_IMAGES = 747
};
-class ov_mycoordinates
+enum Events
{
- public:
- float x, y, z, r;
- ov_mycoordinates(float cx, float cy, float cz, float cr)
- {
- x = cx; y = cy; z = cz; r = cr;
- }
+ EVENT_ARCANE_EXPLOSION = 0,
+ EVENT_FULLFILMENT = 1,
+ EVENT_BLINK = 2,
+ EVENT_EARTH_SHOCK = 3
};
-class boss_skeram : public CreatureScript
+uint32 const BlinkSpells[3] = { 4801, 8195, 20449 };
+Position const BossPositions[3] =
{
-public:
- boss_skeram() : CreatureScript("boss_skeram") { }
-
- CreatureAI* GetAI(Creature* creature) const
- {
- return new boss_skeramAI (creature);
- }
-
- struct boss_skeramAI : public ScriptedAI
- {
- boss_skeramAI(Creature* creature) : ScriptedAI(creature)
- {
- IsImage = false;
- }
-
- uint32 ArcaneExplosion_Timer;
- uint32 EarthShock_Timer;
- uint32 FullFillment_Timer;
- uint32 Blink_Timer;
- uint32 Invisible_Timer;
-
- bool Images75;
- bool Images50;
- bool Images25;
- bool IsImage;
- bool Invisible;
-
- void Reset()
- {
- ArcaneExplosion_Timer = urand(6000, 12000);
- EarthShock_Timer = 2000;
- FullFillment_Timer = 15000;
- Blink_Timer = urand(8000, 20000);
- Invisible_Timer = 500;
-
- Images75 = false;
- Images50 = false;
- Images25 = false;
- Invisible = false;
-
- me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
- me->SetVisible(true);
-
- if (IsImage)
- me->setDeathState(JUST_DIED);
- }
-
- void KilledUnit(Unit* /*victim*/)
- {
- Talk(SAY_SLAY);
- }
-
- void JustDied(Unit* /*killer*/)
- {
- if (!IsImage)
- Talk(SAY_DEATH);
- }
+ { -8306.68f, 2060.84f, 133.062f, 0.0f },
+ { -8330.63f, 2123.14f, 133.062f, 0.0f },
+ { -8344.97f, 2081.36f, 125.649f, 0.0f }
+};
- void EnterCombat(Unit* /*who*/)
- {
- if (IsImage || Images75)
- return;
- Talk(SAY_AGGRO);
- }
+class boss_skeram : public CreatureScript
+{
+ public:
+ boss_skeram() : CreatureScript("boss_skeram") { }
- void UpdateAI(const uint32 diff)
+ struct boss_skeramAI : public BossAI
{
- //Return since we have no target
- if (!UpdateVictim())
- return;
+ boss_skeramAI(Creature* creature) : BossAI(creature, DATA_SKERAM) { }
- //ArcaneExplosion_Timer
- if (ArcaneExplosion_Timer <= diff)
+ void Reset()
{
- DoCast(me->getVictim(), SPELL_ARCANE_EXPLOSION);
- ArcaneExplosion_Timer = urand(8000, 18000);
- } else ArcaneExplosion_Timer -= diff;
+ _flag = 0;
+ _hpct = 75.0f;
+ me->SetVisible(true);
+ }
- //If we are within range melee the target
- if (me->IsWithinMeleeRange(me->getVictim()))
+ void KilledUnit(Unit* /*victim*/)
{
- //Make sure our attack is ready and we arn't currently casting
- if (me->isAttackReady() && !me->IsNonMeleeSpellCasted(false))
- {
- me->AttackerStateUpdate(me->getVictim());
- me->resetAttackTimer();
- }
- }else
+ Talk(SAY_SLAY);
+ }
+
+ void EnterEvadeMode()
{
- //EarthShock_Timer
- if (EarthShock_Timer <= diff)
- {
- DoCast(me->getVictim(), SPELL_EARTH_SHOCK);
- EarthShock_Timer = 1000;
- } else EarthShock_Timer -= diff;
+ ScriptedAI::EnterEvadeMode();
+ if (me->isSummon())
+ ((TempSummon*)me)->UnSummon();
}
- //Blink_Timer
- if (Blink_Timer <= diff)
+ void JustSummoned(Creature* creature)
{
- //DoCast(me, SPELL_BLINK);
- switch (urand(0, 2))
+ // Shift the boss and images (Get it? *Shift*?)
+ uint8 Rand;
+ if (_flag != 0)
{
- case 0:
- me->SetPosition(-8340.782227f, 2083.814453f, 125.648788f, 0.0f);
- DoResetThreat();
- break;
- case 1:
- me->SetPosition(-8341.546875f, 2118.504639f, 133.058151f, 0.0f);
- DoResetThreat();
- break;
- case 2:
- me->SetPosition(-8318.822266f, 2058.231201f, 133.058151f, 0.0f);
- DoResetThreat();
- break;
+ while (_flag & (1 << Rand))
+ Rand = urand(0, 2);
+ me->SetPosition(BossPositions[Rand]);
+ _flag |= (1 << Rand);
+ _flag |= (1 << 7);
}
- DoStopAttack();
- Blink_Timer= urand(20000, 40000);
- } else Blink_Timer -= diff;
-
- int procent = (int) (me->GetHealthPct() + 0.5f);
-
- //Summoning 2 Images and teleporting to a random position on 75% health
- if ((!Images75 && !IsImage) && (procent <= 75 && procent > 70))
- DoSplit(75);
-
- //Summoning 2 Images and teleporting to a random position on 50% health
- if ((!Images50 && !IsImage) && (procent <= 50 && procent > 45))
- DoSplit(50);
-
- //Summoning 2 Images and teleporting to a random position on 25% health
- if ((!Images25 && !IsImage) && (procent <= 25 && procent > 20))
- DoSplit(25);
-
- //Invisible_Timer
- if (Invisible)
- {
- if (Invisible_Timer <= diff)
- {
- //Making Skeram visible after telporting
- me->SetVisible(true);
- me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
-
- Invisible_Timer = 2500;
- Invisible = false;
- } else Invisible_Timer -= diff;
+ while (_flag & (1 << Rand))
+ Rand = urand(0, 2);
+ creature->SetPosition(BossPositions[Rand]);
+ _flag |= (1 << Rand);
+
+ if (_flag & (1 << 7))
+ _flag = 0;
+
+ if (Unit* Target = SelectTarget(SELECT_TARGET_RANDOM))
+ creature->AI()->AttackStart(Target);
+
+ float ImageHealthPct;
+
+ if (me->GetHealthPct() < 25.0f)
+ ImageHealthPct = 0.50f;
+ else if (me->GetHealthPct() < 50.0f)
+ ImageHealthPct = 0.20f;
+ else
+ ImageHealthPct = 0.10f;
+
+ creature->SetMaxHealth(me->GetMaxHealth() * ImageHealthPct);
+ creature->SetHealth(creature->GetMaxHealth() * (me->GetHealthPct() / 100.0f));
}
- DoMeleeAttackIfReady();
- }
-
- void DoSplit(int atPercent /* 75 50 25 */)
- {
- Talk(SAY_SPLIT);
-
- ov_mycoordinates *place1 = new ov_mycoordinates(-8340.782227f, 2083.814453f, 125.648788f, 0);
- ov_mycoordinates *place2 = new ov_mycoordinates(-8341.546875f, 2118.504639f, 133.058151f, 0);
- ov_mycoordinates *place3 = new ov_mycoordinates(-8318.822266f, 2058.231201f, 133.058151f, 0);
-
- ov_mycoordinates *bossc=place1, *i1=place2, *i2=place3;
-
- switch (urand(0, 2))
+ void JustDied(Unit* /*killer*/)
{
- case 0:
- bossc=place1;
- i1=place2;
- i2=place3;
- break;
- case 1:
- bossc=place2;
- i1=place1;
- i2=place3;
- break;
- case 2:
- bossc=place3;
- i1=place1;
- i2=place2;
- break;
+ if (!me->isSummon())
+ Talk(SAY_DEATH);
+ else
+ me->RemoveCorpse();
}
- for (uint16 i = 0; i < 41; ++i)
+ void EnterCombat(Unit* /*who*/)
{
- if (Player* target = CAST_PLR(SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true)))
- {
- if (Group* pGrp = target->GetGroup())
- for (uint8 ico = 0; ico < TARGETICONCOUNT; ++ico)
- {
- //if (grp->m_targetIcons[ico] == me->GetGUID()) -- private member :(
- pGrp->SetTargetIcon(ico, 0, 0);
- }
-
- break;
- }
- }
+ _EnterCombat();
+ events.Reset();
- me->RemoveAllAuras();
- me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
- me->SetVisible(false);
- me->SetPosition(bossc->x, bossc->y, bossc->z, bossc->r);
- Invisible = true;
- DoResetThreat();
- DoStopAttack();
+ events.ScheduleEvent(EVENT_ARCANE_EXPLOSION, urand(6000, 12000));
+ events.ScheduleEvent(EVENT_FULLFILMENT, 15000);
+ events.ScheduleEvent(EVENT_BLINK, urand(30000, 45000));
+ events.ScheduleEvent(EVENT_EARTH_SHOCK, 1000);
- switch (atPercent)
- {
- case 75: Images75 = true; break;
- case 50: Images50 = true; break;
- case 25: Images25 = true; break;
+ Talk(SAY_AGGRO);
}
- Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0);
-
- Creature* Image1 = me->SummonCreature(15263, i1->x, i1->y, i1->z, i1->r, TEMPSUMMON_CORPSE_DESPAWN, 30000);
- if (Image1)
+ void UpdateAI(uint32 const diff)
{
- Image1->SetMaxHealth(me->GetMaxHealth() / 5);
- Image1->SetHealth(me->GetHealth() / 5);
- if (target)
- Image1->AI()->AttackStart(target);
- CAST_AI(boss_skeram::boss_skeramAI, Image1->AI())->IsImage = true;
- }
+ if (!UpdateVictim())
+ return;
- Creature* Image2 = me->SummonCreature(15263, i2->x, i2->y, i2->z, i2->r, TEMPSUMMON_CORPSE_DESPAWN, 30000);
- if (Image2)
- {
- Image2->SetMaxHealth(me->GetMaxHealth() / 5);
- Image2->SetHealth(me->GetHealth() / 5);
- if (target)
- Image2->AI()->AttackStart(target);
- CAST_AI(boss_skeram::boss_skeramAI, Image2->AI())->IsImage = true;
- }
- Invisible = true;
- delete place1;
- delete place2;
- delete place3;
- }
+ events.Update(diff);
+
+ while (uint32 eventId = events.ExecuteEvent())
+ {
+ switch (eventId)
+ {
+ case EVENT_ARCANE_EXPLOSION:
+ // TODO: For some weird reason boss does not cast this
+ DoCast(me, SPELL_ARCANE_EXPLOSION);
+ events.ScheduleEvent(EVENT_ARCANE_EXPLOSION, urand(8000, 18000));
+ break;
+ case EVENT_FULLFILMENT:
+ // TODO: For some weird reason boss does not cast this
+ // Spell actually works, tested in duel
+ DoCast(SelectTarget(SELECT_TARGET_RANDOM, 0, 0.0f, true), SPELL_TRUE_FULFILLMENT, true);
+ events.ScheduleEvent(EVENT_FULLFILMENT, urand(20000, 30000));
+ break;
+ case EVENT_BLINK:
+ DoCast(me, BlinkSpells[urand(0, 2)]);
+ DoResetThreat();
+ me->SetVisible(true);
+ events.ScheduleEvent(EVENT_BLINK, urand(10000, 30000));
+ break;
+ case EVENT_EARTH_SHOCK:
+ DoCastVictim(SPELL_EARTH_SHOCK);
+ events.ScheduleEvent(EVENT_EARTH_SHOCK, 1000);
+ break;
+ }
+ }
- };
+ if (!me->isSummon() && me->GetHealthPct() < _hpct)
+ {
+ DoCast(me, SPELL_SUMMON_IMAGES);
+ Talk(SAY_SPLIT);
+ _hpct -= 25.0f;
+ me->SetVisible(false);
+ events.RescheduleEvent(EVENT_BLINK, 2000);
+ }
+ if (me->IsWithinMeleeRange(me->getVictim()))
+ {
+ events.RescheduleEvent(EVENT_EARTH_SHOCK, 1000);
+ DoMeleeAttackIfReady();
+ }
+ }
+
+ private:
+ float _hpct;
+ uint8 _flag;
+ };
+
+ CreatureAI* GetAI(Creature* creature) const
+ {
+ return new boss_skeramAI(creature);
+ }
};
void AddSC_boss_skeram()
diff --git a/src/server/scripts/Kalimdor/TempleOfAhnQiraj/boss_viscidus.cpp b/src/server/scripts/Kalimdor/TempleOfAhnQiraj/boss_viscidus.cpp
index c97fd40929a..eecc5110512 100644
--- a/src/server/scripts/Kalimdor/TempleOfAhnQiraj/boss_viscidus.cpp
+++ b/src/server/scripts/Kalimdor/TempleOfAhnQiraj/boss_viscidus.cpp
@@ -279,7 +279,7 @@ class npc_glob_of_viscidus : public CreatureScript
else
{
Viscidus->SetHealth(Viscidus->GetHealth() - Viscidus->GetMaxHealth() / 20);
- Viscidus->GetAI()->DoCast(Viscidus, SPELL_VISCIDUS_SHRINKS);
+ Viscidus->CastSpell(Viscidus, SPELL_VISCIDUS_SHRINKS);
}
}
}