fix(Scripts/ZulFarrak): Moved Sergeant Bly's script from DB to C++ (#7855)
This commit is contained in:
@@ -0,0 +1,15 @@
|
|||||||
|
INSERT INTO `version_db_world` (`sql_rev`) VALUES ('1631560059547242900');
|
||||||
|
|
||||||
|
UPDATE `creature_template` SET `AIName`="", `ScriptName`="npc_sergeant_bly" WHERE `entry`=7604;
|
||||||
|
UPDATE `creature_template` SET `AIName`="", `ScriptName`="npc_weegli_blastfuse" WHERE `entry`=7607;
|
||||||
|
UPDATE `gameobject_template` SET `AIName`="", `ScriptName`="go_troll_cage" WHERE `entry` BETWEEN 141070 AND 141074;
|
||||||
|
UPDATE `creature_template` SET `AIName`="", `ScriptName`="npc_shadowpriest_sezziz" WHERE `entry`=7275;
|
||||||
|
|
||||||
|
DELETE FROM `gossip_menu_option` WHERE `MenuId` IN (940,941);
|
||||||
|
DELETE FROM `conditions` WHERE `Sourcetypeorreferenceid` IN (14,15) AND `SourceGroup` IN (940,941);
|
||||||
|
|
||||||
|
DELETE FROM `smart_scripts` WHERE `entryorguid` IN (7604,7607,7275);
|
||||||
|
DELETE FROM `smart_scripts` WHERE `entryorguid` BETWEEN 760400 AND 760403;
|
||||||
|
DELETE FROM `smart_scripts` WHERE `entryorguid` BETWEEN 141070 AND 141074;
|
||||||
|
|
||||||
|
DELETE FROM `creature_summon_groups` WHERE `summonerId`=7604;
|
||||||
@@ -9,10 +9,87 @@
|
|||||||
#include "TemporarySummon.h"
|
#include "TemporarySummon.h"
|
||||||
#include "zulfarrak.h"
|
#include "zulfarrak.h"
|
||||||
|
|
||||||
|
enum Misc
|
||||||
|
{
|
||||||
|
// Paths
|
||||||
|
PATH_ADDS = 81553,
|
||||||
|
|
||||||
|
SAY_BLY_FORWARD = 2
|
||||||
|
};
|
||||||
|
|
||||||
|
struct PyramidEventData
|
||||||
|
{
|
||||||
|
uint8 waveID = 0;
|
||||||
|
uint32 creatureID = 0;
|
||||||
|
Position pos;
|
||||||
|
};
|
||||||
|
|
||||||
|
uint32 const pyramidSpawnTotal = 54;
|
||||||
|
|
||||||
|
/* list of wave spawns: 0 = wave ID, 1 = creature id, 2 = x, 3 = y
|
||||||
|
no z coordinat b/c they're all the same */
|
||||||
|
static PyramidEventData pyramidSpawns[pyramidSpawnTotal] =
|
||||||
|
{
|
||||||
|
{ 1, NPC_SANDFURY_CRETIN, { 1894.64f, 1206.29f } },
|
||||||
|
{ 1, NPC_SANDFURY_SLAVE, { 1890.08f, 1218.68f } },
|
||||||
|
{ 1, NPC_SANDFURY_ACOLYTE, { 1883.76f, 1222.30f } },
|
||||||
|
{ 1, NPC_SANDFURY_CRETIN, { 1874.18f, 1221.24f } },
|
||||||
|
{ 1, NPC_SANDFURY_SLAVE, { 1892.28f, 1225.49f } },
|
||||||
|
{ 1, NPC_SANDFURY_DRUDGE, { 1889.94f, 1212.21f } },
|
||||||
|
{ 1, NPC_SANDFURY_SLAVE, { 1879.02f, 1223.06f } },
|
||||||
|
{ 1, NPC_SANDFURY_CRETIN, { 1874.45f, 1204.44f } },
|
||||||
|
{ 1, NPC_SANDFURY_ACOLYTE, { 1898.23f, 1217.97f } },
|
||||||
|
{ 1, NPC_SANDFURY_SLAVE, { 1882.07f, 1225.70f } },
|
||||||
|
{ 1, NPC_SANDFURY_ZEALOT, { 1896.46f, 1205.62f } },
|
||||||
|
{ 1, NPC_SANDFURY_SLAVE, { 1886.97f, 1225.86f } },
|
||||||
|
{ 1, NPC_SANDFURY_SLAVE, { 1894.72f, 1221.91f } },
|
||||||
|
{ 1, NPC_SANDFURY_SLAVE, { 1883.50f, 1218.25f } },
|
||||||
|
{ 1, NPC_SANDFURY_SLAVE, { 1886.93f, 1221.40f } },
|
||||||
|
{ 1, NPC_SANDFURY_ACOLYTE, { 1889.82f, 1222.51f } },
|
||||||
|
{ 1, NPC_SANDFURY_DRUDGE, { 1893.07f, 1215.26f } },
|
||||||
|
{ 1, NPC_SANDFURY_DRUDGE, { 1878.57f, 1214.16f } },
|
||||||
|
{ 1, NPC_SANDFURY_DRUDGE, { 1883.74f, 1212.35f } },
|
||||||
|
{ 1, NPC_SANDFURY_ZEALOT, { 1877.00f, 1207.27f } },
|
||||||
|
{ 1, NPC_SANDFURY_ZEALOT, { 1873.63f, 1204.65f } },
|
||||||
|
{ 1, NPC_SANDFURY_ACOLYTE, { 1877.40f, 1216.41f } },
|
||||||
|
{ 1, NPC_SANDFURY_ZEALOT, { 1899.63f, 1202.52f } },
|
||||||
|
{ 2, NPC_SANDFURY_CRETIN, { 1902.83f, 1223.41f } },
|
||||||
|
{ 2, NPC_SANDFURY_ACOLYTE, { 1889.82f, 1222.51f } },
|
||||||
|
{ 2, NPC_SANDFURY_SLAVE, { 1883.50f, 1218.25f } },
|
||||||
|
{ 2, NPC_SANDFURY_DRUDGE, { 1883.74f, 1212.35f } },
|
||||||
|
{ 2, NPC_SANDFURY_ZEALOT, { 1877.00f, 1207.27f } },
|
||||||
|
{ 2, NPC_SANDFURY_SLAVE, { 1890.08f, 1218.68f } },
|
||||||
|
{ 2, NPC_SANDFURY_CRETIN, { 1894.64f, 1206.29f } },
|
||||||
|
{ 2, NPC_SANDFURY_ACOLYTE, { 1877.40f, 1216.41f } },
|
||||||
|
{ 2, NPC_SANDFURY_SLAVE, { 1892.28f, 1225.49f } },
|
||||||
|
{ 2, NPC_SANDFURY_DRUDGE, { 1893.07f, 1215.26f } },
|
||||||
|
{ 2, NPC_SANDFURY_ZEALOT, { 1896.46f, 1205.62f } },
|
||||||
|
{ 2, NPC_SANDFURY_CRETIN, { 1874.45f, 1204.44f } },
|
||||||
|
{ 2, NPC_SANDFURY_CRETIN, { 1874.18f, 1221.24f } },
|
||||||
|
{ 2, NPC_SANDFURY_SLAVE, { 1879.02f, 1223.06f } },
|
||||||
|
{ 2, NPC_SANDFURY_ACOLYTE, { 1898.23f, 1217.97f } },
|
||||||
|
{ 2, NPC_SANDFURY_SLAVE, { 1882.07f, 1225.70f } },
|
||||||
|
{ 2, NPC_SANDFURY_ZEALOT, { 1873.63f, 1204.65f } },
|
||||||
|
{ 2, NPC_SANDFURY_SLAVE, { 1886.97f, 1225.86f } },
|
||||||
|
{ 2, NPC_SANDFURY_DRUDGE, { 1878.57f, 1214.16f } },
|
||||||
|
{ 2, NPC_SANDFURY_SLAVE, { 1894.72f, 1221.91f } },
|
||||||
|
{ 2, NPC_SANDFURY_SLAVE, { 1886.93f, 1221.40f } },
|
||||||
|
{ 2, NPC_SANDFURY_ACOLYTE, { 1883.76f, 1222.30f } },
|
||||||
|
{ 2, NPC_SANDFURY_DRUDGE, { 1889.94f, 1212.21f } },
|
||||||
|
{ 2, NPC_SANDFURY_ZEALOT, { 1899.63f, 1202.52f } },
|
||||||
|
{ 3, NPC_SANDFURY_DRUDGE, { 1878.57f, 1214.16f } },
|
||||||
|
{ 3, NPC_SANDFURY_SLAVE, { 1894.72f, 1221.91f } },
|
||||||
|
{ 3, NPC_SANDFURY_SLAVE, { 1886.93f, 1221.40f } },
|
||||||
|
{ 3, NPC_SANDFURY_ACOLYTE, { 1883.76f, 1222.30f } },
|
||||||
|
{ 3, NPC_SANDFURY_DRUDGE, { 1889.94f, 1212.21f } },
|
||||||
|
{ 3, NPC_SHADOWPRIEST_SEZZZIZ, { 1886.30f, 1199.65f } },
|
||||||
|
{ 3, NPC_NEKRUM_GUTCHEWER, { 1881.06f, 1199.70f } }
|
||||||
|
};
|
||||||
|
|
||||||
class instance_zulfarrak : public InstanceMapScript
|
class instance_zulfarrak : public InstanceMapScript
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
instance_zulfarrak() : InstanceMapScript("instance_zulfarrak", 209) { }
|
instance_zulfarrak() : InstanceMapScript(ZFScriptName, 209) {}
|
||||||
|
|
||||||
InstanceScript* GetInstanceScript(InstanceMap* map) const override
|
InstanceScript* GetInstanceScript(InstanceMap* map) const override
|
||||||
{
|
{
|
||||||
@@ -23,44 +100,337 @@ public:
|
|||||||
{
|
{
|
||||||
instance_zulfarrak_InstanceMapScript(Map* map) : InstanceScript(map) { }
|
instance_zulfarrak_InstanceMapScript(Map* map) : InstanceScript(map) { }
|
||||||
|
|
||||||
|
ObjectGuid EndDoorGUID;
|
||||||
|
ObjectGuid BlyGUID;
|
||||||
|
ObjectGuid WeegliGUID;
|
||||||
|
ObjectGuid OroGUID;
|
||||||
|
ObjectGuid RavenGUID;
|
||||||
|
ObjectGuid MurtaGUID;
|
||||||
|
ObjectGuid ShadowpriestGUID;
|
||||||
|
|
||||||
|
GuidList addsAtBase;
|
||||||
|
GuidList movedadds;
|
||||||
|
|
||||||
|
uint32 GahzrillaSummoned;
|
||||||
|
uint32 PyramidPhase;
|
||||||
|
uint32 major_wave_Timer;
|
||||||
|
uint32 minor_wave_Timer;
|
||||||
|
uint32 addGroupSize;
|
||||||
|
uint32 waypoint;
|
||||||
|
|
||||||
void Initialize() override
|
void Initialize() override
|
||||||
{
|
{
|
||||||
_pyramidEventProgress = NOT_STARTED;
|
GahzrillaSummoned = NOT_STARTED;
|
||||||
_gahzrillaSummoned = NOT_STARTED;
|
|
||||||
|
PyramidPhase = 0;
|
||||||
|
major_wave_Timer = 0;
|
||||||
|
minor_wave_Timer = 0;
|
||||||
|
addGroupSize = 0;
|
||||||
|
waypoint = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void OnCreatureCreate(Creature* creature) override
|
||||||
|
{
|
||||||
|
switch (creature->GetEntry())
|
||||||
|
{
|
||||||
|
case NPC_BLY:
|
||||||
|
BlyGUID = creature->GetGUID();
|
||||||
|
creature->SetReactState(REACT_PASSIVE); // starts out passive (in a cage)
|
||||||
|
break;
|
||||||
|
case NPC_RAVEN:
|
||||||
|
RavenGUID = creature->GetGUID();
|
||||||
|
creature->SetReactState(REACT_PASSIVE);// starts out passive (in a cage)
|
||||||
|
break;
|
||||||
|
case NPC_ORO:
|
||||||
|
OroGUID = creature->GetGUID();
|
||||||
|
creature->SetReactState(REACT_PASSIVE);// starts out passive (in a cage)
|
||||||
|
break;
|
||||||
|
case NPC_WEEGLI:
|
||||||
|
WeegliGUID = creature->GetGUID();
|
||||||
|
creature->SetReactState(REACT_PASSIVE);// starts out passive (in a cage)
|
||||||
|
break;
|
||||||
|
case NPC_MURTA:
|
||||||
|
MurtaGUID = creature->GetGUID();
|
||||||
|
creature->SetReactState(REACT_PASSIVE);// starts out passive (in a cage)
|
||||||
|
break;
|
||||||
|
case NPC_SHADOWPRIEST_SEZZZIZ:
|
||||||
|
ShadowpriestGUID = creature->GetGUID();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void OnGameObjectCreate(GameObject* gameobject) override
|
void OnGameObjectCreate(GameObject* gameobject) override
|
||||||
{
|
{
|
||||||
if (gameobject->GetEntry() == GO_END_DOOR && _pyramidEventProgress == DONE)
|
switch (gameobject->GetEntry())
|
||||||
gameobject->SetGoState(GO_STATE_ACTIVE_ALTERNATIVE);
|
{
|
||||||
|
case GO_END_DOOR:
|
||||||
|
EndDoorGUID = gameobject->GetGUID();
|
||||||
|
if (PyramidPhase == PYRAMID_DONE)
|
||||||
|
{
|
||||||
|
HandleGameObject(gameobject->GetGUID(), true, gameobject);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32 GetData(uint32 type) const override
|
void OnUnitDeath(Unit* unit) override
|
||||||
{
|
{
|
||||||
if (type == TYPE_PYRAMID_EVENT)
|
if (unit->GetEntry() == NPC_BLY)
|
||||||
return _pyramidEventProgress;
|
{
|
||||||
return 0;
|
PyramidPhase = PYRAMID_DONE;
|
||||||
|
SaveToDB();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetData(uint32 type, uint32 data) override
|
void SetData(uint32 type, uint32 data) override
|
||||||
{
|
{
|
||||||
switch (type)
|
switch (type)
|
||||||
{
|
{
|
||||||
case TYPE_PYRAMID_EVENT:
|
case DATA_PYRAMID:
|
||||||
_pyramidEventProgress = data;
|
PyramidPhase = data;
|
||||||
break;
|
break;
|
||||||
case TYPE_GAHZRILLA:
|
case DATA_GAHZRILLA:
|
||||||
_gahzrillaSummoned = data;
|
GahzrillaSummoned = data;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
SaveToDB();
|
SaveToDB();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32 GetData(uint32 type) const override
|
||||||
|
{
|
||||||
|
switch (type)
|
||||||
|
{
|
||||||
|
case DATA_PYRAMID:
|
||||||
|
return PyramidPhase;
|
||||||
|
case DATA_GAHZRILLA:
|
||||||
|
return GahzrillaSummoned;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
ObjectGuid GetGuidData(uint32 data) const override
|
||||||
|
{
|
||||||
|
switch (data)
|
||||||
|
{
|
||||||
|
case NPC_BLY:
|
||||||
|
return BlyGUID;
|
||||||
|
case NPC_RAVEN:
|
||||||
|
return RavenGUID;
|
||||||
|
case NPC_ORO:
|
||||||
|
return OroGUID;
|
||||||
|
case NPC_WEEGLI:
|
||||||
|
return WeegliGUID;
|
||||||
|
case NPC_MURTA:
|
||||||
|
return MurtaGUID;
|
||||||
|
case NPC_SHADOWPRIEST_SEZZZIZ:
|
||||||
|
return ShadowpriestGUID;
|
||||||
|
case GO_END_DOOR:
|
||||||
|
return EndDoorGUID;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ObjectGuid::Empty;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Update(uint32 diff) override
|
||||||
|
{
|
||||||
|
switch (PyramidPhase)
|
||||||
|
{
|
||||||
|
case PYRAMID_NOT_STARTED:
|
||||||
|
case PYRAMID_KILLED_ALL_TROLLS:
|
||||||
|
case PYRAMID_MOVED_DOWNSTAIRS:
|
||||||
|
case PYRAMID_DESTROY_GATES:
|
||||||
|
case PYRAMID_GATES_DESTROYED:
|
||||||
|
case PYRAMID_DONE:
|
||||||
|
break;
|
||||||
|
case PYRAMID_ARRIVED_AT_STAIR:
|
||||||
|
SpawnPyramidWave(1);
|
||||||
|
SetData(DATA_PYRAMID, PYRAMID_WAVE_1);
|
||||||
|
major_wave_Timer = 2 * MINUTE * IN_MILLISECONDS;
|
||||||
|
minor_wave_Timer = 0;
|
||||||
|
addGroupSize = 2;
|
||||||
|
break;
|
||||||
|
case PYRAMID_WAVE_1:
|
||||||
|
if (IsWaveAllDead())
|
||||||
|
{
|
||||||
|
SetData(DATA_PYRAMID, PYRAMID_PRE_WAVE_2);
|
||||||
|
major_wave_Timer = 10 * IN_MILLISECONDS; //give players a few seconds before wave 2 starts to rebuff
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (minor_wave_Timer <= diff)
|
||||||
|
{
|
||||||
|
SendAddsUpStairs(addGroupSize++);
|
||||||
|
minor_wave_Timer = 10 * IN_MILLISECONDS;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
minor_wave_Timer -= diff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case PYRAMID_PRE_WAVE_2:
|
||||||
|
if (major_wave_Timer <= diff)
|
||||||
|
{
|
||||||
|
// beginning 2nd wave!
|
||||||
|
SpawnPyramidWave(2);
|
||||||
|
SetData(DATA_PYRAMID, PYRAMID_WAVE_2);
|
||||||
|
minor_wave_Timer = 0;
|
||||||
|
addGroupSize = 2;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
major_wave_Timer -= diff;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case PYRAMID_WAVE_2:
|
||||||
|
if (IsWaveAllDead())
|
||||||
|
{
|
||||||
|
SpawnPyramidWave(3);
|
||||||
|
SetData(DATA_PYRAMID, PYRAMID_PRE_WAVE_3);
|
||||||
|
major_wave_Timer = 5 * IN_MILLISECONDS; //give NPCs time to return to their home spots
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (minor_wave_Timer <= diff)
|
||||||
|
{
|
||||||
|
SendAddsUpStairs(addGroupSize++);
|
||||||
|
minor_wave_Timer = 10 * IN_MILLISECONDS;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
minor_wave_Timer -= diff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case PYRAMID_PRE_WAVE_3:
|
||||||
|
if (major_wave_Timer <= diff)
|
||||||
|
{
|
||||||
|
// move NPCs to bottom of stair
|
||||||
|
MoveNPCIfAlive(NPC_BLY, 1887.92f, 1228.179f, 9.98f, 4.78f);
|
||||||
|
MoveNPCIfAlive(NPC_MURTA, 1891.57f, 1228.68f, 9.69f, 4.78f);
|
||||||
|
MoveNPCIfAlive(NPC_ORO, 1897.23f, 1228.34f, 9.43f, 4.78f);
|
||||||
|
MoveNPCIfAlive(NPC_RAVEN, 1883.68f, 1227.95f, 9.543f, 4.78f);
|
||||||
|
MoveNPCIfAlive(NPC_WEEGLI, 1878.02f, 1227.65f, 9.485f, 4.78f);
|
||||||
|
SetData(DATA_PYRAMID, PYRAMID_WAVE_3);
|
||||||
|
if (Creature* sergeantBlye = instance->GetCreature(BlyGUID))
|
||||||
|
{
|
||||||
|
sergeantBlye->AI()->Talk(SAY_BLY_FORWARD);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
major_wave_Timer -= diff;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case PYRAMID_WAVE_3:
|
||||||
|
if (IsWaveAllDead()) // move NPCS to their final positions
|
||||||
|
{
|
||||||
|
SetData(DATA_PYRAMID, PYRAMID_KILLED_ALL_TROLLS);
|
||||||
|
MoveNPCIfAlive(NPC_BLY, 1883.82f, 1200.83f, 8.87f, 1.32f);
|
||||||
|
MoveNPCIfAlive(NPC_MURTA, 1891.83f, 1201.45f, 8.87f, 1.32f);
|
||||||
|
MoveNPCIfAlive(NPC_ORO, 1894.50f, 1204.40f, 8.87f, 1.32f);
|
||||||
|
MoveNPCIfAlive(NPC_RAVEN, 1874.11f, 1206.17f, 8.87f, 1.32f);
|
||||||
|
MoveNPCIfAlive(NPC_WEEGLI, 1877.52f, 1199.63f, 8.87f, 1.32f);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
void MoveNPCIfAlive(uint32 entry, float x, float y, float z, float o)
|
||||||
|
{
|
||||||
|
if (Creature* npc = instance->GetCreature(GetGuidData(entry)))
|
||||||
|
{
|
||||||
|
if (npc->IsAlive())
|
||||||
|
{
|
||||||
|
npc->SetWalk(true);
|
||||||
|
npc->GetMotionMaster()->MovePoint(1, { x, y, z, o } );
|
||||||
|
npc->SetHomePosition(x, y, z, o);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SpawnPyramidWave(uint32 wave)
|
||||||
|
{
|
||||||
|
for (uint32 i = 0; i < pyramidSpawnTotal; i++)
|
||||||
|
{
|
||||||
|
if (pyramidSpawns[i].waveID == wave)
|
||||||
|
{
|
||||||
|
float orientation = 4.78f;
|
||||||
|
if (pyramidSpawns[i].creatureID == NPC_SHADOWPRIEST_SEZZZIZ || pyramidSpawns[i].creatureID == NPC_NEKRUM_GUTCHEWER)
|
||||||
|
{
|
||||||
|
orientation = 1.32f;
|
||||||
|
}
|
||||||
|
|
||||||
|
Position pos = { pyramidSpawns[i].pos.GetPositionX(), pyramidSpawns[i].pos.GetPositionY(), 8.87f, orientation };
|
||||||
|
if (TempSummon* ts = instance->SummonCreature(pyramidSpawns[i].creatureID, pos))
|
||||||
|
{
|
||||||
|
addsAtBase.push_back(ts->GetGUID());
|
||||||
|
|
||||||
|
if (pyramidSpawns[i].creatureID != NPC_SHADOWPRIEST_SEZZZIZ && pyramidSpawns[i].creatureID != NPC_NEKRUM_GUTCHEWER)
|
||||||
|
{
|
||||||
|
ts->GetMotionMaster()->MoveRandom(10);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IsWaveAllDead()
|
||||||
|
{
|
||||||
|
for (GuidList::iterator itr = addsAtBase.begin(); itr != addsAtBase.end(); ++itr)
|
||||||
|
{
|
||||||
|
if (Creature* add = instance->GetCreature((*itr)))
|
||||||
|
{
|
||||||
|
if (add->IsAlive())
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (GuidList::iterator itr = movedadds.begin(); itr != movedadds.end(); ++itr)
|
||||||
|
{
|
||||||
|
if (Creature* add = instance->GetCreature(((*itr))))
|
||||||
|
{
|
||||||
|
if (add->IsAlive())
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SendAddsUpStairs(uint32 count)
|
||||||
|
{
|
||||||
|
//pop a add from list, send him up the stairs...
|
||||||
|
for (uint32 addCount = 0; addCount < count && !addsAtBase.empty(); addCount++)
|
||||||
|
{
|
||||||
|
if (Creature* add = instance->GetCreature(*addsAtBase.begin()))
|
||||||
|
{
|
||||||
|
add->GetMotionMaster()->MovePath(PATH_ADDS, false);
|
||||||
|
movedadds.push_back(add->GetGUID());
|
||||||
|
}
|
||||||
|
|
||||||
|
addsAtBase.erase(addsAtBase.begin());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
std::string GetSaveData() override
|
std::string GetSaveData() override
|
||||||
{
|
{
|
||||||
std::ostringstream saveStream;
|
std::ostringstream saveStream;
|
||||||
saveStream << "Z F " << _pyramidEventProgress << ' ' << _gahzrillaSummoned;
|
saveStream << "Z F " << PyramidPhase << ' ' << GahzrillaSummoned;
|
||||||
return saveStream.str();
|
return saveStream.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -75,14 +445,10 @@ public:
|
|||||||
|
|
||||||
if (dataHead1 == 'Z' && dataHead2 == 'F')
|
if (dataHead1 == 'Z' && dataHead2 == 'F')
|
||||||
{
|
{
|
||||||
loadStream >> _pyramidEventProgress;
|
loadStream >> PyramidPhase;
|
||||||
loadStream >> _gahzrillaSummoned;
|
loadStream >> GahzrillaSummoned;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
|
||||||
uint32 _pyramidEventProgress;
|
|
||||||
uint32 _gahzrillaSummoned;
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,674 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2016+ AzerothCore <www.azerothcore.org>, released under GNU GPL v2 license, you may redistribute it and/or modify it under version 2 of the License, or (at your option), any later version.
|
||||||
|
* Copyright (C) 2008-2016 TrinityCore <http://www.trinitycore.org/>
|
||||||
|
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* ScriptData
|
||||||
|
SDName: Zulfarrak
|
||||||
|
SD%Complete: 50
|
||||||
|
SDComment: Consider it temporary, no instance script made for this instance yet.
|
||||||
|
SDCategory: Zul'Farrak
|
||||||
|
EndScriptData */
|
||||||
|
|
||||||
|
/* ContentData
|
||||||
|
npc_sergeant_bly
|
||||||
|
npc_weegli_blastfuse
|
||||||
|
EndContentData */
|
||||||
|
|
||||||
|
#include "ScriptMgr.h"
|
||||||
|
#include "ScriptSystem.h"
|
||||||
|
#include "GameObject.h"
|
||||||
|
#include "GameObjectAI.h"
|
||||||
|
#include "InstanceScript.h"
|
||||||
|
#include "MotionMaster.h"
|
||||||
|
#include "ObjectAccessor.h"
|
||||||
|
#include "Player.h"
|
||||||
|
#include "ScriptedCreature.h"
|
||||||
|
#include "ScriptedGossip.h"
|
||||||
|
#include "zulfarrak.h"
|
||||||
|
#include "Cell.h"
|
||||||
|
#include "CellImpl.h"
|
||||||
|
#include "GridNotifiers.h"
|
||||||
|
#include "GridNotifiersImpl.h"
|
||||||
|
|
||||||
|
/*######
|
||||||
|
## npc_sergeant_bly
|
||||||
|
######*/
|
||||||
|
|
||||||
|
enum blySays
|
||||||
|
{
|
||||||
|
SAY_1 = 0,
|
||||||
|
SAY_2 = 1
|
||||||
|
};
|
||||||
|
|
||||||
|
enum blySpells
|
||||||
|
{
|
||||||
|
SPELL_SHIELD_BASH = 11972,
|
||||||
|
SPELL_REVENGE = 12170
|
||||||
|
};
|
||||||
|
|
||||||
|
#define GOSSIP_BLY "That's it! I'm tired of helping you out. It's time we settled things on the battlefield!"
|
||||||
|
|
||||||
|
class npc_sergeant_bly : public CreatureScript
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
npc_sergeant_bly() : CreatureScript("npc_sergeant_bly") { }
|
||||||
|
|
||||||
|
struct npc_sergeant_blyAI : public ScriptedAI
|
||||||
|
{
|
||||||
|
npc_sergeant_blyAI(Creature* creature) : ScriptedAI(creature)
|
||||||
|
{
|
||||||
|
instance = creature->GetInstanceScript();
|
||||||
|
}
|
||||||
|
|
||||||
|
void InitializeAI() override
|
||||||
|
{
|
||||||
|
startedFight = false;
|
||||||
|
me->setFaction(35);
|
||||||
|
postGossipStep = 0;
|
||||||
|
Text_Timer = 0;
|
||||||
|
me->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
|
||||||
|
}
|
||||||
|
|
||||||
|
InstanceScript* instance;
|
||||||
|
|
||||||
|
bool startedFight;
|
||||||
|
uint32 postGossipStep;
|
||||||
|
uint32 Text_Timer;
|
||||||
|
uint32 ShieldBash_Timer;
|
||||||
|
uint32 Revenge_Timer; //this is wrong, spell should never be used unless me->GetVictim() dodge, parry or block attack. Trinity support required.
|
||||||
|
ObjectGuid PlayerGUID;
|
||||||
|
|
||||||
|
void Reset() override
|
||||||
|
{
|
||||||
|
ShieldBash_Timer = 5000;
|
||||||
|
Revenge_Timer = 8000;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MovementInform(uint32 type, uint32 /*id*/) override
|
||||||
|
{
|
||||||
|
if (type != POINT_MOTION_TYPE)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (instance->GetData(DATA_PYRAMID) == PYRAMID_WAVE_3)
|
||||||
|
{
|
||||||
|
if (Creature* shadowpriest = ObjectAccessor::GetCreature(*me, instance->GetGuidData(NPC_SHADOWPRIEST_SEZZZIZ)))
|
||||||
|
{
|
||||||
|
AttackStart(shadowpriest);
|
||||||
|
shadowpriest->CallAssistance();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void UpdateAI(uint32 diff) override
|
||||||
|
{
|
||||||
|
if (postGossipStep > 0 && postGossipStep < 4)
|
||||||
|
{
|
||||||
|
if (Text_Timer <= diff)
|
||||||
|
{
|
||||||
|
switch (postGossipStep)
|
||||||
|
{
|
||||||
|
case 1:
|
||||||
|
//weegli doesn't fight - he goes & blows up the door
|
||||||
|
if (Creature* pWeegli = ObjectAccessor::GetCreature(*me, instance->GetGuidData(NPC_WEEGLI)))
|
||||||
|
{
|
||||||
|
pWeegli->AI()->DoAction(0);
|
||||||
|
}
|
||||||
|
Talk(SAY_1);
|
||||||
|
Text_Timer = 5000;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
Talk(SAY_2);
|
||||||
|
Text_Timer = 5000;
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
me->setFaction(14);
|
||||||
|
Player* target = ObjectAccessor::GetPlayer(*me, PlayerGUID);
|
||||||
|
|
||||||
|
switchFactionIfAlive(NPC_RAVEN, target);
|
||||||
|
switchFactionIfAlive(NPC_ORO, target);
|
||||||
|
switchFactionIfAlive(NPC_MURTA, target);
|
||||||
|
|
||||||
|
if (target)
|
||||||
|
{
|
||||||
|
AttackStart(target);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
postGossipStep++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Text_Timer -= diff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!UpdateVictim())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ShieldBash_Timer <= diff)
|
||||||
|
{
|
||||||
|
DoCastVictim(SPELL_SHIELD_BASH);
|
||||||
|
ShieldBash_Timer = 15000;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ShieldBash_Timer -= diff;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Revenge_Timer <= diff)
|
||||||
|
{
|
||||||
|
DoCastVictim(SPELL_REVENGE);
|
||||||
|
Revenge_Timer = 10000;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Revenge_Timer -= diff;
|
||||||
|
}
|
||||||
|
|
||||||
|
DoMeleeAttackIfReady();
|
||||||
|
}
|
||||||
|
|
||||||
|
void DoAction(int32 /*param*/) override
|
||||||
|
{
|
||||||
|
postGossipStep = 1;
|
||||||
|
Text_Timer = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void switchFactionIfAlive(uint32 entry, Player* target)
|
||||||
|
{
|
||||||
|
if (Creature* crew = ObjectAccessor::GetCreature(*me, instance->GetGuidData(entry)))
|
||||||
|
{
|
||||||
|
if (crew->IsAlive())
|
||||||
|
{
|
||||||
|
crew->setFaction(14);
|
||||||
|
|
||||||
|
if (target)
|
||||||
|
{
|
||||||
|
crew->AI()->AttackStart(target);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void sGossipSelect(Player* player, uint32 /*menuId*/, uint32 gossipListId) override
|
||||||
|
{
|
||||||
|
uint32 const action = player->PlayerTalkClass->GetGossipOptionAction(gossipListId);
|
||||||
|
ClearGossipMenuFor(player);
|
||||||
|
|
||||||
|
if (action == GOSSIP_ACTION_INFO_DEF + 1)
|
||||||
|
{
|
||||||
|
CloseGossipMenuFor(player);
|
||||||
|
PlayerGUID = player->GetGUID();
|
||||||
|
DoAction(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void sGossipHello(Player* player) override
|
||||||
|
{
|
||||||
|
if (instance->GetData(DATA_PYRAMID) >= PYRAMID_DESTROY_GATES && !startedFight)
|
||||||
|
{
|
||||||
|
startedFight = true;
|
||||||
|
AddGossipItemFor(player, GOSSIP_ICON_CHAT, GOSSIP_BLY, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1);
|
||||||
|
SendGossipMenuFor(player, 1517, me->GetGUID());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (instance->GetData(DATA_PYRAMID) == PYRAMID_NOT_STARTED)
|
||||||
|
{
|
||||||
|
SendGossipMenuFor(player, 1515, me->GetGUID());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SendGossipMenuFor(player, 1516, me->GetGUID());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
CreatureAI* GetAI(Creature* creature) const override
|
||||||
|
{
|
||||||
|
return GetZulFarrakAI<npc_sergeant_blyAI>(creature);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/*######
|
||||||
|
+## go_troll_cage
|
||||||
|
+######*/
|
||||||
|
|
||||||
|
class go_troll_cage : public GameObjectScript
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
go_troll_cage() : GameObjectScript("go_troll_cage") { }
|
||||||
|
|
||||||
|
struct go_troll_cageAI : public GameObjectAI
|
||||||
|
{
|
||||||
|
go_troll_cageAI(GameObject* go) : GameObjectAI(go), instance(go->GetInstanceScript()) { }
|
||||||
|
|
||||||
|
InstanceScript* instance;
|
||||||
|
|
||||||
|
bool GossipHello(Player* /*player*/, bool reportUse) override
|
||||||
|
{
|
||||||
|
if (reportUse)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
instance->SetData(DATA_PYRAMID, PYRAMID_CAGES_OPEN);
|
||||||
|
|
||||||
|
//set bly & co to aggressive & start moving to top of stairs
|
||||||
|
initBlyCrewMember(NPC_BLY, 1884.99f, 1263, 41.52f);
|
||||||
|
initBlyCrewMember(NPC_RAVEN, 1882.5f, 1263, 41.52f);
|
||||||
|
initBlyCrewMember(NPC_ORO, 1886.47f, 1270.68f, 41.68f);
|
||||||
|
initBlyCrewMember(NPC_WEEGLI, 1890, 1263, 41.52f);
|
||||||
|
initBlyCrewMember(NPC_MURTA, 1891.19f, 1272.03f, 41.60f);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
void initBlyCrewMember(uint32 entry, float x, float y, float z)
|
||||||
|
{
|
||||||
|
if (Creature* crew = ObjectAccessor::GetCreature(*go, instance->GetGuidData(entry)))
|
||||||
|
{
|
||||||
|
crew->SetReactState(REACT_AGGRESSIVE);
|
||||||
|
crew->SetWalk(true);
|
||||||
|
crew->SetHomePosition(x, y, z, 4.78f);
|
||||||
|
crew->GetMotionMaster()->MovePoint(1, { x, y, z, 4.78f });
|
||||||
|
crew->setFaction(FACTION_ESCORT_N_NEUTRAL_ACTIVE);
|
||||||
|
|
||||||
|
switch (entry)
|
||||||
|
{
|
||||||
|
case NPC_BLY:
|
||||||
|
case NPC_WEEGLI:
|
||||||
|
crew->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
GameObjectAI* GetAI(GameObject* go) const override
|
||||||
|
{
|
||||||
|
return GetZulFarrakAI<go_troll_cageAI>(go);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/*######
|
||||||
|
## npc_weegli_blastfuse
|
||||||
|
######*/
|
||||||
|
|
||||||
|
enum weegliSpells
|
||||||
|
{
|
||||||
|
SPELL_BOMB = 8858,
|
||||||
|
SPELL_GOBLIN_LAND_MINE = 21688,
|
||||||
|
SPELL_SHOOT = 6660,
|
||||||
|
SPELL_WEEGLIS_BARREL = 10772
|
||||||
|
};
|
||||||
|
|
||||||
|
enum weegliSays
|
||||||
|
{
|
||||||
|
SAY_WEEGLI_OHNO = 0,
|
||||||
|
SAY_WEEGLI_OK_I_GO = 1,
|
||||||
|
SAY_WEEGLI_OUT_OF_HERE = 2
|
||||||
|
};
|
||||||
|
|
||||||
|
#define GOSSIP_WEEGLI "Will you blow up that door now?"
|
||||||
|
|
||||||
|
class npc_weegli_blastfuse : public CreatureScript
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
npc_weegli_blastfuse() : CreatureScript("npc_weegli_blastfuse") { }
|
||||||
|
|
||||||
|
struct npc_weegli_blastfuseAI : public ScriptedAI
|
||||||
|
{
|
||||||
|
npc_weegli_blastfuseAI(Creature* creature) : ScriptedAI(creature)
|
||||||
|
{
|
||||||
|
instance = creature->GetInstanceScript();
|
||||||
|
destroyingDoor = false;
|
||||||
|
outroTimer = 2000;
|
||||||
|
outroStage = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32 Bomb_Timer;
|
||||||
|
uint32 LandMine_Timer;
|
||||||
|
uint32 outroTimer;
|
||||||
|
uint8 outroStage;
|
||||||
|
bool destroyingDoor;
|
||||||
|
InstanceScript* instance;
|
||||||
|
|
||||||
|
void InitializeAI() override
|
||||||
|
{
|
||||||
|
me->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
|
||||||
|
Reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Reset() override
|
||||||
|
{
|
||||||
|
Bomb_Timer = 10000;
|
||||||
|
LandMine_Timer = 30000;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AttackStart(Unit* victim) override
|
||||||
|
{
|
||||||
|
AttackStartCaster(victim, 10);//keep back & toss bombs/shoot
|
||||||
|
}
|
||||||
|
|
||||||
|
void UpdateAI(uint32 diff) override
|
||||||
|
{
|
||||||
|
if (!UpdateVictim())
|
||||||
|
{
|
||||||
|
if (destroyingDoor)
|
||||||
|
{
|
||||||
|
if (outroTimer <= diff)
|
||||||
|
{
|
||||||
|
switch (outroStage)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
DoCastSelf(SPELL_WEEGLIS_BARREL);
|
||||||
|
outroTimer = 2000;
|
||||||
|
++outroStage;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
me->GetMotionMaster()->MovePoint(2, 1871.18f, 1100.f, 8.88f);
|
||||||
|
Talk(SAY_WEEGLI_OUT_OF_HERE);
|
||||||
|
me->DespawnOrUnsummon(8000);
|
||||||
|
instance->SetData(DATA_PYRAMID, PYRAMID_GATES_DESTROYED);
|
||||||
|
destroyingDoor = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
outroTimer -= diff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Bomb_Timer <= diff)
|
||||||
|
{
|
||||||
|
DoCastVictim(SPELL_BOMB);
|
||||||
|
Bomb_Timer = 10000;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Bomb_Timer -= diff;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (LandMine_Timer <= diff)
|
||||||
|
{
|
||||||
|
DoCastSelf(SPELL_GOBLIN_LAND_MINE);
|
||||||
|
LandMine_Timer = 30000;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
LandMine_Timer -= diff;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (me->isAttackReady() && !me->IsWithinMeleeRange(me->GetVictim()))
|
||||||
|
{
|
||||||
|
DoCastVictim(SPELL_SHOOT);
|
||||||
|
me->SetSheath(SHEATH_STATE_RANGED);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
me->SetSheath(SHEATH_STATE_MELEE);
|
||||||
|
DoMeleeAttackIfReady();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void JustReachedHome() override
|
||||||
|
{
|
||||||
|
if (instance->GetData(DATA_PYRAMID) == PYRAMID_CAGES_OPEN)
|
||||||
|
{
|
||||||
|
instance->SetData(DATA_PYRAMID, PYRAMID_ARRIVED_AT_STAIR);
|
||||||
|
Talk(SAY_WEEGLI_OHNO);
|
||||||
|
}
|
||||||
|
else if (instance->GetData(DATA_PYRAMID) == PYRAMID_KILLED_ALL_TROLLS)
|
||||||
|
{
|
||||||
|
instance->SetData(DATA_PYRAMID, PYRAMID_MOVED_DOWNSTAIRS);
|
||||||
|
me->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
|
||||||
|
}
|
||||||
|
else if (instance->GetData(DATA_PYRAMID) == PYRAMID_DESTROY_GATES)
|
||||||
|
{
|
||||||
|
destroyingDoor = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MovementInform(uint32 type, uint32 /*id*/) override
|
||||||
|
{
|
||||||
|
if (type != POINT_MOTION_TYPE)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (instance->GetData(DATA_PYRAMID) == PYRAMID_CAGES_OPEN)
|
||||||
|
{
|
||||||
|
instance->SetData(DATA_PYRAMID, PYRAMID_ARRIVED_AT_STAIR);
|
||||||
|
Talk(SAY_WEEGLI_OHNO);
|
||||||
|
}
|
||||||
|
else if (instance->GetData(DATA_PYRAMID) == PYRAMID_KILLED_ALL_TROLLS)
|
||||||
|
{
|
||||||
|
instance->SetData(DATA_PYRAMID, PYRAMID_MOVED_DOWNSTAIRS);
|
||||||
|
me->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
|
||||||
|
}
|
||||||
|
else if (instance->GetData(DATA_PYRAMID) == PYRAMID_DESTROY_GATES)
|
||||||
|
{
|
||||||
|
destroyingDoor = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void DestroyDoor()
|
||||||
|
{
|
||||||
|
if (me->IsAlive())
|
||||||
|
{
|
||||||
|
me->setFaction(35);
|
||||||
|
me->SetWalk(false);
|
||||||
|
me->GetMotionMaster()->MovePoint(0, { 1858.57f, 1146.35f, 14.745f, 3.85f });
|
||||||
|
me->SetHomePosition(1858.57f, 1146.35f, 14.745f, 3.85f);
|
||||||
|
Talk(SAY_WEEGLI_OK_I_GO);
|
||||||
|
instance->SetData(DATA_PYRAMID, PYRAMID_DESTROY_GATES);
|
||||||
|
if (Creature* sergeantBly = ObjectAccessor::GetCreature(*me, instance->GetGuidData(NPC_BLY)))
|
||||||
|
{
|
||||||
|
sergeantBly->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void sGossipSelect(Player* player, uint32 /*menuId*/, uint32 gossipListId) override
|
||||||
|
{
|
||||||
|
uint32 const action = player->PlayerTalkClass->GetGossipOptionAction(gossipListId);
|
||||||
|
ClearGossipMenuFor(player);
|
||||||
|
|
||||||
|
if (action == GOSSIP_ACTION_INFO_DEF + 1)
|
||||||
|
{
|
||||||
|
CloseGossipMenuFor(player);
|
||||||
|
//here we make him run to door, set the charge and run away off to nowhere
|
||||||
|
DestroyDoor();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void sGossipHello(Player* player) override
|
||||||
|
{
|
||||||
|
switch (instance->GetData(DATA_PYRAMID))
|
||||||
|
{
|
||||||
|
case PYRAMID_MOVED_DOWNSTAIRS:
|
||||||
|
AddGossipItemFor(player, GOSSIP_ICON_CHAT, GOSSIP_WEEGLI, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1);
|
||||||
|
SendGossipMenuFor(player, 1514, me->GetGUID()); //if event can proceed to end
|
||||||
|
break;
|
||||||
|
case PYRAMID_NOT_STARTED:
|
||||||
|
SendGossipMenuFor(player, 1511, me->GetGUID()); //if event not started
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
SendGossipMenuFor(player, 1513, me->GetGUID()); //if event are in progress
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
CreatureAI* GetAI(Creature* creature) const override
|
||||||
|
{
|
||||||
|
return GetZulFarrakAI<npc_weegli_blastfuseAI>(creature);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
enum ShadowPriestSezzizEnum
|
||||||
|
{
|
||||||
|
SPELL_SHADOW_BOLT = 15537,
|
||||||
|
SPELL_PSYCHIC_SCREEM = 13704,
|
||||||
|
SPELL_RENEW = 8362,
|
||||||
|
SPELL_HEAL = 12039
|
||||||
|
};
|
||||||
|
|
||||||
|
std::array<std::vector<std::pair<uint32, Position>>, 4> shadowpriestSezzizAdds =
|
||||||
|
{ {
|
||||||
|
{ { NPC_SANDFURY_ZEALOT, { 1874.12f, 1198.90f, 8.87f } }, { NPC_SANDFURY_ACOLYTE, { 1874.12f, 1198.90f, 8.87f } } },
|
||||||
|
{ { NPC_SANDFURY_ACOLYTE, { 895.26f, 1199.09f, 8.87f } }, { NPC_SANDFURY_ACOLYTE, { 895.26f, 1199.088f, 8.87f } } },
|
||||||
|
{ { NPC_SANDFURY_ZEALOT, { 1874.12f, 1198.90f, 8.87f } }, { NPC_SANDFURY_ACOLYTE, { 895.26f, 1199.09f, 8.87f } }, { NPC_SANDFURY_ACOLYTE, { 895.26f, 1199.09f, 8.87f } } },
|
||||||
|
{ { NPC_SANDFURY_ZEALOT, { 895.26f, 1199.09f, 8.87f } }, { NPC_SANDFURY_ZEALOT, { 1874.12f, 1198.90f, 8.87f } }, { NPC_SANDFURY_ACOLYTE, { 1874.12f, 1198.90f } }, { NPC_SANDFURY_ACOLYTE, { 895.26f, 1199.09f, 8.87f } } }
|
||||||
|
} };
|
||||||
|
|
||||||
|
class npc_shadowpriest_sezziz : public CreatureScript
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
npc_shadowpriest_sezziz() : CreatureScript("npc_shadowpriest_sezziz") {}
|
||||||
|
|
||||||
|
struct npc_shadowpriest_sezzizAI : public ScriptedAI
|
||||||
|
{
|
||||||
|
npc_shadowpriest_sezzizAI(Creature* creature) : ScriptedAI(creature) { }
|
||||||
|
|
||||||
|
void Reset() override
|
||||||
|
{
|
||||||
|
_shadowBoltTimer = urand(0, 1 * IN_MILLISECONDS);
|
||||||
|
_physicScreemTimer = urand(1 * IN_MILLISECONDS, 16 * IN_MILLISECONDS);
|
||||||
|
_missingHPForRenewTimer = urand(10 * IN_MILLISECONDS, 15 * IN_MILLISECONDS);
|
||||||
|
_missingHPForHealTimer = urand(7 * IN_MILLISECONDS, 10 * IN_MILLISECONDS);
|
||||||
|
_summonAddsTimer = 12 * IN_MILLISECONDS;
|
||||||
|
_summmonAddsCount = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AttackStart(Unit* victim) override
|
||||||
|
{
|
||||||
|
ScriptedAI::AttackStartCaster(victim, 40.f);
|
||||||
|
}
|
||||||
|
|
||||||
|
void UpdateAI(uint32 diff) override
|
||||||
|
{
|
||||||
|
if (!UpdateVictim())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_summonAddsTimer <= diff)
|
||||||
|
{
|
||||||
|
for (auto itr : shadowpriestSezzizAdds[_summmonAddsCount])
|
||||||
|
{
|
||||||
|
if (Creature* add = me->SummonCreature(itr.first, itr.second, TEMPSUMMON_DEAD_DESPAWN, 10 * IN_MILLISECONDS))
|
||||||
|
{
|
||||||
|
add->AI()->AttackStart(me->GetVictim());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (++_summmonAddsCount >= 4)
|
||||||
|
{
|
||||||
|
_summmonAddsCount = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
_summonAddsTimer = urand(10 * IN_MILLISECONDS, 14 * IN_MILLISECONDS);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_summonAddsTimer -= diff;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_missingHPForHealTimer <= diff)
|
||||||
|
{
|
||||||
|
Unit* unit = nullptr;
|
||||||
|
Acore::MostHPMissingInRange u_check(me, 40.f, 1500);
|
||||||
|
Acore::UnitLastSearcher<Acore::MostHPMissingInRange> searcher(me, unit, u_check);
|
||||||
|
Cell::VisitGridObjects(me, searcher, 40.f);
|
||||||
|
if (unit)
|
||||||
|
{
|
||||||
|
DoCast(unit, SPELL_HEAL);
|
||||||
|
}
|
||||||
|
|
||||||
|
_missingHPForHealTimer = urand(7 * IN_MILLISECONDS, 10 * IN_MILLISECONDS);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_missingHPForHealTimer -= diff;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_missingHPForRenewTimer <= diff)
|
||||||
|
{
|
||||||
|
Unit* unit = nullptr;
|
||||||
|
Acore::MostHPMissingInRange u_check(me, 40.f, 700);
|
||||||
|
Acore::UnitLastSearcher<Acore::MostHPMissingInRange> searcher(me, unit, u_check);
|
||||||
|
Cell::VisitGridObjects(me, searcher, 40.f);
|
||||||
|
if (unit)
|
||||||
|
{
|
||||||
|
DoCast(unit, SPELL_RENEW);
|
||||||
|
}
|
||||||
|
|
||||||
|
_missingHPForRenewTimer = urand(10 * IN_MILLISECONDS, 15 * IN_MILLISECONDS);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_missingHPForRenewTimer -= diff;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_physicScreemTimer <= diff)
|
||||||
|
{
|
||||||
|
DoCastVictim(SPELL_PSYCHIC_SCREEM);
|
||||||
|
_physicScreemTimer = urand(22 * IN_MILLISECONDS, 30 * IN_MILLISECONDS);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_physicScreemTimer -= diff;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_shadowBoltTimer <= diff)
|
||||||
|
{
|
||||||
|
DoCastVictim(SPELL_SHADOW_BOLT);
|
||||||
|
_shadowBoltTimer = urand(3 * IN_MILLISECONDS, 4 * IN_MILLISECONDS);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_shadowBoltTimer -= diff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
uint32 _shadowBoltTimer;
|
||||||
|
uint32 _physicScreemTimer;
|
||||||
|
uint32 _missingHPForRenewTimer;
|
||||||
|
uint32 _missingHPForHealTimer;
|
||||||
|
uint32 _summonAddsTimer;
|
||||||
|
uint8 _summmonAddsCount;
|
||||||
|
};
|
||||||
|
|
||||||
|
CreatureAI* GetAI(Creature* creature) const override
|
||||||
|
{
|
||||||
|
return GetZulFarrakAI<npc_shadowpriest_sezzizAI>(creature);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
void AddSC_zulfarrak()
|
||||||
|
{
|
||||||
|
new npc_sergeant_bly();
|
||||||
|
new npc_weegli_blastfuse();
|
||||||
|
new npc_shadowpriest_sezziz();
|
||||||
|
new go_troll_cage();
|
||||||
|
}
|
||||||
@@ -5,15 +5,61 @@
|
|||||||
#ifndef DEF_ZULFARRACK_H
|
#ifndef DEF_ZULFARRACK_H
|
||||||
#define DEF_ZULFARRACK_H
|
#define DEF_ZULFARRACK_H
|
||||||
|
|
||||||
|
#include "CreatureAIImpl.h"
|
||||||
#include "CellImpl.h"
|
#include "CellImpl.h"
|
||||||
#include "SpellScript.h"
|
#include "SpellScript.h"
|
||||||
|
|
||||||
enum ZulFarrakData
|
#define ZFScriptName "instance_zulfarrak"
|
||||||
{
|
|
||||||
TYPE_PYRAMID_EVENT = 0,
|
|
||||||
TYPE_GAHZRILLA = 1,
|
|
||||||
|
|
||||||
|
enum ZulFarrakCreatures
|
||||||
|
{
|
||||||
|
NPC_SANDFURY_CRETIN = 7789,
|
||||||
|
NPC_SANDFURY_SLAVE = 7787,
|
||||||
|
NPC_SANDFURY_ACOLYTE = 8876,
|
||||||
|
NPC_SANDFURY_DRUDGE = 7788,
|
||||||
|
NPC_SANDFURY_ZEALOT = 8877,
|
||||||
|
NPC_SHADOWPRIEST_SEZZZIZ = 7275,
|
||||||
|
NPC_NEKRUM_GUTCHEWER = 7796,
|
||||||
|
|
||||||
|
NPC_BLY = 7604,
|
||||||
|
NPC_RAVEN = 7605,
|
||||||
|
NPC_ORO = 7606,
|
||||||
|
NPC_WEEGLI = 7607,
|
||||||
|
NPC_MURTA = 7608
|
||||||
|
};
|
||||||
|
|
||||||
|
enum ZulFarrakGameobjects
|
||||||
|
{
|
||||||
GO_END_DOOR = 146084
|
GO_END_DOOR = 146084
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum ZulFarrakData
|
||||||
|
{
|
||||||
|
DATA_PYRAMID = 0,
|
||||||
|
DATA_GAHZRILLA = 1
|
||||||
|
};
|
||||||
|
|
||||||
|
enum ZFPyramidPhases
|
||||||
|
{
|
||||||
|
PYRAMID_NOT_STARTED, //default
|
||||||
|
PYRAMID_CAGES_OPEN, //happens in GO hello for cages
|
||||||
|
PYRAMID_ARRIVED_AT_STAIR, //happens in Weegli's movementinform
|
||||||
|
PYRAMID_WAVE_1,
|
||||||
|
PYRAMID_PRE_WAVE_2,
|
||||||
|
PYRAMID_WAVE_2,
|
||||||
|
PYRAMID_PRE_WAVE_3,
|
||||||
|
PYRAMID_WAVE_3,
|
||||||
|
PYRAMID_KILLED_ALL_TROLLS,
|
||||||
|
PYRAMID_MOVED_DOWNSTAIRS,
|
||||||
|
PYRAMID_DESTROY_GATES,
|
||||||
|
PYRAMID_GATES_DESTROYED,
|
||||||
|
PYRAMID_DONE
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class AI, class T>
|
||||||
|
inline AI* GetZulFarrakAI(T* obj)
|
||||||
|
{
|
||||||
|
return GetInstanceAI<AI>(obj, ZFScriptName);
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -57,6 +57,7 @@ void AddSC_boss_ouro();
|
|||||||
void AddSC_npc_anubisath_sentinel();
|
void AddSC_npc_anubisath_sentinel();
|
||||||
void AddSC_instance_temple_of_ahnqiraj();
|
void AddSC_instance_temple_of_ahnqiraj();
|
||||||
void AddSC_instance_wailing_caverns(); //Wailing caverns
|
void AddSC_instance_wailing_caverns(); //Wailing caverns
|
||||||
|
void AddSC_zulfarrak();
|
||||||
void AddSC_instance_zulfarrak(); //Zul'Farrak instance script
|
void AddSC_instance_zulfarrak(); //Zul'Farrak instance script
|
||||||
void AddSC_ashenvale();
|
void AddSC_ashenvale();
|
||||||
void AddSC_azshara();
|
void AddSC_azshara();
|
||||||
@@ -137,6 +138,7 @@ void AddKalimdorScripts()
|
|||||||
AddSC_npc_anubisath_sentinel();
|
AddSC_npc_anubisath_sentinel();
|
||||||
AddSC_instance_temple_of_ahnqiraj();
|
AddSC_instance_temple_of_ahnqiraj();
|
||||||
AddSC_instance_wailing_caverns(); //Wailing caverns
|
AddSC_instance_wailing_caverns(); //Wailing caverns
|
||||||
|
AddSC_zulfarrak();
|
||||||
AddSC_instance_zulfarrak(); //Zul'Farrak instance script
|
AddSC_instance_zulfarrak(); //Zul'Farrak instance script
|
||||||
AddSC_ashenvale();
|
AddSC_ashenvale();
|
||||||
AddSC_azshara();
|
AddSC_azshara();
|
||||||
|
|||||||
Reference in New Issue
Block a user