aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authormegamage <none@none>2009-05-08 18:39:04 -0500
committermegamage <none@none>2009-05-08 18:39:04 -0500
commit5346498dea71f651e672e14f093137bbd6622ce9 (patch)
tree5682dfd9a5cb5d4a9a51f00a6a4c02c08d040713 /src
parent80bec6788c0201ffdac960b299c62f30da10f661 (diff)
*Update sapphiron script (not finished yet).
--HG-- branch : trunk
Diffstat (limited to 'src')
-rw-r--r--src/bindings/scripts/scripts/zone/naxxramas/boss_patchwerk.cpp13
-rw-r--r--src/bindings/scripts/scripts/zone/naxxramas/boss_sapphiron.cpp299
-rw-r--r--src/game/Unit.cpp7
-rw-r--r--src/game/Unit.h1
4 files changed, 194 insertions, 126 deletions
diff --git a/src/bindings/scripts/scripts/zone/naxxramas/boss_patchwerk.cpp b/src/bindings/scripts/scripts/zone/naxxramas/boss_patchwerk.cpp
index 3f51fc08ee4..99f8741c897 100644
--- a/src/bindings/scripts/scripts/zone/naxxramas/boss_patchwerk.cpp
+++ b/src/bindings/scripts/scripts/zone/naxxramas/boss_patchwerk.cpp
@@ -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;
}
}
diff --git a/src/bindings/scripts/scripts/zone/naxxramas/boss_sapphiron.cpp b/src/bindings/scripts/scripts/zone/naxxramas/boss_sapphiron.cpp
index a0cfb77c06c..44e2def1c88 100644
--- a/src/bindings/scripts/scripts/zone/naxxramas/boss_sapphiron.cpp
+++ b/src/bindings/scripts/scripts/zone/naxxramas/boss_sapphiron.cpp
@@ -26,159 +26,220 @@ EndScriptData */
#define EMOTE_BREATH -1533082
#define EMOTE_ENRAGE -1533083
-#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_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_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) {}
-
- 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;
+ boss_sapphironAI(Creature* c) : ScriptedAI(c)
+ , phase(PHASE_NULL)
+ {
+ }
+
+ 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;
-
- m_creature->RemoveUnitMovementFlag(MOVEMENTFLAG_LEVITATING);
+ if(phase = PHASE_FLIGHT)
+ ClearIceBlock();
+
+ 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 UpdateAI(const uint32 diff)
+ void SpellHitTarget(Unit *target, const SpellEntry *spell)
{
- if (!UpdateVictim())
- return;
-
- if(phase == 1)
+ if(spell->Id == SPELL_ICEBOLT)
{
- if(LifeDrain_Timer < diff)
+ IceBlockMap::iterator itr = iceblocks.find(target->GetGUID());
+ if(itr != iceblocks.end() && !itr->second)
{
- DoCastAOE(SPELL_LIFE_DRAIN);
- LifeDrain_Timer = 24000;
- }else LifeDrain_Timer -= diff;
+ if(GameObject *iceblock = me->SummonGameObject(GO_ICEBLOCK, target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), 0, 0, 0, 0, 0, 25000))
+ itr->second = iceblock->GetGUID();
+ }
+ }
+ }
- if(Blizzard_Timer < diff)
- {
- if (Unit* target = SelectUnit(SELECT_TARGET_RANDOM,0))
- {
- DoCast(target,SPELL_BLIZZARD);
- //It seems NO damage?
- }
- Blizzard_Timer = 20000;
- }else Blizzard_Timer -= diff;
+ 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);
+ }
- //SPELL_CLEAVE
- if(Cleave_Timer < diff)
- {
- DoCast(m_creature->getVictim(),SPELL_CLEAVE);
- Cleave_Timer = 10000;
- }else Cleave_Timer -= diff;
+ 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();
+ }
- //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;
+ void UpdateAI(const uint32 diff)
+ {
+ if(!phase)
+ return;
- 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;
- }
- }
+ events.Update(diff);
- if (phase == 2)
+ if(phase == PHASE_GROUND)
{
- if(Icebolt_Timer < diff && Icebolt_Count < 5)
+ if(!UpdateVictim())
+ return;
+
+ while(uint32 eventId = events.ExecuteEvent())
{
- if (Unit* target = SelectUnit(SELECT_TARGET_RANDOM,0))
+ switch(eventId)
{
- DoCast(target,SPELL_ICEBOLT);
- ++Icebolt_Count;
- error_log("Count incremented");
+ 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;
}
- FrostBreath_Timer = 6000;
- Icebolt_Timer = 4000;
- }else Icebolt_Timer -= diff;
+ }
- if(Icebolt_Count == 5 && IsInFly && FrostBreath_Timer < diff )
+ DoMeleeAttackIfReady();
+ }
+ else
+ {
+ if(me->getThreatManager().isThreatListEmpty())
{
- 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)
+ EnterEvadeMode();
+ return;
+ }
+
+ if(uint32 eventId = events.ExecuteEvent())
{
- 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;
- }
+ 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 (Beserk_Timer < diff)
- {
- DoScriptText(EMOTE_ENRAGE, m_creature);
- DoCast(m_creature,SPELL_BESERK);
- Beserk_Timer = 300000;
- }else Beserk_Timer -= diff;
+ 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 (phase!=2)
- DoMeleeAttackIfReady();
+ 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)
}
};
diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp
index 514a26349ba..5782ec9d5a4 100644
--- a/src/game/Unit.cpp
+++ b/src/game/Unit.cpp
@@ -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)
{
diff --git a/src/game/Unit.h b/src/game/Unit.h
index fcfc14b5394..54384854089 100644
--- a/src/game/Unit.h
+++ b/src/game/Unit.h
@@ -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 ); };