diff options
author | megamage <none@none> | 2009-05-08 18:39:04 -0500 |
---|---|---|
committer | megamage <none@none> | 2009-05-08 18:39:04 -0500 |
commit | 5346498dea71f651e672e14f093137bbd6622ce9 (patch) | |
tree | 5682dfd9a5cb5d4a9a51f00a6a4c02c08d040713 | |
parent | 80bec6788c0201ffdac960b299c62f30da10f661 (diff) |
*Update sapphiron script (not finished yet).
--HG--
branch : trunk
-rw-r--r-- | src/bindings/scripts/scripts/zone/naxxramas/boss_patchwerk.cpp | 13 | ||||
-rw-r--r-- | src/bindings/scripts/scripts/zone/naxxramas/boss_sapphiron.cpp | 299 | ||||
-rw-r--r-- | src/game/Unit.cpp | 7 | ||||
-rw-r--r-- | src/game/Unit.h | 1 |
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 ); }; |