Merge pull request #8725 from krofna/krefixes

Script/AQ: Rewrite Skeram
This commit is contained in:
blub
2013-01-07 14:03:28 -08:00
3 changed files with 184 additions and 241 deletions

View File

@@ -0,0 +1,5 @@
DELETE FROM `spell_target_position` WHERE id IN (4801,8195,20449);
INSERT INTO `spell_target_position` VALUES
(4801,531,-8306.68,2060.84,133.062,0),
(8195,531,-8344.97,2081.36,125.649,0),
(20449,531,-8330.63,2123.14,133.062,0);

View File

@@ -16,287 +16,225 @@
* 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
};
uint32 const BlinkSpells[3] = { 4801, 8195, 20449 };
class boss_skeram : public CreatureScript
{
public:
boss_skeram() : CreatureScript("boss_skeram") { }
public:
boss_skeram() : CreatureScript("boss_skeram") { }
struct boss_skeramAI : public BossAI
{
boss_skeramAI(Creature* creature) : BossAI(creature, DATA_SKERAM) { }
void Reset()
{
_flag = 0;
_hpct = 75.0f;
me->SetVisible(true);
}
void KilledUnit(Unit* /*victim*/)
{
Talk(SAY_SLAY);
}
void EnterEvadeMode()
{
ScriptedAI::EnterEvadeMode();
if (me->isSummon())
((TempSummon*)me)->UnSummon();
}
void JustSummoned(Creature* creature)
{
// Shift the boss and images (Get it? *Shift*?)
uint8 Rand;
if (_flag != 0)
{
while (_flag & (1 << Rand))
Rand = urand(0, 2);
DoCast(me, BlinkSpells[Rand]);
_flag |= (1 << Rand);
_flag |= (1 << 7);
}
while (_flag & (1 << Rand))
Rand = urand(0, 2);
creature->CastSpell(creature, BlinkSpells[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));
}
void JustDied(Unit* /*killer*/)
{
if (!me->isSummon())
Talk(SAY_DEATH);
else
me->RemoveCorpse();
}
void EnterCombat(Unit* /*who*/)
{
_EnterCombat();
events.Reset();
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, 2000);
Talk(SAY_AGGRO);
}
void UpdateAI(uint32 const diff)
{
if (!UpdateVictim())
return;
events.Update(diff);
while (uint32 eventId = events.ExecuteEvent())
{
switch (eventId)
{
case EVENT_ARCANE_EXPLOSION:
DoCastAOE(SPELL_ARCANE_EXPLOSION, true);
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, 2000);
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, 2000);
DoMeleeAttackIfReady();
}
}
private:
float _hpct;
uint8 _flag;
};
CreatureAI* GetAI(Creature* creature) const
{
return new boss_skeramAI (creature);
return new boss_skeramAI(creature);
}
};
struct boss_skeramAI : public ScriptedAI
{
boss_skeramAI(Creature* creature) : ScriptedAI(creature)
class PlayerOrPetCheck
{
public:
bool operator()(WorldObject* object) const
{
IsImage = false;
if (object->GetTypeId() != TYPEID_PLAYER)
if (!object->ToCreature()->isPet())
return true;
return false;
}
};
uint32 ArcaneExplosion_Timer;
uint32 EarthShock_Timer;
uint32 FullFillment_Timer;
uint32 Blink_Timer;
uint32 Invisible_Timer;
class spell_skeram_arcane_explosion : public SpellScriptLoader
{
public:
spell_skeram_arcane_explosion() : SpellScriptLoader("spell_skeram_arcane_explosion") { }
bool Images75;
bool Images50;
bool Images25;
bool IsImage;
bool Invisible;
void Reset()
class spell_skeram_arcane_explosion_SpellScript : public SpellScript
{
ArcaneExplosion_Timer = urand(6000, 12000);
EarthShock_Timer = 2000;
FullFillment_Timer = 15000;
Blink_Timer = urand(8000, 20000);
Invisible_Timer = 500;
PrepareSpellScript(spell_skeram_arcane_explosion_SpellScript);
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);
}
void EnterCombat(Unit* /*who*/)
{
if (IsImage || Images75)
return;
Talk(SAY_AGGRO);
}
void UpdateAI(const uint32 diff)
{
//Return since we have no target
if (!UpdateVictim())
return;
//ArcaneExplosion_Timer
if (ArcaneExplosion_Timer <= diff)
void FilterTargets(std::list<WorldObject*>& targets)
{
DoCast(me->getVictim(), SPELL_ARCANE_EXPLOSION);
ArcaneExplosion_Timer = urand(8000, 18000);
} else ArcaneExplosion_Timer -= diff;
//If we are within range melee the target
if (me->IsWithinMeleeRange(me->getVictim()))
{
//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
{
//EarthShock_Timer
if (EarthShock_Timer <= diff)
{
DoCast(me->getVictim(), SPELL_EARTH_SHOCK);
EarthShock_Timer = 1000;
} else EarthShock_Timer -= diff;
targets.remove_if(PlayerOrPetCheck());
}
//Blink_Timer
if (Blink_Timer <= diff)
void Register()
{
//DoCast(me, SPELL_BLINK);
switch (urand(0, 2))
{
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;
}
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;
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_skeram_arcane_explosion_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
}
};
DoMeleeAttackIfReady();
}
void DoSplit(int atPercent /* 75 50 25 */)
SpellScript* GetSpellScript() const
{
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))
{
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;
}
for (uint16 i = 0; i < 41; ++i)
{
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;
}
}
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();
switch (atPercent)
{
case 75: Images75 = true; break;
case 50: Images50 = true; break;
case 25: Images25 = true; break;
}
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)
{
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;
}
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;
return new spell_skeram_arcane_explosion_SpellScript();
}
};
};
void AddSC_boss_skeram()
{
new boss_skeram();
new spell_skeram_arcane_explosion();
}

View File

@@ -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);
}
}
}