summaryrefslogtreecommitdiffstats
path: root/scripts/lua/libmana.lua
diff options
context:
space:
mode:
Diffstat (limited to 'scripts/lua/libmana.lua')
-rw-r--r--scripts/lua/libmana.lua268
1 files changed, 12 insertions, 256 deletions
diff --git a/scripts/lua/libmana.lua b/scripts/lua/libmana.lua
index cb92276..94d1f99 100644
--- a/scripts/lua/libmana.lua
+++ b/scripts/lua/libmana.lua
@@ -22,22 +22,9 @@ require "scripts/lua/libmana-constants"
local npc_talk_functs = {}
local npc_update_functs = {}
--- Table that associates to each Character pointer its state with respect to
--- NPCs (only one at a time). A state is an array with four fields:
--- . 1: pointer to the NPC the player is currently talking to.
--- . 2: coroutine running the NPC handler.
--- . 3: next event the NPC expects from the server.
--- (1 = npc_next, 2 = npc_choose, 3 = quest_reply, 4 = 1+3)
--- . 4: countdown (in minutes) before the state is deleted.
--- . 5: name of the expected quest variable. (optional)
-local states = {}
-
-- Array containing the function registered by atinit.
local init_fun = {}
--- Tick timer used during update to clean obsolete states.
-local timer
-
-- Creates an NPC and associates the given handler.
-- Note: Cannot be called until map initialization has started.
function create_npc(name, id, gender, x, y, talkfunct, updatefunct)
@@ -45,235 +32,31 @@ function create_npc(name, id, gender, x, y, talkfunct, updatefunct)
if talkfunct then
npc_talk_functs[npc] = function(npc, ch)
talkfunct(npc, ch)
- do_npc_close(npc, ch)
+ mana.npc_end(npc, ch)
end
end
if updatefunct then npc_update_functs[npc] = updatefunct end
return npc
end
--- Waits for the player to acknowledge the previous message, if any.
-function do_wait()
- coroutine.yield(0)
-end
-
--- Sends an npc message to a player.
--- Note: Does not wait for the player to acknowledge the message.
-function do_message(npc, ch, msg)
- -- Wait for the arrival of a pending acknowledgment, if any.
- coroutine.yield(0)
- mana.npc_message(npc, ch, msg)
- -- An acknowledgment is pending, but do not wait for its arrival.
- coroutine.yield(1)
-end
-
--- Sends an NPC question to a player and waits for its answer.
-function do_choice(npc, ch, ...)
- -- Wait for the arrival of a pending acknowledgment, if any.
- coroutine.yield(0)
- mana.npc_choice(npc, ch, ...)
- -- Wait for player choice.
- return coroutine.yield(2)
-end
-
--- Sends an NPC integer ask to a player and waits for its answer.
-function do_ask_integer(npc, ch, min_num, max_num, ...)
- -- Wait for the arrival of a pending acknowledgment, if any.
- coroutine.yield(0)
- mana.npc_ask_integer(npc, ch, min_num, max_num, ...)
- -- Wait for player answer.
- return coroutine.yield(2)
-end
-
--- Sends an NPC string ask to a player and waits for its answer.
-function do_ask_string(npc, ch)
- -- Wait for the arrival of a pending acknowledgment, if any.
- coroutine.yield(0)
- mana.npc_ask_string(npc, ch)
- -- Wait for player answer.
- return coroutine.yield(2)
-end
-
--- Sends an NPC request to send letter to a player and waits for them to
--- send the letter.
-function do_post(npc, ch)
- coroutine.yield(0)
- mana.npc_post(npc, ch)
- return coroutine.yield(1)
-end
-
--- Gets the value of a quest variable.
--- Calling this function while an acknowledment is pending is desirable, so
--- that lag cannot be perceived by the player.
-function get_quest_var(ch, name)
- -- Query the server and return immediatly if a value is available.
- local value = mana.chr_get_quest(ch, name)
- if value then return value end
- -- Wait for database reply.
- return coroutine.yield(3, name)
-end
-
--- Gets the post for a user.
-function getpost(ch)
- mana.chr_get_post(ch)
- return coroutine.yield(3)
-end
-
--- Processes as much of an NPC handler as possible.
-local function process_npc(w, ...)
- local co = w[2]
- local pending = (w[3] == 4)
- local first = true
- while true do
- local b, v, u
- if first then
- -- First time, resume with the arguments the coroutine was waiting for.
- b, v, u = coroutine.resume(co, ...)
- first = false
- else
- -- Otherwise, simply resume.
- b, v, u = coroutine.resume(co)
- end
-
- if not b then print("LUA error: ", v)end
-
- if not b or not v then
- -- Either there was an error, or the handler just finished its work.
- return
- elseif v == 2 then
- -- The coroutine needs a user choice from the server, so wait for it.
- w[3] = 2
- break
- elseif v == 3 then
- -- The coroutine needs the value of a quest variable from the server.
- w[5] = u
- if pending then
- -- The coroutine has also sent a message to the user, so do not
- -- forget about it, as it would flood the user with new messages.
- w[3] = 4
- else
- w[3] = 3
- end
- break
- elseif pending then
- -- The coroutine is about to interact with the user. But the previous
- -- action has not been acknowledged by the user yet, so wait for it.
- w[3] = 1
- break
- elseif v == 1 then
- -- A message has just been sent. But the coroutine can keep going in case
- -- there is still some work to do while waiting for user acknowledgment.
- pending = true
- end
- end
- -- Restore the countdown, as there was some activity.
- w[4] = 5
- return true
-end
+-- These are deprecated and only provided for compatibility!
+do_message = mana.npc_message
+do_choice = mana.npc_choice
+do_ask_integer = mana.npc_ask_integer
+do_ask_string = mana.npc_ask_string
+do_post = mana.npc_post
+get_quest_var = mana.chr_get_quest
+getpost = mana.chr_get_post
-- Registered as the function to call whenever a player starts talking to an
--- NPC. Creates a coroutine based on the registered NPC handler.
+-- NPC. Calls the registered NPC handler.
local function npc_start(npc, ch)
- states[ch] = nil
local h = npc_talk_functs[npc]
- if not h then return end
- local w = { npc, coroutine.create(h) }
- if process_npc(w, npc, ch) then
- states[ch] = w
- if not timer then
- timer = 600
- end
- end
- -- coroutine.resume(w)
- -- do_npc_close(npc, ch)
-end
-
-function do_npc_close(npc, ch)
- mana.npc_end(npc, ch)
-end
-
--- Registered as the function to call whenever a player continues talking to an
--- NPC. Checks that the NPC expects it, and processes the respective coroutine.
-local function npc_next(npc, ch)
- local w = states[ch]
- if w then
- local w3 = w[3]
- if w3 == 4 then
- w[3] = 3
- return
- elseif w3 == 1 and process_npc(w) then
- return
- end
- end
- states[ch] = nil
-end
-
--- Registered as the function to call whenever a player selects a particular
--- reply. Checks that the NPC expects it, and processes the respective
--- coroutine.
-local function npc_choose(npc, ch, u)
- local w = states[ch]
- if not (w and w[1] == npc and w[3] == 2 and process_npc(w, u)) then
- states[ch] = nil
- end
-end
-
-local function npc_integer(npc, ch, u)
- local w = states[ch]
- if not (w and w[1] == npc and w[3] == 2 and process_npc(w, u)) then
- states[ch] = nil
+ if h then
+ h(npc, ch)
end
end
-local function npc_string(npc, ch, u)
- local w = states[ch]
- if not (w and w[1] == npc and w[3] == 2 and process_npc(w, u)) then
- states[ch] = nil
- end
-end
-
--- Called by the game when a player sends a letter.
--- TODO: Actually this function isn't called, probably unfinished implementation
-local function npc_post(npc, ch, sender, letter)
- local w = states[ch]
- if not (w and w[1] == npc and w[3] == 1 and process_npc(w, sender, letter)) then
- states[ch] = nil
- end
-end
-
--- Registered as the function to call whenever a value of a quest variable is
--- retrieved. Checks that the NPC expects it, and processes the respective
--- coroutine.
--- Note: the check for NPC correctness is missing, but it should never matter.
-local function npc_quest_reply(ch, name, value)
- local w = states[ch]
- if w then
- local w3 = w[3]
- if (w3 == 3 or w3 == 4) and w[5] == name then
- w[5] = nil
- if process_npc(w, value) then
- return
- end
- end
- end
- states[ch] = nil
-end
-
--- Registered as the function to call whenever the server has recovered a
--- post for a user.
-local function npc_post_reply(ch, sender, letter)
- local w = states[ch]
- if w then
- local w3 = w[3]
- if (w3 == 3 or w3 == 4) then
- if process_npc(w, sender, letter) then
- return
- end
- end
- end
- states[ch] = nil
-end
-
-- Registered as the function to call every tick for each NPC.
local function npc_update(npc)
local h = npc_update_functs[npc];
@@ -308,28 +91,7 @@ end
-- Registered as the function to call every tick.
-- Checks for scheduled function calls and cleans obsolete connections.
local function update()
- -- check the scheduler
check_schedule()
-
- -- Run every minute only, in order not to overload the server.
- if not timer then return end
- timer = timer - 1
- if timer ~= 0 then return end
- -- Free connections that have been inactive for 3-4 minutes.
- for k, w in pairs(states) do
- local t = w[4] - 1
- if t == 0 then
- states[k] = nil
- else
- w[4] = t
- end
- end
- -- Restart timer if there are still some pending states.
- if next(states) then
- timer = 600
- else
- timer = nil
- end
end
-- Registers a function so that is is executed during map initialization.
@@ -459,12 +221,6 @@ end
mana.on_update(update)
mana.on_npc_start(npc_start)
-mana.on_npc_next(npc_next)
-mana.on_npc_choose(npc_choose)
-mana.on_npc_integer(npc_integer)
-mana.on_npc_string(npc_string)
-mana.on_npc_quest_reply(npc_quest_reply)
-mana.on_npc_post_reply(npc_post_reply)
mana.on_npc_update(npc_update)
mana.on_create_npc_delayed(create_npc_delayed)