The problem is almost resolved.
After a lot of brute-forcing i finally figured the way it works.
You were true about "ShowMenu", yeah.
It seems that the "Start" action will raise a "JumpOutException" if in a new label, so there is no other way, but to use "Show".
That way "Jump" works properly, with working readback and anything i would want.
This leads to the need to change the "day_completed" screen this way, though:
Code: Select all
if tips == "onikakusi":
hotspot (208, 96, 224, 48) activate_sound "sound/SE137.ogg" action [Show("tips_onik"), SetVariable("tips", "onikakusi")]
That ensures the "tips" variable replacement, so we don't get to return to the MainMenu after reading any TIPS. The in-game call will work totally as intended now.
But! If accessing TIPS from main menu, then it won't work as in called in-game. You have to have the game started with a Start label. However, you can not use Start for all TIPS because of mentioned above. After going through the first label, the next Start label will raise an error.
So we have no way but to use "Jump" for the TIPS labels, and call "Start" once. From the screen that divides TIPS into chapters (i.e. you select which chapter you want to view for TIPS).
Instead of
Show("tips_onik", transition=fade), there should be
Start("context_tips_onik").
Then i added the label to the TIPS file.
Code: Select all
label context_tips_onik:
$ unlock_prompt = True
$ tips = "mainmenu"
# $ config.overlay_functions.remove(readback_catcher) # do not do this - look below.
scene black # that's for not removing the readback function, so the background would not be transparent for any reason.
call screen tips_onik
return
So that way readback, while preserving its beautifulness, will not ruin my precious TIPS screen. It didn't quite work as planned, though...
The game then checks for tips value to return to the appropriate screens.
Code: Select all
if tips == "mainmenu":
jump context_tips_onik
else:
$ config.overlay_functions.append(readback_catcher)
call screen tips_onik
return
Also i changed the screen for TIPS:
Code: Select all
if tips == "onikakusi":
hotspot (245, 420, 150, 48) action Show("day_completed", tips="onikakusi", transition=fade)
else:
hotspot (245, 420, 150, 48) action MainMenu(confirm=False)
That way i still can use one screen instead of two for Chapter's TIPS.
Oh, and also i blocked keys associated with "rollback", "dismiss", "hide_windows", "game_menu" in TIPS screen, of course.
Then i had a crazy duel with a readback overlay and mainmenu TIPS button combined. I spent around 10 hours trying to figure out how to disable it for a certain screen. I thought of asking here, started writing, then, after turning computer off, suddenly realized that i've found a solution (StylePreference), It didn't work, though (because current Ren'Py actions don't work with lists), but, not giving up and thanks to SleepKirby's code for Touhou Mecha, i figured out (not familiar with python) how to remove and append list variables accordingly by creating another action in init code above the "-2 python", which is where the readback catcher function is appended.
Maybe somebody will find this function useful.
My Goddess... it actually holds a very big potential for interface (such as hiding/showing analog clock, buying an item with a screen, etc - of course, with some condition or a bit of a work for the latter), while not needing to restart the game. And it's a very big advantage.
Code: Select all
init python:
class ToggleList:
def __init__(self, list, lpos):
self.list = list
self.lpos = lpos
def __call__(self):
if self.lpos in self.list:
self.list.remove(self.lpos)
else:
self.list.append(self.lpos)
return self.list
Then i just had to add an Action to the each of «on»: "hide" "replace", "replaced", "show" statements of a TIPS screen.
Code: Select all
ToggleList(config.overlay_functions, readback_catcher)
Code: Select all
on "show" action [Play("music", bgm_tips, loop=True, fadeout=1.0, if_changed=True), ToggleList(config.overlay_functions, readback_catcher), Play("ambient", None), SetVariable("unlock_prompt", True)]
on "replace" action [Play("music", bgm_tips, loop=True, fadeout=1.0, if_changed=True), ToggleList(config.overlay_functions, readback_catcher), Play("ambient", None), SetVariable("unlock_prompt", True)]
on "replaced" action [SetVariable("unlock_prompt", True), ToggleList(config.overlay_functions, readback_catcher)]
on "hide" action [SetVariable("unlock_prompt", True), ToggleList(config.overlay_functions, readback_catcher)]
It works just perfectly in every case, and i didn't even need to use additional labels.
It's even possible to use it (with some modding) for actually CHANGING MUSIC IN-GAME.
The currently playing %channelname% needs to be changed, however, for this to take effect.
You'll need to define your music as a list (i.e. not
define kowaii_saundo = "iwa.ogg", but
define kowaii_saundo = ["iwa.ogg"]. Because the action works with lists only, after all.
It won't save after you re-launch the game, though, but that's easy - just store it in a persistent.variable_name and define kowaii_saundo as that name. That way it'll read the stored info after re-launching, and will still change list in-game. Like so:
Code: Select all
if not persistent.kowaii_saundov:
$ persistent.kowaii_saundov = ["iwa.ogg"]
define kowaii_saundo = persistent.kowaii_saundov
Then add to the init python section (it's just a slightly changed ToggleList action, nothing special):
Code: Select all
class RemoveList(Action):
def __init__(self, list, lpos):
self.list = list
self.lpos = lpos
def __call__(self):
if self.lpos in self.list:
self.list.remove(self.lpos)
return self.list
else:
return None
class AppendList(Action):
def __init__(self, list, lpos):
self.list = list
self.lpos = lpos
def __call__(self):
if self.lpos in self.list:
return None
else:
self.list.append(self.lpos)
return self.list
Then just add something like this to the preference screen:
Code: Select all
frame:
style_group "pref"
has vbox
label _("Scary sound")
textbutton _("1") action [RemoveList(kowaii_saundo, "iwa.ogg"), AppendList(kowaii_saundo, "jaki.ogg")]
textbutton _("2") action [RemoveList(kowaii_saundo, "jaki.ogg"), AppendList(kowaii_saundo, "iwa.ogg")]
textbutton _("full") action [AppendList(kowaii_saundo, "iwa.ogg"), AppendList(kowaii_saundo, "jaki.ogg")]
And it'll do. Remember, list is not a string, but strings can be used in a list.
The first button makes only one sound play, when "kowaii_saundo" is played;
the second one plays only another one;
the third button plays both.
Now you can change the music versions.
But whenever you choose any of these options, the game, for some reason, starts running. If you don't have a start label, then you'll get an error.
Why the hell it does so, and how to fix such a behavior?
Traceback:
I'm sorry, but an uncaught exception occurred.
While running game code:
ScriptError: could not find label 'start'.
-- Full Traceback ------------------------------------------------------------
Full traceback:
File "E:\Call of Pripyat\gamedata\Matsuri\bgitools\RenPy\Test\renpy\execution.py", line 265, in run
File "E:\Call of Pripyat\gamedata\Matsuri\bgitools\RenPy\Test\renpy\ast.py", line 1267, in execute
File "E:\Call of Pripyat\gamedata\Matsuri\bgitools\RenPy\Test\renpy\script.py", line 485, in lookup
ScriptError: could not find label 'start'.
Windows-XP-5.1.2600-SP2
Ren'Py 6.13.12.1728
A Ren'Py Game 0.0