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

View File

@@ -87,22 +87,30 @@ enum Yells
SAY_OVERLOAD_3 = -1603075,
};
static Position Center[]=
{
{354.8771, -12.90240, 409.803650},
};
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);
pInstance = pCreature->GetInstanceData();
}
Vehicle *vehicle;
Vehicle* vehicle;
ScriptedInstance* pInstance;
void Reset()
{
_Reset();
me->SetReactState(REACT_AGGRESSIVE);
pInstance->SetData(TYPE_LEVIATHAN, NOT_STARTED);
}
void EnterCombat(Unit * /*who*/)
void EnterCombat(Unit* /*who*/)
{
_EnterCombat();
DoScriptText(SAY_AGGRO, me);
@@ -114,31 +122,43 @@ struct boss_flame_leviathanAI : public BossAI
events.ScheduleEvent(EVENT_SUMMON, 0);
//events.ScheduleEvent(EVENT_MIMIRON_INFERNO, 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)))
turret->AI()->DoZoneInCombat();
}
// 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);
}
void JustDied(Unit * /*victim*/)
void JustDied(Unit* /*victim*/)
{
pInstance->SetData(TYPE_LEVIATHAN, DONE);
DoScriptText(SAY_DEATH, me);
_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();
else if (spell->Id == SPELL_ELECTROSHOCK)
else if (pSpell->Id == SPELL_ELECTROSHOCK)
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)
{
if (!me->isInCombat())
@@ -184,8 +204,8 @@ struct boss_flame_leviathanAI : public BossAI
return;
case EVENT_SUMMON:
if (summons.size() < 15) // 4seat+1turret+10lift
if (Creature *lift = DoSummonFlyer(MOB_MECHANOLIFT, me, urand(20,40), 50, 0))
lift->GetMotionMaster()->MoveRandom(100);
if (Creature* pLift = DoSummonFlyer(MOB_MECHANOLIFT, me, urand(20,40), 50, 0))
pLift->GetMotionMaster()->MoveRandom(100);
events.RepeatEvent(2000);
return;
case EVENT_MIMIRON_INFERNO: // Not Blizzlike
@@ -200,7 +220,6 @@ struct boss_flame_leviathanAI : public BossAI
events.PopEvent();
break;
}
DoSpellAttackIfReady(SPELL_BATTERING_RAM);
}
};
@@ -217,7 +236,7 @@ struct boss_flame_leviathan_seatAI : public PassiveAI
#endif
}
Vehicle *vehicle;
Vehicle* vehicle;
#ifdef BOSS_DEBUG
void MoveInLineOfSight(Unit *who)
@@ -228,7 +247,7 @@ struct boss_flame_leviathan_seatAI : public PassiveAI
}
#endif
void PassengerBoarded(Unit *who, int8 seatId, bool apply)
void PassengerBoarded(Unit* who, int8 seatId, bool apply)
{
if (!me->GetVehicle())
return;
@@ -238,13 +257,13 @@ struct boss_flame_leviathan_seatAI : public PassiveAI
if (!apply)
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->SetUInt32Value(UNIT_FIELD_FLAGS, 0); // unselectable
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->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
@@ -255,7 +274,7 @@ struct boss_flame_leviathan_seatAI : public PassiveAI
if (apply)
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->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) {}
void DamageTaken(Unit *who, uint32 &damage)
void DamageTaken(Unit* who, uint32 &damage)
{
if (!CanAIAttack(who))
damage = 0;
@@ -284,7 +303,7 @@ struct boss_flame_leviathan_defense_turretAI : public TurretAI
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)
{
@@ -294,12 +313,12 @@ struct boss_flame_leviathan_overload_deviceAI : public PassiveAI
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
if (me->GetVehicle())
{
if (Unit *player = me->GetVehicle()->GetPassenger(SEAT_PLAYER))
if (Unit* pPlayer = me->GetVehicle()->GetPassenger(SEAT_PLAYER))
{
player->ExitVehicle();
me->GetVehicleBase()->CastSpell(player, SPELL_SMOKE_TRAIL, true);
if (Unit *leviathan = me->GetVehicleBase()->GetVehicleBase())
player->GetMotionMaster()->MoveKnockbackFrom(leviathan->GetPositionX(), leviathan->GetPositionY(), 30, 30);
pPlayer->ExitVehicle();
me->GetVehicleBase()->CastSpell(pPlayer, SPELL_SMOKE_TRAIL, true);
if (Unit* leviathan = me->GetVehicleBase()->GetVehicleBase())
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 (Creature *liquid = DoSummon(MOB_LIQUID, me, 0))
liquid->CastSpell(liquid, 62494, true);
if (Creature* pLiquid = DoSummon(MOB_LIQUID, me, 0))
pLiquid->CastSpell(pLiquid, 62494, true);
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)
{
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);
}
CreatureAI* GetAI_npc_colossus(Creature* pCreature)
{
return new npc_colossusAI(pCreature);
}
void AddSC_boss_flame_leviathan()
{
Script *newscript;
@@ -408,4 +458,9 @@ void AddSC_boss_flame_leviathan()
newscript->Name = "spell_pool_of_tar";
newscript->GetAI = &GetAI_spell_pool_of_tar;
newscript->RegisterSelf();
newscript = new Script;
newscript->Name = "npc_colossus";
newscript->GetAI = &GetAI_npc_colossus;
newscript->RegisterSelf();
}

View File

@@ -29,6 +29,8 @@ enum eGameObjects
GO_Hodir_CHEST = 194307,
GO_Freya_CHEST_HERO = 194325,
GO_Freya_CHEST = 194324,
GO_LEVIATHAN_DOOR = 194905,
GO_LEVIATHAN_GATE = 194630
};
struct instance_ulduar : public ScriptedInstance
@@ -37,6 +39,7 @@ struct instance_ulduar : public ScriptedInstance
uint32 m_auiEncounter[MAX_ENCOUNTER];
std::string m_strInstData;
uint8 flag;
uint64 m_uiLeviathanGUID;
uint64 m_uiIgnisGUID;
@@ -51,7 +54,9 @@ struct instance_ulduar : public ScriptedInstance
uint64 m_uiFreyaGUID;
uint64 m_uiVezaxGUID;
uint64 m_uiYoggSaronGUID;
uint64 m_uiAlgalonGUID;
uint64 m_uiAlgalonGUID;
uint64 m_uiLeviathanDoor[7];
uint64 m_uiLeviathanGateGUID;
GameObject* KologarnChest, *ThorimChest, *HodirChest, *FreyaChest;
@@ -74,9 +79,12 @@ struct instance_ulduar : public ScriptedInstance
ThorimChest = 0;
HodirChest = 0;
FreyaChest = 0;
m_uiLeviathanGateGUID = 0;
flag = 0;
memset(&m_auiEncounter, 0, sizeof(m_auiEncounter));
memset(&m_auiAssemblyGUIDs, 0, sizeof(m_auiAssemblyGUIDs));
memset(&m_uiLeviathanDoor, 0, sizeof(m_uiLeviathanDoor));
}
bool IsEncounterInProgress() const
@@ -161,6 +169,17 @@ struct instance_ulduar : public ScriptedInstance
case GO_Hodir_CHEST: HodirChest = 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_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)
{
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_RAZORSCALE:
case TYPE_XT002:
@@ -195,6 +234,15 @@ struct instance_ulduar : public ScriptedInstance
case TYPE_YOGGSARON:
case TYPE_ALGALON:
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;
}
@@ -218,40 +266,24 @@ struct instance_ulduar : public ScriptedInstance
{
switch(data)
{
case TYPE_LEVIATHAN:
return m_uiLeviathanGUID;
case TYPE_IGNIS:
return m_uiIgnisGUID;
case TYPE_RAZORSCALE:
return m_uiRazorscaleGUID;
case TYPE_XT002:
return m_uiXT002GUID;
case TYPE_KOLOGARN:
return m_uiKologarnGUID;
case TYPE_AURIAYA:
return m_uiAuriayaGUID;
case TYPE_MIMIRON:
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;
case TYPE_LEVIATHAN: return m_uiLeviathanGUID;
case TYPE_IGNIS: return m_uiIgnisGUID;
case TYPE_RAZORSCALE: return m_uiRazorscaleGUID;
case TYPE_XT002: return m_uiXT002GUID;
case TYPE_KOLOGARN: return m_uiKologarnGUID;
case TYPE_AURIAYA: return m_uiAuriayaGUID;
case TYPE_MIMIRON: 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
case DATA_STEELBREAKER:
return m_auiAssemblyGUIDs[0];
case DATA_MOLGEIM:
return m_auiAssemblyGUIDs[1];
case DATA_BRUNDIR:
return m_auiAssemblyGUIDs[2];
case DATA_STEELBREAKER: return m_auiAssemblyGUIDs[0];
case DATA_MOLGEIM: return m_auiAssemblyGUIDs[1];
case DATA_BRUNDIR: return m_auiAssemblyGUIDs[2];
}
return 0;
@@ -275,6 +307,7 @@ struct instance_ulduar : public ScriptedInstance
case TYPE_VEZAX:
case TYPE_YOGGSARON:
case TYPE_ALGALON:
case TYPE_COLOSSUS:
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]
<< 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[12] << " " << m_auiEncounter[13];
<< m_auiEncounter[12] << " " << m_auiEncounter[13] << " " << m_auiEncounter[14];
m_strInstData = saveStream.str();
@@ -309,11 +342,11 @@ struct instance_ulduar : public ScriptedInstance
char dataHead1, dataHead2;
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);
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')
{

View File

@@ -21,7 +21,7 @@
enum eTypes
{
MAX_ENCOUNTER = 14,
MAX_ENCOUNTER = 15,
TYPE_LEVIATHAN = 0,
TYPE_IGNIS = 1,
@@ -37,6 +37,7 @@ enum eTypes
TYPE_VEZAX = 11,
TYPE_YOGGSARON = 12,
TYPE_ALGALON = 13,
TYPE_COLOSSUS = 14,
DATA_STEELBREAKER = 20,
DATA_MOLGEIM = 21,