CampBuddy/Camp.Buddy v2.2.1/Camp_Buddy-2.2.1-pc/renpy/common/00action_other.rpy
2025-03-03 23:00:33 +01:00

672 lines
20 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:
@renpy.pure
class InvertSelected(Action, DictEquality):
"""
:doc: other_action
This inverts the selection state of the provided action, while
proxying over all of the other methods.
"""
def __init__(self, action):
self.action = action
try:
self.alt = action.alt
except:
pass
def __call__(self):
return self.action.__call__()
def get_selected(self):
return not self.action.get_selected()
def get_sensitive(self):
return self.action.get_sensitive()
def periodic(self, st):
return self.action.periodic(st)
def predict(self):
self.action.predict()
@renpy.pure
def If(expression, true=None, false=None):
"""
:doc: other_action
This returns `true` if `expression` is true, and `false`
otherwise. Use this to select an action based on an expression.
Note that the default, None, can be used as an action that causes
a button to be disabled.
"""
if expression:
return true
else:
return false
@renpy.pure
class SelectedIf(Action, DictEquality):
"""
:doc: other_action
This indicates that one action in a list of actions should be used
to determine if a button is selected. This only makes sense
when the button has a list of actions. For example::
# The button is selected only if mars_flag is True
textbutton "Marsopolis":
action [ SelectedIf(SetVariable("mars_flag", True)), SetVariable("on_mars", True) ]
The action inside SelectedIf is run normally when the button is clicked.
"""
# Note: This had been documented to take a boolean.
def __init__(self, expression):
self.expression = expression
if isinstance(expression, Action):
for i in [ "get_selected", "get_sensitive", "get_tooltip", "periodic", "unhovered", "unhovered" ]:
setattr(self, i, getattr(expression, i, None))
def __call__(self):
if isinstance(self.expression, Action):
return self.expression()
return None
def get_selected(self):
return self.expression
@renpy.pure
class SensitiveIf(Action, DictEquality):
"""
:doc: other_action
This indicates that one action in a list of actions should be used
to determine if a button is sensitive. This only makes sense
when the button has a list of actions. For example::
# The button is sensitive only if mars_flag is True
textbutton "Marsopolis":
action [ SensitiveIf(SetVariable("mars_flag", True)), SetVariable("on_mars", True) ]
The action inside SensitiveIf is run normally when the button is clicked.
"""
# Note: This had been documented to take a boolean.
def __init__(self, expression):
self.expression = expression
if isinstance(expression, Action):
for i in [ "get_selected", "get_sensitive", "get_tooltip", "periodic", "unhovered", "unhovered" ]:
setattr(self, i, getattr(expression, i, None))
def __call__(self):
if isinstance(self.expression, Action):
return self.expression()
return None
def get_sensitive(self):
return self.expression
@renpy.pure
class Screenshot(Action, DictEquality):
"""
:doc: other_action
Takes a screenshot.
"""
def __call__(self):
_screenshot()
@renpy.pure
class HideInterface(Action, DictEquality):
"""
:doc: other_action
Causes the interface to be hidden until the user clicks.
"""
def __call__(self):
renpy.call_in_new_context("_hide_windows")
@renpy.pure
class OpenURL(Action, DictEquality):
"""
:doc: other_action
Causes `url` to be opened in a web browser.
"""
def __init__(self, url):
self.url = url
def __call__(self):
try:
import webbrowser
webbrowser.open_new(self.url)
except:
pass
class With(Action, DictEquality):
"""
:doc: other_action
Causes `transition` to occur.
"""
def __init__(self, transition):
self.transition = transition
def __call__(self):
renpy.transition(self.transition)
renpy.restart_interaction()
@renpy.pure
class Notify(Action, DictEquality):
"""
:doc: other_action
Displays `message` using :func:`renpy.notify`.
"""
def __init__(self, message):
self.message = message
def predict(self):
renpy.predict_screen("notify")
def __call__(self):
renpy.notify(self.message)
@renpy.pure
class Rollback(Action, DictEquality):
"""
:doc: other_action
This action causes a rollback to occur, when a rollback is possible.
Otherwise, nothing happens.
The arguments are given to :func:`renpy.rollback`, except that the
`force` argument defaults to "menu".
"""
args = tuple()
kwargs = { "force" : "menu" }
def __init__(self, *args, **kwargs):
self.args = args
kwargs.setdefault("force", "menu")
self.kwargs = kwargs
def __call__(self):
renpy.rollback(*self.args, **self.kwargs)
def get_sensitive(self):
return renpy.can_rollback()
class RollbackToIdentifier(Action, DictEquality):
"""
:doc: other_action
This causes a rollback to an identifier to occur. Rollback
identifiers are returned as part of HistoryEntry objects.
"""
def __init__(self, identifier):
self.identifier = identifier
def __call__(self):
checkpoints = renpy.get_identifier_checkpoints(self.identifier)
if checkpoints is not None:
renpy.rollback(checkpoints=checkpoints, force="menu")
def get_sensitive(self):
return (renpy.get_identifier_checkpoints(self.identifier) is not None)
@renpy.pure
class RestartStatement(Action, DictEquality):
"""
:doc: other_action
This action causes Ren'Py to rollback to before the current
statement, and then re-run the current statement. This may be used
when changing a persistent variable that affects how the statement
is displayed.
If run in a menu context, this waits until the player exits to a
top-level context before performing the rollback.
"""
def __call__(self):
renpy.rollback(force=True, checkpoints=0, defer=True)
@renpy.pure
class RollForward(Action, DictEquality):
"""
:doc: other_action
This action causes a rollforward to occur, if a roll forward is
possible. Otherwise, it is insensitive.
"""
def __call__(self):
return renpy.exports.roll_forward_core()
def get_sensitive(self):
return renpy.roll_forward_info() is not None
#########################################################################
def GetTooltip(screen=None):
"""
:doc: get_tooltip
Returns the tooltip of the currently focused displayable, or None
if no displatable is focused.
`screen`
If not None, this should be the name or tag of a screen. If
given, this function only returns the tooltip if the focused
displayable is part of the screen.
"""
return renpy.display.focus.get_tooltip(screen)
class __TooltipAction(Action, FieldEquality):
identity_fields = [ "tooltip", "value" ]
def __init__(self, tooltip, value):
self.tooltip = tooltip
self.value = value
def __call__(self):
if self.tooltip.value != self.value:
self.tooltip.value = self.value
renpy.restart_interaction()
def unhovered(self):
if self.tooltip.value != self.tooltip.default:
self.tooltip.value = self.tooltip.default
renpy.restart_interaction()
_m1_00screen__TooltipAction = __TooltipAction
class Tooltip(object):
"""
:doc: tooltips class
A tooltip object can be used to define a portion of a screen that is
updated when the mouse hovers an area.
A tooltip object has a ``value`` field, which is set to the `default`
value passed to the constructor when the tooltip is created. When
a button using an action created by the tooltip is hovered, the
value field changes to the value associated with the action.
"""
def __init__(self, default):
self.value = default
self.default = default
def Action(self, value):
"""
:doc: tooltips method
:name: Action
Returns an action that is generally used as the hovered property
of a button. When the button is hovered, the value field of this
tooltip is set to `value`. When the button loses focus, the
value field of this tooltip reverts to the default.
"""
return __TooltipAction(self, value)
action = Action
#########################################################################
@renpy.pure
class Language(Action, DictEquality):
"""
:doc: language_action
Changes the language of the game to `language`.
`language`
A string giving the language to translate to, or None to use
the default language of the game script.
"""
alt = _("Language [text]")
def __init__(self, language):
self.language = language
def __call__(self):
renpy.change_language(self.language)
def get_selected(self):
return _preferences.language == self.language
def get_sensitive(self):
if self.language is None:
return True
return self.language in renpy.known_languages()
#########################################################################
# Transitions used when entering and leaving replays.
config.enter_replay_transition = None
config.exit_replay_transition = None
@renpy.pure
class Replay(Action, DictEquality):
"""
:doc: replay
An action that starts `label` as a replay.
`scope`
A dictionary mapping variable name to value. These variables are set
when entering the replay.
`locked`
If true, this replay is locked. If false, it is unlocked. If None, the
replay is locked if the label has not been seen in any playthrough.
"""
def __init__(self, label, scope={}, locked=None):
self.label = label
self.scope = scope
self.locked = locked
def __call__(self):
if self.locked:
return
if config.enter_replay_transition:
renpy.transition(config.enter_replay_transition)
renpy.call_replay(self.label, self.scope)
if config.exit_replay_transition:
renpy.transition(config.exit_replay_transition)
def get_sensitive(self):
if self.locked is not None:
return not self.locked
return renpy.seen_label(self.label)
@renpy.pure
class EndReplay(Action, DictEquality):
"""
:doc: replay
Ends the current replay.
`confirm`
If true, prompts the user for confirmation before ending the
replay.
"""
def __init__(self, confirm=True):
self.confirm = confirm
def __call__(self):
if not self.get_sensitive():
return
if self.confirm:
layout.yesno_screen(layout.END_REPLAY, EndReplay(False))
else:
renpy.end_replay()
def get_sensitive(self):
return _in_replay
@renpy.pure
class MouseMove(Action, DictEquality):
"""
:doc: other_action
Move the mouse pointer to `x`, `y`. If the device does not have a mouse
pointer or _preferences.mouse_move is False, this does nothing.
`duration`
The time it will take to perform the move, in seconds. During
this time, the mouse may be unresponsive.
"""
def __init__(self, x, y, duration=0):
self.x = x
self.y = y
self.duration = duration
def __call__(self):
if _preferences.mouse_move:
renpy.set_mouse_pos(self.x, self.y, self.duration)
@renpy.pure
class QueueEvent(Action, DictEquality):
"""
:doc: other_action
Queues the given event using :func:`renpy.queue_event`.
"""
def __init__(self, event, up=False):
self.event = event
self.up = up
def __call__(self):
renpy.queue_event(self.event, up=self.up)
class Function(Action, DictEquality):
"""
:doc: other_action
This Action calls `callable` with `args` and `kwargs`.
`callable`
Callable object.
`args`
position arguments to be passed to `callable`.
`kwargs`
keyword arguments to be passed to `callable`.
This Action takes an optional _update_screens keyword argument, which
defaults to true. When it is true, the interaction restarts and
the screens are updated after the function returns.
If the function returns a non-None value, the interaction stops and
returns that value. (When called using the call screen statement, the
result is placed in the `_return` variable.)
"""
update_screens = True
def __init__(self, callable, *args, **kwargs):
self.callable = callable
self.args = args
self.update_screens = kwargs.pop("_update_screens", True)
self.kwargs = kwargs
def __call__(self):
rv = self.callable(*self.args, **self.kwargs)
if self.update_screens:
renpy.restart_interaction()
return rv
@renpy.pure
class Confirm(Action, DictEquality):
"""
:doc: other_action
Prompts the user for confirmation of an action. If the user
clicks yes, the yes action is performed. Otherwise, the `no`
action is performed.
`prompt`
The prompt to display to the user.
`confirm_selected`
If true, the prompt will be displayed even if the `yes` action
is already selected. If false (the default), the prompt
will not be displayed if the `yes` action is selected.
The sensitivity and selectedness of this action match those
of the `yes` action.
"""
def __init__(self, prompt, yes, no=None, confirm_selected=False):
self.prompt = prompt
self.yes = yes
self.no = no
self.confirm_selected = confirm_selected
def __call__(self):
if self.get_selected() and not self.confirm_selected:
return renpy.run(self.yes)
return layout.yesno_screen(self.prompt, self.yes, self.no)
def get_sensitive(self):
if self.yes is None:
return False
return renpy.is_sensitive(self.yes)
def get_selected(self):
return renpy.is_selected(self.yes)
def get_tooltip(self):
return renpy.display.behavior.get_tooltip(self.yes)
@renpy.pure
class Scroll(Action, DictEquality):
"""
:doc: other_action
Causes a Bar, Viewport, or Vpgrid to scroll.
`id`
The id of a bar, viewport, or vpgrid in the current screen.
`direction`
For a vbar, one of "increase" or "decrease". For a viewport
or vpgrid, one of "horizontal increase", "vertical increase",
"horizontal decrease", or "vertical decrease".
`amount`
The amount to scroll by. This can be a number of pixels, or
else "step" or "page".
"""
def __init__(self, id, direction, amount="step"):
self.id = id
self.direction = direction
self.amount = amount
def __call__(self):
d = renpy.get_widget(None, self.id)
if d is None:
raise Exception("There is no displayable with the id {}.".format(self.id))
if self.direction == "increase":
delta = +1
adjustment = d.adjustment
elif self.direction == "decrease":
delta = -1
adjustment = d.adjustment
elif self.direction == "horizontal increase":
delta = +1
adjustment = d.xadjustment
elif self.direction == "horizontal decrease":
delta = -1
adjustment = d.xadjustment
elif self.direction == "vertical increase":
delta = +1
adjustment = d.yadjustment
elif self.direction == "vertical decrease":
delta = -1
adjustment = d.yadjustment
else:
raise Exception("Unknown scroll direction: {}".format(self.direction))
if self.amount == "step":
adjustment.change(adjustment.value + delta * adjustment.step)
elif self.amount == "page":
adjustment.change(adjustment.value + delta * adjustment.page)
else:
adjustment.change(adjustment.value + delta * self.amount)
init -1500:
transform _notify_transform:
# These control the position.
xalign .02 yalign .015
# These control the actions on show and hide.
on show:
alpha 0
linear .25 alpha 1.0
on hide:
linear .5 alpha 0.0
screen notify:
zorder 100
text "[message!tq]" at _notify_transform
# This controls how long it takes between when the screen is
# first shown, and when it begins hiding.
timer 3.25 action Hide('notify')