From 72881e2a713a29fc7eaaa1d7159129e0e4f9867f Mon Sep 17 00:00:00 2001 From: Thorbjørn Lindeijer Date: Sat, 3 Mar 2012 20:44:01 +0100 Subject: Improved handling of item and monster class parameters Item and monster classes could already be identified by either their id or their name. Now the explicit values returned by 'get_item_class' and 'get_monster_class' can also be used as parameter. In addition the above two getters learned to understand all three types of parameter as well, rather than only supporting a name. Reviewed-by: Erik Schilling --- src/scripting/lua.cpp | 181 ++++++++-------------------------------------- src/scripting/luautil.cpp | 76 +++++++++++++++++-- src/scripting/luautil.h | 14 +++- 3 files changed, 108 insertions(+), 163 deletions(-) (limited to 'src/scripting') diff --git a/src/scripting/lua.cpp b/src/scripting/lua.cpp index c6a75d90..59e7d2e1 100644 --- a/src/scripting/lua.cpp +++ b/src/scripting/lua.cpp @@ -214,15 +214,13 @@ static int on_get_special_recharge_cost(lua_State *s) static int get_item_class(lua_State *s) { - const char *name = luaL_checkstring(s, 1); - LuaItemClass::push(s, itemManager->getItemByName(name)); + LuaItemClass::push(s, checkItemClass(s, 1)); return 1; } static int get_monster_class(lua_State *s) { - const char *name = luaL_checkstring(s, 1); - LuaMonsterClass::push(s, monsterManager->getMonsterByName(name)); + LuaMonsterClass::push(s, checkMonsterClass(s, 1)); return 1; } @@ -683,30 +681,8 @@ static int chr_inv_change(lua_State *s) } int nb = lua_tointeger(s, i * 2 + 3); - ItemClass *ic; - int id; - if (lua_isnumber(s, i * 2 + 2)) - { - int id = lua_tointeger(s, i * 2 + 2); - if (id == 0) - { - LOG_WARN("chr_inv_change called with id 0! " - "Currency is now handled through attributes!"); - continue; - } - ic = itemManager->getItem(id); - } - else - { - ic = itemManager->getItemByName(lua_tostring(s, i * 2 + 2)); - } - - if (!ic) - { - raiseScriptError(s, "chr_inv_change called with an unknown item."); - continue; - } - id = ic->getDatabaseID(); + ItemClass *ic = checkItemClass(s, i * 2 + 2); + int id = ic->getDatabaseID(); if (nb < 0) { // Removing too much item is a success as for the scripter's @@ -755,33 +731,12 @@ static int chr_inv_count(lua_State *s) int nb_items = lua_gettop(s) - 3; Inventory inv(q); - int id, nb = 0; + int nb = 0; for (int i = 4; i < nb_items + 4; ++i) { - ItemClass *it; - if (lua_isnumber(s, i)) - it = itemManager->getItem(lua_tointeger(s, i)); - else - it = itemManager->getItemByName(lua_tostring(s, i)); - - if (!it) - { - raiseScriptError(s, "chr_inv_count called with invalid " - "item id or name."); - return 0; - } - id = it->getDatabaseID(); - if (id == 0) - { - LOG_WARN("chr_inv_count called with id 0! " - "Currency is now handled through attributes!"); - lua_pushinteger(s, 0); - } - else - { - nb = inv.count(id, inInventory, inEquipment); - lua_pushinteger(s, nb); - } + ItemClass *it = checkItemClass(s, i); + nb = inv.count(it->getDatabaseID(), inInventory, inEquipment); + lua_pushinteger(s, nb); } return nb_items; } @@ -814,28 +769,6 @@ static int chr_equip_slot(lua_State *s) */ static int chr_equip_item(lua_State *s) { - // Get the itemId - ItemClass *it; - if (lua_isnumber(s, 2)) - it = itemManager->getItem(lua_tointeger(s, 2)); - else - it = itemManager->getItemByName(lua_tostring(s, 2)); - - if (!it) - { - raiseScriptError(s, "chr_equip_item called with invalid " - "item id or name."); - return 0; - } - unsigned int id = it->getDatabaseID(); - if (!id) - { - LOG_WARN("chr_equip_item called with id 0! " - "Currency is now handled through attributes!"); - lua_pushboolean(s, false); - return 1; - } - Character *ch = getCharacter(s, 1); if (!ch) { @@ -843,9 +776,12 @@ static int chr_equip_item(lua_State *s) "called for nonexistent character."); return 0; } + + ItemClass *it = checkItemClass(s, 2); + Inventory inv(ch); - int inventorySlot = inv.getFirstSlot(id); + int inventorySlot = inv.getFirstSlot(it->getDatabaseID()); bool success = false; if (inventorySlot > -1) @@ -884,28 +820,6 @@ static int chr_unequip_slot(lua_State *s) */ static int chr_unequip_item(lua_State *s) { - // Get the itemId - ItemClass *it; - if (lua_isnumber(s, 2)) - it = itemManager->getItem(lua_tointeger(s, 2)); - else - it = itemManager->getItemByName(lua_tostring(s, 2)); - - if (!it) - { - raiseScriptError(s, "chr_unequip_item called with invalid " - "item id or name."); - return 0; - } - unsigned int id = it->getDatabaseID(); - if (!id) - { - LOG_WARN("chr_unequip_item called with id 0! " - "Currency is now handled through attributes!"); - lua_pushboolean(s, false); - return 1; - } - Character *ch = getCharacter(s, 1); if (!ch) { @@ -913,8 +827,11 @@ static int chr_unequip_item(lua_State *s) "called for nonexistent character."); return 0; } + + ItemClass *it = checkItemClass(s, 2); + Inventory inv(ch); - lua_pushboolean(s, inv.unequipItem(id)); + lua_pushboolean(s, inv.unequipItem(it->getDatabaseID())); return 1; } @@ -973,13 +890,13 @@ static int npc_trade(lua_State *s) if (t->start(p)) { - lua_pushinteger(s, 0); - return 1; + lua_pushinteger(s, 0); + return 1; } else { - lua_pushinteger(s, 1); - return 1; + lua_pushinteger(s, 1); + return 1; } } else @@ -1012,11 +929,7 @@ static int npc_trade(lua_State *s) lua_rawgeti(s, -1, i + 1); if (i == 0) // item id or name { - ItemClass *it; - if (lua_isnumber(s, -1)) - it = itemManager->getItem(lua_tointeger(s, -1)); - else - it = itemManager->getItemByName(lua_tostring(s, -1)); + ItemClass *it = getItemClass(s, -1); if (!it) { @@ -1055,13 +968,13 @@ static int npc_trade(lua_State *s) } if (t->start(p)) { - lua_pushinteger(s, 0); - return 1; + lua_pushinteger(s, 0); + return 1; } else { - lua_pushinteger(s, 1); - return 1; + lua_pushinteger(s, 1); + return 1; } } @@ -1553,6 +1466,7 @@ static int monster_class_on(lua_State *s) */ static int monster_create(lua_State *s) { + MonsterClass *monsterClass = checkMonsterClass(s, 1); const int x = luaL_checkint(s, 2); const int y = luaL_checkint(s, 3); @@ -1563,34 +1477,7 @@ static int monster_create(lua_State *s) return 0; } - MonsterClass *spec; - if (lua_isnumber(s, 1)) - { - int monsterId = luaL_checkint(s, 1); - spec = monsterManager->getMonster(monsterId); - if (!spec) - { - raiseScriptError(s, "monster_create called with invalid " - "monster ID: %d", monsterId); - //LOG_WARN("LuaMonster_Create invalid monster ID: " << monsterId); - return 0; - } - } - else - { - std::string monsterName = lua_tostring(s, 1); - spec = monsterManager->getMonsterByName(monsterName); - if (!spec) - { - raiseScriptError(s, "monster_create called with " - "invalid monster name: %s", monsterName.c_str()); - //LOG_WARN("LuaMonster_Create invalid monster name: " - // << monsterName); - return 0; - } - } - - Monster *q = new Monster(spec); + Monster *q = new Monster(monsterClass); q->setMap(m); q->setPosition(Point(x, y)); GameState::enqueueInsert(q); @@ -2484,22 +2371,12 @@ static int item_drop(lua_State *s) { const int x = luaL_checkint(s, 1); const int y = luaL_checkint(s, 2); + ItemClass *ic = checkItemClass(s, 3); const int number = luaL_optint(s, 4, 1); - ItemClass *ic; - if (lua_isnumber(s, 3)) - ic = itemManager->getItem(lua_tointeger(s, 3)); - else - ic = itemManager->getItemByName(lua_tostring(s, 3)); - - if (!ic) - { - raiseScriptError(s, "item_drop called with unknown item id or name."); - return 0; - } Item *i = new Item(ic, number); - MapComposite* map = getScript(s)->getMap(); + MapComposite *map = getScript(s)->getMap(); i->setMap(map); Point pos(x, y); diff --git a/src/scripting/luautil.cpp b/src/scripting/luautil.cpp index 7580ac21..e4260a5c 100644 --- a/src/scripting/luautil.cpp +++ b/src/scripting/luautil.cpp @@ -22,8 +22,10 @@ #include "luautil.h" #include "game-server/character.h" -#include "game-server/npc.h" +#include "game-server/itemmanager.h" #include "game-server/monster.h" +#include "game-server/monstermanager.h" +#include "game-server/npc.h" #include "utils/logger.h" @@ -118,14 +120,12 @@ void UserDataCache::insert(lua_State *s, void *object) valid in the map. TODO: do it. */ -NPC *getNPC(lua_State *s, int p) +Being *getBeing(lua_State *s, int p) { if (!lua_islightuserdata(s, p)) return 0; Thing *t = static_cast(lua_touserdata(s, p)); - if (t->getType() != OBJECT_NPC) - return 0; - return static_cast(t); + return static_cast(t); } Character *getCharacter(lua_State *s, int p) @@ -138,6 +138,26 @@ Character *getCharacter(lua_State *s, int p) return static_cast(t); } +ItemClass *getItemClass(lua_State *s, int p) +{ + ItemClass *itemClass = 0; + + switch (lua_type(s, p)) + { + case LUA_TNUMBER: + itemClass = itemManager->getItem(lua_tointeger(s, p)); + break; + case LUA_TSTRING: + itemClass = itemManager->getItemByName(lua_tostring(s, p)); + break; + case LUA_TUSERDATA: + itemClass = LuaItemClass::check(s, p); + break; + } + + return itemClass; +} + Monster *getMonster(lua_State *s, int p) { if (!lua_islightuserdata(s, p)) @@ -148,14 +168,56 @@ Monster *getMonster(lua_State *s, int p) return static_cast(t); } -Being *getBeing(lua_State *s, int p) +MonsterClass *getMonsterClass(lua_State *s, int p) +{ + MonsterClass *monsterClass = 0; + + switch (lua_type(s, p)) + { + case LUA_TNUMBER: + monsterClass = monsterManager->getMonster(lua_tointeger(s, p)); + break; + case LUA_TSTRING: + monsterClass = monsterManager->getMonsterByName(lua_tostring(s, p)); + break; + case LUA_TUSERDATA: + monsterClass = LuaMonsterClass::check(s, p); + break; + } + + return monsterClass; +} + +NPC *getNPC(lua_State *s, int p) { if (!lua_islightuserdata(s, p)) return 0; Thing *t = static_cast(lua_touserdata(s, p)); - return static_cast(t); + if (t->getType() != OBJECT_NPC) + return 0; + return static_cast(t); } + +ItemClass *checkItemClass(lua_State *s, int p) +{ + ItemClass *itemClass = getItemClass(s, p); + if (!itemClass) + luaL_argerror(s, p, "invalid item type parameter"); + + return itemClass; +} + +MonsterClass *checkMonsterClass(lua_State *s, int p) +{ + MonsterClass *monsterClass = getMonsterClass(s, p); + if (!monsterClass) + luaL_argerror(s, p, "invalid monster type parameter"); + + return monsterClass; +} + + void push(lua_State *s, int val) { lua_pushinteger(s, val); diff --git a/src/scripting/luautil.h b/src/scripting/luautil.h index 2fc7543a..3286bded 100644 --- a/src/scripting/luautil.h +++ b/src/scripting/luautil.h @@ -150,10 +150,16 @@ typedef LuaUserData LuaMonsterClass; typedef LuaUserData LuaStatusEffect; -NPC *getNPC(lua_State *s, int p); -Character *getCharacter(lua_State *s, int p); -Monster *getMonster(lua_State *s, int p); -Being *getBeing(lua_State *s, int p); +Being * getBeing(lua_State *s, int p); +Character * getCharacter(lua_State *s, int p); +ItemClass * getItemClass(lua_State *s, int p); +Monster * getMonster(lua_State *s, int p); +MonsterClass * getMonsterClass(lua_State *s, int p); +NPC * getNPC(lua_State *s, int p); + +ItemClass * checkItemClass(lua_State *s, int p); +MonsterClass * checkMonsterClass(lua_State *s, int p); + /* Polymorphic wrapper for pushing variables. Useful for templates.*/ -- cgit v1.2.3-60-g2f50