mirror of
https://github.com/ProjectEQ/projecteqquests
synced 2026-08-12 00:26:10 -04:00
483 lines
16 KiB
Lua
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
|