landsandboat/scripts/commands/gotoname.lua

108 lines
3.2 KiB
Lua

-----------------------------------
-- func: gotoname
-- desc: Go to given mob or npc by name
-----------------------------------
---@type TCommand
local commandObj = {}
commandObj.cmdprops =
{
permission = 1,
parameters = 'si'
}
local function error(player, msg)
player:printToPlayer(msg)
player:printToPlayer('!gotoname <mob or npc name> (index)')
end
-----------------------------------
-- func: getValidEntities
-- desc: given a list of entities, returns the ones that have valid coordinates
-----------------------------------
local getValidEntities = function(entities)
local validEntities = {}
for i, entity in pairs(entities) do
local pos = entity:getPos()
local invalidCoordinates = (pos.x == 0 and pos.y == 0 and pos.z == 0)
-- only add entity if it is at valid coordinates
if not invalidCoordinates then
table.insert(validEntities, entity)
end
end
return validEntities
end
-----------------------------------
-- func: gotoEntity
-- desc: teleports the player to the given NPC
-----------------------------------
local gotoEntity = function(player, entity)
-- determine whether we need zoneId parameter
local gotoZone = nil
if entity:getZoneID() ~= player:getZoneID() then
gotoZone = entity:getZoneID()
end
-- display message
if entity:isSpawned() then
player:printToPlayer(string.format('Going to %s (%i).', entity:getName(), entity:getID()))
else
player:printToPlayer(string.format('%s (%i) is not currently up. Going to last known coordinates.', entity:getName(), entity:getID()))
end
-- half a second later, go. this delay gives time for previous message to appear
player:timer(500, function(playerArg)
playerArg:setPos(entity:getXPos(), entity:getYPos(), entity:getZPos(), entity:getRotPos(), gotoZone)
end)
end
commandObj.onTrigger = function(player, pattern, index)
-- validate pattern
if pattern == nil or pattern == '' then
error(player, 'You must enter an NPC name')
return
end
local zone = player:getZone()
if not zone then
return
end
local unfilteredEntities = zone:queryEntitiesByName(pattern)
local entities = getValidEntities(unfilteredEntities)
if index ~= nil and index > 0 and index <= #entities then
gotoEntity(player, entities[index])
return
end
if #entities > 20 then
player:printToPlayer('Too many results. Narrow your query or specify an index to go to.')
return
end
if #entities == 0 then
if #unfilteredEntities > 0 then
player:printToPlayer(string.format('%s not spawned in current zone', pattern))
else
player:printToPlayer(string.format('%s not found in current zone', pattern))
end
return
end
if #entities == 1 then
gotoEntity(player, entities[1])
return
end
player:printToPlayer('Multiple entities found. Use !goto name <mob or npc name> <index> to choose:', xi.msg.channel.SYSTEM_3)
for i, entity in pairs(entities) do
player:printToPlayer(string.format('[%d] %s %s (%s)', i, entity:getName(), entity:getZoneName(), entity:getID()), xi.msg.channel.SYSTEM_3)
end
end
return commandObj