Ren'Py Rightclick game_menu disable

Playstorepers

Member
May 24, 2020
160
79
Hey there everyone,

I already asked about this problem in another thread, but the headline was a completely different one and I decided instead of bumping it, to start a new thread with the correct headline.

I have a screen with are cards, that you can rightclick.
But if you rightclick right next to the card, you're opening up the game menu.
I want to deactivate that feature, while still allowing the player enter the game menu via the escape button (It's only a minor inconvenience, but an inconvenience nonetheless)

Here's what I tried so far with all the corresponding problems.

The problem in detail:
1) $ config.keymap['game_menu'].remove('mouseup_3')
Would be the perfect solution, however it only works in the init. I can't change it in-game.

2) $_game_menu_screen = None doesn't work, cuz it also disables the esc button to open up the menu - User should be able to save during the cardgame -> Probably not an option for me

3) create a screen with key ("mouseup_3") action NullAction(): Disallows rightclick on the cards -> Probably not an option

4) create a zorder -20 screen with a transparent fullscreen imagebutton and alternate NullAction(), doesn't work either, because the cards aren't considered a screen, so the fullscreen transparent imagebutton will stop all rightclicks and even all leftclicks on the cards (because you are technically clicking on the imagebutton).

5) remove the original rightclick with
$ config.keymap['game_menu'].remove('mouseup_3') in the init
and then create a screen with:
key ("mouseup_3") action ShowMenu('save')
works fine, until I realized, that the ShowMenu('save') isn't the equivalent for game_menu.
Before, using the rightclick also closed all modal screens, which was really handy for the player.

TLDR: Two questions to everyone here:
1) What's the correct action for key ("mouseup_3") action to simulate the original game_menu action, so it also closes the modal screens.
or even better:
2) How would any of you implement, the rightclick disable?

Thank you all in advance and sorry, if I'm bothering you with my walls of text and stupid questions.
 
Last edited:

Rich

Old Fart
Modder
Donor
Respected User
Game Developer
Jun 25, 2017
2,566
7,382
So, you didn't indicate how you implemented the right-click processing on the cards, and this may be stupid, but what about, on the screen that has the cards, putting yet another image behind the cards (even a transparent or nearly-transparent one) filling the entire screen that implements right-click in exactly the same manner as the cards, but just does nothing when a right-click happens?
 

Playstorepers

Member
May 24, 2020
160
79
So, you didn't indicate how you implemented the right-click processing on the cards, and this may be stupid, but what about, on the screen that has the cards, putting yet another image behind the cards (even a transparent or nearly-transparent one) filling the entire screen that implements right-click in exactly the same manner as the cards, but just does nothing when a right-click happens?
Thank you for your answer and you're right: I should've provided the cardimplementation to the thread.
The problem is, that the cards are not in a screen so to say, they're in an object and my python is not good enough to get a full grasp.


I used the framework, that was provided by renpytom: .

The code, that I'm talking about is the class Klondike(object): part:

Python:
init python:

    class Klondike(object):

        # We represent a card as a (suit, rank) tuple. The suit is one of the
        # following four constants, while the rank is 1 for ace, 2 for 2,
        # ..., 10 for 10, 11 for jack, 12 for queen, 13 for king.
        CLUB = 0
        SPADE = 1
        HEART = 2
        DIAMOND = 3

        def __init__(self, deal=3):

            # Constants that let us easily change where the game is
            # located.
            LEFT=140
            TOP=58
            COL_SPACING = 90
            ROW_SPACING = 120
            CARD_XSPACING = 20
            CARD_YSPACING = 30

            # Store the parameters.
            self.deal = deal
          
            [...........................]


But you gave me a good idea. I will edit my table to have another cardstack, that's so big, that it will cover the entire screen.

Hope it works and thanks for the suggestion.

EDIT: Well, shit. That doesn't work.

If I add another card pile with

self.blockrightclickstock = t.stack(LEFT + COL_SPACING, TOP, xoff=CARD_XSPACING, drag=False, show=self.deal, click=False)

and then append the transparent fullscreencard, it should shutdown all interaction. But if you now click on the fullscreen card, despite disallowing all interactions, it still first "grabs the card to the top", which will then cover all other stacks.
 
Last edited:

anne O'nymous

I'm not grumpy, I'm just coded that way.
Modder
Donor
Respected User
Jun 10, 2017
10,971
16,229
3) create a screen with key ("mouseup_3") action NullAction(): Disallows rightclick on the cards -> Probably not an option
Why it isn't an option ?

As for Rich answer, it's the correct one and have it no reason to not works:
Code:
screen whateve():
    imagebutton:
        idle Solid( "#00000000" )
        xpos 0 ypos 0
        xsize config.screen_width
        ysize config.screen_height
        action NullAction()
        alternate NullAction()

    add Klondike()
But anyway, as I said in your other thread, the correct answer to all your problems is to directly use Ren'py screen language in place of this custom displayable ; I even linked the different parts of the doc that you need to achieve this.
You probably would have needed less time to build it, than you've already lost trying to deal with the right click issue.
 

Playstorepers

Member
May 24, 2020
160
79
Why it isn't an option ?

As for Rich answer, it's the correct one and have it no reason to not works:
Code:
screen whateve():
    imagebutton:
        idle Solid( "#00000000" )
        xpos 0 ypos 0
        xsize config.screen_width
        ysize config.screen_height
        action NullAction()
        alternate NullAction()

    add Klondike()
But anyway, as I said in your other thread, the correct answer to all your problems is to directly use Ren'py screen language in place of this custom displayable ; I even linked the different parts of the doc that you need to achieve this.
You probably would have needed less time to build it, than you've already lost trying to deal with the right click issue.
Thank you again for your answer.

It's not an option, because the rightclick becomes outright inaccessible with this implementation. And it therefore means, that you can't rightclick on the cards.


As for Rich's idea: it was a very good one, but the problem is, that Klondike isn't a displayable, which as we already established, emphasizes your point:
I should rewrite the entire cardgame, so I can understand it completely, since the drag and drops have less to do with python.

I just tried to circumvent it, since I did everything 5 months ago and I didn't want to go over thousand lines of code just to implement it differently. The cardgame was completed and changing everything, just to solve a problem, which seems so easy on the surface (The rightclick issue), was work, that I thought, I could save myself. But there is no argument here from me, that you're right in that regard.

And to elaborate on the problem with:

Code:
screen whateve():
    imagebutton:
        idle Solid( "#00000000" )
        xpos 0 ypos 0
        xsize config.screen_width
        ysize config.screen_height
        action NullAction()
        alternate NullAction()

    add Klondike()
you can't add klondike, since the table (called Klondike) in the cardgame-blueprint doesn't seem to be a displayable. I attempted it, but failed miserably with a error message, that klondike isn't a displayable.

I also tried using another cardback (Transparent big button), another base for the stack (Also transparent and big), but those also don't work, since those will cover the entire table, once clicked.

I'm going to sit on this problem for one week or two and if I can't come up with something, I'm going to rewrite everything.

I thank you both for your input. It was helpful and insightful to say the least.

EDIT:

Just to be sure:
Is there really no action, that emulates the normal game_menu rightclick, which includes closing all modal screens?
Something like: action "game_menu" for a button or something like that.

Or: is it possible to assign an extra (!) command to a keyclick.
something like: key ("mouseup_3") action SetVariable(killswithgamemenu, True), while STILL allowing access to the save menu, which then terminates after opening up, because of that boolean.
The problem is, that if i use the key("mouseup_3"), it overwrites all other rightclicks (as it should, yeah). But is there a method to do it in addition to the normal click?

And I do understand, that rewriting everything in a more familiar environment would be the best... I really do.
But in theory, at least, it's such a small issue, right?

I just want this:
$ config.keymap['game_menu'].remove('mouseup_3')
to work outside of the init-block
 
Last edited:

anne O'nymous

I'm not grumpy, I'm just coded that way.
Modder
Donor
Respected User
Jun 10, 2017
10,971
16,229
As for Rich's idea: it was a very good one, but the problem is, that Klondike isn't a displayable, [...]
Oh, yes, I remember now, it's the embedded Table that is the displayable.
Hmm... It's just a guess, but something like this should works :

Firstly, you edit table.rpy to change its show method:
Code:
[...]
       def show(self ):
            for v in self.cards.itervalues():
                v.offset = __Fixed(0, 0)

       def hide( self ):
           pass

       def  set_sensitive(self, value): 
[...]
then you use the Klondike object that way:
Code:
default cardGame =  Klondike(1)

label whatever:
    python:
        cardGame.set_sensitive(False) 
        cardGame.show()

    call screen cardGame
    "End"

screen cardGame():
    imagebutton:
        idle Solid( "#00000000" )
        xpos 0 ypos 0
        xsize config.screen_width
        ysize config.screen_height
        action NullAction()
        alternate NullAction()

    add cardGame.table
It's not better than writing it in Ren'py screen language, but it should permit you to use the background to catch the right click.

Else at worse there's ui.imagebutton() but I really don't recommend that.



Just to be sure:
Is there really no action, that emulates the normal game_menu rightclick, which includes closing all modal screens?
Something like: action "game_menu" for a button or something like that.
Not in the way you see it.


And I do understand, that rewriting everything in a more familiar environment would be the best... I really do.
But in theory, at least, it's such a small issue, right?

I just want this:
$ config.keymap['game_menu'].remove('mouseup_3')
to work outside of the init-block
It's a small issue, but solving it imply really dirty works. You need to go deep into Ren'py internal, update a list, mimic some behavior and reset something. With every single elements that can change at anytime with a new version of Ren'py, this without this change being notified somewhere since you shouldn't even know that they exist.
 
  • Like
Reactions: Playstorepers

Playstorepers

Member
May 24, 2020
160
79
Oh, yes, I remember now, it's the embedded Table that is the displayable.
Hmm... It's just a guess, but something like this should works :

Firstly, you edit table.rpy to change its show method:
Code:
[...]
       def show(self ):
            for v in self.cards.itervalues():
                v.offset = __Fixed(0, 0)

       def hide( self ):
           pass

       def  set_sensitive(self, value):
[...]
then you use the Klondike object that way:
Code:
default cardGame =  Klondike(1)

label whatever:
    python:
        cardGame.set_sensitive(False)
        cardGame.show()

    call screen cardGame
    "End"

screen cardGame():
    imagebutton:
        idle Solid( "#00000000" )
        xpos 0 ypos 0
        xsize config.screen_width
        ysize config.screen_height
        action NullAction()
        alternate NullAction()

    add cardGame.table
It's not better than writing it in Ren'py screen language, but it should permit you to use the background to catch the right click.

Else at worse there's ui.imagebutton() but I really don't recommend that.





Not in the way you see it.




It's a small issue, but solving it imply really dirty works. You need to go deep into Ren'py internal, update a list, mimic some behavior and reset something. With every single elements that can change at anytime with a new version of Ren'py, this without this change being notified somewhere since you shouldn't even know that they exist.
Thank you for sticking with me through this problem.

And your basic idea might work:

Code:
[...]
       def show(self ):
            for v in self.cards.itervalues():
                v.offset = __Fixed(0, 0)

       def hide( self ):
           pass

       def  set_sensitive(self, value):
[...]
You tried to kill off the layer at which the table gets stuck to, right?


But for whatever reason, that's not the cause for the imagebutton to cover the entire table. Doing it this way will still let the imagebutton cover all the other cards.

In the end, it boils down to everything, that you told me already: using a lot of python doesn't work well with the screen language of renpy, but I appreciate this new angle. I'll look over it again and maybe find something.

As for the other workarounds, that I suggested: Thanks for reading my ideas and debunking them. I thought so.

EDIT:

I checked. It is possible to implement the cardgame in a screen, but it's all a lie! the card stacks are still beneath ALL screens.

For example:

Python:
screen cardGame111():

    imagebutton:
        idle Solid( "#00000000" )
        xpos 0 ypos 0
        xsize config.screen_width
        ysize config.screen_height
        # action NullAction()
        action Notify("HELLO")
        alternate NullAction()


screen cardGame():
    modal True

    add cardGame.table

label start:

    scene bg table

    python:

        cardGame.set_sensitive(False)

    show screen cardGame111
    call screen cardGame

    "End"
I tested this with modal True and modal False for the cardGame screen.
In either case, the cardgame itself isn't on the screen cardGame, but beneath all of it.
If modal is True, then I can't click on anything and if it's false, I can open the hello notify message, but not click on the cards.




But, uh... To build on your idea: Maybe I have to replace the 'master' or ui.layer(layer) in

Python:
def show(self, layer='master'):

            for v in self.cards.itervalues():
                v.offset = __Fixed(0, 0)

            ui.layer(layer)
            ui.add(self)
            ui.close()

        # This hides the table.
        def hide(self, layer='master'):
            ui.layer(layer)
            ui.remove(self)
            ui.close()
You completely removed it, but what if the removal leads to it being 'master' as default.

EDIT 2: I tried inserting numbers into the layer, but that's not it.
It's also not the 'screens' 'transient' and 'overlay'.
 
Last edited: