mirror of
https://github.com/TrinityCore/TrinityCore.git
synced 2026-01-21 17:54:48 +01:00
*Update Sapphiron script.
--HG-- branch : trunk
This commit is contained in:
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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) {}
|
||||
};
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -29,7 +29,10 @@ enum Encounter
|
||||
enum Data
|
||||
{
|
||||
DATA_HEIGAN_ERUPT,
|
||||
DATA_SAPPHIRON_BIRTH,
|
||||
};
|
||||
|
||||
#define GO_BIRTH 181356
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user