diff options
| author | maximius <none@none> | 2009-08-07 12:12:42 -0700 |
|---|---|---|
| committer | maximius <none@none> | 2009-08-07 12:12:42 -0700 |
| commit | fe3ba612d94b715bbbbac944418be1188ad66339 (patch) | |
| tree | dcfba651a684cd3f896988e361240f91c4b1d80f /src/bindings/scripts | |
| parent | be74be36f6d170fd11b2df2ebfc20a9c2e40584a (diff) | |
*Emalon the Stormwatcher fully scripted, by Necroo (boss needs to be spawned and ScriptName needs to be updated)
*Added config options: DurabilityLoss.OnDeath and DurabilityLoss.InPvP, optimized Rate.RepairCost
--HG--
branch : trunk
Diffstat (limited to 'src/bindings/scripts')
8 files changed, 440 insertions, 31 deletions
diff --git a/src/bindings/scripts/CMakeLists.txt b/src/bindings/scripts/CMakeLists.txt index dab90812b59..b67d7cfe4aa 100644 --- a/src/bindings/scripts/CMakeLists.txt +++ b/src/bindings/scripts/CMakeLists.txt @@ -484,6 +484,7 @@ SET(trinityscript_LIB_SRCS scripts/zone/obsidian_sanctum/def_obsidian_sanctum.h scripts/zone/vault_of_archavon/instance_vault_of_archavon.cpp scripts/zone/vault_of_archavon/boss_archavon.cpp + scripts/zone/vault_of_archavon/boss_emalon.cpp scripts/zone/vault_of_archavon/def_vault_of_archavon.h scripts/zone/wintergrasp/wintergrasp.cpp scripts/zone/ulduar/ulduar/boss_algalon.cpp diff --git a/src/bindings/scripts/ScriptMgr.cpp b/src/bindings/scripts/ScriptMgr.cpp index 478c2b904f3..ae298061984 100644 --- a/src/bindings/scripts/ScriptMgr.cpp +++ b/src/bindings/scripts/ScriptMgr.cpp @@ -650,6 +650,8 @@ extern void AddSC_zuldrak(); //Dungeon //Vault of Archavon extern void AddSC_boss_archavon(); +extern void AddSC_boss_emalon(); +extern void AddSC_instance_archavon(); //Region extern void AddSC_wintergrasp(); @@ -1558,6 +1560,8 @@ void ScriptsInit(char const* cfg_file = "trinitycore.conf") //Dungeon //Vault of Archavon AddSC_boss_archavon(); + AddSC_boss_emalon(); + AddSC_instance_archavon(); //Region AddSC_wintergrasp(); diff --git a/src/bindings/scripts/VC80/80ScriptDev2.vcproj b/src/bindings/scripts/VC80/80ScriptDev2.vcproj index d1d41523d36..e5eeda086ff 100644 --- a/src/bindings/scripts/VC80/80ScriptDev2.vcproj +++ b/src/bindings/scripts/VC80/80ScriptDev2.vcproj @@ -2834,6 +2834,10 @@ > </File> <File + RelativePath="..\scripts\zone\vault_of_archavon\boss_emalon.cpp" + > + </File> + <File RelativePath="..\scripts\zone\vault_of_archavon\def_vault_of_archavon.h" > </File> diff --git a/src/bindings/scripts/VC90/90ScriptDev2.vcproj b/src/bindings/scripts/VC90/90ScriptDev2.vcproj index 04645271404..7fe459734ed 100644 --- a/src/bindings/scripts/VC90/90ScriptDev2.vcproj +++ b/src/bindings/scripts/VC90/90ScriptDev2.vcproj @@ -2835,6 +2835,10 @@ > </File> <File + RelativePath="..\scripts\zone\vault_of_archavon\boss_emalon.cpp" + > + </File> + <File RelativePath="..\scripts\zone\vault_of_archavon\def_vault_of_archavon.h" > </File> diff --git a/src/bindings/scripts/scripts/zone/vault_of_archavon/boss_archavon.cpp b/src/bindings/scripts/scripts/zone/vault_of_archavon/boss_archavon.cpp index d963024d69e..51e6df5e023 100644 --- a/src/bindings/scripts/scripts/zone/vault_of_archavon/boss_archavon.cpp +++ b/src/bindings/scripts/scripts/zone/vault_of_archavon/boss_archavon.cpp @@ -3,77 +3,77 @@ UPDATE `creature_template` SET `ScriptName`='boss_archavon' WHERE `entry`='31125 UPDATE `creature_template` SET `ScriptName`='mob_archavon_warder' WHERE `entry`='32353'; *** SQL END ***/ #include "precompiled.h" +#include "def_vault_of_archavon.h" -//These are patchwerk's yell -#define SAY_AGGRO1 -1533017 -#define SAY_AGGRO2 -1533018 -#define SAY_SLAY -1533019 -#define SAY_DEATH -1533020 - -#define EMOTE_BERSERK -1533021 -#define EMOTE_ENRAGE -1533022 +#define EMOTE_BERSERK -1590002 //Spells Archavon -#define SPELL_ROCK_SHARDS 58678 -#define SPELL_CRUSHING_LEAP HEROIC(58960,60894)//Instant (10-80yr range) -- Leaps at an enemy, inflicting 8000 Physical damage, knocking all nearby enemies away, and creating a cloud of choking debris. -#define SPELL_STOMP HEROIC(58663,60880) -#define SPELL_IMPALE HEROIC(58666,60882) //Lifts an enemy off the ground with a spiked fist, inflicting 47125 to 52875 Physical damage and 9425 to 10575 additional damage each second for 8 sec. -#define SPELL_BERSERK 47008 +#define SPELL_ROCK_SHARDS 58678 +#define SPELL_CRUSHING_LEAP HEROIC(58960,60894)//Instant (10-80yr range) -- Leaps at an enemy, inflicting 8000 Physical damage, knocking all nearby enemies away, and creating a cloud of choking debris. +#define SPELL_STOMP HEROIC(58663,60880) +#define SPELL_IMPALE HEROIC(58666,60882) //Lifts an enemy off the ground with a spiked fist, inflicting 47125 to 52875 Physical damage and 9425 to 10575 additional damage each second for 8 sec. +#define SPELL_BERSERK 47008 //Spells Archavon Warders -#define SPELL_ROCK_SHOWER HEROIC(60919,60923) -#define SPELL_SHIELD_CRUSH HEROIC(60897,60899) -#define SPELL_WHIRL HEROIC(60902,60916) +#define SPELL_ROCK_SHOWER HEROIC(60919,60923) +#define SPELL_SHIELD_CRUSH HEROIC(60897,60899) +#define SPELL_WHIRL HEROIC(60902,60916) //4 Warders spawned -#define ARCHAVON_WARDER 32353 //npc 32353 +#define ARCHAVON_WARDER 32353 //npc 32353 //Yell #define SAY_LEAP "Archavon the Stone Watcher lunges for $N!" //$N should be the target -#define EVENT_ROCK_SHARDS 1 //15s cd -#define EVENT_CHOKING_CLOUD 2 //30s cd +#define EVENT_ROCK_SHARDS 1 //15s cd +#define EVENT_CHOKING_CLOUD 2 //30s cd #define EVENT_STOMP 3 //45s cd #define EVENT_IMPALE 4 #define EVENT_BERSERK 5 //300s cd //mob -#define EVENT_ROCK_SHOWER 5 //set = 20s cd,unkown cd -#define EVENT_SHIELD_CRUSH 6 //set = 30s cd -#define EVENT_WHIRL 8 //set= 10s cd +#define EVENT_ROCK_SHOWER 5 //set = 20s cd,unkown cd +#define EVENT_SHIELD_CRUSH 6 //set = 30s cd +#define EVENT_WHIRL 8 //set= 10s cd struct TRINITY_DLL_DECL boss_archavonAI : public ScriptedAI { - boss_archavonAI(Creature *c) : ScriptedAI(c) {} + boss_archavonAI(Creature *c) : ScriptedAI(c) + { + pInstance = c->GetInstanceData(); + } + ScriptedInstance* pInstance; EventMap events; void Reset() { events.Reset(); - } - void KilledUnit(Unit* Victim) - { - if(!(rand()%5)) - DoScriptText(SAY_SLAY, me); + if(pInstance) + pInstance->SetData(DATA_ARCHAVON_EVENT, NOT_STARTED); } + void KilledUnit(Unit* Victim){} + void JustDied(Unit* Killer) { - DoScriptText(SAY_DEATH, me); + if (pInstance) + pInstance->SetData(DATA_ARCHAVON_EVENT, DONE); } void EnterCombat(Unit *who) { - DoScriptText((rand()%2) ? SAY_AGGRO1 : SAY_AGGRO2, me); DoZoneInCombat(); events.ScheduleEvent(EVENT_ROCK_SHARDS, 15000); events.ScheduleEvent(EVENT_CHOKING_CLOUD, 30000); events.ScheduleEvent(EVENT_STOMP, 45000); events.ScheduleEvent(EVENT_BERSERK, 300000); - } + if(pInstance) + pInstance->SetData(DATA_ARCHAVON_EVENT, IN_PROGRESS); + } + // Below UpdateAI may need review/debug. void UpdateAI(const uint32 diff) { //Return since we have no target diff --git a/src/bindings/scripts/scripts/zone/vault_of_archavon/boss_emalon.cpp b/src/bindings/scripts/scripts/zone/vault_of_archavon/boss_emalon.cpp new file mode 100644 index 00000000000..80fe55ca996 --- /dev/null +++ b/src/bindings/scripts/scripts/zone/vault_of_archavon/boss_emalon.cpp @@ -0,0 +1,284 @@ +#include "precompiled.h" +#include "def_vault_of_archavon.h" + +#define EMOTE_OVERCHARGE_TEMPEST_MINION -1590000 +#define EMOTE_MINION_RESPAWN -1590001 + +//Spells Emalon +#define SPELL_CHAIN_LIGHTNING HEROIC(64213,64215) +#define SPELL_LIGHTNING_NOVA HEROIC(64216,65279) +#define SPELL_OVERCHARGE 64218 +#define SPELL_BERSERK 47008 + +//Spells Tempest Minions +#define SPELL_OVERCHARGED 64217 +#define SPELL_OVERCHARGED_BLAST 64219 +#define SPELL_SHOCK 64363 + +//4 Warders spawned +#define TEMPEST_MINIONS 33998 + +#define EVENT_CHAIN_LIGHTNING 1 //5s cd +#define EVENT_OVERCHARGE 2 //45s cd +#define EVENT_LIGHTNING_NOVA 3 //40s cd +#define EVENT_BERSERK 4 //360s cd +#define EVENT_SHOCK 5 //20s cd + +struct Location +{ + float x, y, z, o; +}; + +static Location MinionLocation[]= +{ + -231.713,-281.96,91.466,1.53213, + -205.585,-281.549,91.4661,1.75204, + -205.651,-296.394,91.4661,1.69549, + -232.235,-296.433,91.4998,1.44417 +}; + +struct TRINITY_DLL_DECL boss_emalonAI : public ScriptedAI +{ + boss_emalonAI(Creature *c) : ScriptedAI(c) + { + pInstance = c->GetInstanceData(); + } + + ScriptedInstance* pInstance; + EventMap events; + std::list<uint64> MinionList; + + void Reset() + { + events.Reset(); + DespawnAllMinions(); + SummonAllMinions(); + + if(pInstance) + pInstance->SetData(DATA_EMALON_EVENT, NOT_STARTED); + } + + void DespawnAllMinions() + { + if(!MinionList.empty()) + { + for(std::list<uint64>::const_iterator itr = MinionList.begin(); itr != MinionList.end(); itr++) + { + Unit *Minion = Unit::GetUnit(*m_creature, (*itr)); + if(Minion) + Minion->RemoveFromWorld(); + } + } + + MinionList.clear(); + } + + void JustSummoned(Creature *Summoned) + { + MinionList.push_back(Summoned->GetGUID()); + if(Unit* target = m_creature->getVictim()) + Summoned->AI()->AttackStart(target); + } + + void SummonAllMinions() + { + if(MinionList.empty()) + for(uint8 i = 0; i < 4; i++) + SummonMinion(m_creature, MinionLocation[i].x, MinionLocation[i].y, MinionLocation[i].z, MinionLocation[i].o); + } + + static void SummonMinion(Creature *Summoner, float x, float y, float z, float o) + { + Summoner->SummonCreature(TEMPEST_MINIONS, x, y, z, o, TEMPSUMMON_DEAD_DESPAWN, 0); + } + + void KilledUnit(Unit* Victim){} + + void JustDied(Unit* Killer) + { + DespawnAllMinions(); + if (pInstance) + pInstance->SetData(DATA_EMALON_EVENT, DONE); + } + + void EnterCombat(Unit *who) + { + if(!MinionList.empty()) + { + for(std::list<uint64>::const_iterator itr = MinionList.begin(); itr != MinionList.end(); ++itr) + { + Creature* Minion = (Unit::GetCreature(*m_creature, *itr)); + Minion->AI()->AttackStart(who); + } + } + + DoZoneInCombat(); + events.ScheduleEvent(EVENT_CHAIN_LIGHTNING, 5000); + events.ScheduleEvent(EVENT_OVERCHARGE, 45000); + events.ScheduleEvent(EVENT_LIGHTNING_NOVA, 30000); + events.ScheduleEvent(EVENT_BERSERK, 360000); + events.ScheduleEvent(EVENT_SHOCK, 20000); + + if(pInstance) + pInstance->SetData(DATA_EMALON_EVENT, IN_PROGRESS); + } + + void UpdateAI(const uint32 diff) + { + //Return since we have no target + if(!UpdateVictim()) + return; + + events.Update(diff); + + if(me->hasUnitState(UNIT_STAT_CASTING)) + return; + + while(uint32 eventId = events.ExecuteEvent()) + { + switch(eventId) + { + case EVENT_CHAIN_LIGHTNING: + if(Unit* target = SelectUnit(SELECT_TARGET_RANDOM, 0)) + DoCast(target, SPELL_CHAIN_LIGHTNING); + events.ScheduleEvent(EVENT_CHAIN_LIGHTNING, 20000); + return; + case EVENT_OVERCHARGE: + for(std::list<uint64>::const_iterator itr = MinionList.begin(); itr != MinionList.end(); ++itr) + { + Creature* Minion = (Unit::GetCreature(*m_creature, *itr)); + if(Minion && Minion->isAlive() && !Minion->HasAura(SPELL_OVERCHARGED)) + { + Minion->CastSpell(me, SPELL_OVERCHARGED, true); + Minion->SetHealth(Minion->GetMaxHealth()); + DoScriptText(EMOTE_OVERCHARGE_TEMPEST_MINION, m_creature); + events.ScheduleEvent(EVENT_OVERCHARGE, 45000); + return; + } + } + case EVENT_LIGHTNING_NOVA: + DoCast(me->getVictim(), SPELL_LIGHTNING_NOVA); + events.ScheduleEvent(EVENT_LIGHTNING_NOVA, 25000); + return; + case EVENT_SHOCK: + for(std::list<uint64>::const_iterator itr = MinionList.begin(); itr != MinionList.end(); ++itr) + { + Creature* Minion = (Unit::GetCreature(*m_creature, *itr)); + if(Minion && Minion->isAlive()) + { + if(Unit* target = SelectUnit(SELECT_TARGET_RANDOM, 0)) + { + Minion->CastSpell(target, SPELL_SHOCK, true); + events.ScheduleEvent(EVENT_SHOCK, 20000); + return; + } + } + } + case EVENT_BERSERK: + DoCast(m_creature, SPELL_BERSERK); + return; + } + } + + DoMeleeAttackIfReady(); + } +}; + +/*###### +## Mob Tempest Minions +######*/ +struct TRINITY_DLL_DECL mob_tempest_minionsAI : public ScriptedAI +{ + mob_tempest_minionsAI(Creature *c) : ScriptedAI(c) + { + pInstance = c->GetInstanceData(); + EmalonGUID = pInstance ? pInstance->GetData64(DATA_EMALON) : 0; + Emalon = Unit::GetCreature(*m_creature, EmalonGUID); + } + + ScriptedInstance* pInstance; + EventMap events; + uint64 EmalonGUID; + std::list<Creature*> MinionList; + Creature* Emalon; + uint32 SPELL_OVERCHARGED_Timer; + bool AlreadyOvercharged; + + void Reset() + { + events.Reset(); + AlreadyOvercharged = false; + SPELL_OVERCHARGED_Timer = 0; + } + + void EnterCombat(Unit *who) + { + DoZoneInCombat(); + if(Emalon) + Emalon->AI()->AttackStart(who); + } + + void JustDied(Unit* Killer) + { + m_creature->RemoveCorpse(); + m_creature->RemoveFromWorld(); + if(Emalon) + { + boss_emalonAI::SummonMinion(Emalon, Emalon->GetPositionX(), Emalon->GetPositionY(), Emalon->GetPositionZ(), Emalon->GetOrientation()); + DoScriptText(EMOTE_MINION_RESPAWN, m_creature); + } + } + + void UpdateAI(const uint32 diff) + { + //Return since we have no target + if(!UpdateVictim()) + return; + + if(Aura *OverchargedAura = m_creature->GetAura(SPELL_OVERCHARGED)) + { + if(OverchargedAura->GetStackAmount() < 10) + { + if (SPELL_OVERCHARGED_Timer < diff) + { + DoCast(me, SPELL_OVERCHARGED); + SPELL_OVERCHARGED_Timer = 2000; + }else SPELL_OVERCHARGED_Timer -=diff; + } + else + { + if(OverchargedAura->GetStackAmount() == 10 && (AlreadyOvercharged == false)) + { + DoCast(me,SPELL_OVERCHARGED_BLAST); + AlreadyOvercharged = true; + } + } + } + DoMeleeAttackIfReady(); + } +}; + +CreatureAI* GetAI_mob_tempest_minions(Creature *_Creature) +{ + return new mob_tempest_minionsAI (_Creature); +} + +CreatureAI* GetAI_boss_emalon(Creature *_Creature) +{ + return new boss_emalonAI (_Creature); +} + +void AddSC_boss_emalon() +{ + Script *newscript; + + newscript = new Script; + newscript->Name="boss_emalon"; + newscript->GetAI = &GetAI_boss_emalon; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name="mob_tempest_minions"; + newscript->GetAI = &GetAI_mob_tempest_minions; + newscript->RegisterSelf(); +} diff --git a/src/bindings/scripts/scripts/zone/vault_of_archavon/def_vault_of_archavon.h b/src/bindings/scripts/scripts/zone/vault_of_archavon/def_vault_of_archavon.h index f46ba447945..5b11d5729eb 100644 --- a/src/bindings/scripts/scripts/zone/vault_of_archavon/def_vault_of_archavon.h +++ b/src/bindings/scripts/scripts/zone/vault_of_archavon/def_vault_of_archavon.h @@ -1,4 +1,13 @@ #ifndef DEF_ARCHAVON_H #define DEF_ARCHAVON_H +enum +{ + DATA_ARCHAVON = 1, + DATA_EMALON = 2, + + DATA_ARCHAVON_EVENT = 3, + DATA_EMALON_EVENT = 4 +}; + #endif diff --git a/src/bindings/scripts/scripts/zone/vault_of_archavon/instance_vault_of_archavon.cpp b/src/bindings/scripts/scripts/zone/vault_of_archavon/instance_vault_of_archavon.cpp index dc725b2be66..e7f6f572a77 100644 --- a/src/bindings/scripts/scripts/zone/vault_of_archavon/instance_vault_of_archavon.cpp +++ b/src/bindings/scripts/scripts/zone/vault_of_archavon/instance_vault_of_archavon.cpp @@ -1,9 +1,112 @@ #include "precompiled.h" #include "def_vault_of_archavon.h" +#define NUMBER_OF_ENCOUNTERS 2 + struct TRINITY_DLL_DECL instance_archavon : public ScriptedInstance { instance_archavon(Map *Map) : ScriptedInstance(Map) {Initialize();}; + + std::string strInstData; + uint64 Archavon; + uint64 Emalon; + uint32 Encounters[NUMBER_OF_ENCOUNTERS]; + + void Initialize() + { + Archavon = 0; + Emalon = 0; + + for(uint8 i = 0; i < NUMBER_OF_ENCOUNTERS; i++) + Encounters[i] = NOT_STARTED; + } + + bool IsEncounterInProgress() const + { + for(uint8 i = 0; i < NUMBER_OF_ENCOUNTERS; ++i) + if(Encounters[i] == IN_PROGRESS) + return true; + + return false; + } + + void OnCreatureCreate(Creature *creature, bool add) + { + switch(creature->GetEntry()) + { + case 31125: Archavon = creature->GetGUID(); break; + case 33993: Emalon = creature->GetGUID(); break; + } + } + + uint64 GetData64(uint32 identifier) + { + switch(identifier) + { + case DATA_ARCHAVON: return Archavon; + case DATA_EMALON: return Emalon; + } + return 0; + } + + uint32 GetData(uint32 identifier) + { + switch(identifier) + { + case DATA_ARCHAVON_EVENT: return Encounters[0]; + case DATA_EMALON_EVENT: return Encounters[1]; + } + return 0; + } + + void SetData(uint32 identifier, uint32 data) + { + switch(identifier) + { + case DATA_ARCHAVON_EVENT: Encounters[0] = data; break; + case DATA_EMALON_EVENT: Encounters[1] = data; break; + } + + if (data == DONE) + { + OUT_SAVE_INST_DATA; + + std::ostringstream saveStream; + saveStream << Encounters[0] << " " << Encounters[1]; + + strInstData = saveStream.str(); + + SaveToDB(); + OUT_SAVE_INST_DATA_COMPLETE; + } + } + + std::string GetSaveData() + { + return strInstData; + } + + void Load(const char* chrIn) + { + if (!chrIn) + { + OUT_LOAD_INST_DATA_FAIL; + return; + } + + OUT_LOAD_INST_DATA(chrIn); + + std::istringstream loadStream(chrIn); + loadStream >> Encounters[0] >> Encounters[1]; + + for(uint8 i = 1; i < NUMBER_OF_ENCOUNTERS; ++i) + { + if (Encounters[i] == IN_PROGRESS) + Encounters[i] = NOT_STARTED; + } + + OUT_LOAD_INST_DATA_COMPLETE; + } }; InstanceData* GetInstanceData_instance_archavon(Map* map) |
