Question about having a "menu" inside a screen

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
Avantharis
Regular
Posts: 43
Joined: Mon Feb 23, 2015 6:40 pm
Tumblr: avantharis
Deviantart: Avantharis
Contact:

Question about having a "menu" inside a screen

#1 Post by Avantharis »

So, this days I have trying around a bit more and created a small code which allow the player to create either a gladiator or mage and have a battle.

The problem I am facing is, that during the battle itself, I would like to, instead of having attack, defense menu options along with every spell the player know, to somehow have a menu option which opens a new "menu" in a new screen (if possible) to avoid have a huge menu list.

So far I got almost everything, except the Spell menu in the fight does not work. I mean, since vbox does not allow "menu" and a couple of other stuff, I am right now using "textbox" and so far I managed to have the player selected spell to appear correctly in the new screen, I tried using "textbutton" with a hide function (to hide the screen) and below, as child, have the actual effects. But nothing happens (the menu closes, but nothing else, I guess child below don´t work in this case?). I looked around using the search function but didn´t find anything.

Here is the code:
- Note in the battle menu there is "cast fire ball" but I did add it only to test the effect of the spell, since I could test it otherwise until I solved my problem. What is important is a "Cast a Spell" option.

Code: Select all

label start:
    e "What is your name"
    $ player_name = renpy.input ("What is your name?")
    $ player_name = player_name.strip()
 
    if player_name =="":
        $ player_name ="Ren"
    
    e "So, your name is %(player_name)s!"

    "Choose your character"
    
    $ STR = 0
    $ CON = 0
    $ INT = 0
    $ AGI = 0
    $ strmod = 0
    $ conmod = 0
    $ intmod = 0
    $ agimod = 0
    $ weaponskill = 0
    $ level = 0
    $ HP = 0
    $ class1 = ""
    $ special = ""
    $ weapon = ""
    $ maxspell = 0
    
    
    menu:
        "Gladiator":
            $ STR = 16
            $ CON = 15
            $ INT = 10
            $ AGI = 15
            $ weaponskill = 15
            $ level = 5
            $ class1 = "Gladiator"
            $ special = "Fury"
            $ weapon = "Trident"
            $ armor = "Leather and Plates"
                
        "Mage":
            $ STR = 9
            $ CON = 12
            $ INT = 17
            $ AGI = 14
            $ weaponskill = 15
            $ level = 5
            $ class1 = "Mage"
            $ special = "Arcane Spells"
            $ weapon = "Staff"
            $ armor = "Leather"

    if STR >=12:
        $ strmod+=2
    if STR <=12:
        $ strmod =-2
    if AGI >=12:
        $ agimod +=1
    if CON >=12:
        $ conmod +=1
    if INT >=12:
        $ intmod +=1
    if INT >=15:
        $ intmod +=1
    if INT >=17:
        $ intmod +=1
    if class1 == "Mage":
        jump Spells
    if class1 == "Gladiator":
        jump herofinalstats
        
label Spells:

    e "choose your spells"
    $ maxspell = 4 + intmod
    $maxspelltest = 7
    e "now you can learn upon to [maxspell]"
    $ sp1 = "Fire Ball"
    $ sp2 = "Arcane Shield"
    $ sp3 = "Fire Arrow"
    $ sp4 = "Dispel Magic"
    $ sp5 = "Fire Shield"
    $ sp6 = "Fire Darts"
    $ sp7 = "Weaken"
    $ sp8 = "Slow"
    $ sp1t = False
    $ sp2t = False
    $ sp3t = False
    $ sp4t = False
    $ sp5t = False
    $ sp6t = False
    $ sp7t = False
    $ sp8t = False
    $ spellbook = []
    $ test = 4
    
    while maxspell>=0:

        menu:
            "[sp1]" if sp1t == False: 
                $ spellbook.append ("Fire Ball")
                $maxspell -=1
                e "[sp1] scribed in your spell book, you still have [maxspell] left"
                $ sp1t = True
            "[sp2]" if sp2t == False: 
                $ spellbook.append ("Arcane Shield")
                $maxspell -=1
                e "[sp2] scribed in your spell book, you still have [maxspell] left"
                $sp2t= True
            "[sp3]" if sp3t == False: 
                $ spellbook.append ("Fire Arrow")
                $maxspell -=1
                $sp3t = True
                e "[sp3] scribed in your spell book, you still have [maxspell] left"
            "[sp4]" if sp4t == False: 
                $ spellbook.append ("Dispel Magic")
                $maxspell -=1
                $sp4t=True
                e "[sp4] scribed in your spell book, you still have [maxspell] left"
            "[sp5]" if sp5t == False: 
                $ spellbook.append ("Fire Shield")
                $maxspell -=1
                $sp5t = True
                e "[sp5] scribed in your spell book, you still have [maxspell] left"

            "[sp6]" if sp6t == False: 
                $ spellbook.append ("Fire Darts")
                $maxspell -=1
                $sp6t= True
                e "[sp6] scribed in your spell book, you still have [maxspell] left"
 
            "[sp7]" if sp7t == False: 
                $ spellbook.append ("Weaken")
                $maxspell -=1
                e "[sp7] scribed in your spell book, you still have [maxspell] left"
                $sp7t = True

            "[sp8]" if sp8t == False: 
                $ spellbook.append ("Slow")
                $maxspell -=1
                e "[sp8] scribed in your spell book, you still have [maxspell] left"
                $sp8t = True
        
        if maxspell == 0:
            jump herofinalstats
           
    
label herofinalstats:

    $ ac = 0
    $ wdmin = 0
    $ wdmax = 0
    $ hp = 0
    $ bhp = 0
    $ spointmax = 0
    $ spointmin = 0
    # enemy variables
    $ ename = ""
    $ ehp = 0
    $ eskill = 0
    $ emindam = 0
    $ emaxdam = 0
    $ eac = 0
    $ eweapon = ""
    $ earmor =""

    
    if armor == "Leather":
        $ ac = 5
    if armor == "Leather and Plates":
        $ ac= 10
    if weapon == "Trident":
        $wdmin = 4
        $wdmax = 18
    if weapon == "Staff":
        $wdmin = 2
        $wdmax = 8
    if class1 == "Gladiator":
        $ hp = renpy.random.randint (6,18) *  level
        $ bsk = 10 +  level
    if class1 == "Mage":
        $ hp = renpy.random.randint (4,10) *  level
        $ bsk = 10 +  level % 2
        $ spointmax = level * INT + intmod *3
    if class1 == "Gladiator":
        $spellbook= [None]

    
label lizardman:
    
    e "The first battle is against the Lizard-man"
    

    $ename = "Lizard-man"
    $ehp = 65
    $eskill = 14
    $emindam = 6
    $emaxdam = 12
    $eac = 8
    $eweapon = "Spear"
    $earmor = "Leather"
    
    show screen battlescreen
    

    e "let the battle start!"

label firstbattle:
    
    $ round = 0
    $ atres = 0
    $ etres =0
    $ dam = 0
    $ mdam = 0
    $ spelldec = 0
    
    while (hp > 0) and (ehp > 0):
    
        menu:
            "Attack":
                $ atres = renpy.random.randint (1,20)
                if atres >= weaponskill - eac:
                    n "attack roll [atres] against enemy armor [eac]"
                    $ dam = renpy.random.randint (wdmin, wdmax)
                    n "enemy suffer [dam] plus your strenght modifer [strmod]"
                    $ ehp -= dam + strmod
                if atres <= weaponskill - eac:
                    n "attack fails"
            "Cast Fireball (Test Only to check effect)" if sp1t == True and spointmin <19:
                $ mdam = renpy.random.randint (10,30)
                $ spointmax -= 20
                $ ehp -= mdam
                n "you cast a Fireball spell, causing [mdam] of damage and consuming 20 spellpoints"
                
            "Cast a Spell":
                show screen spellbook2
            
            "Defend":
                n "Test"
              
return
    
And here is the screen code

Code: Select all

screen battlescreen:

    frame: 
        xalign 0.01 yalign 0.05
        vbox:
            label "[player_name]"
            frame:
                xalign 0.0
                yalign 0.0
                vbox:
                    text "Class: [class1] / Level:[level]"
                    text "HP: [hp]"
                    text "SP: [spointmax]"
                    text "Skill: [bsk]"
            label "Attributes"
            frame:
                xalign 0.0
                yalign 0.0
                vbox:
                   text "Str:[STR]([strmod])" size 12
                   text "Agi:[AGI]([agimod])" size 12
                   text "Con:[CON]([conmod])" size 12
                   text "Ibt:[INT]([intmod])" size 12
            label "Special Ability"
            vbox:
                text "[special]" 
            label "Weapons"
            frame:
                xalign 0.0
                yalign 0.0
                vbox:
                    text "[weapon] Damage: [wdmin] - [wdmax]"
                    text "[armor] : [ac] Rate"
            label "Spells"
            frame:
                xalign 0.0
                yalign 0.0
                vbox:
                    textbutton "Open Spellbook" action Show ("spellbook1")
 
    frame:
        xalign 0.98 yalign 0.05
        vbox:
            label "[ename]"
            text "HP: [ehp]"
            text "Skill: [eskill]"
            label "Weapons"
            text "[eweapon] - Damage: [emindam] - [emaxdam]"
            text "[earmor] : [eac] Rate"

screen spellbook1:

    frame:
        xalign 0.5 yalign 0.5
        vbox:
            label "Spellbook"
            frame:
                xalign 0.0
                yalign 0.0
                vbox:
                    text "[spellbook]"
                    textbutton "Close" action Hide("spellbook1")
                    
screen spellbook2:
    zorder 1
    #modal True
    frame:
        xalign 0.5 yalign 0.5
        vbox:
            label "Spellbook"
            frame:
                xalign 0.0
                yalign 0.0
                vbox:
                    if sp1t == True and spointmin <=19:
                        textbutton "[sp1]" action Hide ("spellbook2")
                        $ mdam = renpy.random.randint (10,30)
                        $ spointmax -= 20
                        $ ehp -= mdam
                        $ spelldec = "fireball"
                    if sp2t == True:
                        textbutton "[sp2]" action Hide ("spellbook2")
                    if sp3t == True:
                        textbutton "[sp3]" action Hide ("spellbook2")
                    if sp3t == True:
                        textbutton "[sp3]" action Hide ("spellbook2")
                    if sp4t == True:
                        textbutton "[sp4]" action Hide ("spellbook2")
                    if sp5t == True:
                        textbutton "[sp5]" action Hide ("spellbook2")
                    if sp6t == True:
                        textbutton "[sp6]" action Hide ("spellbook2")
                    if sp7t == True:
                        textbutton "[sp7]" action Hide ("spellbook2")
                    if sp8t == True:
                        textbutton "[sp8]" action Hide ("spellbook2")
                    textbutton "Close" action Hide ("spellbook2")
 
My Pixiv Profile: https://pixiv.me/avantharis

User avatar
kitsalai
Regular
Posts: 65
Joined: Wed Jan 08, 2014 11:05 pm
Projects: Imaginatum
Location: US
Contact:

Re: Question about having a "menu" inside a screen

#2 Post by kitsalai »

Hey Avantharis. I finally found some time and decided to look into your problem.

First thing I want to say is that menus are essentially screens. When you call menu, you're actually calling "screen choice(items)". Menu just makes the process very intuitive and easy. To achieve multiple menu choices, you can either do all menus or customize it with your own screens but it seems like your code is a hybrid of both.

For using all menus, you can add if statements to the menu like so: (http://www.renpy.org/doc/html/menus.html)

Code: Select all

menu:
    "[sp1]": if sp1t and spointmin <=19
        ...
And instead of having "screen spellbook2", you will have label spellbook2.
And instead of show screen spellbook2, you need to make it jump spellbook2.



If you want heavy customization (like menu placements or complicated actions), you can technically do what you have with screen spellbook2 but those textbuttons need to have an action (the variable statements you have afterwards will never run). I would recommend creating a function within a python init block and call it in the textbutton like this:

Code: Select all

textbutton "[sp1] action [yourownfunction, Hide("spellbook2")]
I recommend that you stick with one method for giving players options. It makes it easier to code.

User avatar
Avantharis
Regular
Posts: 43
Joined: Mon Feb 23, 2015 6:40 pm
Tumblr: avantharis
Deviantart: Avantharis
Contact:

Re: Question about having a "menu" inside a screen

#3 Post by Avantharis »

Thank very much for the help kitsalai!
kitsalai wrote:Hey Avantharis. I finally found some time and decided to look into your problem.

First thing I want to say is that menus are essentially screens. When you call menu, you're actually calling "screen choice(items)". Menu just makes the process very intuitive and easy. To achieve multiple menu choices, you can either do all menus or customize it with your own screens but it seems like your code is a hybrid of both.

For using all menus, you can add if statements to the menu like so: (http://www.renpy.org/doc/html/menus.html)

Code: Select all

menu:
    "[sp1]": if sp1t and spointmin <=19
        ...
And instead of having "screen spellbook2", you will have label spellbook2.
And instead of show screen spellbook2, you need to make it jump spellbook2.
Thanks! I did just that and it work like I wish now.

If you want heavy customization (like menu placements or complicated actions), you can technically do what you have with screen spellbook2 but those textbuttons need to have an action (the variable statements you have afterwards will never run). I would recommend creating a function within a python init block and call it in the textbutton like this:

Code: Select all

textbutton "[sp1] action [yourownfunction, Hide("spellbook2")]
I recommend that you stick with one method for giving players options. It makes it easier to code.
I understand, I will look more in to that, thanks the advice!
My Pixiv Profile: https://pixiv.me/avantharis

Post Reply

Who is online

Users browsing this forum: Google [Bot]