Inventory : can only use Recipe/Combine once

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
Altaka
Newbie
Posts: 2
Joined: Sun Jul 28, 2019 4:33 am
Contact:

Inventory : can only use Recipe/Combine once

#1 Post by Altaka »

Hi !

I'm using a version of Leon's inventory for my game. After fighting with many aspects, I've finally made it work quite nicely for my game's needs. I can get items, combine them to make a new items and drop them easily. Yay !
But (of course there is one) once I've combined items, I can't do it again.

Let's say I want to use a quill and a parchement to make a letter : I select the items, combine them, and I have my letter.
Then I want to use a label/a stamp on a bone : I select the items,... And no matter how much I click on the combine button, it doesn't work.

All I know is that the first "combination" will be the only one (If I combine the stamp and the bone first, I won't be able to combine the parchement and the quill). The order of selection doesn't matter and my "recipes" are working.

Here is the code :

Code: Select all

init -1 python:
    import copy
    import renpy.store as store
    import renpy.exports as renpy # we need this so Ren'Py properly handles rollback with classes
    from operator import attrgetter # we need this for sorting items

    inv_page = 0 # initial page of teh inventory screen
    item = None
    class Player(renpy.store.object):
        def __init__(self, name, element=None):
            self.name=name
            self.element=element
    player = Player("Derp")

    class Recipe(store.object):
        def __init__(self, items=[], item_created=None):
            self.items = items
            self.item_created = item_created
        def combine_check(self):
            too_many=False # too many items selected?
            correct_recipe_items = copy.copy(self.items) # make a copy of the list of recipe items
            for item in inventory.selected_items:
                if item.recipeItem: # and item in self.items:
                    if item in correct_recipe_items:
                        correct_recipe_items.remove(item) # remove the current item from the list of correct_recipe_items; if correct_recipe_items is empty at the end, we have created the recipe
                    if not (item in self.items): # current item is not in this recipe
                        too_many=True
            if len(correct_recipe_items) == 0 and not too_many: # correct_recipe_items is empty means we have selecte just the right items
                inventory.add(self.item_created) # add the newly created item
                for drop_item in self.items: # remove all the items in this recipe from inventory
                    inventory.drop(drop_item)

    class Item(store.object):
            def __init__(self, name, player=None, element="", image="", recipeItem=True):
                self.selected_items=False
                self.recipeItem=recipeItem
                self.name = name
                self.player=player # which character can use this item?
                self.element=element # does this item change elemental damage?
                self.image=image # image file to use for this item
            def use(self): #here we define what should happen when we use the item
                if self.recipeItem:
                    if self in inventory.selected_items:
                        inventory.selected_items.remove(self)
                    else:
                        inventory.selected_items.append(self)
 
    class Inventory(store.object):
        def __init__(self, selected_items=False):
            self.items = []
            self.selected_items = []
        def add(self, item): # a simple method that adds an item; we could also add conditions here (like check if there is space in the inventory)
            self.items.append(item)
        def drop(self, item):
            self.items.remove(item)
        def has_item(self, item):
            if item in self.items:
                return True
            else:
                return False


    def item_use():
        item.use()

    #Tooltips:
    style.tips_top = Style(style.default)
    #style.title.font="VINERITC.ttf"
    style.tips_top.size=14
    style.tips_top.color="#1f001a"
    #style.tips_top.outlines=[(3, "6b7eef", 0,0)]
    style.tips_top.kerning = 5

    style.tips_bottom = Style(style.tips_top)
    style.tips_bottom.font="VINERITC.TTF"
    style.tips_top.size=25
    #style.tips_bottom.outlines=[(0, "6b7eef", 1, 1), (0, "6b7eef", 2, 2)]
    style.tips_bottom.kerning = 1

    style.button.background=Frame("gui/frame.png",25,25)
    style.button.yminimum=52
    style.button.xminimum=52
    style.button_text.color="000"


    showitems = True #turn True to debug the inventory


screen inventory_button:
    textbutton "Inventaire" action [ Show("inventory_screen"), Hide("inventory_button")] align (.95,.04)

screen inventory_screen:
    add "gui/inventory.png" # the background
    modal True #prevent clicking on other stuff when inventory is shown
    hbox align (.95,.04) spacing 20:
        textbutton "Fermer l'inventaire" action [ Hide("inventory_screen"), Show("inventory_button") ]
    $ x = 125 # coordinates of the top left item position
    $ y = 25
    $ i = 0
    $ sorted_items = sorted(inventory.items, key=attrgetter('name')) #sort by name
    $ sorted_items = sorted(inventory.items, key=attrgetter('element'), reverse=True) # we sort the items, so non-consumable items that change elemental damage (guns) are listed first
    $ next_inv_page = inv_page + 1
    if next_inv_page > int(len(inventory.items)/9):
        $ next_inv_page = 0
    $ tmp_inventory = []
    for item in sorted_items:
        $ tmp_inventory.append(item)
        if tmp_inventory.count(item) == 1:
            if i+1 <= (inv_page+1)*15 and i+1>inv_page*15:
                $ x += 190
                if i%5==0:
                    $ y += 170
                    $ x = 125
                $ pic = item.image
                $ my_tooltip = "tooltip_inventory_" + pic.replace("gui/", "").replace(".png", "") # we use tooltips to describe what the item does.
                if item.recipeItem:
                    imagebutton idle pic hover pic xpos x ypos y action [Hide("gui_tooltip"), SetVariable("item", item), item_use] hovered [ Play ("sound", "sfx/click.wav"), Show("gui_tooltip", my_picture=my_tooltip, my_tt_ypos=650) ] unhovered [Hide("gui_tooltip")] at inv_eff
                else:
                    imagebutton idle pic hover pic xpos x ypos y action [Hide("gui_tooltip"), Show("inventory_button"), SetVariable("item", item), Hide("inventory_screen"), item_use] hovered [ Play ("sound", "sfx/click.wav"), Show("gui_tooltip", my_picture=my_tooltip, my_tt_ypos=693) ] unhovered [Hide("gui_tooltip")] at inv_eff
                if item in inventory.selected_items:
                    add "gui/selected.png" xpos x ypos y anchor(.5,.5)
                $ i += 1
            if sorted_items.count(item) > 1:
                text str(sorted_items.count(item)) xpos x+50 ypos y-50 anchor(.5,.5) color "#000" #align(.9,.1)
        if len(inventory.items)>15:
            textbutton _("Next Page") action [SetVariable('inv_page', next_inv_page), Show("inventory_screen")] xpos .775 ypos .500

    hbox align (0.05,.04) spacing 20:
        textbutton "Assembler" action [Function(combine_items)] align (.80,.80)



screen gui_tooltip (my_picture="", my_tt_xpos=58, my_tt_ypos=640):
    add my_picture xpos my_tt_xpos ypos my_tt_ypos

init -1:
    transform inv_eff: # too lazy to make another version of each item, we just use ATL to make hovered items super bright
        zoom 0.5 xanchor 0.5 yanchor 0.5
        on idle:
            linear 0.2 alpha 1.0
        on hover:
            linear 0.2 alpha 2.5


    #image information = Text("INFORMATION", style="tips_top")
    #Tooltips-inventory:
#[ bunch of tooltips]

    image sidewalk = "Sidewalk.jpg"
#[Preparing the imagemap}

init python:

    def combine_items():
        global Recipe
        for recipe in recipes:
            Recipe.combine_check(recipe)
        Inventory.selected_items = []
        return

init :
#[...defining the characters here]

# The game starts here.
label start:
    transform moveright:
        linear 0.5 xpos 0.85
    transform moveleft:
        linear 0.5 xpos 0.15
    python:
            player = Player("Derp")

            chocolate = Item("Chocolat", image="gui/chocolate.png", recipeItem=True)
            approved = Item("Os approuvé !", element="choupi", image="gui/approved.png", recipeItem=True)
            bone = Item("Os", element="choupi", image="gui/bone.png", recipeItem=True)
            plume = Item("Plume", element="choupi", image="gui/plume.png", recipeItem=True)
            parchement = Item("Parchemin", element="choupi", image="gui/parchemin.png", recipeItem=True)
            lettre_sentimentale = Item("Lettre sentimentale", element="choupi", image="gui/lettre_sentimentale.png", recipeItem=True)
            cristal = Item("Cristal", element="choupi", image="gui/cristal.png", recipeItem=True)
            stamp= Item("Bon JP", element="choupi", image="gui/stamp.png", recipeItem=True)
            tower = Item("Tour d'échec", element="choupi", image="gui/tower.png", recipeItem=True)
            towercristal = Item("Tour d'échec avec un cristal caché", element="choupi", image="gui/tower_and_cristal.png", recipeItem=True)
            inventory = Inventory()
            #add items to the initial inventory:
            inventory.add(chocolate)
            inventory.add(bone)
            inventory.add(cristal)
            inventory.add(stamp)
            inventory.add(parchement)
            inventory.add(plume)
            inventory.add(tower)
            #recipes/combinations 
            global recipes
            recipes = []
            recipes = [Recipe([parchement, plume], lettre_sentimentale), Recipe([stamp, bone], approved), Recipe([cristal, tower], towercristal)]
(Sorry for my French in the items' description :mrgreen: )
I guess it must have something to do with the "item_created" value but I don't see how I can change it. Should I add a "Self.item_created=None" after the combine function or in the definition of "Recipe" ? Or something else ?

So if someone has an idea or an answer, I'm all ears !

Altaka

Post Reply

Who is online

Users browsing this forum: No registered users