Compare commits

...

99 Commits

Author SHA1 Message Date
Tom Rothamel b159a34e44 Elide the filename when assigning names to statements. 2018-11-09 17:47:50 -05:00
Tom Rothamel 63efa20467 Update the error handling styles at init 9999.
This allows the styles to change to deal with the actual size
of the screen.
2018-11-09 01:23:58 -05:00
Tom Rothamel 17b943693c Allow error handling hyperlink functions to be pickled.
Fixes #1626.
2018-11-09 01:16:54 -05:00
Tom Rothamel 8e09177b6e Ensure the full path to a directory exists in DirectoryPackage.
Fixes #1627.
2018-11-08 22:31:47 -05:00
Tom Rothamel ddaf9f3de3 Check in keywords. 2018-11-08 02:02:15 -05:00
Tom Rothamel 8900d6f3df Update changelog. 2018-11-07 20:48:46 -05:00
Tom Rothamel 2e2f2ea460 Merge pull request #1625 from Beuc/patch-4
Fixes to French translation
2018-11-07 20:28:39 -05:00
Tom Rothamel adb928e234 Merge pull request #1624 from Beuc/patch-3
Fix missing spaces in the_question's screens.rpy
2018-11-07 20:27:56 -05:00
Beuc 53261a7a52 Fixes to French translation 2018-11-07 17:06:17 +01:00
Beuc 2e6f61e673 Fix missing spaces in the_question's screens.rpy 2018-11-07 16:04:31 +01:00
Tom Rothamel 1392cd9dad Allow FilePageNext and FilePagePrevious to choose if they go to auto and quick.
Fixes #1621.
2018-11-07 02:09:49 -05:00
Tom Rothamel c2be31d5de Merge pull request #1622 from Andykl/Transalion_Fix
Fix typos in Russian translate
2018-11-06 12:24:38 -05:00
Andy_kl e419711493 Fix typos in Russian translate 2018-11-06 17:37:43 +03:00
Tom Rothamel c734c5cda1 Merge pull request #1619 from Andykl/Launcher_Adds
Updated working of input screen for launcher
2018-11-05 22:00:28 -05:00
Tom Rothamel bde048b359 Merge pull request #1620 from Andykl/Rework_variable_viewer
Added button which hides deleted variables to the Variable Viewer.
2018-11-04 18:50:08 -05:00
Tom Rothamel 9878ccec4b Store the game version in _version and the json. 2018-11-04 17:41:10 -05:00
Andy_kl 30d8911abf Added button which hides deleted variables to the Variable Viewer. 2018-11-04 23:57:23 +03:00
Tom Rothamel d9ab291a68 Move absolute into minstore and mark as pure. 2018-11-04 12:53:39 -05:00
Tom Rothamel 1bc29461d1 Movie can now take a single movie with color and mask data side by side.
This should prevent movie sprites from going out of sync, by
taking both the color and mask data from a single file.

Fixes #1515.
2018-11-03 17:39:40 -04:00
Tom Rothamel f2e62c571c Document that screens can take positional arguments. 2018-11-03 17:39:40 -04:00
Andy_kl 0208328307 Updated russian translate 2018-11-03 21:38:27 +03:00
Andy_kl 3ee71e9b0d Added text-tag comment for translators. 2018-11-03 21:37:42 +03:00
Andy_kl d83788fa23 Added uppercase letters for translation name 2018-11-03 20:58:21 +03:00
Andy_kl 3c2cebacef Added underscore and space in the names of projects and files 2018-11-03 20:54:17 +03:00
Tom Rothamel 834b9fa1d1 Define centerd and vcentered normally.
Fixes #1347.
2018-11-03 13:17:51 -04:00
Tom Rothamel 9dd55e7b66 Merge pull request #1618 from Andykl/Fix_1161
Fix #1161
2018-11-03 13:16:57 -04:00
Tom Rothamel 857a8a65a2 Update sponsor docs. 2018-11-03 13:04:35 -04:00
Andy_kl dc58e6e8c8 Revert "Fix #1161"
This reverts commit c6dd267772.
2018-11-03 20:00:47 +03:00
Andy_kl 7f8101e2ee Revert "Fix #1045"
This reverts commit c2895f465c.
2018-11-03 19:59:07 +03:00
Andy_kl f7b389a5bc Updated working of input screen 2018-11-03 09:52:07 +03:00
Andy_kl c2895f465c Fix #1045 2018-11-03 06:43:08 +03:00
Andy_kl 075ba4bc49 Fix #1347 2018-11-03 06:41:36 +03:00
Andy_kl c6dd267772 Fix #1161 2018-11-03 04:53:58 +03:00
Tom Rothamel 06443a5f2e Fix typo. 2018-11-02 17:15:29 -04:00
Tom Rothamel ed564397d2 Merge pull request #1615 from Andykl/Fix_Issues
Fix issues with quick_menu on phones and performance encoding.
2018-11-01 22:12:47 -04:00
Andy_kl 66ef5ba2cf Fix #1360 2018-11-01 20:47:17 +03:00
Andy_kl fed3430d76 Fix #1603 2018-11-01 19:12:25 +03:00
Tom Rothamel cca4bf016c Set the compatibility channel looping properly. 2018-10-31 23:34:10 -04:00
Tom Rothamel 432ba06a48 Fix audio crash in moonlight walks. 2018-10-30 23:17:44 -04:00
Tom Rothamel 92fb4098b2 Update changelog. 2018-10-30 22:48:22 -04:00
Tom Rothamel a4340f7798 Merge pull request #1574 from Andykl/Drag_Changes
Extension of the Drag'n'Drop functional
2018-10-30 21:52:18 -04:00
Tom Rothamel 80ec5ad31e Merge pull request #1584 from Andykl/UserStatement_change
Changes in register_statement
2018-10-30 21:52:00 -04:00
Tom Rothamel df4d653b86 Merge pull request #1600 from vollschauer/master
Add delay to renpy.sound.set_volume
2018-10-30 21:50:37 -04:00
Andy_kl bcfa6d126b Doc this 2018-10-31 03:39:34 +03:00
Tom Rothamel 92bd507781 Update the credits. 2018-10-30 00:18:36 -04:00
Tom Rothamel b6966bdc21 Update changelog. 2018-10-30 00:04:27 -04:00
Tom Rothamel 6f5c8975b6 Minor cleanups for the last PR. 2018-10-29 22:38:54 -04:00
Tom Rothamel 35b60303ff Merge pull request #1610 from Andykl/UserLanguage
Added stuff for autodetect language by user's locale
2018-10-29 22:21:08 -04:00
Tom Rothamel 969e269f4d Merge pull request #1611 from KosMos-pv/master
Add missing history_allow_tags set to tutorial and The question.
2018-10-29 21:53:09 -04:00
Konstantin Mozheyko 291af49bc9 Add missing history_allow_tags set to tutorial and The question. 2018-10-29 15:00:20 +02:00
Tom Rothamel ffa33a8f29 Merge pull request #1609 from Beuc/patch-2
emscripten: detect and start configuring accordingly
2018-10-28 23:48:57 -04:00
Tom Rothamel 10e3acf760 Merge pull request #1608 from Beuc/patch-1
Rename IMG_SavePNG* to avoid conflict with PygameSDL2's
2018-10-28 23:48:36 -04:00
Andy_kl 93a9b9deee Doc last 2018-10-29 06:41:51 +03:00
Tom Rothamel 37604894e4 Lint now properly checks images for existence, even in superset cases. 2018-10-28 23:35:58 -04:00
Andy_kl 67717ef9b7 Added configuration variables to control language autodetect. 2018-10-29 06:20:03 +03:00
Andy_kl 43534a758c Added function for detect user locale 2018-10-29 06:14:06 +03:00
Sylvain Beucler bf8e70485d emscripten: detect and start configuring accordingly 2018-10-28 21:51:35 +01:00
Sylvain Beucler b3af65d7ab Rename IMG_SavePNG* to avoid conflict with PygameSDL2's during static linking 2018-10-28 21:15:39 +01:00
Tom Rothamel 6b7260fe39 Report and error out on extraneous arguments.
Because of changes that have been made over the past few years,
it was possible to write:

    show eileen happy but with random attributes appended

And Ren'Py would take it. That was never intended, and this closes
off this case.
2018-10-28 00:59:16 -04:00
Tom Rothamel 4809c16cd9 lint: Have show deal with layeredimages.
It now considers the available attributes when checking the
image.

Fixes #1604.
2018-10-27 23:13:11 -04:00
Tom Rothamel df0e0086c7 Draw underline and strikethrough when a glyph's width is zero.
Fixes #1605.
2018-10-26 22:22:41 -04:00
Tom Rothamel abd01eb734 Create phone choice images.
Fixes renpy/rapt#16.
2018-10-25 21:22:05 -04:00
Tom Rothamel 4818e43632 Allow shift keys in the emulator.
This lets one do shift+I, to inspect styles in small or touch mode.
2018-10-25 21:17:58 -04:00
Tom Rothamel a3ed117153 Lower version to 7.1.2. 2018-10-24 21:26:30 -04:00
Tom Rothamel f73acbdf9f Merge pull request #1602 from ShehriyarQureshi/master
Add checks for tags that require value
2018-10-24 19:07:33 -04:00
Shehriyar Qureshi 0b0c97e2ec Add checks for tags that require value
Some tags that require value, when supplied none, raise python's
exceptions which might be hard to interpret.

Added simple checks to those tags to see if the supplied value is
empty. Raises exception that is easier to read than the ones
Python raises.
2018-10-24 09:49:51 +05:00
Tom Rothamel ffbe373dbb Display the text tag and string when parsing a text tag fails.
Fixes #1598.
2018-10-23 22:30:14 -04:00
Tom Rothamel 3f0e21b174 Merge pull request #1599 from fblampe/master
translation: Translated more strings to German, fixed ellipses.
2018-10-22 18:39:05 -04:00
Unknown d521e79b46 Add delay to renpy.sound.set_volume 2018-10-21 20:17:24 +02:00
Tom Rothamel f725485412 Indicate we require a 64-bit Java. 2018-10-21 11:04:20 -04:00
Felix Lampe e7015b9b88 translation: Translated more strings to German, fixed ellipses. 2018-10-21 14:22:59 +02:00
Tom Rothamel 4b74d34580 gui: Add gui.choice_button_text_insensitive_color 2018-10-21 01:05:26 -04:00
Tom Rothamel 9ca2db8869 Document config.menu_include_disabled. 2018-10-21 00:34:23 -04:00
Tom Rothamel 274934d356 Compat menu actions. 2018-10-20 22:58:51 -04:00
Tom Rothamel 56fe28955a Add config.menu_include_disabled.
This causes Ren'Py to include disabled menu items as part of the
a menu, rather than removing them entirely.
2018-10-19 21:49:50 -04:00
Tom Rothamel ba06e9538b Add requirements to the documentation. 2018-10-18 21:05:31 -04:00
Tom Rothamel e117adb219 Clear kwargs and args from being set inappropriatey.
This is an attempt to fix a bug in Planet Stronghold 2 that was
caused by kwargs being set when it should not have been.
2018-10-18 00:50:33 -04:00
Tom Rothamel 27aa12a5f0 Include the current Ren'Py version in a savefile. 2018-10-17 11:14:35 -04:00
Tom Rothamel 25c39eebf9 Changelog last. 2018-10-17 02:01:56 -04:00
Tom Rothamel 4b4aa38455 Add SetLocalVariable and ToggleLocalVariable
These make it possible to set variables in the local context of a
used screen.
2018-10-16 21:47:47 -04:00
Tom Rothamel c468f8c60e ShowIf should not pass focus when it's hiding.
Fixes #1592.
2018-10-15 23:16:37 -04:00
Tom Rothamel 1d8643045a Merge pull request #1594 from Andykl/Directly_At
Added the ability to specify a transform directly in the SL
2018-10-14 08:38:14 -04:00
Tom Rothamel 51e79498f0 Merge pull request #1577 from Andykl/Displayable_Changes
Avoid skipping displayables with redefined __bool__
2018-10-13 19:37:48 -04:00
Tom Rothamel 06590beca2 Merge pull request #1593 from XelaPy/patch-1
Adds "transpose" keyword to SL2 vpgrid.
2018-10-13 09:39:46 -04:00
Andy_kl 496d5d1c14 Doc for this 2018-10-13 16:18:30 +03:00
Tom Rothamel 96a6f9556c Start the 7.1.2 changelog. 2018-10-12 23:16:44 -04:00
Andy_kl 1ae6255301 Move creating ATLTransform in SLBlock 2018-10-12 21:45:20 +03:00
Andy_kl 207c9ad79b Mark constant for atl_transform 2018-10-12 19:12:18 +03:00
Andy_kl 788ee0399a Rework it 2018-10-12 19:01:01 +03:00
Andy_kl ee1027a8da Added the ability to specify a transform directly in the SL 2018-10-12 18:09:32 +03:00
Xela b3a528ddcc Adds "transpose" keyword to SL2 vpgrid.
Fixes #1560
2018-10-12 15:31:42 +03:00
Tom Rothamel 19204d0f82 Force the size of FriBidiChr to 4 bytes on all problems.
Fixes a problem where on windows it was corrupting RTL text into
garbage.
2018-10-12 01:41:52 -04:00
Andy_kl 1789b5a2ca More correctly check of the block value 2018-09-29 20:50:32 +03:00
Andy_kl bc121ac0cc Added "possible" value for block argument 2018-09-29 20:27:50 +03:00
Andy_kl a2e8a536b4 Added init_priority for register_statement 2018-09-29 20:07:29 +03:00
Andy_kl a6a97a3f4f Avoid skipping displayables with redefined __bool__ 2018-09-22 11:36:32 +03:00
Andy_kl 715899ade4 Added drop_allowable property for Drag class 2018-09-20 07:13:49 +03:00
Andy_kl d829d1ab2f Added min_overlap property 2018-09-20 04:51:16 +03:00
Andy_kl 2069612eff Fix typo 2018-09-20 04:11:30 +03:00
81 changed files with 1487 additions and 703 deletions
+1
View File
@@ -212,6 +212,7 @@ define gui.choice_button_text_size = gui.text_size
define gui.choice_button_text_xalign = 0.5
define gui.choice_button_text_idle_color = "#cccccc"
define gui.choice_button_text_hover_color = "#ffffff"
define gui.choice_button_text_insensitive_color = "#444444"
## File Slot Buttons ###########################################################
+10 -13
View File
@@ -1421,16 +1421,18 @@ screen quick_menu():
zorder 100
hbox:
style_prefix "quick"
if quick_menu:
xalign 0.5
yalign 1.0
hbox:
style_prefix "quick"
textbutton _("Back") action Rollback()
textbutton _("Skip") action Skip() alternate Skip(fast=True, confirm=True)
textbutton _("Auto") action Preference("auto-forward", "toggle")
textbutton _("Menu") action ShowMenu()
xalign 0.5
yalign 1.0
textbutton _("Back") action Rollback()
textbutton _("Skip") action Skip() alternate Skip(fast=True, confirm=True)
textbutton _("Auto") action Preference("auto-forward", "toggle")
textbutton _("Menu") action ShowMenu()
style window:
@@ -1512,8 +1514,3 @@ style slider_pref_vbox:
style slider_pref_slider:
variant "small"
xsize gui.scale(600)
+23 -16
View File
@@ -23,24 +23,32 @@ label add_file:
python hide:
import os
import codecs
filename = ""
while True:
filename = interface.input(
_("FILENAME"),
_("Enter the name of the script file to create."),
allow=interface.FILENAME_LETTERS,
cancel=Jump("navigation"),
default=filename,
)
filename = filename.strip()
if not filename:
interface.error(_("The file name may not be empty."), label=None)
continue
filename = interface.input(_("FILENAME"), _("Enter the name of the script file to create."), filename="withslash", cancel=Jump("navigation"))
if "." in filename and not filename.endswith(".rpy"):
interface.error(_("The filename must have the .rpy extension."), label=None)
continue
elif "." not in filename:
filename += ".rpy"
if "." in filename and not filename.endswith(".rpy"):
interface.error(_("The filename must have the .rpy extension."), label="navigation")
elif "." not in filename:
filename += ".rpy"
path = os.path.join(project.current.gamedir, filename)
dir = os.path.dirname(path)
path = os.path.join(project.current.gamedir, filename)
dir = os.path.dirname(path)
if os.path.exists(path):
interface.error(_("The file already exists."), label="navigation")
contents = u"\uFEFF"
contents += _("# Ren'Py automatically loads all script files ending with .rpy. To use this\n# file, define a label and jump to it from another file.\n")
contents += "\n"
if os.path.exists(path):
interface.error(_("The file already exists."), label=None)
continue
try:
os.makedirs(dir)
@@ -54,4 +62,3 @@ label add_file:
f.write(contents.encode("utf-8"))
jump navigation_refresh
+1 -1
View File
@@ -28,7 +28,7 @@ init python:
ANDROID_OK = 5
NO_RAPT_TEXT = _("To build Android packages, please download RAPT, unzip it, and place it into the Ren'Py directory. Then restart the Ren'Py launcher.")
NO_JDK_TEXT = _("A Java 8 Development Kit is required to build Android packages on Windows. The JDK is different from the JRE, so it's possible you have Java without having the JDK.\n\nPlease {a=http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html}download and install the JDK{/a}, then restart the Ren'Py launcher.")
NO_JDK_TEXT = _("A 64-bit/x64 Java 8 Development Kit is required to build Android packages on Windows. The JDK is different from the JRE, so it's possible you have Java without having the JDK.\n\nPlease {a=http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html}download and install the JDK{/a}, then restart the Ren'Py launcher.")
NO_SDK_TEXT = _("RAPT has been installed, but you'll need to install the Android SDK before you can build Android packages. Choose Install SDK to do this.")
NO_KEY_TEXT = _("RAPT has been installed, but a key hasn't been configured. Please create a new key, or restore android.keystore.")
NO_CONFIG_TEXT = _("The current project has not been configured. Use \"Configure\" to configure it before building.")
+28 -30
View File
@@ -327,25 +327,6 @@ label new_gui_project:
python:
gui_new = True
project_name = interface.input(
_("PROJECT NAME"),
_("Please enter the name of your project:"),
filename=True,
cancel=Jump("front_page"))
project_name = project_name.strip()
if not project_name:
interface.error(_("The project name may not be empty."))
project_dir = os.path.join(persistent.projects_directory, project_name)
if project.manager.get(project_name) is not None:
interface.error(_("[project_name!q] already exists. Please choose a different project name."), project_name=project_name)
if os.path.exists(project_dir):
interface.error(_("[project_dir!q] already exists. Please choose a different project name."), project_dir=project_dir)
gui_replace_images = True
gui_replace_code = True
gui_update_code = True
@@ -369,20 +350,37 @@ label gui_project_size:
if gui_size == "custom":
gui_width = ""
while True:
gui_width = interface.input(
_("WIDTH"),
_("Please enter the width of your game, in pixels."),
cancel=Jump("front_page"),
allow=interface.DIGITS_LETTERS,
)
gui_width = interface.input(_("WIDTH"), _("Please enter the width of your game, in pixels."), cancel=Jump("front_page"))
try:
gui_width = int(gui_width)
except:
interface.error(_("The width must be a number."), label=None)
continue
break
try:
gui_width = int(gui_width)
except:
interface.error(_("The width must be a number."))
gui_height = ""
while True:
gui_height = interface.input(
_("HEIGHT"),
_("Please enter the height of your game, in pixels."),
cancel=Jump("front_page"),
allow=interface.DIGITS_LETTERS,
)
gui_height = interface.input(_("HEIGHT"), _("Please enter the height of your game, in pixels."), cancel=Jump("front_page"))
try:
gui_height = int(gui_height)
except:
interface.error(_("The height must be a number."))
try:
gui_height = int(gui_height)
except:
interface.error(_("The height must be a number."), label=None)
continue
break
gui_size = (gui_width, gui_height)
+4 -11
View File
@@ -25,6 +25,7 @@ import os
from renpy.store import config
import renpy.display
class ImageGenerator(object):
def __init__(self, parameters):
@@ -199,7 +200,6 @@ class ImageGenerator(object):
self.generate_image("textbox", X, Y, self.boring_color.opacity(.8))
YSIZE = 240
YBORDER = 5
@@ -237,7 +237,6 @@ class ImageGenerator(object):
(YSIZE, 1.0),
]
self.generate_image("nvl", X, Y, self.boring_color.opacity(.8))
X = [
@@ -252,8 +251,6 @@ class ImageGenerator(object):
self.generate_image("phone/nvl", X, Y, self.boring_color.opacity(.8))
def generate_choice_button(self):
XSIZE = 790
XINSIDE = 100
@@ -277,6 +274,8 @@ class ImageGenerator(object):
self.generate_image("button/choice_idle_background", X, Y, self.boring_color.opacity(.8))
self.generate_image("button/choice_hover_background", X, Y, self.accent_color.opacity(.95))
self.generate_image("phone/button/choice_idle_background", X, Y, self.boring_color.opacity(.8))
self.generate_image("phone/button/choice_hover_background", X, Y, self.accent_color.opacity(.95))
def generate_overlay(self):
@@ -288,7 +287,6 @@ class ImageGenerator(object):
line_width = self.scale_int(3)
if self.p.light:
opacity = 0.9
else:
@@ -332,7 +330,6 @@ class ImageGenerator(object):
s.subsurface((border, border, width - 2 * border, height - 2 * border)).fill(self.boring_color)
self.save(s, "frame")
def generate_quick_buttons(self):
width = self.scale_int(100)
height = self.scale_int(30)
@@ -379,7 +376,6 @@ class ImageGenerator(object):
self.generate_image("notify", X, Y, self.boring_color.opacity(.8))
def generate_icon(self):
icon_fn = os.path.join(config.renpy_base, "launcher", "game", "gui7", "icon.png")
@@ -406,7 +402,6 @@ class ImageGenerator(object):
self.save(surf, "window_icon", overwrite=False)
def generate_menus(self):
s = self.make_surface(self.width, self.height)
s.fill(self.menu_color)
@@ -414,7 +409,6 @@ class ImageGenerator(object):
self.save(s, "main_menu", overwrite=False)
self.save(s, "game_menu", overwrite=False)
def generate_all(self):
self.generate_textbox()
self.generate_choice_button()
@@ -427,6 +421,7 @@ class ImageGenerator(object):
self.generate_menus()
self.generate_icon()
if __name__ == "__main__":
import argparse
@@ -439,5 +434,3 @@ if __name__ == "__main__":
args = ap.parse_args()
ImageGenerator(args.prefix, args.width, args.height).generate_all()
+22 -6
View File
@@ -251,7 +251,12 @@ screen launcher_input:
add SPACER
input style "l_default" value ScreenVariableInputValue("value", returnable=True) size 24 xalign 0.5 color INPUT_COLOR
input style "l_default":
value ScreenVariableInputValue("value", returnable=True)
size 24
xalign 0.5
color INPUT_COLOR
allow allow
if filename:
add SPACER
@@ -384,7 +389,13 @@ init python in interface:
yield
store._ignore_action = Jump("front_page")
def input(title, message, filename=False, sanitize=True, cancel=None, default=""):
import string
DIGITS_LETTERS = string.digits
PROJECT_LETTERS = DIGITS_LETTERS + string.ascii_letters + " _"
FILENAME_LETTERS = PROJECT_LETTERS + "\\/"
TRANSLATE_LETTERS = string.ascii_letters + "_"
def input(title, message, filename=False, sanitize=True, cancel=None, allow=None, default=""):
"""
Requests typewritten input from the user.
"""
@@ -393,7 +404,15 @@ init python in interface:
while True:
rv = renpy.call_screen("launcher_input", title=title, message=message, filename=filename, cancel=cancel, default=rv)
rv = renpy.call_screen(
"launcher_input",
title=title,
message=message,
filename=filename or (allow in [PROJECT_LETTERS, FILENAME_LETTERS]),
allow=allow,
cancel=cancel,
default=rv
)
if sanitize:
if ("[" in rv) or ("{" in rv):
@@ -507,6 +526,3 @@ init python in interface:
"""
return common(_("CHOICE"), store.QUESTION_COLOR, message, choices=choices, selected=selected, **kwargs)
+39 -34
View File
@@ -62,28 +62,52 @@ label new_project:
if persistent.projects_directory is None:
$ interface.error(_("The projects directory could not be set. Giving up."))
if not persistent.legacy:
python:
if persistent.legacy:
python:
check_language_support()
gui_kind = interface.choice(
_("Which interface would you like to use? The new GUI has a modern look, supports wide screens and mobile devices, and is easier to customize. Legacy themes might be necessary to work with older example code.\n\n[language_support!t]\n\nIf in doubt, choose the new GUI, then click Continue on the bottom-right."),
[ ( 'new_gui_project', _("New GUI Interface") ), ( 'new_theme_project', _("Legacy Theme Interface")) ],
"new_gui_project",
cancel=Jump("front_page"),
)
else:
new_project_language = (_preferences.language or "english").title()
gui_kind = "new_gui_project"
# When translating this, feel free to replace [new_project_language] with the translation of your language.
$ interface.info(_("You will be creating an [new_project_language] language project. Change the launcher language in preferences to create a project in another language."))
jump new_gui_project
# When translating this, feel free to replace [new_project_language] with the translation of your language.
interface.info(_("You will be creating an [new_project_language]{#this substitution may be localized} language project. Change the launcher language in preferences to create a project in another language."))
python:
check_language_support()
gui_kind = interface.choice(
_("Which interface would you like to use? The new GUI has a modern look, supports wide screens and mobile devices, and is easier to customize. Legacy themes might be necessary to work with older example code.\n\n[language_support!t]\n\nIf in doubt, choose the new GUI, then click Continue on the bottom-right."),
[ ( 'new_gui_project', _("New GUI Interface") ), ( 'new_theme_project', _("Legacy Theme Interface")) ],
"new_gui_project",
cancel=Jump("front_page"),
project_name = ""
while True:
project_name = interface.input(
_("PROJECT NAME"),
_("Please enter the name of your project:"),
allow=interface.PROJECT_LETTERS,
cancel=Jump("front_page"),
default=project_name,
)
renpy.jump(gui_kind)
project_name = project_name.strip()
if not project_name:
interface.error(_("The project name may not be empty."), label=None)
continue
project_dir = os.path.join(persistent.projects_directory, project_name)
if project.manager.get(project_name) is not None:
interface.error(_("[project_name!q] already exists. Please choose a different project name."), project_name=project_name, label=None)
continue
if os.path.exists(project_dir):
interface.error(_("[project_dir!q] already exists. Please choose a different project name."), project_dir=project_dir, label=None)
continue
break
jump expression gui_kind
screen select_template:
@@ -125,25 +149,6 @@ screen select_template:
label new_theme_project:
python hide:
project_name = interface.input(
_("PROJECT NAME"),
_("Please enter the name of your project:"),
filename=True,
cancel=Jump("front_page"))
project_name = project_name.strip()
if not project_name:
interface.error(_("The project name may not be empty."))
project_dir = os.path.join(persistent.projects_directory, project_name)
if project.manager.get(project_name) is not None:
interface.error(_("[project_name!q] already exists. Please choose a different project name."), project_name=project_name)
if os.path.exists(project_dir):
interface.error(_("[project_dir!q] already exists. Please choose a different project name."), project_dir=project_dir)
if len(project.manager.templates) == 1:
template = project.manager.templates[0]
else:
+2 -3
View File
@@ -267,7 +267,7 @@ init python in distribute:
def mkdir(self, path):
if not os.path.isdir(path):
os.mkdir(path, 0755)
os.makedirs(path, 0755)
def __init__(self, path):
self.path = path
@@ -278,8 +278,7 @@ init python in distribute:
# If this is not a directory, ensure all parent directories
# have been created
if not os.path.isdir(os.path.dirname(fn)):
os.makedirs(os.path.dirname(fn), 0755)
self.mkdir(os.path.dirname(fn))
shutil.copy2(path, fn)
if xbit:
+29 -17
View File
@@ -7,7 +7,7 @@ translate german strings:
# about.rpy:43
old "View license"
new "Lizenz ansehen"
new "Lizenz anzeigen"
# add_file.rpy:28
old "FILENAME"
@@ -15,7 +15,7 @@ translate german strings:
# add_file.rpy:28
old "Enter the name of the script file to create."
new "Geben Sie den Namen der Script-Datei ein, um sie zu erstellen."
new "Geben Sie den Namen der zu erstellenden Script-Datei ein."
# add_file.rpy:31
old "The filename must have the .rpy extension."
@@ -235,7 +235,7 @@ translate german strings:
# distribute.rpy:443
old "Scanning project files..."
new "Projektdateien werden geprüft"
new "Projektdateien werden geprüft..."
# distribute.rpy:459
old "Building distributions failed:\n\nThe build.directory_name variable may not include the space, colon, or semicolon characters."
@@ -247,7 +247,7 @@ translate german strings:
# distribute.rpy:516
old "Scanning Ren'Py files..."
new "RenPy-Dateien werden geprüft"
new "RenPy-Dateien werden geprüft..."
# distribute.rpy:569
old "All packages have been built.\n\nDue to the presence of permission information, unpacking and repacking the Linux and Macintosh distributions on Windows is not supported."
@@ -255,7 +255,7 @@ translate german strings:
# distribute.rpy:752
old "Archiving files..."
new "Dateien werden archiviert"
new "Dateien werden archiviert..."
# distribute.rpy:1050
old "Unpacking the Macintosh application for signing..."
@@ -335,7 +335,7 @@ translate german strings:
# distribute_gui.rpy:242
old "Force Recompile"
new "Force Recompile"
new "Neu kompilieren"
# distribute_gui.rpy:246
old "Build"
@@ -409,6 +409,10 @@ translate german strings:
old "Open [text] directory."
new "Open [text] directory."
# front_page.rpy:91
old "PROJECTS:"
new "PROJEKTE:"
# front_page.rpy:93
old "refresh"
new "Aktualisieren"
@@ -469,6 +473,10 @@ translate german strings:
old "All script files"
new "Alle Dateien"
# front_page.rpy:221
old "Actions"
new "Aktionen"
# front_page.rpy:223
old "Navigate Script"
new "Skript navigieren"
@@ -479,7 +487,7 @@ translate german strings:
# front_page.rpy:237
old "Change/Update GUI"
new "Change/Update GUI"
new "GUI anpassen/aktualisieren"
# front_page.rpy:239
old "Change Theme"
@@ -487,7 +495,7 @@ translate german strings:
# front_page.rpy:242
old "Delete Persistent"
new "Persistent-Dateien löschen"
new "Persistenz-Dateien löschen"
# front_page.rpy:251
old "Build Distributions"
@@ -511,11 +519,11 @@ translate german strings:
# front_page.rpy:272
old "Checking script for potential problems..."
new "Überprüft Script auf potentielle Probleme"
new "Überprüfe Script auf potentielle Probleme..."
# front_page.rpy:287
old "Deleting persistent data..."
new "Löscht Persistent-Dateien"
new "Lösche Persistent-Dateien..."
# front_page.rpy:295
old "Recompiling all rpy files into rpyc files..."
@@ -879,7 +887,7 @@ translate german strings:
# preferences.rpy:94
old "Projects directory: [text]"
new "Projects directory: [text]"
new "Projektverzeichnis: [text]"
# preferences.rpy:96
old "Not Set"
@@ -891,7 +899,7 @@ translate german strings:
# preferences.rpy:117
old "Text editor: [text]"
new "Text editor: [text]"
new "Texteditor: [text]"
# preferences.rpy:133
old "Update Channel:"
@@ -923,11 +931,15 @@ translate german strings:
# preferences.rpy:174
old "Show edit file section"
new "Show edit file section"
new "'Dateien bearbeiten' anzeigen"
# preferences.rpy:175
old "Large fonts"
new "Large fonts"
new "Große Schriftarten"
# preferences.rpy:182
old "Sponsor message"
new "Sponsoren-Hinweis"
# preferences.rpy:178
old "Console output"
@@ -967,7 +979,7 @@ translate german strings:
# project.rpy:242
old "Ren'Py is scanning the project..."
new "RenPy scannt das Projekt"
new "RenPy scannt das Projekt..."
# project.rpy:568
old "Launching"
@@ -1031,7 +1043,7 @@ translate german strings:
# translations.rpy:224
old "Ren'Py is generating translations...."
new "RenPy erstellt Übersetzungen"
new "RenPy erstellt Übersetzungen..."
# translations.rpy:235
old "Ren'Py has finished generating [language] translations."
@@ -1087,7 +1099,7 @@ translate german strings:
# translations.rpy:374
old "Ren'Py is extracting dialogue...."
new "RenPy extrahiert Dialoge"
new "RenPy extrahiert Dialoge..."
# translations.rpy:378
old "Ren'Py has finished extracting dialogue. The extracted dialogue can be found in dialogue.[persistent.dialogue_format] in the base directory."
+1 -2
View File
@@ -1253,7 +1253,7 @@ translate indonesian strings:
new "Navigasi: [project.current.display_name!q]"
# new_project.rpy:71
old "You will be creating an [new_project_language] language project. Change the launcher language in preferences to create a project in another language."
old "You will be creating an [new_project_language]{#this substitution may be localized} language project. Change the launcher language in preferences to create a project in another language."
new "Kamu akan membuat bahasa proyek : [new_project_language]. Ganti bahasa launcher di pengaturan untuk membuat proyek dalam bahasa lain."
# preferences.rpy:187
@@ -1271,4 +1271,3 @@ translate indonesian strings:
# translations.rpy:343
old "Extract Dialogue: [project.current.display_name!q]"
new "Extrak Dialog: [project.current.display_name!q]"
+1 -2
View File
@@ -1221,7 +1221,7 @@ translate japanese strings:
new "ナビゲーション: [project.current.display_name!q]"
# new_project.rpy:71
old "You will be creating an [new_project_language] language project. Change the launcher language in preferences to create a project in another language."
old "You will be creating an [new_project_language]{#this substitution may be localized} language project. Change the launcher language in preferences to create a project in another language."
new "日本語のプロジェクトを作成します。別の言語のプロジェクトを作成するには、設定でランチャーの言語を変更してください。"
# preferences.rpy:187
@@ -1321,4 +1321,3 @@ translate japanese strings:
# front_page.rpy:221
old "Actions"
new "アクション"
+1 -2
View File
@@ -913,7 +913,7 @@
new "Direktori projek tidak boleh ditetapkan. Putus asa."
# new_project.rpy:71
old "You will be creating an [new_project_language] language project. Change the launcher language in preferences to create a project in another language."
old "You will be creating an [new_project_language]{#this substitution may be localized} language project. Change the launcher language in preferences to create a project in another language."
new "Anda akan mencipta projek bahasa [new_project_language]. Tukar bahasa pelancar dalam menu keutamaan untuk mencipta projek dalam bahasa yang lain."
# new_project.rpy:79
@@ -1263,4 +1263,3 @@
# updater.rpy:201
old "Proceed"
new "Teruskan"
+1 -2
View File
@@ -1130,7 +1130,7 @@ translate piglatin strings:
new "Hetay rojectspay irectoryday ouldcay otnay ebay etsay. Ivinggay upay."
# new_project.rpy:71
old "You will be creating an [new_project_language] language project. Change the launcher language in preferences to create a project in another language."
old "You will be creating an [new_project_language]{#this substitution may be localized} language project. Change the launcher language in preferences to create a project in another language."
new "Ouyay illway ebay reatingcay anay [new_project_language] anguagelay rojectpay. Hangecay hetay auncherlay anguagelay inay referencespay otay reatecay aay rojectpay inay anotheray anguagelay."
# new_project.rpy:79
@@ -1484,4 +1484,3 @@ translate piglatin strings:
# updater.rpy:188
old "Fetching the list of update channels"
new "Etchingfay hetay istlay ofay updateay annelschay"
+7
View File
@@ -813,3 +813,10 @@ translate russian strings:
old "return"
new "вернуться"
# _developer\developer.rpym:154
old "Hide deleted"
new "Скрыть удалённые"
# _developer\developer.rpym:154
old "Show deleted"
new "Показать удалённые"
+15 -7
View File
@@ -21,6 +21,10 @@ translate russian strings:
old "The filename must have the .rpy extension."
new "Имя должно иметь расширение .rpy."
# add_file.rpy:37
old "The file name may not be empty."
new "Имя файла не может быть пустым."
# add_file.rpy:39
old "The file already exists."
new "Файл уже существует."
@@ -31,11 +35,11 @@ translate russian strings:
# android.rpy:30
old "To build Android packages, please download RAPT, unzip it, and place it into the Ren'Py directory. Then restart the Ren'Py launcher."
new "Чтобы построить Android-пакет, пожалуйста, загрузите RAPT, разархивируйте его и поместить в директорию Ren'Py. Затем перезагрузите лаунчер Ren'Py."
new "Чтобы построить Android-пакет, пожалуйста, загрузите RAPT, разархивируйте его, и поместите в директорию Ren'Py. Затем перезагрузите лаунчер Ren'Py."
# android.rpy:31
old "A Java 8 Development Kit is required to build Android packages on Windows. The JDK is different from the JRE, so it's possible you have Java without having the JDK.\n\nPlease {a=http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html}download and install the JDK{/a}, then restart the Ren'Py launcher."
new "Чтобы построить Android-пакеты на Windows требуется инструментарий разработки Java 8. JDK отличен от JRE, и возможно, у вас есть Java без JDK.\n\nПожалуйста, {a=http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html}загрузите и установите JDK{/a}, и перезапустите лаунчер Ren'Py."
old "A 64-bit/x64 Java 8 Development Kit is required to build Android packages on Windows. The JDK is different from the JRE, so it's possible you have Java without having the JDK.\n\nPlease {a=http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html}download and install the JDK{/a}, then restart the Ren'Py launcher."
new "Чтобы построить Android-пакеты на Windows требуется 64-битный инструментарий разработки Java 8. JDK отличен от JRE, и возможно, у вас есть Java без JDK.\n\nПожалуйста, {a=http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html}загрузите и установите JDK{/a}, и перезапустите лаунчер Ren'Py."
# android.rpy:32
old "RAPT has been installed, but you'll need to install the Android SDK before you can build Android packages. Choose Install SDK to do this."
@@ -215,7 +219,7 @@ translate russian strings:
# androidstrings.rpy:17
old "The build seems to have failed."
new "Ой, ошибка со сборкой приключилась..."
new "Похоже, сборка провалилась."
# androidstrings.rpy:18
old "Launching app."
@@ -225,6 +229,10 @@ translate russian strings:
old "The build seems to have succeeded."
new "Кажется, сборка прошла успешно!"
# androidstrings.rpy:20
old "The armeabi-v7a version works on most phones on tablets, while the x86_64 version works on the simulator and chromebooks."
new "Версия armeabi-v7a работает на большинстве смартфонов и планшетов, а версия x86_64 требуется для симуляторов и хромбуков."
# androidstrings.rpy:20
old "What is the full name of your application? This name will appear in the list of installed applications."
new "Каким будет полное имя вашего приложения? Это имя будет представлено в списке установленных приложений."
@@ -367,7 +375,7 @@ translate russian strings:
# androidstrings.rpy:55
old "Do you accept the Android SDK Terms and Conditions?"
new "Вы принимаете условияя и положения пользования Android SDK?"
new "Вы принимаете условия и положения пользования Android SDK?"
# androidstrings.rpy:56
old "I'm downloading the Android SDK. This might take a while."
@@ -1146,8 +1154,8 @@ translate russian strings:
new "Директория проектов не может быть установлена. Сдаюсь."
# new_project.rpy:71
old "You will be creating an [new_project_language] language project. Change the launcher language in preferences to create a project in another language."
new "Вы создаёте проект на языке [new_project_language]. Чтобы создать проект на другом языке, измените язык лаунчера."
old "You will be creating an [new_project_language]{#this substitution may be localized} language project. Change the launcher language in preferences to create a project in another language."
new "Вы создаёте проект на русском языке. Чтобы создать проект на другом языке, измените язык лаунчера."
# new_project.rpy:79
old "Which interface would you like to use? The new GUI has a modern look, supports wide screens and mobile devices, and is easier to customize. Legacy themes might be necessary to work with older example code.\n\n[language_support!t]\n\nIf in doubt, choose the new GUI, then click Continue on the bottom-right."
@@ -898,7 +898,7 @@ translate simplified_chinese strings:
new "传统主题界面"
# new_project.rpy:71
old "You will be creating an [new_project_language] language project. Change the launcher language in preferences to create a project in another language."
old "You will be creating an [new_project_language]{#this substitution may be localized} language project. Change the launcher language in preferences to create a project in another language."
new "您将创建一个 [new_project_language] 语言的工程。要创建其他语言的工程,请在设置里更改启动器语言。"
# new_project.rpy:90
@@ -1248,4 +1248,3 @@ translate simplified_chinese strings:
# dmgcheck.rpy:50
old "This is probably because Ren'Py is running directly from a Macintosh drive image. To fix this, quit this launcher, copy the entire %s folder somewhere else on your computer, and run Ren'Py again."
new "这可能是由于 Ren'Py 直接从 Macintosh 磁盘镜像中运行导致的。要修复此问题,退出启动器,复制整个 %s 文件夹到您计算机的其他任意位置,并重新运行 Ren'Py。"
+1 -1
View File
@@ -914,7 +914,7 @@ translate spanish strings:
new "No se puede establecer el directorio de proyectos. Abandonando."
# new_project.rpy:71
old "You will be creating an [new_project_language] language project. Change the launcher language in preferences to create a project in another language."
old "You will be creating an [new_project_language]{#this substitution may be localized} language project. Change the launcher language in preferences to create a project in another language."
new "Vas a crear un proyecto en idioma [new_project_language]. Cambia el idioma del lanzador en preferencias para crear un proyecto en otro idioma."
# new_project.rpy:79
+1 -1
View File
@@ -116,7 +116,7 @@ screen translate:
value FieldInputValue(persistent, "translate_language")
size 24
color INPUT_COLOR
allow interface.TRANSLATE_LETTERS
# Left side.
frame:
style "l_indent"
+4 -4
View File
@@ -34,7 +34,7 @@
#define png_voidp voidp
#endif
int IMG_SavePNG(const char *file, SDL_Surface *surf,int compression){
int renpy_IMG_SavePNG(const char *file, SDL_Surface *surf,int compression){
SDL_RWops *fp;
int ret;
@@ -44,7 +44,7 @@ int IMG_SavePNG(const char *file, SDL_Surface *surf,int compression){
return (-1);
}
ret=IMG_SavePNG_RW(fp,surf,compression);
ret=renpy_IMG_SavePNG_RW(fp,surf,compression);
SDL_RWclose(fp);
return ret;
}
@@ -54,12 +54,12 @@ static void png_write_data(png_structp png_ptr,png_bytep data, png_size_t length
SDL_RWwrite(rp,data,1,length);
}
int IMG_SavePNG_RW(SDL_RWops *src, SDL_Surface *surf,int compression){
int renpy_IMG_SavePNG_RW(SDL_RWops *src, SDL_Surface *surf,int compression){
png_structp png_ptr;
png_infop info_ptr;
SDL_PixelFormat *fmt=NULL;
SDL_Surface *tempsurf=NULL;
int ret,funky_format;
int ret;
unsigned int i;
png_colorp palette;
Uint8 *palette_alpha=NULL;
+2 -2
View File
@@ -36,14 +36,14 @@ extern "C" {
* Takes a filename, a surface to save, and a compression level. The
* compression level can be 0(min) through 9(max), or -1(default).
*/
DECLSPEC int SDLCALL IMG_SavePNG(const char *file,
DECLSPEC int SDLCALL renpy_IMG_SavePNG(const char *file,
SDL_Surface *surf,
int compression);
/**
* Takes a SDL_RWops pointer, a surface to save, and a compression level.
* compression can be 0(min) through 9(max), or -1(default).
*/
DECLSPEC int SDLCALL IMG_SavePNG_RW(SDL_RWops *src,
DECLSPEC int SDLCALL renpy_IMG_SavePNG_RW(SDL_RWops *src,
SDL_Surface *surf,
int compression);
#ifdef __cplusplus
+1 -1
View File
@@ -31,7 +31,7 @@ void save_png_core(PyObject *pysurf, SDL_RWops *rw, int compress) {
surf = PySurface_AsSurface(pysurf);
/* Can't release GIL, since we're not using threaded RWops. */
IMG_SavePNG_RW(rw, surf, compress);
renpy_IMG_SavePNG_RW(rw, surf, compress);
}
/* This pixellates a 32-bit RGBA pygame surface to a destination
+4 -4
View File
@@ -12,17 +12,17 @@
*
* Copyright (C) 2004 Sharif FarsiWeb, Inc.
* Copyright (C) 2001,2002 Behdad Esfahbod
*
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
*
* You should have received a copy of the GNU Lesser General Public License
* along with this library, in a file named COPYING; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place, Suite 330,
@@ -127,7 +127,7 @@ typedef FRIBIDI_UINT16 fribidi_uint16;
typedef FRIBIDI_UINT32 fribidi_uint32;
typedef FRIBIDI_BOOLEAN fribidi_boolean;
typedef FRIBIDI_UNICHAR FriBidiChar;
typedef FRIBIDI_UINT32 FriBidiChar;
typedef FRIBIDI_STR_INDEX FriBidiStrIndex;
+4
View File
@@ -29,6 +29,10 @@
#define RENPY_GLES_2
#elif defined EMSCRIPTEN
#define RENPY_GLES_2
#elif defined RASPBERRY_PI
#define RENPY_GLES_2
+6 -2
View File
@@ -55,7 +55,7 @@ setup_env("LD")
setup_env("CXX")
import setuplib
from setuplib import android, ios, raspi, include, library, cython, cmodule, copyfile, find_unnecessary_gen
from setuplib import android, ios, emscripten, raspi, include, library, cython, cmodule, copyfile, find_unnecessary_gen
# These control the level of optimization versus debugging.
setuplib.extra_compile_args = [ "-Wno-unused-function" ]
@@ -189,6 +189,10 @@ if (android or ios):
glew_libs = [ 'GLESv2', 'z', 'm' ]
gl2_only = True
egl = "egl_none.c"
elif emscripten:
glew_libs = []
gl2_only = True
egl = "egl_none.c"
elif raspi:
glew_libs = [ 'SDL2', 'GLESv2', 'EGL', 'z', 'm' ]
gl2_only = True
@@ -212,7 +216,7 @@ cython("renpy.gl.glenviron_limited", libs=glew_libs, compile_if=not gl2_only)
cython("renpy.gl.glrtt_copy", libs=glew_libs)
cython("renpy.gl.glrtt_fbo", libs=glew_libs)
if not (android or ios):
if not (android or ios or emscripten):
# renpy.angle
def anglecopy(fn):
copyfile("renpy/gl/" + fn, "renpy/angle/" + fn, "DEF ANGLE = False", "DEF ANGLE = True")
+5 -2
View File
@@ -39,6 +39,9 @@ ios = "RENPY_IOS" in os.environ
# True of we're building on raspberry pi.
raspi = "RENPY_RASPBERRY_PI" in os.environ
# True of we're building with emscripten.
emscripten = "RENPY_EMSCRIPTEN" in os.environ
# Is coverage enabled?
coverage = "RENPY_COVERAGE" in os.environ
@@ -92,7 +95,7 @@ def include(header, directory=None, optional=True):
If given, returns False rather than abandoning the process.
"""
if android or ios:
if android or ios or emscripten:
return True
for i in install:
@@ -131,7 +134,7 @@ def library(name, optional=False):
rather than reporting an error.
"""
if android or ios:
if android or ios or emscripten:
return True
for i in install:
+5 -2
View File
@@ -41,7 +41,7 @@ except ImportError:
vc_version = 0
# The tuple giving the version number.
version_tuple = (7, 2, 0, vc_version)
version_tuple = (7, 1, 2, vc_version)
# The name of this version.
version_name = "On the road again."
@@ -70,6 +70,7 @@ macintosh = False
linux = False
android = False
ios = False
emscripten = False
# Should we enable experimental features and debugging?
experimental = "RENPY_EXPERIMENTAL" in os.environ
@@ -121,11 +122,13 @@ elif platform.mac_ver()[0]:
macintosh = True
elif "ANDROID_PRIVATE" in os.environ:
android = True
elif sys.platform == 'emscripten':
emscripten = True
else:
linux = True
# A flag that's true if we're on a smartphone or tablet-like platform.
mobile = android or ios
mobile = android or ios or emscripten
# A flag that's set to true if the game directory is bundled inside a mac app.
macapp = False
+3 -1
View File
@@ -767,7 +767,6 @@ class Label(Node):
rollback = "force"
translation_relevant = True
__slots__ = [
'name',
'parameters',
@@ -1409,6 +1408,9 @@ class Call(Node):
args, kwargs = self.arguments.evaluate()
renpy.store._args = args
renpy.store._kwargs = kwargs
else:
renpy.store._args = None
renpy.store._kwargs = None
def predict(self):
+2 -2
View File
@@ -335,7 +335,7 @@ class Channel(object):
"""
# Update the channel volume.
vol = self.chan_volume * renpy.game.preferences.volumes[self.mixer]
vol = self.chan_volume * renpy.game.preferences.volumes.get(self.mixer, 1.0)
if vol != self.actual_volume:
renpysound.set_volume(self.number, vol)
@@ -343,7 +343,7 @@ class Channel(object):
# This should be set from something that checks to see if our
# mixer is muted.
force_stop = self.context.force_stop or (renpy.game.preferences.mute[self.mixer] and self.stop_on_mute)
force_stop = self.context.force_stop or (renpy.game.preferences.mute.get(self.mixer, False) and self.stop_on_mute)
if self.playing and force_stop:
renpysound.stop(self.number)
+2 -2
View File
@@ -58,8 +58,8 @@ set_mixer = renpy.audio.music.set_mixer
set_queue_empty_callback = renpy.audio.music.set_queue_empty_callback
def set_volume(volume, channel="sound"):
renpy.audio.music.set_volume(volume, 0, channel=channel)
def set_volume(volume, delay=0, channel="sound"):
renpy.audio.music.set_volume(volume, delay, channel=channel)
def set_pan(pan, delay, channel="sound"):
+49 -6
View File
@@ -157,6 +157,26 @@ init -1600 python:
return cs.scope[self.name] == self.value
# Not pure.
def SetLocalVariable(name, value):
"""
:doc: data_action
Causes the variable `name` to be set to `value` in the current
local context.
This function is only useful in a screen that has been use by
another scene, as it provides a way of setting the value of a
variable inside the used screen. In all other cases,
:func:`SetScreenVariable` should be preferred, as it allows more
of the screen to be cached.
This must be created in the context that the variable is set
in - it can't be passed in from somewhere else.
"""
return SetDict(sys._getframe(1).f_locals, name, value)
@renpy.pure
class ToggleField(Action, FieldEquality):
@@ -224,9 +244,9 @@ init -1600 python:
`true_value`
If not None, then this is the true value we use.
If not None, then this is the true value used.
`false_value`
If not None, then this is the false value we use.
If not None, then this is the false value used.
"""
return ToggleField(store, variable, true_value=true_value, false_value=false_value, kind="variable")
@@ -241,9 +261,9 @@ init -1600 python:
value when the action is performed.
`true_value`
If not None, then this is the true value we use.
If not None, then this is the true value used.
`false_value`
If not None, then this is the false value we use.
If not None, then this is the false value used.
"""
identity_fields = [ "dict", ]
@@ -283,6 +303,29 @@ init -1600 python:
return rv
# Not pure.
def ToggleLocalVariable(name, true_value=None, false_value=None):
"""
:doc: data_action
Toggles the value of `name` in the current local context.
This function is only useful in a screen that has been use by
another scene, as it provides a way of setting the value of a
variable inside the used screen. In all other cases,
:func:`ToggleScreenVariable` should be preferred, as it allows more
of the screen to be cached.
This must be created in the context that the variable is set
in - it can't be passed in from somewhere else.
`true_value`
If not None, then this is the true value used.
`false_value`
If not None, then this is the false value used.
"""
return ToggleDict(sys._getframe(1).f_locals, name, true_value=true_value, false_value=false_value)
@renpy.pure
class ToggleScreenVariable(Action, FieldEquality):
@@ -292,9 +335,9 @@ init -1600 python:
Toggles the value of the variable `name` in the current screen.
`true_value`
If not None, then this is the true value we use.
If not None, then this is the true value used.
`false_value`
If not None, then this is the false value we use.
If not None, then this is the false value used.
"""
equality_fields = [ "name", "true_value", "false_value" ]
+40 -23
View File
@@ -748,26 +748,35 @@ init -1500 python:
class FilePageNext(Action, DictEquality):
"""
:doc: file_action
:doc: file_action
Goes to the next file page.
Goes to the next file page.
`max`
If set, this should be an integer that gives the number of
the maximum file page we can go to.
`max`
If set, this should be an integer that gives the number of
the maximum file page we can go to.
`wrap`
If true, we can go to the first page when on the last file page if max is set.
"""
`wrap`
If true, we can go to the first page when on the
last file page if `max` is set.
`auto`
If true and wrap is set, this can bring the player to
the page of automatic saves.
`quick`
If true and wrap is set, this can bring the player to
the page of automatic saves.
"""
alt = _("Next file page.")
def __init__(self, max=None, wrap=False):
def __init__(self, max=None, wrap=False, auto=True, quick=True):
page = persistent._file_page
if page == "auto":
if config.has_quicksave:
if config.has_quicksave and quick:
page = "quick"
else:
page = "1"
@@ -781,9 +790,9 @@ init -1500 python:
if max is not None:
if page > max:
if wrap:
if config.has_autosave:
if config.has_autosave and auto:
page = "auto"
elif config.has_quicksave:
elif config.has_quicksave and quick:
page = "quick"
else:
page = "1"
@@ -815,40 +824,48 @@ init -1500 python:
Goes to the previous file page, if possible.
`max`
If set, this should be an integer that gives the number of
the maximum file page we can go to. This is required to enable
wrap.
`max`
If set, this should be an integer that gives the number of
the maximum file page we can go to. This is required to enable
wrap.
`wrap`
If true, we can go to the last page when on the first file page if max is set.
`auto`
If true, this can bring the player to
the page of automatic saves.
`quick`
If true, this can bring the player to
the page of automatic saves.
`wrap`
If true, we can go to the last page when on the first file page if max is set.
"""
alt = _("Previous file page.")
def __init__(self, max=None, wrap=False):
def __init__(self, max=None, wrap=False, auto=True, quick=True):
if wrap and max is not None:
max = str(max)
else:
max = None
page = persistent._file_page
if page == "auto":
page = max
elif page == "quick":
if config.has_autosave:
if config.has_autosave and auto:
page = "auto"
else:
page = max
elif page == "1":
if config.has_quicksave:
if config.has_quicksave and quick:
page = "quick"
elif config.has_autosave:
elif config.has_autosave and auto:
page = "auto"
else:
page = max
+3
View File
@@ -180,6 +180,9 @@ init -1900 python:
config.window_auto_show = [ "say" ]
config.window_auto_hide = [ "scene", "call screen" ]
if vesion <= (7, 1, 1):
config.menu_actions = False
# The version of Ren'Py this script is intended for, or
# None if it's intended for the current version.
config.script_version = None
+22 -1
View File
@@ -36,7 +36,7 @@ init -1500 python:
config.default_afm_enable = False
# If not None, the default language to use.
config.default_language = None
config.default_language = "russian"
# If not None, the default value of wait_voice
config.default_wait_for_voice = True
@@ -76,6 +76,13 @@ init 1500 python hide:
if config.default_afm_time is not None:
_preferences.afm_time = config.default_afm_time
if config.enable_language_autodetect:
locale, region = renpy.translation.detect_user_locale()
if locale is not None:
lang_name = config.locale_to_language_function(locale, region)
if lang_name is not None:
config.default_language = lang_name
if config.default_language is not None:
_preferences.language = config.default_language
@@ -115,6 +122,18 @@ init 1500 python hide:
renpy.persistent.save()
raise Exception(error)
init -1500 python:
def _locale_to_language_function(locale, region):
lang_name = renpy.translation.locales.get(region)
if lang_name is not None and lang_name in renpy.known_languages():
return lang_name
lang_name = renpy.translation.locales.get(locale)
if lang_name is not None and lang_name in renpy.known_languages():
return lang_name
config.locale_to_language_function = _locale_to_language_function
init -1500 python:
def _imagemap_auto_function(auto_param, variant):
rv = auto_param % variant
@@ -203,3 +222,5 @@ init -1500:
image text = renpy.ParameterizedText(style="centered_text")
image vtext = renpy.ParameterizedText(style="centered_vtext")
# Set _version to the version when the game was first started.
default _version = config.version
+3 -9
View File
@@ -352,7 +352,7 @@ init -1400:
define irisout = CropMove(1.0, "irisout")
define irisin = CropMove(1.0, "irisin")
# Various uses of PushMove.
define pushright = PushMove(1.0, "pushright")
define pushleft = PushMove(1.0, "pushleft")
@@ -375,6 +375,8 @@ init -1400:
# The default narrator.
define _narrator = Character(None, kind=adv, what_style='say_thought')
define centered = Character(None, what_style="centered_text", window_style="centered_window")
define vcentered = Character(None, what_style="centered_vtext", window_style="centered_window")
init 1400 python:
if not hasattr(store, 'narrator'):
@@ -383,14 +385,6 @@ init 1400 python:
renpy.pure('narrator')
renpy.pure('name_only')
if not hasattr(store, 'centered'):
centered = Character(None, what_style="centered_text", window_style="centered_window")
if not hasattr(store, 'vcentered'):
vcentered = Character(None, what_style="centered_vtext", window_style="centered_window")
renpy.pure('centered')
renpy.pure('vcentered')
# This is necessary to ensure that config.default_transform works.
if config.default_transform:
config.default_transform._show()
+1 -1
View File
@@ -22,7 +22,7 @@
# This is kind of a catch-all file for things that are defined in the library,
# but don't merit their own files.
init -9999:
init 9999:
# Re-run the errorhandling setup, so we can adjust the styles to the new size
# of the screen.
call _errorhandling
+3 -1
View File
@@ -79,8 +79,10 @@ init 1600:
else:
for i, m in enumerate(mixers):
renpy.sound.set_mixer(i, m, default=True)
if m == 'music':
if i >= 3:
renpy.music.set_music(i, True, default=True)
else:
renpy.music.set_music(i, False, default=True)
+19 -7
View File
@@ -30,7 +30,7 @@ screen _developer:
modal True
frame:
style_group ""
style_prefix ""
has side "t c b":
spacing gui._scale(10)
@@ -74,7 +74,7 @@ screen _developer:
screen _image_attributes():
frame:
style_group ""
style_prefix ""
right_padding 0
has side "c b":
@@ -110,13 +110,19 @@ label _image_attributes:
return
screen _variable_viewer(entries):
screen _variable_viewer(all_entries, deleted_entries):
zorder 1010
modal True
default show_deleted = True
python:
if show_deleted:
entries = all_entries
else:
entries = [(n, v) for n, v in all_entries if n not in deleted_entries]
frame:
style_group ""
style_prefix ""
right_padding 0
has side "t c b":
@@ -144,6 +150,9 @@ screen _variable_viewer(entries):
textbutton _(u"Return"):
action Return(True)
if all_entries and deleted_entries:
textbutton (_(u"Hide deleted") if show_deleted else _(u"Show deleted")):
action ToggleScreenVariable("show_deleted")
label _debugger_screen:
@@ -157,6 +166,7 @@ label _debugger_screen:
aRepr.maxstring = 120
entries = [ ]
deleted_entries = set()
for sn, d in renpy.python.store_dicts.items():
@@ -181,11 +191,14 @@ label _debugger_screen:
name = (sn + "." + vn)[6:]
if vn not in d:
deleted_entries.add(name)
entries.append((name, value))
entries.sort(key=lambda e : e[0])
renpy.call_screen("_variable_viewer", entries=entries)
renpy.call_screen("_variable_viewer", all_entries=entries, deleted_entries=deleted_entries)
return
@@ -477,7 +490,7 @@ screen _image_location_picker(image_files):
default filter = ""
frame:
style_group ""
style_prefix ""
has side "t c b":
spacing gui._scale(10)
@@ -651,4 +664,3 @@ init python:
config.underlay.append(renpy.Keymap(
image_load_log = ToggleScreen("_image_load_log")
))
+23 -21
View File
@@ -241,33 +241,35 @@ init label _errorhandling:
color "#405060"
hover_color Color("#048")
# Early hyperlink support.
python hide:
def hyperlink_styler(target):
return style._hyperlink
def hyperlink_function(target):
if target.startswith("http:") or target.startswith("https:"):
try:
import webbrowser
webbrowser.open(target)
except:
pass
if target.startswith("edit:"):
prefix, line, filename = target.split(":", 2)
line = int(line)
renpy.launch_editor([ filename ], line)
style._default.hyperlink_functions = (hyperlink_styler, hyperlink_function, None)
return
# Invokes _errorhanding when this is first loaded.
init:
call _errorhandling
# Early hyperlink support.
init python:
def _error_hyperlink_styler(target):
return style._hyperlink
def _error_hyperlink_function(target):
if target.startswith("http:") or target.startswith("https:"):
try:
import webbrowser
webbrowser.open(target)
except:
pass
if target.startswith("edit:"):
prefix, line, filename = target.split(":", 2)
line = int(line)
renpy.launch_editor([ filename ], line)
style._default.hyperlink_functions = (_error_hyperlink_styler, _error_hyperlink_function, None)
init python:
# The keymap we use before the real keymap is defined.
+18
View File
@@ -27,6 +27,7 @@ from __future__ import print_function
import collections
import os
import renpy
# Can we add more config variables?
locked = False
@@ -719,6 +720,12 @@ translate_files = [ ]
# translated.
translate_comments = [ ]
# Should we trying detect user locale on first launch?
enable_language_autodetect = False
# A function from (locale, region) -> existing language.
locale_to_language_function = None
# Should we pass the full argument list to the say screen?
old_say_args = False
@@ -806,6 +813,8 @@ fast_skipping_callbacks = [ ]
# Should the audio periodic callback run in its own thread.
audio_periodic_thread = True
if renpy.emscripten:
audio_periodic_thread = False
# A list of fonts to preload on Ren'Py startup.
preload_fonts = [ ]
@@ -906,6 +915,15 @@ say_attributes_use_side_image = True
# Does the menu statement show a window by itself, when there is no caption?
menu_showed_window = False
# Should the menu statement produce actions instead of values?
menu_actions = True
# Should disabled menu items be included?
menu_include_disabled = False
# Should we report extraneous attributes?
report_extraneous_attributes = True
del os
del collections
-2
View File
@@ -219,8 +219,6 @@ BarValue = renpy.ui.BarValue
Style = renpy.style.Style # @UndefinedVariable
absolute = renpy.display.core.absolute
NoRollback = renpy.python.NoRollback
+3
View File
@@ -704,6 +704,9 @@ class Button(renpy.display.layout.Window):
self._duplicatable = False
def _duplicate(self, args):
if args and args.args:
args.extraneous()
return self
def predict_one_action(self):
+11 -1
View File
@@ -240,6 +240,13 @@ class DisplayableArguments(renpy.object.Object):
return rv
def extraneous(self):
if renpy.config.developer and renpy.config.report_extraneous_attributes:
raise Exception("Image '{}' does not accept attributes '{}'.".format(
" ".join(self.name),
" ".join(self.args),
))
default_style = renpy.style.Style("default")
@@ -352,6 +359,9 @@ class Displayable(renpy.object.Object):
setting its own _duplicatable flag.
"""
if args and args.args:
args.extraneous()
return self
def _in_current_store(self):
@@ -510,7 +520,7 @@ class Displayable(renpy.object.Object):
for d in self.visit():
if not d:
if d is None:
continue
id_d = id(d)
+29 -5
View File
@@ -47,10 +47,11 @@ def default_drag_group():
return rv
def default_drag_joined(drag):
return [ (drag, 0, 0) ]
def default_drop_allowable(drop, drags):
return True
class Drag(renpy.display.core.Displayable, renpy.python.RevertableObject):
"""
@@ -168,6 +169,12 @@ class Drag(renpy.display.core.Displayable, renpy.python.RevertableObject):
If false, the default, the drag is dropped onto the droppable with
the largest degree of overlap.
`drop_allowable`
A callback that is called to determine whether this drop allow
the current drags dropped onto. It is called with two arguments.
The first is the Drag which determines its sensitivity.
The second is a list of Drags that are being dragged.
Except for `d`, all of the parameters are available as fields (with
the same name) on the Drag object. In addition, after the drag has
been rendered, the following fields become available:
@@ -177,7 +184,7 @@ class Drag(renpy.display.core.Displayable, renpy.python.RevertableObject):
`w`, `h`
The width and height of the Drag's child, in pixels.
"""
"""
focusable = True
@@ -198,6 +205,7 @@ class Drag(renpy.display.core.Displayable, renpy.python.RevertableObject):
drag_raise=True,
dragged=None,
dropped=None,
drop_allowable=default_drop_allowable,
drag_handle=(0.0, 0.0, 1.0, 1.0),
drag_joined=default_drag_joined,
clicked=None,
@@ -219,6 +227,7 @@ class Drag(renpy.display.core.Displayable, renpy.python.RevertableObject):
self.drag_raise = drag_raise
self.dragged = dragged
self.dropped = dropped
self.drop_allowable = drop_allowable
self.drag_handle = drag_handle
self.drag_joined = drag_joined
self.clicked = clicked
@@ -740,6 +749,11 @@ class DragGroup(renpy.display.layout.MultiBox):
All positional parameters to the DragGroup constructor should be
Drags, that are added to the DragGroup.
`min_overlap`
An integer which means the minimum number of pixels at the
overlap so that drop will be allow.
"""
_list_type = renpy.python.RevertableList
@@ -753,6 +767,9 @@ class DragGroup(renpy.display.layout.MultiBox):
replaces = properties.pop("replaces", None)
min_overlap = properties.pop("min_overlap", 0)
self.min_overlap = min_overlap
super(DragGroup, self).__init__(**properties)
if replaces is not None:
@@ -873,7 +890,11 @@ class DragGroup(renpy.display.layout.MultiBox):
overlap = rect_overlap_area(r1, r2)
if overlap >= max_overlap:
if (
overlap >= max_overlap and
overlap >= self.min_overlap and
c.drop_allowable(c, joined)
):
rv = c
max_overlap = overlap
@@ -898,8 +919,11 @@ class DragGroup(renpy.display.layout.MultiBox):
if c.x is None:
continue
if (x >= c.x and y >= c.y and
x < (c.x+c.w) and y < (c.y+c.h)):
if (
x >= c.x and y >= c.y and
x < (c.x + c.w) and y < (c.y + c.h) and
c.drop_allowable(c, joined)
):
return c
def get_children(self):
+5 -1
View File
@@ -77,10 +77,14 @@ def touch_emulator(ev, x, y):
y = 0
elif ev.type == pygame.KEYDOWN and not ios:
if not ev.key in TOUCH_KEYS:
if ev.mod & pygame.KMOD_SHIFT:
pass
elif not ev.key in TOUCH_KEYS:
return None, x, y
elif ev.type == pygame.KEYUP and not ios:
if ev.mod & pygame.KMOD_SHIFT:
pass
if not ev.key in TOUCH_KEYS:
return None, x, y
+7
View File
@@ -433,6 +433,9 @@ class ImageReference(renpy.display.core.Displayable):
def _duplicate(self, args):
if args and args.args:
args.extraneous()
rv = self._copy(args)
rv.target = None
@@ -663,6 +666,10 @@ class DynamicImage(renpy.display.core.Displayable):
return True
def _duplicate(self, args):
if args and args.args:
args.extraneous()
rv = self._copy(args)
rv.target = None
# This does not set _duplicatable, since it should always remain the
+3
View File
@@ -120,6 +120,9 @@ class Container(renpy.display.core.Displayable):
def _duplicate(self, args):
if args and args.args:
args.extraneous()
if not self._duplicatable:
return self
+3
View File
@@ -983,6 +983,9 @@ class Transform(Container):
def _duplicate(self, args):
if args and args.args:
args.extraneous()
if not self._duplicatable:
return self
+35 -6
View File
@@ -137,7 +137,7 @@ def interact():
return fullscreen
def get_movie_texture(channel, mask_channel=None):
def get_movie_texture(channel, mask_channel=None, side_mask=False):
if not renpy.audio.music.get_playing(channel):
return None, False
@@ -145,16 +145,29 @@ def get_movie_texture(channel, mask_channel=None):
c = renpy.audio.music.get_channel(channel)
surf = c.read_video()
if mask_channel:
if side_mask:
if surf is not None:
w, h = surf.get_size()
w //= 2
mask_surf = surf.subsurface((w, 0, w, h))
surf = surf.subsurface((0, 0, w, h))
else:
mask_surf = None
elif mask_channel:
mc = renpy.audio.music.get_channel(mask_channel)
mask_surf = mc.read_video()
else:
mask_surf = None
if mask_channel:
if mask_surf is not None:
# Something went wrong with the mask video.
if surf and mask_surf:
if surf:
renpy.display.module.alpha_munge(mask_surf, surf, renpy.display.im.identity)
else:
surf = None
@@ -228,6 +241,16 @@ class Movie(renpy.display.core.Displayable):
file will be automatically played on `channel` when the Movie is
shown, and automatically stopped when the movie is hidden.
`side_mask`
If true, this tells Ren'Py to use the side-by-side mask mode for
the Movie. In this case, the movie is divided in half. The left
half is used for color information, while the right half is used
for alpha information. The width of the displayable is half the
width of the movie file.
Where possible, `side_mask` should be used over `mask` as it has
no chance of frames going out of sync.
`mask`
If given, this should be the path to a movie file that is used as
the alpha channel of this displayable. The movie file will be
@@ -282,6 +305,7 @@ class Movie(renpy.display.core.Displayable):
mask = None
mask_channel = None
side_mask = False
image = None
@@ -302,7 +326,7 @@ class Movie(renpy.display.core.Displayable):
renpy.audio.music.register_channel(name, renpy.config.movie_mixer, loop=True, stop_on_mute=False, movie=True, framedrop=framedrop)
def __init__(self, fps=24, size=None, channel="movie", play=None, mask=None, mask_channel=None, image=None, play_callback=None, **properties):
def __init__(self, fps=24, size=None, channel="movie", play=None, mask=None, mask_channel=None, image=None, play_callback=None, side_mask=False, **properties):
super(Movie, self).__init__(**properties)
global auto_channel_serial
@@ -314,6 +338,9 @@ class Movie(renpy.display.core.Displayable):
self.channel = channel
self._play = play
if side_mask:
mask = None
self.mask = mask
if mask is None:
@@ -323,6 +350,8 @@ class Movie(renpy.display.core.Displayable):
else:
self.mask_channel = mask_channel
self.side_mask = side_mask
self.ensure_channel(self.channel)
self.ensure_channel(self.mask_channel)
@@ -357,7 +386,7 @@ class Movie(renpy.display.core.Displayable):
if self.size is None:
tex, _ = get_movie_texture(self.channel, self.mask_channel)
tex, _ = get_movie_texture(self.channel, self.mask_channel, self.side_mask)
if playing and (tex is not None):
width, height = tex.get_size()
+35 -4
View File
@@ -873,9 +873,29 @@ def menu(items, set_expr):
# Filter the list of items to only include ones for which the
# condition is true.
items = [ (substitute(label), value)
for label, condition, value in items
if renpy.python.py_eval(condition) ]
if renpy.config.menu_actions:
location=renpy.game.context().current
new_items = [ ]
for label, condition, value in items:
label = substitute(label)
condition = renpy.python.py_eval(condition)
if (not renpy.config.menu_include_disabled) and (not condition):
continue
new_items.append((label, renpy.ui.ChoiceReturn(label, value, location, sensitive=condition)))
items = new_items
else:
items = [ (substitute(label), value)
for label, condition, value in items
if renpy.python.py_eval(condition) ]
# Filter the list of items on the set_expr:
if set_expr:
@@ -904,6 +924,7 @@ def menu(items, set_expr):
set.append(label)
except AttributeError:
set.add(label)
return rv
@@ -1035,7 +1056,11 @@ def display_menu(items,
if not label:
value = None
if value is not None:
if isinstance(value, renpy.ui.ChoiceReturn):
action = value
chosen = action.get_chosen()
elif value is not None:
action = renpy.ui.ChoiceReturn(label, value, location)
chosen = action.get_chosen()
else:
@@ -1612,6 +1637,10 @@ def reload_script():
s = get_screen("menu")
session.pop("_reload_screen", None)
session.pop("_reload_screen_args", None)
session.pop("_reload_screen_kwargs", None)
if not renpy.store.main_menu:
if s is not None:
@@ -1754,6 +1783,8 @@ except:
platform = "Android"
elif renpy.ios:
platform = "iOS"
elif sys.platform == "emscripten":
platform = "emscripten"
else:
platform = "Unknown"
+1 -1
View File
@@ -557,7 +557,7 @@ cdef class GLDraw:
# Pick a texture environment subsystem.
if EGL or renpy.android or renpy.ios or (allow_shader and use_subsystem(
if EGL or renpy.android or renpy.ios or renpy.emscripten or (allow_shader and use_subsystem(
glenviron_shader,
"RENPY_GL_ENVIRON",
"shader",
+42 -25
View File
@@ -139,17 +139,22 @@ def image_exists_imprecise(name):
else:
required.add(i)
for im in renpy.display.image.images:
for im, d in renpy.display.image.images.items():
if im[0] != nametag:
continue
attrs = set(im[1:])
if [ i for i in required if i not in attrs ]:
if [ i for i in banned if i in attrs ]:
continue
if [ i for i in banned if i in attrs ]:
li = getattr(d, "_list_attributes", None)
if li is not None:
attrs = attrs | set(li(im[0], required))
if [ i for i in required if i not in attrs ]:
continue
imprecise_cache.add(name)
@@ -172,18 +177,40 @@ def image_exists_precise(name):
nametag = name[0]
required = set(name[1:])
required = set()
banned = set()
for im in renpy.display.image.images:
for i in name[1:]:
if i[0] == "-":
banned.add(i[1:])
else:
required.add(i)
for im, d in renpy.display.image.images.items():
if im[0] != nametag:
continue
attrs = set(im[1:])
if attrs == required:
precise_cache.add(name)
return True
if attrs - required:
continue
rest = required - attrs
if rest:
try:
da = renpy.display.core.DisplayableArguments()
da.name=( im[0], ) + tuple(i for i in name[1:] if i in attrs)
da.args=tuple(i for i in name[1:] if i in rest)
d._duplicate(da)
except:
continue
precise_cache.add(name)
return True
return False
@@ -202,26 +229,16 @@ def image_exists(name, expression, tag, precise=True):
if expression:
return
namelist = list(name)
names = " ".join(namelist)
# Look for the precise name.
while namelist:
if tuple(namelist) in renpy.display.image.images:
return
namelist.pop()
# If we're not precise, then we have to start looking for images
# that we can possibly match.
if precise:
if image_exists_precise(name):
return
else:
if not precise:
if image_exists_imprecise(name):
return
report("The image named '%s' was not declared.", names)
# If we're not precise, then we have to start looking for images
# that we can possibly match.
if image_exists_precise(name):
return
report("'{}' is not an image.".format(" ".join(name)) )
# Only check each file once.
+1 -1
View File
@@ -425,7 +425,7 @@ def save(slotname, extra_info='', mutate_flag=False):
screenshot = renpy.game.interface.get_screenshot()
json = { "_save_name" : extra_info }
json = { "_save_name" : extra_info, "_renpy_version" : list(renpy.version_tuple), "_version" : renpy.config.version }
for i in renpy.config.save_json_callbacks:
i(json)
+2
View File
@@ -49,6 +49,8 @@ from renpy.translation import translate_string as __ # @UnusedImport
from renpy.python import store_eval as eval
from renpy.display.core import absolute
def _(s):
"""
+3
View File
@@ -93,6 +93,8 @@ def analyze():
return
s = "\n"
s = s.encode("utf-8")
renpy.log.real_stdout.write(s)
renpy.display.log.write(s)
@@ -108,6 +110,7 @@ def analyze():
dt[3],
event.format(*args),
)
s = s.encode("utf-8")
renpy.log.real_stdout.write(s)
renpy.display.log.write(s)
+1
View File
@@ -52,6 +52,7 @@ pure_functions = {
# minstore.py
"_",
"_p",
"absolute",
# defaultstore.py
"ImageReference", "Image", "Frame", "Solid", "LiveComposite", "LiveCrop",
+2
View File
@@ -882,6 +882,7 @@ Keyword("droppable")
Keyword("drag_raise")
Keyword("dragged")
Keyword("dropped")
Keyword("drop_allowable")
Keyword("drag_handle")
Keyword("drag_joined")
Keyword("clicked")
@@ -893,6 +894,7 @@ add(ui_properties)
add(position_properties)
FunctionStatementParser("draggroup", "ui.draggroup", many)
Keyword("min_overlap")
add(ui_properties)
add(position_properties)
+1 -1
View File
@@ -580,7 +580,7 @@ class Script(object):
finally:
self.record_pycode = True
self.assign_names(stmts, fullfn)
self.assign_names(stmts, renpy.parser.elide_filename(fullfn))
if not renpy.macapp:
+15 -1
View File
@@ -39,7 +39,7 @@ import renpy.display
import renpy.pyanalysis
import renpy.sl2
from renpy.display.motion import Transform
from renpy.display.transform import Transform, ATLTransform
from renpy.display.layout import Fixed
from renpy.display.predict import displayable as predict_displayable
@@ -312,6 +312,9 @@ class SLBlock(SLNode):
and child displayables.
"""
# RawBlock from parse or None if not present.
atl_transform = None
def __init__(self, loc):
SLNode.__init__(self, loc)
@@ -377,6 +380,13 @@ class SLBlock(SLNode):
self.has_keyword = bool(self.keyword)
self.keyword_children = [ ]
if self.atl_transform is not None:
self.has_keyword = True
self.atl_transform.mark_constant()
const = self.atl_transform.constant
self.constant = min(self.constant, const)
for i in self.children:
if i.has_keyword:
self.keyword_children.append(i)
@@ -414,6 +424,10 @@ class SLBlock(SLNode):
for i in self.keyword_children:
i.keywords(context)
if self.atl_transform is not None:
transform = ATLTransform(self.atl_transform, context=context.scope)
context.keywords["at"] = transform
style_prefix = context.keywords.pop("style_prefix", NotGiven)
if style_prefix is NotGiven:
+4 -1
View File
@@ -90,7 +90,7 @@ class ShowIf(renpy.display.layout.Container):
if self.show_child:
cw, ch = cr.get_size()
rv = renpy.display.render.Render(cw, ch)
rv.blit(cr, (0, 0))
rv.blit(cr, (0, 0), focus=self.condition)
else:
rv = renpy.display.render.Render(0, 0)
@@ -375,6 +375,7 @@ Keyword("xinitial")
Keyword("yinitial")
Keyword("scrollbars")
Keyword("spacing")
Keyword("transpose")
Style("spacing")
Style("xminimum")
Style("yminimum")
@@ -460,6 +461,7 @@ Keyword("droppable")
Keyword("drag_raise")
Keyword("dragged")
Keyword("dropped")
Keyword("drop_allowable")
Keyword("drag_handle")
Keyword("drag_joined")
Keyword("drag_offscreen")
@@ -472,6 +474,7 @@ Keyword("alternate")
Style("child")
DisplayableParser("draggroup", renpy.display.dragdrop.DragGroup, None, many, replaces=True)
Keyword("min_overlap")
DisplayableParser("mousearea", renpy.display.behavior.MouseArea, 0, replaces=True)
Keyword("hovered")
+9
View File
@@ -220,6 +220,7 @@ class Parser(object):
"""
seen_keywords = set()
block = False
# Parses a keyword argument from the lexer.
def parse_keyword(l, expect):
@@ -244,6 +245,14 @@ class Parser(object):
seen_keywords.add(name)
if name == "at" and block and l.keyword("transform"):
l.require(":")
l.expect_eol()
l.expect_block("ATL block")
expr = renpy.atl.parse_atl(l.subblock_lexer())
target.atl_transform = expr
return
expr = l.comma_expression()
target.keyword.append((name, expr))
+43 -19
View File
@@ -32,7 +32,22 @@ registry = { }
parsers = renpy.parser.ParseTrie()
def register(name, parse=None, lint=None, execute=None, predict=None, next=None, scry=None, block=False, init=False, translatable=False, execute_init=None, label=None, warp=None): # @ReservedAssignment
def register(
name,
parse=None,
lint=None,
execute=None,
predict=None,
next=None,
scry=None,
block=False,
init=False,
translatable=False,
execute_init=None,
init_priority=0,
label=None,
warp=None,
):
"""
:doc: statement_register
:name: renpy.register_statement
@@ -48,7 +63,8 @@ def register(name, parse=None, lint=None, execute=None, predict=None, next=None,
When this is False, the statement does not expect a block. When True, it
expects a block, but leaves it up to the lexer to parse that block. If the
string "script", the block is interpreted as containing one or more
Ren'Py script language statements.
Ren'Py script language statements. If the string "possible", the
block expect condition is determined by the parse function.
`parse`
This is a function that takes a Lexer object. This function should parse the
@@ -99,21 +115,29 @@ def register(name, parse=None, lint=None, execute=None, predict=None, next=None,
`init`
True if this statement should be run at init-time. (If the statement
is not already inside an init block, it's automatically placed inside
an init 0 block.) This calls the execute function, in addition to the
an init block.) This calls the execute function, in addition to the
execute_init function.
`init_priority`
An integer that determines the priority of initialisation of init block.
"""
name = tuple(name.split())
registry[name] = dict(parse=parse,
lint=lint,
execute=execute,
execute_init=execute_init,
predict=predict,
next=next,
scry=scry,
label=label,
warp=warp)
registry[name] = dict(
parse=parse,
lint=lint,
execute=execute,
execute_init=execute_init,
predict=predict,
next=next,
scry=scry,
label=label,
warp=warp,
)
if block not in [True, False, "script", "possible"]:
raise Exception("Unknown \"block\" argument value: {}".format(block))
# The function that is called to create an ast.UserStatement.
def parse_user_statement(l, loc):
@@ -123,21 +147,21 @@ def register(name, parse=None, lint=None, execute=None, predict=None, next=None,
rv = renpy.ast.UserStatement(loc, l.text, l.subblock)
rv.translatable = translatable
if not block:
if block is False:
l.expect_noblock(" ".join(name) + " statement")
l.advance()
elif block is True:
l.expect_block(" ".join(name) + " statement")
elif block == "script":
l.expect_block(" ".join(name) + " statement")
rv.code_block = renpy.parser.parse_block(l.subblock_lexer())
l.advance()
else:
l.expect_block(" ".join(name) + " statement")
l.advance()
l.advance()
finally:
renpy.exports.pop_error_handler()
if init and not l.init:
rv = renpy.ast.Init(loc, [ rv ], 0)
rv = renpy.ast.Init(loc, [rv], init_priority + l.init_offset)
return rv
+30 -32
View File
@@ -640,9 +640,6 @@ cdef class FTFont:
if glyph.split == SPLIT_INSTEAD:
continue
if glyph.width == 0:
continue
x = <int> (glyph.x + xo)
y = <int> (glyph.y + yo)
@@ -668,37 +665,38 @@ cdef class FTFont:
underline_end = min(underline_end, surf.w - 1)
for py from 0 <= py < rows:
if glyph.width > 0:
for py from 0 <= py < rows:
if bmy < 0:
bmy += 1
continue
line = pixels + bmy * pitch + bmx * 4
gline = cache.bitmap.buffer + py * cache.bitmap.pitch + pxstart
for px from 0 <= px < width:
alpha = gline[0]
# Modulate Sa by the glyph's alpha.
alpha = (alpha * Sa + Sa) >> 8
# Only draw if we increase the alpha - a cheap way to
# allow overlapping characters.
if line[3] < alpha:
line[0] = Sr
line[1] = Sg
line[2] = Sb
line[3] = alpha
gline += 1
line += 4
if bmy < 0:
bmy += 1
continue
line = pixels + bmy * pitch + bmx * 4
gline = cache.bitmap.buffer + py * cache.bitmap.pitch + pxstart
for px from 0 <= px < width:
alpha = gline[0]
# Modulate Sa by the glyph's alpha.
alpha = (alpha * Sa + Sa) >> 8
# Only draw if we increase the alpha - a cheap way to
# allow overlapping characters.
if line[3] < alpha:
line[0] = Sr
line[1] = Sg
line[2] = Sb
line[3] = alpha
gline += 1
line += 4
bmy += 1
# Underlining.
if underline:
+232 -178
View File
@@ -875,212 +875,250 @@ class Layout(object):
for type, text in tokens: # @ReservedAssignment
if type == PARAGRAPH:
try:
# Note that this code is duplicated for the p tag, and for
# the empty line case, below.
fill_empty_line()
if type == PARAGRAPH:
paragraphs.append(line)
line = [ ]
# Note that this code is duplicated for the p tag, and for
# the empty line case, below.
fill_empty_line()
continue
paragraphs.append(line)
line = [ ]
elif type == TEXT:
line.extend(tss[-1].subsegment(text))
continue
continue
elif type == DISPLAYABLE:
line.append((DisplayableSegment(tss[-1], text, renders), u""))
continue
elif type == TEXT:
line.extend(tss[-1].subsegment(text))
continue
# Otherwise, we have a text tag.
elif type == DISPLAYABLE:
line.append((DisplayableSegment(tss[-1], text, renders), u""))
continue
tag, _, value = text.partition("=")
# Otherwise, we have a text tag.
if tag and tag[0] == "/":
tss.pop()
tag, _, value = text.partition("=")
if not tss:
raise Exception("%r closes a text tag that isn't open." % text)
if tag and tag[0] == "/":
tss.pop()
elif tag == "_start":
fs = FlagSegment()
line.append((fs, ""))
self.start_segment = fs
if not tss:
raise Exception("%r closes a text tag that isn't open." % text)
elif tag == "_end":
fs = FlagSegment()
line.append((fs, ""))
self.end_segment = fs
elif tag == "_start":
fs = FlagSegment()
line.append((fs, ""))
self.start_segment = fs
elif tag == "p":
# Duplicated from the newline tag.
fill_empty_line()
elif tag == "_end":
fs = FlagSegment()
line.append((fs, ""))
self.end_segment = fs
paragraphs.append(line)
line = [ ]
elif tag == "p":
# Duplicated from the newline tag.
fill_empty_line()
elif tag == "space":
width = self.scale_int(int(value))
line.append((SpaceSegment(tss[-1], width=width), u""))
paragraphs.append(line)
line = [ ]
elif tag == "vspace":
# Duplicates from the newline tag.
elif tag == "space":
height = self.scale_int(int(value))
if len(value) < 1:
raise Exception("empty value supplied for tag %r" % tag)
if line:
width = self.scale_int(int(value))
line.append((SpaceSegment(tss[-1], width=width), u""))
elif tag == "vspace":
if len(value) < 1:
raise Exception("empty value supplied for tag %r" % tag)
# Duplicates from the newline tag.
height = self.scale_int(int(value))
if line:
paragraphs.append(line)
line = [ (SpaceSegment(tss[-1], height=height), u"") ]
paragraphs.append(line)
line = [ (SpaceSegment(tss[-1], height=height), u"") ]
paragraphs.append(line)
line = [ ]
line = [ ]
elif tag == "w":
pass
elif tag == "w":
pass
elif tag == "fast":
pass
elif tag == "fast":
pass
elif tag == "nw":
pass
elif tag == "nw":
pass
elif tag == "a":
self.has_hyperlinks = True
elif tag == "a":
self.has_hyperlinks = True
hyperlink_styler = style.hyperlink_functions[0]
hyperlink_styler = style.hyperlink_functions[0]
if hyperlink_styler:
hls = hyperlink_styler(value)
else:
hls = style
old_prefix = hls.prefix
link = len(self.hyperlink_targets) + 1
self.hyperlink_targets[link] = value
if not text_displayable.hyperlink_sensitive(value):
hls.set_prefix("insensitive_")
elif (renpy.display.focus.get_focused() is text_displayable) and (renpy.display.focus.argument == link):
hls.set_prefix("hover_")
else:
hls.set_prefix("idle_")
ts = push()
# inherit vertical style
vert_style = ts.vertical
size = ts.size
ts.take_style(hls, self)
ts.vertical = vert_style
ts.hyperlink = link
if renpy.config.hyperlink_inherit_size:
ts.size = size
hls.set_prefix(old_prefix)
elif tag == "b":
push().bold = True
elif tag == "i":
push().italic = True
elif tag == "u":
if value:
push().underline = self.scale_int(int(value))
else:
push().underline = self.scale_int(1)
elif tag == "s":
push().strikethrough = True
elif tag == "plain":
ts = push()
ts.bold = False
ts.italic = False
ts.underline = False
ts.strikethrough = False
elif tag == "":
style = getattr(renpy.store.style, value)
push().take_style(style, self)
elif tag == "font":
push().font = value
elif tag == "size":
if len(value) < 1:
raise Exception("empty value supplied for tag %r" % tag)
if value[0] in "+-":
push().size += int(value)
else:
push().size = int(value)
elif tag == "color":
if len(value) < 1:
raise Exception("empty value supplied for tag %r" % tag)
push().color = renpy.easy.color(value)
elif tag == "outlinecolor":
if len(value) < 1:
raise Exception("empty value supplied for tag %r" % tag)
push().outline_color = renpy.easy.color(value)
elif tag == "alpha":
if len(value) < 1:
raise Exception("empty value supplied for tag %r" % tag)
ts = push()
if value[0] in "+-":
value = ts.color.alpha + float(value)
elif value[0] == "*":
value = ts.color.alpha * float(value[1:])
else:
value = float(value)
ts.color = ts.color.replace_opacity(value)
elif tag == "k":
if len(value) < 1:
raise Exception("empty value supplied for tag %r" % tag)
push().kerning = self.scale(float(value))
elif tag == "rt":
ts = push()
# inherit vertical style
vert_style = ts.vertical
ts.take_style(style.ruby_style, self)
ts.vertical = vert_style
ts.ruby_top = True
self.has_ruby = True
elif tag == "art":
ts = push()
# inherit vertical style
vert_style = ts.vertical
ts.take_style(style.altruby_style, self)
ts.vertical = vert_style
ts.ruby_top = "alt"
self.has_ruby = True
elif tag == "rb":
push().ruby_bottom = True
# We only care about ruby if we have a top.
elif tag == "cps":
if len(value) < 1:
raise Exception("empty value supplied for tag %r" % tag)
ts = push()
if value[0] == "*":
ts.cps *= float(value[1:])
else:
ts.cps = float(value)
elif tag == "vert":
push().vertical = True
elif tag == "horiz":
ts = push()
ts.vertical = False
elif tag[0] == "#":
pass
if hyperlink_styler:
hls = hyperlink_styler(value)
else:
hls = style
raise Exception("Unknown text tag %r" % text)
old_prefix = hls.prefix
link = len(self.hyperlink_targets) + 1
self.hyperlink_targets[link] = value
if not text_displayable.hyperlink_sensitive(value):
hls.set_prefix("insensitive_")
elif (renpy.display.focus.get_focused() is text_displayable) and (renpy.display.focus.argument == link):
hls.set_prefix("hover_")
else:
hls.set_prefix("idle_")
ts = push()
# inherit vertical style
vert_style = ts.vertical
size = ts.size
ts.take_style(hls, self)
ts.vertical = vert_style
ts.hyperlink = link
if renpy.config.hyperlink_inherit_size:
ts.size = size
hls.set_prefix(old_prefix)
elif tag == "b":
push().bold = True
elif tag == "i":
push().italic = True
elif tag == "u":
if value:
push().underline = self.scale_int(int(value))
else:
push().underline = self.scale_int(1)
elif tag == "s":
push().strikethrough = True
elif tag == "plain":
ts = push()
ts.bold = False
ts.italic = False
ts.underline = False
ts.strikethrough = False
elif tag == "":
style = getattr(renpy.store.style, value)
push().take_style(style, self)
elif tag == "font":
push().font = value
elif tag == "size":
if value[0] in "+-":
push().size += int(value)
else:
push().size = int(value)
elif tag == "color":
push().color = renpy.easy.color(value)
elif tag == "outlinecolor":
push().outline_color = renpy.easy.color(value)
elif tag == "alpha":
ts = push()
if value[0] in "+-":
value = ts.color.alpha + float(value)
elif value[0] == "*":
value = ts.color.alpha * float(value[1:])
else:
value = float(value)
ts.color = ts.color.replace_opacity(value)
elif tag == "k":
push().kerning = self.scale(float(value))
elif tag == "rt":
ts = push()
# inherit vertical style
vert_style = ts.vertical
ts.take_style(style.ruby_style, self)
ts.vertical = vert_style
ts.ruby_top = True
self.has_ruby = True
elif tag == "art":
ts = push()
# inherit vertical style
vert_style = ts.vertical
ts.take_style(style.altruby_style, self)
ts.vertical = vert_style
ts.ruby_top = "alt"
self.has_ruby = True
elif tag == "rb":
push().ruby_bottom = True
# We only care about ruby if we have a top.
elif tag == "cps":
ts = push()
if value[0] == "*":
ts.cps *= float(value[1:])
else:
ts.cps = float(value)
elif tag == "vert":
push().vertical = True
elif tag == "horiz":
ts = push()
ts.vertical = False
elif tag[0] == "#":
pass
else:
raise Exception("Unknown text tag %r" % text)
except:
renpy.game.exception_info = "While processing text tag {{{!s}}} in {!r}.:".format(text, text_displayable.get_all_text())
raise
# If the line is empty, fill it with a space.
fill_empty_line()
@@ -1417,6 +1455,10 @@ class Text(renpy.display.core.Displayable):
self.displayable_offsets = [ ]
def _duplicate(self, args):
if args and args.args:
args.extraneous()
if self._duplicatable:
rv = self._copy(args)
rv._unique()
@@ -1453,6 +1495,18 @@ class Text(renpy.display.core.Displayable):
s = s.replace("\\", "\\\\").replace("\"", "\\\"").replace("\n", "\\n")
return u"Text \"{}\"".format(s)
def get_all_text(self):
"""
Gets all the text,
"""
s = u""
for i in self.text:
if isinstance(i, basestring):
s += i
return s
def _scope(self, scope, update=True):
"""
Called to update the scope, when necessary.
+217
View File
@@ -681,3 +681,220 @@ def known_languages():
"""
return { i for i in renpy.game.script.translator.languages if i is not None } # @UndefinedVariable
################################################################################
# Detect language
################################################################################
locales = {
"ab": "abkhazian",
"aa": "afar",
"af": "afrikaans",
"ak": "akan",
"sq": "albanian",
"am": "amharic",
"ar": "arabic",
"an": "aragonese",
"hy": "armenian",
"as": "assamese",
"av": "avaric",
"ae": "avestan",
"ay": "aymara",
"az": "azerbaijani",
"bm": "bambara",
"ba": "bashkir",
"eu": "basque",
"be": "belarusian",
"bn": "bengali",
"bh": "bihari",
"bi": "bislama",
"bs": "bosnian",
"br": "breton",
"bg": "bulgarian",
"my": "burmese",
"ca": "catalan",
"ch": "chamorro",
"ce": "chechen",
"ny": "chewa",
"cv": "chuvash",
"kw": "cornish",
"co": "corsican",
"cr": "cree",
"hr": "croatian",
"cs": "czech",
"da": "danish",
"dv": "maldivian",
"nl": "dutch",
"dz": "dzongkha",
"en": "english",
"et": "estonian",
"ee": "ewe",
"fo": "faroese",
"fj": "fijian",
"fi": "finnish",
"fr": "french",
"ff": "fulah",
"gl": "galician",
"ka": "georgian",
"de": "german",
"el": "greek",
"gn": "guaran",
"gu": "gujarati",
"ht": "haitian",
"ha": "hausa",
"he": "hebrew",
"hz": "herero",
"hi": "hindi",
"ho": "hiri_motu",
"hu": "hungarian",
"id": "indonesian",
"ga": "irish",
"ig": "igbo",
"ik": "inupiaq",
"is": "icelandic",
"it": "italian",
"iu": "inuktitut",
"ja": "japanese",
"jv": "javanese",
"kl": "greenlandic",
"kn": "kannada",
"kr": "kanuri",
"ks": "kashmiri",
"kk": "kazakh",
"km": "khmer",
"ki": "kikuyu",
"rw": "kinyarwanda",
"ky": "kirghiz",
"kv": "komi",
"kg": "kongo",
"ko": "korean",
"ku": "kurdish",
"kj": "kuanyama",
"la": "latin",
"lb": "luxembourgish",
"lg": "ganda",
"li": "limburgan",
"ln": "lingala",
"lo": "lao",
"lt": "lithuanian",
"lv": "latvian",
"gv": "manx",
"mk": "macedonian",
"mg": "malagasy",
"ms": "malay",
"ml": "malayalam",
"mt": "maltese",
"mi": "maori",
"mr": "marathi",
"mh": "marshallese",
"mn": "mongolian",
"na": "nauru",
"nv": "navaho",
"ne": "nepali",
"ng": "ndonga",
"no": "norwegian",
"ii": "nuosu",
"nr": "ndebele",
"oc": "occitan",
"oj": "ojibwa",
"om": "oromo",
"or": "oriya",
"os": "ossetian",
"pa": "panjabi",
"pi": "pali",
"fa": "persian",
"pl": "polish",
"ps": "pashto",
"pt": "portuguese",
"qu": "quechua",
"rm": "romansh",
"rn": "rundi",
"ro": "romanian",
"ru": "russian",
"sa": "sanskrit",
"sc": "sardinian",
"sd": "sindhi",
"se": "sami",
"sm": "samoan",
"sg": "sango",
"sr": "serbian",
"gd": "gaelic",
"sn": "shona",
"si": "sinhala",
"sk": "slovak",
"sl": "slovene",
"so": "somali",
"st": "sotho",
"es": "spanish",
"su": "sundanese",
"sw": "swahili",
"ss": "swati",
"sv": "swedish",
"ta": "tamil",
"te": "telugu",
"tg": "tajik",
"th": "thai",
"ti": "tigrinya",
"bo": "tibetan",
"tk": "turkmen",
"tl": "tagalog",
"tn": "tswana",
"to": "tongan",
"tr": "turkish",
"ts": "tsonga",
"tt": "tatar",
"tw": "twi",
"ty": "tahitian",
"ug": "uighur",
"uk": "ukrainian",
"ur": "urdu",
"uz": "uzbek",
"ve": "venda",
"vi": "vietnamese",
"wa": "walloon",
"cy": "welsh",
"wo": "wolof",
"fy": "frisian",
"xh": "xhosa",
"yi": "yiddish",
"yo": "yoruba",
"za": "zhuang",
"zu": "zulu",
"chs": "simplified_chinese",
"cht": "traditional_chinese",
"zh": "traditional_chinese",
}
def detect_user_locale():
import locale
if renpy.windows:
import ctypes
windll = ctypes.windll.kernel32
locale_name = locale.windows_locale.get(windll.GetUserDefaultUILanguage())
elif renpy.android:
from jnius import autoclass
Locale = autoclass('java.util.Locale')
locale_name = str(Locale.getDefault().getLanguage())
elif renpy.ios:
import pyobjus
NSLocale = pyobjus.autoclass("NSLocale")
languages = NSLocale.preferredLanguages()
locale_name = languages.objectAtIndex_(0).UTF8String().decode("utf-8")
locale_name.replace("-", "_")
else:
locale_name = locale.getdefaultlocale()
if locale_name is not None:
locale_name = locale_name[0]
if locale_name is None:
return None, None
normalize = locale.normalize(locale_name)
if normalize == locale_name:
language = region = locale_name
else:
locale_name = normalize
if '.' in locale_name:
locale_name, _ = locale_name.split('.', 1)
language, region = locale_name.lower().split("_")
return language, region
+6 -2
View File
@@ -662,10 +662,13 @@ class ChoiceActionBase(Action):
previously visited and mark it so if it is chosen.
"""
def __init__(self, label, value, location=None, block_all=None):
sensitive = True
def __init__(self, label, value, location=None, block_all=None, sensitive=True):
self.label = label
self.value = value
self.location = location
self.sensitive = sensitive
if block_all is None:
self.block_all = renpy.config.fix_rollback_without_choice
@@ -681,7 +684,8 @@ class ChoiceActionBase(Action):
self.chosen = renpy.game.persistent._chosen = { }
def get_sensitive(self):
return not renpy.exports.in_fixed_rollback() or (not self.block_all and self.get_selected())
return (self.sensitive and
not renpy.exports.in_fixed_rollback() or (not self.block_all and self.get_selected()))
def get_selected(self):
roll_forward = renpy.exports.roll_forward_info()
+31
View File
@@ -236,6 +236,37 @@ Please think twice about archiving your game. Keeping files open will
help others run your game on future platforms platforms that may not
exist until after you're gone.
Requirements
------------
Some stores ask the requirements for Ren'Py applications to run. While
this varies from game to game, here's a set of minimums for a generic
visual novel.
**Windows**
* Version: Windows XP or higher.
* CPU: 2.0 GHz Core 2 Duo
* RAM: 2.0 GB
* Graphics: OpenGL 2.0 or DirectX 9.0c
**macOS**
* Version: 10.6+
* CPU: 2.0 GHz Core 2 Duo (64 bit only)
* RAM: 2.0 GB
* Graphics: OpenGL 2.0
**Linux**
* Version: Ubuntu 12.04+
* CPU: 2.0 GHz Core 2 Duo
* RAM: 2.0 GB
* Graphics: OpenGL 2.0
The amount of disk space required is entirely determined by the assets in your
game, and the amount of CPU and RAM needed may also vary.
Build Functions
---------------
+80
View File
@@ -2,7 +2,87 @@
Full Changelog
==============
.. _renpy-7.1.2:
7.1.2
=====
Improvements
------------
Ren'Py's screen language now support the inclusion of anonymous ATL
transforms. It's now possible to write::
screen hello_title():
text "Hello.":
at transform:
align (0.5, 0.5) alpha 0.0
linear 0.5 alpha 1.0
The new :func:`SetLocalVariable` and :func:`ToggleLocalVariable` actions
make it possible to set variables inside used screens.
The new :var:`config.menu_include_disabled` variable determines if menus
should include entries disabled by an if clause.
Shift-keybindings (like shift+I and shift+R) now work in the android
emulation mode.
Ren'Py now better reports errors in text tags that require a value but are
not given one.
The new :var:`_version` variable indicates the version of the game itself
that was used when a new game is first created. This only stores the version
at game creation - after that, it's up to the creator to keep it updated.
The :func:`Movie` displayable now supports a new mode the color data and
alpha mask data are placed side-by-side in the same file. This prevents
issues where a main and mask movie could go out of sync.
The :func:`FilePageNext` and :func:`FilePagePrevious` functions now take
arguments that control if the they can bring the player to the auto or
quick save pages.
Translations
------------
Ren'Py now has the ability to automatically detect the locale of the user's
system, and use it to set the language. Please see
:var:`config.enable_language_autodetect` and the :ref:`Translation <translation>`
documentation for how this works.
The French, German, Korean, and Russian translations have been updated.
Fixes
-----
A Windows-specific bug that caused RTL (the support for languages like
Arabic and Hebrew) to corrupt the second half of text strings has been
fixed. This should prevent garbage characters from being displayed when
rendering those languages.
Ren'Py will now report an error if a game accesses an image that does not
exist, but has as a prefix an image that does exist. Before this change,
if ``eileen happy`` exists and ``eileen happy unknown`` was shown, the
additional attribute would be ignored.
Lint has been improved to deal with images that take attributes that are
not in the image name, like layered images.
Ren'Py generates choice menu images that are suitable for use on the phone.
Android Fixes
-------------
As Ren'Py's new Android support only worked well on a 64-bit version of
Java 8, we make that 64-bit requirement explicit.
.. _renpy-7.1.1:
7.1.1
=====
.. _history-7.1.1:
History Fix
+21
View File
@@ -389,6 +389,12 @@ Occasionally Used
The default implementation of this uses the narrator character to
display a blank line without interacting.
.. var:: config.enable_language_autodetect = False
If true, Ren'Py will attempt to determine the name of the language
to use based on the locale of the player's system. If successful,
this languagfe will be used as the default language.
.. var:: config.enter_sound = None
If not None, this is a sound file that is played when entering the
@@ -520,6 +526,16 @@ Occasionally Used
If not None, this should be a string giving the default language
that the game is translated into by the translation framework.
.. var:: config.locale_to_language_function = ...
A function that determines the language the game should use,
based on the the user's locale.
It takes 2 arguments strings that give the the ISO code of the locale
and the ISO code of the region.
It should return a string giving the name of a translation to use, or
None to use the default translation.
.. var:: config.main_menu = [ ... ]
The default main menu, when not using screens. For more details,
@@ -534,6 +550,11 @@ Occasionally Used
A list of layer names (as strings) that are cleared when entering
the game menu.
.. var:: config.menu_include_disabled = False
When this variable is set, choices disables with the if statement are
included as disabled buttons.
.. var:: config.menu_window_subtitle = ""
The :var:`_window_subtitle` variable is set to this value when entering
+4
View File
@@ -56,6 +56,7 @@ the omission in future versions.
* Eniko
* Eevee (Lexy Munroe)
* Evilantishad0w
* Felix Lampe
* Franck_v
* Gas
* George Economidis
@@ -82,6 +83,7 @@ the omission in future versions.
* Kevin Turner
* Kinsman
* Koichi "vbkaisetsu" Akabe
* Konstantin Mozheyko
* Konstantin Nikolayev
* Kuroonehalf
* Kyouryuukunn
@@ -126,10 +128,12 @@ the omission in future versions.
* Saltome
* Sapphi
* Scout
* Shehriyar Qureshi
* Shiz
* SleepKirby
* Spiky Caterpillar
* Susnux
* Sylvain Beucler
* Thuong Nguyen Huu
* Tlm-2501
* Tmrwiz
File diff suppressed because one or more lines are too long
+2 -1
View File
@@ -65,4 +65,5 @@ true. In the following menu::
...
The third choice will only be presented if the ``drank_tea`` variable is
true.
true. (However if, the :var:`config.menu_include_disabled` variable is set
to True, it will be shown as a disabled button.)
+10 -12
View File
@@ -1408,16 +1408,18 @@ screen quick_menu():
zorder 100
hbox:
style_prefix "quick"
if quick_menu:
xalign 0.5
yalign 1.0
hbox:
style_prefix "quick"
textbutton _("Back") action Rollback()
textbutton _("Skip") action Skip() alternate Skip(fast=True, confirm=True)
textbutton _("Auto") action Preference("auto-forward", "toggle")
textbutton _("Menu") action ShowMenu()
xalign 0.5
yalign 1.0
textbutton _("Back") action Rollback()
textbutton _("Skip") action Skip() alternate Skip(fast=True, confirm=True)
textbutton _("Auto") action Preference("auto-forward", "toggle")
textbutton _("Menu") action ShowMenu()
style window:
@@ -1455,7 +1457,3 @@ style slider_pref_vbox:
style slider_pref_slider:
variant "small"
xsize 900
+20 -11
View File
@@ -169,10 +169,25 @@ allow the game to react to various events.
All user interface statements take the following common properties:
`at`
A transform, or list of transforms, that are used to wrap this
displayable. The show, hide, replace, and replaced external events
are delivered to a transform if and only if it is added directly
to the screen.
This can be a transform, or a list of transforms, or an anonymous
transform (a transform that is defined directly in at)
::
transform hello_t:
align (0.7, 0.5) alpha 0.0
linear 0.5 alpha 1.0
screen hello_title():
text "Hello." at hello_t
text "Hello.":
at transform:
align (0.2, 0.5) alpha 0.0
linear 0.5 alpha 1.0
This transforms are used to wrap this displayable. The show, hide,
replace, and replaced external events are delivered to a transform
if and only if it is added directly to the screen.
For example, if a vbox is wrapped in a transform, and added directly
to the screen, then events are delivered to that transform. But if
@@ -1808,16 +1823,11 @@ Screen Statements
In addition to the screen statement, there are three Ren'Py script
language statements that involve screens.
Two of these statements take a keyword argument list. This is a Python
argument list, in parentheses, consisting of only keyword
arguments. Positional arguments, extra positional arguments (*), and
extra keyword arguments (**) are not allowed.
Show Screen
-----------
The ``show screen`` statement causes a screen to be shown. It takes an
screen name, and an optional argument list. If present, the arguments
screen name, and an optional Python argument list. If present, the arguments
are used to initialize the scope of the screen.
The show screen statement takes an optional ``nopredict`` keyword, that
@@ -1986,4 +1996,3 @@ An example of defining a screen variant is:
variant "small"
text "Hello, World." size 30
+148 -148
View File
@@ -1,187 +1,187 @@
<ul class='sponsors'>
<li> __skwrl__ (6.99.14.37.1.1)
<li> Adia Alderson (6.99.137.1.1)
<li> Aleema (6.99.137.1.1)
<li> <a href="http://alexdodge.net/" rel="nofollow">Alex Dodge</a> (6.99.147.1.1)
<li> <a href="https://rabidb.com/" rel="nofollow">AlexSSZ</a> (6.99.137.1.1)
<li> <a href="https://alic-szecsei.com" rel="nofollow">Alic Szecsei</a> (6.99.14.37.1.1)
<li> Anne Camlin (7.07.1.1)
<li> __skwrl__ (6.99.14.37.1.2)
<li> Adia Alderson (6.99.137.1.2)
<li> Aleema (6.99.137.1.2)
<li> <a href="http://alexdodge.net/" rel="nofollow">Alex Dodge</a> (6.99.147.1.2)
<li> <a href="https://rabidb.com/" rel="nofollow">AlexSSZ</a> (6.99.137.1.2)
<li> <a href="https://alic-szecsei.com" rel="nofollow">Alic Szecsei</a> (6.99.14.37.1.2)
<li> Anne Camlin (7.07.1.2)
<li> <a href="https://lemmasoft.renai.us/forums/viewtopic.php?f=51&t=34131" rel="nofollow">AR09FQF-AQ09FRF</a> (6.99.14.17.0)
<li> Asatiir (6.99.137.0)
<li> <a href="https://www.atwistedspirit.com/" rel="nofollow">ATwistedSpirit</a> (7.17.1.1)
<li> <a href="https://www.atwistedspirit.com/" rel="nofollow">ATwistedSpirit</a> (7.17.1.2)
<li> <a href="https://patchworkprincess.moe/" rel="nofollow">Azura (Vanessa Parker)</a> (7.07.1)
<li> <a href="https://www.youtube.com/channel/UC3Xm0sk-rRCtD-yVp64WPWQ" rel="nofollow">BadGamer</a> (6.99.14.37.1.1)
<li> <a href="https://www.youtube.com/channel/UC3Xm0sk-rRCtD-yVp64WPWQ" rel="nofollow">BadGamer</a> (6.99.14.37.1.2)
<li> Belfort and Bastion (6.99.137.1)
<li> Biotikos Development (6.99.137.1.1)
<li> Biotikos Development (6.99.137.1.2)
<li> Bob (6.99.137.0)
<li> <a href="https://bobcgames.tumblr.com" rel="nofollow">Bob Conway</a> (6.99.14.17.1.1)
<li> Bob Reus (7.17.1.1)
<li> Booom313's tinker corner (6.99.147.1.1)
<li> Boreas Bear (6.99.137.1.1)
<li> <a href="http://boyslaughplus.moe" rel="nofollow">Boys Laugh +</a> (6.99.137.1.1)
<li> <a href="https://bobcgames.tumblr.com" rel="nofollow">Bob Conway</a> (6.99.14.17.1.2)
<li> Bob Reus (7.17.1.2)
<li> Booom313's tinker corner (6.99.147.1.2)
<li> Boreas Bear (6.99.137.1.2)
<li> <a href="http://boyslaughplus.moe" rel="nofollow">Boys Laugh +</a> (6.99.137.1.2)
<li> Brett Douglas (6.99.146.99.14.3)
<li> Brimney (6.99.137.1.1)
<li> <a href="https://www.renpy.org/agegate?url=https://www.brunimultimedia.com" rel="nofollow">Bruni Multimedia</a> (6.99.147.1.1)
<li> Brimney (6.99.137.1.2)
<li> <a href="https://www.renpy.org/agegate?url=https://www.brunimultimedia.com" rel="nofollow">Bruni Multimedia</a> (6.99.147.1.2)
<li> <a href="http://www.bura.cl" rel="nofollow">BURA</a> (6.99.13)
<li> Cameron Woodard (6.99.14.37.1.1)
<li> Cara Hillstock (6.99.137.1.1)
<li> <a href="https://www.celebrityhunter.com.br" rel="nofollow">Celebrity Hunter</a> (7.17.1.1)
<li> Charlene Gilbert (6.99.137.1.1)
<li> <a href="http://charliethegoldfish.com" rel="nofollow">Charlie Francis Cassidy</a> (6.99.137.1.1)
<li> Chekhov's Ghost (7.17.1.1)
<li> Cherry Kiss Games (6.99.14.17.1.1)
<li> Chrysoula Tzavelas (6.99.137.1.1)
<li> <a href="https://cloverfirefly.itch.io" rel="nofollow">cloverfirefly</a> (6.99.137.1.1)
<li> CobaltCore (7.1.1)
<li> CobraPL (7.17.1.1)
<li> <a href="https://www.renpy.org/agegate?url=https://obscurasoft.com/" rel="nofollow">Coming Out On Top</a> (6.99.137.1.1)
<li> <a href="http://www.computerart.club/" rel="nofollow">computerart.club</a> (6.99.147.1.1)
<li> CookieNomNom (7.1.1)
<li> Crazy Cactus (6.99.14.37.1.1)
<li> <a href="https://www.renpy.org/agegate?url=http://cricketbat.me" rel="nofollow">cricketbat_</a> (7.07.1.1)
<li> Cameron Woodard (6.99.14.37.1.2)
<li> Cara Hillstock (6.99.137.1.2)
<li> <a href="https://www.celebrityhunter.com.br" rel="nofollow">Celebrity Hunter</a> (7.17.1.2)
<li> Charlene Gilbert (6.99.137.1.2)
<li> <a href="http://charliethegoldfish.com" rel="nofollow">Charlie Francis Cassidy</a> (6.99.137.1.2)
<li> Chekhov's Ghost (7.17.1.2)
<li> Cherry Kiss Games (6.99.14.17.1.2)
<li> Chrysoula Tzavelas (6.99.137.1.2)
<li> <a href="https://cloverfirefly.itch.io" rel="nofollow">cloverfirefly</a> (6.99.137.1.2)
<li> CobaltCore (7.1.17.1.2)
<li> CobraPL (7.17.1.2)
<li> <a href="https://www.renpy.org/agegate?url=https://obscurasoft.com/" rel="nofollow">Coming Out On Top</a> (6.99.137.1.2)
<li> <a href="http://www.computerart.club/" rel="nofollow">computerart.club</a> (6.99.147.1.2)
<li> CookieNomNom (7.1.17.1.2)
<li> Crazy Cactus (6.99.14.37.1.2)
<li> <a href="https://www.renpy.org/agegate?url=http://cricketbat.me" rel="nofollow">cricketbat_</a> (7.07.1.2)
<li> <a href="http://cultofape.com" rel="nofollow">CultOfApe</a> (6.99.147.0)
<li> Culture4Jam (6.99.137.1.1)
<li> Daniel Burns (7.17.1.1)
<li> Culture4Jam (6.99.137.1.2)
<li> Daniel Burns (7.17.1.2)
<li> <a href="http://dark-aii.net" rel="nofollow">Dark-Aii</a> (6.99.14.16.99.14.3)
<li> <a href="http://www.darksirengames.com" rel="nofollow">DarkSirenGames</a> (6.99.137.1.1)
<li> Darryl Taylor (7.07.1.1)
<li> David Koster (6.99.147.1.1)
<li> David Yingling (6.99.14.17.1.1)
<li> Dee (7.17.1.1)
<li> Denny Cheng (6.99.14.27.1.1)
<li> Dharker Studios Ltd (6.99.136.99.14, 7.1.1)
<li> <a href="http://coriginate.com" rel="nofollow">Ds110</a> (6.99.137.1.1)
<li> DuoDevelopers (7.1.1)
<li> E. William Brown (6.99.137.1.1)
<li> <a href="https://twitter.com/WC_EchoFrost" rel="nofollow">EchoFrost (Watercress)</a> (6.99.14.27.1.1)
<li> <a href="https://www.youtube.com/c/ElaineDoesCoding" rel="nofollow">ElaineDoesCoding</a> (7.07.1.1)
<li> eric chi hung ng (7.07.1.1)
<li> Euan 'Xolf' Robertson (6.99.137.1.1)
<li> <a href="http://www.darksirengames.com" rel="nofollow">DarkSirenGames</a> (6.99.137.1.2)
<li> Darryl Taylor (7.07.1.2)
<li> David Koster (6.99.147.1.2)
<li> David Yingling (6.99.14.17.1.2)
<li> Dee (7.17.1.2)
<li> Denny Cheng (6.99.14.27.1.2)
<li> Dharker Studios Ltd (6.99.136.99.14, 7.1.17.1.2)
<li> <a href="http://coriginate.com" rel="nofollow">Ds110</a> (6.99.137.1.2)
<li> DuoDevelopers (7.1.17.1.2)
<li> E. William Brown (6.99.137.1.2)
<li> <a href="https://twitter.com/WC_EchoFrost" rel="nofollow">EchoFrost (Watercress)</a> (6.99.14.27.1.2)
<li> <a href="https://www.youtube.com/c/ElaineDoesCoding" rel="nofollow">ElaineDoesCoding</a> (7.07.1.2)
<li> eric chi hung ng (7.07.1.2)
<li> Euan 'Xolf' Robertson (6.99.137.1.2)
<li> Eve Hallows (6.99.136.99.14)
<li> Exiscoming (6.99.147.1.1)
<li> <a href="https://moonlitworks.com/" rel="nofollow">Eyzi</a> (7.07.1.1)
<li> Fuseblower (7.07.1.1)
<li> George (7.17.1.1)
<li> <a href="http://www.gtbono.com" rel="nofollow">Giovanni Tempobono</a> (7.17.1.1)
<li> <a href="https://goldengamebarn.com/" rel="nofollow">Golden Game Barn</a> (6.99.137.1.1)
<li> <a href="https://twitter.com/goodtalesvn" rel="nofollow">Good Tales</a> (7.17.1.1)
<li> Great Chicken Studio (6.99.147.1.1)
<li> Grimiku (7.07.1.1)
<li> Gunso (6.99.137.1.1)
<li> HAG Productions (7.1.1)
<li> <a href="http://hanb.jp" rel="nofollow">HanbitGaram (MOEWORK Entertainment)</a> (7.17.1.1)
<li> Exiscoming (6.99.147.1.2)
<li> <a href="https://moonlitworks.com/" rel="nofollow">Eyzi</a> (7.07.1.2)
<li> Fuseblower (7.07.1.2)
<li> George (7.17.1.2)
<li> <a href="http://www.gtbono.com" rel="nofollow">Giovanni Tempobono</a> (7.17.1.2)
<li> <a href="https://goldengamebarn.com/" rel="nofollow">Golden Game Barn</a> (6.99.137.1.2)
<li> <a href="https://twitter.com/goodtalesvn" rel="nofollow">Good Tales</a> (7.17.1.2)
<li> Great Chicken Studio (6.99.147.1.2)
<li> Grimiku (7.07.1.2)
<li> Gunso (6.99.137.1.2)
<li> HAG Productions (7.1.17.1.2)
<li> <a href="http://hanb.jp" rel="nofollow">HanbitGaram (MOEWORK Entertainment)</a> (7.17.1.2)
<li> Happimochi (6.99.136.99.14)
<li> HopesGaming (7.1.1)
<li> HopesGaming (7.1.17.1.2)
<li> <a href="https://ijemin.com" rel="nofollow">I_Jemin</a> (6.99.137.0)
<li> <a href="https://irredeemable.net/" rel="nofollow">Irredeemable Games</a> (6.99.147.1.1)
<li> J. C. Holder (6.99.137.1.1)
<li> <a href="https://irredeemable.net/" rel="nofollow">Irredeemable Games</a> (6.99.147.1.2)
<li> J. C. Holder (6.99.137.1.2)
<li> James Tyner (6.99.137.1)
<li> JeongPyo Lee (6.99.137.1.1)
<li> Joanna B (6.99.137.1.1)
<li> JoeBanks (7.17.1.1)
<li> Jonas Kyratzes (7.1.1)
<li> jonnymelabo (6.99.137.1.1)
<li> JeongPyo Lee (6.99.137.1.2)
<li> Joanna B (6.99.137.1.2)
<li> JoeBanks (7.17.1.2)
<li> Jonas Kyratzes (7.1.17.1.2)
<li> jonnymelabo (6.99.137.1.2)
<li> Josh Kaplan (6.99.136.99.14.2)
<li> K. Starbuck (6.99.136.99.14)
<li> Kampmichi (7.1.1)
<li> Kayde Initials (6.99.137.1.1)
<li> <a href="http://kexboy.com" rel="nofollow">KEXBOY</a> (6.99.137.1.1)
<li> Kikai Digital (7.07.1.1)
<li> <a href="http://www.gamesbykinmoku.com" rel="nofollow">Kinmoku</a> (6.99.137.1.1)
<li> <a href="http://krsm94.web.fc2.com/" rel="nofollow">Klast Halc (crAsm)</a> (6.99.14.27.1.1)
<li> Kosmos Games (6.99.147.1.1)
<li> <a href="https://de.koubaibu.tech/" rel="nofollow">Koubaibu Technology Group</a> (7.17.1.1)
<li> lain105/EckoMars (6.99.137.1.1)
<li> LateWhiteRabbit (6.99.147.1.1)
<li> <a href="https://lernakow.itch.io" rel="nofollow">Lernakow</a> (6.99.14.37.1.1)
<li> LewdKitty (7.07.1.1)
<li> <a href="https://www.renpy.org/agegate?url=https://www.lewdlab.com/" rel="nofollow">Lewdlab</a> (6.99.14.17.1.1)
<li> <a href="https://lemmasoft.renai.us/forums/viewtopic.php?f=66&t=48011&p=482643" rel="nofollow">Lezalith</a> (7.17.1.1)
<li> Lictor (6.99.14.27.1.1)
<li> Little Napoleon (7.17.1.1)
<li> <a href="http://trash.moe/" rel="nofollow">Lore</a> (6.99.137.1.1)
<li> Luke Jackson (6.99.137.1.1)
<li> <a href="http://luscious-spirit-studios.tumblr.com/" rel="nofollow">Luscious Spirit Studios</a> (6.99.137.1.1)
<li> <a href="https://www.renpy.org/agegate?url=https://www.patreon.com/Luxee" rel="nofollow">Luxee</a> (6.99.14.37.1.1)
<li> Maeve Bandruid (6.99.137.1.1)
<li> <a href="https://www.renpy.org/agegate?url=https://www.patreon.com/manitu" rel="nofollow">MANITU Games CO.</a> (6.99.137.1.1)
<li> <a href="https://manorstories.fr" rel="nofollow">ManorStories</a> (6.99.147.1.1)
<li> <a href="http://www.marionettecode.com/" rel="nofollow">Marionette</a> (6.99.147.1.1)
<li> Kampmichi (7.1.17.1.2)
<li> Kayde Initials (6.99.137.1.2)
<li> <a href="http://kexboy.com" rel="nofollow">KEXBOY</a> (6.99.137.1.2)
<li> Kikai Digital (7.07.1.2)
<li> <a href="http://www.gamesbykinmoku.com" rel="nofollow">Kinmoku</a> (6.99.137.1.2)
<li> <a href="http://krsm94.web.fc2.com/" rel="nofollow">Klast Halc (crAsm)</a> (6.99.14.27.1.2)
<li> Kosmos Games (6.99.147.1.2)
<li> <a href="https://de.koubaibu.tech/" rel="nofollow">Koubaibu Technology Group</a> (7.17.1.2)
<li> lain105/EckoMars (6.99.137.1.2)
<li> LateWhiteRabbit (6.99.147.1.2)
<li> <a href="https://lernakow.itch.io" rel="nofollow">Lernakow</a> (6.99.14.37.1.2)
<li> LewdKitty (7.07.1.2)
<li> <a href="https://www.renpy.org/agegate?url=https://www.lewdlab.com/" rel="nofollow">Lewdlab</a> (6.99.14.17.1.2)
<li> <a href="https://lemmasoft.renai.us/forums/viewtopic.php?f=66&t=48011&p=482643" rel="nofollow">Lezalith</a> (7.17.1.2)
<li> Lictor (6.99.14.27.1.2)
<li> Little Napoleon (7.17.1.2)
<li> <a href="http://trash.moe/" rel="nofollow">Lore</a> (6.99.137.1.2)
<li> Luke Jackson (6.99.137.1.2)
<li> <a href="http://luscious-spirit-studios.tumblr.com/" rel="nofollow">Luscious Spirit Studios</a> (6.99.137.1.2)
<li> <a href="https://www.renpy.org/agegate?url=https://www.patreon.com/Luxee" rel="nofollow">Luxee</a> (6.99.14.37.1.2)
<li> Maeve Bandruid (6.99.137.1.2)
<li> <a href="https://www.renpy.org/agegate?url=https://www.patreon.com/manitu" rel="nofollow">MANITU Games CO.</a> (6.99.137.1.2)
<li> <a href="https://manorstories.fr" rel="nofollow">ManorStories</a> (6.99.147.1.2)
<li> <a href="http://www.marionettecode.com/" rel="nofollow">Marionette</a> (6.99.147.1.2)
<li> MAW.3D.Art (6.99.13)
<li> Max J Sher (6.99.137.1.1)
<li> MCatter Dev (7.17.1.1)
<li> <a href="https://meagantrott.com" rel="nofollow">Meagan Trott</a> (6.99.137.1.1)
<li> <a href="http://metasepia.icecavern.net" rel="nofollow">Metasepia Games</a> (6.99.137.1.1)
<li> <a href="http://www.meyaoi.com" rel="nofollow">Meyaoi Games</a> (6.99.136.99.14, 6.99.14.37.1.1)
<li> Meyvol (6.99.14.17.1.1)
<li> Michael Simon (7.1.1)
<li> Michaela Laws (6.99.137.1.1)
<li> Max J Sher (6.99.137.1.2)
<li> MCatter Dev (7.17.1.2)
<li> <a href="https://meagantrott.com" rel="nofollow">Meagan Trott</a> (6.99.137.1.2)
<li> <a href="http://metasepia.icecavern.net" rel="nofollow">Metasepia Games</a> (6.99.137.1.2)
<li> <a href="http://www.meyaoi.com" rel="nofollow">Meyaoi Games</a> (6.99.136.99.14, 6.99.14.37.1.2)
<li> Meyvol (6.99.14.17.1.2)
<li> Michael Simon (7.1.17.1.2)
<li> Michaela Laws (6.99.137.1.2)
<li> <a href="http://www.milkteestudios.com" rel="nofollow">Milktee Studios</a> (7.07.1)
<li> Miss Skizzors (7.07.1.1)
<li> Montse Latre (7.1.1)
<li> <a href="https://mrvaldez.ph/" rel="nofollow">MrValdez</a> (7.07.1.1)
<li> Miss Skizzors (7.07.1.2)
<li> Montse Latre (7.1.17.1.2)
<li> <a href="https://mrvaldez.ph/" rel="nofollow">MrValdez</a> (7.07.1.2)
<li> <a href="https://ms45.itch.io" rel="nofollow">Ms .45</a> (6.99.13)
<li> nasredin (6.99.14.37.1.1)
<li> Natalie Van Sistine (7.07.1.1)
<li> <a href="https://cafe.naver.com/vmo.cafe" rel="nofollow">Naver cafe VMO</a> (7.17.1.1)
<li> nasredin (6.99.14.37.1.2)
<li> Natalie Van Sistine (7.07.1.2)
<li> <a href="https://cafe.naver.com/vmo.cafe" rel="nofollow">Naver cafe VMO</a> (7.17.1.2)
<li> <a href="http://cafe.naver.com/vmo" rel="nofollow">NaverCafe VMO</a> (6.99.137.1)
<li> Neigan (7.0)
<li> Nicholas Swenson (6.99.147.1.1)
<li> <a href="https://www.patreon.com/nikraria" rel="nofollow">nikraria</a> (6.99.137.1.1)
<li> Nova Alamak (6.99.14.37.1.1)
<li> Nicholas Swenson (6.99.147.1.2)
<li> <a href="https://www.patreon.com/nikraria" rel="nofollow">nikraria</a> (6.99.137.1.2)
<li> Nova Alamak (6.99.14.37.1.2)
<li> <a href="http://devety.com" rel="nofollow">Oleksii olety Kyrylchuk</a> (6.99.14.16.99.14.2)
<li> <a href="https://www.renpy.org/agegate?url=https://www.patreon.com/palantogames" rel="nofollow">Palanto Games</a> (7.07.1.1)
<li> Panthera Morag (6.99.137.1.1)
<li> Patchwork Princess (7.17.1.1)
<li> <a href="https://www.renpy.org/agegate?url=https://www.patreon.com/palantogames" rel="nofollow">Palanto Games</a> (7.07.1.2)
<li> Panthera Morag (6.99.137.1.2)
<li> Patchwork Princess (7.17.1.2)
<li> Patricia (6.99.137.1.1)
<li> <a href="http://peachpattch.com/" rel="nofollow">peachpattch</a> (6.99.147.1.1)
<li> philat (6.99.14.17.1.1)
<li> plasterbrain (6.99.137.1.1)
<li> <a href="http://peachpattch.com/" rel="nofollow">peachpattch</a> (6.99.147.1.2)
<li> philat (6.99.14.17.1.2)
<li> plasterbrain (6.99.137.1.2)
<li> Ploppertje (6.99.136.99.14.3)
<li> Podge (6.99.137.1.1)
<li> Podge (6.99.137.1.2)
<li> Puriwit Sesupaponphong (6.99.13)
<li> Puriwit Sesupaponphong (6.99.137.1)
<li> Pólyí Konrád (7.17.1.1)
<li> <a href="http://www.cottoncandycyanide.com/" rel="nofollow">Quantum Suicide</a> (7.17.1.1)
<li> <a href="http://razzartvisual.com/" rel="nofollow">Razz</a> (6.99.137.1.1)
<li> <a href="http://www.cottoncandycyanide.com/" rel="nofollow">Quantum Suicide</a> (7.17.1.2)
<li> <a href="http://razzartvisual.com/" rel="nofollow">Razz</a> (6.99.137.1.2)
<li> <a href="https://twitter.com/ragnarhomsar" rel="nofollow">Realga</a> (7.07.1)
<li> René Dudfield (6.99.137.1.1)
<li> Richard (6.99.147.1.1)
<li> <a href="http://impqueen.com/" rel="nofollow">Rinmaru</a> (6.99.137.1.1)
<li> Rizia Praja (6.99.14.17.1.1)
<li> René Dudfield (6.99.137.1.2)
<li> Richard (6.99.147.1.2)
<li> <a href="http://impqueen.com/" rel="nofollow">Rinmaru</a> (6.99.137.1.2)
<li> Rizia Praja (6.99.14.17.1.2)
<li> Robyn Rosenfeld (7.1)
<li> <a href="http://sunkoiwish.com/" rel="nofollow">Royce A Xaiyeon</a> (6.99.137.1.1)
<li> Ryan Balgos (6.99.147.1.1)
<li> <a href="http://sunkoiwish.com/" rel="nofollow">Royce A Xaiyeon</a> (6.99.137.1.2)
<li> Ryan Balgos (6.99.147.1.2)
<li> Ryan Whited (6.99.147.1)
<li> <a href="https://saiffyros.wordpress.com/" rel="nofollow">Saiffyros</a> (6.99.147.1.1)
<li> Sam Yang (6.99.137.1.1)
<li> Simply Aria (6.99.147.1.1)
<li> <a href="http://sleepyagents.co.uk" rel="nofollow">Sleepy Agents</a> (6.99.137.1.1)
<li> Snowlocke (7.07.1.1)
<li> <a href="https://saiffyros.wordpress.com/" rel="nofollow">Saiffyros</a> (6.99.147.1.2)
<li> Sam Yang (6.99.137.1.2)
<li> Simply Aria (6.99.147.1.2)
<li> <a href="http://sleepyagents.co.uk" rel="nofollow">Sleepy Agents</a> (6.99.137.1.2)
<li> Snowlocke (7.07.1.2)
<li> <a href="http://store.steampowered.com/app/570350/Sorry_Entschuldigung__A_Psychological_Horror_Visual_Novel/" rel="nofollow">Sorry. (Entschuldigung)</a> (6.99.14.27.1)
<li> Spyros Panagiotopoulos (6.99.147.1)
<li> Steamlynx (6.99.14.17.1.1)
<li> Stefan Gagne (6.99.137.1.1)
<li> <a href="https://www.renpy.org/agegate?url=http://www.patreon.com/errilhl" rel="nofollow">Studio Errilhl</a> (6.99.14.37.1.1)
<li> Taosym (6.99.137.1.1)
<li> Steamlynx (6.99.14.17.1.2)
<li> Stefan Gagne (6.99.137.1.2)
<li> <a href="https://www.renpy.org/agegate?url=http://www.patreon.com/errilhl" rel="nofollow">Studio Errilhl</a> (6.99.14.37.1.2)
<li> Taosym (6.99.137.1.2)
<li> Teofilo Hurtado (6.99.147.1.1)
<li> Thomas Charlie (6.99.137.1.1)
<li> Timothy Landreth (6.99.137.1.1)
<li> Timothy Young (6.99.14.17.1.1)
<li> TJ Huckabee (6.99.137.1.1)
<li> Thomas Charlie (6.99.137.1.2)
<li> Timothy Landreth (6.99.137.1.2)
<li> Timothy Young (6.99.14.17.1.2)
<li> TJ Huckabee (6.99.137.1.2)
<li> ToastCrust (6.99.136.99.14)
<li> Tobias Wüthrich (6.99.136.99.14.3)
<li> <a href="http://tremmigames.tk/" rel="nofollow">tremmiGames</a> (7.07.1.1)
<li> trooper6 (6.99.137.1.1)
<li> <a href="https://www.youtube.com/tryinmorning" rel="nofollow">tryinmorning</a> (6.99.137.1.1)
<li> <a href="https://studiomugenjohncel.wordpress.com/" rel="nofollow">Uncle Mugen (Mugenjohncel</a> (6.99.14.27.1.1)
<li> <a href="http://www.visualsaga.com/" rel="nofollow">Visual Saga</a> (6.99.137.1.1)
<li> <a href="http://tremmigames.tk/" rel="nofollow">tremmiGames</a> (7.07.1.2)
<li> trooper6 (6.99.137.1.2)
<li> <a href="https://www.youtube.com/tryinmorning" rel="nofollow">tryinmorning</a> (6.99.137.1.2)
<li> <a href="https://studiomugenjohncel.wordpress.com/" rel="nofollow">Uncle Mugen (Mugenjohncel</a> (6.99.14.27.1.2)
<li> <a href="http://www.visualsaga.com/" rel="nofollow">Visual Saga</a> (6.99.137.1.2)
<li> Vollschauer (6.99.136.99.14)
<li> <a href="http://vxlloyd.com" rel="nofollow">VX Lloyd</a> (6.99.14.37.0)
<li> Wayne Wollesen (6.99.14.37.1.1)
<li> <a href="https://www.facebook.com/weeabooriot" rel="nofollow">Weeabooriot Cosplay</a> (6.99.137.1.1)
<li> <a href="https://arcaniinteractive.com/" rel="nofollow">William Lucht</a> (7.07.1.1)
<li> William Tumeo (6.99.137.1.1)
<li> <a href="http://winterwolves.com/ambersmagicshop.htm" rel="nofollow">Winter Wolves</a> (6.99.137.1.1)
<li> <a href="http://astralore.com/" rel="nofollow">Yakmala!</a> (6.99.137.1.1)
<li> <a href="https://www.facebook.com/weeabooriot" rel="nofollow">Weeabooriot Cosplay</a> (6.99.137.1.2)
<li> <a href="https://arcaniinteractive.com/" rel="nofollow">William Lucht</a> (7.07.1.2)
<li> William Tumeo (6.99.137.1.2)
<li> <a href="http://winterwolves.com/ambersmagicshop.htm" rel="nofollow">Winter Wolves</a> (6.99.137.1.2)
<li> <a href="http://astralore.com/" rel="nofollow">Yakmala!</a> (6.99.137.1.2)
</ul>
+9
View File
@@ -127,6 +127,15 @@ and rolled-back when rollback occurs.
Controls of if skipping is allowed.
.. var:: _version = ...
This is set to :var:`config.version` when a new game is started. It can be
use by the ``after_load`` label or :var:`config.after_load_callbacks` to
determine which upgrades need to be done.
This is only set once, upon the initial start. After that, the game is
responsible for updating _version as necessary.
.. var:: _window = False
This set by the ``window show`` and ``window hide`` statements, and indirectly
+3
View File
@@ -380,6 +380,9 @@ The default language is chosen using the following method:
* If :var:`config.language` is set, that language is used.
* If the game has ever chosen a language in the past, that language is
used.
* If this is the first time the game has been run and
:var:`config.enable_language_autodetect` is True, Ren'Py tries to
autodtetect the language using :var:`config.locale_to_language_function`.
* If this is the first time the game has been run,
:var:`config.default_language` is used. (This defaults to the None
language.)
+4 -3
View File
@@ -799,10 +799,10 @@ screen preferences():
style_prefix "radio"
label _("Language")
textbutton "English" text_font "DejaVuSans.ttf"action Language(None)
textbutton "Français" text_font "DejaVuSans.ttf"action Language("french")
textbutton "English" text_font "DejaVuSans.ttf" action Language(None)
textbutton "Français" text_font "DejaVuSans.ttf" action Language("french")
textbutton "Русский" text_font "DejaVuSans.ttf" action Language("russian")
textbutton "Bahasa Melayu" text_font "DejaVuSans.ttf"action Language("malay")
textbutton "Bahasa Melayu" text_font "DejaVuSans.ttf" action Language("malay")
#end language_picker
@@ -974,6 +974,7 @@ screen history():
if not _history_list:
label _("The dialogue history is empty.")
define gui.history_allow_tags = set()
style history_window is empty
+3 -3
View File
@@ -187,7 +187,7 @@ translate french strings:
# screens.rpy:782
old "Rollback Side"
new "Rollback"
new "Rembobinage côté"
# screens.rpy:783
#old "Disable"
@@ -215,7 +215,7 @@ translate french strings:
# screens.rpy:800
old "Language"
new "Langage"
new "Langue"
# screens.rpy:815
old "Text Speed"
@@ -351,7 +351,7 @@ translate french strings:
# screens.rpy:1111
old "Mouse Wheel Up\nClick Rollback Side"
new "Molette de souris vers le haut\nClic dans le sens Rollback"
new "Molette de souris vers le haut\nClic du côté rembobinage"
# screens.rpy:1115
old "Mouse Wheel Down"
File diff suppressed because one or more lines are too long
+1
View File
@@ -951,6 +951,7 @@ screen history():
if not _history_list:
label _("The dialogue history is empty.")
define gui.history_allow_tags = set()
style history_window is empty