Simple Inventory.

Discuss how to use the Ren'Py engine to create visual novels and story-based games. New releases are announced in this section.
Forum rules
This is the right place for Ren'Py help. Please ask one question per thread, use a descriptive subject like 'NotFound error in option.rpy' , and include all the relevant information - especially any relevant code and traceback messages. Use the code tag to format scripts.
Post Reply
Message
Author
Jayn
Newbie
Posts: 16
Joined: Sun May 13, 2012 6:15 am
Contact:

Simple Inventory.

#1 Post by Jayn »

I apologize for the second thread. (I felt it would be easier for others with the same question to find if I made this one separate.)

I'm not sure if what I want to do is possible, or what information to provide. I've spent all night trying to figure something like this out and searching the forums, but I'm terrible with coding language and everything is just kind of complicated to me (even though once I understand it, I feel like an idiot.)

I figured out how to make this code work.

Code: Select all

init python:   
    showitems = True
   
    def display_items_overlay():
        if showitems:
            inventory_show = "Inventory: "
            for i in range(0, len(items)):
                item_name = items[i].title()
                if i > 0:
                    inventory_show += ", "
                inventory_show += item_name
            ui.frame()
            ui.text(inventory_show)
    config.overlay_functions.append(display_items_overlay)

##
$ items.append("stone") #when you want to add items
$ items.remove("stone")#when you want to remove items
$ showitems = False #when you don't want to show the inventory onscreen (cutscenes and the like)
$ showitems = True #when you want to reshow the inventory after the cutscene is over
What I would like to do, though, is use this same basic code (simple to understand and use), except as a screen. As things are, the Inventory stays on screen (unless I hide it.) What I would like to do is make it so that the same styled inventory comes up, but only if the player presses a button to show the inventory.

Otherwise, I'd like the inventory to stay off screen.

I'd also like the option to 'view' inventory to only come up when there's 'something' in the inventory. For example, one of my characters obtains a sweatshirt, and it goes into the simple onscreen inventory in the left hand corner. What I would like instead is for an option to come up to 'view inventory', and they can be taken to a screen that lists all of the items they have.

I am not sure how to go about this, in the least. Screens confuse me. I'm not sure how to write them, or where to place what (or what variables to change, etc.) Any help would be greatly appreciated. Thank you for reading.

(On another note, I am also wondering if with the simple on screen inventory, it's possible to have the items show up going vertically instead of horizontally. This isn't really a big deal, but yeah...Thank you!)


User avatar
Showsni
Miko-Class Veteran
Posts: 563
Joined: Tue Jul 24, 2007 12:58 pm
Contact:

Re: Simple Inventory.

#2 Post by Showsni »

I'm not sure how you've set your items up, but the way I do an inventory I have items as a class, and the inventory as a screen. Then I also have a class for each character, part of which contains a list for their inventory. If you only have one character of course you wouldn't need that and you could have just one list for your inventory, but I digress...

What exactly do you want to be able to do with the inventory? Do you just want it to list what items are on hand, or do you want players to be able to go into the inventory and view detailed descriptions of the items, or be able to use the items in certain cases?

Anyway, my coding is a little like this:

Let's say $ items = [] is an empty list that we're going to hold inventory items in. Then

Code: Select all

screen inventory:
    frame:
        xalign 0.0
        yalign 0.0
        vbox:
            for i in items:
                text i
In this case, each item has to be a string so that it will show up properly as text. This gives you a vertical list of each item, with each one on a new line.

Now, if you have the items as a class, with perhaps a name and some properties you could change it to something like

Code: Select all

for i in items:
    text i.name
fairly easily.

If you want something to actually happen from the inventory use a textbutton instead of text, and then you can add some actions. Let's say I have items as a class with a name and a short description, like so:

Code: Select all

class item:
    def __init__(self, name, description):
        self.name = name
        if description == "":
            self.description = "A random thing."
        else:
            self.description = description
(That bit's in a python block and an init block)

And then I define my items like this:

Code: Select all

$ sweatshirt = item("Sweatshirt", "A red jumper.")
Now I could have my inventory screen like so:

Code: Select all

screen inventory:
    vbox:
        xalign 0.0
        yalign 0.0
        frame:
            vbox:
                for i in items:
                    textbutton i.name hovered SetVariable("data", i.description) unhovered SetVariable ("data", "My inventory.") action SetVariable ("data", "Clicked!")
        null height 20
        frame:
            text data
Remembering to set initial values for all the vairables we've used somewhere

Code: Select all

    $ sweatshirt = item("Sweatshirt", "A red jumper.")
    $ items = []
    $ data = "My inventory."
Now adding something to the inventory with append as usual

Code: Select all

$ items.append(sweatshirt)
will let it show up in the inventory, which can be seen or hidden with
show screen inventory
hide screen inventory
Now we can hover over the items to view a description of them, or click on them for something else to happen.

Now, you wanted to only open the inventory when there's something in it. The best way is to set up another screen. Something like this:

Code: Select all

screen showinv:
    if not items == []:
        frame:
            xalign 0.0
            yalign 0.0
            textbutton "Open Inventory" action (Hide("showinv"), Show("inventory"))
Let's add a bit to our previous inventory code to let us close it...

Code: Select all

screen inventory:
    vbox:
        xalign 0.0
        yalign 0.0
        frame:
            vbox:
                for i in items:
                    textbutton i.name hovered SetVariable("data", i.description) unhovered SetVariable ("data", "My inventory.") action SetVariable("data", "Clicked!")
                textbutton "Close Inventory" action (Hide("inventory"), Show("showinv"))
        null height 20
        frame:
            text data    
Now use
show screen showinv
at the start of your game (or somwehere) instead of show inventory. We'll now have a button to open the inventory that will only show up when there's something actually in the inventory.

EDIT:

As for where to put the coding for the screens, you can put them in the file with the predefined screens, or put them at the top of your regular code, it doesn't really matter.

As for what action you want to happen when you hover over or click on an item, that's up to you. Here are the possible actions: http://www.renpy.org/doc/html/screen_actions.html

Jayn
Newbie
Posts: 16
Joined: Sun May 13, 2012 6:15 am
Contact:

Re: Simple Inventory.

#3 Post by Jayn »

Thank you for your help and the reply!

I tried the second code...I put this code in screens. (Just as a test.)

Code: Select all

#Inventories
init: 
     python:
         class item:
             def __init__(self, name, description):
                 self.name = name
                 if description == "":
                     self.description = "A random thing."
                 else:
                     self.description = description
                     
                     
 
                     
$ data = "My inventory."
$ items = []
$ sweatshirt = items("Sweatshirt", "A red jumper.")


screen inventory:
    vbox:
        xalign 0.0
        yalign 0.0
        frame:
            vbox:
                for i in items:
                    textbutton i.name hovered SetVariable("data", i.description) unhovered SetVariable ("data", "My inventory.") action SetVariable("data", "Clicked!")
                textbutton "Close Inventory" action (Hide("inventory"), Show("showinv"))
        null height 20
        frame:
            text data   
            

#Inventory 2

screen showinv:
    if not items == []:
        frame:
            xalign 0.0
            yalign 0.0
            textbutton "Open Inventory" action (Hide("showinv"), Show("inventory"))
However, I keep getting an error when I launch the game. It goes past the menu, and then it gives me an error when I try to use '$ items.append(sweatshirt)'.

This is the error;

Code: Select all

I'm sorry, but an uncaught exception occurred.

While running game code:
  File "game/script.rpy", line 317, in script
                 $ items.append(sweatshirt)
  File "game/script.rpy", line 317, in python
                 $ items.append(sweatshirt)
NameError: name 'items' is not defined

-- Full Traceback ------------------------------------------------------------

Full traceback:
  File "C:\Users\Kreeshel\renpy-6.13.7\renpy\execution.py", line 261, in run
  File "C:\Users\Kreeshel\renpy-6.13.7\renpy\ast.py", line 630, in execute
  File "C:\Users\Kreeshel\renpy-6.13.7\renpy\python.py", line 978, in py_exec_bytecode
  File "game/script.rpy", line 317, in <module>
NameError: name 'items' is not defined

Windows-post2008Server-6.1.7600
Ren'Py 6.13.7.1646
A Ren'Py Game 0.0



As for what I want the inventory to function like, I just want it to show what items the player has. I don't want it to be toggled by point and click or anything. I'm using menus. In this scenario, the menu is asking what sweatshirt the player wants to take (and eventually give, I suppose.) to someone else.

The player can pick from three colors.

Depending on which one they pick, it will show up in his inventory just as "Red Sweatshirt" text. Nothing too fancy, haha. So I just want it to list what object they have.

Edit: I tried to ignore it just now to make sure everything else was okay, and I got a similar error stating that the 'screen button' is not known.

I also tried putting [] in quotes. [/color]

User avatar
Showsni
Miko-Class Veteran
Posts: 563
Joined: Tue Jul 24, 2007 12:58 pm
Contact:

Re: Simple Inventory.

#4 Post by Showsni »

I think the error is because you have
$ sweatshirt = items("Sweatshirt", "A red jumper.")
instead of
$ sweatshirt = item("Sweatshirt", "A red jumper.")

In my example, item was for the class, and items for the list of items. I should probably have called them something else to make the difference more clear!

If you just want a list, though, you don't really need to bother with a class at all. If your inventory is just something like ["Red Jumper", "Blue Jumper", "Yellow Jumper"] then I think something like

Code: Select all

screen inventory:
    frame:
        xalign 0.0
        yalign 0.0
        vbox:
            for i in items:
                text i
would probably work.

Jayn
Newbie
Posts: 16
Joined: Sun May 13, 2012 6:15 am
Contact:

Re: Simple Inventory.

#5 Post by Jayn »

Thank you for your help! I'm sorry, I'm totally new at this and I know I'm probably being really slow. I appreciate your patience. So this is the new code in screens.

Code: Select all

#Inventories

$ data = "My inventory."
$ items = []
$ sweatshirt = item("Sweatshirt", "A red jumper.")


screen inventory:
    frame:
        xalign 0.0
        yalign 0.0
        vbox:
            for i in items:
                text i
       
#Inventory 2

screen showinv:
    if not items == []:
        frame:
            xalign 0.0
            yalign 0.0
            textbutton "Open Inventory" action (Hide("showinv"), Show("inventory"))
##

And thus, a new error!
What you said about the 'item' 'items' thing worked! But then I got the same error I'm getting now with the different code.

Code: Select all

I'm sorry, but an uncaught exception occurred.

While running game code:
  File "game/script.rpy", line 159, in script
         $ item.append(sweatshirt)
  File "game/script.rpy", line 159, in python
         $ item.append(sweatshirt)
AttributeError: class item has no attribute 'append'

-- Full Traceback ------------------------------------------------------------

Full traceback:
  File "C:\Users\Kreeshel\renpy-6.13.7\renpy\execution.py", line 261, in run
  File "C:\Users\Kreeshel\renpy-6.13.7\renpy\ast.py", line 630, in execute
  File "C:\Users\Kreeshel\renpy-6.13.7\renpy\python.py", line 978, in py_exec_bytecode
  File "game/script.rpy", line 159, in <module>
AttributeError: class item has no attribute 'append'

Windows-post2008Server-6.1.7600
Ren'Py 6.13.7.1646
A Ren'Py Game 0.0

Jayn
Newbie
Posts: 16
Joined: Sun May 13, 2012 6:15 am
Contact:

Re: Simple Inventory.

#6 Post by Jayn »

I decided to go back to the simple onscreen inventory code, just to keep moving forward because at this point I'm pretty confused, and for some reason THAT code won't work for me now, either, even though it was working perfectly fine before.

Code: Select all

init python:   
    showitems = True
   
    def display_items_overlay():
        if showitems:
            inventory_show = "Inventory: "
            for i in range(0, len(items)):
                item_name = items[i].title()
                if i > 0:
                    inventory_show += ", "
                inventory_show += item_name
            ui.frame()
            ui.text(inventory_show)
    config.overlay_functions.append(display_items_overlay)

##
$ items.append("stone") #when you want to add items
$ items.remove("stone")#when you want to remove items
$ showitems = False #when you don't want to show the inventory onscreen (cutscenes and the like)
$ showitems = True #when you want to reshow the inventory after the cutscene is over


Now I get the same 'Name items is not defined' error even though this code worked perfectly well before, when I try to use this code; $ items.append("stone").

I don't understand. :c

Edit; Okay, I got the simple inventory to work by adding 'items = []'. So no worries here, sorry. [/color]

LittleUrchin
Regular
Posts: 43
Joined: Sat Aug 11, 2012 4:53 pm
Location: Trapped inside a snow cone with a purple walrus and a broken jukebox
Contact:

Re: Simple Inventory.

#7 Post by LittleUrchin »

I know this is old by now and this probably won't make a difference anymore, but I think the error was that you needed to put

Code: Select all

$ items.append(sweatshirt)
instead of

Code: Select all

$ item.append(sweatshirt)
[/color]

Dart87
Newbie
Posts: 9
Joined: Mon Dec 02, 2013 12:26 pm
Contact:

Re: Simple Inventory.

#8 Post by Dart87 »

Hi ! I know this is an old post but I understand this code and I'm using it to learn class and stuff. So I'm trying this code but I get an error. I don't understand why.

Code: Select all

#Inv
init python:
    class Item:
        def __init__(self, name, description):
            self.name = name
            if description == "":
                self.description = "A random thing."
            else:
                self.description = description

#Screen
screen Inventaire:
    vbox:
        xalign 0.0
        yalign 0.0
        frame:
            vbox:
                for i in ItemList:
                    textbutton i.name hovered SetVariable("ItemData", i.description) unhovered SetVariable ("ItemData", "My inventory.") action SetVariable ("ItemData", "Clicked!")
        null height 20
        frame:
            text ItemData

#Game
label start:

    $ ItemList = []
    $ ItemData = "My inventory."

    $ sweatshirt = Item("Sweatshirt", "A red jumper.")

    $ ItemList.append("sweatshirt")
    
"blaba"
I'm sorry, but an uncaught exception occurred.

While running game code:
File "game/Testeur.rpy", line 47, in script
"blaba"
File "game/Testeur.rpy", line 23, in execute
screen Inventaire:
File "game/Testeur.rpy", line 24, in execute
vbox:
File "game/Testeur.rpy", line 27, in execute
frame:
File "game/Testeur.rpy", line 28, in execute
vbox:
File "game/Testeur.rpy", line 29, in execute
for i in ItemList:
File "game/Testeur.rpy", line 30, in execute
textbutton i.name hovered SetVariable("ItemData", i.description) unhovered SetVariable ("ItemData", "My inventory.") action SetVariable ("ItemData", "Clicked!")
AttributeError: 'str' object has no attribute 'name'

DragoonHP
Miko-Class Veteran
Posts: 758
Joined: Tue Jun 22, 2010 12:54 am
Completed: Christmas
IRC Nick: DragoonHP
Location: Zion Island, Solario
Contact:

Re: Simple Inventory.

#9 Post by DragoonHP »

Hey. You get that error because of the quotation marks you put around sweatshirt in ItemList.append("sweatshirt"). You need to remove those so that Ren'Py know that you are referencing a variable. Something like this:

Code: Select all

    $ ItemList.append(sweatshirt)
Also, there is a better inventory code in the Cookbook section. You might want to look at it.

Dart87
Newbie
Posts: 9
Joined: Mon Dec 02, 2013 12:26 pm
Contact:

Re: Simple Inventory.

#10 Post by Dart87 »

Thank you !

Post Reply

Who is online

Users browsing this forum: Google [Bot], Kocker