Skip to content

Expedition Methods

void AddLockout(string event_name, uint32 seconds_duration)

Adds an event lockout timer to the expedition with the specified duration.

The lockout is added to all current members of the expedition whether they're inside the zone or not. This also adds the lockout to any clients inside the dynamic zone that are not part of the expedition (in the event that they've quit the expedition and haven't been teleported out yet)

The lockout is also stored internally in the expedition. New members added to the expedition will receive these lockouts once they zone into the expedition's dynamic zone.

The lockout replaces any existing lockout held by the expedition and members.

The lockout is assigned the current expedition's internal uuid for tracking.

Note: The source adds 60s to the lockout timer sent to clients to compensate for the client displaying lockouts rounded down to the nearest minute. If adding lockout times using live packet data subtract 60s from the time (live adds 60s as well)

function event_death(e)
  local expedition = eq.get_expedition() -- current instance's expedition (we should be inside a dz)
  if not expedition.valid then
    eq.debug("report a bug") -- possible fallback would be to manually iterate clients and add lockouts
  else
    expedition:AddLockout("Keldovan the Harrier", 86400) -- add a 1 day lockout
  end
end

void AddLockoutDuration(string event_name, int seconds, bool members_only = true)

Adds duration to existing member lockouts for the event. If seconds is negative then lockout duration is reduced.

Unlike UpdateLockoutDuration which applies a static lockout duration to all members based on the expedition's internal lockout, this modifies each member's existing lockout duration separately.

If a member does not have the specified event lockout and seconds is positive, the lockout is added to the member with the current expedition's uuid.

By default this only updates expedition members. Passing false for members_only will update the expedition's internal lockout duration as well which will affect any future members added to the expedition.

Non-expedition members inside the expedition's dynamic zone instance are always updated

-- inside dz, after killing some progression npcs
function event_death(e)
  local dz = eq.get_expedition()
  if dz.valid then
    -- add durations to each member's current event lockout when specific npcs killed
    -- the expedition's lockout is unaffected, new members will receive original lockout
    if e.self:GetNPCTypeID() == 294042 then
      dz:AddLockout("Some Event", 25200) -- create 7 hour lockout when this npc is killed
    elseif e.self:GetNPCTypeID() == 294043 then
      dz:AddLockoutDuration("Some Event", 57600) -- add 16 hours when this npc is killed
    end
  end
end

void AddReplayLockout(int seconds_duration)

Adds a Replay Timer lockout to the expedition. This is a shortcut alternative to adding the lockout by name through the AddLockout method.

Replay Timer's use a hardcoded event name and are used as a lockout against requesting the expedition itself.

Unlike normal event lockouts, any members added to the expedition after a replay timer has been assigned will receive the lockout immediately with a reset expiration timer based on the original duration.

function event_say(e)
  if e.message == "request" then
    local expedition = e.other:CreateExpedition("anguish", 0, 36000, "Anguish, the Fallen Palace", 6, 54)
    if expedition.valid then
      eq.debug("Expedition creation was succesful")
      expedition:AddReplayLockout(7200) -- 2 hour request lockout
    end
  end
end

void AddReplayLockoutDuration(int seconds, bool members_only = true)

Adds duration to expedition's Replay Timer lockout. See AddLockoutDuration

function event_say(e)
  if e.message == "request" then
    local dz = e.other:CreateExpedition("ikkinz", 0, 21600, "Ikkinz, Chambers of Singular Might", 1, 6)
    if dz.valid then
      expedition:AddReplayLockout(3600) -- 1 hour replay lockout
    end
  end
end

-- inside dz, after killing some progression npcs
function event_death(e)
  local dz = eq.get_expedition()
  if dz.valid then
    if e.self:GetNPCTypeID() == 294042 then
      dz:AddReplayLockoutDuration(25200) -- add 7 hours to replay lockout when this npc is killed
    elseif e.self:GetNPCTypeID() == 294043 then
      -- add 16 hours to replay lockout when this npc is killed
      -- expedition lockout is unaffected, new members will receive the original (7 hours - elapsed)
      dz:AddReplayLockoutDuration(57600)
    end
  end
end

uint32_t GetDynamicZoneID()

Returns the expedition's dynamic zone id

local dz_id = expedition:GetDynamicZoneID()

uint32_t GetID()

Returns the expedition's id

local id = expedition:GetID()

int GetInstanceID()

Returns the expedition's dynamic zone instance id

local instance_id = expedition:GetInstanceID()

string GetLeaderName()

Returns the expedition's current leader name

local leader_name = expedition:GetLeaderName()

LUA_TTABLE GetLockouts()

Returns a table containing the expedition's current internal lockouts and time remaining. This includes lockouts that were inherited by the leader on creation and not just lockouts assigned during the current expedition.

local lockouts = expedition:GetLockouts()
for event_name,remaining in pairs(lockouts) do
  eq.debug(string.format("event: (%s) remaining: (%s)s", event_name, remaining))
end

string GetLootEventByNPCTypeID(uint32 npc_type_id)

string GetLootEventBySpawnID(uint32 spawn_id)

Returns an event name associated with an npc type id or spawn id set by the SetLootEventByNPCTypeID or SetLootEventBySpawnID apis.

Returns an empty string if no event set

Important: This is only valid inside the expedition's dynamic zone instance

function event_death(e)
  local npc_type_id = e.self:GetNPCTypeID()
  local spawn_id = e.self:GetID()
  local dz = eq.get_expedition() -- current instance's expedition (we should be inside a dz)
  if dz.valid then
    local event_name = dz:GetLootEventByNPCTypeID(npc_type_id)
    eq.debug(string.format("Npc type (%s) was associated with event (%s)", npc_type_id, event_name))
    event_name = dz:GetLootEventBySpawnID(spawn_id)
    eq.debug(string.format("This npc entity id (%s) was associated with event (%s)", spawn_id, event_name))
  end
end

int GetMemberCount()

Returns number of members in expedition

local count = dz:GetMemberCount()

LUA_TTABLE GetMembers()

Returns a Lua table containing member names and character ids

local members = dz:GetMembers()
for name,id in pairs(members) do
  eq.debug(string.format("Member name (%s) character id (%s)", name, id))
end

string GetName()

Returns name of the expedition

local expedition_name = dz:GetName()

int GetSecondsRemaining()

Returns seconds remaining until expedition's dynamic zone expires

local seconds_remaining = dz:GetSecondsRemaining()

string GetUUID()

Returns expedition's internal uuid assigned on creation

local uuid = dz:GetUUID()

int GetZoneID()

Returns zone id of the expedition's dynamic zone

local zone_id = dz:GetZoneID()

string GetZoneName()

Returns zone short name of the expedition's dynamic zone

local zone_short_name = dz:GetZoneName()

int GetZoneVersion()

Returns zone version of the expedition's dynamic zone instance

local zone_version = dz:GetZoneVersion()

bool HasLockout(string event_name)

Returns whether the expedition internally has the specified event lockout. This is the primary function that should be used for initialization scripts to determine which events are available to an expedition.

function init()
  local dz = eq.get_expedition()
  if dz.valid then
    local has_lockout = dz:HasLockout("Ture")
    if not has_lockout then
      eq.debug("Expedition doesn't have this lockout, we can spawn this event")
    end
  end
end

bool HasReplayLockout()

Returns whether the expedition internally has a Replay Timer lockout set. Shortcut alternative to checking HasLockout

local has_replay_lockout = dz:HasReplayLockout()

bool IsLocked()

Returns if the expedition is currently locked by SetLocked

local dz = eq.get_expedition()
if dz.valid then
  if dz:IsLocked() then
    eq.debug("expedition is locked")
  else
    eq.debug("expedition is not locked")
  end
end

void RemoveCompass()

Removes any compass set by SetCompass

dz:RemoveCompass()

void RemoveLockout(string event_name)

Removes the lockout from the expedition and from any current members

dz:RemoveLockout("Ture")

void SetCompass(int zone_id, float x, float y, float z)

void SetCompass(string zone_short_name, float x, float y, float z)

Set the location of the expedition's dynamic zone compass. This only applies to non-instances outside of the dz.

function event_say(e)
  if e.message == "request" then
    local dz = e.other:CreateExpedition("anguish", 0, 36000, "Anguish, the Fallen Palace", 6, 54)
    if dz.valid then
      -- set compass to the anguish door inside wallofslaughter by zone id
      dz:SetCompass(300, 1353.15, 1712.19, 109.001)
      -- set compass to the anguish door inside wallofslaughter by zone name
      dz:SetCompass("wallofslaughter", 1353.15, 1712.19, 109.001)
    end
  end
end

void SetLocked(bool locked, ExpeditionLockMessage lock_msg = ExpeditionLockMessage::None, uint32_t msg_color = Chat::Yellow)

If true, lock an expedition to prevent new members from being added. False unlocks.

Passing a lock_msg sends an expedition locked message to clients inside the expedition's dynamic zone. See ExpeditionLockMessage for types and messages

function event_death(e)
  local dz = eq.get_expedition()
  if dz.valid then
    -- no new members may be added to this expedition until it's unlocked
    dz:SetLocked(true, ExpeditionLockMessage.Close)
  end
end

void SetLootEventByNPCTypeID(uint32_t npc_type_id, string event_name)

Important: This must be set from a script inside the expedition's dynamic zone instance

Associates an event with the specified npc type id to prevent it from being looted by characters that didn't receive the event lockout from the current expedition.

This is an important initialization step to prevent exploits in expeditions

function init()
  local dz = eq.get_expedition()
  if dz.valid then
    -- associate the "Keldovan the Harrier" event with his npc type id
    dz:SetLootEventByNPCTypeID(317005, 'Keldovan the Harrier')
  end
end

void SetLootEventBySpawnID(uint32_t spawn_id, string event_name)

Important: This must be set from a script inside the expedition's dynamic zone instance

Associates an event with the specified entity spawn id to prevent it from being looted by characters that didn't receive the event lockout from the current expedition.

This is an important initialization step to prevent exploits in expeditions

Unlike SetLootEventByNPCTypeID this associates the event with specific spawns inside the dynamic zone. This is for cases where multiple npc types may exist like spawnable chests which should be associated with the event that spawned them.

function event_death(e)
  local dz = eq.get_expedition()
  if dz.valid then
    dz:AddLockout("Lower Globe of Discordant Energy")

    -- associate this spawned chest with the event
    local chest = eq.spawn2(317087, 0, 0, -301 ,702, -201, 0);
    dz:SetLootEventBySpawnID(chest:GetID(), "Lower Globe of Discordant Energy")
  end
end

void SetReplayLockoutOnMemberJoin(bool value)

This toggles whether Replay Timer lockouts are automatically added to new members that join an expedition

function event_say(e)
  if e.message == "request" then
    local dz = e.other:CreateExpedition("anguish", 0, 36000, "Anguish, the Fallen Palace", 6, 54)
    if dz.valid then
      dz:SetReplayLockoutOnMemberJoin(false)
    end
  end
end

void SetSafeReturn(uint32_t zone_id, float x, float y, float z, float heading)

void SetSafeReturn(string zone_short_name, float x, float y, float z, float heading)

Set the expedition's dynamic zone safe return zone and coordinates. This is the location clients are moved to when an expedition expires or for clients that are automatically teleported out of the zone by the kick timer if they quit the expedition

function event_say(e)
  if e.message == "request" then
    local dz = e.other:CreateExpedition("anguish", 0, 36000, "Anguish, the Fallen Palace", 6, 54)
    if dz.valid then
      -- by zone id
      dz:SetSafeReturn(300, 1349.13, 1715.00, 123.81, 0)
      -- or by zone name
      dz:SetSafeReturn("wallofslaughter", 1349.13, 1715.00, 123.81, 0)
    end
  end
end

void SetSecondsRemaining(uint32 seconds_remaining)

Set seconds remaining on expedition's dynamic zone before it expires. This currently only supports reducing time. It will have no effect if the new seconds remaining is larger than the current time remaining.

Note: this method is async, GetSecondsRemaining will not immediately show the change.

function event_timer(e)
  if e.timer == "event_fail_timer" then
    eq.depop()
    local dz = eq.get_expedition()
    if dz.valid then
      dz:SetSecondsRemaining(300) -- close down expedition in 5 minutes
    end
  end
end

void SetZoneInLocation(float x, float y, float z, float heading)

Override the zone-in location of the expedition's dynamic zone used by Client::MovePCDynamicZone

function event_say(e)
  if e.message == "request" then
    local dz = e.other:CreateExpedition("anguish", 0, 36000, "Anguish, the Fallen Palace", 6, 54)
    if dz.valid then
      dz:SetZoneInLocation(-9, -2466, -79, 0)
    end
  end
end

void UpdateLockoutDuration(string event_name, uint32_t seconds, bool members_only = true)

Sets the lockout of all members in the expedition to the specified duration based on the expedition's internal lockout start time.

Unlike AddLockout which replaces lockouts with a new lockout timer, this modifies the duration of an existing lockout relative to its original start time.

Calling this on an expedition that does not have the internal lockout has no effect. All members essentially receive an updated lockout copied from the expedition's internal timer.

Prefer using AddLockoutDuration to update individual member lockouts

The expedition's internal lockout is NOT modified by default. New members added to the expedition that zone in to the dz will receive the lockout as originally added. This can be overridden by passing false for the members_only parameter.

Note: Member lockouts updated with this method are assigned the current expedition's uuid

function event_say(e)
  if e.message == "request" then
    local dz = e.other:CreateExpedition("anguish", 0, 36000, "Anguish, the Fallen Palace", 6, 54)
    if dz.valid then
      expedition:AddReplayLockout(7200) -- 2 hour replay lockout
    end
  end
end

-- inside dz, after killing some progression npc
function event_death(e)
  local dz = eq.get_expedition()
  if dz.valid then
    -- copies expedition's lockout to all current members with modified duration.
    -- member lockout durations will be (7 hours - elapsed time since added)
    dz:UpdateLockoutDuration("Replay Timer", 25200) -- 7 hours
  end
end