How to disable menu choices while keeping them visible to the player

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
mehve
Newbie
Posts: 2
Joined: Wed Aug 02, 2017 6:22 am
Contact:

How to disable menu choices while keeping them visible to the player

#1 Post by mehve »

I'm looking for a way to show a disabled menu choice to the player. The player sees the choice in the menu but is unable to select it. Ideally, I want to have a visual cue that the choice is intentionally disabled, such as the menu item being faded or a different color.

Example 1:

Code: Select all

label test:
    "I run down the alleyway but come to a dead end.  What should I do?"
    menu:
        "Turn around":
            jump turn_around_in_alley
        "Grow wings and fly away":
            # This menu choice is impossible.
            # The player should see this choice in the menu but be unable to click on it.
    return
I'd also like this to be triggered by a Boolean variable so that some of these disabled menu choices will be available only if a player has completed certain actions earlier in the game. The closest example I've found to this in the documentation is Menu Choices https://www.renpy.org/doc/html/menus.html# but this doesn't give me exactly what I want because it hides the menu option completely.

Example 2:

Code: Select all

label test:
    $ has_wings = False
    "I'm walking down the street.  I come to a stop sign."
    menu:
        "Turn left":
            jump go_left
        "Grow wings and fly away" if has_wings:
            # This menu choice disappears completely if has_wings is False, which isn't what I want. 
    return
Has anyone done this before in Ren'Py and could offer some advice? I haven't come across any code like this in the forums or elsewhere. Is there a simple way to do this using the Ren'Py library that I just haven't figured out yet or am I going to have to do something a bit more complicated?

User avatar
Scribbles
Miko-Class Veteran
Posts: 636
Joined: Wed Sep 21, 2016 4:15 pm
Completed: Pinewood Island, As We Know It
Projects: In Blood
Organization: Jaime Scribbles Games
Deviantart: breakfastdoodles
itch: scribbles
Location: Ohio
Contact:

Re: How to disable menu choices while keeping them visible to the player

#2 Post by Scribbles »

hmmm, you could create a loop so that when the player clicks on it, it just takes them back to the menu so

Code: Select all


label test:
    "I'm walking down the street ..."

label choice:
    menu:
        "turn left":
            jump go_left
         "Grow wings":
            jump choice
it might seem like the player clicks on it and nothing happens, but I haven't tested it so I'm not sure. Hopefully that helps!
Image - Image -Image

User avatar
trooper6
Lemma-Class Veteran
Posts: 3712
Joined: Sat Jul 09, 2011 10:33 pm
Projects: A Close Shave
Location: Medford, MA
Contact:

Re: How to disable menu choices while keeping them visible to the player

#3 Post by trooper6 »

I bit of searching would help you answer that question:
viewtopic.php?f=8&t=25453&p=313338
A Close Shave:
*Last Thing Done (Aug 17): Finished coding emotions and camera for 4/10 main labels.
*Currently Doing: Coding of emotions and camera for the labels--On 5/10
*First Next thing to do: Code in all CG and special animation stuff
*Next Next thing to do: Set up film animation
*Other Thing to Do: Do SFX and Score (maybe think about eye blinks?)
Check out My Clock Cookbook Recipe: http://lemmasoft.renai.us/forums/viewto ... 51&t=21978

User avatar
carrot
Regular
Posts: 28
Joined: Fri Jul 28, 2017 7:43 am
Contact:

Re: How to disable menu choices while keeping them visible to the player

#4 Post by carrot »

This is kind of a hack and it's definitely a monkeypatch, but in combination with the stuff in the link in the previous post, you can put this into an init python block and it'll automatically disable the choices without you having to put "(disabled)" in the text, and you won't have to double up the choices.

Code: Select all

init -1 python:
    # we use display.get_info() because it persists between reloads so we don't end up with an endless loop
    if getattr(renpy.display.get_info(), 'oldmenu', None) is None:
        renpy.display.get_info().oldmenu = renpy.exports.menu

    # append " (disabled)" to any choices that fail their conditions
    # while also pretending that they've all succeeded and calling the built-in menu
    def menu_override(items, set_expr):
        items = [ (renpy.exports.substitute(label) + (" (disabled)" if not renpy.python.py_eval(condition) else ""), "True", value)
                  for label, condition, value in items ]

        return renpy.display.get_info().oldmenu(items, set_expr)

    # intercept the built-in menu
    renpy.exports.menu = menu_override
And for the sake of completion, in screens.rpy, replace:

Code: Select all

screen choice(items):
    style_prefix "choice"

    vbox:
        for i in items:
            textbutton i.caption action i.action
with (edited from the other post, which was from a while ago):

Code: Select all

screen choice:
    style_prefix "choice"

    vbox:
        for i in items:
            if i.action:
                if " (disabled)" in i.caption:
                    textbutton i.caption.replace(" (disabled)", "")
                else:
                    textbutton i.caption action i.action
            else:
                textbutton i.caption
So now you can define your menu just like any other:

Code: Select all

menu:
    "1":
        "sdfjhsjfhsdjd"

    "2":
        "sdjfhjsdhfjhsjdhfs"

    "3" if False: # this will be unclickable ingame
        "sfdjhsjhfhjsdj"
You'll still need to style it to grey it out, but the mechanics of it are all there.

mikolajspy
Regular
Posts: 169
Joined: Sun Jun 04, 2017 12:05 pm
Completed: Too many, check signature
Deviantart: mikolajspy
Location: Wrocław, Poland
Contact:

Re: How to disable menu choices while keeping them visible to the player

#5 Post by mikolajspy »

I would do something rather simple, like:

Code: Select all

label test:
    $ has_wings = False
    "I'm walking down the street.  I come to a stop sign."
    menu can_use_option:
        "Turn left":
            jump go_left
        "Grow wings and fly away" if has_wings:
            jump label_what_happens_if_player_has_wings #proceed with story in this branch.
            # This menu choice disappears completely if has_wings is False
        "{s}   Grow wings and fly away   {/s}" if has_wings = False:   #{s}...{/s} for striketrough, visible, yet crossed out, you can also change text color.
            jump can_use_option #clicking gets back to menu, so player thinks nothing happened.
            # This menu choice disappears completely if has_wings is True.
    return

User avatar
carrot
Regular
Posts: 28
Joined: Fri Jul 28, 2017 7:43 am
Contact:

Re: How to disable menu choices while keeping them visible to the player

#6 Post by carrot »

Yep that works too. If you've just got the one menu section, it's definitely more straightforward.

If you end up with a lot of disabled options throughout your game, though, it could be easier in the long run to change the menu behaviour.

Totally depends on the project. At the very least, you've got lots of methods to choose from now.

User avatar
mehve
Newbie
Posts: 2
Joined: Wed Aug 02, 2017 6:22 am
Contact:

Re: How to disable menu choices while keeping them visible to the player

#7 Post by mehve »

Thanks everyone for the advice and links, this was all extremely helpful. After playing around with these examples and reading through jw2pfd's cookbook post, I think I can move forward with using this in my project. And I've got a much better grasp on using screens in general. Thanks again!

User avatar
MadeVeryMerry
Newbie
Posts: 12
Joined: Wed Nov 11, 2015 12:52 am
Contact:

Re: How to disable menu choices while keeping them visible to the player

#8 Post by MadeVeryMerry »

Sorry to resurrect this post, but I'm playing with this code in a Clue-like minigame and I want to be able to make conditions false as the player discovers clues. I'm still pretty new to Ren'Py so I don't know how I would set menu options as unclickable without doubling up.

This is the code (using strikethrough/menu loops) that I'm dealing with right now.

Code: Select all

menu room_choice:
    "Where was he killed?"
    
    "The ballroom":
        "The dance floor was stained with blood!"
        
    "The study":
        "The books will never be the same!"
        
    "The conservatory" if conservatory == True:
        "Those plants have tasted blood!"
        $conservatory = False
        
    "{s}The conservatory{/s}" if conservatory == False:
        "No, I already know it can't be the conservatory."
        jump room_choice
I want to incorporate the screen method so I don't have to double up the choices, but am unsure how to give conditions to choices without doing so.

ETA: I'm using the conservatory as a test subject right now, so the ballroom and the study don't currently have "false" options.

User avatar
mitoky
Veteran
Posts: 316
Joined: Sat Feb 07, 2015 9:12 pm
Projects: The Purring Demon's Love, circus eterie
Contact:

Re: How to disable menu choices while keeping them visible to the player

#9 Post by mitoky »

MadeVeryMerry wrote: Wed Nov 08, 2017 11:45 am Sorry to resurrect this post, but I'm playing with this code in a Clue-like minigame and I want to be able to make conditions false as the player discovers clues. I'm still pretty new to Ren'Py so I don't know how I would set menu options as unclickable without doubling up.

This is the code (using strikethrough/menu loops) that I'm dealing with right now.

Code: Select all

menu room_choice:
    "Where was he killed?"
    
    "The ballroom":
        "The dance floor was stained with blood!"
        
    "The study":
        "The books will never be the same!"
        
    "The conservatory" if conservatory == True:
        "Those plants have tasted blood!"
        $conservatory = False
        
    "{s}The conservatory{/s}" if conservatory == False:
        "No, I already know it can't be the conservatory."
        jump room_choice
I want to incorporate the screen method so I don't have to double up the choices, but am unsure how to give conditions to choices without doing so.

ETA: I'm using the conservatory as a test subject right now, so the ballroom and the study don't currently have "false" options.

Code: Select all

[code]menu room_choice:
    "Where was he killed?"
    
    "The ballroom":
        "The dance floor was stained with blood!"
        
    "The study":
        "The books will never be the same!"
        
    "The conservatory":
        if conservatory:
            "Those plants have tasted blood!"
            $ conservatory = False
        else:
            "No, I already know it can't be the conservatory."
            jump room_choice
If conversatory is "False" before this menu appears, just change "if" into "if not" and "False" into "True"

User avatar
MadeVeryMerry
Newbie
Posts: 12
Joined: Wed Nov 11, 2015 12:52 am
Contact:

Re: How to disable menu choices while keeping them visible to the player

#10 Post by MadeVeryMerry »

That would still essentially "double up" my choices, though. Is there no way to avoid that? I'm trying to use the method described in the post above:
carrot wrote: Wed Aug 02, 2017 1:40 pm This is kind of a hack and it's definitely a monkeypatch, but in combination with the stuff in the link in the previous post, you can put this into an init python block and it'll automatically disable the choices without you having to put "(disabled)" in the text, and you won't have to double up the choices.

Code: Select all

init -1 python:
    # we use display.get_info() because it persists between reloads so we don't end up with an endless loop
    if getattr(renpy.display.get_info(), 'oldmenu', None) is None:
        renpy.display.get_info().oldmenu = renpy.exports.menu

    # append " (disabled)" to any choices that fail their conditions
    # while also pretending that they've all succeeded and calling the built-in menu
    def menu_override(items, set_expr):
        items = [ (renpy.exports.substitute(label) + (" (disabled)" if not renpy.python.py_eval(condition) else ""), "True", value)
                  for label, condition, value in items ]

        return renpy.display.get_info().oldmenu(items, set_expr)

    # intercept the built-in menu
    renpy.exports.menu = menu_override
And for the sake of completion, in screens.rpy, replace:

Code: Select all

screen choice(items):
    style_prefix "choice"

    vbox:
        for i in items:
            textbutton i.caption action i.action
with (edited from the other post, which was from a while ago):

Code: Select all

screen choice:
    style_prefix "choice"

    vbox:
        for i in items:
            if i.action:
                if " (disabled)" in i.caption:
                    textbutton i.caption.replace(" (disabled)", "")
                else:
                    textbutton i.caption action i.action
            else:
                textbutton i.caption
So now you can define your menu just like any other:

Code: Select all

menu:
    "1":
        "sdfjhsjfhsdjd"

    "2":
        "sdjfhjsdhfjhsjdhfs"

    "3" if False: # this will be unclickable ingame
        "sfdjhsjhfhjsdj"
You'll still need to style it to grey it out, but the mechanics of it are all there.
The "no, I already know" screens are more or less placeholders and I don't want them to be in the final game. In the example above, option 3 is set as False, and I want to know if it's possible for me to have 3 clickable, set 3 as false, and then have it unclickable when it loops around again. I'm probably misunderstanding something fundamental about Python because I'm not very good at learning the basics first. :oops:

Post Reply

Who is online

Users browsing this forum: Ahrefs [Bot], Bing [Bot]