Add InventoryList width property & allow custom crafting grids.
authorIlya Zhuravlev <zhuravlevilya@ya.ru>
Sun, 19 Aug 2012 21:29:56 +0000 (01:29 +0400)
committerPerttu Ahola <celeron55@gmail.com>
Sat, 1 Sep 2012 07:01:41 +0000 (10:01 +0300)
doc/lua_api.txt
src/inventory.cpp
src/inventory.h
src/inventorymanager.cpp
src/player.cpp
src/scriptapi.cpp
src/test.cpp

index 8a6ea5dea714ab729e22e7c3f24b50ece87ce3af..88c594eb2c8528f1021c6dc4202854252c06a200 100644 (file)
@@ -1118,6 +1118,8 @@ methods:
 - is_empty(listname): return true if list is empty
 - get_size(listname): get size of a list
 - set_size(listname, size): set size of a list
+- get_width(listname): get width of a list
+- set_width(listname, width): set width of list; currently used for crafting
 - get_stack(listname, i): get a copy of stack index i in list
 - set_stack(listname, i, stack): copy stack to index i in list
 - get_list(listname): return full list
index 0a0a29cd550f782d6276d208212bf011d0bb36df..fda11e40fde5e5904bc5cb42ae4d1b0f104af1c2 100644 (file)
@@ -431,6 +431,7 @@ InventoryList::InventoryList(std::string name, u32 size, IItemDefManager *itemde
 {
        m_name = name;
        m_size = size;
+       m_width = 0;
        m_itemdef = itemdef;
        clearItems();
        //m_dirty = false;
@@ -459,6 +460,11 @@ void InventoryList::setSize(u32 newsize)
        m_size = newsize;
 }
 
+void InventoryList::setWidth(u32 newwidth)
+{
+       m_width = newwidth;
+}
+
 void InventoryList::setName(const std::string &name)
 {
        m_name = name;
@@ -468,6 +474,8 @@ void InventoryList::serialize(std::ostream &os) const
 {
        //os.imbue(std::locale("C"));
        
+       os<<"Width "<<m_width<<"\n";
+
        for(u32 i=0; i<m_items.size(); i++)
        {
                const ItemStack &item = m_items[i];
@@ -492,6 +500,7 @@ void InventoryList::deSerialize(std::istream &is)
 
        clearItems();
        u32 item_i = 0;
+       m_width = 0;
 
        for(;;)
        {
@@ -513,6 +522,12 @@ void InventoryList::deSerialize(std::istream &is)
                {
                        break;
                }
+               else if(name == "Width")
+               {
+                       iss >> m_width;
+                       if (iss.fail())
+                               throw SerializationError("incorrect width property");
+               }
                else if(name == "Item")
                {
                        if(item_i > getSize() - 1)
@@ -543,6 +558,7 @@ InventoryList & InventoryList::operator = (const InventoryList &other)
 {
        m_items = other.m_items;
        m_size = other.m_size;
+       m_width = other.m_width;
        m_name = other.m_name;
        m_itemdef = other.m_itemdef;
        //setDirty(true);
@@ -560,6 +576,11 @@ u32 InventoryList::getSize() const
        return m_items.size();
 }
 
+u32 InventoryList::getWidth() const
+{
+       return m_width;
+}
+
 u32 InventoryList::getUsedSlots() const
 {
        u32 num = 0;
index a3c5982562492fe7cccfff1b0fbbbd18e0cfff69..5f90183d2302ac6d3e0fe3f8e28065b930e94468 100644 (file)
@@ -176,6 +176,7 @@ public:
        ~InventoryList();
        void clearItems();
        void setSize(u32 newsize);
+       void setWidth(u32 newWidth);
        void setName(const std::string &name);
        void serialize(std::ostream &os) const;
        void deSerialize(std::istream &is);
@@ -185,6 +186,7 @@ public:
 
        const std::string &getName() const;
        u32 getSize() const;
+       u32 getWidth() const;
        // Count used slots
        u32 getUsedSlots() const;
        u32 getFreeSlots() const;
@@ -240,7 +242,7 @@ public:
 
 private:
        std::vector<ItemStack> m_items;
-       u32 m_size;
+       u32 m_size, m_width;
        std::string m_name;
        IItemDefManager *m_itemdef;
 };
index ec4d47def36bdd94abc8a34f8d513e55b596e883..e2e5378383f8d4a0956256d9aa061ec6db086dd1 100644 (file)
@@ -769,18 +769,16 @@ bool getCraftingResult(Inventory *inv, ItemStack& result,
        
        result.clear();
 
-       // TODO: Allow different sizes of crafting grids
-
        // Get the InventoryList in which we will operate
        InventoryList *clist = inv->getList("craft");
-       if(!clist || clist->getSize() != 9)
+       if(!clist)
                return false;
 
        // Mangle crafting grid to an another format
        CraftInput ci;
        ci.method = CRAFT_METHOD_NORMAL;
-       ci.width = 3;
-       for(u16 i=0; i<9; i++)
+       ci.width = clist->getWidth() ? clist->getWidth() : 3;
+       for(u16 i=0; i<clist->getSize(); i++)
                ci.items.push_back(clist->getItem(i));
 
        // Find out what is crafted and add it to result item slot
@@ -793,7 +791,7 @@ bool getCraftingResult(Inventory *inv, ItemStack& result,
        if(found && decrementInput)
        {
                // CraftInput has been changed, apply changes in clist
-               for(u16 i=0; i<9; i++)
+               for(u16 i=0; i<clist->getSize(); i++)
                {
                        clist->changeItem(i, ci.items[i]);
                }
index 2e084b415a4b51c8607616bad815a21d5ba35b8f..36f12c77b5053728d2e3cec221184603958ac108 100644 (file)
@@ -45,7 +45,8 @@ Player::Player(IGameDef *gamedef):
        updateName("<not set>");
        inventory.clear();
        inventory.addList("main", PLAYER_INVENTORY_SIZE);
-       inventory.addList("craft", 9);
+       InventoryList *craft = inventory.addList("craft", 9);
+       craft->setWidth(3);
        inventory.addList("craftpreview", 1);
        inventory.addList("craftresult", 1);
 
index 95e2b5d01ad28a9be6b0baa0287376b486da88d3..81e96aec64c2a3879fccc237af357e11b7e14edf 100644 (file)
@@ -1847,6 +1847,20 @@ private:
                return 1;
        }
 
+       // get_width(self, listname)
+       static int l_get_width(lua_State *L)
+       {
+               InvRef *ref = checkobject(L, 1);
+               const char *listname = luaL_checkstring(L, 2);
+               InventoryList *list = getlist(L, ref, listname);
+               if(list){
+                       lua_pushinteger(L, list->getWidth());
+               } else {
+                       lua_pushinteger(L, 0);
+               }
+               return 1;
+       }
+
        // set_size(self, listname, size)
        static int l_set_size(lua_State *L)
        {
@@ -1869,6 +1883,23 @@ private:
                return 0;
        }
 
+       // set_width(self, listname, size)
+       static int l_set_width(lua_State *L)
+       {
+               InvRef *ref = checkobject(L, 1);
+               const char *listname = luaL_checkstring(L, 2);
+               int newwidth = luaL_checknumber(L, 3);
+               Inventory *inv = getinv(L, ref);
+               InventoryList *list = inv->getList(listname);
+               if(list){
+                       list->setWidth(newwidth);
+               } else {
+                       return 0;
+               }
+               reportInventoryChange(L, ref);
+               return 0;
+       }
+
        // get_stack(self, listname, i) -> itemstack
        static int l_get_stack(lua_State *L)
        {
@@ -2062,6 +2093,8 @@ const luaL_reg InvRef::methods[] = {
        method(InvRef, is_empty),
        method(InvRef, get_size),
        method(InvRef, set_size),
+       method(InvRef, get_width),
+       method(InvRef, set_width),
        method(InvRef, get_stack),
        method(InvRef, set_stack),
        method(InvRef, get_list),
index fe5a4f232d0819fd857afc0eb01173b881688f69..f81f2910c62c14117e6c255c7152cfd334df832c 100644 (file)
@@ -698,6 +698,7 @@ struct TestInventory: public TestBase
        {
                std::string serialized_inventory =
                "List 0 32\n"
+               "Width 3\n"
                "Empty\n"
                "Empty\n"
                "Empty\n"
@@ -735,6 +736,7 @@ struct TestInventory: public TestBase
                
                std::string serialized_inventory_2 =
                "List main 32\n"
+               "Width 5\n"
                "Empty\n"
                "Empty\n"
                "Empty\n"
@@ -778,6 +780,8 @@ struct TestInventory: public TestBase
                inv.getList("0")->setName("main");
                UASSERT(!inv.getList("0"));
                UASSERT(inv.getList("main"));
+               UASSERT(inv.getList("main")->getWidth() == 3);
+               inv.getList("main")->setWidth(5);
                std::ostringstream inv_os(std::ios::binary);
                inv.serialize(inv_os);
                UASSERT(inv_os.str() == serialized_inventory_2);