diff options
Diffstat (limited to 'scripts/lua/libmana.lua')
-rw-r--r-- | scripts/lua/libmana.lua | 268 |
1 files changed, 12 insertions, 256 deletions
diff --git a/scripts/lua/libmana.lua b/scripts/lua/libmana.lua index cb92276b..94d1f99e 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) |