Code: Select all
init python:
from collections import OrderedDict
class DisplayableSwitcher(renpy.Displayable, NoRollback):
DEFAULT = {"d": Null(), "start_st": 0, "pause_st": 0, "force_pause": 0, "force_resume": 0}
"""This plainly switches displayable without reshowing the image/changing any variables by calling change method.
"""
def __init__(self, start_displayable="default", displayable=None, conditions=None, always_reset=True, **kwargs):
"""Expects a dict of displayable={"string": something we can show in Ren'Py}
Default is Null() unless specified otherwise.
"""
super(DisplayableSwitcher, self).__init__(**kwargs)
if not isinstance(displayable, _dict):
self.displayable = {"default": self.DEFAULT.copy()}
else:
self.displayable = {}
for s, d in displayable.iteritems():
self.displayable[s] = self.DEFAULT.copy()
d = renpy.easy.displayable(d)
if isinstance(d, ImageReference):
d = renpy.display.image.images[(d.name)]
self.displayable[s]["d"] = d
if isinstance(d, renpy.atl.ATLTransformBase):
self.displayable[s]["atl"] = d.copy()
self.displayable["default"] = displayable.get("default", self.DEFAULT.copy())
if not isinstance(conditions, (tuple, list)):
self.conditions = None
else:
self.conditions = OrderedDict()
for c, a in conditions:
code = renpy.python.py_compile(c, 'eval')
self.conditions[c] = a
self.always_reset = always_reset
self.d = self.displayable[start_displayable]
self.animation_mode = "normal"
self.last_st = 0
self.last_condition = None
def per_interact(self):
if self.conditions:
for c, v in self.conditions.iteritems():
if renpy.python.py_eval_bytecode(c):
s = v[0]
if len(v) > 1:
mode = v[1]
else:
mode = "normal"
# We only want to change if we got a new condition:
if self.last_condition != c or (self.always_reset and "reset" in v):
self.last_condition = c
self.change(s, mode)
break
def change(self, s, mode="normal"):
self.d = self.displayable[s]
self.animation_mode = mode
if mode == "reset":
self.d["force_restart"] = 1
elif mode == "pause":
self.d["pause_st"] = self.last_st - self.d["start_st"]
elif mode == "resume":
self.d["force_resume"] = 1
def render(self, width, height, st, at):
if not st:
for d in self.displayable.itervalues():
d["start_st"] = 0
d["pause_st"] = 0
rp = store.renpy
self.last_st = st
if self.animation_mode == "reset":
if self.d["force_restart"]:
self.d["force_restart"] = 0
if "atl" in self.d:
self.d["d"].take_execution_state(self.d["atl"])
self.d["d"].atl_st_offset = st
else:
self.d["start_st"] = st
st = st - self.d["start_st"] if not "atl" in self.d else st
elif self.animation_mode in ("pause", "show_paused"):
st = self.d["pause_st"]
elif self.animation_mode == "resume":
if self.d["force_resume"]:
self.d["force_resume"] = 0
self.d["start_st"] = st
st = st - self.d["start_st"] + self.d["pause_st"]
d = self.d["d"]
render = rp.Render(width, height)
render.place(d)
rp.redraw(self, 0)
return render
def visit(self):
return [v["d"] for v in self.displayable.values()]
image BallImage:
Solid("F00", xysize=(100, 100))
transform Rolling():
subpixel True
ease 2 offset (0,0)
ease 2 offset (100,0)
repeat
transform Bouncing():
subpixel True
easein 1 offset (0,0)
easeout 1 offset (0,100)
repeat
default BallState = 1
default AnimVariable = 2
image CompositeImage:
LiveComposite(
(100,100),
(0,0), DisplayableSwitcher(displayable={
"Rolling": At("BallImage", Rolling()),
"Bouncing": At("BallImage", Bouncing()),
},
conditions=(
("BallState == 1 and AnimVariable == 0", ("Rolling", )),
("BallState == 1 and AnimVariable == 1", ("Rolling", "reset")),
("BallState == 1 and AnimVariable == 2", ("Rolling", "reset")),
("BallState == 1 and AnimVariable == 3", ("Rolling", "pause")),
("BallState == 1 and AnimVariable == 4", ("Rolling", "show_paused")),
("BallState == 1 and AnimVariable == 5", ("Rolling", "resume")),
("BallState == 1 and AnimVariable > 5", ("default", )),
("BallState == 2 and AnimVariable == 0", ("Bouncing", )),
("BallState == 2 and AnimVariable == 1", ("Bouncing", "reset")),
("BallState == 2 and AnimVariable == 2", ("Bouncing", "reset")),
("BallState == 2 and AnimVariable == 3", ("Bouncing", "pause")),
("BallState == 2 and AnimVariable == 4", ("Bouncing", "show_paused")),
("BallState == 2 and AnimVariable == 5", ("Bouncing", "resume")),
("BallState == 2 and AnimVariable > 5", ("default", )),
("True", ("default", )))),
)
label start:
while 1:
show CompositeImage as ci
"meow"
hide ci
"meow"
return
This... nothing will be effected. I've also changed all of that BS I wrote earlier to pass correct placement properties with a simple render.place() which should do exactly the same thing.