Code question: sorting through a list doesn't work after appending a new item to it

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
Alem
Regular
Posts: 38
Joined: Wed Mar 15, 2017 7:53 am
Contact:

Code question: sorting through a list doesn't work after appending a new item to it

#1 Post by Alem »

I'm still pretty new to python and my problem may be a misunderstanding on my part. So, I wanted to check out Renpy's inventory templates and stopped on this one. Tinkered with it for a bit and decided to add some features for later use, namely filtering the inventory for a specific item type. It works fine until I try to add a new item to the list via appending. Then all items from the inventory screen vanish without any errors. Game's directory is also clean - no error or traceback logs.

Most of the code is from the tutorial itself. Init and classes:

Code: Select all

init -1 python:
    import renpy.store as store
    import renpy.exports as renpy # we need this so Ren'Py properly handles rollback with classes

    inv_page = 0 # initial page of teh inventory screen
    item = None
    filter = "1"
    
    class Player(store.object):
        def __init__(self, name, max_hp=0, max_mp=0, element=None):
            self.name=name
            self.max_hp=max_hp
            self.hp=max_hp
            self.max_mp=max_mp
            self.mp=max_mp
            self.element=element

    class Item(store.object):
        def __init__(self, name, player=None, hp=0, mp=0, element="", image="", cost=0, type=""):
            self.name = name
            self.player=player # which character can use this item?
            self.hp = hp # does this item restore hp?
            self.mp = mp # does this item restore mp?
            self.element=element # does this item change elemental damage?
            self.image=image # image file to use for this item
            self.cost=cost # how much does it cost in shops?
            self.type=type
        def use(self): #here we define what should happen when we use the item
            if self.hp>0: #healing item
                player.hp = player.hp+self.hp
                if player.hp > player.max_hp: # can't heal beyond max HP
                    player.hp = player.max_hp
                inventory.drop(self) # consumable item - drop after use
            elif self.mp>0: #mp restore item
                player.mp = player.mp+self.mp
                if player.mp > player.max_mp: # can't increase MP beyond max MP
                    player.mp = player.max_mp
                inventory.drop(self) # consumable item - drop after use
            else:
                player.element=self.element #item to change elemental damage; we don't drop it, since it's not a consumable item

    class Inventory(store.object):
        def __init__(self, money=10):
            self.money = money
            self.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 buy(self, item):
            if self.money >= item.cost:
                self.items.append(item)
                self.money -= item.cost

    def item_use():
        item.use()
Inventory sceen with filtering:

Code: Select all

screen inventory_screen:    
    add "gui/inventory.png" # the background
    modal True #prevent clicking on other stuff when inventory is shown
    #use battle_frame(char=player, position=(.97,.20)) # we show characters stats (mp, hp) on the inv. screen
    #use battle_frame(char=dog, position=(.97,.50))
    
    hbox align (.95,.895):
        textbutton "Close Inventory" action [Hide("inventory_screen"), Show("inventory_button"), Return(None)]
        
    $ x = 200 # coordinates of the top left item position
    $ y = 25
    $ i = 0
    $ next_inv_page = inv_page + 1            
    if next_inv_page > int(len(inventory.items)/24):
        $ next_inv_page = 0
        for item in inventory.items:
            if filter == item.type:
                if i+1 <= (inv_page+1)*24 and i+1>inv_page*24:
                    $ x += 300
                    if i%6==0:
                        $ y += 200
                        $ x = 200
                    $ pic = item.image
                    $ my_tooltip = "tooltip_inventory_" + pic.replace("gui/inv_", "").replace(".png", "") # we use tooltips to describe what the item does.
                    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 player.element and (player.element==item.element): #indicate the selected gun
                            add "gui/selected.png" xpos x ypos y anchor(.5,.5)
                $ i += 1
                if len(inventory.items)>24:
                    textbutton _("Turn Page") action [SetVariable('inv_page', next_inv_page), Show("inventory_screen")] xpos .475 ypos .85
Scene body:

Code: Select all

label start:
    python:
        player = Player("Derp", 100, 50)
        player.hp = 50
        player.mp = 10
        filter = "1"
            
        chocolate = Item("Chocolate", hp=40, image="gui/inv_chocolate.png", type="1")
        banana = Item("Banana", mp=20, image="gui/inv_banana.png", type="2")    
        gun = Item("Gun", element="bullets", image="gui/inv_gun.png", type="3")
        laser = Item("Laser Gun", element="laser", image="gui/inv_laser.png", type="4")
        inventory = Inventory()
        
        #add items to the initial inventory:
        inventory.add(chocolate)
        inventory.add(banana)
        inventory.add(gun)
        inventory.add(banana)
        inventory.add(laser)

    scene sidewalk
    show screen inventory_button
    "Me" "Lalala~"
    "You found a laser gun!"
    $inventory.add(gun)
    $inventory.add(laser)
    "The end"
The vanishing happens on $inventory.add(gun) step and the inventory goes blank. This didn't happen in the original tutorial, so it's probably somehow linked to my if filter == item.type: in the filtering code. I'm stuck :< Any help?

Thank you!

Alem
Regular
Posts: 38
Joined: Wed Mar 15, 2017 7:53 am
Contact:

Re: Code question: sorting through a list doesn't work after appending a new item to it

#2 Post by Alem »

Sorry for a long post, spoiler tag doesn't do what I hoped it does ><

User avatar
Scribbles
Miko-Class Veteran
Posts: 636
Joined: Wed Sep 21, 2016 4:15 pm
Completed: Pinewood Island, As We Know It
Projects: In Blood
Organization: Jaime Scribbles Games
Deviantart: breakfastdoodles
itch: scribbles
Location: Ohio
Contact:

Re: Code question: sorting through a list doesn't work after appending a new item to it

#3 Post by Scribbles »

perhaps if you put the python code before the start label? > < I'm sorry I'm not really familiar with that code, but hopefully you get it figured out!

Code: Select all

init python:
    player = Player("Derp", 100, 50)
    player.hp = 50
    player.mp = 10
    filter = "1"
            
      ##and so on

label start:
    scene sidewalk
Image - Image -Image

User avatar
carrot
Regular
Posts: 28
Joined: Fri Jul 28, 2017 7:43 am
Contact:

Re: Code question: sorting through a list doesn't work after appending a new item to it

#4 Post by carrot »

Is your indentation right, here (in inventory_screen)?

Code: Select all

if next_inv_page > int(len(inventory.items)/24):
    $ next_inv_page = 0
    for item in inventory.items: # <--- I'm talking specifically about this line
        ...
The item-drawing loop is nested in the same if-statement as your check for the inventory page, so it'll only draw if it's on the last page (from what I'm seeing).

Does it fix it if you un-indent the whole for-loop block?

Alem
Regular
Posts: 38
Joined: Wed Mar 15, 2017 7:53 am
Contact:

Re: Code question: sorting through a list doesn't work after appending a new item to it

#5 Post by Alem »

carrot wrote: Fri Aug 11, 2017 5:25 pm Is your indentation right, here (in inventory_screen)?

The item-drawing loop is nested in the same if-statement as your check for the inventory page, so it'll only draw if it's on the last page (from what I'm seeing).

Does it fix it if you un-indent the whole for-loop block?
Bullseye. Thank you :)

Post Reply

Who is online

Users browsing this forum: Google [Bot], IrisColt