WTS/game/scripts/cds.rpy

118 lines
3.4 KiB
Plaintext

python early hide:
import inspect
__register_params = frozenset(inspect.signature(renpy.register_statement).parameters).difference({"name", "parse"})
def register_decorator(cls):
"""
A class decorator which registers a new statement.
The name of the statement will be the class name unless a `name` class attribute is present, which should be a string.
The `parse` method should be a static method that returns an object which will be passed to the other methods as `self`.
Returning an instance of the class is disabled for now.
"""
# security
def raiser(*args, **kwargs):
raise NotImplementedError("Returning an instance of the class is disabled")
cls.__init__ = raiser
name = getattr(cls, "name", cls.__name__)
parse = getattr(cls, "parse", cls) # left in
renpy.register_statement(name,
parse=parse,
**{k:getattr(cls, k) for k in __register_params.intersection(vars(cls))})
return cls
python early:
def parse_chibi(l):
who = l.simple_expression()
action = l.simple_expression()
return (who, action)
def execute_chibi(p):
print(f"{p}")
who, action = p
func = eval(f"{who}_chibi.{action}")
# print(f"Execution: {who} {action}")
def lint_chibi(p):
who, action = p
try:
chibi = eval(f"{who}_chibi")
except Exception:
renpy.error(f"Character chibi not defined: {who}")
def predict_chibi(p):
who, action = p
chibi = eval(f"{who}_chibi")
doll = eval(f"{who}")
layers = (
l[0] for pose in chibi.poses.keys()
for k in doll.states.values() if k[0] and k[2]
for l in k[0].get_layers(k[0]._hash, subpath=posixpath.join("chibi", pose)).values()
)
return layers
renpy.register_statement(
name="chibi",
parse=parse_chibi,
execute=execute_chibi,
lint=lint_chibi,
predict=predict_chibi,
)
def parse_random(l):
l.require(":")
l.expect_eol()
ll = l.subblock_lexer()
blocks = []
while ll.advance():
with ll.catch_error():
weight = 1.0
condition = "True"
if ll.keyword("block"):
ll.expect_block("block")
block = ll.subblock_lexer().renpy_block()
if ll.keyword("weight"):
weight = float(ll.require(ll.float))
if ll.keyword("if"):
ll.expect_block("if block")
condition = ll.require(ll.python_expression)
else:
block = ll.renpy_statement()
blocks.append((block, weight, condition))
return {"blocks": blocks}
def next_random(p):
blocks = [(block, weight, condition) for block, weight, condition in p["blocks"] if eval(condition)]
total_weight = sum(weight for _, weight, _ in blocks)
n = renpy.random.random() * total_weight
for block, weight, _ in blocks:
if n <= weight:
break
else:
n -= weight
return block
renpy.register_statement(
name="random",
block=True,
predict_all=True,
parse=parse_random,
next=next_random,
)