diff options
author | Thorbjørn Lindeijer <thorbjorn@lindeijer.nl> | 2010-05-29 22:11:12 +0200 |
---|---|---|
committer | Thorbjørn Lindeijer <thorbjorn@lindeijer.nl> | 2010-05-30 17:50:55 +0200 |
commit | 3e669831a05c36a38519b6f22cb1ed3c11837f2f (patch) | |
tree | 21a2763b425480c909d43efe0856cfbab48e3573 | |
parent | 8a95ed77fec7c2ef3c0fac81258f70db25009b48 (diff) | |
download | manaserv-3e669831a05c36a38519b6f22cb1ed3c11837f2f.tar.gz manaserv-3e669831a05c36a38519b6f22cb1ed3c11837f2f.tar.bz2 manaserv-3e669831a05c36a38519b6f22cb1ed3c11837f2f.tar.xz manaserv-3e669831a05c36a38519b6f22cb1ed3c11837f2f.zip |
Copied basic Lua libs back from tmwserv-data and added dummy data
The dummy data is currently mostly empty data though, so still nothing
to see as far as the example content is concerned.
Reviewed-by: Bertram
-rw-r--r-- | docs/manaserv.xml | 30 | ||||
-rw-r--r-- | example/clientdata/mana-skills.xml | 3 | ||||
-rw-r--r-- | example/clientdata/maps/desert.tmx | 18 | ||||
-rw-r--r-- | example/clientdata/monsters.xml | 3 | ||||
-rw-r--r-- | example/clientdata/tilesets/tmw_desert_spacing.png | bin | 0 -> 37830 bytes | |||
-rw-r--r-- | example/serverdata/maps.xml | 4 | ||||
-rw-r--r-- | example/serverdata/permissions.xml | 42 | ||||
-rw-r--r-- | example/serverdata/scripts/bomtest.lua | 7 | ||||
-rw-r--r-- | scripts/lua/libmana-constants.lua | 103 | ||||
-rw-r--r-- | scripts/lua/libmana.lua | 448 | ||||
-rw-r--r-- | scripts/lua/npclib.lua | 103 | ||||
-rw-r--r-- | src/common/resourcemanager.cpp | 3 | ||||
-rw-r--r-- | src/scripting/lua.cpp | 3 |
13 files changed, 752 insertions, 15 deletions
diff --git a/docs/manaserv.xml b/docs/manaserv.xml index f4874320..909400a8 100644 --- a/docs/manaserv.xml +++ b/docs/manaserv.xml @@ -1,5 +1,5 @@ <?xml version="1.0"?> -<!-- +<!-- An example configuration file for ~/.manaserv.xml Documentation: http://doc.manasource.org/manaserv.xml @@ -10,7 +10,7 @@ <configuration> <!-- Database configuration *************************************************** - Uncomment one of the following parts according to the database backend you + Uncomment one of the following parts according to the database backend you would like to use. --> @@ -38,7 +38,7 @@ optional, default="mana" --> <!-- -<option name="mysql_hostname" value="localhost"/> +<option name="mysql_hostname" value="localhost"/> <option name="mysql_port" value="3306"/> <option name="mysql_database" value="mana"/> <option name="mysql_username" value="mana"/> @@ -46,8 +46,8 @@ --> -<!-- - PostgreSQL specific configuration. +<!-- + PostgreSQL specific configuration. TODO! --> @@ -84,23 +84,25 @@ --> <option name="net_gameServerAddress" value="localhost"/> <option name="net_gameServerPort" value="9604"/> - - <!--Paths to data files--> + + <!-- Paths to data files --> + <option name="serverPath" value="." /> <option name="clientDataPath" value="example/clientdata" /> <option name="serverDataPath" value="example/serverdata" /> - - <!-- Gameplay-related config option--> - <option name="visualRange" value="448"/> + + <!-- Gameplay-related config option --> + <option name="visualRange" value="448"/> <option name="respawnMap" value="4"/> <option name="respawnX" value="1000"/> <option name="respawnY" value="1000"/> <option name="defaultPvp" value="free" /> <option name="floorItemDecayTime" value="10" /> <option name="hpRegenBreakAfterHit" value="50" /> - - <!-- Network-related config options--> + + <!-- Network-related config options --> <option name="net_maxClients" value="1000"/> - <!-- Account-creation-related config options--> + + <!-- Account-creation-related config options --> <option name="account_allowRegister" value="1" /> <option name="account_denyRegisterReason" value="The server administrator has disabled automatic registration!" /> <option name="account_minEmailLength" value="7" /> @@ -109,6 +111,7 @@ <option name="account_maxNameLength" value="16" /> <option name="account_minPasswordLength" value="6" /> <option name="account_maxPasswordLength" value="25" /> + <!-- Character-creation-related config options --> <option name="char_numHairStyles" value="17" /> <option name="char_numHairColors" value="9" /> @@ -117,6 +120,7 @@ <option name="char_maxNameLength" value="25" /> <option name="char_maxCharacters" value="3" /> <option name="char_startingPoints" value="60" /> + <!-- Chat-related config options --> <option name="chat_maxChannelNameLength" value="15" /> <!-- I noticed the following configuration-like enumeration values which are never checked: diff --git a/example/clientdata/mana-skills.xml b/example/clientdata/mana-skills.xml new file mode 100644 index 00000000..118450c6 --- /dev/null +++ b/example/clientdata/mana-skills.xml @@ -0,0 +1,3 @@ +<?xml version="1.0" encoding="utf-8"?> +<skills> +</skills> diff --git a/example/clientdata/maps/desert.tmx b/example/clientdata/maps/desert.tmx new file mode 100644 index 00000000..f35f5483 --- /dev/null +++ b/example/clientdata/maps/desert.tmx @@ -0,0 +1,18 @@ +<?xml version="1.0" encoding="UTF-8"?> +<map version="1.0" orientation="orthogonal" width="40" height="40" tilewidth="32" tileheight="32"> + <tileset firstgid="1" name="Desert" tilewidth="32" tileheight="32" spacing="1" margin="1"> + <image source="../tilesets/tmw_desert_spacing.png"/> + </tileset> + <layer name="Ground" width="40" height="40"> + <data encoding="base64" compression="gzip"> + H4sIAAAAAAAAA+2Y2QrCMBBFo31wA+sCrlirdd/q/3+dIzZUhtAmMRlH6cPBBlJyvDO2g5EQIvJIFwiBnudzbLgp/JYMvH4lv2dWI2AMTBj4qKgBdSBA3j7OmgIzA+ZAC2gDHYIsVsDagMSj36HAbwOcgO0X/YrySzTzpPDbMfS7Iy/sdxGv/r8S++Gew+uyvHBfuvBT/Q4OKD95XeaHc3WV3x6tpY9pfr7riz0xx6x+upwd+DUymiJ/FxURaO6TLD70C0U+X8jvWkRHc5/qPhu/scjniz4wKGGouU91n8/eoyYW6jmHk2dM6GMzm1F43bJPnWfn+/sncXS+Ljp+T6d7tpfSL2Xoh/uam59Nfd/nCyq/1MAPZ8ktP1WtOftR5mczm1H6/QsxA4dfAWfF7b/BqsYVFZ/xABSXR5cAGQAA + </data> + </layer> + <objectgroup name="Objects" width="40" height="40"> + <object name="Main script" type="SCRIPT" x="16" y="25" width="167" height="10"> + <properties> + <property name="FILENAME" value="scripts/bomtest.lua"/> + </properties> + </object> + </objectgroup> +</map> diff --git a/example/clientdata/monsters.xml b/example/clientdata/monsters.xml new file mode 100644 index 00000000..21ddc80a --- /dev/null +++ b/example/clientdata/monsters.xml @@ -0,0 +1,3 @@ +<?xml version="1.0" encoding="utf-8"?> +<monsters> +</monsters> diff --git a/example/clientdata/tilesets/tmw_desert_spacing.png b/example/clientdata/tilesets/tmw_desert_spacing.png Binary files differnew file mode 100644 index 00000000..4e9995c0 --- /dev/null +++ b/example/clientdata/tilesets/tmw_desert_spacing.png diff --git a/example/serverdata/maps.xml b/example/serverdata/maps.xml new file mode 100644 index 00000000..94673852 --- /dev/null +++ b/example/serverdata/maps.xml @@ -0,0 +1,4 @@ +<?xml version="1.0" encoding="utf-8"?> +<maps> + <map id="1" name="desert" /> +</maps> diff --git a/example/serverdata/permissions.xml b/example/serverdata/permissions.xml new file mode 100644 index 00000000..f2eeae36 --- /dev/null +++ b/example/serverdata/permissions.xml @@ -0,0 +1,42 @@ +<?xml version="1.0" encoding="utf-8"?> +<permissions> + <class level="1"> + <alias>player</alias> + <allow>@help</allow> + <allow>@where</allow> + <allow>@rights</allow> + <allow>@report</allow> + </class> + <class level="2"> + <alias>tester</alias> + <allow>@warp</allow> + </class> + <class level="3"> + <alias>dev</alias> + <allow>@item</allow> + <allow>@drop</allow> + <allow>@money</allow> + <allow>@spawn</allow> + <allow>@attribute</allow> + </class> + <class level="4"> + <alias>gm</alias> + <allow>@goto</allow> + <allow>@recall</allow> + <allow>@ban</allow> + <allow>@history</allow> + </class> + <class level="5"> + </class> + <class level="6"> + </class> + <class level="7"> + </class> + <class level="8"> + <alias>admin</alias> + <allow>@reload</allow> + <allow>@givepermission</allow> + <allow>@takepermission</allow> + <allow>@announce</allow> + </class> +</permissions> diff --git a/example/serverdata/scripts/bomtest.lua b/example/serverdata/scripts/bomtest.lua new file mode 100644 index 00000000..d4b02124 --- /dev/null +++ b/example/serverdata/scripts/bomtest.lua @@ -0,0 +1,7 @@ +------------------------------------------------------------------------------- +-- This file verifies that an UTF-8 BOM is correctly handled by manaserv ------ + +function testUtf8Bom() + -- Dummy function, the test is really about whether the hidden BOM at the + -- start of this file is skipped before tripping the Lua parser. +end diff --git a/scripts/lua/libmana-constants.lua b/scripts/lua/libmana-constants.lua new file mode 100644 index 00000000..227b93fb --- /dev/null +++ b/scripts/lua/libmana-constants.lua @@ -0,0 +1,103 @@ +------------------------------------------------------------- +-- Mana Support Library Constants -- +-- -- +-- Some useful numeric values for use by other scripts. -- +-- -- +---------------------------------------------------------------------------------- +-- Copyright 2008 The Mana World Development Team -- +-- -- +-- This file is part of The Mana Server. -- +-- -- +-- The Mana Server is free software; you can redistribute it and/or modify it -- +-- under the terms of the GNU General Public License as published by the Free -- +-- Software Foundation; either version 2 of the License, or any later version. -- +---------------------------------------------------------------------------------- + +DAMAGE_PHYSICAL = 0 +DAMAGE_MAGICAL = 1 +DAMAGE_OTHER = 2 + +ELEMENT_NEUTRAL = 0 +ELEMENT_FIRE = 1 +ELEMENT_WATER = 2 +ELEMENT_EARTH = 3 +ELEMENT_AIR = 4 +ELEMENT_LIGHTNING = 5 +ELEMENT_METAL = 6 +ELEMENT_WOOD = 7 +ELEMENT_ICE = 8 + +ATTR_PHY_ATK_MIN = 0 +ATTR_PHY_ATK_DELTA = 1 +ATTR_MAG_ATK = 2 +ATTR_PHY_RES = 3 +ATTR_MAG_RES = 4 +ATTR_EVADE = 5 +ATTR_HIT = 6 +ATTR_HP = 7 +ATTR_HP_REGEN = 8 +ELEM_NEUTRAL = 9 +ELEM_FIRE = 10 +ELEM_WATER = 11 +ELEM_EARTH = 12 +ELEM_AIR = 13 +ELEM_SACRED = 14 +ELEM_DEATH = 15 +ATTR_STRENGTH = 16 +ATTR_AGILITY = 17 +ATTR_DEXTERITY = 18 +ATTR_VITALITY = 19 +ATTR_INTELLIGENCE = 20 +ATTR_WILLPOWER = 21 +SKILL_WEAPON_NONE = 100 +SKILL_WEAPON_KNIFE = 101 +SKILL_WEAPON_SWORD = 102 +SKILL_WEAPON_POLEARM = 103 +SKILL_WEAPON_STAFF = 104 +SKILL_WEAPON_WHIP = 105 +SKILL_WEAPON_BOW = 106 +SKILL_WEAPON_SHOOTING = 107 +SKILL_WEAPON_MACE = 108 +SKILL_WEAPON_AXE = 109 +SKILL_WEAPON_THROWN = 110 + +TILESIZE = 32 +HOURS = 3600 +MINUTES = 60 + +TYPE_ITEM = 0; +TYPE_ACTOR = 1; +TYPE_NPC = 2; +TYPE_MONSTER = 3; +TYPE_CHARACTER = 4; +TYPE_EFFECT = 5; +TYPE_OTHER = 6; + +ACTION_STAND = 0; +ACTION_WALK = 1; +ACTION_ATTACK = 2; +ACTION_SIT = 3; +ACTION_DEAD = 4; +ACTION_HURT = 5; + +DIRECTION_DEFAULT = 0; +DIRECTION_UP = 1; +DIRECTION_DOWN = 2; +DIRECTION_LEFT = 3; +DIRECTION_RIGHT = 4; +DIRECTION_INVALID = 5; + +EMOTE_DISGUST = 10000; +EMOTE_SURPRISE = 10001; +EMOTE_HAPPY = 10002; +EMOTE_SAD = 10003; +EMOTE_EVIL = 10004; +EMOTE_WINK = 10005; +EMOTE_ANGEL = 10006; +EMOTE_BLUSH = 10007; +EMOTE_TONGUE = 10008; +EMOTE_GRIN = 10009; +EMOTE_UPSET = 10010; +EMOTE_PERTURBED = 10011; +EMOTE_SPEECH = 10012; +EMOTE_BLAH = 10013; diff --git a/scripts/lua/libmana.lua b/scripts/lua/libmana.lua new file mode 100644 index 00000000..8ea5168b --- /dev/null +++ b/scripts/lua/libmana.lua @@ -0,0 +1,448 @@ +------------------------------------------------------------- +-- Mana Support Library -- +-- -- +-- Functions which are called by the game engine and -- +-- helper functions useful for writing other scripts. -- +-- -- +---------------------------------------------------------------------------------- +-- Copyright 2008 The Mana World Development Team -- +-- -- +-- This file is part of The Mana Server. -- +-- -- +-- The Mana Server is free software; you can redistribute it and/or modify it -- +-- under the terms of the GNU General Public License as published by the Free -- +-- Software Foundation; either version 2 of the License, or any later version. -- +---------------------------------------------------------------------------------- + +require "scripts/lua/libmana-constants" + + +-- Table that associates to each NPC pointer the handler function that is +-- called when a player starts talking to an NPC. +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, x, y, talkfunct, updatefunct) + local npc = mana.npc_create(name, id, x, y) + if talkfunct then npc_talk_functs[npc] = talkfunct 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 + +-- Called by the game whenever a player starts talking to an NPC. +-- Creates a coroutine based on the registered NPC handler. +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 + +-- Called by the game whenever a player keeps talking to an NPC. +-- Checks that the NPC expects it, and processes the respective coroutine. +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 + +-- Called by the game whenever a player selects a particular reply. +-- Checks that the NPC expects it, and processes the respective coroutine. +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 + +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 + end +end + +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. +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 + +-- Called by the game whenever the value of a quest variable is known. +-- Checks that the NPC expects it, and processes the respective coroutine. +-- Note: the check for NPC correctness is missing, but it should never matter. +function 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 + +function 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 + +-- Called by the game every tick for each NPC. +function npc_update(npc) + local h = npc_update_functs[npc]; + if h then h(npc) end; +end + +-- Called by the game every tick. +-- Checks for scheduled function calls +-- Cleans obsolete connections. +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. +function atinit(f) + init_fun[#init_fun + 1] = f +end + +-- Called by the game for creating NPCs embedded into maps. +-- Delays the creation until map initialization is performed. +-- Note: Assumes that the "npc_handler" global field contains the NPC handler. +function create_npc_delayed(name, id, x, y) + -- Bind the name to a local variable first, as it will be reused. + local h = npc_handler + atinit(function() create_npc(name, id, x, y, h, nil) end) + npc_handler = nil +end + +-- Called during map initialization. +-- Executes all the functions registered by atinit. +function initialize() + for i,f in ipairs(init_fun) do + f() + end + init_fun = nil +end + + +-- SCHEDULER + +-- Table of scheduled jobs. A job is an array with 3 elements: +-- 0: the UNIX timestamp when it is executed +-- 1: the function which is executed +-- 2: nil when it is a one-time job. Repetition interval is seconds when it is +-- a repeated job. +local scheduler_jobs = {} + +-- compare function used to sort the scheduler_jobs table. +-- the jobs which come first are at the end of the table. +local function job_cmp(job1, job2) + return (job1[0] > job2[0]) +end + +-- checks for jobs which have to be executed, executes them and reschedules +-- them when they are repeated jobs. +function check_schedule() + if #scheduler_jobs==0 then return end + while os.time() > scheduler_jobs[#scheduler_jobs][0] do + -- retreive the job and remove it from the schedule + job = scheduler_jobs[#scheduler_jobs] + table.remove(scheduler_jobs) + -- reschedule the job when it is a repeated job + if job[2] then + schedule_every(job[2], job[1]) + end + -- execute the job + job[1]() + end +end + +-- schedules a function call to be executed once in n seconds +function schedule_in(seconds, funct) + local job = {} + job[0] = os.time() + seconds + job[1] = funct + job[2] = nil + table.insert(scheduler_jobs, job) + table.sort(scheduler_jobs, job_cmp) +end + +-- schedules a function call to be executed at regular intervals of n seconds +function schedule_every(seconds, funct) + local job = {} + job[0] = os.time() + seconds + job[1] = funct + job[2] = seconds + table.insert(scheduler_jobs, job) + table.sort(scheduler_jobs, job_cmp) +end + + +-- DEATH NOTIFICATIONS +local ondeath_functs = {} +local onremove_functs = {} + +-- requests the gameserver to notify the script engine when the being +-- dies and adds a script function to be executed in this case. +function on_death(being, funct) + if ondeath_functs[being] == nil then + ondeath_functs[being] = {} + end + table.insert(ondeath_functs[being], funct) + mana.being_register(being) +end + +-- requests the gameserver to notify the script engine when the being +-- dies and adds a script function to be executed in this case. +function on_remove(being, funct) + if onremove_functs[being] == nil then + onremove_functs[being] = {} + end + table.insert(onremove_functs[being], funct) + mana.being_register(being) +end + +-- called by the engine when a registred being dies. +function death_notification(being) + if type(ondeath_functs[being]) == "table" then + for i,funct in pairs(ondeath_functs[being]) do + funct() + end + ondeath_functs[being] = nil + end +end + +-- called by the engine when a registred being is removed. +function remove_notification(being) + if type(onremove_functs[being]) == "table" then + for i,funct in pairs(onremove_functs[being]) do + funct() + end + onremove_functs[being] = nil + ondeath_functs[being] = nil + end +end + + +-- Below are some convenience methods added to the engine API + +mana.chr_money_change = function(ch, amount) + return mana.chr_inv_change(ch, 0, amount) +end + +mana.chr_money = function(ch) + return mana.chr_inv_count(ch, 0) +end + + + +function cast(ch, arg) + if arg == 1 then + mana.being_say(ch, "Kaaame...Haaame... HAAAAAA!") + end + if arg == 2 then + mana.being_say(ch, "HAA-DOKEN!") + end + if arg == 3 then + mana.being_say(ch, "Sonic BOOM") + end + +end diff --git a/scripts/lua/npclib.lua b/scripts/lua/npclib.lua new file mode 100644 index 00000000..9edfcbd9 --- /dev/null +++ b/scripts/lua/npclib.lua @@ -0,0 +1,103 @@ +---------------------------------------------------------- +-- Library for commonly used NPC scripts -- +-- -- +-- -- +-- Any NPC update function or talk function which could -- +-- be used for NPCs on more than one map should be -- +-- placed here. -- +-- -- +---------------------------------------------------------------------------------- +-- Copyright 2008 The Mana World Development Team -- +-- -- +-- This file is part of The Mana Server. -- +-- -- +-- The Mana Server is free software; you can redistribute it and/or modify it -- +-- under the terms of the GNU General Public License as published by the Free -- +-- Software Foundation; either version 2 of the License, or any later version. -- +---------------------------------------------------------------------------------- + +module("npclib", package.seeall); + + +-- Update function walkaround_small +-- makes the NPC walk around in a 64x64 pixel square around its start location. +-- Useful for NPCs which are supposed to stay on a specific spot but +-- move a bit from time to time. + +local wasmall_timer = {} +local wasmall_startx = {} +local wasmall_starty = {} + +function walkaround_small(npc) + if not wasmall_timer[npc] then + wasmall_timer[npc] = 1 + wasmall_startx[npc] = mana.posX(npc) + wasmall_starty[npc] = mana.posY(npc) + end + + wasmall_timer[npc] = wasmall_timer[npc] + 1 + + if wasmall_timer[npc] == 100 then + wasmall_timer[npc] = math.random(1, 10) + local x = math.random(-32, 32) + wasmall_startx[npc] + local y = math.random(-32, 32) + wasmall_starty[npc] + mana.being_walk(npc, x, y, 2) + end +end + + +-- Update function walkaround_wide +-- makes the NPC walk around in a 256x256 pixel square around its start +-- location. Useful for NPCs which are supposed to be found near a specific +-- location but not nailed to the floor. + +local wawide_timer = {} +local wawide_startx = {} +local wawide_starty = {} + +function walkaround_wide(npc) + if not wawide_timer[npc] then + wawide_timer[npc] = 1 + wawide_startx[npc] = mana.posX(npc) + wawide_starty[npc] = mana.posY(npc) + end + + wawide_timer[npc] = wawide_timer[npc] + 1 + + if wawide_timer[npc] == 50 then + wawide_timer[npc] = math.random(1, 10) + local x = math.random(-128, 128) + wawide_startx[npc] + local y = math.random(-128, 128) + wawide_starty[npc] + mana.being_walk(npc, x, y, 2) + end +end + + +-- Update function walkaround_map +-- makes the NPC wander around the whole map. Useful when the players are +-- supposed to search a bit for the NPC. + +local wam_timer = {} + +function walkaround_map(npc) + if not wam_timer[npc] then + wam_timer[npc] = 1 + end + + wam_timer[npc] = wam_timer[npc] + 1 + + if wam_timer[npc] == 50 then + wam_timer[npc] = math.random(1, 10) + local x = math.random(-128, 128) + mana.posX(npc) + local y = math.random(-128, 128) + mana.posY(npc) + mana.being_walk(npc, x, y, 2) + end +end + +-- Allows passage of more information to an NPC's talk function +function talk(f, ...) + local a = {...} + return function(npc, ch) + f(npc, ch, a) + end +end diff --git a/src/common/resourcemanager.cpp b/src/common/resourcemanager.cpp index 8db45465..5d2a8cf4 100644 --- a/src/common/resourcemanager.cpp +++ b/src/common/resourcemanager.cpp @@ -41,11 +41,14 @@ void ResourceManager::initialize() { PHYSFS_permitSymbolicLinks(1); + const std::string serverPath = + Configuration::getValue("serverPath", "."); const std::string clientDataPath = Configuration::getValue("clientDataPath", "example/clientdata"); const std::string serverDataPath = Configuration::getValue("serverDataPath", "example/serverdata"); + PHYSFS_addToSearchPath(serverPath.c_str(), 1); PHYSFS_addToSearchPath(clientDataPath.c_str(), 1); PHYSFS_addToSearchPath(serverDataPath.c_str(), 1); } diff --git a/src/scripting/lua.cpp b/src/scripting/lua.cpp index 507b348f..ca916248 100644 --- a/src/scripting/lua.cpp +++ b/src/scripting/lua.cpp @@ -1694,6 +1694,5 @@ LuaScript::LuaScript(): lua_settable(mState, LUA_REGISTRYINDEX); lua_settop(mState, 0); - loadFile("scripts/libs/libmana.lua"); + loadFile("scripts/lua/libmana.lua"); } - |