I have a problem which is really simple and I know from my memory of precedent asked questions that this kind of stuff is frequent with Renpy, but I can't figure it out, neither where I read that, nor how to fix it.
Let me explain,
I have an inventory system, ( you can see it in image here : https://i.imgur.com/Z4CbASa.png ) which is working.
But, when you get one item, save the game, then reload a previous save before you found it, this item is still in you inventory.
I have to idea how to begin to try solving that even if I read the tuto about what's is save and what's not saved by rendpy (https://www.renpy.org/doc/html/save_load_rollback.html).
I already tinker a workaroud for my item system to be compatible with the rollback system but I can't do it with SAVE/LOAD system.
So I will show you the way I define the inventory system in Python and the way I add an item in the inventory during a playthrouht and maybe one of the clever minds which hang up aroud here will be able to identify how I should solve this.
How I add an item during a playthrough
Code: Select all
$ inventory.add(items["Ducktape"])
My inventory system
Code: Select all
class Player(renpy.store.object):
def __init__(self, name, max_main_health=0, max_main_hunger=0, max_main_thirst=0, max_main_energy=0, max_main_sleep=0, max_main_moral=0, max_main_tension=0, element=None):
self.name=name
self.max_main_health=max_main_health
self.main_health=max_main_health
self.max_main_hunger=max_main_hunger
self.main_hunger=max_main_hunger
self.max_main_thirst=max_main_thirst
self.main_thirst=max_main_thirst
self.max_main_energy=max_main_energy
self.main_energy=max_main_energy
self.max_main_sleep=max_main_sleep
self.main_sleep=max_main_sleep
self.max_main_moral=max_main_moral
self.main_moral=max_main_moral
self.max_main_tension=max_main_tension
self.main_tension=max_main_tension
self.element=element
player = Player("Derp", 100, 50)
class Item(store.object):
def __init__(self,
name,
player=None,
cost=0,
main_health=0,
main_hunger=0,
main_thirst=0,
main_energy=0,
main_sleep=0,
main_moral=0,
main_tension=0,
element="",
image="",
trashable=True,
usable=True):
self.name=name
self.player=player # which character can use this item?
self.cost=cost # how much does it cost in shops?
self.main_health = main_health # does this item modify health?
self.main_hunger = main_hunger # does this item modify hunger?
self.main_thirst = main_thirst # does this item modify thirst?
self.main_energy = main_energy # does this item modify energy?
self.main_sleep = main_sleep # does this item modify sleep?
self.main_moral = main_moral # does this item modify moral?
self.main_tension = main_tension # does this item modify tension?
self.element=element # does this item change elemental damage?
self.image=image
self.trashable = trashable
self.usable= usable
def use(self): #here we define what should happen when we use the item
if self.main_health>0: # healing item
player.main_health = player.main_health+self.main_health
if player.main_health > player.max_main_health: # can't heal beyond max HP
player.main_health = player.max_main_health
inventory.drop(self) # consumable item - drop after use
elif self.main_hunger>0: # hunger restore item
player.main_hunger = player.main_hunger+self.main_hunger
if player.main_hunger > player.max_main_hunger: # can't increase hunger beyond max
player.main_hunger = player.max_main_hunger
inventory.drop(self) # consumable item - drop after use
elif self.main_thirst>0: # thirst restore item
player.main_thirst = player.main_thirst+self.main_thirst
if player.main_thirst > player.max_main_thirst: # can't increase thirst beyond max
player.main_thirst = player.max_main_thirst
inventory.drop(self) # consumable item - drop after use
elif self.main_moral<0: # moral gain item
player.main_moral = player.main_moral+self.main_moral
if player.main_moral > player.max_main_moral: # can't increase moral beyond max
player.main_moral = player.max_main_moral
elif self.main_moral<0: # moral down item
player.main_moral = player.main_moral-self.main_moral
if player.main_moral < 0: # can't decrease moral beyond zero
player.main_moral = 0
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, spaces = 4):
self.items = []
self.spaces = spaces
def add(self, item):
if self.has_space():
self.items.append(item)
return True
else:
return False
def trash(self, item):
if item.trashable and item in self.items:
self.items.remove(item)
print("", "Item is trashed!")
else:
print("", "Item can't be trashed!")
def drop(self, item):
if item in self.items:
self.items.remove(item)
print("", "Item dropped!")
else:
print("", "Item can't be dropped!")
def use(self, item):
if item.usable and item in self.items:
item.use()
def has_space(self):
return len(self.items) < self.spaces
class Container(store.object):
def __init__(self, allowed=[], allow_all=False, spaces = 4):
self.items = []
self.allowed = allowed
self.allow_all = allow_all
self.spaces = spaces
def add(self, item):
if self.allow_all or item in self.allowed:
self.items.append(item)
return True
else:
return False
def drop(self, item):
if item in self.items:
self.items.remove(item)
print("", "Item dropped!")
else:
print("", "Item can't be dropped!")
def trash(self, item):
if item.trashable and item in self.items:
self.items.remove(item)
print("", "Item dropped!")
else:
print("", "Item can't be dropped!")
def clear_container_found(self, item):
self.items.remove(item)
def has_space(self):
return len(self.items) < self.spaces
def move_item(from_container, to_container, item):
if to_container.add(item):
if not from_container.drop(item):
print("", "Failed to drop [item.name]!")
else:
print("", "Item moved")
else:
if to_container.has_space():
print("", "Failed to add [item.name] for some reason.")
else:
print("", "Failed to add [item.name]: out of space!")
Code: Select all
init python:
items = {
"Null_Item": Item("Null_Item", image="gui/item_icon_tools.png"),
# Quest_Item
"Revolver": Item("Revolver", image="gui/item_icon_weapon_revolver.png", trashable=False, usable=False),
"Tools": Item("Tools", image="gui/item_icon_tools.png", trashable=False, usable=False),
"Ducktape": Item("Ducktape", image="gui/item_icon_ducktape.png", trashable=False, usable=False),
"Towel": Item("Towel", image="gui/item_icon_towel.png", trashable=True, usable=False),
"Soap": Item("Soap", image="gui/item_icon_soap.png", trashable=True, usable=False),
and this
Code: Select all
inventory = Inventory()
container = Container()
container_null = Container([items["Null_Item"]])
inventory_big = Container("Container", allow_all=True)
container1 = Container([items["Ducktape"], items["Tools"]])
container2 = Container([items["Teddybear"]])
container3 = Container([items["Towel"], items["Sponge"], items["Bassin"], items["Soap"]])
container4 = Container([items["Manche"]])
container5 = Container()
container_gift_1 = Container([items["RedApple"]])
container_food = Container([items["FoodRationSmall"], items["FoodRationBig"], items["FoodCan"], items["Rice"]])
container_gaztank = Container([items["Butane"]])
container_generator = Container([items["Gasoline"]])
container_cloth = Container([items["Clothes"], items["SewingKit"], items["Fabric"]])
container_toiletries = Container([items["Clothes"]])
container_alcohol= Container([items["WineCalifornian"], items["WineItalian"], items["WineFrench"]])
container_fillwater = Container([items["WaterBottleEmpty"]])
container_found = Container("Container", allow_all=True)
container_trash = Container("Container", allow_all=True)
# Container space
inventory.spaces = 4
inventory_big.spaces = 14
container_found.spaces = 13
container_food.spaces = 1
container_trash.spaces = 1
And, if, just by curiosity, you are interested about my lame workaround to make it work with the rollback system in order to avoid item duplication, this is the code:
Code: Select all
if not items["Ducktape"] in inventory.items and not items["Ducktape"] in inventory_big.items:
$ inventory.add(items["Ducktape"])
And it's still better than this : $ renpy.block_rollback() double lol