Page 1 of 5

Infinite, Stackable Inventory/Crafting/Vendor - UPDATED v1.5

Posted: Thu Mar 06, 2014 9:06 am
by saguaro
Updated 5/21, version 1.5 now compatible with Ren'Py 6.99.10:
Changes to screen language caused issues with the previous version of this framework. Thanks to all the updates made to Ren'Py over the past year I have been able to correct those errors and refactor the code. If you were using a previous version the only change you need to make is updating any inventory/vendor screen show statements (there is only one inventory screen now). Object classes are the same.

DEETS

I tried to make this inventory as readable and easy to use as possible. It has more features than most games will need, but you can easily ignore the features you don't want. Please note this code is provided as-is without any guarantee it will be maintained through future versions of Ren'Py.

Includes:
- Image or text items
- Quantities stack
- Create unlimited items and inventories
- Infinite scrolling grid or list layout
- Sorting by item name, quantity, value
- Vendor screen for buying/selling
- Functions for adding, removing, changing items, checking quantity, item use, item crafting, trade, and banking

crafting_screenshot.png
banking_screen.png
Inventory.rpy contains the classes and screens or you can download the demo files. Drop the demo files into a new project. Usage instructions provided in the demo are:

Code: Select all

## inventory 1.5 demo
      
label start:  
    ## If using the crafting feature, add an empty cookbook list after start to keep track of recipes
    $ cookbook = list() 
   
    ######### DEFINE INVENTORIES ##########    
    $ jane_inv = Inventory("Jane")
    
    ######### DEFINE ITEM OBJECTS ##########
    ### The format is name, description, icon image (if applicable), value (if applicable, selling/buying value), action (screen language action to be performed when icon is clicked on inventory screen), and recipe (if craftable).
    
    ### Items without icons are created like this:      
    #$ quarter = Item("Quarter", "A new quarter)
    
    ### Items with icons are created like this:
    $ eye = Item(name="Eyeball", desc="A human eyeball, how creepy!", icon="images/eye.png", value=250)

    # Items that can be used in crafting
    $ but = Item("Button", "A shiny button", "images/button.png", 100, act=Show("inventory_popup", message="This item is only used in crafting"))
    
    $ yarn = Item("Yarn", "Yarny yarny yarn.", "images/yarn.png", 30, act=Show("inventory_popup", message="This item is only used in crafting"))  
    
    $ fabric = Item("Fabric", "You know, cloth.", "images/fabric.png", 100, act=Show("inventory_popup", message="This item is only used in crafting"))
    
    $ coin = Item("Coin", "An old coin", "images/coin.png", 1, act=Show("inventory_popup", message="This item is only used in crafting"))
    
    # An item with a unique action (shows screen with custom message)
    $ sword = Item("Awesome Sword", "An awesome sword.", "images/sword.png", 500, Show("inventory_popup", message="You wave the sword around wildly but nothing happens."))

    # An item that can be crafted has a recipe, which is a nested list of [ingredient, qty]
    $ necklace = Item("Penny Necklace", "Super magic.", "images/necklace.png", 50, recipe=[[coin,6],[yarn,1]])    
    $ doll = Item("Handmade Doll", "Guaranteed to bring luck. (Or not?) Very huggable, mind the needle.", "images/doll.png", 100000, recipe=[[but,2],[fabric,3],[yarn,1]])    
    
label demo:    
    # Display an inventory by using the inventory object name as the parameter  
    "For this demo the inventory_screen modal has been set to False (line 150 of inventory.rpy)."
    show screen inventory_screen(jane_inv)         
    
    "Let's add some items to Jane's inventory. The format is item, quantity."
    $ jane_inv.take(coin,4)
    $ jane_inv.take(sword)
    $ jane_inv.take(eye)
    $ jane_inv.take(but,2)
    $ jane_inv.take(fabric,3)
    $ jane_inv.take(yarn,2)        
      
    "You can hover over the items to see a description. If you click on the sword you will perform the action associated with that item (show a screen with a message).  You can sort inventory several ways and can switch between a grid and list view. If you're using text items you'll only want to enable the list view."  
    
    "Now, let's remove a coin."
    $ jane_inv.drop(coin)   
    
    "We can also check to see if Jane has a certain item.  The check function returns the quantity, if any."    
    if jane_inv.qty(coin): 
        $ qty = jane_inv.qty(coin)
        "Jane still has [qty] coins. Good job, Jane."
    else:
        "Jane doesn't have any coins. You must have changed this script!"   

    if jane_inv.qty(but):
        $ qty = jane_inv.qty(but)
        "Jane has [qty] buttons."
    else:
        "Jane doesn't have any buttons."
        
    "You can also change an item and modify the name, description, and icon if you need to."
    $ sword.change("Broken sword", "This sword is old and busted.", "images/broke_sword.png", 50, act=Show("inventory_popup", message="It's broken, be careful!"))
    
    "Now the sword is broken and you can't even wave it around anymore.  Let's sell it and buy something else."
    
    "We'll create a vendor named Mindy and give her money and inventory.  Mindy really likes eyes and buttons. Her barter percentage is 75, so she will only buy items from Jane at 75 percent of their value."
    $ mindy_inv = Inventory("Mindy", 500, 75)
    $ mindy_inv.take(eye,4)
    $ mindy_inv.take(but,3)
    $ mindy_inv.take(coin,2)    
    
    # vendor screen parameters are left-side inventory, right-side inventory
    show screen inventory_screen(jane_inv, mindy_inv)
    
    "Now we'll give Jane some walking-around money."
    $ jane_inv.money = 500    
    
    "The inventory screen can take two inventory parameters and display the inventories side-by-side. You can click an item to buy/sell between the two.  Neither character can buy items if they don't have enough money.  Trade mode allows you to exchange items without money and bank mode allows withdrawing and depositing money."    
    
    $ chest = Inventory("Storage Chest")

    "Using trade and bank modes together, you can create a storage chest."
    show screen inventory_screen(jane_inv, chest, trade_mode=True, bank_mode=True)    
    
    "That's it! Exit to end the demo when you are finished."    

Re: Infinite, Stackable Inventory and Vendor Screens

Posted: Thu Mar 06, 2014 9:57 am
by xela
Excellent job! Some really good ideas for structure and display as well...

Re: Infinite, Stackable Inventory, Crafting, and Vendor Scre

Posted: Fri Mar 14, 2014 8:51 am
by saguaro
Thanks, I appreciate that!

Updated to add a basic crafting feature. I tried to keep the styling to a minimum, but there is a custom style at the end of inventory.rpy so I could tidy things up a little bit. The gist of the demo is now in the first post for those curious about how functions are set up.

Re: Infinite, Stackable Inventory, Crafting, and Vendor Scre

Posted: Fri Mar 14, 2014 12:01 pm
by Sidji972
Awesome guy! I tested it and your craft system is really good!

PS : there is a small issue with scroll i think, impossible to sell craft item :)

Re: Infinite, Stackable Inventory, Crafting, and Vendor Scre

Posted: Fri Mar 14, 2014 1:16 pm
by saguaro
Thanks for testing this! I try to test my code but it's always better for a different person to test it out. I set the value for the doll to 100000 so the vendor must have that much money to purchase it. But if the scroll problem persists let me know the screen and circumstance and I'll fix it.

Re: Infinite, Stackable Inventory, Crafting, and Vendor Scre

Posted: Sun Apr 13, 2014 5:03 pm
by Skaiya
Thank you, so so so so SO much.
This is exactly what I was been looking for since November last year ;-;

Re: Infinite, Stackable Inventory, Crafting, and Vendor Scre

Posted: Thu Apr 24, 2014 12:02 pm
by Eligar
This couldn't have been more perfect, thank you so much!

Re: Infinite, Stackable Inventory, Crafting, and Vendor Scre

Posted: Sun May 04, 2014 9:24 am
by Alitza
Is there an easy way add to this nice inventory chance wearing inventory items such as another inventory but with items without prices?

thanks in advance

Re: Infinite, Stackable Inventory, Crafting, and Vendor Scre

Posted: Sun May 04, 2014 5:45 pm
by saguaro
It sounds like you are asking for a 'trade' function that allows items to be swapped between inventory screens without money being exchanged.

That's a good idea for a feature, so I have updated the inventory.rpy script with a "trade" function, which you can now download from the first post. You can summon the trade screen by adding a third "True" argument:

Code: Select all

    show screen vendor(jane_inv, mindy_inv, True)
This will allow you to trade between inventories, so if you had a character's "closet" or "treasure chest" inventory, for example, they could take an leave items at will. In the example posted, mindy_inv would be the "closet" inventory.

I hope that helps.

Re: Infinite, Stackable Inventory, Crafting, and Vendor Scre

Posted: Mon May 05, 2014 6:01 am
by Alitza
that's what I wanted

Thanks

Re: Infinite, Stackable Inventory, Crafting, and Vendor Scre

Posted: Sat May 10, 2014 9:13 pm
by Stapper
I've taken this awesome script as a base for my game and have to say that you've made it insanely user-friendly to use and modify. Thank you very much for sharing this!

I have however one thing that I cannot figure out. I would like to remove the ascending and descending options, because I won't have enough items to make them useful. However when I hide them and use the defaults, the sort by quantity and value are showing correctly with the highest amount first but the sort by name is inverted and starts with the yarn instead of the awesome sword.

How can I remedy this little problem?

Re: Infinite, Stackable Inventory, Crafting, and Vendor Scre

Posted: Sun May 11, 2014 8:43 am
by saguaro
Thank you, I'm glad you've found it useful!

Sorting ascending/descending is controlled by the Inventory instance variable x.sort_order, which has a default of false (descending).

Since you want names to be ascending and numbers to be descending, you'll want to update the sort_name function of the Inventory class (line 43 of inventory.rpy) so it always sorts as ascending. Simply remove the reverse parameter.

Code: Select all

        def sort_name(self):
            self.inv.sort(key=lambda i: i[0].name)
            renpy.restart_interaction()

Re: Infinite, Stackable Inventory, Crafting, and Vendor Scre

Posted: Mon May 12, 2014 12:25 am
by Stapper
Works like a charm! Thanks a lot :)

Re: Infinite, Stackable Inventory, Crafting, and Vendor Scre

Posted: Mon May 19, 2014 10:50 pm
by storymasterq
Hi! This is an amazing system. So good that I've slightly changed my game just so I can use it :D

A question, is there an easy way to make selling to a vendor gains only half of an item's declared value? A second question, is there a way to transfer only the money to a vendor (or, a chest, actually)?

Re: Infinite, Stackable Inventory, Crafting, and Vendor Scre

Posted: Wed May 21, 2014 7:07 pm
by noeinan
This looks really cool! Thanks for making it-- I am trying to make a game centering around smithing so it will be very useful to me. :) I noticed that if you hide the recipe screen there doesn't seem to be a way to show it again, but I think that should be an easy fix on my part. Thanks again!