286 lines
9.6 KiB
Plaintext
286 lines
9.6 KiB
Plaintext
# Custom text tags
|
|
# https://www.renpy.org/doc/html/custom_text_tags.html
|
|
|
|
image text_tag_hearts_image = Fixed(love_heart((15, 0), 12, 0.1), love_heart((20, -10), 6, 0.5), love_heart((10, 10), 6, 1), fit_first=True, xsize=32)
|
|
|
|
init python:
|
|
def convert_tags_to_kwargs(contents):
|
|
kwargs = {"style": "what"}
|
|
for kind, text in contents:
|
|
if kind == renpy.TEXT_TAG:
|
|
if text.startswith("="):
|
|
kwargs["style"] = text.split("=")[1]
|
|
|
|
if text.startswith("color="):
|
|
kwargs["color"] = text.split("=")[1]
|
|
|
|
if text.startswith("size="):
|
|
kwargs["size"] = int(text.split("=")[1])
|
|
|
|
if text.startswith("outlinecolor="):
|
|
kwargs["outlines"] = [(2, text.split("=")[1], 1, 1)]
|
|
|
|
if text == "b":
|
|
kwargs["bold"] = True
|
|
|
|
if text == "i":
|
|
kwargs["italics"] = True
|
|
|
|
return kwargs
|
|
|
|
@renpy.pure
|
|
def text_tag_icon(tag, argument):
|
|
"""Insert a unicode heart symbol. Usage {heart}"""
|
|
return [(renpy.TEXT_DISPLAYABLE, Transform(argument, xysize=(32, 32)))]
|
|
|
|
@renpy.pure
|
|
def text_tag_unicode(tag, argument, contents):
|
|
"""Render contents using a font that supports all/most Unicode characters. Usage {unicode}☺{/unicode}"""
|
|
# DejaVuSans is included by default in Ren'py
|
|
return [(renpy.TEXT_TAG, "font=DejaVuSans.ttf")] + contents + [(renpy.TEXT_TAG, "/font")]
|
|
|
|
@renpy.pure
|
|
def text_tag_heart(tag, argument):
|
|
"""Insert a unicode heart symbol. Usage {heart}"""
|
|
return [(renpy.TEXT_DISPLAYABLE, At(Text("{unicode}❤{/unicode}", style="what", xsize=24, ysize=24), heart_text))]
|
|
|
|
@renpy.pure
|
|
def text_tag_hearts(tag, argument):
|
|
"""Insert multiple unicode heart symbols. Usage {hearts}"""
|
|
return [(renpy.TEXT_DISPLAYABLE, Transform("text_tag_hearts_image"))]
|
|
|
|
@renpy.pure
|
|
def text_tag_number(tag, argument):
|
|
"""Convert a number to words if lower than 100 or a multiple of 100. Usage {number=expression}"""
|
|
num = int(renpy.store.eval(argument)) # Can be a function or an expression.
|
|
words = num_to_word(num) if num < 100 or num % 100 == 0 else str(num)
|
|
return [(renpy.TEXT_TEXT, words)]
|
|
|
|
@renpy.pure
|
|
def text_tag_wave(tag, argument, contents):
|
|
rv = []
|
|
kwargs = convert_tags_to_kwargs(contents)
|
|
for kind, text in contents:
|
|
if kind == renpy.TEXT_TEXT:
|
|
end_pause = len(text)/100.0
|
|
for i, letter in enumerate(text):
|
|
start_pause = i/100.0
|
|
d = At(Text(letter, **kwargs), wave_text(start_pause, end_pause))
|
|
rv.append((renpy.TEXT_DISPLAYABLE, d))
|
|
else:
|
|
rv.append((kind, text))
|
|
return rv
|
|
|
|
@renpy.pure
|
|
def text_tag_bounce(tag, argument, contents):
|
|
rv = []
|
|
kwargs = convert_tags_to_kwargs(contents)
|
|
for kind, text in contents:
|
|
if kind == renpy.TEXT_TEXT:
|
|
end_pause = len(text)/100.0
|
|
for i, letter in enumerate(text):
|
|
start_pause = i/100.0
|
|
d = At(Text(letter, **kwargs), bounce_text(start_pause, end_pause))
|
|
rv.append((renpy.TEXT_DISPLAYABLE, d))
|
|
else:
|
|
rv.append((kind, text))
|
|
return rv
|
|
|
|
@renpy.pure
|
|
def text_tag_shake(tag, argument, contents):
|
|
rv = []
|
|
kwargs = convert_tags_to_kwargs(contents)
|
|
for kind, text in contents:
|
|
if kind == renpy.TEXT_TEXT:
|
|
for i, letter in enumerate(text):
|
|
d = At(Text(letter, **kwargs), shake_text)
|
|
rv.append((renpy.TEXT_DISPLAYABLE, d))
|
|
else:
|
|
rv.append((kind, text))
|
|
return rv
|
|
|
|
@renpy.pure
|
|
def text_tag_pulse(tag, argument, contents):
|
|
rv = []
|
|
kwargs = convert_tags_to_kwargs(contents)
|
|
for kind, text in contents:
|
|
if kind == renpy.TEXT_TEXT:
|
|
d = At(Text(text, **kwargs), pulse_text)
|
|
rv.append((renpy.TEXT_DISPLAYABLE, d))
|
|
else:
|
|
rv.append((kind, text))
|
|
return rv
|
|
|
|
@renpy.pure
|
|
def text_tag_shudder(tag, argument, contents):
|
|
rv = []
|
|
kwargs = convert_tags_to_kwargs(contents)
|
|
for kind, text in contents:
|
|
if kind == renpy.TEXT_TEXT:
|
|
d = At(Text(text, **kwargs), shudder_text)
|
|
rv.append((renpy.TEXT_DISPLAYABLE, d))
|
|
else:
|
|
rv.append((kind, text))
|
|
return rv
|
|
|
|
@renpy.pure
|
|
def text_tag_flip(tag, argument, contents):
|
|
rv = []
|
|
kwargs = convert_tags_to_kwargs(contents)
|
|
for kind, text in contents:
|
|
if kind == renpy.TEXT_TEXT:
|
|
d = Transform(At(Text(text, **kwargs), flip_text), pos=(240, -2))
|
|
rv.append((renpy.TEXT_DISPLAYABLE, d))
|
|
else:
|
|
rv.append((kind, text))
|
|
return rv
|
|
|
|
@renpy.pure
|
|
def text_tag_rotate(tag, argument, contents):
|
|
rv = []
|
|
kwargs = convert_tags_to_kwargs(contents)
|
|
for kind, text in contents:
|
|
if kind == renpy.TEXT_TEXT:
|
|
for i, letter in enumerate(text):
|
|
d = Transform(At(Text(letter, **kwargs), rotate_text), pos=(240, -2))
|
|
rv.append((renpy.TEXT_DISPLAYABLE, d))
|
|
else:
|
|
rv.append((kind, text))
|
|
return rv
|
|
|
|
def text_love_heart_func(pos, size, trans, st, at):
|
|
warper_rotate = _warper.easein(st / 0.5)
|
|
warper_alpha = _warper.easein(st / 1.0)
|
|
warper_yoffset = _warper.easein(st / 1.0)
|
|
warper_xoffset = _warper.easein(st / 0.2)
|
|
trans.child = Text("{unicode}❤{/unicode}", style="what", size=size)
|
|
trans.rotate = renpy.atl.interpolate(warper_rotate, -10, 10, renpy.atl.PROPERTIES["alpha"])
|
|
trans.yoffset = renpy.atl.interpolate(warper_yoffset, 6, -6, renpy.atl.PROPERTIES["yoffset"])
|
|
trans.xoffset = renpy.atl.interpolate(warper_xoffset, -1, 1, renpy.atl.PROPERTIES["xoffset"])
|
|
trans.alpha = renpy.atl.interpolate(warper_alpha, 1, 0, renpy.atl.PROPERTIES["alpha"])
|
|
return 0.01
|
|
|
|
def text_shake_func(trans, st, at):
|
|
trans.xoffset = absolute(renpy.random.randint(-1, 1))
|
|
trans.yoffset = absolute(renpy.random.randint(-1, 1))
|
|
return 0.02
|
|
|
|
transform wave_text(start_pause, end_pause):
|
|
animation
|
|
subpixel True
|
|
yoffset 0
|
|
pos (240, -2) # Workaround; Xpos seems to not account for text box offset and text outline?
|
|
pause start_pause
|
|
easein 0.75 yoffset -6
|
|
easein 0.75 yoffset 0
|
|
pause end_pause
|
|
repeat
|
|
|
|
transform bounce_text(start_pause, end_pause):
|
|
animation
|
|
subpixel True
|
|
yoffset 0
|
|
pos (240, -2) # Workaround; Xpos seems to not account for text box offset and text outline?
|
|
pause start_pause
|
|
easeout_bounce 1 yoffset -6 yzoom 1.1
|
|
easein_bounce 1 yoffset 0 yzoom 1.0
|
|
pause end_pause
|
|
repeat
|
|
|
|
transform pulse_text:
|
|
animation
|
|
subpixel True
|
|
yzoom 1
|
|
pos (240, -2) # Workaround; Xpos seems to not account for text box offset and text outline?
|
|
pause 1
|
|
easeout 0.5 yzoom 1.15
|
|
easein 0.25 yzoom 1.0
|
|
easeout 0.5 yzoom 1.15
|
|
easein 0.25 yzoom 1.0
|
|
repeat
|
|
|
|
transform shake_text:
|
|
animation
|
|
subpixel True
|
|
pos (240, -2) # Workaround; Xpos seems to not account for text box offset and text outline?
|
|
function text_shake_func
|
|
|
|
transform shudder_text:
|
|
animation
|
|
subpixel True
|
|
pos (240, -2) # Workaround; Xpos seems to not account for text box offset and text outline?
|
|
easeout 0.1 xoffset -3
|
|
easeout 0.1 xoffset 3
|
|
easeout 0.1 xoffset -3
|
|
easeout 0.1 xoffset 3
|
|
easeout 0.1 xoffset 0
|
|
pause 0.5
|
|
repeat
|
|
|
|
transform flip_text:
|
|
animation
|
|
subpixel True
|
|
perspective True
|
|
matrixtransform RotateMatrix(0, 0, 0)
|
|
pos (0, 0) # Bugs out without explicit pos; We fix the offsets in a parent
|
|
easein 1 matrixtransform RotateMatrix(360.0, 0, 0)
|
|
pause 1.5
|
|
repeat
|
|
|
|
transform rotate_text:
|
|
animation
|
|
subpixel True
|
|
perspective True
|
|
matrixtransform RotateMatrix(0, 0, 0)
|
|
pos (0, 0) # Bugs out without explicit pos; We fix the offsets in a parent
|
|
easein 1 matrixtransform RotateMatrix(0, 0, 360.0)
|
|
pause 1.5
|
|
repeat
|
|
|
|
transform love_heart(pos, size, pause):
|
|
animation
|
|
subpixel True
|
|
anchor (0.5, 0.5)
|
|
xpos 240+pos[0] # Workaround; Xpos seems to not account for text box offset and text outline?
|
|
ypos -2+pos[1] # Workaround; Xpos seems to not account for text box offset and text outline?
|
|
pause pause
|
|
function renpy.partial(text_love_heart_func, pos, size)
|
|
repeat
|
|
|
|
transform heart_text:
|
|
animation
|
|
subpixel True
|
|
anchor (0.5, 0.5)
|
|
yzoom 1
|
|
xzoom 1
|
|
pos (256, 14) # Workaround; Xpos seems to not account for text box offset and text outline?
|
|
easein 0.25 yzoom 1.05 xzoom 1.05
|
|
easein 0.25 yzoom 1.0 xzoom 1.0
|
|
easein 0.25 yzoom 1.05 xzoom 1.05
|
|
easein 0.25 yzoom 1.0 xzoom 1.0
|
|
choice:
|
|
pause 0.25
|
|
choice:
|
|
pause 0.35
|
|
choice:
|
|
pause 0.45
|
|
repeat
|
|
|
|
define config.custom_text_tags = {
|
|
"unicode": text_tag_unicode,
|
|
"wave": text_tag_wave,
|
|
"bounce": text_tag_bounce,
|
|
"shake": text_tag_shake,
|
|
"shudder": text_tag_shudder,
|
|
"pulse": text_tag_pulse,
|
|
"flip": text_tag_flip,
|
|
"rotate": text_tag_rotate,
|
|
}
|
|
|
|
define config.self_closing_custom_text_tags = {
|
|
"icon": text_tag_icon,
|
|
"heart": text_tag_heart,
|
|
"hearts": text_tag_hearts,
|
|
"number": text_tag_number,
|
|
}
|