[SOLVED!] Problem with Shop System

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
User avatar
Sterkiherz
Regular
Posts: 67
Joined: Wed Oct 03, 2018 6:16 pm
Projects: Comic: Miraclewish; Visual Novel: A Cursed Traveler's Tale; RPG game: Joseph's Tale; Adventure game: Star fragments.
Tumblr: SterkiHerz
Deviantart: SterkiHerz
itch: sterkiherz
Contact:

[SOLVED!] Problem with Shop System

#1 Post by Sterkiherz » Tue Aug 18, 2020 1:56 pm

Hello!
So I've been working on an Inventory system for my game and I've decided to add a shop to it.
I am using this inventory system provided in here.

And this is what my Inventory code looks like:

Code: Select all

######################CODE############################
init -1 python:
    class Item(object):
        def __init__(self, name, info, cost, wt, damage, amount=0, **kwargs):
            self.name = name
            self.info = info
            self.cost = cost
            self.wt = wt
            self.damage = damage
            self.amount = amount
    #inventory
    class Backpack(object):
        def __init__(self, maxwt, gold, **kwargs):
            self.maxwt = maxwt
            self.space_left = maxwt
            self.mySet = set()
            self.gold = gold

        def add_Item(self, item, found=False):
            #find item
            if item.wt <= self.space_left:
                self.mySet.add(item)
                self.space_left -= item.wt
                item.amount += 1
                return "{0} added to inventory.".format(item.name)
            else:
                if item.wt > self.space_left:
                    return "There is not enough space in your inventory!"
            #buy
        def buy_item(self, item):
            if item.cost <= self.gold and (item.wt <= self.space_left):
                self.gold -= item.cost
                self.mySet.add(item)
                self.space_left -= item.wt
                item.amount += 1
                return "You've successfully bought {0}.".format(item.name)
            else:
                if item.wt > self.space_left:
                    return "There is not enough space in your inventory!"
                elif item.cost > self.gold:
                    return "You don't have enough Money!"
                else:
                    return "There is some problem here."
            #sell
        def sell_Item(self, item):
            if item in self.mySet:
                item.amount -= 1
                self.space_left += item.wt
                if item.amount == 0:
                    self.mySet.remove(item)
                self.gold += item.cost #divide by 2
                return "You've successfully sold {0}.".format(item.name)
            else:
                return "{0} not in inventory!".format(item.name)

        def remove_Item(self, item, sell=False):
            if not sell:
                if item in self.mySet:
                    item.amount -= 1
                    self.space_left += item.wt
                    if item.amount == 0:
                        self.mySet.remove(item)
                    return "{0} removed from inventory.".format(item.name)
                else:
                    return "{0} not in inventory!".format(item.name)
            else:
                if item in self.mySet:
                    item.amount -= 1
                    self.space_left += item.wt
                    if item.amount == 0:
                        self.mySet.remove(item)
                    self.gold += item.cost #divide by 2
                    return "{0} removed from inventory.".format(item.name)
    #shops
    class GShopinv(object):
        def __init__(self, maxwt, gold, **kwargs):
            self.maxwt = maxwt
            self.space_left = maxwt
            self.mySet = set()
            self.gold = gold

        def add_gShopItem(self, item):
            self.mySet.add(item)
            return "New items added to Shops."#.format(item.name)

        def remove_gShopItem(self, item):
            self.mySet.remove(item)
            return "Some Items have been removed from Shops."#.format(item.name)

    class MShopinv(object):
        def __init__(self, maxwt, gold, **kwargs):
            self.maxwt = maxwt
            self.space_left = maxwt
            self.mySet = set()
            self.gold = gold

        def add_mShopItem(self, item):
            self.mySet.add(item)
            return "New items added to Shops."#.format(item.name)

        def remove_mShopItem(self, item):
            self.mySet.remove(item)
            return "Some Items have been removed from Shops."#.format(item.name)

# ------------- Variable declarations ---------------
#BACKPACK & MONEY
default backpack = set()
default myBackpack = Backpack(50, 50)
default money = 50
#SHOPs
default gshop = GShopinv(50,50)
default gshopinv = set()
default mshop = MShopinv(50,50)
default mshopinv = set()

#ITEMS (name, info, cost, wt, damage)
default chocolates = Item("Chocolates", "The best gift for your loved one...unless they don't like chocolate!", 150, 1, 0)
#other items...
This is working perfectly at the moment, but my problem comes when making a working shop system.

This is the screen for my shop:

Code: Select all

screen giftshopbuy():
    tag room
    add "screens/giftshop.png"
    add "screens/shopkeeper.png" xalign 0.0 yalign 0.5 #use transformation to slide to left side**
    use no_quick_menu

    #shop items
    default tt = Tooltip("No item selected.")

    vpgrid:
        cols 5
        spacing 15
        draggable True
        mousewheel True
        ysize 400

        scrollbars "vertical"

        side_xalign 0.76
        side_yalign 0.5

        for item in gshop.mySet:
            textbutton ("[item.name]:\n [item.cost]"):
                xysize (100, 80)
                text_style "buttonz"
                action Confirm("Do you wish to buy this item?", yes=Function(myBackpack.mySet.buy_item, (item)))#**how?

                hovered tt.Action(item.info)

    vbox:
        xalign 0.0
        yalign 0.96
        spacing 10
        #back btn
        use lobby_button("screens/back_%s.png", [Hide("giftshopbuy"), Show("overlay"), Show("tracker"), Show("giftshop")])
        #sell
        textbutton _("Sell Mode") text_style "buttony2" action Show("giftshopsell")

#tooltip
    vbox:
        xalign 0.5
        yalign 0.8
        text tt.value
As you can see, I was trying to display the various shop items as textbuttons and when the user clicks on one a confirm screen shows up asking if they wish to buy the item or not, calling a function to deduct money and store the item into the backpack.

The problem is that I seem to be doing something wrong in there because whenever I enter the shop I get the following error:

Code: Select all

I'm sorry, but an uncaught exception occurred.

While running game code:
  File "game/script.rpy", line 256, in script
    call screen giftshopbuy
  File "renpy/common/000statements.rpy", line 531, in execute_call_screen
    store._return = renpy.call_screen(name, *args, **kwargs)
  File "game/scripts/lobby.rpy", line 123, in execute
    screen giftshopbuy():
  File "game/scripts/lobby.rpy", line 123, in execute
    screen giftshopbuy():
  File "game/scripts/lobby.rpy", line 132, in execute
    vpgrid:
  File "game/scripts/lobby.rpy", line 144, in execute
    for item in gshop.mySet:
  File "game/scripts/lobby.rpy", line 145, in execute
    textbutton ("[item.name]:\n [item.cost]"):
  File "game/scripts/lobby.rpy", line 145, in keywords
    textbutton ("[item.name]:\n [item.cost]"):
AttributeError: 'RevertableSet' object has no attribute 'buy_item'

-- Full Traceback ------------------------------------------------------------

Full traceback:
  File "game/script.rpy", line 256, in script
    call screen giftshopbuy
  File "D:\CIIN\Programas\renpy-7.3.5-sdk.7z\renpy-7.3.5-sdk\renpy\ast.py", line 1949, in execute
    self.call("execute")
  File "D:\CIIN\Programas\renpy-7.3.5-sdk.7z\renpy-7.3.5-sdk\renpy\ast.py", line 1937, in call
    return renpy.statements.call(method, parsed, *args, **kwargs)
  File "D:\CIIN\Programas\renpy-7.3.5-sdk.7z\renpy-7.3.5-sdk\renpy\statements.py", line 277, in call
    return method(parsed, *args, **kwargs)
  File "renpy/common/000statements.rpy", line 531, in execute_call_screen
    store._return = renpy.call_screen(name, *args, **kwargs)
  File "D:\CIIN\Programas\renpy-7.3.5-sdk.7z\renpy-7.3.5-sdk\renpy\exports.py", line 2905, in call_screen
    rv = renpy.ui.interact(mouse="screen", type="screen", roll_forward=roll_forward)
  File "D:\CIIN\Programas\renpy-7.3.5-sdk.7z\renpy-7.3.5-sdk\renpy\ui.py", line 297, in interact
    rv = renpy.game.interface.interact(roll_forward=roll_forward, **kwargs)
  File "D:\CIIN\Programas\renpy-7.3.5-sdk.7z\renpy-7.3.5-sdk\renpy\display\core.py", line 2702, in interact
    repeat, rv = self.interact_core(preloads=preloads, trans_pause=trans_pause, **kwargs)
  File "D:\CIIN\Programas\renpy-7.3.5-sdk.7z\renpy-7.3.5-sdk\renpy\display\core.py", line 3094, in interact_core
    root_widget.visit_all(lambda i : i.per_interact())
  File "D:\CIIN\Programas\renpy-7.3.5-sdk.7z\renpy-7.3.5-sdk\renpy\display\core.py", line 541, in visit_all
    d.visit_all(callback, seen)
  File "D:\CIIN\Programas\renpy-7.3.5-sdk.7z\renpy-7.3.5-sdk\renpy\display\core.py", line 541, in visit_all
    d.visit_all(callback, seen)
  File "D:\CIIN\Programas\renpy-7.3.5-sdk.7z\renpy-7.3.5-sdk\renpy\display\core.py", line 541, in visit_all
    d.visit_all(callback, seen)
  File "D:\CIIN\Programas\renpy-7.3.5-sdk.7z\renpy-7.3.5-sdk\renpy\display\screen.py", line 430, in visit_all
    callback(self)
  File "D:\CIIN\Programas\renpy-7.3.5-sdk.7z\renpy-7.3.5-sdk\renpy\display\core.py", line 3094, in <lambda>
    root_widget.visit_all(lambda i : i.per_interact())
  File "D:\CIIN\Programas\renpy-7.3.5-sdk.7z\renpy-7.3.5-sdk\renpy\display\screen.py", line 440, in per_interact
    self.update()
  File "D:\CIIN\Programas\renpy-7.3.5-sdk.7z\renpy-7.3.5-sdk\renpy\display\screen.py", line 625, in update
    self.screen.function(**self.scope)
  File "game/scripts/lobby.rpy", line 123, in execute
    screen giftshopbuy():
  File "game/scripts/lobby.rpy", line 123, in execute
    screen giftshopbuy():
  File "game/scripts/lobby.rpy", line 132, in execute
    vpgrid:
  File "game/scripts/lobby.rpy", line 144, in execute
    for item in gshop.mySet:
  File "game/scripts/lobby.rpy", line 145, in execute
    textbutton ("[item.name]:\n [item.cost]"):
  File "game/scripts/lobby.rpy", line 145, in keywords
    textbutton ("[item.name]:\n [item.cost]"):
  File "<screen language>", line 148, in <module>
AttributeError: 'RevertableSet' object has no attribute 'buy_item'

Windows-8-6.2.9200
Ren'Py 7.3.5.606
A Cursed Travelers Tale 1.0
Tue Aug 18 14:41:10 2020
For the confirm to buy thing, I've looked at this post. BUT I don't know how to apply this code to my system. Since I am not showing each item manually, but instead I'm using:

Code: Select all

for item in gshop.mySet:
            textbutton ("[item.name]:\n [item.cost]"):
                ...
---

Thank you for reading and have a nice day~
Last edited by Sterkiherz on Tue Aug 18, 2020 8:52 pm, edited 1 time in total.
Image
𝓟𝓸𝓻𝓽𝓯𝓸𝓵𝓲𝓸𝓣𝔀𝓲𝓽𝓽𝓮𝓻 ✦ 𝓓𝓲𝓼𝓬𝓸𝓻𝓭 (sterkiherz#7005) ✦ sterki.herz@gmail.com
~~Feel free to contact me for any questions~~
︵‿︵‿୨♡୧‿︵‿︵
Hugs & Kisses, Sterki Herz

ichfly
Newbie
Posts: 14
Joined: Sat Aug 15, 2020 12:40 pm
Contact:

Re: Problem with Shop System

#2 Post by ichfly » Tue Aug 18, 2020 3:29 pm

you problem is in

Code: Select all

 Confirm("Do you wish to buy this item?", yes=Function(myBackpack.mySet.buy_item, (item)))#**how?
you call the buy_item of the set not the backpack what you want to do is call buy_item of backpack --> myBackpack.buy_item

User avatar
Sterkiherz
Regular
Posts: 67
Joined: Wed Oct 03, 2018 6:16 pm
Projects: Comic: Miraclewish; Visual Novel: A Cursed Traveler's Tale; RPG game: Joseph's Tale; Adventure game: Star fragments.
Tumblr: SterkiHerz
Deviantart: SterkiHerz
itch: sterkiherz
Contact:

Re: Problem with Shop System

#3 Post by Sterkiherz » Tue Aug 18, 2020 4:52 pm

ichfly wrote:
Tue Aug 18, 2020 3:29 pm
you problem is in

Code: Select all

 Confirm("Do you wish to buy this item?", yes=Function(myBackpack.mySet.buy_item, (item)))#**how?
you call the buy_item of the set not the backpack what you want to do is call buy_item of backpack --> myBackpack.buy_item
Hi! Thank you for your reply!
That seemed to have fixed the error but I've realized that when I click the confirm button it takes me back to the game instead of staying on the shop screen.
Also, for some reason it won't take the money and it won't store the item in the backpack :(
Do you have any idea why is it doing this?
Image
𝓟𝓸𝓻𝓽𝓯𝓸𝓵𝓲𝓸𝓣𝔀𝓲𝓽𝓽𝓮𝓻 ✦ 𝓓𝓲𝓼𝓬𝓸𝓻𝓭 (sterkiherz#7005) ✦ sterki.herz@gmail.com
~~Feel free to contact me for any questions~~
︵‿︵‿୨♡୧‿︵‿︵
Hugs & Kisses, Sterki Herz

User avatar
hell_oh_world
Miko-Class Veteran
Posts: 777
Joined: Fri Jul 12, 2019 5:21 am
Projects: The Button Man
Organization: NILA
Github: hell-oh-world
Location: Philippines
Contact:

Re: Problem with Shop System

#4 Post by hell_oh_world » Tue Aug 18, 2020 6:20 pm

The issue might be because of the return statement in the buy Function, i suggest removing those parts and replacing them with something like `store._return = "Return Value"`
Quoting...
If the function returns a non-None value, the interaction stops and returns that value. (When called using the call screen statement, the result is placed in the _return variable.)
Also, kinda makes sense that it goes back to the game as you're returning dialogue like responses when the item is bought so its expected. What do you expect though?
May I also suggest to try this whole inventory thing in the console (shift + o), try using the items' functions etc, to see if all of them are really working.
Last edited by hell_oh_world on Tue Aug 18, 2020 6:33 pm, edited 4 times in total.

ichfly
Newbie
Posts: 14
Joined: Sat Aug 15, 2020 12:40 pm
Contact:

Re: Problem with Shop System

#5 Post by ichfly » Tue Aug 18, 2020 6:25 pm

are you sure you are looking in

Code: Select all

myBackpack.gold
and

Code: Select all

myBackpack.mySet
? because you also have declared

Code: Select all

default money = 50

User avatar
Sterkiherz
Regular
Posts: 67
Joined: Wed Oct 03, 2018 6:16 pm
Projects: Comic: Miraclewish; Visual Novel: A Cursed Traveler's Tale; RPG game: Joseph's Tale; Adventure game: Star fragments.
Tumblr: SterkiHerz
Deviantart: SterkiHerz
itch: sterkiherz
Contact:

Re: Problem with Shop System

#6 Post by Sterkiherz » Tue Aug 18, 2020 8:52 pm

hell_oh_world wrote:
Tue Aug 18, 2020 6:20 pm
The issue might be because of the return statement in the buy Function, i suggest removing those parts and replacing them with something like `store._return = "Return Value"`
Quoting...
If the function returns a non-None value, the interaction stops and returns that value. (When called using the call screen statement, the result is placed in the _return variable.)
Also, kinda makes sense that it goes back to the game as you're returning dialogue like responses when the item is bought so its expected. What do you expect though?
May I also suggest to try this whole inventory thing in the console (shift + o), try using the items' functions etc, to see if all of them are really working.
Thank you so much! You're right about the 'dialog' part! I've changed it to show a message on a screen instead and it works now! I don't know why I didn't think of that before!

Here's what I did to the functions:

Code: Select all

    #buy
        def buy_item(self, item):
            if item.cost <= self.gold and (item.wt <= self.space_left):
                self.gold -= item.cost
                self.mySet.add(item)
                self.space_left -= item.wt
                item.amount += 1
                message = "You've successfully bought the item!"
                renpy.show_screen("purchase_done", message=message)
            else:
                if item.wt > self.space_left:
                    message = "There is not enough space in your inventory!"
                    renpy.show_screen("purchase_done", message=message)
                elif item.cost > self.gold:
                    message = "You don't have enough Money!"
                    renpy.show_screen("purchase_done", message=message)
                else:
                    message = "There is some problem here."
                    renpy.show_screen("purchase_done", message=message)
            #sell
        def sell_Item(self, item):
            if item in self.mySet:
                item.amount -= 1
                self.space_left += item.wt
                if item.amount == 0:
                    self.mySet.remove(item)
                self.gold += item.cost #divide by 2
                message = "You've successfully sold the item!"
                renpy.show_screen("purchase_done", message=message)
            else:
                message = "This item is not in your inventory!"
                renpy.show_screen("purchase_done", message=message)
It would take me back to the shop screen and If I check the backpack the item is in there now and the money is being deducted!
It works now!

--
? because you also have declared
Ah! That was just for testing, guess I forgot to delete that part since I am not using it n.n
But thank you for pointing out my first mistake!

Thank you both so much! :D
Image
𝓟𝓸𝓻𝓽𝓯𝓸𝓵𝓲𝓸𝓣𝔀𝓲𝓽𝓽𝓮𝓻 ✦ 𝓓𝓲𝓼𝓬𝓸𝓻𝓭 (sterkiherz#7005) ✦ sterki.herz@gmail.com
~~Feel free to contact me for any questions~~
︵‿︵‿୨♡୧‿︵‿︵
Hugs & Kisses, Sterki Herz

Post Reply

Who is online

Users browsing this forum: Bing [Bot]