summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGuillaume Melquiond <guillaume.melquiond@gmail.com>2007-08-11 09:52:32 +0000
committerGuillaume Melquiond <guillaume.melquiond@gmail.com>2007-08-11 09:52:32 +0000
commit797f8b0f29d8cfcefe8777bf337d75406210f71c (patch)
tree85833a464cbf80959c5f14f384249e409f686dce
parentde75c0a271c06e5569ec280ea04daadb9d4fea0c (diff)
downloadmanaserv-797f8b0f29d8cfcefe8777bf337d75406210f71c.tar.gz
manaserv-797f8b0f29d8cfcefe8777bf337d75406210f71c.tar.bz2
manaserv-797f8b0f29d8cfcefe8777bf337d75406210f71c.tar.xz
manaserv-797f8b0f29d8cfcefe8777bf337d75406210f71c.zip
Added Lua functions for handling inventories.
-rw-r--r--ChangeLog5
-rw-r--r--data/test.lua13
-rw-r--r--src/scripting/lua.cpp105
3 files changed, 117 insertions, 6 deletions
diff --git a/ChangeLog b/ChangeLog
index 215618be..bef5063a 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2007-08-11 Guillaume Melquiond <guillaume.melquiond@gmail.com>
+
+ * src/scripting/lua.cpp: Added Lua functions for handling inventories.
+ * data/test.lua: Tested them.
+
2007-08-10 Guillaume Melquiond <guillaume.melquiond@gmail.com>
* data/test.lua: Added Lua helper functions to simplify scripts.
diff --git a/data/test.lua b/data/test.lua
index 5252b825..6b914634 100644
--- a/data/test.lua
+++ b/data/test.lua
@@ -107,9 +107,20 @@ function my_npc1(npc, ch)
do_message(npc, ch, "Hello! I am the testing NPC")
do_message(npc, ch, "This message is just here for testing intertwined connections.")
do_message(npc, ch, "What do you want?")
- local v = do_choice(npc, ch, "Guns! Lots of guns!", "Nothing.")
+ local v = do_choice(npc, ch, "Guns! Lots of guns!", "A christmas party!", "Nothing.")
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 = tmw.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 a santa 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
+ tmw.chr_inv_change(ch, 524, -1, 511, 1)
+ end
+ end
end
end
diff --git a/src/scripting/lua.cpp b/src/scripting/lua.cpp
index fd3eb4f4..911c27cc 100644
--- a/src/scripting/lua.cpp
+++ b/src/scripting/lua.cpp
@@ -32,6 +32,9 @@ extern "C" {
#include "resourcemanager.h"
#include "game-server/character.hpp"
#include "game-server/gamehandler.hpp"
+#include "game-server/inventory.hpp"
+#include "game-server/item.hpp"
+#include "game-server/itemmanager.hpp"
#include "game-server/mapmanager.hpp"
#include "game-server/npc.hpp"
#include "game-server/state.hpp"
@@ -91,7 +94,8 @@ static Character *getCharacter(lua_State *s, int p)
}
/**
- * Callback for sending a NPC_MESSAGE (1: NPC, 2: Character, 3: string).
+ * Callback for sending a NPC_MESSAGE.
+ * tmw.msg_npc_message(npc, character, string)
*/
static int LuaMsg_NpcMessage(lua_State *s)
{
@@ -112,7 +116,8 @@ static int LuaMsg_NpcMessage(lua_State *s)
}
/**
- * Callback for sending a NPC_CHOICE (1: NPC, 2: Character, 3: string).
+ * Callback for sending a NPC_CHOICE.
+ * tmw.msg_npc_choice(npc, character, string...)
*/
static int LuaMsg_NpcChoice(lua_State *s)
{
@@ -140,8 +145,8 @@ static int LuaMsg_NpcChoice(lua_State *s)
}
/**
- * Callback for creating a NPC on the current map with the current script
- * (1: int) (2: int) (3: int).
+ * Callback for creating a NPC on the current map with the current script.
+ * tmw.obj_create_npc(int id, int x, int y): npc
*/
static int LuaObj_CreateNpc(lua_State *s)
{
@@ -169,7 +174,7 @@ static int LuaObj_CreateNpc(lua_State *s)
/**
* Callback for warping a player to another place.
- * (1: Character) (2: nil/int) (3: int) (4: int)
+ * tmw.chr_warp(character, nil/int map, int x, int y)
*/
static int LuaChr_Warp(lua_State *s)
{
@@ -203,6 +208,94 @@ static int LuaChr_Warp(lua_State *s)
return 0;
}
+/**
+ * Callback for inserting/removing items in inventory.
+ * The function can be called several times in a row, but it is better to
+ * perform all the changes at once, so as to reduce bandwidth. Removals
+ * (negative amount) should be passed first, then insertions (positive amount).
+ * If a removal fails, all the previous operations are canceled (except for
+ * items dropped on the floor, hence why removals should be passed first), and
+ * the function returns false. Otherwise the function will return true.
+ * Note: If an insertion fails, extra items are dropped on the floor.
+ * tmw.chr_inv_change(character, (int id, int nb)...): bool success
+ */
+static int LuaChr_InvChange(lua_State *s)
+{
+ Character *q = getCharacter(s, 1);
+ if (!q)
+ {
+ LOG_WARN("LuaChr_InvChange called with incorrect parameters.");
+ return 0;
+ }
+ int nb_items = (lua_gettop(s) - 1) / 2;
+ Inventory inv(q, true);
+ for (int i = 0; i < nb_items; ++i)
+ {
+ if (!lua_isnumber(s, i * 2 + 2) || !lua_isnumber(s, i * 2 + 3))
+ {
+ LOG_WARN("LuaChr_InvChange called with incorrect parameters.");
+ return 0;
+ }
+ int id = lua_tointeger(s, i * 2 + 2);
+ int nb = lua_tointeger(s, i * 2 + 3);
+ if (nb < 0)
+ {
+ nb = inv.remove(id, -nb);
+ if (nb)
+ {
+ inv.cancel();
+ lua_pushboolean(s, 0);
+ return 1;
+ }
+ }
+ else
+ {
+ nb = inv.insert(id, nb);
+ if (nb)
+ {
+ if (ItemClass *ic = ItemManager::getItem(id))
+ {
+ Item *item = new Item(ic, nb);
+ item->setMap(q->getMap());
+ item->setPosition(q->getPosition());
+ DelayedEvent e = { EVENT_INSERT };
+ GameState::enqueueEvent(item, e);
+ }
+ }
+ }
+ }
+ lua_pushboolean(s, 1);
+ return 1;
+}
+
+/**
+ * Callback for counting items in inventory.
+ * tmw.chr_inv_count(character, int id...): int count...
+ */
+static int LuaChr_InvCount(lua_State *s)
+{
+ Character *q = getCharacter(s, 1);
+ if (!q)
+ {
+ LOG_WARN("LuaChr_InvCount called with incorrect parameters.");
+ return 0;
+ }
+ int nb_items = lua_gettop(s) - 1;
+ lua_checkstack(s, nb_items);
+ Inventory inv(q);
+ for (int i = 2; i <= nb_items + 1; ++i)
+ {
+ if (!lua_isnumber(s, i))
+ {
+ LOG_WARN("LuaChr_InvCount called with incorrect parameters.");
+ return 0;
+ }
+ int nb = inv.count(lua_tointeger(s, i));
+ lua_pushinteger(s, nb);
+ }
+ return nb_items;
+}
+
LuaScript::LuaScript(lua_State *s):
mState(s),
nbArgs(-1)
@@ -224,6 +317,8 @@ LuaScript::LuaScript(lua_State *s):
{ "msg_npc_choice", &LuaMsg_NpcChoice },
{ "obj_create_npc", &LuaObj_CreateNpc },
{ "chr_warp", &LuaChr_Warp },
+ { "chr_inv_change", &LuaChr_InvChange },
+ { "chr_inv_count", &LuaChr_InvCount },
{ NULL, NULL }
};
luaL_register(mState, "tmw", callbacks);