Inventory Help

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
ClazzyAzzy
Newbie
Posts: 1
Joined: Sun May 19, 2024 8:00 pm
Contact:

Inventory Help

#1 Post by ClazzyAzzy »

Apologies if this seems silly, but I was wondering if there was a way to make the interactable hotspots add things to your inventory. :?:
I’m very… new when it comes to python, and I’ve been taking a crack at it for like? 3 hours.

Any tips/ideas welcome…
My plan was making an investigative type point and click where you collect clues on the map.

To be more specific, I’ve tried putting picking it up as a true/false bool that woukd switch to true under specific conditions (like when you int with a hotspot)

but if im lucky enough to not immediately explode the pc, then it seems to just be adding more items than i need to, and not exclusively when i click on it..

jeffster
Miko-Class Veteran
Posts: 520
Joined: Wed Feb 03, 2021 9:55 pm
Contact:

Re: Inventory Help

#2 Post by jeffster »

For every item you can set an imagebutton (or a hotspot if you use imagemap).

Set conditions (with "if") whether to show for each of those buttons or hotspots.

For example, if on map1 you have to find
- a case located at pos (100, 800)
- and a book located at pos (700, 700):

Code: Select all

# Set that you don't have the case and the book:
default have_case = False
default have_book = False

# Show them as buttons on screen
screen map1_clues():

    if not have_case:
        imagebutton:
            auto "case_%s.png"
            pos (100, 800)
            action SetVariable("have_case", True)

    if not have_book:
        imagebutton:
            auto "book_%s.png"
            pos (700, 700)
            action SetVariable("have_book", True)

#...
label look_for_clues:
    scene map1
    show screen map1_clues
    "Look for clues!"
    hide screen map1_clues
Here if player clicked "book" button, it would disappear from the map, and the variable have_book will be True. Then you could check the variable and add that item to the inventory. The same with "case" button.

Code: Select all

    scene map1
    show screen map1_clues
    "Look for clues!"
    hide screen map1_clues
    if have_book:
        # Add book to inventory
    if have_case:
        # Add case to inventory
Of course instead of just SetVariable you can call some label or function to react to finding the clue.
If the problem is solved, please edit the original post and add [SOLVED] to the title. 8)

MikiSiku
Newbie
Posts: 2
Joined: Fri May 24, 2024 12:03 am
Contact:

Re: Inventory Help

#3 Post by MikiSiku »

I am working on this same thing and this is soooo helpful!! Thank you!
However, I would like more detail about adding the item to the inventory.... Above, you just say "#add book to inventory"

Would you recommend I have a second screen that is the inventory? The items in the inventory (displayed in a bar at the side) would also need to be imagebuttons that could be used later in the game. For example, the player needs to use the book with the correct bookcase at a library (a third screen).

So, I would need to set the have_book variable go to false again, once the player has selected the book AND the bookcase imagebutton. I would also need to have a way to show that the book is selected (like with the hover appearance)...

jeffster
Miko-Class Veteran
Posts: 520
Joined: Wed Feb 03, 2021 9:55 pm
Contact:

Re: Inventory Help

#4 Post by jeffster »

MikiSiku wrote: Fri May 24, 2024 12:30 am Above, you just say "#add book to inventory"
It depends on your implementation of inventory.
They were discussed here often, and there are various ready-to-use inventory systems in the Ren'Py Cookbook, all kinds of types and styles:
viewforum.php?f=51

Here instead of "have_book" you can code the inventory as a dictionary of items, where an item would be:

inventory['book'] = list or dict of data, like book's picture, description, maybe amount etc.

Example:

Code: Select all

# Initialize inventory as an empty dict:
default inventory = {}

label start:
    # ...Some script

    # Adding the book (picture & description):

    $ inventory['book'] = ["items/book_%s.png", "It's an old book with strange symbols. Its cover feels warm."]

    # Checking if you have the book:

    if 'book' in inventory:
        # True if it's there

    if 'book' not in inventory:
        # True if it's not there

Hence you don't need a separate variable have_book, that was just an example.

Another example - initialize the inventory already filled with some items:

Code: Select all

default inventory = {
    'case': ["items/case_%s.png", "The case you found in the abandoned lab."],
    'cigarette butt': ["items/butt_%s.png", "What... Are there traces of lipstick?"],
    }

# Changing the description (like after you investigated that item):

    $ inventory['cigarette butt'][1] = "The lipstick matches the one Robin uses!"
Pictures:
need to have a way to show that the book is selected (like with the hover appearance)...
To show that the book is selected, it's convenient to use "imagebutton auto":
https://renpy.org/doc/html/screens.html#imagebutton

Then for
imagebutton auto "book_%s.png":
we create pictures like:

book_idle.png
book_hover.png
book_selected_idle.png
book_selected_hover.png

and the button shows the correct image depending on the button's state.

Buttons in screens:
Would you recommend I have a second screen that is the inventory? The items in the inventory (displayed in a bar at the side) would also need to be imagebuttons that could be used later in the game. For example, the player needs to use the book with the correct bookcase at a library (a third screen).
An example how to use inventory in a screen:

Code: Select all

screen library():
    default select = None       # At first, no items are selected

    # Show the background:
    add "library_background.webp"

    vbox:
        # Inventory items at the left edge of the screen.
        # If there are too many items, use a scrollable viewport or more than one column (= grid).

        align (0.0, 0.5)

        for i in inventory:
            # "for" will loop through item keys: "book", "case" etc.
                                                                                 # Each item will have:
            imagebutton auto inventory[i][0]:                     # picture
                tooltip inventory[i][1]                                    # description
                action SetScreenVariable("select", i)          # click sets this item as the selected one
                selected (select == i)                                   # condition to show this button as selected

    # Some other stuff on that screen, like bookshelf buttons etc.
This example is made as one screen, but you can make inventory as a separate screen.

Then you can re-use it in other screens...
https://renpy.org/doc/html/screens.html#use

...or you can probably (?) use interactions between different screens, then just make "select" a regular variable instead of a "Screen Variable" as in my example.
https://renpy.org/doc/html/screens.html ... n-language

Here in one screen of the example above, the inventory is at the left edge, and interactable buttons somewhere else.
Like this button (the bookshelf to put the book on):

Code: Select all

    imagebutton auto "bookshelf_%s.png":
        sensitive ("select" == "book")
        action put_book
And you create function "put_book", which would run when you click the bookshelf after "book" button is selected:

Code: Select all

init python:
    def put_book():
        # Remove the book from the inventory:
        del store.inventory['book']

        # Show a notification or something
        renpy.notify("You put the book in place!")

        # Do any other stuff here: play some sound and whatnot...
        renpy.play("audio/chime.opus")

Removing the book from the inventory--
So, I would need to set the have_book variable go to false again, once the player has selected the book AND the bookcase imagebutton.
As "book" key was removed from "inventory" dictionary, Ren'Py will repaint the screen not having that item in the inventory anymore.

If for some reason that repaint doesn't happen, add to the function "renpy.restart_interaction":

Code: Select all

init python:
    def put_book():
        # Remove the book from the inventory:
        del store.inventory['book']

        # Show a notification or something
        renpy.notify("You put the book in place!")

        # Do any other stuff here: play some sound and whatnot...
        renpy.play("audio/chime.opus")

        renpy.restart_interaction()
If the problem is solved, please edit the original post and add [SOLVED] to the title. 8)

jeffster
Miko-Class Veteran
Posts: 520
Joined: Wed Feb 03, 2021 9:55 pm
Contact:

Re: Inventory Help

#5 Post by jeffster »

MikiSiku wrote: Fri May 24, 2024 12:30 am For example, the player needs to use the book with the correct bookcase at a library (a third screen).

So, I would need to set the have_book variable go to false again, once the player has selected the book AND the bookcase imagebutton. I would also need to have a way to show that the book is selected (like with the hover appearance)...
PS. Another way to put a book on a shelf is to make the book draggable.
https://renpy.org/doc/html/drag_drop.html

For example, click the book button => Create a draggable. => If it's dropped not in the correct bookcase, snap it back.

BTW, to do those complex things with screens, we don't have to stay in the open screen all the time:
(1) Call the screen. Return from it when some complex stuff needs to be done.
(2) In the script - after the "call screen" - check the _return variable and do some stuff, then go on or loop back to calling the screen:

Code: Select all

label library:
    $ book_dragged = None
    call screen library1
    if _return == "drag":
        $ book_dragged = inventory['book']
        $ del inventory['book']
        jump library
    elif _return == "placed":
        #...You put the book on the shelf
        jump library

    # Go on further with the script
The book button would have
action Return("drag"),
and the bookcase button would have
action Return("placed"),
etc.
In the screen, the draggable book would be shown under condition

Code: Select all

        if book_dragged:
            drag:
                #...
If the problem is solved, please edit the original post and add [SOLVED] to the title. 8)

Post Reply

Who is online

Users browsing this forum: Bing [Bot]