peq-quests/chambersc/encounters/mpg_foresight.lua
2023-08-06 23:02:10 -04:00

483 lines
16 KiB
Lua

-- Mastery of Foresight Raid Trial
-- MPG Raid Trial General Notes
-- 1 MPG_hate - The Mastery of Hate (Raid)
-- 2 MPG_endurance - The Mastery of Endurance (Raid)
-- 4 MPG_foresight - The Mastery of Foresight (Raid)
-- 8 MPG_specialization - The Mastery of Specialization (Raid)
-- 16 MPG_adaptation - The Mastery of Adaptation (Raid)
-- 32 MPG_corruption - The Mastery of Corruption (Raid)
--
-- Lockout on Win: 5 days
-- Lockout on Loss: 3 hours
-- Flag Global
-- mpg_group_trials
-- mpg_raid_trials
local event_started = false;
local instance_id;
local lockout_win = "5d";
local lockout_loss = "3h";
local this_zone = 'chambersc';
local this_bit = 4;
local player_list;
local warnings = 0;
local emotes = {};
local hazards = {};
local hazard_timer = 30;
local kyvs = {};
local kyv_client;
local kyv_targets = {};
local kyv_timer = 10;
local equipment = {};
local equipment_client;
local equipment_timer = 15;
local dragorns = {};
local dragorn_timer = 35;
local last_emote = '';
local emote_grace = 8;
local client_list;
function setup()
hazards = {
[1] = { "The room begins to heat up dramatically. The north side looks safe.", north_safe },
[2] = { "The room begins to heat up dramatically. The south side looks safe.", south_safe },
[3] = { "The room begins to heat up dramatically. The east side looks safe.", east_safe },
[4] = { "The room begins to heat up dramatically. The west side looks safe.", west_safe },
};
other_emotes = {
[2] = { "The room begins to heat up dramatically. The center looks safe.", center_safe },
[10] = { "You notice that the Dragorn before you is preparing to cast a devastating spell. Doing enough damage to him might interrupt the process." },
};
kyvs = {
[1] = { "From the corner of your eye, you notice a Kyv taking aim at your position. You should move.", kyv_move, 5696, "You are struck by a stray arrow!"},
[2] = { "From the corner of your eye, you notice a Kyv taking aim near your position. He appears to be leading the target, anticipating your next movement. You should stand still.", kyv_stop, 5696 ,"You are struck by a stray arrow!"},
[3] = { "From the corner of your eye, you notice a Kyv taking aim at your head. You should duck.", kyv_duck, 5694 ,"Your head is struck by a deadly arrow!"},
};
equipment = {
[1] = { "Your rings constrict and bite into your fingers. You should remove them.", check_rings },
[2] = { "The Weapon in your right hand begins to heat up dramatically. You should remove it.", check_weapon }
};
dragorns = {
[1] = { "You notice that the Dragorn before you is preparing to cast a devastating close-range spell.", 5693, cast_5693 },
[2] = { "The Dragorn before you is developing an anti-magic aura.", 5699, self_cast },
[3] = { "The Dragorn before you is sprouting sharp spikes.", 5698, self_cast },
[4] = { "You notice that the Dragorn before you is making preparations to cast a devastating spell. Doing enough damage to him might interrupt the process." , 5693, cast_5693 }
};
end
function Start_Event(e)
last_emote = '';
event_started = true;
eq.spawn2(306020,0,0,0,0,0,0); -- NPC: #death_touch
eq.spawn2(306013,0,0,-161,385,60,284); -- Dragorn Acolyte
eq.spawn2(306014,0,0,-256,384,60,220); -- Dragorn Adept
eq.spawn2(306015,0,0,-315,317,60,160); -- Dragorn Annihilator
eq.spawn2(306016,0,0,-316,223,60,96); -- Dragorn Flamecaster
eq.spawn2(306017,0,0,-249,164,60,30); -- Dragorn Incinerator
eq.spawn2(306018,0,0,-158,160,60,482); -- Dragorn Spellscribe
eq.spawn2(306012,0,0,-194,286,66,96); -- a kyv sureshot
eq.spawn2(306021,0,0,-227,290,66,428); -- a kyv sureshot
eq.spawn2(306022,0,0,-223,260,66,276); -- a kyv sureshot
eq.spawn2(306023,0,0,-188,257,66,166); -- a kyv sureshot
eq.spawn2(306011,0,0,e.self:GetX(),e.self:GetY(),e.self:GetZ(),0); -- NPC: a_hazard
eq.set_timer("emotes", 5 * 1000);
eq.set_timer("equipment", equipment_timer * 1000);
client_list = eq.get_characters_in_instance(instance_id);
end
function Boss_Spawn(e)
event_started = false;
instance_id = eq.get_zone_instance_id();
player_list = eq.get_characters_in_instance(instance_id);
emote_grace = 8;
end
function Boss_Say(e)
if not event_started then
if ValidatePlayersAreInZone(e.other) then
if e.message:findi("hail") then
e.self:Say("This is the Mastery of Foresight Trial. You must react quickly to deadly and unforgiving hazards. Are you ready to [begin]?");
elseif e.message:findi("begin") then
local dz = eq.get_expedition()
if dz.valid then
dz:SetLocked(true, ExpeditionLockMessage.Begin, 14) -- live uses "Event Messages" type 365 (not in emu clients)
dz:AddReplayLockout(eq.seconds(lockout_loss))
end
e.self:Say("Very well! Let the battle commence!");
Start_Event(e);
end
else
e.self:Say("It appears all members of your adventure are not present, please have them join you before you begin.");
end
end
end
function ValidatePlayersAreInZone(requestor)
local el = eq.get_entity_list();
for k,v in pairs(player_list) do
member = el:GetClientByCharID(v)
if not member.valid then
requestor:Message(MT.Red, "All members of the group/raid need to be in " .. eq.get_zone_long_name() .. ". " );
return false;
end
end
return true;
end
function Do_Hazard()
local num = math.random(1,#hazards);
if last_hazard == num then
Do_Hazard();
else
last_hazard = num;
eq.zone_emote(MT.Lime, hazards[num][1]);
hazards[num][2]();
end
end
function Boss_Timer(e)
local client;
local num;
eq.stop_timer(e.timer);
if e.timer == "equipment" then
client = eq.get_entity_list():GetRandomClient(-204,270,65,150000);
if client.valid then
num = math.random(1,#equipment);
equipment_client = {client:GetID(), num};
client:Message(MT.Lime, equipment[num][1]);
eq.set_timer("equipment_action", 3 * 1000);
end
elseif e.timer == "equipment_action" then
client = eq.get_entity_list():GetClientByID(equipment_client[1]);
if client.valid then
num = equipment_client[2];
equipment[num][2](e.self,client);
eq.set_timer("equipment", equipment_timer * 1000);
end
end
end
function Boss_Signal(e)
if e.signal == 1 then
-- Check to see if any of the Dragorn are still alive.
local el = eq.get_entity_list();
if not el:IsMobSpawnedByNpcTypeID(306013) and not el:IsMobSpawnedByNpcTypeID(306014) and not el:IsMobSpawnedByNpcTypeID(306015) and not el:IsMobSpawnedByNpcTypeID(306016) and not el:IsMobSpawnedByNpcTypeID(306017) and not el:IsMobSpawnedByNpcTypeID(306018) then
Event_Win(e);
end
elseif e.signal == 9 then
-- received a signal that someone has zoned out
-- recheck the current client count v/s the count
-- when the event started
local now_clients = eq.get_entity_list():GetClientList();
local count = 0;
for v in now_clients.entries do
count = count + 1;
end
if count < 6 then
Event_Loss(e);
end
end
end
function Kyv_Spawn(e)
eq.set_timer('kyv', kyv_timer * 1000);
end
function Kyv_Timer(e)
local msg = '';
local client;
local num;
local loc;
local i;
if e.timer == 'kyv' then
eq.stop_timer(e.timer);
i = e.self:GetNPCTypeID();
client = eq.get_entity_list():GetRandomClient(-204, 270, 65, 150000);
if client.valid then
num = math.random(1,#kyvs);
kyv_targets[i] = { client:GetID(), num, {client:GetX(), client:GetY() }};
client:Message(MT.Lime, kyvs[num][1]);
eq.set_timer('kyv_action', 3000);
end
elseif e.timer == 'kyv_action' then
eq.stop_timer(e.timer);
i = e.self:GetNPCTypeID();
client = eq.get_entity_list():GetClientByID(kyv_targets[i][1]);
if client.valid then
loc = kyv_targets[i][3];
if not kyvs[kyv_targets[i][2]][2](e, client, loc) then
client:Message(MT.Lime, kyvs[kyv_targets[i][2]][4]);
e.self:CastSpell(kyvs[kyv_targets[i][2]][3], client:GetID(), 0, 4500);
else
msg = 'An arrow narrowly misses you.';
end
client:Message(MT.Lime, msg);
end
eq.set_timer('kyv', kyv_timer * 1000 + 4500);
end
end
-- Return true if client moved
-- Return false if they did not
function kyv_move(e, client, loc)
if client.valid then
if loc[1] == client:GetX() and loc[2] == client:GetY() then
return false;
end
end
return true;
end
-- Return true if client has stopped or engaged in battle
-- Return false if they are moving or engaged in battle
function kyv_stop(e, client, loc)
if client.valid then
if client:IsMoving() or client:IsEngaged() then
return false;
end
end
return true;
end
-- Return true if client has ducked
-- return false if client has not ducked
function kyv_duck(e, client, loc)
if client.valid then
if client:GetAppearance() == Appearance.Crouching then
return true;
end
end
return false;
end
function Hazard_Spawn(e)
eq.set_timer('hazard', hazard_timer * 1000);
end
function Hazard_Timer(e)
eq.stop_timer(e.timer);
if e.timer == "north" then
ae_check(e, -327, -89, 270, 398);
elseif e.timer == "south" then
ae_check(e, -327, -89, 150, 270);
elseif e.timer == "east" then
ae_check(e, -327, -206, 150, 398);
elseif e.timer == "west" then
ae_check(e, -206, -89, 150, 398);
elseif e.timer == "hazard" then
Do_Hazard();
end
end
function check_rings(mob, client)
if client.valid then
if client:GetItemIDAt(Slot.Finger1) ~= -1 then
client:Message(MT.Lime, "Your rings clamp down, breaking fingers and disabling your manual dexterity.");
mob:CastSpell(5695, client:GetID()); -- Spell: Crippling Clamp
else
client:Message(MT.Lime, "Your regain the use of your fingers.");
end
if client:GetItemIDAt(Slot.Finger2) ~= -1 then
client:Message(MT.Lime, "Your rings clamp down, breaking fingers and disabling your manual dexterity.");
mob:CastSpell(5695, client:GetID()); -- Spell: Crippling Clamp
else
client:Message(MT.Lime, "Your regain the use of your fingers.");
end
end
end
function check_weapon(mob, client)
if client.valid then
if client:GetItemIDAt(Slot.Secondary) ~= -1 then
client:Message(MT.Lime, "Your weaponry becomes incredibly hot, searing your hands!");
mob:CastSpell(2315, client:GetID()); -- Spell: Searing Heat
else
client:Message(MT.Lime, "Your weaponry cools down.");
end
end
end
function ae_check(e, xmin, xmax, ymin, ymax)
local cl = eq.get_entity_list():GetClientList();
local x,y;
for v in cl.entries do
if v.valid then
x = v:GetX();
y = v:GetY();
if x < xmin or x > xmax or y < ymin or y > ymax then
v:Message(MT.Lime,'The room explodes with chaotic energy.');
--e.self:CastSpell(5693, v:GetID());
v:Damage(e.self, 5000, 5693, 1);
else
v:Message(MT.Lime,'The room explodes with chaotic energy.');
v:Message(MT.Lime,'You escape the blast unscathed.');
end
end
end
eq.set_timer('hazard', hazard_timer * 1000);
end
function north_safe()
eq.set_timer('north', emote_grace * 1000);
end
function center_safe()
eq.zone_emote(MT.Yellow, "Center Safe");
end
function south_safe()
eq.set_timer("south", emote_grace * 1000);
end
function east_safe()
eq.set_timer("east", emote_grace * 1000);
end
function west_safe()
eq.set_timer("west", emote_grace * 1000);
end
function Dragorn_Spawn(e)
eq.set_timer('dragorn', dragorn_timer * 1000);
end
function Dragorn_Death(e)
eq.signal(306019, 1); -- NPC: Master_of_Foresight
end
function Dragorn_Timer(e)
local num;
if e.timer == 'dragorn' then
num = math.random(1,#dragorns);
local dist = 50;
local mob_x = e.self:GetX();
local mob_y = e.self:GetY();
local x,y,z;
local cl = eq.get_entity_list():GetClientList();
for v in cl.entries do
if v.valid then
x = v:GetX(); y = v:GetY(); z = v:GetZ();
if e.self:CalculateDistance( x, y, z ) < dist then
v:Message(MT.Lime, dragorns[num][1]);
end
end
end
-- eq.set_timer('dragorn_cast', dragorn_timer * 1000);
dragorns[num][3](e.self, dragorns[num][2]);
--in here there should be a check to see if we did enough damage to prevent getting nuked (flashfire). ballpark 50k damage required to interrupt
--all dragorn spells are ~8 seconds after emote
--elseif (e.timer == 'dragorn_cast') then
end
end
function cast_5693(mob, spell)
local dist = 30;
local mob_x = mob:GetX();
local mob_y = mob:GetY();
local x,y,z;
local cl = eq.get_entity_list():GetClientList();
for v in cl.entries do
if v.valid then
x = v:GetX(); y = v:GetY(); z = v:GetZ();
if mob:CalculateDistance( x, y, z ) < dist then
mob:CastSpell(spell, v:GetID(),0,8000);
end
end
end
end
--dragorns only use this
function self_cast(mob,spell)
mob:CastSpell(spell, mob:GetID(),0,8000);
end
--repop_zone does not work
function Event_Loss(e)
eq.depop_with_timer();
eq.repop_zone();
end
function Event_Win(e)
-- Depop the hazards
eq.depop_all(306011);
-- Depop the sureshots
eq.depop_all(306012);
eq.depop_all(306021);
eq.depop_all(306022);
eq.depop_all(306023);
-- Disable the deathtouch
eq.depop_all(306020);
-- Spawn Shell of the Master
eq.spawn2(306024,0,0,-204,274,66,144); -- NPC: Shell_of_the_Master_
-- Update the Lockouts
local dz = eq.get_expedition()
if dz.valid then
dz:AddReplayLockoutDuration(eq.seconds(lockout_win)) -- 5 days + current timer (max 123 hours)
end
local mpg_helper = require("mpg_helper");
mpg_helper.UpdateRaidTrialFlag(player_list, this_bit);
eq.depop_with_timer();
end
function event_encounter_load(e)
setup();
eq.register_npc_event('mpg_foresight', Event.spawn, 306019, Boss_Spawn);
eq.register_npc_event('mpg_foresight', Event.say, 306019, Boss_Say);
eq.register_npc_event('mpg_foresight', Event.death_complete, 306019, Boss_Death);
eq.register_npc_event('mpg_foresight', Event.timer, 306019, Boss_Timer);
eq.register_npc_event('mpg_foresight', Event.signal, 306019, Boss_Signal);
eq.register_npc_event('mpg_foresight', Event.spawn, 306011, Hazard_Spawn);
eq.register_npc_event('mpg_foresight', Event.timer, 306011, Hazard_Timer);
eq.register_npc_event('mpg_foresight', Event.spawn, 306012, Kyv_Spawn);
eq.register_npc_event('mpg_foresight', Event.timer, 306012, Kyv_Timer);
eq.register_npc_event('mpg_foresight', Event.spawn, 306021, Kyv_Spawn);
eq.register_npc_event('mpg_foresight', Event.timer, 306021, Kyv_Timer);
eq.register_npc_event('mpg_foresight', Event.spawn, 306022, Kyv_Spawn);
eq.register_npc_event('mpg_foresight', Event.timer, 306022, Kyv_Timer);
eq.register_npc_event('mpg_foresight', Event.spawn, 306023, Kyv_Spawn);
eq.register_npc_event('mpg_foresight', Event.timer, 306023, Kyv_Timer);
eq.register_npc_event('mpg_foresight', Event.spawn, 306013, Dragorn_Spawn);
eq.register_npc_event('mpg_foresight', Event.spawn, 306014, Dragorn_Spawn);
eq.register_npc_event('mpg_foresight', Event.spawn, 306015, Dragorn_Spawn);
eq.register_npc_event('mpg_foresight', Event.spawn, 306016, Dragorn_Spawn);
eq.register_npc_event('mpg_foresight', Event.spawn, 306017, Dragorn_Spawn);
eq.register_npc_event('mpg_foresight', Event.spawn, 306018, Dragorn_Spawn);
eq.register_npc_event('mpg_foresight', Event.timer, 306013, Dragorn_Timer);
eq.register_npc_event('mpg_foresight', Event.timer, 306014, Dragorn_Timer);
eq.register_npc_event('mpg_foresight', Event.timer, 306015, Dragorn_Timer);
eq.register_npc_event('mpg_foresight', Event.timer, 306016, Dragorn_Timer);
eq.register_npc_event('mpg_foresight', Event.timer, 306017, Dragorn_Timer);
eq.register_npc_event('mpg_foresight', Event.timer, 306018, Dragorn_Timer);
eq.register_npc_event('mpg_foresight', Event.death_complete, 306013, Dragorn_Death);
eq.register_npc_event('mpg_foresight', Event.death_complete, 306014, Dragorn_Death);
eq.register_npc_event('mpg_foresight', Event.death_complete, 306015, Dragorn_Death);
eq.register_npc_event('mpg_foresight', Event.death_complete, 306016, Dragorn_Death);
eq.register_npc_event('mpg_foresight', Event.death_complete, 306017, Dragorn_Death);
eq.register_npc_event('mpg_foresight', Event.death_complete, 306018, Dragorn_Death);
end
function event_encounter_unload(e)
end