Add support to Flame Leviathan.

Thanks to SnakeIce for posting patch, and Manuel for support during codecleanup.

--HG--
branch : trunk
This commit is contained in:
Supabad
2010-05-29 15:32:28 +02:00
parent 0d64afc166
commit 1b66be14f6
3 changed files with 152 additions and 63 deletions
@@ -87,22 +87,30 @@ enum Yells
SAY_OVERLOAD_3 = -1603075, SAY_OVERLOAD_3 = -1603075,
}; };
static Position Center[]=
{
{354.8771, -12.90240, 409.803650},
};
struct boss_flame_leviathanAI : public BossAI struct boss_flame_leviathanAI : public BossAI
{ {
boss_flame_leviathanAI(Creature *pCreature) : BossAI(pCreature, TYPE_LEVIATHAN), vehicle(pCreature->GetVehicleKit()) boss_flame_leviathanAI(Creature* pCreature) : BossAI(pCreature, TYPE_LEVIATHAN), vehicle(pCreature->GetVehicleKit())
{ {
assert(vehicle); assert(vehicle);
pInstance = pCreature->GetInstanceData();
} }
Vehicle *vehicle; Vehicle* vehicle;
ScriptedInstance* pInstance;
void Reset() void Reset()
{ {
_Reset(); _Reset();
me->SetReactState(REACT_AGGRESSIVE); me->SetReactState(REACT_AGGRESSIVE);
pInstance->SetData(TYPE_LEVIATHAN, NOT_STARTED);
} }
void EnterCombat(Unit * /*who*/) void EnterCombat(Unit* /*who*/)
{ {
_EnterCombat(); _EnterCombat();
DoScriptText(SAY_AGGRO, me); DoScriptText(SAY_AGGRO, me);
@@ -114,31 +122,43 @@ struct boss_flame_leviathanAI : public BossAI
events.ScheduleEvent(EVENT_SUMMON, 0); events.ScheduleEvent(EVENT_SUMMON, 0);
//events.ScheduleEvent(EVENT_MIMIRON_INFERNO, urand(60000, 120000)); // Not Blizzlike //events.ScheduleEvent(EVENT_MIMIRON_INFERNO, urand(60000, 120000)); // Not Blizzlike
//events.ScheduleEvent(EVENT_HODIR_FURY, urand(60000, 120000)); // Not Blizzlike //events.ScheduleEvent(EVENT_HODIR_FURY, urand(60000, 120000)); // Not Blizzlike
pInstance->SetData(TYPE_LEVIATHAN, IN_PROGRESS);
if (Creature *turret = CAST_CRE(vehicle->GetPassenger(SEAT_TURRET))) if (Creature *turret = CAST_CRE(vehicle->GetPassenger(SEAT_TURRET)))
turret->AI()->DoZoneInCombat(); turret->AI()->DoZoneInCombat();
} }
// TODO: effect 0 and effect 1 may be on different target // TODO: effect 0 and effect 1 may be on different target
void SpellHitTarget(Unit *pTarget, const SpellEntry *spell) void SpellHitTarget(Unit* pTarget, const SpellEntry* pSpell)
{ {
if (spell->Id == SPELL_PURSUED) if (pSpell->Id == SPELL_PURSUED)
AttackStart(pTarget); AttackStart(pTarget);
} }
void JustDied(Unit * /*victim*/) void JustDied(Unit* /*victim*/)
{ {
pInstance->SetData(TYPE_LEVIATHAN, DONE);
DoScriptText(SAY_DEATH, me); DoScriptText(SAY_DEATH, me);
_JustDied(); _JustDied();
} }
void SpellHit(Unit * /*caster*/, const SpellEntry *spell) void SpellHit(Unit* /*caster*/, const SpellEntry* pSpell)
{ {
if (spell->Id == 62472) if (pSpell->Id == 62472)
vehicle->InstallAllAccessories(); vehicle->InstallAllAccessories();
else if (spell->Id == SPELL_ELECTROSHOCK) else if (pSpell->Id == SPELL_ELECTROSHOCK)
me->InterruptSpell(CURRENT_CHANNELED_SPELL); me->InterruptSpell(CURRENT_CHANNELED_SPELL);
} }
void DoAction(const int32 param)
{
if (param == 1)
{
me->GetMotionMaster()->MovePoint(0, Center[0]);
me->SetReactState(REACT_AGGRESSIVE);
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
}
}
void UpdateAI(const uint32 diff) void UpdateAI(const uint32 diff)
{ {
if (!me->isInCombat()) if (!me->isInCombat())
@@ -184,8 +204,8 @@ struct boss_flame_leviathanAI : public BossAI
return; return;
case EVENT_SUMMON: case EVENT_SUMMON:
if (summons.size() < 15) // 4seat+1turret+10lift if (summons.size() < 15) // 4seat+1turret+10lift
if (Creature *lift = DoSummonFlyer(MOB_MECHANOLIFT, me, urand(20,40), 50, 0)) if (Creature* pLift = DoSummonFlyer(MOB_MECHANOLIFT, me, urand(20,40), 50, 0))
lift->GetMotionMaster()->MoveRandom(100); pLift->GetMotionMaster()->MoveRandom(100);
events.RepeatEvent(2000); events.RepeatEvent(2000);
return; return;
case EVENT_MIMIRON_INFERNO: // Not Blizzlike case EVENT_MIMIRON_INFERNO: // Not Blizzlike
@@ -200,7 +220,6 @@ struct boss_flame_leviathanAI : public BossAI
events.PopEvent(); events.PopEvent();
break; break;
} }
DoSpellAttackIfReady(SPELL_BATTERING_RAM); DoSpellAttackIfReady(SPELL_BATTERING_RAM);
} }
}; };
@@ -217,7 +236,7 @@ struct boss_flame_leviathan_seatAI : public PassiveAI
#endif #endif
} }
Vehicle *vehicle; Vehicle* vehicle;
#ifdef BOSS_DEBUG #ifdef BOSS_DEBUG
void MoveInLineOfSight(Unit *who) void MoveInLineOfSight(Unit *who)
@@ -228,7 +247,7 @@ struct boss_flame_leviathan_seatAI : public PassiveAI
} }
#endif #endif
void PassengerBoarded(Unit *who, int8 seatId, bool apply) void PassengerBoarded(Unit* who, int8 seatId, bool apply)
{ {
if (!me->GetVehicle()) if (!me->GetVehicle())
return; return;
@@ -238,13 +257,13 @@ struct boss_flame_leviathan_seatAI : public PassiveAI
if (!apply) if (!apply)
return; return;
if (Creature *turret = CAST_CRE(vehicle->GetPassenger(SEAT_TURRET))) if (Creature* turret = CAST_CRE(vehicle->GetPassenger(SEAT_TURRET)))
{ {
turret->setFaction(me->GetVehicleBase()->getFaction()); turret->setFaction(me->GetVehicleBase()->getFaction());
turret->SetUInt32Value(UNIT_FIELD_FLAGS, 0); // unselectable turret->SetUInt32Value(UNIT_FIELD_FLAGS, 0); // unselectable
turret->AI()->AttackStart(who); turret->AI()->AttackStart(who);
} }
if (Unit *device = vehicle->GetPassenger(SEAT_DEVICE)) if (Unit* device = vehicle->GetPassenger(SEAT_DEVICE))
{ {
device->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_SPELLCLICK); device->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_SPELLCLICK);
device->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); device->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
@@ -255,7 +274,7 @@ struct boss_flame_leviathan_seatAI : public PassiveAI
if (apply) if (apply)
return; return;
if (Unit *device = vehicle->GetPassenger(SEAT_DEVICE)) if (Unit* device = vehicle->GetPassenger(SEAT_DEVICE))
{ {
device->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_SPELLCLICK); device->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_SPELLCLICK);
device->SetUInt32Value(UNIT_FIELD_FLAGS, 0); // unselectable device->SetUInt32Value(UNIT_FIELD_FLAGS, 0); // unselectable
@@ -268,7 +287,7 @@ struct boss_flame_leviathan_defense_turretAI : public TurretAI
{ {
boss_flame_leviathan_defense_turretAI(Creature *c) : TurretAI(c) {} boss_flame_leviathan_defense_turretAI(Creature *c) : TurretAI(c) {}
void DamageTaken(Unit *who, uint32 &damage) void DamageTaken(Unit* who, uint32 &damage)
{ {
if (!CanAIAttack(who)) if (!CanAIAttack(who))
damage = 0; damage = 0;
@@ -284,7 +303,7 @@ struct boss_flame_leviathan_defense_turretAI : public TurretAI
struct boss_flame_leviathan_overload_deviceAI : public PassiveAI struct boss_flame_leviathan_overload_deviceAI : public PassiveAI
{ {
boss_flame_leviathan_overload_deviceAI(Creature *c) : PassiveAI(c) {} boss_flame_leviathan_overload_deviceAI(Creature* pCreature) : PassiveAI(pCreature) {}
void DoAction(const int32 param) void DoAction(const int32 param)
{ {
@@ -294,12 +313,12 @@ struct boss_flame_leviathan_overload_deviceAI : public PassiveAI
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
if (me->GetVehicle()) if (me->GetVehicle())
{ {
if (Unit *player = me->GetVehicle()->GetPassenger(SEAT_PLAYER)) if (Unit* pPlayer = me->GetVehicle()->GetPassenger(SEAT_PLAYER))
{ {
player->ExitVehicle(); pPlayer->ExitVehicle();
me->GetVehicleBase()->CastSpell(player, SPELL_SMOKE_TRAIL, true); me->GetVehicleBase()->CastSpell(pPlayer, SPELL_SMOKE_TRAIL, true);
if (Unit *leviathan = me->GetVehicleBase()->GetVehicleBase()) if (Unit* leviathan = me->GetVehicleBase()->GetVehicleBase())
player->GetMotionMaster()->MoveKnockbackFrom(leviathan->GetPositionX(), leviathan->GetPositionY(), 30, 30); pPlayer->GetMotionMaster()->MoveKnockbackFrom(leviathan->GetPositionX(), leviathan->GetPositionY(), 30, 30);
} }
} }
} }
@@ -314,8 +333,8 @@ struct boss_flame_leviathan_safety_containerAI : public PassiveAI
{ {
if (id == me->GetEntry()) if (id == me->GetEntry())
{ {
if (Creature *liquid = DoSummon(MOB_LIQUID, me, 0)) if (Creature* pLiquid = DoSummon(MOB_LIQUID, me, 0))
liquid->CastSpell(liquid, 62494, true); pLiquid->CastSpell(pLiquid, 62494, true);
me->DisappearAndDie(); // this will relocate creature to sky me->DisappearAndDie(); // this will relocate creature to sky
} }
} }
@@ -346,6 +365,32 @@ struct spell_pool_of_tarAI : public TriggerAI
} }
}; };
struct npc_colossusAI : public ScriptedAI
{
npc_colossusAI(Creature* pCreature) : ScriptedAI(pCreature)
{
pInstance = pCreature->GetInstanceData();
}
ScriptedInstance *pInstance;
Position pPos;
void JustDied(Unit* /*Who*/)
{
if (me->GetHomePosition().IsInDist(Center,50.f))
{
if (pInstance)
pInstance->SetData(TYPE_COLOSSUS,pInstance->GetData(TYPE_COLOSSUS)+1);
}
}
void UpdateAI(const uint32 diff)
{
if (!UpdateVictim())
return;
}
};
CreatureAI* GetAI_boss_flame_leviathan(Creature* pCreature) CreatureAI* GetAI_boss_flame_leviathan(Creature* pCreature)
{ {
return new boss_flame_leviathanAI (pCreature); return new boss_flame_leviathanAI (pCreature);
@@ -376,6 +421,11 @@ CreatureAI* GetAI_spell_pool_of_tar(Creature* pCreature)
return new spell_pool_of_tarAI (pCreature); return new spell_pool_of_tarAI (pCreature);
} }
CreatureAI* GetAI_npc_colossus(Creature* pCreature)
{
return new npc_colossusAI(pCreature);
}
void AddSC_boss_flame_leviathan() void AddSC_boss_flame_leviathan()
{ {
Script *newscript; Script *newscript;
@@ -408,4 +458,9 @@ void AddSC_boss_flame_leviathan()
newscript->Name = "spell_pool_of_tar"; newscript->Name = "spell_pool_of_tar";
newscript->GetAI = &GetAI_spell_pool_of_tar; newscript->GetAI = &GetAI_spell_pool_of_tar;
newscript->RegisterSelf(); newscript->RegisterSelf();
newscript = new Script;
newscript->Name = "npc_colossus";
newscript->GetAI = &GetAI_npc_colossus;
newscript->RegisterSelf();
} }
@@ -29,6 +29,8 @@ enum eGameObjects
GO_Hodir_CHEST = 194307, GO_Hodir_CHEST = 194307,
GO_Freya_CHEST_HERO = 194325, GO_Freya_CHEST_HERO = 194325,
GO_Freya_CHEST = 194324, GO_Freya_CHEST = 194324,
GO_LEVIATHAN_DOOR = 194905,
GO_LEVIATHAN_GATE = 194630
}; };
struct instance_ulduar : public ScriptedInstance struct instance_ulduar : public ScriptedInstance
@@ -37,6 +39,7 @@ struct instance_ulduar : public ScriptedInstance
uint32 m_auiEncounter[MAX_ENCOUNTER]; uint32 m_auiEncounter[MAX_ENCOUNTER];
std::string m_strInstData; std::string m_strInstData;
uint8 flag;
uint64 m_uiLeviathanGUID; uint64 m_uiLeviathanGUID;
uint64 m_uiIgnisGUID; uint64 m_uiIgnisGUID;
@@ -52,6 +55,8 @@ struct instance_ulduar : public ScriptedInstance
uint64 m_uiVezaxGUID; uint64 m_uiVezaxGUID;
uint64 m_uiYoggSaronGUID; uint64 m_uiYoggSaronGUID;
uint64 m_uiAlgalonGUID; uint64 m_uiAlgalonGUID;
uint64 m_uiLeviathanDoor[7];
uint64 m_uiLeviathanGateGUID;
GameObject* KologarnChest, *ThorimChest, *HodirChest, *FreyaChest; GameObject* KologarnChest, *ThorimChest, *HodirChest, *FreyaChest;
@@ -74,9 +79,12 @@ struct instance_ulduar : public ScriptedInstance
ThorimChest = 0; ThorimChest = 0;
HodirChest = 0; HodirChest = 0;
FreyaChest = 0; FreyaChest = 0;
m_uiLeviathanGateGUID = 0;
flag = 0;
memset(&m_auiEncounter, 0, sizeof(m_auiEncounter)); memset(&m_auiEncounter, 0, sizeof(m_auiEncounter));
memset(&m_auiAssemblyGUIDs, 0, sizeof(m_auiAssemblyGUIDs)); memset(&m_auiAssemblyGUIDs, 0, sizeof(m_auiAssemblyGUIDs));
memset(&m_uiLeviathanDoor, 0, sizeof(m_uiLeviathanDoor));
} }
bool IsEncounterInProgress() const bool IsEncounterInProgress() const
@@ -161,6 +169,17 @@ struct instance_ulduar : public ScriptedInstance
case GO_Hodir_CHEST: HodirChest = add ? pGo : NULL; break; case GO_Hodir_CHEST: HodirChest = add ? pGo : NULL; break;
case GO_Freya_CHEST_HERO: FreyaChest = add ? pGo : NULL; break; case GO_Freya_CHEST_HERO: FreyaChest = add ? pGo : NULL; break;
case GO_Freya_CHEST: FreyaChest = add ? pGo : NULL; break; case GO_Freya_CHEST: FreyaChest = add ? pGo : NULL; break;
case GO_LEVIATHAN_DOOR:
m_uiLeviathanDoor[flag] = pGo->GetGUID();
HandleGameObject(NULL, true, pGo);
flag++;
if (flag == 7)
flag =0;
break;
case GO_LEVIATHAN_GATE:
m_uiLeviathanGateGUID = pGo->GetGUID();
HandleGameObject(NULL, false, pGo);
break;
} }
} }
@@ -169,6 +188,26 @@ struct instance_ulduar : public ScriptedInstance
switch(type) switch(type)
{ {
case TYPE_LEVIATHAN: case TYPE_LEVIATHAN:
if (data == IN_PROGRESS)
{
HandleGameObject(m_uiLeviathanDoor[0],false);
HandleGameObject(m_uiLeviathanDoor[1],false);
HandleGameObject(m_uiLeviathanDoor[2],false);
HandleGameObject(m_uiLeviathanDoor[3],false);
HandleGameObject(m_uiLeviathanDoor[4],false);
HandleGameObject(m_uiLeviathanDoor[5],false);
HandleGameObject(m_uiLeviathanDoor[6],false);
}
else
{
HandleGameObject(m_uiLeviathanDoor[0],true);
HandleGameObject(m_uiLeviathanDoor[1],true);
HandleGameObject(m_uiLeviathanDoor[2],true);
HandleGameObject(m_uiLeviathanDoor[3],true);
HandleGameObject(m_uiLeviathanDoor[4],true);
HandleGameObject(m_uiLeviathanDoor[5],true);
HandleGameObject(m_uiLeviathanDoor[6],true);
}
case TYPE_IGNIS: case TYPE_IGNIS:
case TYPE_RAZORSCALE: case TYPE_RAZORSCALE:
case TYPE_XT002: case TYPE_XT002:
@@ -195,6 +234,15 @@ struct instance_ulduar : public ScriptedInstance
case TYPE_YOGGSARON: case TYPE_YOGGSARON:
case TYPE_ALGALON: case TYPE_ALGALON:
m_auiEncounter[type] = data; m_auiEncounter[type] = data;
case TYPE_COLOSSUS:
m_auiEncounter[TYPE_COLOSSUS] = data;
if (data == 2)
{
if (Creature* pBoss = instance->GetCreature(m_uiLeviathanGUID))
pBoss->AI()->DoAction(1);
if (GameObject* pGate = instance->GetGameObject(m_uiLeviathanGateGUID))
pGate->SetGoState(GO_STATE_ACTIVE_ALTERNATIVE);
}
break; break;
} }
@@ -218,40 +266,24 @@ struct instance_ulduar : public ScriptedInstance
{ {
switch(data) switch(data)
{ {
case TYPE_LEVIATHAN: case TYPE_LEVIATHAN: return m_uiLeviathanGUID;
return m_uiLeviathanGUID; case TYPE_IGNIS: return m_uiIgnisGUID;
case TYPE_IGNIS: case TYPE_RAZORSCALE: return m_uiRazorscaleGUID;
return m_uiIgnisGUID; case TYPE_XT002: return m_uiXT002GUID;
case TYPE_RAZORSCALE: case TYPE_KOLOGARN: return m_uiKologarnGUID;
return m_uiRazorscaleGUID; case TYPE_AURIAYA: return m_uiAuriayaGUID;
case TYPE_XT002: case TYPE_MIMIRON: return m_uiMimironGUID;
return m_uiXT002GUID; case TYPE_HODIR: return m_uiMimironGUID;
case TYPE_KOLOGARN: case TYPE_THORIM: return m_uiThorimGUID;
return m_uiKologarnGUID; case TYPE_FREYA: return m_uiFreyaGUID;
case TYPE_AURIAYA: case TYPE_VEZAX: return m_uiVezaxGUID;
return m_uiAuriayaGUID; case TYPE_YOGGSARON: return m_uiYoggSaronGUID;
case TYPE_MIMIRON: case TYPE_ALGALON: return m_uiAlgalonGUID;
return m_uiMimironGUID;
case TYPE_HODIR:
return m_uiMimironGUID;
case TYPE_THORIM:
return m_uiThorimGUID;
case TYPE_FREYA:
return m_uiFreyaGUID;
case TYPE_VEZAX:
return m_uiVezaxGUID;
case TYPE_YOGGSARON:
return m_uiYoggSaronGUID;
case TYPE_ALGALON:
return m_uiAlgalonGUID;
// Assembly of Iron // Assembly of Iron
case DATA_STEELBREAKER: case DATA_STEELBREAKER: return m_auiAssemblyGUIDs[0];
return m_auiAssemblyGUIDs[0]; case DATA_MOLGEIM: return m_auiAssemblyGUIDs[1];
case DATA_MOLGEIM: case DATA_BRUNDIR: return m_auiAssemblyGUIDs[2];
return m_auiAssemblyGUIDs[1];
case DATA_BRUNDIR:
return m_auiAssemblyGUIDs[2];
} }
return 0; return 0;
@@ -275,6 +307,7 @@ struct instance_ulduar : public ScriptedInstance
case TYPE_VEZAX: case TYPE_VEZAX:
case TYPE_YOGGSARON: case TYPE_YOGGSARON:
case TYPE_ALGALON: case TYPE_ALGALON:
case TYPE_COLOSSUS:
return m_auiEncounter[type]; return m_auiEncounter[type];
} }
@@ -289,7 +322,7 @@ struct instance_ulduar : public ScriptedInstance
saveStream << "U U " << m_auiEncounter[0] << " " << m_auiEncounter[1] << " " << m_auiEncounter[2] << " " << m_auiEncounter[3] saveStream << "U U " << m_auiEncounter[0] << " " << m_auiEncounter[1] << " " << m_auiEncounter[2] << " " << m_auiEncounter[3]
<< m_auiEncounter[4] << " " << m_auiEncounter[5] << " " << m_auiEncounter[6] << " " << m_auiEncounter[7] << m_auiEncounter[4] << " " << m_auiEncounter[5] << " " << m_auiEncounter[6] << " " << m_auiEncounter[7]
<< m_auiEncounter[8] << " " << m_auiEncounter[9] << " " << m_auiEncounter[10] << " " << m_auiEncounter[11] << m_auiEncounter[8] << " " << m_auiEncounter[9] << " " << m_auiEncounter[10] << " " << m_auiEncounter[11]
<< m_auiEncounter[12] << " " << m_auiEncounter[13]; << m_auiEncounter[12] << " " << m_auiEncounter[13] << " " << m_auiEncounter[14];
m_strInstData = saveStream.str(); m_strInstData = saveStream.str();
@@ -309,11 +342,11 @@ struct instance_ulduar : public ScriptedInstance
char dataHead1, dataHead2; char dataHead1, dataHead2;
uint32 data0, data1, data2, data3, data4, data5, data6, uint32 data0, data1, data2, data3, data4, data5, data6,
data7, data8, data9, data10, data11, data12, data13; data7, data8, data9, data10, data11, data12, data13, data14;
std::istringstream loadStream(strIn); std::istringstream loadStream(strIn);
loadStream >> dataHead1 >> dataHead2 >> data0 >> data1 >> data2 >> data3 >> data4 >> data5 >> data6 loadStream >> dataHead1 >> dataHead2 >> data0 >> data1 >> data2 >> data3 >> data4 >> data5 >> data6
>> data7 >> data8 >> data9 >> data10 >> data11 >> data12 >> data13; >> data7 >> data8 >> data9 >> data10 >> data11 >> data12 >> data13 >> data14;
if (dataHead1 == 'U' && dataHead2 == 'U') if (dataHead1 == 'U' && dataHead2 == 'U')
{ {
+2 -1
View File
@@ -21,7 +21,7 @@
enum eTypes enum eTypes
{ {
MAX_ENCOUNTER = 14, MAX_ENCOUNTER = 15,
TYPE_LEVIATHAN = 0, TYPE_LEVIATHAN = 0,
TYPE_IGNIS = 1, TYPE_IGNIS = 1,
@@ -37,6 +37,7 @@ enum eTypes
TYPE_VEZAX = 11, TYPE_VEZAX = 11,
TYPE_YOGGSARON = 12, TYPE_YOGGSARON = 12,
TYPE_ALGALON = 13, TYPE_ALGALON = 13,
TYPE_COLOSSUS = 14,
DATA_STEELBREAKER = 20, DATA_STEELBREAKER = 20,
DATA_MOLGEIM = 21, DATA_MOLGEIM = 21,