mirror of
https://github.com/mod-playerbots/azerothcore-wotlk.git
synced 2026-01-27 23:56:25 +00:00
fix(Scripts/ShadowLabyrinth): Update Grandmaster Vorpil's script (#16018)
init
This commit is contained in:
@@ -56,261 +56,249 @@ float VorpilPosition[3] = {-253.548f, -263.646f, 17.0864f};
|
|||||||
//x, y, z, and orientation
|
//x, y, z, and orientation
|
||||||
float VoidPortalCoords[5][4] =
|
float VoidPortalCoords[5][4] =
|
||||||
{
|
{
|
||||||
{-208.411f, -263.652f, 17.086313f, 3.121870040893554687f}, //portal A 33566
|
{-208.411f, -263.652f, 17.086313f, 3.121870040893554687f}, //portal A 33566
|
||||||
{-261.676f, -297.69f, 17.087011f, 1.360249996185302734f}, //portal B 33614
|
{-261.676f, -297.69f, 17.087011f, 1.360249996185302734f}, //portal B 33614
|
||||||
{-282.272f, -240.432f, 12.683899f, 5.580170154571533203f}, //portal C 33615
|
{-282.272f, -240.432f, 12.683899f, 5.580170154571533203f}, //portal C 33615
|
||||||
{-291.833f, -268.595f, 12.682545f, 0.047733999788761138f}, //portal D 33567
|
{-291.833f, -268.595f, 12.682545f, 0.047733999788761138f}, //portal D 33567
|
||||||
{-303.966f, -255.759f, 12.683404f, 6.012829780578613281f} //portal E 33616
|
{-303.966f, -255.759f, 12.683404f, 6.012829780578613281f} //portal E 33616
|
||||||
};
|
};
|
||||||
|
|
||||||
class boss_grandmaster_vorpil : public CreatureScript
|
struct boss_grandmaster_vorpil : public BossAI
|
||||||
{
|
{
|
||||||
public:
|
boss_grandmaster_vorpil(Creature* creature) : BossAI(creature, DATA_GRANDMASTER_VORPIL)
|
||||||
boss_grandmaster_vorpil() : CreatureScript("boss_grandmaster_vorpil") { }
|
|
||||||
|
|
||||||
CreatureAI* GetAI(Creature* creature) const override
|
|
||||||
{
|
{
|
||||||
return GetShadowLabyrinthAI<boss_grandmaster_vorpilAI>(creature);
|
instance = creature->GetInstanceScript();
|
||||||
|
sayIntro = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct boss_grandmaster_vorpilAI : public ScriptedAI
|
InstanceScript* instance;
|
||||||
|
bool sayIntro, sayHelp;
|
||||||
|
int count = 0;
|
||||||
|
|
||||||
|
void Reset() override
|
||||||
{
|
{
|
||||||
boss_grandmaster_vorpilAI(Creature* creature) : ScriptedAI(creature), summons(me)
|
sayHelp = false;
|
||||||
|
events.Reset();
|
||||||
|
summons.DespawnAll();
|
||||||
|
if (instance)
|
||||||
{
|
{
|
||||||
instance = creature->GetInstanceScript();
|
instance->SetData(DATA_GRANDMASTER_VORPIL_EVENT, NOT_STARTED);
|
||||||
sayIntro = false;
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
InstanceScript* instance;
|
void summonPortals()
|
||||||
EventMap events;
|
{
|
||||||
SummonList summons;
|
for (uint8 i = 0; i < 5; ++i)
|
||||||
|
|
||||||
bool sayIntro, sayHelp;
|
|
||||||
|
|
||||||
int count = 0;
|
|
||||||
|
|
||||||
void Reset() override
|
|
||||||
{
|
{
|
||||||
sayHelp = false;
|
me->SummonCreature(NPC_VOID_PORTAL, VoidPortalCoords[i][0], VoidPortalCoords[i][1], VoidPortalCoords[i][2], VoidPortalCoords[i][3], TEMPSUMMON_CORPSE_DESPAWN, 3000000);
|
||||||
events.Reset();
|
|
||||||
summons.DespawnAll();
|
|
||||||
|
|
||||||
if (instance)
|
|
||||||
instance->SetData(DATA_GRANDMASTERVORPILEVENT, NOT_STARTED);
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void summonPortals()
|
void spawnVoidTraveler()
|
||||||
|
{
|
||||||
|
uint8 pos = urand(0, 4);
|
||||||
|
me->SummonCreature(NPC_VOID_TRAVELER, VoidPortalCoords[pos][0], VoidPortalCoords[pos][1], VoidPortalCoords[pos][2], VoidPortalCoords[pos][3], TEMPSUMMON_CORPSE_TIMED_DESPAWN, 5000);
|
||||||
|
if (!sayHelp)
|
||||||
{
|
{
|
||||||
for (uint8 i = 0; i < 5; ++i)
|
Talk(SAY_HELP);
|
||||||
me->SummonCreature(NPC_VOID_PORTAL, VoidPortalCoords[i][0], VoidPortalCoords[i][1], VoidPortalCoords[i][2], VoidPortalCoords[i][3], TEMPSUMMON_CORPSE_DESPAWN, 3000000);
|
sayHelp = true;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void spawnVoidTraveler()
|
int counterVoidSpawns(int count)
|
||||||
|
{
|
||||||
|
int timer = 0;
|
||||||
|
switch(count)
|
||||||
{
|
{
|
||||||
uint8 pos = urand(0, 4);
|
case 1:
|
||||||
me->SummonCreature(NPC_VOID_TRAVELER, VoidPortalCoords[pos][0], VoidPortalCoords[pos][1], VoidPortalCoords[pos][2], VoidPortalCoords[pos][3], TEMPSUMMON_CORPSE_TIMED_DESPAWN, 5000);
|
case 2:
|
||||||
if (!sayHelp)
|
timer = 13300;
|
||||||
{
|
break;
|
||||||
Talk(SAY_HELP);
|
case 3:
|
||||||
sayHelp = true;
|
timer = 12100;
|
||||||
}
|
break;
|
||||||
|
case 4:
|
||||||
|
timer = 10900;
|
||||||
|
break;
|
||||||
|
case 5:
|
||||||
|
case 6:
|
||||||
|
timer = 9700;
|
||||||
|
break;
|
||||||
|
case 7:
|
||||||
|
case 8:
|
||||||
|
timer = 7200;
|
||||||
|
break;
|
||||||
|
case 9:
|
||||||
|
timer = 6000;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
timer = 4800;
|
||||||
}
|
}
|
||||||
|
return timer;
|
||||||
|
}
|
||||||
|
|
||||||
int counterVoidSpawns(int count)
|
void JustSummoned(Creature* summon) override
|
||||||
|
{
|
||||||
|
summons.Summon(summon);
|
||||||
|
if (summon->GetEntry() == NPC_VOID_TRAVELER)
|
||||||
{
|
{
|
||||||
int timer = 0;
|
summon->AI()->SetGUID(me->GetGUID());
|
||||||
switch(count)
|
|
||||||
{
|
|
||||||
case 1:
|
|
||||||
case 2:
|
|
||||||
timer = 13300;
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
timer = 12100;
|
|
||||||
break;
|
|
||||||
case 4:
|
|
||||||
timer = 10900;
|
|
||||||
break;
|
|
||||||
case 5:
|
|
||||||
case 6:
|
|
||||||
timer = 9700;
|
|
||||||
break;
|
|
||||||
case 7:
|
|
||||||
case 8:
|
|
||||||
timer = 7200;
|
|
||||||
break;
|
|
||||||
case 9:
|
|
||||||
timer = 6000;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
timer = 4800;
|
|
||||||
}
|
|
||||||
return timer;
|
|
||||||
}
|
}
|
||||||
|
else if (summon->GetEntry() == NPC_VOID_PORTAL)
|
||||||
void JustSummoned(Creature* summon) override
|
|
||||||
{
|
{
|
||||||
summons.Summon(summon);
|
summon->CastSpell(summon, SPELL_VOID_PORTAL_VISUAL, false);
|
||||||
if (summon->GetEntry() == NPC_VOID_TRAVELER)
|
|
||||||
summon->AI()->SetGUID(me->GetGUID());
|
|
||||||
else if (summon->GetEntry() == NPC_VOID_PORTAL)
|
|
||||||
summon->CastSpell(summon, SPELL_VOID_PORTAL_VISUAL, false);
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void KilledUnit(Unit* victim) override
|
void KilledUnit(Unit* victim) override
|
||||||
|
{
|
||||||
|
if (victim->GetTypeId() == TYPEID_PLAYER)
|
||||||
{
|
{
|
||||||
if (victim->GetTypeId() == TYPEID_PLAYER)
|
Talk(SAY_SLAY);
|
||||||
Talk(SAY_SLAY);
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void JustDied(Unit* /*killer*/) override
|
void JustDied(Unit* /*killer*/) override
|
||||||
|
{
|
||||||
|
Talk(SAY_DEATH);
|
||||||
|
summons.DespawnAll();
|
||||||
|
if (instance)
|
||||||
{
|
{
|
||||||
Talk(SAY_DEATH);
|
instance->SetData(DATA_GRANDMASTER_VORPIL_EVENT, DONE);
|
||||||
summons.DespawnAll();
|
|
||||||
|
|
||||||
if (instance)
|
|
||||||
instance->SetData(DATA_GRANDMASTERVORPILEVENT, DONE);
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void JustEngagedWith(Unit* /*who*/) override
|
void JustEngagedWith(Unit* /*who*/) override
|
||||||
|
{
|
||||||
|
Talk(SAY_AGGRO);
|
||||||
|
summonPortals();
|
||||||
|
events.ScheduleEvent(EVENT_SPELL_SHADOWBOLT, urand(9700, 20000));
|
||||||
|
events.ScheduleEvent(EVENT_SPELL_DRAWSHADOWS, 36400);
|
||||||
|
events.ScheduleEvent(EVENT_SUMMON_TRAVELER, 10900);
|
||||||
|
if (IsHeroic())
|
||||||
{
|
{
|
||||||
Talk(SAY_AGGRO);
|
events.ScheduleEvent(EVENT_SPELL_BANISH, urand(17000, 28000));
|
||||||
summonPortals();
|
|
||||||
|
|
||||||
events.ScheduleEvent(EVENT_SPELL_SHADOWBOLT, urand(9700, 20000));
|
|
||||||
events.ScheduleEvent(EVENT_SPELL_DRAWSHADOWS, 36400);
|
|
||||||
events.ScheduleEvent(EVENT_SUMMON_TRAVELER, 10900);
|
|
||||||
if (IsHeroic())
|
|
||||||
{
|
|
||||||
events.ScheduleEvent(EVENT_SPELL_BANISH, urand(17000, 28000));
|
|
||||||
}
|
|
||||||
if (instance)
|
|
||||||
{
|
|
||||||
instance->SetData(DATA_GRANDMASTERVORPILEVENT, IN_PROGRESS);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
if (instance)
|
||||||
void MoveInLineOfSight(Unit* who) override
|
|
||||||
{
|
{
|
||||||
ScriptedAI::MoveInLineOfSight(who);
|
instance->SetData(DATA_GRANDMASTER_VORPIL_EVENT, IN_PROGRESS);
|
||||||
|
|
||||||
if (!sayIntro && who->GetTypeId() == TYPEID_PLAYER)
|
|
||||||
{
|
|
||||||
Talk(SAY_INTRO);
|
|
||||||
sayIntro = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void UpdateAI(uint32 diff) override
|
void MoveInLineOfSight(Unit* who) override
|
||||||
|
{
|
||||||
|
ScriptedAI::MoveInLineOfSight(who);
|
||||||
|
if (!sayIntro && who->GetTypeId() == TYPEID_PLAYER)
|
||||||
{
|
{
|
||||||
if (!UpdateVictim())
|
Talk(SAY_INTRO);
|
||||||
return;
|
sayIntro = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
events.Update(diff);
|
void UpdateAI(uint32 diff) override
|
||||||
switch (events.ExecuteEvent())
|
{
|
||||||
{
|
if (!UpdateVictim())
|
||||||
case EVENT_SPELL_SHADOWBOLT:
|
return;
|
||||||
me->CastSpell(me, SPELL_SHADOWBOLT_VOLLEY, false);
|
|
||||||
events.RepeatEvent(urand(9700, 20000));
|
events.Update(diff);
|
||||||
break;
|
switch (events.ExecuteEvent())
|
||||||
case EVENT_SPELL_BANISH:
|
{
|
||||||
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 30, false))
|
case EVENT_SPELL_SHADOWBOLT:
|
||||||
me->CastSpell(target, SPELL_BANISH, false);
|
DoCastAOE(SPELL_SHADOWBOLT_VOLLEY);
|
||||||
events.RepeatEvent(urand(17000, 28000));
|
events.RepeatEvent(urand(9700, 20000));
|
||||||
break;
|
break;
|
||||||
case EVENT_SUMMON_TRAVELER:
|
case EVENT_SPELL_BANISH:
|
||||||
spawnVoidTraveler();
|
DoCastRandomTarget(SPELL_BANISH, 0, 30.0f, true);
|
||||||
count++;
|
events.RepeatEvent(urand(17000, 28000));
|
||||||
events.RepeatEvent(counterVoidSpawns(count));
|
break;
|
||||||
break;
|
case EVENT_SUMMON_TRAVELER:
|
||||||
case EVENT_SPELL_DRAWSHADOWS:
|
spawnVoidTraveler();
|
||||||
|
count++;
|
||||||
|
events.RepeatEvent(counterVoidSpawns(count));
|
||||||
|
break;
|
||||||
|
case EVENT_SPELL_DRAWSHADOWS:
|
||||||
|
{
|
||||||
|
DoCastSelf(SPELL_DRAW_SHADOWS, true);
|
||||||
|
Map* map = me->GetMap();
|
||||||
|
Map::PlayerList const& PlayerList = map->GetPlayers();
|
||||||
|
for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i)
|
||||||
{
|
{
|
||||||
me->CastSpell(me, SPELL_DRAW_SHADOWS, true);
|
if (Player* player = i->GetSource())
|
||||||
Map* map = me->GetMap();
|
{
|
||||||
Map::PlayerList const& PlayerList = map->GetPlayers();
|
if (player->IsAlive() && !player->HasAura(SPELL_BANISH))
|
||||||
for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i)
|
{
|
||||||
if (Player* player = i->GetSource())
|
player->TeleportTo(me->GetMapId(), VorpilPosition[0], VorpilPosition[1], VorpilPosition[2], 0, TELE_TO_NOT_LEAVE_COMBAT);
|
||||||
if (player->IsAlive() && !player->HasAura(SPELL_BANISH))
|
}
|
||||||
player->TeleportTo(me->GetMapId(), VorpilPosition[0], VorpilPosition[1], VorpilPosition[2], 0, TELE_TO_NOT_LEAVE_COMBAT);
|
}
|
||||||
|
|
||||||
me->NearTeleportTo(VorpilPosition[0], VorpilPosition[1], VorpilPosition[2], 0.0f);
|
|
||||||
events.ScheduleEvent(EVENT_SPELL_RAIN_OF_FIRE, 1000);
|
|
||||||
events.RepeatEvent(urand(36400, 44950));
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
case EVENT_SPELL_RAIN_OF_FIRE:
|
me->NearTeleportTo(VorpilPosition[0], VorpilPosition[1], VorpilPosition[2], 0.0f);
|
||||||
me->CastSpell(me, DUNGEON_MODE(SPELL_RAIN_OF_FIRE_N, SPELL_RAIN_OF_FIRE_H));
|
events.ScheduleEvent(EVENT_SPELL_RAIN_OF_FIRE, 1000);
|
||||||
events.DelayEvents(6000);
|
events.RepeatEvent(urand(36400, 44950));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
DoMeleeAttackIfReady();
|
case EVENT_SPELL_RAIN_OF_FIRE:
|
||||||
|
DoCastSelf(DUNGEON_MODE(SPELL_RAIN_OF_FIRE_N, SPELL_RAIN_OF_FIRE_H));
|
||||||
|
events.DelayEvents(6000);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
};
|
DoMeleeAttackIfReady();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class npc_voidtraveler : public CreatureScript
|
struct npc_voidtraveler : public ScriptedAI
|
||||||
{
|
{
|
||||||
public:
|
npc_voidtraveler(Creature* creature) : ScriptedAI(creature) {}
|
||||||
npc_voidtraveler() : CreatureScript("npc_voidtraveler") { }
|
|
||||||
|
|
||||||
CreatureAI* GetAI(Creature* creature) const override
|
ObjectGuid VorpilGUID;
|
||||||
|
uint32 moveTimer;
|
||||||
|
bool sacrificed;
|
||||||
|
|
||||||
|
void Reset() override
|
||||||
{
|
{
|
||||||
return GetShadowLabyrinthAI<npc_voidtravelerAI>(creature);
|
moveTimer = 1000;
|
||||||
|
sacrificed = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct npc_voidtravelerAI : public ScriptedAI
|
void SetGUID(ObjectGuid guid, int32) override
|
||||||
{
|
{
|
||||||
npc_voidtravelerAI(Creature* creature) : ScriptedAI(creature)
|
VorpilGUID = guid;
|
||||||
{
|
}
|
||||||
moveTimer = 1000;
|
|
||||||
sacrificed = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
ObjectGuid VorpilGUID;
|
void UpdateAI(uint32 diff) override
|
||||||
uint32 moveTimer;
|
{
|
||||||
bool sacrificed;
|
moveTimer += diff;
|
||||||
|
if (moveTimer >= 1000)
|
||||||
void SetGUID(ObjectGuid guid, int32) override
|
|
||||||
{
|
{
|
||||||
VorpilGUID = guid;
|
moveTimer = 0;
|
||||||
}
|
Creature* Vorpil = ObjectAccessor::GetCreature(*me, VorpilGUID);
|
||||||
|
if (!Vorpil)
|
||||||
void UpdateAI(uint32 diff) override
|
|
||||||
{
|
|
||||||
moveTimer += diff;
|
|
||||||
if (moveTimer >= 1000)
|
|
||||||
{
|
{
|
||||||
moveTimer = 0;
|
me->DespawnOrUnsummon();
|
||||||
Creature* Vorpil = ObjectAccessor::GetCreature(*me, VorpilGUID);
|
return;
|
||||||
if (!Vorpil)
|
}
|
||||||
{
|
me->GetMotionMaster()->MoveFollow(Vorpil, 0.0f, 0.0f);
|
||||||
me->DespawnOrUnsummon();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
me->GetMotionMaster()->MoveFollow(Vorpil, 0.0f, 0.0f);
|
|
||||||
|
|
||||||
if (sacrificed)
|
if (sacrificed)
|
||||||
{
|
{
|
||||||
me->AddAura(DUNGEON_MODE(SPELL_EMPOWERING_SHADOWS_N, SPELL_EMPOWERING_SHADOWS_H), Vorpil);
|
Vorpil->AddAura(DUNGEON_MODE(SPELL_EMPOWERING_SHADOWS_N, SPELL_EMPOWERING_SHADOWS_H), Vorpil);
|
||||||
Vorpil->ModifyHealth(int32(Vorpil->CountPctFromMaxHealth(4)));
|
Vorpil->ModifyHealth(int32(Vorpil->CountPctFromMaxHealth(4)));
|
||||||
me->CastSpell(me, SPELL_SHADOW_NOVA, true);
|
DoCastAOE(SPELL_SHADOW_NOVA, true);
|
||||||
me->KillSelf();
|
me->KillSelf();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (me->IsWithinDist(Vorpil, 3.0f))
|
if (me->IsWithinDist(Vorpil, 3.0f))
|
||||||
{
|
{
|
||||||
me->CastSpell(me, SPELL_SACRIFICE, false);
|
DoCastSelf(SPELL_SACRIFICE);
|
||||||
sacrificed = true;
|
sacrificed = true;
|
||||||
moveTimer = 500;
|
moveTimer = 500;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
void AddSC_boss_grandmaster_vorpil()
|
void AddSC_boss_grandmaster_vorpil()
|
||||||
{
|
{
|
||||||
new boss_grandmaster_vorpil();
|
RegisterShadowLabyrinthCreatureAI(boss_grandmaster_vorpil);
|
||||||
new npc_voidtraveler();
|
RegisterShadowLabyrinthCreatureAI(npc_voidtraveler);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -68,7 +68,7 @@ public:
|
|||||||
break;
|
break;
|
||||||
case SCREAMING_HALL_DOOR:
|
case SCREAMING_HALL_DOOR:
|
||||||
m_uiScreamingHallDoorGUID = go->GetGUID();
|
m_uiScreamingHallDoorGUID = go->GetGUID();
|
||||||
if (m_auiEncounter[DATA_GRANDMASTERVORPILEVENT] == DONE)
|
if (m_auiEncounter[DATA_GRANDMASTER_VORPIL_EVENT] == DONE)
|
||||||
go->SetGoState(GO_STATE_ACTIVE);
|
go->SetGoState(GO_STATE_ACTIVE);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -116,7 +116,7 @@ public:
|
|||||||
m_auiEncounter[type] = uiData;
|
m_auiEncounter[type] = uiData;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DATA_GRANDMASTERVORPILEVENT:
|
case DATA_GRANDMASTER_VORPIL_EVENT:
|
||||||
if (uiData == DONE)
|
if (uiData == DONE)
|
||||||
DoUseDoorOrButton(m_uiScreamingHallDoorGUID);
|
DoUseDoorOrButton(m_uiScreamingHallDoorGUID);
|
||||||
m_auiEncounter[type] = uiData;
|
m_auiEncounter[type] = uiData;
|
||||||
|
|||||||
@@ -30,10 +30,11 @@ enum slData
|
|||||||
TYPE_RITUALISTS = 0,
|
TYPE_RITUALISTS = 0,
|
||||||
TYPE_HELLMAW = 1,
|
TYPE_HELLMAW = 1,
|
||||||
DATA_BLACKHEARTTHEINCITEREVENT = 2,
|
DATA_BLACKHEARTTHEINCITEREVENT = 2,
|
||||||
DATA_GRANDMASTERVORPILEVENT = 3,
|
DATA_GRANDMASTER_VORPIL = 3,
|
||||||
DATA_MURMUR = 4,
|
DATA_GRANDMASTER_VORPIL_EVENT = 4,
|
||||||
DATA_MURMUREVENT = 5,
|
DATA_MURMUR = 5,
|
||||||
MAX_ENCOUNTER = 6
|
DATA_MURMUREVENT = 6,
|
||||||
|
MAX_ENCOUNTER = 7
|
||||||
};
|
};
|
||||||
|
|
||||||
enum slNPCandGO
|
enum slNPCandGO
|
||||||
|
|||||||
Reference in New Issue
Block a user