From 3629aebb96959afc56cf04d1f2fc4a9f03e94183 Mon Sep 17 00:00:00 2001 From: Thorbjørn Lindeijer Date: Sat, 25 Feb 2012 21:18:46 +0100 Subject: Merged the example client and server data It's easier to just talk about world data and to modify it as a whole. If there is really a need to separate it, a project can still choose to do that (and in whatever suitable way). There is no need to enforce this separation or to do it in our example. Reviewed-by: Erik Schilling --- example/scripts/bomtest.lua | 7 ++ example/scripts/crafting.lua | 99 +++++++++++++++++++++ example/scripts/global_events.lua | 78 +++++++++++++++++ example/scripts/items/candy.lua | 17 ++++ example/scripts/main.lua | 17 ++++ example/scripts/maps/desert.lua | 149 ++++++++++++++++++++++++++++++++ example/scripts/monster/testmonster.lua | 26 ++++++ example/scripts/npcs/banker.lua | 79 +++++++++++++++++ example/scripts/npcs/barber.lua | 139 +++++++++++++++++++++++++++++ example/scripts/npcs/debugger.lua | 100 +++++++++++++++++++++ example/scripts/npcs/emotemaker.lua | 45 ++++++++++ example/scripts/npcs/healer.lua | 21 +++++ example/scripts/npcs/merchant.lua | 114 ++++++++++++++++++++++++ example/scripts/npcs/postman.lua | 30 +++++++ example/scripts/npcs/shaker.lua | 48 ++++++++++ example/scripts/special_actions.lua | 39 +++++++++ example/scripts/status/jump.lua | 53 ++++++++++++ example/scripts/status/plague.lua | 28 ++++++ 18 files changed, 1089 insertions(+) create mode 100644 example/scripts/bomtest.lua create mode 100644 example/scripts/crafting.lua create mode 100644 example/scripts/global_events.lua create mode 100644 example/scripts/items/candy.lua create mode 100644 example/scripts/main.lua create mode 100644 example/scripts/maps/desert.lua create mode 100644 example/scripts/monster/testmonster.lua create mode 100644 example/scripts/npcs/banker.lua create mode 100644 example/scripts/npcs/barber.lua create mode 100644 example/scripts/npcs/debugger.lua create mode 100644 example/scripts/npcs/emotemaker.lua create mode 100644 example/scripts/npcs/healer.lua create mode 100644 example/scripts/npcs/merchant.lua create mode 100644 example/scripts/npcs/postman.lua create mode 100644 example/scripts/npcs/shaker.lua create mode 100644 example/scripts/special_actions.lua create mode 100644 example/scripts/status/jump.lua create mode 100644 example/scripts/status/plague.lua (limited to 'example/scripts') diff --git a/example/scripts/bomtest.lua b/example/scripts/bomtest.lua new file mode 100644 index 0000000..d4b0212 --- /dev/null +++ b/example/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/example/scripts/crafting.lua b/example/scripts/crafting.lua new file mode 100644 index 0000000..eae26a4 --- /dev/null +++ b/example/scripts/crafting.lua @@ -0,0 +1,99 @@ +------------------------------------------------------------- +-- Example crafting script file -- +-- -- +-- This file allows you to implement your own crafting -- +-- system. -- +---------------------------------------------------------------------------------- +-- Copyright 2011 Manasource Development Team -- +-- -- +-- This file is part of Manasource. -- +-- -- +-- Manasource 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. -- +---------------------------------------------------------------------------------- + +-- This function is called by the game engine when a character tries to craft +-- something from items in its inventory +function on_craft(ch, recipe) + -- ch is the crafting character + -- + -- recipe is a table with the ingredients. + -- it is a common 1-based array. each element of this array is a table with the + -- two keys "id" and "amount". + -- The engine has already checked that the character owns enough of those things, + -- so you needn't do this again. + + -- uncomment one (but not both!) of the following three lines to enable the + -- example crafting systems + + mana.chat_message(ch, "There is no crafting in this game world.") + --craft_strict(ch, recipe) + --craft_lax(ch, recipe) +end + + +-- a primitive example crafting system which cares about item order and exact amount +function craft_strict(ch, recipe) + if (recipe[1].id == 8 and recipe[1].amount == 2 and -- has two iron + recipe[2].id == 9 and recipe[2].amount == 1) -- and one wood + then + mana.chr_inv_change(ch, + 8, -2, --take away the iron + 9, -1, --take away the wood + 5, 1 ) -- give a sword + mana.chat_message(ch, "You've crafted a sword") + return + end + mana.chat_message(ch, "This wouldn't create anything useful") +end + +-- a primitive example crafting system which doesn't care about item order +-- and amount. It even allows to mention the same item multiple times. +function craft_lax(ch, recipe) + recipe = make_condensed_and_sorted_item_list(recipe) + + if (recipe[1].id == 8 and recipe[1].amount >= 2 and -- has at least two iron + recipe[2].id == 9 and recipe[2].amount >= 1) -- and at least one wood + then + mana.chr_inv_change(ch, + 8, -2, --take away the iron + 9, -1, --take away the wood + 5, 1 ) -- give a sword + mana.chat_message(ch, "You've crafted a sword") + return + end + mana.chat_message(ch, "This wouldn't create anything useful") +end + +-- this turns multiple occurences of the same item into one by adding up +-- their amounts and sorts the recipe by item ID. +-- This makes stuff a lot easier when your crafting system isn't supposed to care +-- about the order items are in. +function make_condensed_and_sorted_item_list(recipe) + + local condensed = {} + for index, item in pairs(recipe) do + if condensed[item.id] == nil then + condensed[item.id] = item.amount + else + condensed[item.id] = condensed[item.id] + item.amount + end + end + + local sorted = {} + for id, amount in pairs(condensed) do + local item = {} + item.id = id + item.amount = amount + table.insert(sorted, item) + end + + table.sort(sorted, function(item1, item2) + return (item1.id < item2.id) + end + ) + + return sorted + +end \ No newline at end of file diff --git a/example/scripts/global_events.lua b/example/scripts/global_events.lua new file mode 100644 index 0000000..548351a --- /dev/null +++ b/example/scripts/global_events.lua @@ -0,0 +1,78 @@ +------------------------------------------------------------- +-- Global event script file -- +-- -- +-- This file allows you to modify how certain events which -- +-- happen frequently in the game on different maps are -- +-- supposed to be handled. It is a collection of script -- +-- functions which are always called when certain events -- +-- happen, regardless on which map. Script execution is -- +-- done in the context of the map the event happens on. -- +---------------------------------------------------------------------------------- +-- Copyright 2010 Manasource Development Team -- +-- -- +-- This file is part of Manasource. -- +-- -- +-- Manasource 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. -- +---------------------------------------------------------------------------------- + + +-- This function is called when the hit points of a character reach zero. +function on_chr_death(ch) + mana.being_say(ch, "Noooooo!!!") +end + +-- This function is called when the player clicks on the �OK� button after +-- the death message appeared. It should be used to implement the respawn +-- mechanic (for example: warp the character to the respawn location and +-- bring HP above zero in some way) +function on_chr_death_accept(ch) + mana.being_heal(ch) -- restores to full hp + -- mana.being_heal(ch, 1) --restores 1 hp (in case you want to be less nice) + mana.chr_warp(ch, 1, 815, 100) --warp the character to the respawn location +end + +-- This function is called after chr_death_accept. The difference is that +-- it is called in the context of the map the character is spawned on after +-- the respawn logic has happened. +function on_chr_respawn(ch) + -- calls the local_respawn_function of the map the character respawned + -- on when the script of the map has one + if local_respawn_function ~= nil then + local_respawn_function(ch) + end +end + + +-- This function is called when a new character enters the world for the +-- first time. This can, for example, be used to give starting equipment +-- to the character and/or initialize a tutorial quest. +function on_chr_birth(ch) + -- this message is shown on first login. + mana.chat_message(0, ch, "And so your adventure begins...") +end + +-- This function is called when a character logs into the game. This can, +-- for example, be utilized for a message-of-the-day or for various +-- handlings of offline processing mechanics. +function on_chr_login(ch) + mana.chat_message(0, ch, "Welcome to Manasource") +end + + +-- This function is called when a character is disconnected. This could +-- be useful for various handling of offline processing mechanics. +function on_chr_logout(ch) + -- notifies nearby players of logout + local around = mana.get_beings_in_circle( + posX(ch), + posY(ch), + 1000) + local msg = mana.being_get_name(ch).." left the game." + for b in pairs(around) do + if mana.being_type(b) == TYPE_CHARACTER then + mana.chat_message(0, b, msg) + end + end +end diff --git a/example/scripts/items/candy.lua b/example/scripts/items/candy.lua new file mode 100644 index 0000000..a740ce6 --- /dev/null +++ b/example/scripts/items/candy.lua @@ -0,0 +1,17 @@ +------------------------------------------------------------- +-- Example use script. Makes the player character say -- +-- "*munch*munch*munch*" when using this item. -- +-- The HP regeneration effect is handled separately based -- +-- on the heal value in items.xml -- +---------------------------------------------------------------------------------- +-- Copyright 2009 The Mana World Development Team -- +-- -- +-- This file is part of The Mana World. -- +-- -- +-- The Mana World 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. -- +---------------------------------------------------------------------------------- +function use(user) + mana.being_say(user, "*munch*munch*munch*") +end diff --git a/example/scripts/main.lua b/example/scripts/main.lua new file mode 100644 index 0000000..d5d8bd0 --- /dev/null +++ b/example/scripts/main.lua @@ -0,0 +1,17 @@ +---------------------------------------------------------------------------------- +-- Copyright 2011 Manasource Development Team -- +-- -- +-- This file is part of Manasource. -- +-- -- +-- Manasource 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. -- +---------------------------------------------------------------------------------- + +-- This is the main script file loaded by the server, as configured in +-- manaserv.xml. It defines how certain global events should be handled. + +-- At the moment the event handlers are split up over the following files: +require "scripts/global_events" +require "scripts/special_actions" +require "scripts/crafting" diff --git a/example/scripts/maps/desert.lua b/example/scripts/maps/desert.lua new file mode 100644 index 0000000..c330247 --- /dev/null +++ b/example/scripts/maps/desert.lua @@ -0,0 +1,149 @@ +---------------------------------------------------------- +-- Template script for the Desert map -- +---------------------------------------------------------------------------------- +-- Copyright 2011 The Mana Development Team -- +-- -- +-- This file is part of Manasource Project. -- +-- -- +-- Manasource 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. -- +---------------------------------------------------------------------------------- + +-- From scripts/ +require "scripts/lua/npclib" +-- From example/scripts +require "scripts/npcs/banker" +require "scripts/npcs/barber" +require "scripts/npcs/merchant" +require "scripts/npcs/shaker" + +atinit(function() + + -- Barber examples + create_npc("Barber Twin", 1, GENDER_MALE, 14 * TILESIZE + TILESIZE / 2, 9 * TILESIZE + TILESIZE / 2, Barber, nil) + create_npc("Barber Twin", 1, GENDER_MALE, 20 * TILESIZE + TILESIZE / 2, 11 * TILESIZE + TILESIZE / 2, npclib.talk(Barber, {14, 15, 16}, {}), nil) + + -- A simple banker + create_npc("Banker", 8, GENDER_MALE, 35 * TILESIZE + TILESIZE / 2, 24 * TILESIZE + TILESIZE / 2, Banker, nil) + + -- A simple merchant. + merchant_buy_table = { {"Candy", 10, 20}, {"Regenerative trinket", 10, 30}, {"Minor health potion", 10, 50}, {11, 10, 60}, {12, 10, 40} } + merchant_sell_table = { {"Candy", 10, 19}, {"Sword", 10, 30}, {"Bow", 10, 200}, {"Leather shirt", 10, 300} } + create_npc("Merchant", 3, GENDER_MALE, 4 * TILESIZE + TILESIZE / 2, 16 * TILESIZE + TILESIZE / 2, npclib.talk(Merchant, merchant_buy_table, merchant_sell_table), nil) + + -- Another Merchant, selling some equipment, and buying everything... + smith_buy_table = { {"Sword", 10, 50}, {7, 10, 70}, {10, 10, 20} } + create_npc("Smith", 5, GENDER_MALE, 15 * TILESIZE + TILESIZE / 2, 16 * TILESIZE + TILESIZE / 2, npclib.talk(Smith, smith_buy_table), nil) + + -- The most simple NPC - Welcoming new ones around. + create_npc("Harmony", 11, GENDER_FEMALE, 4 * TILESIZE + TILESIZE / 2, 25 * TILESIZE + TILESIZE / 2, npclib.talk(Harmony, "Welcome in the template world!\nI hope you'll find here whatever you were searching for.", "Do look around to find some interesting things coming along!"), Harmony_update) + + -- Creates a Monster an let it talk for testing purpose. + create_npc("Tamer", 9, GENDER_UNSPECIFIED, 28 * TILESIZE + TILESIZE / 2, 21 * TILESIZE + TILESIZE / 2, Tamer, nil) +end) + +function Smith(npc, ch, list) + local sword_count = mana.chr_inv_count(ch, true, true, "Sword") + if sword_count > 0 then + do_message(npc, ch, "Ah! I can see you already have a sword.") + end + Merchant(npc, ch, list) +end + +function possessions_table(npc, ch) + local item_message = "Inventory:".. + "\nSlot id, item id, item name, amount:".. + "\n----------------------" + local inventory_table = mana.chr_get_inventory(ch) + for i = 1, #inventory_table do + item_message = item_message.."\n"..inventory_table[i].slot..", " + ..inventory_table[i].id..", "..inventory_table[i].name..", " + ..inventory_table[i].amount + end + do_message(npc, ch, item_message) + + item_message = "Equipment:".. + "\nSlot id, item id, item name:".. + "\n----------------------" + local equipment_table = mana.chr_get_equipment(ch) + for i = 1, #equipment_table do + item_message = item_message.."\n"..equipment_table[i].slot..", " + ..equipment_table[i].id..", "..equipment_table[i].name + end + do_message(npc, ch, item_message) + +end + +-- Global variable used to know whether Harmony talked to someone. +harmony_have_talked_to_someone = false +function Harmony(npc, ch, list) + -- Say all the messages in the messages list. + for i = 1, #list do + do_message(npc, ch, list[i]) + end + --- Give the player 100 units of money the first time. + if harmony_have_talked_to_someone == false then + do_message(npc, ch, "Here is some money for you to find some toys to play with.\nEh Eh!") + mana.chr_money_change(ch, 100) + do_message(npc, ch, string.format("You now have %d shiny coins!", mana.chr_money(ch))) + harmony_have_talked_to_someone = true + do_message(npc, ch, string.format("Try to come back with a better level than %i.", mana.chr_get_level(ch))) + else + do_message(npc, ch, "Let me see what you've got so far... Don't be afraid!") + mana.effect_create(EMOTE_WINK, npc) + possessions_table(npc, ch) + end + do_message(npc, ch, "Have fun!") + mana.effect_create(EMOTE_HAPPY, npc) + -- Make Harmony disappear for a while... with a small earthquake effect! + local shakeX = mana.posX(npc) + local shakeY = mana.posY(npc) + mana.npc_disable(npc) + tremor(shakeX, shakeY, 300) + + -- 20 seconds later, Harmony comes back + schedule_in(20, function() mana.npc_enable(npc) end) + schedule_in(20, function() tremor(shakeX, shakeY, 300) end) +end + +-- Global variable used to control Harmony's updates. +-- One tick equals to 100ms, so 100 below equals to 10000ms or 10 seconds +harmony_tick_count = 0 +function Harmony_update(npc) + if harmony_have_talked_to_someone == false then + harmony_tick_count = harmony_tick_count + 1 + if harmony_tick_count > 100 then + harmony_tick_count = 0 + mana.being_say(npc, "Hey! You're new! Come here...") + end + end +end + +function Tamer(npc, ch, list) + mana.being_say(npc, string.format("You have %s Sword(s).", + mana.chr_inv_count(ch, true, true, "Sword"))) + mana.being_say(npc, string.format("You are %s pixel away.", + mana.get_distance(npc, ch))) + mana.being_say(npc, "I will now spawn a monster for your training session.") + + -- Remove monsters in the area + for i, b in ipairs(mana.get_beings_in_rectangle(mana.posX(npc) - 3 * TILESIZE, + mana.posY(npc) - 3 * TILESIZE, + 6 * TILESIZE, 6 * TILESIZE)) do + if mana.being_type(b) == TYPE_MONSTER then + mana.monster_remove(b) + end + end + + local m1 = mana.monster_create("Maggot", mana.posX(ch), mana.posY(ch)) + mana.monster_change_anger(m1, ch, 100) + + -- (The following is not safe, since the being might have been removed by + -- the time this function gets executed (especially with the above code)) + -- + --schedule_in(0.5, function() + -- mana.being_say(m1, "Roaaarrrr!!!") + -- mana.monster_change_anger(m1, ch, 100) + -- end) +end diff --git a/example/scripts/monster/testmonster.lua b/example/scripts/monster/testmonster.lua new file mode 100644 index 0000000..9938943 --- /dev/null +++ b/example/scripts/monster/testmonster.lua @@ -0,0 +1,26 @@ +---------------------------------------------------------------------------------- +-- Copyright 2009 The Mana World Development Team -- +-- -- +-- This file is part of The Mana World. -- +-- -- +-- The Mana World 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. -- +---------------------------------------------------------------------------------- + +function update(mob) + local r = math.random(0, 200); + if r == 0 then + mana.being_say(mob, "Roar! I am a boss") + end +end + +function strike(mob, victim, hit) + if hit > 0 then + mana.being_say(mob, "Take this! "..hit.." damage!") + mana.being_say(victim, "Oh Noez!") + else + mana.being_say(mob, "Oh no, my attack missed!") + mana.being_say(victim, "Whew...") + end +end diff --git a/example/scripts/npcs/banker.lua b/example/scripts/npcs/banker.lua new file mode 100644 index 0000000..4e04865 --- /dev/null +++ b/example/scripts/npcs/banker.lua @@ -0,0 +1,79 @@ +---------------------------------------------------------- +-- Banker Function -- +---------------------------------------------------------------------------------- +-- Copyright 2008 The Mana World Development Team -- +-- -- +-- This file is part of The Mana World. -- +-- -- +-- The Mana World 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. -- +---------------------------------------------------------------------------------- + +function Banker(npc, ch) + if mana.being_get_gender(ch) == GENDER_MALE then + do_message(npc, ch, "Welcome to the bank, sir!") + elseif mana.being_get_gender(ch) == GENDER_FEMALE then + do_message(npc, ch, "Welcome to the bank, madam!") + else + do_message(npc, ch, "Welcome to the bank... uhm... person of unspecified gender!") + end + local account = tonumber(get_quest_var(ch, "BankAccount")) + local result = -1 + do_wait() + + if (account == nil) then --Initial account creation, if needed + do_message(npc, ch, "Hello! Would you like to setup a bank account? There is a sign-on bonus right now!") + result = do_choice(npc, ch, "Yes", "No") + if (result == 1) then + mana.chr_set_quest(ch, "BankAccount", 5) + do_message(npc, ch, "Your account has been made. Your sign-on bonus is 5GP.") + account = 5 + end + end + + if (account ~= nil) then --If the player has an account + local money = 0 + local input = 0 + result = 1 + while (result < 3) do --While they've choosen a valid option that isn't "Never mind" + account = tonumber(get_quest_var(ch, "BankAccount")) --Why do I need to convert this? + do_message(npc, ch, "Your balance: " .. account .. ".\nYour money: " .. mana.chr_money(ch) .. ".") + result = do_choice(npc, ch, "Deposit", "Withdraw", "Never mind") + if (result == 1) then --Deposit + money = mana.chr_money(ch); + if (money > 0) then --Make sure they have money to deposit + do_message(npc, ch, "How much would you like to deposit? (0 will cancel)") + input = do_ask_integer(npc, ch, 0, money, 1) + do_wait() + money = mana.chr_money(ch) + if (input > 0 and input <= money) then --Make sure something weird doesn't happen and they try to deposit more than they have + mana.chr_money_change(ch, -input) + mana.chr_set_quest(ch, "BankAccount", account + input) + do_message(npc, ch, input .. " GP deposited.") + elseif (input > money) then --Chosen more than they have + do_message(npc, ch, "You don't have that much money. But you just did....") + end + else + do_message(npc, ch, "You don't have any money to deposit!") + end + elseif (result == 2) then --Withdraw + if (account > 0) then --Make sure they have money to withdraw + do_message(npc, ch, "How much would you like to withdraw? (0 will cancel)") + input = do_ask_integer(npc, ch, 0, account, 1) + if (input > 0 and input <= account) then --Make sure something weird doesn't happen and they try to withdraw more than they have + mana.chr_money_change(ch, input) + mana.chr_set_quest(ch, "BankAccount", account - input) + do_message(npc, ch, input .. " GP withdrawn.") + elseif (input > account) then --Chosen more than they have + do_message(npc, ch, "You don't have that much in your account. But you just did....") + end + else + do_message(npc, ch, "Your account is empty!") + end + end + end --This ends the while loop + end + + do_message(npc, ch, "Thank you. Come again!") +end diff --git a/example/scripts/npcs/barber.lua b/example/scripts/npcs/barber.lua new file mode 100644 index 0000000..fbb2862 --- /dev/null +++ b/example/scripts/npcs/barber.lua @@ -0,0 +1,139 @@ +---------------------------------------------------------- +-- Barber Function -- +---------------------------------------------------------------------------------- +-- Copyright 2009 The Mana World Development Team -- +-- -- +-- This file is part of The Mana World. -- +-- -- +-- The Mana World 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. -- +---------------------------------------------------------------------------------- + +local barber_styles = {"Flat ponytail", "Bowl cut","Combed back", "Emo", "Mohawk", + "Pompadour", "Center parting/Short and slick", "Long and slick", "Short and curly", + "Pigtails", "Long and curly", "Parted", "Perky ponytail", "Wave", "Mane", "Bun"} + +local barber_colors = {"Light brown", "Green", "Dark red", "Light purple", "Gray", "Blonde", + "Blue", "Brown", "Light Bblue", "Dark purple", "Black", "Shock white"} + +function Barber(npc, ch, data) + local style_ids = nil + local color_ids = nil + + -- If extra data was passed, let's have a look at it + if data ~= nil then + style_ids = data[1] + if #data > 1 then + color_ids = data[2] + end + end + + -- Setup up default styles (if needed) + if style_ids == nil then + style_ids = {} + for i = 1, 13 do + style_ids[i] = i + end + end + + -- Setup up default colors (if needed) + if color_ids == nil then + color_ids = {} + for i = 1, 11 do + color_ids[i] = i + end + end + + -- Nothing to show? Then we can return + if #color_ids == 0 and #style_ids == 0 then + return + end + + local result = 0 + + local styles = {} + + -- If we have style IDs, lets get their names + if #style_ids > 0 then + for i = 1, #style_ids do + styles[i] = barber_styles[style_ids[i]] + end + result = 1 + end + + local colors = {} + + -- If we have color style IDs, lets get their names + if #color_ids > 0 then + for i = 1, #color_ids do + colors[i] = barber_colors[color_ids[i]] + end + + if result == 0 then + result = 2 + else + result = 3 + end + end + + -- Choose an appropriate message + if result == 1 then + do_message(npc, ch, "Hello! What style would you like today?") + elseif result == 2 then + do_message(npc, ch, "Hello! What color would you like today?") + else + do_message(npc, ch, "Hello! What can I do for you today?") + end + + print("#styles ==", #styles) + + -- Repeat until the user selects nothing + repeat + if (result == 1) then -- Do styles + result = do_choice(npc, ch, "Bald", styles, "Surprise me", "Never mind") + + result = result -1 + + --Random + if (result == #styles + 1) then + result = math.random(#styles + 1) - 1 + print("Random") + end + + print("Style ==", result) + + if (result == 0) then + mana.chr_set_hair_style(ch, 0) + result = 1 + elseif (result <= #styles) then + mana.chr_set_hair_style(ch, style_ids[result]) + result = 1 + else --"Never mind" + result = 3 + end + elseif (result == 2) then -- Do colors + result = do_choice(npc, ch, colors, "Surprise me", "Never mind") + + --Random + if (result == #colors + 1) then + result = math.random(#colors) + end + + if (result <= #colors) then + mana.chr_set_hair_color(ch, color_ids[result - 1]) + result = 2 + else --"Never mind" + result = 3 + end + end + + -- If we have both styles and colors, show the main menu + if #styles > 0 and #colors > 0 then + result = do_choice(npc, ch, "Change my style", "Change my color", "Never mind") + end + until result >= 3 --While they've choosen a valid option that isn't "Never mind" + + -- Let's close up + do_message(npc, ch, "Thank you. Come again!") +end diff --git a/example/scripts/npcs/debugger.lua b/example/scripts/npcs/debugger.lua new file mode 100644 index 0000000..142c3fd --- /dev/null +++ b/example/scripts/npcs/debugger.lua @@ -0,0 +1,100 @@ +---------------------------------------------------------- +-- Seller Function Sample -- +---------------------------------------------------------------------------------- +-- Copyright 2009-2010 The Mana World Development Team -- +-- -- +-- This file is part of The Mana World. -- +-- -- +-- The Mana World 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. -- +---------------------------------------------------------------------------------- + +function npc1_talk(npc, ch) + on_remove(ch, function() print "Player has left the map." end); + do_message(npc, ch, "Hello! I am the testing NPC.") + local rights = mana.chr_get_rights(ch); + + if (rights >= 128) then + do_message(npc, ch, "Oh mighty server administrator, how can I avoid your wrath?") + elseif (rights >= 8) then + do_message(npc, ch, "How can I be of assistance, sir gamemaster?") + elseif (rights >= 4) then + do_message(npc, ch, "What feature would you like to debug, developer?") + elseif (rights >= 2) then + do_message(npc, ch, "How can I assist you in your testing duties?") + elseif (rights >= 1) then + do_message(npc, ch, "What do you want, lowly player?") + else + do_message(npc, ch, "...aren't you supposed to be banned??") + end + + local v = do_choice(npc, ch, "Guns! Lots of guns!", + "A Christmas party!", + "To make a donation.", + "Slowly count from one to ten.", + "Tablepush Test") + if v == 1 then + do_message(npc, ch, "Sorry, this is a heroic-fantasy game, I do not have any gun.") + + elseif v == 2 then + local n1, n2 = mana.chr_inv_count(ch, 524, 511) + if n1 == 0 or n2 ~= 0 then + do_message(npc, ch, "Yeah right...") + else + do_message(npc, ch, "I can't help you with the party. But I see you have a fancy hat. I could change it into Santa's hat. Not much of a party, but it would get you going.") + v = do_choice(npc, ch, "Please do.", "No way! Fancy hats are classier.") + if v == 1 then + mana.chr_inv_change(ch, 524, -1, 511, 1) + end + end + + elseif v == 3 then + if mana.chr_money_change(ch, -100) then + do_message(npc, ch, string.format("Thank you for you patronage! You are left with %d GP.", mana.chr_money(ch))) + local g = tonumber(get_quest_var(ch, "001_donation")) + if not g then g = 0 end + g = g + 100 + mana.chr_set_quest(ch, "001_donation", g) + do_message(npc, ch, string.format("As of today, you have donated %d GP.", g)) + else + do_message(npc, ch, "I would feel bad taking money from someone that poor.") + end + + elseif v == 4 then + mana.being_say(npc, "As you wish...") + schedule_in(2, function() mana.being_say(npc, "One") end) + schedule_in(4, function() mana.being_say(npc, "Two") end) + schedule_in(6, function() mana.being_say(npc, "Three") end) + schedule_in(8, function() mana.being_say(npc, "Four") end) + schedule_in(10, function() mana.being_say(npc, "Five") end) + schedule_in(12, function() mana.being_say(npc, "Six") end) + schedule_in(14, function() mana.being_say(npc, "Seven") end) + schedule_in(16, function() mana.being_say(npc, "Eight") end) + schedule_in(18, function() mana.being_say(npc, "Nine") end) + schedule_in(20, function() mana.being_say(npc, "Ten") end) + + elseif v == 5 then + function printTable (t) + for k,v in pairs(t) do + print (k, ":", v) + end + end + local t1, t2, t3, t4, t5 = mana.test_tableget(); + print("---------------"); + print ("Table 1:"); + printTable (t1) + print ("Table 2:"); + printTable (t2) + print ("Table 3:"); + printTable (t3) + print ("Table 4:"); + printTable (t4) + print ("Table 5:"); + printTable (t5) + print("---------------"); + end + + do_message(npc, ch, "See you later!") +end + diff --git a/example/scripts/npcs/emotemaker.lua b/example/scripts/npcs/emotemaker.lua new file mode 100644 index 0000000..83d2f56 --- /dev/null +++ b/example/scripts/npcs/emotemaker.lua @@ -0,0 +1,45 @@ +---------------------------------------------------------- +-- Emote use Function Sample -- +---------------------------------------------------------------------------------- +-- Copyright 2009-2010 The Mana World Development Team -- +-- -- +-- This file is part of The Mana World. -- +-- -- +-- The Mana World 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. -- +---------------------------------------------------------------------------------- + +emo_count = 0 +emo_state = EMOTE_SURPRISE + +function emote_talk(npc, ch) + if emo_state == EMOTE_SURPRISE then + state = "confused" + elseif emo_state == EMOTE_SAD then + state = "sad" + elseif emo_state == EMOTE_HAPPY then + state = "happy" + end + do_message(npc, ch, string.format("The emotional palm seems %s.", state)) + v = do_choice(npc, ch, + "Stupid palm, you are ugly and everyone hates you!", + "You are such a nice palm, let me give you a hug.", + "Are you a cocos nucifera or a syagrus romanzoffiana?") + + if (v == 1) then + emo_state = EMOTE_SAD + elseif (v == 2) then + emo_state = EMOTE_HAPPY + elseif (v == 3) then + emo_state = EMOTE_SURPRISE + end +end + +function emote_update(npc) + emo_count = emo_count + 1 + if emo_count > 50 then + emo_count = 0 + mana.effect_create(emo_state, npc) + end +end diff --git a/example/scripts/npcs/healer.lua b/example/scripts/npcs/healer.lua new file mode 100644 index 0000000..88335c2 --- /dev/null +++ b/example/scripts/npcs/healer.lua @@ -0,0 +1,21 @@ +---------------------------------------------------------- +-- Healer Function Sample -- +---------------------------------------------------------------------------------- +-- Copyright 2009-2010 The Mana World Development Team -- +-- -- +-- This file is part of The Mana World. -- +-- -- +-- The Mana World 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. -- +---------------------------------------------------------------------------------- + +function Healer(npc, ch) + do_message(npc, ch, "Do you need healing?") + local c = do_choice(npc, ch, "Heal me fully", "Heal 100 HP", "Don't heal me") + if c == 1 then + mana.being_heal(ch) + elseif c == 2 then + mana.being_heal(ch, 100) + end +end diff --git a/example/scripts/npcs/merchant.lua b/example/scripts/npcs/merchant.lua new file mode 100644 index 0000000..92eeea3 --- /dev/null +++ b/example/scripts/npcs/merchant.lua @@ -0,0 +1,114 @@ +---------------------------------------------------------- +-- Merchant Function Sample -- +---------------------------------------------------------------------------------- +-- Copyright 2009-2010 The Mana World Development Team -- +-- -- +-- This file is part of The Mana World. -- +-- -- +-- The Mana World 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. -- +---------------------------------------------------------------------------------- + +function Merchant(npc, ch, buy_sell_table) + + local function say(message) + do_message(npc, ch, message) + end + + -- Important note: You can add two tables made of trinoms here when calling the + -- merchant function. E.g.: Merchant(npc, ch, buy_table, sell_table) + -- Even though, the function here will see only one table: + -- buy_sell_table[1] will corresponds to the first table (used to list + -- boughtable items, and buy_sell_table[2] listing sellable items. + + local rights = mana.chr_get_rights(ch); + + if (rights >= 128) then + mana.announce(mana.being_get_name(ch) .. " the big administrator was at my shop!", + mana.being_get_name(npc)) + say "Oh mighty server administrator, how can I avoid your wrath?" + elseif (rights >= 8) then + say "How can I be of assistance, sir gamemaster?" + elseif (rights >= 4) then + say "What feature would you like to debug, developer?" + elseif (rights >= 2) then + say "How can I assist you in your testing duties?" + elseif (rights >= 1) then + if mana.being_get_gender(ch) == GENDER_FEMALE then + say "What do you want, Madam?" + else + say "What do you want, Sir?" + end + else + say "...Aren't you supposed to be banned??" + end + + -- Constructing the choice list + local choice_table = {} + table.insert (choice_table, "To Buy...") + + if (buy_sell_table[2] == nil) then + table.insert (choice_table, "To sell stuff...") + else + table.insert (choice_table, "Can you make me a price for what I have?") + end + table.insert (choice_table, "Tell me about the objects on this map") + table.insert (choice_table, "Nevermind...") + + local v = do_choice(npc, ch, choice_table) + + --Debug and learning purpose + --for i,k in ipairs(choice_table) do print(i,k) end + -- The buy table first line content + --print (((buy_sell_table[1])[1])[1], ((buy_sell_table[1])[1])[2], ((buy_sell_table[1])[1])[3]) + -- The sell table first line content + --print (((buy_sell_table[2])[1])[1], ((buy_sell_table[2])[1])[2], ((buy_sell_table[2])[1])[3]) + + if v == 1 then + -- "To buy." + local buycase = mana.npc_trade(npc, ch, false, buy_sell_table[1]) + if buycase == 0 then + say "What do you want to buy?" + elseif buycase == 1 then + say "I've got no items to sell." + else + say "Hmm, something went wrong... Ask a scripter to fix the buying mode!" + end + + elseif v == 2 then + + if buy_sell_table[2] == nil then + -- "To sell stuff..." + local sellcase = mana.npc_trade(npc, ch, true) + if sellcase == 0 then + say "Ok, what do you want to sell?" + elseif sellcase == 1 then + say "I'm not interested by any of your items." + else + say "Hmm, something went wrong... Ask a scripter to fix this!" + end + else + -- "Can you make me a price for what I have?" + local sellcase = mana.npc_trade(npc, ch, true, buy_sell_table[2]) + if sellcase == 0 then + say "Here we go:" + elseif sellcase == 1 then + say "I'm not that interested in any of your items." + else + say "Hmm, something went wrong... Ask a scripter to fix me!" + end + end + + elseif v == 3 then + + local objects = mana.map_get_objects() + say("There are " .. #objects .. " objects on this map, their names are:") + for i=1,#objects do + say(tostring(i) .. ": " .. objects[i]:name()) + end + + end + + say "See you later!" +end diff --git a/example/scripts/npcs/postman.lua b/example/scripts/npcs/postman.lua new file mode 100644 index 0000000..712ea99 --- /dev/null +++ b/example/scripts/npcs/postman.lua @@ -0,0 +1,30 @@ +---------------------------------------------------------- +-- Postman Function Sample -- +---------------------------------------------------------------------------------- +-- Copyright 2009-2010 The Mana World Development Team -- +-- -- +-- This file is part of The Mana World. -- +-- -- +-- The Mana World 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. -- +---------------------------------------------------------------------------------- + +function post_talk(npc, ch) + do_message(npc, ch, "Hello " .. mana.being_get_name(ch)) + local strength = mana.being_get_attribute(ch, ATTR_STRENGTH) + do_message(npc, ch, "You have " .. tostring(strength) .. " strength") + do_message(npc, ch, "What would you like to do?") + local answer = do_choice(npc, ch, "View Mail", "Send Mail", "Nothing") + if answer == 1 then + local sender, post = getpost(ch) + if sender == "" then + do_message(npc, ch, "No Post right now, sorry") + else + do_message(npc, ch, tostring(sender) .. " sent you " .. tostring(post)) + end + end + if answer == 2 then + do_post(npc, ch) + end +end diff --git a/example/scripts/npcs/shaker.lua b/example/scripts/npcs/shaker.lua new file mode 100644 index 0000000..9d7bafb --- /dev/null +++ b/example/scripts/npcs/shaker.lua @@ -0,0 +1,48 @@ +---------------------------------------------------------------------------------- +-- Copyright 2009-2010 The Mana World Development Team -- +-- -- +-- This file is part of The Mana World. -- +-- -- +-- The Mana World 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. -- +---------------------------------------------------------------------------------- + +shake_count = 0 + +function shaker_update(npc) + shake_count = shake_count + 1 + if shake_count > 20 then + shake_count = 0 + + center_x = mana.posX(npc) + center_y = mana.posY(npc) + tremor(center_x, center_y, 300) + + end +end + +-- function which causes a screen shake effect for all players near a +-- certain point with an intensity and direction relative to said point +function square(x) + return x * x +end + +function tremor (center_x, center_y, intensity) + for dummy, object in ipairs(mana.get_beings_in_circle(center_x, center_y, intensity)) do + if mana.being_type(object) == TYPE_CHARACTER then + object_x = mana.posX(object) + object_y = mana.posY(object) + dist_x = object_x - center_x + dist_y = object_y - center_y + dist = math.sqrt(square(dist_x) + square(dist_y)) + intensity_local = intensity - dist + intensity_x = (intensity - dist) * (dist_x / dist) / 5 + intensity_y = (intensity - dist) * (dist_y / dist) / 5 + mana.chr_shake_screen(object, intensity_x, intensity_y) + end + end +end + + + diff --git a/example/scripts/special_actions.lua b/example/scripts/special_actions.lua new file mode 100644 index 0000000..135ad35 --- /dev/null +++ b/example/scripts/special_actions.lua @@ -0,0 +1,39 @@ +------------------------------------------------------------- +-- Special action script file -- +-- -- +-- This file allows you to implement your special -- +-- action system. The system can for example implement -- +-- magic, physical attack or also such mundane things -- +-- as showing emoticons over the characters heads. -- +---------------------------------------------------------------------------------- +-- Copyright 2010 Manasource Development Team -- +-- -- +-- This file is part of Manasource. -- +-- -- +-- Manasource 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. -- +---------------------------------------------------------------------------------- + +local specialCost = {} +specialCost[1] = 50 +specialCost[2] = 250 +specialCost[3] = 1000 + +function use_special(ch, id) + -- perform whatever the special with the ID does + if id == 1 then + mana.being_say(ch, "Kaaame...Haaame... HAAAAAA!") + end + if id == 2 then + mana.being_say(ch, "HAA-DOKEN!") + end + if id == 3 then + mana.being_say(ch, "Sonic BOOM") + end +end + +function get_special_recharge_cost(id) + -- return the recharge cost for the special with the ID + return specialCost[id] +end diff --git a/example/scripts/status/jump.lua b/example/scripts/status/jump.lua new file mode 100644 index 0000000..3410747 --- /dev/null +++ b/example/scripts/status/jump.lua @@ -0,0 +1,53 @@ +------------------------------------------------------------- +-- This status jumps from being to being -- +-- Thats all it does. -- +---------------------------------------------------------------------------------- +-- Copyright 2009 The Mana World Development Team -- +-- -- +-- This file is part of The Mana World. -- +-- -- +-- The Mana World 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. -- +---------------------------------------------------------------------------------- + + +function tick(target, ticknumber) + if (ticknumber % 10 == 0) then + mana.being_say(target, "I have the jumping bug!") + end + + if (mana.being_get_status_time(target, 2) < 2000) then + mana.being_set_status_time(target, 2, 6000) + end + + if (ticknumber % 50 ~= 0) then return end + + local victims = mana.get_beings_in_circle(mana.posX(target), mana.posY(target), 64) + local count = #victims + + if i == 0 then return end + + local i + local remaining = 1000 + local victim = nil + + repeat + remaining = remaining - 1 + i = math.random(count) + victim = victims[i] + if (victim == target) then + victim = nil + i = -1 + else + i = mana.being_type(victim) + end + until (i == TYPE_MONSTER or i == TYPE_CHARACTER or remaining == 0) + + if (victim == nil) then return end + + mana.being_remove_status(target, 2) + + mana.being_apply_status(victim, 2, 6000) + mana.being_say(victim, "Now I have the jumping bug") +end diff --git a/example/scripts/status/plague.lua b/example/scripts/status/plague.lua new file mode 100644 index 0000000..5f98268 --- /dev/null +++ b/example/scripts/status/plague.lua @@ -0,0 +1,28 @@ +------------------------------------------------------------- +-- This when applied to a being will spread from one being -- +-- to another -- +-- Thats all it does. -- +---------------------------------------------------------------------------------- +-- Copyright 2009 The Mana World Development Team -- +-- -- +-- This file is part of The Mana World. -- +-- -- +-- The Mana World 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. -- +---------------------------------------------------------------------------------- + +function tick(target, ticknumber) + if (ticknumber % 10 == 0) then + mana.being_say(target, "I have the plague! :( = " .. ticknumber) + end + local victims = mana.get_beings_in_circle(mana.posX(target), mana.posY(target), 64) + local i = 1 + while (victims[i]) do + if (mana.being_has_status(victims[i], 1) == false) then + mana.being_apply_status(victims[i], 1, 6000) + mana.being_say(victims[i], "I don't feel so good") + end + i = i + 1 + end +end -- cgit