Textbuttons with conditions with key values

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
wyverngem
Miko-Class Veteran
Posts: 615
Joined: Mon Oct 03, 2011 7:27 pm
Completed: Simple as Snow, Lady Luck's Due,
Projects: Aether Skies, Of the Waterfall
Tumblr: casting-dreams
itch: castingdreams
Location: USA
Contact:

Textbuttons with conditions with key values

#1 Post by wyverngem »

I'm working on making my game more accessible for my brother. He uses self-voicing to read the screens of the game. I'm working on a project that has a main menu that has a list of textbuttons in a hbox which displays different tasks. However, menu items disappear when they do not meet the conditions. How can I code the buttons to key with the appropriate number?

Update: Figure out how to do everything except for making a list of conditions that must be met for the button to show. Specifically for True/False and int values. I don't use strings, but could.

Could I use a function perhaps?


-----------------------
I'm thinking this is a challenge for those with more experience in coding. My initial thought was to create a Python Class that can be access with for loop on a screen. It would create the buttons only if the conditions of the buttons were met, and assign them appropriate number key value. Is this possible? Anyone have an idea of what it might look like?

This is my typical button:

Code: Select all

            if settime.now in range (5,17): #settime.now is a python class that determines the time of day. The conditional determines if the time is right to have the button..
                textbutton "Rest":# I use a textbutton so the self-voicing can do it's job.
                    idle_background "gui/task/sleep_idle.png" #A pretty image Custom to each button that is the background
                    hover_background "gui/task/sleep_hover.png" # A pretty image custom to each button that is the hover_background
                    action Jump("rest") # The act or action that the button takes.
However, it gets more complicated:

Code: Select all

            if potion_recipes != []: #Conditions checks to see if you have any recipes in your cook book. No time restraints.
                textbutton "Cookbook":
                    idle_background "gui/task/grimoire_idle.png"
                    hover_background "gui/task/grimoire_hover.png"
                    action Jump("craft_recipe")
Another example.

Code: Select all

            if unlocked_clinic == True and settime.now in range(6,18): #Checks the time and if the clinic is unlocked.
                frame:
                    textbutton "Clinic" action Jump("clinic")
The most complicated act is this one: It uses the day, if it's unlocked, the time, and if you've gone to the store.

Code: Select all

            if day == 21 or day == 7:
                if unlocked_market:
                    if settime.now > 5 and settime.now < 15:
                        if WentMarketSell == False:
                            textbutton "Market":
                                idle_background "gui/task/market_idle.png"
                                hover_background "gui/task/market_hover.png"
                                action Jump("market")
The second issue is that the screen uses a variable to determine what sub-menu the player is on. I based it off of the Help screen with the variable. I'm thinking my class would have to have the following values:

name = name
conditions = conditions
act = act
page = page

I think I can get away with the idle_background and hover_backgrounds if I use something like this:

Code: Select all

hover_background "gui/task/[item.name]_hover.png"
When I define the for loop, and can just simple check if the button should appear on the current page.

Am I on the right track? I'd figure I put them into a list when I create the buttons. They'd all be created at the beginning of the game behind the scenes. I'm just curious if Ren'py would know what to do with the information if I wrote it something like this:

Code: Select all

    for buttons in main_menu_list:
        textbutton buttons.name:
            idle_background "gui/task/[buttons.name].png"
            hover_background "gui/task/[buttons.name].png"
        key str(i) action buttons.act
        key "K_KP" + str(i) action buttons.act
        
    for n, i in enumerate(items, 1): # n would be the number starting from 1
        if n<10:
            key "K_KP" + str(n) action i.action
            key str(n) action i.action
This is all guesswork, as the only thing I truly have is the screen menu coded to work in the screen language way. Not sure if looking at the choice screen would help me figure it out. Since I know you can pass conditions in there too. Any ideas is much appreciated. Thanks for reading.
Last edited by wyverngem on Sun Feb 24, 2019 7:45 pm, edited 1 time in total.

User avatar
wyverngem
Miko-Class Veteran
Posts: 615
Joined: Mon Oct 03, 2011 7:27 pm
Completed: Simple as Snow, Lady Luck's Due,
Projects: Aether Skies, Of the Waterfall
Tumblr: casting-dreams
itch: castingdreams
Location: USA
Contact:

Re: Textbuttons with conditions with key values

#2 Post by wyverngem »

So I figure out how to do everything except put in conditions. How do a set of conditions that must be passed for the buttons to show?

Code: Select all

init python:
    import renpy.store as store
    main_buttons = list()
    class Task(store.object):
        def __init__(self, name, act=Jump('dayplanner'), page='base'):
            global task_buttons
            self.name = name
            self.act = act # screen action
            self.page = page
            #self.condition = condition #Haven't figure this out.

            main_buttons.append(self)
    # Things to Do in the Studio
    button_craft = Task('studio', SetVariable('page', 'craft'))
    button_crafting = Task('craft', Jump('craft'), page='craft')
    button_craft_grimoire = Task('grimoire', Jump('craft_grimoire'), page='craft')
    button_craft_bulk = Task('bulk', Jump('craft_bulk'), page='craft')
    button_craft_home = Task('home', SetVariable('page', 'base'), 'craft')
    # Places to Explore
    button_explore = Task('explore', SetVariable('page', 'explore'))
    button_explore_ocean = Task('ocean', Jump('explore_ocean'), page='explore')
    button_explore_forest = Task('forest', Jump('explore_forest'), page='explore')
    button_explore_town = Task('town', Jump('explore_town'), page='explore')
    button_explore_home = Task('home', SetVariable('page', 'base'), 'explore')
    # Places in Town
    button_town = Task('town', SetVariable('page', 'town'))
    button_town_pub = Task('pub', Jump('town_pub'), page='town')
    button_town_market = Task('market', Jump('town_market'), page='town')
    button_town_stall = Task('stall', Jump('town_stall'), page='town')
    button_town_clinc = Task('clinic', Jump('town_clinic'), page='town')
    button_town_home = Task('home', SetVariable('page', 'base'), 'town')
    # Home Events
    button_rest = Task('rest', Jump('rest'))
    button_sleep = Task('sleep', Jump('setNight'))

default page = 'base'

# The main menu screen.
screen tasks:
    $ assignKey = 0
    style_group "mmtasks"
    text "What should I do now?"
    hbox:
        for b in main_buttons:
            if b.page == page:
                $ name = str(b.name)
                $ assignKey = (assignKey + 1)
                button:
                    text str(assignKey) + ") " + name.title()
                    #idle_background "gui/mm/"+ b.name +"room_idle.jpg" #Commented out for testing without images.
                    #hover_background "gui/mm/"+ b.name +"room_hover.jpg" #Commented out for testing without images.
                    action b.act
    $ assignKey = 0
    for b in main_buttons:
        if b.page == page:
            $ assignKey = (assignKey + 1)
            key str(assignKey) action b.act
            key "K_KP" + str(assignKey) action b.act

style mmtasks_button:
    xsize 100
    ysize 200

style mmtasks_button_text:
    xalign 0.5
    yalign 0.5

style mmtasks_hbox:
    xalign 0.5
    yalign 0.5

#Variables not needed in game.
define e = Character("Eileen")
image silver = Solid("#C0C0C0")

# The game starts here.
label start:
    $ quick_menu = False
    scene black with dissolve
    e "You've created a new Ren'Py game."
    e "Once you add a story, pictures, and music, you can release it to the world!"

label dayplanner:
    "This is your dayplanner."
    call screen tasks with dissolve
return

# Menu Pages: Crafting
label craft:
    "Crafting"
    jump dayplanner
label craft_grimoire:
    "Grimoire"
    jump dayplanner
label craft_bulk:
    "Bulk"
    jump dayplanner
# Menu Pages: Explore
label explore_ocean:
    "Ocean"
    jump dayplanner
label explore_forest:
    "Forest"
    jump dayplanner
label explore_town:
    "Town"
    jump dayplanner
# Menu Pages: Town
label town_pub:
    "Pub"
    jump dayplanner
label town_stall:
    "Stall"
    jump dayplanner
label town_market:
    "Market"
    jump dayplanner
label town_clinic:
    "Clinic"
    jump dayplanner
#Leaves the demo.
label setNight:
    "End of game."
    return

philat
Eileen-Class Veteran
Posts: 1910
Joined: Wed Dec 04, 2013 12:33 pm
Contact:

Re: Textbuttons with conditions with key values

#3 Post by philat »

Code: Select all

init python:
    import renpy.store as store
    main_buttons = list()
    class Task(store.object):
        def __init__(self, name, act=Jump('dayplanner'), page='base', condition="True"):
            global task_buttons
            self.name = name
            self.act = act # screen action
            self.page = page
            self.condition = condition

            main_buttons.append(self)
    # Things to Do in the Studio
    button_craft = Task('studio', SetVariable('page', 'craft'))
    button_crafting = Task('craft', Jump('craft'), page='craft')
    button_craft_grimoire = Task('grimoire', Jump('craft_grimoire'), page='craft', condition="False") # arbitrary test case
    button_craft_bulk = Task('bulk', Jump('craft_bulk'), page='craft')
    button_craft_home = Task('home', SetVariable('page', 'base'), 'craft')
    # Places to Explore
    button_explore = Task('explore', SetVariable('page', 'explore'))
    button_explore_ocean = Task('ocean', Jump('explore_ocean'), page='explore')
    button_explore_forest = Task('forest', Jump('explore_forest'), page='explore')
    button_explore_town = Task('town', Jump('explore_town'), page='explore')
    button_explore_home = Task('home', SetVariable('page', 'base'), 'explore')
    # Places in Town
    button_town = Task('town', SetVariable('page', 'town'))
    button_town_pub = Task('pub', Jump('town_pub'), page='town')
    button_town_market = Task('market', Jump('town_market'), page='town')
    button_town_stall = Task('stall', Jump('town_stall'), page='town')
    button_town_clinc = Task('clinic', Jump('town_clinic'), page='town')
    button_town_home = Task('home', SetVariable('page', 'base'), 'town')
    # Home Events
    button_rest = Task('rest', Jump('rest'))
    button_sleep = Task('sleep', Jump('setNight'))

default page = 'base'

# The main menu screen.
screen tasks:
    default buttons = [b for b in main_buttons if b.page==page and eval(b.condition)]
    style_group "mmtasks"
    text "What should I do now?"
    hbox:
        $ buttons = [b for b in main_buttons if b.page==page and eval(b.condition)]
        for i, b in enumerate(buttons):
            button:
                text str(i+1) +") " + b.name.title():
                action b.act
            key str(i+1) action b.act
            key "K_KP" + str(i+1) action b.act 
Something baaaasically along the lines of the above. I haven't tested, but I would imagine you don't want to keep all of that in init python though, due to save/load concerns.

User avatar
wyverngem
Miko-Class Veteran
Posts: 615
Joined: Mon Oct 03, 2011 7:27 pm
Completed: Simple as Snow, Lady Luck's Due,
Projects: Aether Skies, Of the Waterfall
Tumblr: casting-dreams
itch: castingdreams
Location: USA
Contact:

Re: Textbuttons with conditions & key values [solved]

#4 Post by wyverngem »

I tried your way initially, before I realized once defined it couldn't change or read, even with functions. So I ended up doing it another way. It does look interesting though. I want to look how to do your buttons instead of mine.
I ended up creating a Python Function that reads the name of the event and returns true if the conditions are met. Ended up working pretty nicely as I didn't have to write if statements for each and every line. My screen ended up looking like this.

Code: Select all

screen tasks:
    $ assignKey = 0
    style_group "mmtasks"
    hbox:
        for b in main_buttons:
            if b.taskpage == taskpage:
                if check(b.name):
                    $ name = str(b.name)
                    $ assignKey = (assignKey + 1)
                    button:
                        text str(assignKey) + ") " + name.title()
                        idle_background "gui/mm/"+ b.name +"_idle.png"
                        hover_background "gui/mm/"+ b.name +"_hover.png"
                        action b.act
    $ assignKey = 0
    for b in main_buttons:
        if b.taskpage == taskpage:
            if check(b.name):
                $ assignKey = (assignKey + 1)
                if assignKey < 10:
                    key str(assignKey) action b.act
                    key "K_KP" + str(assignKey) action b.act
I had to still define the conditions, but it worked out nicely.

Code: Select all

    def check(name):
        global settime
        global unlocked_market
        global day
        # The categories show only until midnight.
        if name == "workshop" or name == "explore" or name == "visit" or name == "town":
            if settime.now in range(5,24):
                return True
        elif name == "market":
            if day == 21 or day == 7:
                if unlocked_market:
                    if settime.now > 5 and settime.now < 15:
                        if WentMarketSell == False:
                            return True
         #foo

Post Reply

Who is online

Users browsing this forum: fufuffiero, Sugar_and_rice