*Update sapphiron script (not finished yet).

--HG--
branch : trunk
This commit is contained in:
megamage
2009-05-08 18:39:04 -05:00
parent 80bec6788c
commit 5346498dea
4 changed files with 197 additions and 129 deletions
@@ -88,15 +88,14 @@ struct TRINITY_DLL_DECL boss_patchwerkAI : public ScriptedAI
//amount of HP within melee distance
uint32 MostHP = 0;
Unit* pMostHPTarget = NULL;
std::list<HostilReference*>::iterator i = m_creature->getThreatManager().getThreatList().begin();
for(; i != m_creature->getThreatManager().getThreatList().end();)
std::list<HostilReference*>::iterator i = me->getThreatManager().getThreatList().begin();
for(; i != me->getThreatManager().getThreatList().end(); ++i)
{
Unit* pTemp = Unit::GetUnit(*m_creature, (*i)->getUnitGuid());
++i;
if (pTemp && pTemp->isAlive() && pTemp->GetHealth() > MostHP && m_creature->IsWithinMeleeRange(pTemp))
Unit* target = (*i)->getTarget();
if (target->isAlive() && target->GetHealth() > MostHP && me->IsWithinMeleeRange(target))
{
MostHP = pTemp->GetHealth();
pMostHPTarget = pTemp;
MostHP = target->GetHealth();
pMostHPTarget = target;
}
}
@@ -26,159 +26,220 @@ EndScriptData */
#define EMOTE_BREATH -1533082
#define EMOTE_ENRAGE -1533083
#define SPELL_FROST_AURA HEROIC(28531,55799)
#define SPELL_CLEAVE 19983
#define SPELL_TAIL_SWEEP HEROIC(55697,55696)
#define SPELL_SUMMON_BLIZZARD 28560
#define SPELL_LIFE_DRAIN HEROIC(28542,55665)
#define SPELL_ICEBOLT 28522
#define SPELL_FROST_BREATH 29318
#define SPELL_FROST_AURA HEROIC(28531,55799)
#define SPELL_LIFE_DRAIN HEROIC(28542,55665)
//#define SPELL_CHILL 28560
#define SPELL_BLIZZARD 28547
#define SPELL_BESERK 26662
#define SPELL_CLEAVE 19983
#define SPELL_TAIL_SWEEP 55697
#define SPELL_FROST_BREATH2 28524
#define SPELL_BERSERK 26662
#define SPELL_CHILL HEROIC(28547,55699)
#define MOB_BLIZZARD 16474
#define GO_ICEBLOCK 181247
enum Phases
{
PHASE_NULL = 0,
PHASE_GROUND,
PHASE_FLIGHT,
};
enum Events
{
EVENT_BERSERK = 1,
EVENT_CLEAVE,
EVENT_TAIL,
EVENT_DRAIN,
EVENT_BLIZZARD,
EVENT_FLIGHT,
EVENT_LIFTOFF,
EVENT_ICEBOLT,
EVENT_BREATH,
EVENT_LAND,
EVENT_GROUND,
};
typedef std::map<uint64, uint64> IceBlockMap;
struct TRINITY_DLL_DECL boss_sapphironAI : public ScriptedAI
{
boss_sapphironAI(Creature* c) : ScriptedAI(c) {}
boss_sapphironAI(Creature* c) : ScriptedAI(c)
, phase(PHASE_NULL)
{
}
uint32 Icebolt_Count;
uint32 Icebolt_Timer;
uint32 FrostBreath_Timer;
uint32 FrostAura_Timer;
uint32 LifeDrain_Timer;
uint32 Blizzard_Timer;
uint32 Tail_Sweep_Timer;
uint32 Cleave_Timer;
uint32 Fly_Timer;
uint32 Fly2_Timer;
uint32 Beserk_Timer;
uint32 phase;
bool IsInFly;
uint32 land_Timer;
EventMap events;
Phases phase;
uint32 iceboltCount;
IceBlockMap iceblocks;
void Reset()
{
FrostAura_Timer = 2000;
LifeDrain_Timer = 24000;
Blizzard_Timer = 20000;
Tail_Sweep_Timer=(rand()%2+9)*1000;
Cleave_Timer=10000;
Fly_Timer = 45000;
Icebolt_Timer = 4000;
land_Timer = 0;
Beserk_Timer = 15*60000;
phase = 1;
Icebolt_Count = 0;
IsInFly = false;
if(phase = PHASE_FLIGHT)
ClearIceBlock();
m_creature->RemoveUnitMovementFlag(MOVEMENTFLAG_LEVITATING);
events.Reset();
phase = PHASE_NULL;
}
void EnterCombat(Unit *who)
{
DoZoneInCombat();
me->CastSpell(me, SPELL_FROST_AURA, true);
events.ScheduleEvent(EVENT_BERSERK, 15*60000);
EnterPhaseGround();
}
void SpellHitTarget(Unit *target, const SpellEntry *spell)
{
if(spell->Id == SPELL_ICEBOLT)
{
IceBlockMap::iterator itr = iceblocks.find(target->GetGUID());
if(itr != iceblocks.end() && !itr->second)
{
if(GameObject *iceblock = me->SummonGameObject(GO_ICEBLOCK, target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), 0, 0, 0, 0, 0, 25000))
itr->second = iceblock->GetGUID();
}
}
}
void EnterPhaseGround()
{
events.SetPhase(PHASE_GROUND);
events.ScheduleEvent(EVENT_CLEAVE, 5000+rand()%10000, 0, PHASE_GROUND);
events.ScheduleEvent(EVENT_TAIL, 5000+rand()%10000, 0, PHASE_GROUND);
events.ScheduleEvent(EVENT_DRAIN, 24000, 0, PHASE_GROUND);
events.ScheduleEvent(EVENT_BLIZZARD, 5000+rand()%15000, 0, PHASE_GROUND);
events.ScheduleEvent(EVENT_FLIGHT, 45000);
}
void ClearIceBlock()
{
for(IceBlockMap::iterator itr = iceblocks.begin(); itr != iceblocks.end(); ++itr)
{
if(Player *player = Unit::GetPlayer(itr->first))
player->RemoveAura(SPELL_ICEBOLT);
if(GameObject *go = GameObject::GetGameObject(*me, itr->second))
go->Delete();
}
iceblocks.clear();
}
void UpdateAI(const uint32 diff)
{
if (!UpdateVictim())
if(!phase)
return;
if(phase == 1)
events.Update(diff);
if(phase == PHASE_GROUND)
{
if(LifeDrain_Timer < diff)
{
DoCastAOE(SPELL_LIFE_DRAIN);
LifeDrain_Timer = 24000;
}else LifeDrain_Timer -= diff;
if(!UpdateVictim())
return;
if(Blizzard_Timer < diff)
while(uint32 eventId = events.ExecuteEvent())
{
if (Unit* target = SelectUnit(SELECT_TARGET_RANDOM,0))
switch(eventId)
{
DoCast(target,SPELL_BLIZZARD);
//It seems NO damage?
case EVENT_BERSERK:
DoScriptText(EMOTE_ENRAGE, m_creature);
DoCast(me, SPELL_BERSERK);
return;
case EVENT_CLEAVE:
DoCast(me->getVictim(), SPELL_CLEAVE);
events.ScheduleEvent(EVENT_CLEAVE, 10000, 0, PHASE_GROUND);
return;
case EVENT_TAIL:
DoCastAOE(SPELL_TAIL_SWEEP);
events.ScheduleEvent(EVENT_TAIL, (rand()%2+9)*1000, 0, PHASE_GROUND);
return;
case EVENT_DRAIN:
DoCastAOE(SPELL_LIFE_DRAIN);
events.ScheduleEvent(EVENT_DRAIN, 24000, 0, PHASE_GROUND);
return;
case EVENT_BLIZZARD:
if(Unit* target = SelectUnit(SELECT_TARGET_RANDOM,0))
DoCast(target,SPELL_SUMMON_BLIZZARD);
events.ScheduleEvent(EVENT_BLIZZARD, 20000, 0, PHASE_GROUND);
break;
case EVENT_FLIGHT:
phase = PHASE_FLIGHT;
events.SetPhase(PHASE_FLIGHT);
events.ScheduleEvent(EVENT_LIFTOFF, 0);
return;
}
Blizzard_Timer = 20000;
}else Blizzard_Timer -= diff;
//SPELL_CLEAVE
if(Cleave_Timer < diff)
{
DoCast(m_creature->getVictim(),SPELL_CLEAVE);
Cleave_Timer = 10000;
}else Cleave_Timer -= diff;
//Tail Sweep_Timer,
if(Tail_Sweep_Timer < diff)
{
DoCast(m_creature,SPELL_TAIL_SWEEP);
Tail_Sweep_Timer=(rand()%2+9)*1000;
}else Tail_Sweep_Timer -= diff;
if (m_creature->GetHealth()*100 / m_creature->GetMaxHealth() > 10)
{
if(Fly_Timer < diff)
{
phase = 2;
m_creature->HandleEmoteCommand(EMOTE_ONESHOT_LIFTOFF);
m_creature->AddUnitMovementFlag(MOVEMENTFLAG_LEVITATING);
m_creature->GetMotionMaster()->Clear(false);
m_creature->GetMotionMaster()->MoveIdle();
m_creature->SetHover(true);
Icebolt_Timer = 4000;
Icebolt_Count = 0;
IsInFly = true;
}else Fly_Timer -= diff;
}
}
if (phase == 2)
{
if(Icebolt_Timer < diff && Icebolt_Count < 5)
{
if (Unit* target = SelectUnit(SELECT_TARGET_RANDOM,0))
{
DoCast(target,SPELL_ICEBOLT);
++Icebolt_Count;
error_log("Count incremented");
}
FrostBreath_Timer = 6000;
Icebolt_Timer = 4000;
}else Icebolt_Timer -= diff;
if(Icebolt_Count == 5 && IsInFly && FrostBreath_Timer < diff )
{
DoScriptText(EMOTE_BREATH, m_creature);
DoCast(m_creature->getVictim(),SPELL_FROST_BREATH);
land_Timer = 2000;
IsInFly = false;
FrostBreath_Timer = 6000;
}else FrostBreath_Timer -= diff;
if(!IsInFly && land_Timer < diff)
{
phase = 1;
m_creature->HandleEmoteCommand(EMOTE_ONESHOT_LAND);
m_creature->RemoveUnitMovementFlag(MOVEMENTFLAG_LEVITATING);
m_creature->GetMotionMaster()->Clear(false);
m_creature->GetMotionMaster()->MoveChase(m_creature->getVictim());
m_creature->SetHover(true);
land_Timer = 0;
Fly_Timer = 67000;
}else land_Timer -= diff;
}
if (Beserk_Timer < diff)
{
DoScriptText(EMOTE_ENRAGE, m_creature);
DoCast(m_creature,SPELL_BESERK);
Beserk_Timer = 300000;
}else Beserk_Timer -= diff;
if (phase!=2)
DoMeleeAttackIfReady();
}
else
{
if(me->getThreatManager().isThreatListEmpty())
{
EnterEvadeMode();
return;
}
if(uint32 eventId = events.ExecuteEvent())
{
switch(eventId)
{
case EVENT_LIFTOFF:
me->AttackStop();
me->GetMotionMaster()->MoveIdle();
me->HandleEmoteCommand(EMOTE_ONESHOT_LIFTOFF);
me->AddUnitMovementFlag(MOVEMENTFLAG_LEVITATING);
me->SendMovementFlagUpdate();
events.ScheduleEvent(EVENT_ICEBOLT, 1000);
iceboltCount = HeroicMode ? 3 : 2;
return;
case EVENT_ICEBOLT:
{
std::vector<Unit*> targets;
std::list<HostilReference*>::iterator i = me->getThreatManager().getThreatList().begin();
for(; i != me->getThreatManager().getThreatList().end(); ++i)
if((*i)->getTarget()->GetTypeId() == TYPEID_PLAYER && !(*i)->getTarget()->HasAura(SPELL_ICEBOLT))
targets.push_back((*i)->getTarget());
if(targets.empty())
iceboltCount = 0;
else
{
std::vector<Unit*>::iterator itr = targets.begin();
advance(itr, rand()%targets.size());
iceblocks.insert(std::make_pair((*itr)->GetGUID(), 0));
DoCast(*itr, SPELL_ICEBOLT);
--iceboltCount;
}
if(iceboltCount)
events.ScheduleEvent(EVENT_ICEBOLT, 1000);
else
events.ScheduleEvent(EVENT_BREATH, 1000);
return;
}
case EVENT_BREATH:
DoScriptText(EMOTE_BREATH, me);
ClearIceBlock();
events.ScheduleEvent(EVENT_LAND, 1000);
return;
case EVENT_LAND:
me->HandleEmoteCommand(EMOTE_ONESHOT_LAND);
me->RemoveUnitMovementFlag(MOVEMENTFLAG_LEVITATING);
me->SendMovementFlagUpdate();
events.ScheduleEvent(EVENT_GROUND, 1000);
return;
case EVENT_GROUND:
EnterPhaseGround();
return;
}
}//if(uint32 eventId = events.ExecuteEvent())
}//if(phase == PHASE_GROUND)
}
};
+7
View File
@@ -12163,6 +12163,13 @@ void Unit::StopMoving()
SendMessageToSet(&data,false);
}
void Unit::SendMovementFlagUpdate()
{
WorldPacket data;
BuildHeartBeatMsg(&data);
SendMessageToSet(&data, false);
}
/*
void Unit::SetFeared(bool apply, uint64 casterGUID, uint32 spellID)
{
+1
View File
@@ -1212,6 +1212,7 @@ class TRINITY_DLL_SPEC Unit : public WorldObject
void SendMonsterMoveByPath(Path const& path, uint32 start, uint32 end);
void SendMonsterMoveWithSpeed(float x, float y, float z, uint32 transitTime = 0, Player* player = NULL);
void SendMonsterMoveWithSpeedToCurrentDestination(Player* player = NULL);
void SendMovementFlagUpdate();
bool isAlive() const { return (m_deathState == ALIVE); };
bool isDead() const { return ( m_deathState == DEAD || m_deathState == CORPSE ); };