316 lines
9.4 KiB
Text
316 lines
9.4 KiB
Text
# Copyright 2004-2019 Tom Rothamel <pytom@bishoujo.us>
|
|
#
|
|
# Permission is hereby granted, free of charge, to any person
|
|
# obtaining a copy of this software and associated documentation files
|
|
# (the "Software"), to deal in the Software without restriction,
|
|
# including without limitation the rights to use, copy, modify, merge,
|
|
# publish, distribute, sublicense, and/or sell copies of the Software,
|
|
# and to permit persons to whom the Software is furnished to do so,
|
|
# subject to the following conditions:
|
|
#
|
|
# The above copyright notice and this permission notice shall be
|
|
# included in all copies or substantial portions of the Software.
|
|
#
|
|
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
|
|
init -1500 python:
|
|
|
|
|
|
##########################################################################
|
|
# Menu-related actions.
|
|
|
|
config.show_menu_enable = {
|
|
"save" : "(not main_menu) and (not _in_replay)",
|
|
"load" : "(not _in_replay)",
|
|
}
|
|
|
|
@renpy.pure
|
|
class ShowMenu(Action, DictEquality):
|
|
"""
|
|
:doc: menu_action
|
|
|
|
Causes us to enter the game menu, if we're not there already. If we
|
|
are in the game menu, then this shows a screen or jumps to a label.
|
|
|
|
`screen` is usually the name of a screen, which is shown using
|
|
the screen mechanism. If the screen doesn't exist, then "_screen"
|
|
is appended to it, and that label is jumped to.
|
|
|
|
* ShowMenu("load")
|
|
* ShowMenu("save")
|
|
* ShowMenu("preferences")
|
|
|
|
This can also be used to show user-defined menu screens. For
|
|
example, if one has a "stats" screen defined, one can
|
|
show it as part of the game menu using:
|
|
|
|
* ShowMenu("stats")
|
|
|
|
ShowMenu without an argument will enter the game menu at the
|
|
default screen, taken from _game_menu_screen.
|
|
|
|
Extra arguments and keyword arguments are passed on to the screen
|
|
"""
|
|
|
|
def __init__(self, screen=None, *args, **kwargs):
|
|
self.screen = screen
|
|
self.args = args
|
|
self.kwargs = kwargs
|
|
|
|
def predict(self):
|
|
if renpy.has_screen(self.screen):
|
|
renpy.predict_screen(self.screen, *self.args, **self.kwargs)
|
|
|
|
def __call__(self):
|
|
|
|
if not self.get_sensitive():
|
|
return
|
|
|
|
orig_screen = screen = self.screen or store._game_menu_screen
|
|
|
|
if not (renpy.has_screen(screen) or renpy.has_label(screen)):
|
|
screen = screen + "_screen"
|
|
|
|
# Ugly. We have different code depending on if we're in the
|
|
# game menu or not.
|
|
if renpy.context()._menu:
|
|
|
|
if renpy.has_screen(screen):
|
|
|
|
renpy.transition(config.intra_transition)
|
|
renpy.show_screen(screen, _transient=True, *self.args, **self.kwargs)
|
|
renpy.restart_interaction()
|
|
|
|
elif renpy.has_label(screen):
|
|
renpy.transition(config.intra_transition)
|
|
|
|
ui.layer("screens")
|
|
ui.remove_above(None)
|
|
ui.close()
|
|
|
|
renpy.jump(screen)
|
|
|
|
else:
|
|
raise Exception("%r is not a screen or a label." % orig_screen)
|
|
|
|
else:
|
|
renpy.call_in_new_context("_game_menu", *self.args, _game_menu_screen=screen, **self.kwargs)
|
|
|
|
def get_selected(self):
|
|
screen = self.screen or store._game_menu_screen
|
|
|
|
if screen is None:
|
|
return False
|
|
|
|
return renpy.get_screen(screen)
|
|
|
|
def get_sensitive(self):
|
|
screen = self.screen or store._game_menu_screen
|
|
|
|
if screen is None:
|
|
return False
|
|
|
|
if screen in config.show_menu_enable:
|
|
return eval(config.show_menu_enable[screen])
|
|
else:
|
|
return True
|
|
|
|
@renpy.pure
|
|
class Start(Action, DictEquality):
|
|
"""
|
|
:doc: menu_action
|
|
|
|
Causes Ren'Py to jump out of the menu context to the named
|
|
label. The main use of this is to start a new game from the
|
|
main menu. Common uses are:
|
|
|
|
* Start() - Start at the start label.
|
|
* Start("foo") - Start at the "foo" label.
|
|
"""
|
|
|
|
def __init__(self, label="start"):
|
|
self.label = label
|
|
|
|
def __call__(self):
|
|
renpy.jump_out_of_context(self.label)
|
|
|
|
|
|
@renpy.pure
|
|
class MainMenu(Action, DictEquality):
|
|
"""
|
|
:doc: menu_action
|
|
|
|
Causes Ren'Py to return to the main menu.
|
|
|
|
`confirm`
|
|
If true, causes Ren'Py to ask the user if he wishes to
|
|
return to the main menu, rather than returning
|
|
directly.
|
|
"""
|
|
|
|
def __init__(self, confirm=True):
|
|
self.confirm = confirm
|
|
|
|
def __call__(self):
|
|
|
|
if not self.get_sensitive():
|
|
return
|
|
|
|
if self.confirm:
|
|
if config.autosave_on_quit:
|
|
renpy.force_autosave()
|
|
|
|
layout.yesno_screen(layout.MAIN_MENU, MainMenu(False))
|
|
else:
|
|
renpy.full_restart(config.game_main_transition)
|
|
|
|
def get_sensitive(self):
|
|
return not renpy.context()._main_menu
|
|
|
|
_confirm_quit = True
|
|
|
|
@renpy.pure
|
|
class Quit(Action, DictEquality):
|
|
"""
|
|
:doc: menu_action
|
|
|
|
Quits the game.
|
|
|
|
`confirm`
|
|
If true, prompts the user if he wants to quit, rather
|
|
than quitting directly. If None, asks if and only if
|
|
the user is not at the main menu.
|
|
"""
|
|
|
|
def __init__(self, confirm=None):
|
|
self.confirm = confirm
|
|
|
|
def __call__(self):
|
|
|
|
confirm = self.confirm
|
|
|
|
if confirm is None:
|
|
confirm = (not main_menu) and _confirm_quit
|
|
|
|
if confirm:
|
|
if config.autosave_on_quit:
|
|
renpy.force_autosave()
|
|
|
|
layout.yesno_screen(layout.QUIT, Quit(False))
|
|
|
|
else:
|
|
renpy.quit(save=True)
|
|
|
|
@renpy.pure
|
|
class Skip(Action, DictEquality):
|
|
"""
|
|
:doc: other_action
|
|
|
|
Causes the game to begin skipping. If the game is in a menu
|
|
context, then this returns to the game. Otherwise, it just
|
|
enables skipping.
|
|
|
|
`fast`
|
|
If true, skips directly to the next menu choice.
|
|
|
|
`confirm`
|
|
If true, asks for confirmation before beginning skipping.
|
|
"""
|
|
|
|
fast = False
|
|
confirm = False
|
|
|
|
def __init__(self, fast=False, confirm=False):
|
|
self.fast = fast
|
|
self.confirm = confirm
|
|
|
|
def __call__(self):
|
|
if not self.get_sensitive():
|
|
return
|
|
|
|
if self.confirm:
|
|
if self.fast:
|
|
if _preferences.skip_unseen:
|
|
layout.yesno_screen(layout.FAST_SKIP_UNSEEN, Skip(True))
|
|
else:
|
|
layout.yesno_screen(layout.FAST_SKIP_SEEN, Skip(True))
|
|
else:
|
|
layout.yesno_screen(layout.SLOW_SKIP, Skip(False))
|
|
|
|
return
|
|
|
|
if renpy.context()._menu:
|
|
if self.fast:
|
|
renpy.jump("_return_fast_skipping")
|
|
else:
|
|
renpy.jump("_return_skipping")
|
|
else:
|
|
|
|
if not config.skipping:
|
|
if self.fast:
|
|
config.skipping = "fast"
|
|
else:
|
|
config.skipping = "slow"
|
|
else:
|
|
config.skipping = None
|
|
|
|
renpy.restart_interaction()
|
|
|
|
def get_selected(self):
|
|
if self.fast:
|
|
return config.skipping == "fast"
|
|
else:
|
|
return config.skipping and config.skipping != "fast"
|
|
|
|
def get_sensitive(self):
|
|
if not config.allow_skipping:
|
|
return False
|
|
|
|
if not _skipping:
|
|
return False
|
|
|
|
if store.main_menu:
|
|
return False
|
|
|
|
if renpy.game.context().seen_current(True):
|
|
return True
|
|
|
|
if _preferences.skip_unseen:
|
|
return True
|
|
|
|
return False
|
|
|
|
@renpy.pure
|
|
class Help(Action, DictEquality):
|
|
"""
|
|
:doc: other_action
|
|
|
|
Displays help.
|
|
|
|
If a screen named ``help`` is defined, that screen is displayed
|
|
using :func:`ShowMenu` and `help` is ignored.
|
|
|
|
`help`
|
|
A string that is used to find help. This is used in the
|
|
following way:
|
|
|
|
* If a label with this name exists, the label is called in
|
|
a new context.
|
|
* Otherwise, this is interpreted as giving the name of a file
|
|
that should be opened in a web browser.
|
|
|
|
If `help` is None, :var:`config.help` is used as the default
|
|
value.
|
|
"""
|
|
|
|
def __init__(self, help=None):
|
|
self.help = help
|
|
|
|
def __call__(self):
|
|
_help(self.help)
|