Inventory item disapper

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
nropexin
Newbie
Posts: 7
Joined: Wed Feb 08, 2017 6:30 am
Contact:

Inventory item disapper

#1 Post by nropexin » Mon Apr 10, 2017 9:50 pm

I am new to coding so i followed leon inventory guide to setup the inventory bag in the game.
viewtopic.php?f=51&t=23071

So whatever i understand i modified the code to suit the need,.

I have few question hope i will be cleared here.

1. Some code start with "init python" i understand we are initiating python code.
But in some cases are like
init -1 python
init 3 python
what does -1 or 3 or so on.... number really do here?

2. If i have two to three items it randomly shuffles. i know the code itself is wrote in that way, is there any option to make it in order.


3. Now my real problem in the the game....
When i buying an item, i lose money and the item is added to the inventory. The code is working fine.
But for bug testing purpose when i do shift+r, item automatically disappear and i gain back the money. Also when i have the item in inventory it carries over onto different save files along with the lost money which suppose not to happen. Is there anyway to lock the item while refreshing. Please let me know where i did mistake.


Below are the codes which is used in the game.

Code in Script.rpy

Code: Select all

# Inventory code
init python:

    class Item(store.object):
        def __init__(self, name, image="", cost=0):
            self.name = name
            self.image=image # image file to use for this item
            self.cost=cost # how much does it cost in shops?
    
    class Inventory(store.object):
        def __init__(self, money=50):
            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 sell(self, item):
            self.money += item.cost
            self.items.remove(item) 
            
        def buy(self, item):
            if self.money >= item.cost:
                self.items.append(item)
                self.money -= item
                return True
            else:
                return False
                #message = "Item added to inventory"
                #renpy.show_screen("purchase_done", message=message)
            #else:
                #message = "You don't have enough money to buy this item"
                #renpy.show_screen("inventory_popup", message=message)
                
        def earn(self, amount):
            self.money += amount
            
        def has_item(self, item):
                if item in self.items:
                    return True
                else:
                    return False
                    
## Items
    chocolate = Item("Chocolate", image="images/inv_chocolate.png")
    banana = Item("Banana", image="images/inv_banana.png")    
    gun = Item("Gun", image="images/inv_gun.png", cost=60)
    laser = Item("Laser Gun", image="images/inv_laser.png")
    inventory = Inventory()

Code in Gui.rpy

Code: Select all

 
## Inventory ##

init -1 python:

    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 the inventory screen
    item = None
    
    #def item_use():
    #item.use()

    #Tooltips:
    style.tips_top = Style(style.default)
    style.tips_top.size=30
    style.tips_top.color="fff"
    style.tips_top.outlines=[(1, "6b7eef", 0,0)]
    style.tips_top.kerning = 5

    style.tips_bottom = Style(style.tips_top)
    style.tips_top.size=40
    style.tips_bottom.outlines=[(0, "6b7eef", 1, 1), (0, "6b7eef", 2, 2)]
    style.tips_bottom.kerning = 2
    
    style.button.background=Frame("images/inv_frame.png",25,25)
    style.button.yminimum=102
    style.button.xminimum=102
    style.button_text.color="000"
            
screen scr_gui_bag:    
    add "images/bg_bag.jpg" # the background
    tag menu
## Money Value
    hbox align (0.53,0.12) spacing 20:
        text "$"+str(inventory.money) size 60
        
## Exit
    imagebutton auto "bg_bag_exit_%s.png" xpos 0 ypos 0 focus_mask True action Return("scr_gui_bag")
    
## Inventory Slots
    $ x = 350 # coordinates of the top left item position
    $ y = 150
    $ i = 0
    $ sorted_items = sorted(inventory.items, 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)/12):
        $ next_inv_page = 0
    for item in sorted_items:
        if i+1 <= (inv_page+1)*12 and i+1>inv_page*12:
            $ x += 245
            if i%6==0:
                $ y += 240
                $ x = 350
            $ pic = item.image
            $ my_tooltip = "tooltip_inventory_" + pic.replace("images/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"), SetVariable("item", item), Hide("inventory_screen"), item_use] hovered [Show("gui_tooltip", my_picture=my_tooltip, my_tt_ypos=693) ] unhovered [Hide("gui_tooltip")] at inv_eff
            imagebutton idle pic hover pic xpos x ypos y action [Hide("gui_tooltip"), SetVariable("item", item), Hide("inventory_screen")] hovered [Show("gui_tooltip", my_picture=my_tooltip, my_tt_ypos=693) ] unhovered [Hide("gui_tooltip")] at inv_eff
        $ i += 1
        if len(inventory.items)>12:
            textbutton _("Next Page") action [SetVariable('inv_page', next_inv_page), Show("scr_gui_bag")] xpos 0.455 ypos 0.68

screen gui_tooltip (my_picture="", my_tt_xpos=58, my_tt_ypos=687):
    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:", size=40)#, style="tips_top")
    #Tooltips-inventory:
    image tooltip_inventory_chocolate=LiveComposite((1300, 80), (225,110), ImageReference("information"), (250,175), Text("I got chocolate.", size=40))
Code in label

Code: Select all

    Char1 "I will take the choc."
    Char2 "That¡¯ll be $10."
    Char2 "Enjoy your purchase."
    Char1 "Thanks..."
    if inventory.has_item(chocolate):
        "You already have that item."
    else:
        $ inventory.add(chocolate)
        $ inventory.money -= 10

User avatar
nyaatrap
Crawling Chaos
Posts: 1824
Joined: Mon Feb 13, 2012 5:37 am
Location: Kimashi Tower, Japan
Contact:

Re: Inventory item disapper

#2 Post by nyaatrap » Tue Apr 11, 2017 8:33 am

There are two problems.

If you define objects in init, they are defined every time you load a game - this means your save file is lost.
To save objects, You need to declare them by 'default' statement, not 'init'

Code: Select all

default inventory = Inventory()
default itemX = Item()
The second problem is ren'py saves data at the start of the current interaction. This means every changes in the current interaction is lost when you reload a game.
To prevent it, you need to add $renpy.retain_after_load before you open the inventory screen.

Code: Select all

$renpy.block_rollback()
$renpy.retain_after_load()
call inventory_screen
Number of init is order to run programs before the main menu is shown. init -999 runs first ,then init -998..... and 999 is the last.

FYI, this cookbook was written before default and retain_after_load are implemented. It looks as bug in its thread, but it's fixed in ren'py side (but no one mention there).

nropexin
Newbie
Posts: 7
Joined: Wed Feb 08, 2017 6:30 am
Contact:

Re: Inventory item disapper

#3 Post by nropexin » Wed Apr 12, 2017 9:35 am

ohhh great the code is working now.
But every time in the label i have to use $inventory = Inventory(). Is that correct way todo it or I am missing something here.

I have moved the object before init as like below
script.rpy

Code: Select all

default inventory = Inventory()
default chocolate = Item("Chocolate", image="images/inv_chocolate.png")
init python:
    class Item(store.object):
        def __init__(self, name, image="", cost=0):
            self.name = name
            self.image=image # image file to use for this item
            self.cost=cost # how much does it cost in shops?
Also in the label i have called the inventory as like below
Code in label

Code: Select all

    Char1 "I will take the choc."
    Char2 "That¡¯ll be $10."
    Char2 "Enjoy your purchase."
    Char1 "Thanks..."
    $inventory = Inventory()
    if inventory.has_item(chocolate):
        "You already have that item."
    else:
        $ inventory.add(chocolate)
        $ inventory.money -= 10

User avatar
nyaatrap
Crawling Chaos
Posts: 1824
Joined: Mon Feb 13, 2012 5:37 am
Location: Kimashi Tower, Japan
Contact:

Re: Inventory item disapper

#4 Post by nyaatrap » Thu Apr 13, 2017 12:05 pm

nropexin wrote:But every time in the label i have to use $inventory = Inventory().
I don't know why you have to do. Without those lines anything should work. If not, maybe your save data is not compatible so don't load it.
default statements are run after all init codes, before the label start.

Post Reply

Who is online

Users browsing this forum: No registered users