diff options
-rw-r--r-- | example/serverdata/scripts/maps/desert.lua | 13 | ||||
-rw-r--r-- | src/game-server/inventory.cpp | 42 | ||||
-rw-r--r-- | src/game-server/inventory.h | 5 | ||||
-rw-r--r-- | src/scripting/lua.cpp | 17 |
4 files changed, 59 insertions, 18 deletions
diff --git a/example/serverdata/scripts/maps/desert.lua b/example/serverdata/scripts/maps/desert.lua index 8b7da1f..baeeb54 100644 --- a/example/serverdata/scripts/maps/desert.lua +++ b/example/serverdata/scripts/maps/desert.lua @@ -34,7 +34,7 @@ atinit(function() -- 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(Merchant, smith_buy_table), nil) + 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) @@ -43,6 +43,14 @@ atinit(function() 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 + -- Global variable used to know whether Harmony talked to someone. harmony_have_talked_to_someone = false function Harmony(npc, ch, list) @@ -85,7 +93,8 @@ function Harmony_update(npc) end function Tamer(npc, ch, list) - mana.being_say(npc, string.format("You have %s Swords.", mana.chr_inv_count(ch, "Sword"))) + 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.") diff --git a/src/game-server/inventory.cpp b/src/game-server/inventory.cpp index 4d447d3..1b5e67e 100644 --- a/src/game-server/inventory.cpp +++ b/src/game-server/inventory.cpp @@ -217,14 +217,34 @@ unsigned int Inventory::insert(unsigned int itemId, unsigned int amount) return amount; } -unsigned int Inventory::count(unsigned int itemId) const +unsigned int Inventory::count(unsigned int itemId, + bool inInventory, bool inEquipment) const { unsigned int nb = 0; - for (InventoryData::iterator it = mPoss->inventory.begin(), - it_end = mPoss->inventory.end(); - it != it_end; ++it) - if (it->second.itemId == itemId) - nb += it->second.amount; + if (inInventory) + { + for (InventoryData::iterator it = mPoss->inventory.begin(), + it_end = mPoss->inventory.end(); it != it_end; ++it) + if (it->second.itemId == itemId) + nb += it->second.amount; + } + + if (inEquipment) + { + std::set<unsigned> itemInstances; + for (EquipData::iterator it = mPoss->equipSlots.begin(), + it_end = mPoss->equipSlots.end(); it != it_end; ++it) + { + if (it->second.itemId != itemId || !it->second.itemInstance) + continue; + + // If the insertion was successful, then it was the first time, + // and can be counted. + if ((itemInstances.insert(it->second.itemInstance)).second) + ++nb; + } + } + return nb; } @@ -248,9 +268,10 @@ unsigned int Inventory::remove(unsigned int itemId, unsigned int amount) MessageOut invMsg(GPMSG_INVENTORY); bool triggerLeaveInventory = true; - for (InventoryData::iterator it = mPoss->inventory.begin(), - it_end = mPoss->inventory.end(); it != it_end; ++it) + for (InventoryData::iterator it = mPoss->inventory.begin(); + it != mPoss->inventory.end();) { + LOG_DEBUG("Remove: Treating slot id: " << it->first); if (it->second.itemId == itemId) { if (amount) @@ -273,8 +294,10 @@ unsigned int Inventory::remove(unsigned int itemId, unsigned int amount) else { invMsg.writeInt16(0); - mPoss->inventory.erase(it); + // Ensure the slot is set empty. LOG_DEBUG("Slot id: " << it->first << " is now empty."); + mPoss->inventory.erase(it++); + continue; } } else @@ -284,6 +307,7 @@ unsigned int Inventory::remove(unsigned int itemId, unsigned int amount) triggerLeaveInventory = false; } } + ++it; } if (triggerLeaveInventory) diff --git a/src/game-server/inventory.h b/src/game-server/inventory.h index 812c142..4593add 100644 --- a/src/game-server/inventory.h +++ b/src/game-server/inventory.h @@ -112,8 +112,11 @@ class Inventory /** * Counts number of items with given Id. + * @param inInventory Search in player's inventory. + * @param inEquipment Search in player's equipment. */ - unsigned int count(unsigned int itemId) const; + unsigned int count(unsigned int itemId, bool inInventory = true, + bool inEquipment = true) const; /** * Gets the ID of the items in a given slot. diff --git a/src/scripting/lua.cpp b/src/scripting/lua.cpp index f681133..1465873 100644 --- a/src/scripting/lua.cpp +++ b/src/scripting/lua.cpp @@ -435,23 +435,28 @@ static int chr_inv_change(lua_State *s) } /** - * mana.chr_inv_count(Character*, int item_id...): int count... + * mana.chr_inv_count(Character*, bool in inventory, bool in equipment, + * int item_id...): int count... * Callback for counting items in inventory. + * The function can search in inventory and/or in the equipment. */ static int chr_inv_count(lua_State *s) { Character *q = getCharacter(s, 1); - if (!q) + if (!q || !lua_isboolean(s, 2) || !lua_isboolean(s, 3)) { raiseScriptError(s, "chr_inv_count called with incorrect parameters."); return 0; } - int nb_items = lua_gettop(s) - 1; - lua_checkstack(s, nb_items); + + bool inInventory = lua_toboolean(s, 2); + bool inEquipment = lua_toboolean(s, 3); + + int nb_items = lua_gettop(s) - 3; Inventory inv(q); int id, nb = 0; - for (int i = 2; i <= nb_items + 1; ++i) + for (int i = 4; i < nb_items + 4; ++i) { ItemClass *it; if (lua_isnumber(s, i)) @@ -474,7 +479,7 @@ static int chr_inv_count(lua_State *s) } else { - nb = inv.count(id); + nb = inv.count(id, inInventory, inEquipment); lua_pushinteger(s, nb); } } |