I avoid to use objects because in some cases saving and rollback with objects might not work very well:
Note that it's the change to the variables that matters – changes to fields in objects will not cause those objects to be saved.
https://renpy.org/doc/html/save_load_rollback.html
Keeping data in dicts and lists never failed me. And actually my example works, here's a proof of concept:
Edit: v.2 updated, with tooltips and text input to add items by name:
Code: Select all
define items = {
"book": ("book.png", "Description of book"),
"bug": ("bug.png", "Description of bug"),
"dice": ("dice.png", "Description of dice"),
"film": ("film.png", "Description of film"),
"look": ("look.png", "Description of look"),
"pawn": ("pawn.png", "Description of pawn"),
"sun": ("sun.png", "Description of sun"),
"talk": ("talk.png", "Description of talk"),
"tool": ("tool.png", "Description of tool"),
"wand": ("wand.png", "Description of wand"),
}
default inventory = [] # [ [item_name, amount] ]
init python:
def set_item(item_name, amount):
""" Universal function to add or remove inventory items """
try:
i = [x[0] for x in inventory].index(item_name)
if amount <= 0:
inventory.pop(i)
else:
inventory[i][1] = amount
except:
if amount > 0:
inventory.append([item_name, amount])
def get_item(item_name):
""" Get amount of those items """
try:
i = [x[0] for x in inventory].index(item_name)
return inventory[i][1]
except:
return 0
screen inv(page_number=0, current_item=""):
grid 4 2:
align (0.5, 0.5)
spacing 12
for i in range(8*page_number, 8*page_number+8):
if i < len(inventory):
button:
size_group "items"
background "#345"
hover_background "#579"
vbox:
xalign 0.5
add items[inventory[i][0]][0] # pic
text inventory[i][0]: # name
size 42
yoffset 24
text str(inventory[i][1]): # amount
xalign 1.0
yoffset -64
color "#FF0"
tooltip items[inventory[i][0]][1] # description
action Return((inventory[i][0], inventory[i][1]))
text f"{len(inventory)} items. Page {page_number+1}" align (0.5, 0.0) size 64
if page_number > 0:
textbutton "<" align (0.0, 0.5) action Return(-1) text_size 96
if page_number < (len(inventory)-1)//8:
textbutton ">" align (1.0, 0.5) action Return(1) text_size 96
if current_item:
textbutton "-" align (0.4, 0.9) action Return("-") text_size 96
textbutton "+" align (0.6, 0.9) action Return("+") text_size 96
add items[current_item][0] align (0.5, 0.9)
$ tooltip = GetTooltip()
if tooltip:
text "[tooltip]" align (0.5, 0.2)
frame:
style "itemName"
input id "itemName":
default current_item
style itemName:
align (0.5, 0.8)
xsize 360
background "#345"
hover_background "#579"
label start:
python:
n = 0
for i in items:
set_item(i, n)
n += 1
pageN = 0
current_item = ""
label loop:
call screen inv(pageN, current_item)
if type(_return) is int:
$ pageN = min(max(pageN+_return, 0), (len(inventory)-1)//8)
elif type(_return) is str:
if _return == '-':
$ set_item(current_item, get_item(current_item)-1)
elif _return == '+':
$ set_item(current_item, get_item(current_item)+1)
else:
python:
if _return in items:
current_item = _return
else:
renpy.notify(f"No such item: {_return}")
else:
$ current_item = _return[0]
jump loop
I attach the distributive of the game so you can test how it works.
Unpack it and run the "game" folder with Ren'Py 8 SDK.