Scripts/Hellfire: Rework Blood Furnace

This commit is contained in:
Gacko
2012-08-29 22:23:15 +01:00
committed by Nay
parent b89b8ff277
commit e07a8db6da
5 changed files with 553 additions and 44 deletions

View File

@@ -39,5 +39,9 @@
#define DATA_PRISON_CELL6 18
#define DATA_PRISON_CELL7 19
#define DATA_PRISON_CELL8 20
#define DATA_BROGGOK_LEVER 21
#define ACTION_ACTIVATE_BROGGOK 22
#define ACTION_RESET_BROGGOK 23
#define ACTION_PREPARE_BROGGOK 24
#endif

View File

@@ -47,9 +47,9 @@ class boss_broggok : public CreatureScript
{
}
struct boss_broggokAI : public ScriptedAI
struct boss_broggokAI : public BossAI
{
boss_broggokAI(Creature* creature) : ScriptedAI(creature)
boss_broggokAI(Creature* creature) : BossAI(creature, DATA_BROGGOK)
{
instance = creature->GetInstanceScript();
}
@@ -59,27 +59,21 @@ class boss_broggok : public CreatureScript
uint32 AcidSpray_Timer;
uint32 PoisonSpawn_Timer;
uint32 PoisonBolt_Timer;
bool canAttack;
void Reset()
{
_Reset();
AcidSpray_Timer = 10000;
PoisonSpawn_Timer = 5000;
PoisonBolt_Timer = 7000;
if (instance)
{
instance->SetData(TYPE_BROGGOK_EVENT, NOT_STARTED);
instance->HandleGameObject(instance->GetData64(DATA_DOOR4), true);
}
DoAction(ACTION_RESET_BROGGOK);
instance->SetData(TYPE_BROGGOK_EVENT, NOT_STARTED);
}
void EnterCombat(Unit* /*who*/)
{
DoScriptText(SAY_AGGRO, me);
if (instance)
{
instance->SetData(TYPE_BROGGOK_EVENT, IN_PROGRESS);
instance->HandleGameObject(instance->GetData64(DATA_DOOR4), false);
}
}
void JustSummoned(Creature* summoned)
@@ -94,7 +88,8 @@ class boss_broggok : public CreatureScript
{
if (!UpdateVictim())
return;
if (!canAttack)
return;
if (AcidSpray_Timer <= diff)
{
DoCast(me->getVictim(), SPELL_SLIME_SPRAY);
@@ -132,6 +127,26 @@ class boss_broggok : public CreatureScript
}
}
void DoAction(int32 const action)
{
switch (action)
{
case ACTION_PREPARE_BROGGOK:
me->SetInCombatWithZone();
break;
case ACTION_ACTIVATE_BROGGOK:
me->SetReactState(REACT_AGGRESSIVE);
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC | UNIT_FLAG_IMMUNE_TO_NPC | UNIT_FLAG_NON_ATTACKABLE);
canAttack = true;
break;
case ACTION_RESET_BROGGOK:
me->SetReactState(REACT_PASSIVE);
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC | UNIT_FLAG_IMMUNE_TO_NPC | UNIT_FLAG_NON_ATTACKABLE);
canAttack = false;
break;
}
}
};
CreatureAI* GetAI(Creature* creature) const
@@ -140,7 +155,27 @@ class boss_broggok : public CreatureScript
}
};
class go_broggok_lever : public GameObjectScript
{
public:
go_broggok_lever() : GameObjectScript("go_broggok_lever") {}
bool OnGossipHello(Player* player, GameObject* go)
{
if (InstanceScript* instance = go->GetInstanceScript())
if (instance->GetData(TYPE_BROGGOK_EVENT) != DONE && instance->GetData(TYPE_BROGGOK_EVENT) != IN_PROGRESS)
{
instance->SetData(TYPE_BROGGOK_EVENT, IN_PROGRESS);
if (Creature* broggok = Creature::GetCreature(*go, instance->GetData64(DATA_BROGGOK)))
broggok->AI()->DoAction(ACTION_PREPARE_BROGGOK);
}
go->UseDoorOrButton();
return false;
}
};
void AddSC_boss_broggok()
{
new boss_broggok();
new go_broggok_lever();
}

View File

@@ -57,7 +57,9 @@ enum eKelidan
SPELL_VORTEX = 37370,
ENTRY_KELIDAN = 17377,
ENTRY_CHANNELER = 17653
ENTRY_CHANNELER = 17653,
ACTION_ACTIVATE_ADDS = 92
};
const float ShadowmoonChannelers[5][4]=
@@ -107,6 +109,8 @@ class boss_kelidan_the_breaker : public CreatureScript
Firenova = false;
addYell = false;
SummonChannelers();
me->SetReactState(REACT_PASSIVE);
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC | UNIT_FLAG_IMMUNE_TO_NPC | UNIT_FLAG_NON_ATTACKABLE);
if (instance)
instance->SetData(TYPE_KELIDAN_THE_BREAKER_EVENT, NOT_STARTED);
}
@@ -152,7 +156,8 @@ class boss_kelidan_the_breaker : public CreatureScript
if (channeler && channeler->isAlive())
return;
}
me->SetReactState(REACT_AGGRESSIVE);
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC | UNIT_FLAG_IMMUNE_TO_NPC | UNIT_FLAG_NON_ATTACKABLE);
if (killer)
me->AI()->AttackStart(killer);
}
@@ -269,7 +274,6 @@ class boss_kelidan_the_breaker : public CreatureScript
DoMeleeAttackIfReady();
}
};
CreatureAI* GetAI(Creature* creature) const
@@ -295,16 +299,11 @@ class mob_shadowmoon_channeler : public CreatureScript
{
public:
mob_shadowmoon_channeler()
: CreatureScript("mob_shadowmoon_channeler")
{
}
mob_shadowmoon_channeler() : CreatureScript("mob_shadowmoon_channeler") {}
struct mob_shadowmoon_channelerAI : public ScriptedAI
{
mob_shadowmoon_channelerAI(Creature* creature) : ScriptedAI(creature)
{
}
mob_shadowmoon_channelerAI(Creature* creature) : ScriptedAI(creature){}
uint32 ShadowBolt_Timer;
uint32 MarkOfShadow_Timer;

View File

@@ -35,9 +35,7 @@ class instance_blood_furnace : public InstanceMapScript
{
public:
instance_blood_furnace()
: InstanceMapScript("instance_blood_furnace", 542)
{
}
: InstanceMapScript("instance_blood_furnace", 542) {}
struct instance_blood_furnace_InstanceMapScript : public InstanceScript
{
@@ -63,6 +61,18 @@ class instance_blood_furnace : public InstanceMapScript
uint64 PrisonCell7GUID;
uint64 PrisonCell8GUID;
std::set<uint64> PrisonersCell5;
std::set<uint64> PrisonersCell6;
std::set<uint64> PrisonersCell7;
std::set<uint64> PrisonersCell8;
uint8 PrisonerCounter5;
uint8 PrisonerCounter6;
uint8 PrisonerCounter7;
uint8 PrisonerCounter8;
uint64 BroggokLeverGUID;
uint32 m_auiEncounter[MAX_ENCOUNTER];
std::string str_data;
@@ -89,24 +99,45 @@ class instance_blood_furnace : public InstanceMapScript
PrisonCell6GUID = 0;
PrisonCell7GUID = 0;
PrisonCell8GUID = 0;
PrisonersCell5.clear();
PrisonersCell6.clear();
PrisonersCell7.clear();
PrisonersCell8.clear();
PrisonerCounter5 = 0;
PrisonerCounter6 = 0;
PrisonerCounter7 = 0;
PrisonerCounter8 = 0;
BroggokLeverGUID = 0;
}
void OnCreatureCreate(Creature* creature)
{
switch (creature->GetEntry())
{
case 17381:
The_MakerGUID = creature->GetGUID();
break;
case 17380:
BroggokGUID = creature->GetGUID();
break;
case 17377:
Kelidan_The_BreakerGUID = creature->GetGUID();
break;
case 17381:
The_MakerGUID = creature->GetGUID();
break;
case 17380:
BroggokGUID = creature->GetGUID();
break;
case 17377:
Kelidan_The_BreakerGUID = creature->GetGUID();
break;
case 17398:
StorePrisoner(creature);
break;
}
}
void OnCreatureDeath(Creature* unit)
{
if (unit && unit->GetTypeId() == TYPEID_UNIT && unit->GetEntry() == 17398)
PrisonerDied(unit->GetGUID());
}
void OnGameObjectCreate(GameObject* go)
{
if (go->GetEntry() == 181766) //Final exit door
@@ -138,6 +169,9 @@ class instance_blood_furnace : public InstanceMapScript
PrisonCell7GUID = go->GetGUID();
if (go->GetEntry() == 181817) //Broggok prison cell back left
PrisonCell8GUID = go->GetGUID();
if (go->GetEntry() == 181982)
BroggokLeverGUID = go->GetGUID(); //Broggok lever
}
uint64 GetData64(uint32 data)
@@ -161,18 +195,25 @@ class instance_blood_furnace : public InstanceMapScript
case DATA_PRISON_CELL6: return PrisonCell6GUID;
case DATA_PRISON_CELL7: return PrisonCell7GUID;
case DATA_PRISON_CELL8: return PrisonCell8GUID;
case DATA_BROGGOK_LEVER: return BroggokLeverGUID;
}
return 0;
}
void SetData(uint32 /*type*/, uint32 data)
void SetData(uint32 type, uint32 data)
{
switch (data)
switch (type)
{
case TYPE_THE_MAKER_EVENT: m_auiEncounter[0] = data; break;
case TYPE_BROGGOK_EVENT: m_auiEncounter[1] = data; break;
case TYPE_KELIDAN_THE_BREAKER_EVENT: m_auiEncounter[2] = data; break;
case TYPE_THE_MAKER_EVENT:
m_auiEncounter[0] = data;
break;
case TYPE_BROGGOK_EVENT:
m_auiEncounter[1] = data;
UpdateBroggokEvent(data);
break;
case TYPE_KELIDAN_THE_BREAKER_EVENT:
m_auiEncounter[2] = data;
break;
}
if (data == DONE)
@@ -189,15 +230,14 @@ class instance_blood_furnace : public InstanceMapScript
}
}
uint32 GetData(uint32 data)
uint32 GetData(uint32 type)
{
switch (data)
switch (type)
{
case TYPE_THE_MAKER_EVENT: return m_auiEncounter[0];
case TYPE_BROGGOK_EVENT: return m_auiEncounter[1];
case TYPE_KELIDAN_THE_BREAKER_EVENT: return m_auiEncounter[2];
}
return 0;
}
@@ -225,6 +265,147 @@ class instance_blood_furnace : public InstanceMapScript
OUT_LOAD_INST_DATA_COMPLETE;
}
void UpdateBroggokEvent(uint32 data)
{
switch (data)
{
case IN_PROGRESS:
ActivateCell(DATA_PRISON_CELL5);
HandleGameObject(Door4GUID, false);
break;
case NOT_STARTED:
ResetPrisons();
HandleGameObject(Door5GUID, false);
HandleGameObject(Door4GUID, true);
if (GameObject* lever = instance->GetGameObject(BroggokLeverGUID))
lever->Respawn();
break;
}
}
void ResetPrisons()
{
PrisonerCounter5 = PrisonersCell5.size();
ResetPrisoners(PrisonersCell5);
HandleGameObject(PrisonCell5GUID, false);
PrisonerCounter6 = PrisonersCell6.size();
ResetPrisoners(PrisonersCell6);
HandleGameObject(PrisonCell6GUID, false);
PrisonerCounter7 = PrisonersCell7.size();
ResetPrisoners(PrisonersCell7);
HandleGameObject(PrisonCell7GUID, false);
PrisonerCounter8 = PrisonersCell8.size();
ResetPrisoners(PrisonersCell8);
HandleGameObject(PrisonCell8GUID, false);
}
void ResetPrisoners(std::set<uint64> prisoners)
{
for (std::set<uint64>::iterator i = prisoners.begin(); i != prisoners.end(); ++i)
if (Creature* prisoner = instance->GetCreature(*i))
ResetPrisoner(prisoner);
}
void ResetPrisoner(Creature* prisoner)
{
if (!prisoner->isAlive())
prisoner->Respawn(true);
prisoner->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC | UNIT_FLAG_IMMUNE_TO_NPC | UNIT_FLAG_NON_ATTACKABLE);
}
void StorePrisoner(Creature* creature)
{
float posX = creature->GetPositionX();
float posY = creature->GetPositionY();
if (posX >= 405.0f && posX <= 423.0f)
{
if (posY >= 106.0f && posY <= 123.0f)
{
PrisonersCell5.insert(creature->GetGUID());
++PrisonerCounter5;
}
else if (posY >= 76.0f && posY <= 91.0f)
{
PrisonersCell6.insert(creature->GetGUID());
++PrisonerCounter6;
}
else return;
}
else if (posX >= 490.0f && posX <= 506.0f)
{
if (posY >= 106.0f && posY <= 123.0f)
{
PrisonersCell7.insert(creature->GetGUID());
++PrisonerCounter7;
}
else if (posY >= 76.0f && posY <= 91.0f)
{
PrisonersCell8.insert(creature->GetGUID());
++PrisonerCounter8;
}
else
return;
}
else
return;
ResetPrisoner(creature);
}
void PrisonerDied(uint64 guid)
{
if (PrisonersCell5.find(guid) != PrisonersCell5.end() && --PrisonerCounter5 <= 0)
ActivateCell(DATA_PRISON_CELL6);
else if (PrisonersCell6.find(guid) != PrisonersCell6.end() && --PrisonerCounter6 <= 0)
ActivateCell(DATA_PRISON_CELL7);
else if (PrisonersCell7.find(guid) != PrisonersCell7.end() && --PrisonerCounter7 <= 0)
ActivateCell(DATA_PRISON_CELL8);
else if (PrisonersCell8.find(guid) != PrisonersCell8.end() && --PrisonerCounter8 <= 0)
ActivateCell(DATA_DOOR5);
}
void ActivateCell(uint8 id)
{
switch (id)
{
case DATA_PRISON_CELL5:
HandleGameObject(PrisonCell5GUID,true);
ActivatePrisoners(PrisonersCell5);
break;
case DATA_PRISON_CELL6:
HandleGameObject(PrisonCell6GUID,true);
ActivatePrisoners(PrisonersCell6);
break;
case DATA_PRISON_CELL7:
HandleGameObject(PrisonCell7GUID,true);
ActivatePrisoners(PrisonersCell7);
break;
case DATA_PRISON_CELL8:
HandleGameObject(PrisonCell8GUID,true);
ActivatePrisoners(PrisonersCell8);
break;
case DATA_DOOR5:
HandleGameObject(Door5GUID,true);
if (Creature* broggok = instance->GetCreature(BroggokGUID))
broggok->AI()->DoAction(ACTION_ACTIVATE_BROGGOK);
break;
}
}
void ActivatePrisoners(std::set<uint64> prisoners)
{
for (std::set<uint64>::iterator i = prisoners.begin(); i != prisoners.end(); ++i)
if (Creature* prisoner = instance->GetCreature(*i))
{
prisoner->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC | UNIT_FLAG_IMMUNE_TO_NPC | UNIT_FLAG_NON_ATTACKABLE);
prisoner->SetInCombatWithZone();
}
}
};
InstanceScript* GetInstanceScript(InstanceMap* map) const