diff options
Diffstat (limited to 'src')
4 files changed, 364 insertions, 41 deletions
diff --git a/src/bindings/scripts/scripts/northrend/azjol_nerub/ahnkahet/boss_prince_taldaram.cpp b/src/bindings/scripts/scripts/northrend/azjol_nerub/ahnkahet/boss_prince_taldaram.cpp index 511e1f2629a..605219e59e1 100644 --- a/src/bindings/scripts/scripts/northrend/azjol_nerub/ahnkahet/boss_prince_taldaram.cpp +++ b/src/bindings/scripts/scripts/northrend/azjol_nerub/ahnkahet/boss_prince_taldaram.cpp @@ -18,7 +18,7 @@ /* ScriptData SDName: boss_prince_taldaram -SDAuthor: LordVanMartin +SDAuthor: Tartalo & tlexii SD%Complete: 0 SDComment: SDCategory: Ahn'kahet @@ -33,65 +33,294 @@ EndScriptData */ #define SPELL_FLAME_SPHERE_SUMMON_1 55895// 1x 30106 #define H_SPELL_FLAME_SPHERE_SUMMON_1 59511// 1x 31686 #define H_SPELL_FLAME_SPHERE_SUMMON_2 59512// 1x 31687 -#define SPELL_FLAME_SPHERE_SPAWN_EFFEKT 55891 +#define SPELL_FLAME_SPHERE_SPAWN_EFFECT 55891 #define SPELL_FLAME_SPHERE_VISUAL 55928 #define SPELL_FLAME_SPHERE_PERIODIC 55926 #define H_SPELL_FLAME_SPHERE_PERIODIC 59508 -#define SPELL_FLAME_SPHERE_DEATH_EFFEKT 55947 +#define SPELL_FLAME_SPHERE_DEATH_EFFECT 55947 +#define SPELL_BEAM_VISUAL 60342 #define SPELL_EMBRACE_OF_THE_VAMPYR 55959 #define H_SPELL_EMBRACE_OF_THE_VAMPYR 59513 #define SPELL_VANISH 55964 +#define CREATURE_FLAME_SPHERE 30106 +#define H_CREATURE_FLAME_SPHERE_1 31686 +#define H_CREATURE_FLAME_SPHERE_2 31687 + +#define DATA_EMBRACE_DMG 20000 +#define H_DATA_EMBRACE_DMG 40000 + +#define DATA_GROUND_POSITION_Z 11.4 +#define DATA_SPHERE_DISTANCE 100.0 + //not in db //Yell #define SAY_AGGRO -1619021 #define SAY_SLAY_1 -1619022 #define SAY_SLAY_2 -1619023 -#define SAY_SLAY_3 -1619024 -#define SAY_DEATH -1619025 -#define SAY_FEED_1 -1619026 -#define SAY_FEED_2 -1619027 -#define SAY_VANISH_1 -1619028 -#define SAY_VANISH_2 -1619029 +#define SAY_DEATH -1619024 +#define SAY_FEED_1 -1619025 +#define SAY_FEED_2 -1619026 +#define SAY_VANISH_1 -1619027 +#define SAY_VANISH_2 -1619028 + +enum CombatPhase +{ + NORMAL, + CASTING_FLAME_SPHERES, + JUST_VANISHED, + VANISHED, + FEEDING +}; struct TRINITY_DLL_DECL boss_taldaramAI : public ScriptedAI { - boss_taldaramAI(Creature *c) : ScriptedAI(c) {} + boss_taldaramAI(Creature *c) : ScriptedAI(c) + { + pInstance = c->GetInstanceData(); + m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE); + m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + } + + uint32 uiBloodthirstTimer; + uint32 uiVanishTimer; + uint32 uiWaitTimer; + uint32 uiEmbraceTimer; + uint32 uiEmbraceTakenDamage; + uint32 uiFlamesphereTimer; + uint32 uiPhaseTimer; + + uint64 uiSphereGuids[2]; - void Reset() {} + Unit *pEmbraceTarget; + + CombatPhase Phase; + + ScriptedInstance* pInstance; + + void Reset() + { + uiBloodthirstTimer = 10000; + uiVanishTimer = (25 + rand()%10)*1000; + uiEmbraceTimer = 20000; + uiFlamesphereTimer = 5000; + uiEmbraceTakenDamage = 0; + Phase = NORMAL; + uiPhaseTimer = 0; + pEmbraceTarget = NULL; + if (pInstance) + pInstance->SetData(DATA_PRINCE_TALDARAM_EVENT, NOT_STARTED); + } + void EnterCombat(Unit* who) { - DoScriptText(SAY_AGGRO, m_creature); + if (pInstance) + pInstance->SetData(DATA_PRINCE_TALDARAM_EVENT, IN_PROGRESS); + DoScriptText(SAY_AGGRO, m_creature); } - void AttackStart(Unit* who) {} - void MoveInLineOfSight(Unit* who) {} + void UpdateAI(const uint32 diff) { - //Return since we have no target if (!UpdateVictim()) return; - - DoMeleeAttackIfReady(); + if (uiPhaseTimer < diff) + { + switch (Phase) + { + case CASTING_FLAME_SPHERES: + //DoCast(m_creature, SPELL_FLAME_SPHERE_SUMMON_1); + DoSpawnCreature(CREATURE_FLAME_SPHERE, 0, 0, 5, 0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 10000); + if (HeroicMode) + { + //DoCast(m_creature, H_SPELL_FLAME_SPHERE_SUMMON_1); + DoSpawnCreature(H_CREATURE_FLAME_SPHERE_1, 0, 0, 5, 0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 10000); + //DoCast(m_creature, H_SPELL_FLAME_SPHERE_SUMMON_2); + DoSpawnCreature(H_CREATURE_FLAME_SPHERE_2, 0, 0, 5, 0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 10000); + } + Phase = NORMAL; + uiPhaseTimer = 0; + break; + case JUST_VANISHED: + DoModifyThreatPercent(pEmbraceTarget, 100); + DoTeleportTo(pEmbraceTarget->GetPositionX(),pEmbraceTarget->GetPositionY(),pEmbraceTarget->GetPositionZ()); + Phase = VANISHED; + uiPhaseTimer = 1400; + break; + case VANISHED: + DoCast(pEmbraceTarget,HeroicMode ? H_SPELL_EMBRACE_OF_THE_VAMPYR : SPELL_EMBRACE_OF_THE_VAMPYR ); + Phase = FEEDING; + uiPhaseTimer = 20000; + break; + case FEEDING: + Phase = NORMAL; + uiPhaseTimer = 0; + pEmbraceTarget = NULL; + break; + case NORMAL: + if (uiBloodthirstTimer < diff) + { + DoCast(m_creature->getVictim(),SPELL_BLOODTHIRST); + uiBloodthirstTimer = 10000; + } else uiBloodthirstTimer -= diff; + + if (uiFlamesphereTimer < diff) + { + DoCast(m_creature, SPELL_CONJURE_FLAME_SPHERE); + Phase = CASTING_FLAME_SPHERES; + uiPhaseTimer = 3000 + diff; + uiFlamesphereTimer = 15000; + } else uiFlamesphereTimer -= diff; + + if (uiVanishTimer < diff ) + { + //Count alive players + Unit *target = NULL; + std::list<HostilReference *> t_list = m_creature->getThreatManager().getThreatList(); + std::vector<Unit *> target_list; + for(std::list<HostilReference *>::iterator itr = t_list.begin(); itr!= t_list.end(); ++itr) + { + target = Unit::GetUnit(*m_creature, (*itr)->getUnitGuid()); + // exclude pets & totems + if (target && target->GetTypeId() == TYPEID_PLAYER && target->isAlive()) + target_list.push_back(target); + target = NULL; + } + //He only vanishes if there are 3 or more alive players + if (target_list.size() > 2) + { + DoScriptText(RAND(SAY_VANISH_1,SAY_VANISH_2), m_creature); + DoCast(m_creature,SPELL_VANISH); + Phase = JUST_VANISHED; + uiPhaseTimer = 1000; + pEmbraceTarget = SelectUnit(SELECT_TARGET_RANDOM, 0); + while (pEmbraceTarget && pEmbraceTarget->GetTypeId() != TYPEID_PLAYER) + pEmbraceTarget = SelectUnit(SELECT_TARGET_RANDOM, 0); + } + uiVanishTimer = (25 + rand()%10)*1000; + } else uiVanishTimer -= diff; + + DoMeleeAttackIfReady(); + break; + } + } else uiPhaseTimer -= diff; } + + void DamageTaken(Unit* done_by, uint32 &damage) + { + if (Phase == FEEDING && pEmbraceTarget && pEmbraceTarget->isAlive()) + { + uiEmbraceTakenDamage += damage; + if (uiEmbraceTakenDamage > (HeroicMode ? H_DATA_EMBRACE_DMG : DATA_EMBRACE_DMG)) + { + Phase = NORMAL; + uiPhaseTimer = 0; + pEmbraceTarget = NULL; + m_creature->CastStop(); + } + } + } + void JustDied(Unit* killer) { DoScriptText(SAY_DEATH, m_creature); + + if (pInstance) + pInstance->SetData(DATA_PRINCE_TALDARAM_EVENT, DONE); } void KilledUnit(Unit *victim) { if (victim == m_creature) return; + if (Phase == FEEDING && pEmbraceTarget && victim == pEmbraceTarget) + { + Phase = NORMAL; + uiPhaseTimer = 0; + pEmbraceTarget = NULL; + } + DoScriptText(RAND(SAY_SLAY_1,SAY_SLAY_2), m_creature); + } + + bool CheckSpheres() + { + if(!pInstance) + return false; + uiSphereGuids[0] = pInstance->GetData64(DATA_SPHERE1); + uiSphereGuids[1] = pInstance->GetData64(DATA_SPHERE2); + + GameObject *pSpheres[2]; + for (uint8 i=0; i < 2; ++i) + { + pSpheres[i] = pInstance->instance->GetGameObject(uiSphereGuids[i]); + if (!pSpheres[i]) + return false; + if (pSpheres[i]->GetGoState() != GO_STATE_ACTIVE) + return false; + } + RemovePrison(); + return true; + } + + void RemovePrison() + { + m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE); + m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); + m_creature->RemoveAurasDueToSpell(SPELL_BEAM_VISUAL); + m_creature->SetHomePosition(m_creature->GetPositionX(), m_creature->GetPositionY(), DATA_GROUND_POSITION_Z, m_creature->GetOrientation()); + uint64 prison_GUID = pInstance->GetData64(DATA_PRINCE_TALDARAM_PLATFORM); + pInstance->HandleGameObject(prison_GUID,true); + } +}; - switch(rand()%3) +struct TRINITY_DLL_DECL mob_taldaram_flamesphereAI : public ScriptedAI +{ + mob_taldaram_flamesphereAI(Creature *c) : ScriptedAI(c) + { + pInstance = c->GetInstanceData(); + } + + uint32 uiDespawnTimer; + ScriptedInstance* pInstance; + + void Reset() + { + m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + m_creature->AddUnitMovementFlag(MOVEMENTFLAG_FLYING + MOVEMENTFLAG_HOVER); + m_creature->setFaction(16); + DoCast(m_creature, SPELL_FLAME_SPHERE_VISUAL); + DoCast(m_creature, SPELL_FLAME_SPHERE_SPAWN_EFFECT); + DoCast(m_creature, HeroicMode ? H_SPELL_FLAME_SPHERE_PERIODIC : SPELL_FLAME_SPHERE_PERIODIC); + uiDespawnTimer = 10000; + Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0); + if (pTarget) { - case 0: DoScriptText(SAY_SLAY_1, m_creature);break; - case 1: DoScriptText(SAY_SLAY_2, m_creature);break; - case 2: DoScriptText(SAY_SLAY_3, m_creature);break; + float angle,x,y; + angle = m_creature->GetAngle(pTarget); + x = m_creature->GetPositionX() + DATA_SPHERE_DISTANCE * cos(angle); + y = m_creature->GetPositionY() + DATA_SPHERE_DISTANCE * sin(angle); + m_creature->GetMotionMaster()->MovePoint(0, x, y, m_creature->GetPositionZ()); } } + + void EnterCombat(Unit *who) {} + void MoveInLineOfSight(Unit *who) {} + + void JustDied(Unit* slayer) + { + DoCast(m_creature, SPELL_FLAME_SPHERE_DEATH_EFFECT); + } + + void UpdateAI(const uint32 diff) + { + if (uiDespawnTimer < diff) + { + m_creature->DealDamage(m_creature, m_creature->GetMaxHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); + m_creature->RemoveCorpse(); + } + else uiDespawnTimer -= diff; + } }; CreatureAI* GetAI_boss_taldaram(Creature* pCreature) @@ -99,6 +328,33 @@ CreatureAI* GetAI_boss_taldaram(Creature* pCreature) return new boss_taldaramAI (pCreature); } +CreatureAI* GetAI_mob_taldaram_flamesphere(Creature* pCreature) +{ + return new mob_taldaram_flamesphereAI (pCreature); +} + +bool GOHello_prince_taldaram_sphere(Player *pPlayer, GameObject *pGO) +{ + ScriptedInstance *pInstance = pGO->GetInstanceData(); + + Creature *pPrinceTaldaram = Unit::GetCreature(*pGO, pInstance ? pInstance->GetData64(DATA_PRINCE_TALDARAM) : 0); + if (pPrinceTaldaram && pPrinceTaldaram->isAlive()) + { + // maybe these are hacks :( + pGO->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_UNK1); + pGO->SetGoState(GO_STATE_ACTIVE); + + switch(pGO->GetEntry()) + { + case 193093: pInstance->SetData(DATA_SPHERE1_EVENT,IN_PROGRESS); break; + case 193094: pInstance->SetData(DATA_SPHERE2_EVENT,IN_PROGRESS); break; + } + + CAST_AI(boss_taldaramAI, pPrinceTaldaram->AI())->CheckSpheres(); + } + return true; +} + void AddSC_boss_taldaram() { Script *newscript; @@ -107,4 +363,14 @@ void AddSC_boss_taldaram() newscript->Name="boss_taldaram"; newscript->GetAI = &GetAI_boss_taldaram; newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name="mob_taldaram_flamesphere"; + newscript->GetAI = &GetAI_mob_taldaram_flamesphere; + newscript->RegisterSelf(); + + newscript = new Script; + newscript->Name = "prince_taldaram_sphere"; + newscript->pGOHello = &GOHello_prince_taldaram_sphere; + newscript->RegisterSelf(); } diff --git a/src/bindings/scripts/scripts/northrend/azjol_nerub/ahnkahet/def_ahnkahet.h b/src/bindings/scripts/scripts/northrend/azjol_nerub/ahnkahet/def_ahnkahet.h index 97c0db55d72..9c17171d019 100644 --- a/src/bindings/scripts/scripts/northrend/azjol_nerub/ahnkahet/def_ahnkahet.h +++ b/src/bindings/scripts/scripts/northrend/azjol_nerub/ahnkahet/def_ahnkahet.h @@ -30,4 +30,11 @@ #define DATA_JEDOGA_SHADOWSEEKER_EVENT 8 #define DATA_HERALD_VOLAZJ_EVENT 9 #define DATA_AMANITAR_EVENT 10 + +#define DATA_SPHERE1 11 +#define DATA_SPHERE2 12 +#define DATA_SPHERE1_EVENT 13 +#define DATA_SPHERE2_EVENT 14 +#define DATA_PRINCE_TALDARAM_PLATFORM 15 + #endif diff --git a/src/bindings/scripts/scripts/northrend/azjol_nerub/ahnkahet/instance_ahnkahet.cpp b/src/bindings/scripts/scripts/northrend/azjol_nerub/ahnkahet/instance_ahnkahet.cpp index db9befd65cf..a1516f06dd5 100644 --- a/src/bindings/scripts/scripts/northrend/azjol_nerub/ahnkahet/instance_ahnkahet.cpp +++ b/src/bindings/scripts/scripts/northrend/azjol_nerub/ahnkahet/instance_ahnkahet.cpp @@ -45,19 +45,26 @@ struct TRINITY_DLL_DECL instance_ahnkahet : public ScriptedInstance uint64 Jedoga_Shadowseeker; uint64 Herald_Volazj; uint64 Amanitar; + + uint64 Prince_TaldaramSpheres[2]; + uint64 Prince_TaldaramPlatform; + uint64 Prince_TaldaramGate; uint32 m_auiEncounter[MAX_ENCOUNTER]; + uint32 spheres[2]; - void Initialize() - { - Elder_Nadox =0; - Prince_Taldaram =0; - Jedoga_Shadowseeker =0; - Herald_Volazj =0; - Amanitar =0; - - for(uint8 i = 0; i < MAX_ENCOUNTER; ++i) - m_auiEncounter[i] = NOT_STARTED; + void Initialize() + { + Elder_Nadox =0; + Prince_Taldaram =0; + Jedoga_Shadowseeker =0; + Herald_Volazj =0; + Amanitar =0; + + for(uint8 i = 0; i < MAX_ENCOUNTER; ++i) + m_auiEncounter[i] = NOT_STARTED; + spheres[0] = NOT_STARTED; + spheres[1] = NOT_STARTED; } bool IsEncounterInProgress() const @@ -75,21 +82,48 @@ struct TRINITY_DLL_DECL instance_ahnkahet : public ScriptedInstance { case 29309: Elder_Nadox = pCreature->GetGUID(); break; case 29308: Prince_Taldaram = pCreature->GetGUID(); break; - case 29310: Jedoga_Shadowseeker = pCreature->GetGUID(); break; + case 29310: Jedoga_Shadowseeker = pCreature->GetGUID(); break; case 29311: Herald_Volazj = pCreature->GetGUID(); break; case 30258: Amanitar = pCreature->GetGUID(); break; } } + + void OnGameObjectCreate(GameObject* pGo, bool add) + { + switch(pGo->GetEntry()) + { + case 193564: Prince_TaldaramPlatform = pGo->GetGUID();break; + case 193093: Prince_TaldaramSpheres[0] = pGo->GetGUID(); + if (spheres[0] == IN_PROGRESS) + { + pGo->SetGoState(GO_STATE_ACTIVE); + pGo->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_UNK1); + } + break; + case 193094: Prince_TaldaramSpheres[1] = pGo->GetGUID(); + if (spheres[1] == IN_PROGRESS) + { + pGo->SetGoState(GO_STATE_ACTIVE); + pGo->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_UNK1); + } + break; + case 192236: Prince_TaldaramGate = pGo->GetGUID(); // Web gate past Prince Taldaram + if (m_auiEncounter[1] == DONE)HandleGameObject(NULL,true,pGo);break; + } + } uint64 GetData64(uint32 identifier) { switch(identifier) { - case DATA_ELDER_NADOX: return Elder_Nadox; - case DATA_PRINCE_TALDARAM: return Prince_Taldaram; - case DATA_JEDOGA_SHADOWSEEKER: return Jedoga_Shadowseeker; - case DATA_HERALD_VOLAZJ: return Herald_Volazj; - case DATA_AMANITAR: return Amanitar; + case DATA_ELDER_NADOX: return Elder_Nadox; + case DATA_PRINCE_TALDARAM: return Prince_Taldaram; + case DATA_JEDOGA_SHADOWSEEKER: return Jedoga_Shadowseeker; + case DATA_HERALD_VOLAZJ: return Herald_Volazj; + case DATA_AMANITAR: return Amanitar; + case DATA_SPHERE1: return Prince_TaldaramSpheres[0]; + case DATA_SPHERE2: return Prince_TaldaramSpheres[1]; + case DATA_PRINCE_TALDARAM_PLATFORM: return Prince_TaldaramPlatform; } return 0; } @@ -101,6 +135,10 @@ struct TRINITY_DLL_DECL instance_ahnkahet : public ScriptedInstance case DATA_ELDER_NADOX_EVENT: m_auiEncounter[0] = data;break; case DATA_PRINCE_TALDARAM_EVENT: + if (data == DONE) + { + HandleGameObject(Prince_TaldaramGate,true); + } m_auiEncounter[1] = data; break; case DATA_JEDOGA_SHADOWSEEKER_EVENT: m_auiEncounter[2] = data; break; @@ -108,7 +146,11 @@ struct TRINITY_DLL_DECL instance_ahnkahet : public ScriptedInstance m_auiEncounter[3] = data; break; case DATA_AMANITAR: m_auiEncounter[4] = data; break; - } + case DATA_SPHERE1_EVENT: + spheres[0] = data; break; + case DATA_SPHERE2_EVENT: + spheres[1] = data; break; + } if (data == DONE) { @@ -125,6 +167,8 @@ struct TRINITY_DLL_DECL instance_ahnkahet : public ScriptedInstance case DATA_JEDOGA_SHADOWSEEKER_EVENT: return m_auiEncounter[2]; case DATA_HERALD_VOLAZJ: return m_auiEncounter[3]; case DATA_AMANITAR: return m_auiEncounter[4]; + case DATA_SPHERE1_EVENT: return spheres[0]; + case DATA_SPHERE2_EVENT: return spheres[1]; } return 0; } @@ -137,7 +181,8 @@ struct TRINITY_DLL_DECL instance_ahnkahet : public ScriptedInstance std::ostringstream saveStream; saveStream << "A K " << m_auiEncounter[0] << " " << m_auiEncounter[1] << " " - << m_auiEncounter[2] << m_auiEncounter[3] << m_auiEncounter[4]; + << m_auiEncounter[2] << " " << m_auiEncounter[3] << " " << m_auiEncounter[4] << " " + << spheres[0] << " " << spheres[1]; str_data = saveStream.str(); @@ -156,10 +201,10 @@ struct TRINITY_DLL_DECL instance_ahnkahet : public ScriptedInstance OUT_LOAD_INST_DATA(in); char dataHead1, dataHead2; - uint16 data0,data1,data2,data3,data4; + uint16 data0,data1,data2,data3,data4, data5, data6; std::istringstream loadStream(in); - loadStream >> dataHead1 >> dataHead2 >> data0 >> data1 >> data2 >> data3 >> data4; + loadStream >> dataHead1 >> dataHead2 >> data0 >> data1 >> data2 >> data3 >> data4 >> data5 >> data6; if (dataHead1 == 'A' && dataHead2 == 'K') { @@ -173,6 +218,9 @@ struct TRINITY_DLL_DECL instance_ahnkahet : public ScriptedInstance if (m_auiEncounter[i] == IN_PROGRESS) m_auiEncounter[i] = NOT_STARTED; + spheres[0] = data5; + spheres[1] = data6; + }else OUT_LOAD_INST_DATA_FAIL; OUT_LOAD_INST_DATA_COMPLETE; diff --git a/src/bindings/scripts/system/ScriptLoader.cpp b/src/bindings/scripts/system/ScriptLoader.cpp index 8ecd4e6fcf6..420019563a6 100644 --- a/src/bindings/scripts/system/ScriptLoader.cpp +++ b/src/bindings/scripts/system/ScriptLoader.cpp @@ -262,6 +262,7 @@ extern void AddSC_winterspring(); //northrend extern void AddSC_instance_ahnkahet(); //Azjol-Nerub Ahn'kahet +extern void AddSC_boss_taldaram(); extern void AddSC_boss_elder_nadox(); extern void AddSC_boss_anubrekhan(); //Naxxramas extern void AddSC_boss_maexxna(); @@ -662,6 +663,7 @@ void AddScripts() //northrend AddSC_instance_ahnkahet(); //Azjol-Nerub Ahn'kahet + AddSC_boss_taldaram(); AddSC_boss_elder_nadox(); AddSC_boss_anubrekhan(); //Naxxramas AddSC_boss_maexxna(); |