diff options
author | megamage <none@none> | 2009-05-09 10:50:41 -0500 |
---|---|---|
committer | megamage <none@none> | 2009-05-09 10:50:41 -0500 |
commit | e35d07ad81f5acedcbe436bf429db5581edc6b81 (patch) | |
tree | ae238465d80bc7dcbba5b66dddf6708837be6f2a /src | |
parent | 1de3e5d8e846c7bfe48ca4982df7615c392abb9e (diff) |
*Update Sapphiron script.
--HG--
branch : trunk
Diffstat (limited to 'src')
-rw-r--r-- | src/bindings/scripts/include/sc_creature.cpp | 22 | ||||
-rw-r--r-- | src/bindings/scripts/include/sc_creature.h | 3 | ||||
-rw-r--r-- | src/bindings/scripts/scripts/creature/mob_generic_creature.cpp | 52 | ||||
-rw-r--r-- | src/bindings/scripts/scripts/zone/naxxramas/boss_sapphiron.cpp | 131 | ||||
-rw-r--r-- | src/bindings/scripts/scripts/zone/naxxramas/def_naxxramas.h | 3 | ||||
-rw-r--r-- | src/bindings/scripts/scripts/zone/naxxramas/instance_naxxramas.cpp | 11 | ||||
-rw-r--r-- | src/game/Object.cpp | 18 | ||||
-rw-r--r-- | src/game/Object.h | 1 |
8 files changed, 219 insertions, 22 deletions
diff --git a/src/bindings/scripts/include/sc_creature.cpp b/src/bindings/scripts/include/sc_creature.cpp index 258c7627dce..a76fbb8e1ef 100644 --- a/src/bindings/scripts/include/sc_creature.cpp +++ b/src/bindings/scripts/include/sc_creature.cpp @@ -785,13 +785,29 @@ void LoadOverridenSQLData() goInfo->goober.lockId = 57; // need LOCKTYPE_QUICK_OPEN } +#define SPELL(x) const_cast<SpellEntry*>(GetSpellStore()->LookupEntry(x)) + void LoadOverridenDBCData() { SpellEntry *spellInfo; // Black Temple : Illidan : Parasitic Shadowfiend Passive - spellInfo = const_cast<SpellEntry*>(GetSpellStore()->LookupEntry(41913)); - if(spellInfo) + if(spellInfo = SPELL(41913)) spellInfo->EffectApplyAuraName[0] = 4; // proc debuff, and summon infinite fiends -} + // Naxxramas : Sapphiron : Frost Breath Visual Effect + //if(spellInfo = SPELL(30101)) + // spellInfo->EffectImplicitTargetA[0] = TARGET_DEST_DEST; // orig 18 + + //temp, not needed in 310 + if(spellInfo = SPELL(28531)) + { + spellInfo->DurationIndex = 21; + spellInfo->Effect[0] = SPELL_EFFECT_APPLY_AREA_AURA_ENEMY; + } + if(spellInfo = SPELL(55799)) + { + spellInfo->DurationIndex = 21; + spellInfo->Effect[0] = SPELL_EFFECT_APPLY_AREA_AURA_ENEMY; + } +} diff --git a/src/bindings/scripts/include/sc_creature.h b/src/bindings/scripts/include/sc_creature.h index 638b6926a27..c2c93a520a9 100644 --- a/src/bindings/scripts/include/sc_creature.h +++ b/src/bindings/scripts/include/sc_creature.h @@ -137,7 +137,7 @@ struct TRINITY_DLL_DECL ScriptedAI : public CreatureAI void JustRespawned(); //Called at waypoint reached or PointMovement end - void MovementInform(uint32, uint32){} + void MovementInform(uint32 type, uint32 id){} // Called when AI is temporarily replaced or put back when possess is applied or removed void OnPossess(bool apply) {} @@ -264,7 +264,6 @@ struct TRINITY_DLL_DECL NullCreatureAI : public ScriptedAI void MoveInLineOfSight(Unit *) {} void AttackStart(Unit *) {} void EnterEvadeMode() {} - bool IsVisible(Unit *) const { return false; } void UpdateAI(const uint32) {} }; diff --git a/src/bindings/scripts/scripts/creature/mob_generic_creature.cpp b/src/bindings/scripts/scripts/creature/mob_generic_creature.cpp index 2f2d5349f2a..56155a9ff2f 100644 --- a/src/bindings/scripts/scripts/creature/mob_generic_creature.cpp +++ b/src/bindings/scripts/scripts/creature/mob_generic_creature.cpp @@ -156,11 +156,58 @@ struct TRINITY_DLL_DECL generic_creatureAI : public ScriptedAI } } }; + CreatureAI* GetAI_generic_creature(Creature *_Creature) { return new generic_creatureAI (_Creature); } +struct TRINITY_DLL_DECL trigger_periodicAI : public NullCreatureAI +{ + trigger_periodicAI(Creature* c) : NullCreatureAI(c) + { + if(me->m_spells[0]) + { + if(me->m_spells[1]) + spell = GetSpellStore()->LookupEntry(HEROIC(me->m_spells[0], me->m_spells[1])); + else + spell = GetSpellStore()->LookupEntry(me->m_spells[0]); + } + else + spell = NULL; + + if(me->m_spells[2]) + { + if(me->m_spells[3]) + interval = HEROIC(me->m_spells[2], me->m_spells[3]); + else + interval = me->m_spells[2]; + } + else + interval = 1000; + timer = interval; + } + + uint32 timer, interval; + const SpellEntry * spell; + + void UpdateAI(const uint32 diff) + { + if(timer < diff) + { + if(spell) + me->CastSpell(me, spell, true); + timer = interval; + } + else + timer -= diff; + } +}; + +CreatureAI* GetAI_trigger_periodic(Creature *_Creature) +{ + return new trigger_periodicAI (_Creature); +} void AddSC_generic_creature() { @@ -169,5 +216,10 @@ void AddSC_generic_creature() newscript->Name="generic_creature"; newscript->GetAI = &GetAI_generic_creature; newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name="trigger_periodic"; + newscript->GetAI = &GetAI_trigger_periodic; + newscript->RegisterSelf(); } diff --git a/src/bindings/scripts/scripts/zone/naxxramas/boss_sapphiron.cpp b/src/bindings/scripts/scripts/zone/naxxramas/boss_sapphiron.cpp index 44e2def1c88..97165d4a389 100644 --- a/src/bindings/scripts/scripts/zone/naxxramas/boss_sapphiron.cpp +++ b/src/bindings/scripts/scripts/zone/naxxramas/boss_sapphiron.cpp @@ -22,6 +22,7 @@ SDCategory: Naxxramas EndScriptData */ #include "precompiled.h" +#include "def_naxxramas.h" #define EMOTE_BREATH -1533082 #define EMOTE_ENRAGE -1533083 @@ -33,8 +34,10 @@ EndScriptData */ #define SPELL_LIFE_DRAIN HEROIC(28542,55665) #define SPELL_ICEBOLT 28522 #define SPELL_FROST_BREATH 29318 -#define SPELL_FROST_BREATH2 28524 +#define SPELL_FROST_EXPLOSION 28524 +#define SPELL_FROST_MISSILE 30101 #define SPELL_BERSERK 26662 +#define SPELL_DIES 29357 #define SPELL_CHILL HEROIC(28547,55699) @@ -44,6 +47,7 @@ EndScriptData */ enum Phases { PHASE_NULL = 0, + PHASE_BIRTH, PHASE_GROUND, PHASE_FLIGHT, }; @@ -59,8 +63,10 @@ enum Events EVENT_LIFTOFF, EVENT_ICEBOLT, EVENT_BREATH, + EVENT_EXPLOSION, EVENT_LAND, EVENT_GROUND, + EVENT_BIRTH, }; typedef std::map<uint64, uint64> IceBlockMap; @@ -77,6 +83,17 @@ struct TRINITY_DLL_DECL boss_sapphironAI : public ScriptedAI uint32 iceboltCount; IceBlockMap iceblocks; + void InitializeAI() + { + float x, y, z; + me->GetPosition(x, y, z); + me->SummonGameObject(GO_BIRTH, x, y, z, 0, 0, 0, 0, 0, 0); + me->SetVisibility(VISIBILITY_OFF); + me->SetReactState(REACT_PASSIVE); + + Reset(); + } + void Reset() { if(phase = PHASE_FLIGHT) @@ -108,13 +125,35 @@ struct TRINITY_DLL_DECL boss_sapphironAI : public ScriptedAI } } + void JustDied(Unit*) + { + me->CastSpell(me, SPELL_DIES, true); + } + + void MovementInform(uint32, uint32 id) + { + if(id == 1) + events.ScheduleEvent(EVENT_LIFTOFF, 0); + } + + void DoAction(const int32 param) + { + if(param == DATA_SAPPHIRON_BIRTH) + { + phase = PHASE_BIRTH; + events.ScheduleEvent(EVENT_BIRTH, 25000); + } + } + void EnterPhaseGround() { + phase = PHASE_GROUND; + me->SetReactState(REACT_AGGRESSIVE); 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_BLIZZARD, 5000+rand()%5000, 0, PHASE_GROUND); events.ScheduleEvent(EVENT_FLIGHT, 45000); } @@ -152,25 +191,37 @@ struct TRINITY_DLL_DECL boss_sapphironAI : public ScriptedAI return; case EVENT_CLEAVE: DoCast(me->getVictim(), SPELL_CLEAVE); - events.ScheduleEvent(EVENT_CLEAVE, 10000, 0, PHASE_GROUND); + events.ScheduleEvent(EVENT_CLEAVE, 5000+rand()%10000, 0, PHASE_GROUND); return; case EVENT_TAIL: DoCastAOE(SPELL_TAIL_SWEEP); - events.ScheduleEvent(EVENT_TAIL, (rand()%2+9)*1000, 0, PHASE_GROUND); + events.ScheduleEvent(EVENT_TAIL, 5000+rand()%10000, 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); + { + //DoCastAOE(SPELL_SUMMON_BLIZZARD); + float x, y, z; + me->GetGroundPointAroundUnit(x, y, z, rand_norm()*20, rand_norm()*2*M_PI); + if(Creature *summon = me->SummonCreature(MOB_BLIZZARD, x, y, z, 0, TEMPSUMMON_TIMED_DESPAWN, 25000+rand()%5000)) + { + summon->setFaction(me->getFaction()); + summon->GetMotionMaster()->MoveRandom(40); + } + events.ScheduleEvent(EVENT_BLIZZARD, HEROIC(20000,7000), 0, PHASE_GROUND); break; + } case EVENT_FLIGHT: phase = PHASE_FLIGHT; events.SetPhase(PHASE_FLIGHT); - events.ScheduleEvent(EVENT_LIFTOFF, 0); + me->SetReactState(REACT_PASSIVE); + me->AttackStop(); + float x, y, z, o; + me->GetHomePosition(x, y, z, o); + me->GetMotionMaster()->MovePoint(1, x, y, z); return; } } @@ -179,24 +230,22 @@ struct TRINITY_DLL_DECL boss_sapphironAI : public ScriptedAI } else { - if(me->getThreatManager().isThreatListEmpty()) + /*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; + events.ScheduleEvent(EVENT_ICEBOLT, 1500); + iceboltCount = HEROIC(2,3); return; case EVENT_ICEBOLT: { @@ -224,23 +273,73 @@ struct TRINITY_DLL_DECL boss_sapphironAI : public ScriptedAI return; } case EVENT_BREATH: + { DoScriptText(EMOTE_BREATH, me); + DoCastAOE(SPELL_FROST_MISSILE); + events.ScheduleEvent(EVENT_EXPLOSION, 8000); + return; + } + case EVENT_EXPLOSION: + CastExplosion(); ClearIceBlock(); - events.ScheduleEvent(EVENT_LAND, 1000); + events.ScheduleEvent(EVENT_LAND, 3000); return; case EVENT_LAND: me->HandleEmoteCommand(EMOTE_ONESHOT_LAND); me->RemoveUnitMovementFlag(MOVEMENTFLAG_LEVITATING); me->SendMovementFlagUpdate(); - events.ScheduleEvent(EVENT_GROUND, 1000); + events.ScheduleEvent(EVENT_GROUND, 1500); return; case EVENT_GROUND: EnterPhaseGround(); return; + case EVENT_BIRTH: + me->SetVisibility(VISIBILITY_ON); + me->SetReactState(REACT_AGGRESSIVE); + return; } }//if(uint32 eventId = events.ExecuteEvent()) }//if(phase == PHASE_GROUND) } + + void CastExplosion() + { + DoZoneInCombat(); // make sure everyone is in threatlist + std::vector<Unit*> targets; + std::list<HostilReference*>::iterator i = me->getThreatManager().getThreatList().begin(); + for(; i != me->getThreatManager().getThreatList().end(); ++i) + { + Unit *target = (*i)->getTarget(); + if(target->GetTypeId() != TYPEID_PLAYER) + continue; + + if(target->HasAura(SPELL_ICEBOLT)) + { + target->ApplySpellImmune(0, IMMUNITY_ID, SPELL_FROST_EXPLOSION, true); + targets.push_back(target); + continue; + } + + for(IceBlockMap::iterator itr = iceblocks.begin(); itr != iceblocks.end(); ++itr) + { + if(GameObject *go = GameObject::GetGameObject(*me, itr->second)) + { + if(go->IsInBetween(me, target, 2.0f) + && me->GetExactDistance2d(target->GetPositionX(), target->GetPositionY()) - me->GetExactDistance2d(go->GetPositionX(), go->GetPositionY()) < 5.0f) + { + target->ApplySpellImmune(0, IMMUNITY_ID, SPELL_FROST_EXPLOSION, true); + targets.push_back(target); + break; + } + } + } + } + + me->CastSpell(me, SPELL_FROST_EXPLOSION, true); + + for(std::vector<Unit*>::iterator itr = targets.begin(); itr != targets.end(); ++itr) + (*itr)->ApplySpellImmune(0, IMMUNITY_ID, SPELL_FROST_EXPLOSION, false); + } }; CreatureAI* GetAI_boss_sapphiron(Creature *_Creature) diff --git a/src/bindings/scripts/scripts/zone/naxxramas/def_naxxramas.h b/src/bindings/scripts/scripts/zone/naxxramas/def_naxxramas.h index b0931c556fe..12c1dc6edfa 100644 --- a/src/bindings/scripts/scripts/zone/naxxramas/def_naxxramas.h +++ b/src/bindings/scripts/scripts/zone/naxxramas/def_naxxramas.h @@ -29,7 +29,10 @@ enum Encounter enum Data { DATA_HEIGAN_ERUPT, + DATA_SAPPHIRON_BIRTH, }; +#define GO_BIRTH 181356 + #endif diff --git a/src/bindings/scripts/scripts/zone/naxxramas/instance_naxxramas.cpp b/src/bindings/scripts/scripts/zone/naxxramas/instance_naxxramas.cpp index dfa085f39be..4743a44f2d3 100644 --- a/src/bindings/scripts/scripts/zone/naxxramas/instance_naxxramas.cpp +++ b/src/bindings/scripts/scripts/zone/naxxramas/instance_naxxramas.cpp @@ -58,11 +58,21 @@ inline uint32 GetEruptionSection(float x, float y) struct TRINITY_DLL_DECL instance_naxxramas : public ScriptedInstance { instance_naxxramas(Map *map) : ScriptedInstance(map) + , Sapphiron(NULL) { SetBossNumber(15); } std::set<GameObject*> HeiganEruption[4]; + Creature *Sapphiron; + + void OnCreatureCreate(Creature *creature, bool add) + { + switch(creature->GetEntry()) + { + case 15989: Sapphiron = add ? creature : NULL; break; + } + } void OnObjectCreate(GameObject* go, bool add) { @@ -83,6 +93,7 @@ struct TRINITY_DLL_DECL instance_naxxramas : public ScriptedInstance case 181202: SetBossRoomDoor(BOSS_HEIGAN, go, add); break; case 181203: SetBossPassageDoor(BOSS_HEIGAN, go, add); break; case 181241: SetBossRoomDoor(BOSS_LOATHEB, go, add); break; + case GO_BIRTH: if(!add && Sapphiron) Sapphiron->AI()->DoAction(DATA_SAPPHIRON_BIRTH); break; } } diff --git a/src/game/Object.cpp b/src/game/Object.cpp index f649164e21b..6b7a3cdd4ac 100644 --- a/src/game/Object.cpp +++ b/src/game/Object.cpp @@ -1309,6 +1309,21 @@ bool WorldObject::HasInArc(const float arcangle, const WorldObject* obj) const return (( angle >= lborder ) && ( angle <= rborder )); } +bool WorldObject::IsInBetween(const WorldObject *obj1, const WorldObject *obj2, float size) const +{ + if(GetPositionX() > std::max(obj1->GetPositionX(), obj2->GetPositionX()) + || GetPositionX() < std::min(obj1->GetPositionX(), obj2->GetPositionX()) + || GetPositionY() > std::max(obj1->GetPositionY(), obj2->GetPositionY()) + || GetPositionY() < std::min(obj1->GetPositionY(), obj2->GetPositionY())) + return false; + + if(!size) + size = GetObjectSize() / 2; + + float angle = obj1->GetAngle(this) - obj1->GetAngle(obj2); + return abs(sin(angle)) * GetExactDistance2d(obj1->GetPositionX(), obj1->GetPositionY()) < size; +} + void WorldObject::GetRandomPoint( float x, float y, float z, float distance, float &rand_x, float &rand_y, float &rand_z) const { if(distance==0) @@ -1658,6 +1673,8 @@ TempSummon *Map::SummonCreature(uint32 entry, float x, float y, float z, float a return NULL; } + summon->SetHomePosition(x, y, z, angle); + summon->InitStats(duration); Add((Creature*)summon); summon->InitSummon(); @@ -1680,7 +1697,6 @@ TempSummon* WorldObject::SummonCreature(uint32 entry, float x, float y, float z, if(!pCreature) return NULL; - pCreature->SetHomePosition(x, y, z, ang); pCreature->SetTempSummonType(spwtype); return pCreature; diff --git a/src/game/Object.h b/src/game/Object.h index 68438c4df85..e7e03501dc1 100644 --- a/src/game/Object.h +++ b/src/game/Object.h @@ -480,6 +480,7 @@ class TRINITY_DLL_SPEC WorldObject : public Object float GetAngle( const float x, const float y ) const; void GetSinCos(const float x, const float y, float &vsin, float &vcos); bool HasInArc( const float arcangle, const WorldObject* obj ) const; + bool IsInBetween(const WorldObject *obj1, const WorldObject *obj2, float size = 0) const; virtual void SendMessageToSet(WorldPacket *data, bool self, bool to_possessor = true); virtual void SendMessageToSetInRange(WorldPacket *data, float dist, bool self, bool to_possessor = true); |