aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authormegamage <none@none>2009-05-09 10:50:41 -0500
committermegamage <none@none>2009-05-09 10:50:41 -0500
commite35d07ad81f5acedcbe436bf429db5581edc6b81 (patch)
treeae238465d80bc7dcbba5b66dddf6708837be6f2a /src
parent1de3e5d8e846c7bfe48ca4982df7615c392abb9e (diff)
*Update Sapphiron script.
--HG-- branch : trunk
Diffstat (limited to 'src')
-rw-r--r--src/bindings/scripts/include/sc_creature.cpp22
-rw-r--r--src/bindings/scripts/include/sc_creature.h3
-rw-r--r--src/bindings/scripts/scripts/creature/mob_generic_creature.cpp52
-rw-r--r--src/bindings/scripts/scripts/zone/naxxramas/boss_sapphiron.cpp131
-rw-r--r--src/bindings/scripts/scripts/zone/naxxramas/def_naxxramas.h3
-rw-r--r--src/bindings/scripts/scripts/zone/naxxramas/instance_naxxramas.cpp11
-rw-r--r--src/game/Object.cpp18
-rw-r--r--src/game/Object.h1
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);