Skip to content

npc

Acts as an NPC: speaks, plays sounds, walks and reads where it is.

Source: src/Moongate.Server.Ultima/Modules/NpcModule.cs

npc.bleed_chance(serial) -> integer?

The bleed_chance of the NPC's template: the percent chance that a blow it lands begins its victim's bleeding. nil for an unknown NPC or a template that sets none: it never bleeds then.

ParameterTypeDefault
serialinteger

Returns integer?.

npc.can_see(serial, other, range?, in_sight?) -> boolean

Whether the NPC sees the mobile: on its map, within range tiles (default 16, 0 to 32), not hidden, not a game master or an administrator, and in line of sight from eye to eye (never beyond ultima.line_of_sight.max_distance, 25); with in_sight false the line of sight is not checked. False for itself or an unknown NPC or mobile.

Pass in_sight false for a mobile the NPC keeps following once it saw it.

ParameterTypeDefault
serialinteger
otherinteger
range (optional)integer16
in_sight (optional)booleantrue

Returns boolean.

npc.delete(serial) -> boolean

Deletes the NPC and what it carries, on the next turn of the game loop; false for a serial that is not an NPC in the world.

ParameterTypeDefault
serialinteger

Returns boolean.

npc.distance_to(serial, x, y) -> integer?

The tiles between the NPC and x, y, the larger of the two differences, as the view range counts them; nil for an unknown NPC.

ParameterTypeDefault
serialinteger
xinteger
yinteger

Returns integer?.

npc.face(serial, x, y) -> boolean

Turns the NPC towards x, y without stepping, seen by the players in range; false for an unknown or frozen NPC or its own cell.

ParameterTypeDefault
serialinteger
xinteger
yinteger

Returns boolean.

npc.find_path(serial, x, y, z?, partial?) -> table?

The steps from the NPC to x, y (z defaults to the ground there) as a list of DirectionType, to walk with npc.step; with partial true, the steps to the closest place when it cannot be reached. Each call searches, so keep the list. Nil when there is no path, the place is too far or the NPC is unknown.

ParameterTypeDefault
serialinteger
xinteger
yinteger
z (optional)integernil
partial (optional)booleanfalse

Returns table?.

npc.flee_at(serial) -> integer?

The flee_at of the NPC's template: the percent of its hit points (0 to 100) under which it runs from a fight, or -1 for one that never does. nil for an unknown NPC or a template that sets none: the script's own value then.

ParameterTypeDefault
serialinteger

Returns integer?.

npc.get_prop(serial, key) -> any?

A value the NPC keeps across restarts: a string, a number or a bool; nil when it has none.

ParameterTypeDefault
serialinteger
keystring

Returns any?.

npc.ghosts_in_sight(serial, range?, limit?) -> table

The serials of the dead players, ghosts, within range cells that the NPC sees, in the line of sight and whatever their hidden flag says, staff ghosts too; at most limit of them. Nearest first. Empty for an unknown NPC or a range out of bounds. What a healer looks for: npc.players_in_sight never lists a ghost.

ParameterTypeDefault
serialinteger
range (optional)integer16
limit (optional)integer2147483647

Returns table.

npc.home(serial) -> table?

The home of an NPC of a spawn region, the area it was spawned in, as a table { x1, y1, x2, y2 }; nil for an NPC without one or an unknown NPC.

ParameterTypeDefault
serialinteger

Returns table?.

npc.location(serial) -> table?

Where the NPC is, as a table { x, y, z, map }; nil for an unknown NPC.

ParameterTypeDefault
serialinteger

Returns table?.

npc.look_at(serial, other) -> boolean

Turns the NPC towards another mobile, player or NPC, without stepping, as npc.face does towards a place: towards who speaks to it. False for an unknown or frozen NPC, a mobile not in the world or on another map, or one on its own cell.

ParameterTypeDefault
serialinteger
otherinteger

Returns boolean.

npc.mobiles_in_sight(serial, range?, limit?) -> table

The serials of the mobiles, players and other NPCs, the NPC sees within range cells, in the line of sight, at most limit of them, nearest first: what a creature that goes for everyone looks at. The NPC itself, the hidden, the dead and the staff are left out. Empty for an unknown NPC or a range out of bounds. npc.players_in_sight is the same for the players only.

ParameterTypeDefault
serialinteger
range (optional)integer16
limit (optional)integer2147483647

Returns table.

npc.name(serial) -> string?

The NPC's name; nil for an unknown NPC.

ParameterTypeDefault
serialinteger

Returns string?.

npc.nearby(serial, range, kind?) -> table

The serials of the mobiles within range tiles (0 to 32) of the NPC, itself left out, nearest first: the other NPCs, or with kind 'players' the players, with 'all' everyone. Height and line of sight are not checked. Empty for an unknown NPC or a range out of bounds.

for _, other in ipairs(npc.nearby(serial, 8)) do ... end
ParameterTypeDefault
serialinteger
rangeinteger
kind (optional)string"npcs"

Returns table.

npc.play_sound(serial, sound) -> boolean

Plays a sound id (0 to 65535) or a kind of its template's [mobile.sounds] (start_attack, idle, attack, hurt, death) where the NPC stands, for the players within 15 cells (0x54); false for an unknown NPC, a sound out of range or a kind its template does not set.

npc.play_sound(serial, 0x69)
npc.play_sound(serial, "idle")
ParameterTypeDefault
serialinteger
soundany

Returns boolean.

npc.players_in_sight(serial, range?, limit?) -> table

The serials of the players the NPC sees within range tiles (default 16, 0 to 32), as npc.can_see says, nearest first; with limit, that many at most, so a script that wants the nearest does not pay for a crowd. A line of sight is not checked beyond ultima.line_of_sight.max_distance (25). Empty for an unknown NPC, a range out of bounds or a limit below 1.

The nearest player the NPC sees within 16 tiles:

local prey = npc.players_in_sight(serial, 16, 1)[1]
ParameterTypeDefault
serialinteger
range (optional)integer16
limit (optional)integer2147483647

Returns table.

npc.say(serial, text) -> boolean

The NPC says text overhead (cut to 128 characters) to the players within 15 cells; false for an unknown NPC or blank text.

ParameterTypeDefault
serialinteger
textstring

Returns boolean.

npc.say_cliloc(serial, cliloc, args?, affix?) -> boolean

The NPC says a text of the client overhead, by its cliloc number, to the players within 15 cells: each player reads it in the language of its client, which npc.say cannot do. args fills the placeholders of the text (~1_AMOUNT~ and the like), several of them separated by a tab. affix is written after the text, for the texts that end with a colon and expect a value of the server, such as a banker's 1042673; it is ASCII, anything else shows as a question mark. False for an unknown NPC or a number that is no cliloc.

ParameterTypeDefault
serialinteger
clilocinteger
args (optional)string""
affix (optional)string""

Returns boolean.

npc.say_cliloc_to(serial, player, cliloc, args?, affix?) -> boolean

The NPC says a text of the client overhead, by its cliloc number, to one player only (nobody else sees it), in the language of its client, as ModernUO's private overhead messages. args and affix are as for npc.say_cliloc. False for an unknown NPC, a mobile that is not in the world or has no client, or a number that is no cliloc.

ParameterTypeDefault
serialinteger
playerinteger
clilocinteger
args (optional)string""
affix (optional)string""

Returns boolean.

npc.script_id(serial) -> string?

The script_id of the NPC's mobile template, such as monster, guard or healer: what kind of creature it is to the scripts that look at others. nil for an unknown NPC or a template without a script.

ParameterTypeDefault
serialinteger

Returns string?.

npc.search(text, limit?) -> table

Finds mobile templates whose id or name holds the text, without regard to case, and those of the body when the text is a number (17 or 0x11), sorted by id, as a list of { id, name, body } with the template's id as the name when it has none. The body is the template's own or the one of its race for its gender; a template with neither (an abstract base) is never found. limit is the most to give, 40 by default and between 1 and 100; empty for a blank text.

ParameterTypeDefault
textstring
limit (optional)integer40

Returns table.

npc.set_prop(serial, key, value?) -> boolean

Keeps a string, a number or a bool on the NPC across restarts, saved with it by the world save; nil removes it. False for a table, a function or a blank key.

vega.lua counts the hellos it hears, across restarts:

vega = {}
function vega.on_speech(serial, speaker, text)
if text:lower():find("hello", 1, true) then
npc.look_at(serial, speaker)
local times = (npc.get_prop(serial, "vega.greeted") or 0) + 1
npc.set_prop(serial, "vega.greeted", times)
npc.say(serial, "Meow! That's " .. times .. " hellos.")
end
end
ParameterTypeDefault
serialinteger
keystring
value (optional)anynil

Returns boolean.

npc.spawn(template, map, x, y, z, callback?) -> boolean

Spawns an NPC of a mobile template at x, y, z of the map. It is saved first, so it appears a moment later: its on_spawn runs then, and so does the optional function with its serial. False for an unknown template, a spot outside the map or a z outside -128 to 127.

ParameterTypeDefault
templatestring
mapMapType | string
xinteger
yinteger
zinteger
callback (optional)functionnil

Returns boolean.

npc.spell_circles(serial) -> integer?

The spell_circles of the NPC's template: the highest circle of Magery (1 to 8) a creature casts from, as UOX3's SPATTACK. nil for an unknown NPC or a template that sets none, which casts nothing; 0 is the same as none.

ParameterTypeDefault
serialinteger

Returns integer?.

npc.step(serial, direction, running?) -> boolean

One step in a direction (North to NorthWest), a run when running is true, turning first when needed, seen by the players in range; how often it is called sets the speed. False when blocked or for DirectionType.Running, which is not a direction.

ParameterTypeDefault
serialinteger
directionDirectionType | string
running (optional)booleanfalse

Returns boolean.

npc.walk_to(serial, x, y, z?, range?, running?) -> string?

One step along a path to x, y (z defaults to the ground there), a run when running is true: 'arrived' within range tiles of it (default 0), 'moving' after a step or after opening a door in its way (an NPC that opens doors, see opens_doors), 'blocked' when the step was refused or it waits to look for another way, 'no_path' when the last search did not reach the place; nil for an unknown NPC, a negative range or a z outside -128 to 127.

Call it on every think; the NPC takes one step each time:

guard = {}
function guard.on_think(serial)
local state = npc.walk_to(serial, 1434, 1699)
if state == "arrived" then
npc.say(serial, "All quiet at the bank.")
end
end

To follow someone, pass where it stands on every think and a range of 1 to stop beside it:

local where = mobile.location(target)
npc.walk_to(serial, where.x, where.y, where.z, 1, true)
ParameterTypeDefault
serialinteger
xinteger
yinteger
z (optional)integernil
range (optional)integernil
running (optional)booleanfalse

Returns string?.

npc.wander(serial) -> boolean

One stroll step, as ModernUO's wander: two times in three straight ahead, else another way. An NPC of a spawn region keeps to its home and from outside walks back along a path, with a random step when none is found. False when it did not move, as in a home of one cell, or for an unknown NPC.

wander.lua strolls one think in four:

wander = {}
local thinks = {}
function wander.on_think(serial)
thinks[serial] = (thinks[serial] or 0) + 1
if thinks[serial] % 4 == 0 then
npc.wander(serial)
end
end
ParameterTypeDefault
serialinteger

Returns boolean.

Made with ❤️ by Tom

Buy me a coffee