Check if player has certain items in 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
Doeny
Regular
Posts: 145
Joined: Wed Sep 07, 2022 8:28 pm
Contact:

Check if player has certain items in inventory

#1 Post by Doeny »

Hi, I was wondering if there's a way to create a class/object with list as one of it's properties, which contains a register of items the player has to have in their inventory to satisfy a certain condition.

For example: (the list contains 10x wood, 5x fiber & 3x rope).
Is it possible to create such a list that could be compared with player's traits?

User avatar
m_from_space
Miko-Class Veteran
Posts: 978
Joined: Sun Feb 21, 2021 3:36 am
Contact:

Re: Check if player has certain items in inventory

#2 Post by m_from_space »

Doeny wrote: Thu Jan 04, 2024 2:02 am Hi, I was wondering if there's a way to create a class/object with list as one of it's properties, which contains a register of items the player has to have in their inventory to satisfy a certain condition.

For example: (the list contains 10x wood, 5x fiber & 3x rope).
Is it possible to create such a list that could be compared with player's traits?
If you're only talking about the player, you don't really need a class, since there always will only be one instance of "the player", right? (Classes are mostly useful, if you want to derive multiple objects from it, like a class "Animal" or "NPC".)

Since you want to store not only an item, but also its amount, I suggest using a simple dictionary for the inventory.

Code: Select all

default inventory = {
    "wood": 0,
    "fiber": 0,
    "rope": 0
}
Now you can put things inside of it or remove them.

Code: Select all

label start:
    # add stuff
    $ inventory["wood"] += 10
    $ inventory["fiber"] += 5
    # remove 2 wood
    $ inventory["wood"] -= 2
To check for contents, you can just use common logic.

Code: Select all

label start:
    if inventory["wood"] >= 10 and inventory["fiber"] >= 5 and inventory["rope"] >= 3:
        "You're well equipped."
    else:
        "You gotta go collect more stuff!"

Doeny
Regular
Posts: 145
Joined: Wed Sep 07, 2022 8:28 pm
Contact:

Re: Check if player has certain items in inventory

#3 Post by Doeny »

m_from_space wrote: Thu Jan 04, 2024 3:59 am
Since you want to store not only an item, but also its amount, I suggest using a simple dictionary for the inventory.
Well, that looks less complicated than I thought. I'll see how far can I go with this. Thanks.

Doeny
Regular
Posts: 145
Joined: Wed Sep 07, 2022 8:28 pm
Contact:

Re: Check if player has certain items in inventory

#4 Post by Doeny »

m_from_space wrote: Thu Jan 04, 2024 3:59 am
If you're only talking about the player, you don't really need a class, since there always will only be one instance of "the player", right? (Classes are mostly useful, if you want to derive multiple objects from it, like a class "Animal" or "NPC".)

Since you want to store not only an item, but also its amount, I suggest using a simple dictionary for the inventory.
I'm wondering, is there a way to put it in another dictionary and make it work for multiple objects? Because I have like 9 materials to work on, and don't wanna create a separate line for each of them.

So would it possibly work if I did it like this, or does it need some changes? (I guess it does so, but I wanna know if this solution is even possible in python's terms)

Code: Select all

default craft_items = {
    "item_1":
        ["a", _("item_1"), ("wood": 50, "fiber": 50)],
}
...
...
...
if craft_items[2] >= inventory:
	"You're well equipped."

User avatar
m_from_space
Miko-Class Veteran
Posts: 978
Joined: Sun Feb 21, 2021 3:36 am
Contact:

Re: Check if player has certain items in inventory

#5 Post by m_from_space »

Doeny wrote: Fri Jan 05, 2024 11:34 pm I'm wondering, is there a way to put it in another dictionary and make it work for multiple objects? Because I have like 9 materials to work on, and don't wanna create a separate line for each of them.
You can put lists in dicts, dicts in lists, and all other ways possible. What do you mean you want to make work for multiple objects? If it's about a recipe, you will have to put down the recipe for every object. But of course you could create function. On the other hand, if you have multiple objects that all use the same 9 materials, you could of course create a class for the materials and items themselves.

Code: Select all

init python:
    # to create an item and determine how much materials are necessary for that item
    class Item:
        def __init__(self, name, description, recipe=None):
            self.name = name
            self.description = description
            if recipe is None:
                self.recipe = {}
            else:
                self.recipe = recipe
            return

# building materials (they do not have recipes, because they are basic)
define wood = Item("Wood", "Sticks & Logs")
define fiber = Item("Fiber", "Plant fibers")

# some basic items that are made out of the building materials and/or other items
define rope = Item("Rope", "A basic rope.", recipe={fiber: 10})
define raft = Item("Raft", "A simple raft.", recipe={rope: 5, wood: 20})
I used "define" here, since the items and their recipes probably do not change.

And here is a function that could check whether a player has enough in their inventory (we now store whole Item objects in side the inventory). That's why we do not use quotes anymore, it refers to a variable now.

Code: Select all

# starting inventory (can be empty of course)
default inventory = {fiber: 2, wood: 5, rope: 1}

init python:
    # determine if the player can make this item
    def canCreate(item):
        global inventory
        for ingredient, amount in item.recipe.items():
            # the player doesn't even have this ingredient
            if incredient not in inventory:
                return False
            # the player has too little of it
            if inventory[ingredient] < amount:
                return False
        # the loop finished successfully, so we're good
        return True

label start:
    if canCreate(raft):
        "You have enough materials to build a raft."
    else:
        "Nope."
I hope this makes sense so far. I hope there are no typos in the code, I didn't test it.

Doeny
Regular
Posts: 145
Joined: Wed Sep 07, 2022 8:28 pm
Contact:

Re: Check if player has certain items in inventory

#6 Post by Doeny »

m_from_space wrote: Sat Jan 06, 2024 6:05 am
Doeny wrote: Fri Jan 05, 2024 11:34 pm I'm wondering, is there a way to put it in another dictionary and make it work for multiple objects? Because I have like 9 materials to work on, and don't wanna create a separate line for each of them.
You can put lists in dicts, dicts in lists, and all other ways possible. What do you mean you want to make work for multiple objects? If it's about a recipe, you will have to put down the recipe for every object. But of course you could create function. On the other hand, if you have multiple objects that all use the same 9 materials, you could of course create a class for the materials and items themselves.

I hope this makes sense so far. I hope there are no typos in the code, I didn't test it.
It does. Thank you so much, that's a huge help for me!

Post Reply

Who is online

Users browsing this forum: Ahrefs [Bot], Google [Bot], Toma