1# Copyright 2004-2021 Tom Rothamel <pytom@bishoujo.us>
2#
3# Permission is hereby granted, free of charge, to any person
4# obtaining a copy of this software and associated documentation files
5# (the "Software"), to deal in the Software without restriction,
6# including without limitation the rights to use, copy, modify, merge,
7# publish, distribute, sublicense, and/or sell copies of the Software,
8# and to permit persons to whom the Software is furnished to do so,
9# subject to the following conditions:
10#
11# The above copyright notice and this permission notice shall be
12# included in all copies or substantial portions of the Software.
13#
14# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21
22from __future__ import division, absolute_import, with_statement, print_function, unicode_literals
23from renpy.compat import *
24
25from renpy.minstore import *
26
27# But please note that this will not be available in the body
28# of user code, unless we re-import it.
29import renpy.display
30import renpy.audio
31import renpy.text
32
33import renpy.display.im as im
34import renpy.display.anim as anim
35
36_restart = None
37
38# Used by the call/return mechanism.
39_return = None
40_args = None
41_kwargs = None
42
43# Should the in-game window be shown?
44_window = False
45
46# The window subtitle.
47_window_subtitle = ''
48
49# Should rollback be allowed?
50_rollback = True
51
52# Should beginning a new rollback be allowed?
53_begin_rollback = True
54
55# Should skipping be allowed?
56_skipping = True
57
58# Should dismissing pauses and transitions be allowed?
59_dismiss_pause = True
60
61# config.
62_config = renpy.config
63
64# Used by the ui functions.
65_widget_by_id = None
66_widget_properties = { }
67
68# The text rectangle, or None to use the automatic code.
69_text_rect = None
70
71# Are we in various menus?
72_menu = False
73main_menu = False
74
75# Is autosaving allowed?
76_autosave = True
77
78# Should live2d fading happen?
79_live2d_fade = True
80
81
82class _Config(object):
83
84    def __getstate__(self):
85        return None
86
87    def __setstate__(self, data):
88        return
89
90    def register(self, name, default, cat=None, help=None): # @ReservedAssignment
91        setattr(self, name, default)
92        _config.help.append((cat, name, help))
93
94    def __getattr__(self, name):
95        cvars = vars(_config)
96
97        if name not in cvars:
98            raise Exception('config.%s is not a known configuration variable.' % (name))
99
100        return cvars[name]
101
102    def __setattr__(self, name, value):
103        cvars = vars(_config)
104
105        if name not in cvars and renpy.config.locked:
106            raise Exception('config.%s is not a known configuration variable.' % (name))
107
108        if name == "script_version":
109            renpy.store._set_script_version(value) # E1101 @UndefinedVariable
110
111        if name == "developer":
112            if value == "auto":
113                renpy.config.original_developer = value
114                renpy.config.developer = renpy.config.default_developer
115                return
116
117        cvars[name] = value
118
119    def __delattr__(self, name):
120        if renpy.config.locked:
121            raise Exception('Deleting configuration variables is not supported.')
122        else:
123            delattr(renpy.config, name)
124
125
126# The styles object.
127style = None
128
129config = _Config()
130library = config
131
132eval = renpy.python.py_eval # @ReservedAssignment
133
134# Displayables.
135Bar = renpy.display.behavior.Bar
136Button = renpy.display.behavior.Button
137ImageButton = renpy.display.behavior.ImageButton
138Input = renpy.display.behavior.Input
139TextButton = renpy.display.behavior.TextButton
140
141ImageReference = renpy.display.image.ImageReference
142DynamicImage = renpy.display.image.DynamicImage
143
144Image = renpy.display.im.image
145
146Frame = renpy.display.imagelike.Frame
147Borders = renpy.display.imagelike.Borders
148Solid = renpy.display.imagelike.Solid
149FileCurrentScreenshot = renpy.display.imagelike.FileCurrentScreenshot
150
151LiveComposite = renpy.display.layout.LiveComposite
152LiveCrop = renpy.display.layout.LiveCrop
153LiveTile = renpy.display.layout.LiveTile
154
155Composite = renpy.display.layout.Composite
156Crop = renpy.display.layout.Crop
157Tile = renpy.display.layout.Tile
158
159Flatten = renpy.display.layout.Flatten
160
161Null = renpy.display.layout.Null
162Window = renpy.display.layout.Window
163Viewport = renpy.display.viewport.Viewport
164DynamicDisplayable = renpy.display.layout.DynamicDisplayable
165ConditionSwitch = renpy.display.layout.ConditionSwitch
166ShowingSwitch = renpy.display.layout.ShowingSwitch
167AlphaMask = renpy.display.layout.AlphaMask
168
169Transform = renpy.display.motion.Transform
170
171Animation = anim.Animation
172Movie = renpy.display.video.Movie
173Particles = renpy.display.particle.Particles
174SnowBlossom = renpy.display.particle.SnowBlossom
175
176Text = renpy.text.text.Text
177ParameterizedText = renpy.text.extras.ParameterizedText
178FontGroup = renpy.text.font.FontGroup
179
180Drag = renpy.display.dragdrop.Drag
181DragGroup = renpy.display.dragdrop.DragGroup
182
183Sprite = renpy.display.particle.Sprite
184SpriteManager = renpy.display.particle.SpriteManager
185
186Matrix = renpy.display.matrix.Matrix # @UndefinedVariable
187
188Live2D = renpy.gl2.live2d.Live2D
189
190Model = renpy.display.model.Model
191
192# Currying things.
193Alpha = renpy.curry.curry(renpy.display.layout.Alpha)
194Position = renpy.curry.curry(renpy.display.layout.Position)
195Pan = renpy.curry.curry(renpy.display.motion.Pan)
196Move = renpy.curry.curry(renpy.display.motion.Move)
197Motion = renpy.curry.curry(renpy.display.motion.Motion)
198Revolve = renpy.curry.curry(renpy.display.motion.Revolve)
199Zoom = renpy.curry.curry(renpy.display.motion.Zoom)
200RotoZoom = renpy.curry.curry(renpy.display.motion.RotoZoom)
201FactorZoom = renpy.curry.curry(renpy.display.motion.FactorZoom)
202SizeZoom = renpy.curry.curry(renpy.display.motion.SizeZoom)
203Fade = renpy.curry.curry(renpy.display.transition.Fade)
204Dissolve = renpy.curry.curry(renpy.display.transition.Dissolve)
205ImageDissolve = renpy.curry.curry(renpy.display.transition.ImageDissolve)
206AlphaDissolve = renpy.curry.curry(renpy.display.transition.AlphaDissolve)
207CropMove = renpy.curry.curry(renpy.display.transition.CropMove)
208PushMove = renpy.curry.curry(renpy.display.transition.PushMove)
209Pixellate = renpy.curry.curry(renpy.display.transition.Pixellate)
210
211OldMoveTransition = renpy.curry.curry(renpy.display.movetransition.OldMoveTransition)
212MoveTransition = renpy.curry.curry(renpy.display.movetransition.MoveTransition)
213MoveFactory = renpy.curry.curry(renpy.display.movetransition.MoveFactory)
214MoveIn = renpy.curry.curry(renpy.display.movetransition.MoveIn)
215MoveOut = renpy.curry.curry(renpy.display.movetransition.MoveOut)
216ZoomInOut = renpy.curry.curry(renpy.display.movetransition.ZoomInOut)
217RevolveInOut = renpy.curry.curry(renpy.display.movetransition.RevolveInOut)
218
219MultipleTransition = renpy.curry.curry(renpy.display.transition.MultipleTransition)
220ComposeTransition = renpy.curry.curry(renpy.display.transition.ComposeTransition)
221Pause = renpy.curry.curry(renpy.display.transition.NoTransition)
222SubTransition = renpy.curry.curry(renpy.display.transition.SubTransition)
223
224# Misc.
225ADVSpeaker = ADVCharacter = renpy.character.ADVCharacter
226Speaker = Character = renpy.character.Character
227DynamicCharacter = renpy.character.DynamicCharacter
228MultiPersistent = renpy.persistent.MultiPersistent
229
230Action = renpy.ui.Action
231BarValue = renpy.ui.BarValue
232
233AudioData = renpy.audio.audio.AudioData
234
235# NOTE: When exporting something from here, decide if we need to add it to
236# renpy.pyanalysis.pure_functions.
237
238Style = renpy.style.Style # @UndefinedVariable
239
240NoRollback = renpy.python.NoRollback
241
242
243class _layout_class(__builtins__["object"]):
244    """
245    This is used to generate declarative versions of MultiBox and Grid.
246    """
247
248    def __init__(self, cls, doc, nargs=0, **extra_kwargs):
249        self.cls = cls
250        self.nargs = nargs
251        self.extra_kwargs = extra_kwargs
252
253        self.__doc__ = doc
254
255    def __call__(self, *args, **properties):
256
257        conargs = args[:self.nargs]
258        kids = args[self.nargs:]
259
260        kwargs = self.extra_kwargs.copy()
261        kwargs.update(properties)
262
263        rv = self.cls(*conargs, **kwargs)
264        for i in kids:
265            rv.add(renpy.easy.displayable(i))
266
267        return rv
268
269
270Fixed = _layout_class(renpy.display.layout.MultiBox, """
271:name: Fixed
272:doc: disp_box
273:args: (*args, **properties)
274
275A box that fills the screen. Its members are laid out
276from back to front, with their position properties
277controlling their position.
278""", layout="fixed")
279
280HBox = _layout_class(renpy.display.layout.MultiBox, """
281:doc: disp_box
282:args: (*args, **properties)
283
284A box that lays out its members from left to right.
285""", layout='horizontal')
286
287VBox = _layout_class(renpy.display.layout.MultiBox, """
288:doc: disp_box
289:args: (*args, **properties)
290
291A layout that lays out its members from top to bottom.
292""", layout='vertical')
293
294Grid = _layout_class(renpy.display.layout.Grid, """
295:doc: disp_grid
296:args: (cols, rows, *args, **properties)
297
298Lays out displayables in a grid. The first two positional arguments
299are the number of columns and rows in the grid. This must be followed
300by `columns * rows` positional arguments giving the displayables that
301fill the grid.
302""", nargs=2, layout='vertical')
303
304
305def AlphaBlend(control, old, new, alpha=False):
306    """
307    :doc: disp_effects
308
309    This transition uses a `control` displayable (almost always some sort of
310    animated transform) to transition from one displayable to another. The
311    transform is evaluated. The `new` displayable is used where the transform
312    is opaque, and the `old` displayable is used when it is transparent.
313
314    `alpha`
315        If true, the image is composited with what's behind it. If false,
316        the default, the image is opaque and overwrites what's behind it.
317    """
318
319    return renpy.display.transition.AlphaDissolve(control, 0.0, old_widget=old, new_widget=new, alpha=alpha)
320
321
322def At(d, *args):
323    """
324    :doc: disp_at
325
326    Given a displayable `d`, applies each of the transforms in `args`
327    to it. The transforms are applied in left-to-right order, so that
328    the outermost transform is the rightmost argument. ::
329
330        transform birds_transform:
331             xpos -200
332             linear 10 xpos 800
333             pause 20
334             repeat
335
336        image birds = At("birds.png", birds_transform)
337        """
338
339    rv = renpy.easy.displayable(d)
340
341    for i in args:
342
343        if isinstance(i, renpy.display.motion.Transform):
344            rv = i(child=rv)
345        else:
346            rv = i(rv)
347
348    return rv
349
350
351# The color class/function.
352Color = renpy.color.Color
353color = renpy.color.Color
354
355# Conveniently get rid of all the packages we had imported before.
356import renpy.exports as renpy # @Reimport
357
358# The default menu functions.
359menu = renpy.display_menu
360predict_menu = renpy.predict_menu
361
362# The default transition.
363default_transition = None
364
365# Is the mouse visible?
366mouse_visible = True
367
368# Is the overlay suppressed?
369suppress_overlay = False
370
371# The default ADVCharacter.
372adv = ADVCharacter(None,
373                   who_prefix='',
374                   who_suffix='',
375                   what_prefix='',
376                   what_suffix='',
377
378                   show_function=renpy.show_display_say,
379                   predict_function=renpy.predict_show_display_say,
380
381                   condition=None,
382                   dynamic=False,
383                   image=None,
384
385                   interact=True,
386                   slow=True,
387                   slow_abortable=True,
388                   afm=True,
389                   ctc=None,
390                   ctc_pause=None,
391                   ctc_timedpause=None,
392                   ctc_position="nestled",
393                   all_at_once=False,
394                   with_none=None,
395                   callback=None,
396                   type='say',
397                   advance=True,
398
399                   who_style='say_label',
400                   what_style='say_dialogue',
401                   window_style='say_window',
402                   screen='say',
403                   mode='say',
404                   voice_tag=None,
405
406                   kind=False)
407
408# predict_say and who are defined in 00library.rpy, but we add default
409# versions here in case there is a problem with initialization. (And
410# for pickling purposes.)
411
412
413def predict_say(who, what):
414    who = Character(who, kind=adv)
415    try:
416        who.predict(what)
417    except:
418        pass
419
420
421def say(who, what, interact=True, *args, **kwargs):
422    who = Character(who, kind=adv)
423    who(what, interact=interact, *args, **kwargs)
424
425
426# Used by renpy.reshow_say and extend.
427_last_say_who = None
428_last_say_what = None
429_last_say_args = ()
430_last_say_kwargs = { }
431
432# Used to store the things pinned into the cache.
433_cache_pin_set = set()
434
435# Used to store displayables that should be predicted.
436_predict_set = set()
437
438# A map from a screen name to an (args, kwargs) tuple. The arguments and
439# keyword arguments can be
440_predict_screen = dict()
441
442# Should the default screens be shown?
443_overlay_screens = None
444
445# If we're in a replay, the label of the start of the replay.
446_in_replay = None
447
448# Used to store the side image attributes.
449_side_image_attributes = None
450_side_image_attributes_reset = False
451
452# True if we're in the main_menu, False otherwise. This controls autosave,
453# among other things.
454main_menu = False
455
456# The action that's used when the player clicks the ignore button on the
457# error handling screen.
458_ignore_action = None
459
460# The save slot that Ren'Py saves to on quit.
461_quit_slot = None
462
463# The directory in which Ren'Py saves screenshots.
464_screenshot_pattern = None
465
466# Make these available to user code.
467import sys
468import os
469
470
471def public_api():
472    ui
473    im
474    object
475    range
476    sorted
477    os
478    sys
479
480
481del public_api
482