python early: def execute_init_hell(o): _image_name, _count = o _image = renpy.get_registered_image(_image_name) _image1 = " ".join(_image_name) + " 1" _image2 = " ".join(_image_name) + " 2" _image3 = " ".join(_image_name) + " 3" renpy.image(_image1, Transform(_image, matrixcolor=ColorizeMatrix("#000","#a00"))) renpy.start_predict(_image1) renpy.image(_image2, Transform(_image, matrixcolor=ContrastMatrix(.95)*ColorizeMatrix("#a00","#aaa"))) renpy.start_predict(_image2) renpy.image(_image3, Transform(_image, matrixcolor=ContrastMatrix(.75)*ColorizeMatrix("#000","#a30"))) renpy.start_predict(_image3) def parse_hell(lex): import renpy.parser _image_name = renpy.parser.parse_image_name(lex, string=True) lex.require(',') _count = lex.simple_expression() return (_image_name, _count) def execute_hell(o): _image_name, _count = o _image1 = " ".join(_image_name) + " 1" _image2 = " ".join(_image_name) + " 2" _image3 = " ".join(_image_name) + " 3" renpy.scene() renpy.show(_image_name) renpy.with_statement(Dissolve(1)) renpy.with_statement(Pause(1)) renpy.show(_image1) renpy.with_statement(Dissolve(1)) for i in range(eval(_count)): renpy.show(_image2, tag="hell") renpy.with_statement(Dissolve(.25)) renpy.show(_image3, tag="hell") renpy.with_statement(Dissolve(.25)) renpy.show(_image2, tag="hell") renpy.with_statement(Dissolve(.25)) renpy.hide("hell") renpy.with_statement(Dissolve(.25)) renpy.with_statement(Pause(1)) renpy.scene() renpy.show(_image_name) renpy.with_statement(Dissolve(1)) renpy.register_statement("hell", parse=parse_hell, execute=execute_hell, execute_init=execute_init_hell) init -1 python: class PlayLoop(): def __init__(self, mov, loops=True, transition=None, label=None, hard=False): self.mov = mov self.loops = loops self.transition = transition self.label = label self.hard = hard def play(self): if not self.mov: return store.suppress_overlay = True img = renpy.get_registered_image(self.mov) c = img.channel if self.label: renpy.show(self.label, what=self.mov) else: renpy.show(self.mov) if self.transition: renpy.with_statement(self.transition) d = None while not d: renpy.ui.pausebehavior(.001, False) rv = renpy.ui.interact() d = renpy.music.get_duration(c) while self.loops: if not self.hard: renpy.ui.saybehavior() renpy.ui.pausebehavior(d, self.hard) rv = renpy.ui.interact() if rv: break if self.loops is not True: self.loops -= 1 p = None while not p: renpy.ui.pausebehavior(.001, False) rv = renpy.ui.interact() p = renpy.music.get_pos(c) p = d - p if not self.hard: renpy.ui.saybehavior() renpy.ui.pausebehavior(p, self.hard) rv = renpy.ui.interact() if img.image: if self.label: name = self.label else: name = "img" renpy.show(name, what=img.image) if self.transition: renpy.with_statement(self.transition) else: renpy.hide(self.mov) if self.transition: renpy.with_statement(self.transition) store.suppress_overlay = False def week_save(d): d['week'] = _curr_wk config.save_json_callbacks.append(week_save) def pause_trans(trans, st, at, pi=0, po=5): if st > pi: return None return float(pi + random.random() * po) @renpy.pure def get_colorize(who): if (who is None or who == ""): return "#000" if "{color=#" in who: return who.split("{color=")[1].split("}")[0] try: return renpy.get_widget_properties("who")["color"] except: return gui.accent_color @renpy.pure def get_centered(): cw = renpy.get_widget_properties("window")["style"] if isinstance(cw, (str, unicode)): return cw == "centered_window" elif renpy.in_rollback(): return cw.inspect()[0][0][0] == "centered_window" else: return False @renpy.pure def get_imagesize(d): d = renpy.easy.displayable(d) w, h = renpy.render(d, 0, 0, 0, 0).get_size() w, h = int(round(w)), int(round(h)) return w, h @renpy.pure def isSay(): return renpy.get_screen("say") is not None @renpy.pure def isSayer(): if isSay(): return renpy.get_screen("say").scope.get("who", None) in [None, ""] return False @renpy.pure def isChoice(): return renpy.get_screen("choice") is not None @renpy.pure def getPos(p, say=False, sayer=False): xpos = p[0] or (config.screen_width + gui.scrollbar_size) // 2 if say: ypos = p[1] or config.screen_height - 110 - (_last_textbox_ysize - 80) * say else: ypos = p[1] or config.screen_height // 2 return (xpos, ypos) @renpy.pure def getAnchor(a): try: return {"topleft":(0., 0.), "top":(.5, 0.), "topright":(1., 0.), "left":(0., .5), "center":(.5, .5), "right":(1., .5), "bottomleft":(0., 1.), "bottom":(.5, 1.), "bottomright":(1., 1.)}[a] except KeyError: if isSay(): return (.5, 1.) else: return (.5, .5) @renpy.pure def getSize(s, say=False, sayer=False): return (s or config.screen_height - 110 - (_last_textbox_ysize - 80) * say - 50) def isMM(): return renpy.get_screen("main_menu") is not None @renpy.pure def getImgPos(p): xpos = p[0] or 0 ypos = p[1] or 0 return (xpos, ypos) @renpy.pure def getImgAnchor(a): try: return {"topleft":(0., 0.), "top":(.5, 0.), "topright":(1., 0.), "left":(0., .5), "center":(.5, .5), "right":(1., .5), "bottomleft":(0., 1.), "bottom":(.5, 1.), "bottomright":(1., 1.)}[a] except KeyError: return (0., 0.) def isSplashscreen(): for s in renpy.game.context().dynamic_stack: if s.get('_splash', False): return True return False @renpy.pure def isPlayer(): return renpy.get_screen("mp_window") is not None _last_textbox_ysize = 0 def get_textbox_ysize(what, outlines, choice): rv = gui.dialogue_ypos rv += int(Text(what, style="say_dialogue", outlines=outlines).size(gui.dialogue_width)[1]) rv += 10 rv += int(Text("", style="quick_button_text").size(gui.dialogue_width)[1]) rv += gui.quick_button_borders.top + gui.quick_button_borders.bottom + gui.quick_button_borders.pad_top + gui.quick_button_borders.pad_bottom rv = max(rv, gui.textbox_height) store._last_textbox_ysize = rv return rv import base64 renpy.load_string(base64.b64decode("bGFiZWwgc3RhcnQ6DQogJCBfc2tpcHBpbmcgPSBGYWxzZQ0KICQgbXJfbWFpbl9tZW51LnN0b3AoKQ0KIHNjZW5lIGJsYWNrDQogY2VudGVyZWQgIkNvbmdyYXRzIGZvciBlaXRoZXIgbWFraW5nIGFuIGluY29tcGF0aWJsZSBzYXZlIGZpbGUgbG9hZGFibGUgb3IgY2hhbmdpbmcgdGhlIHNjcmlwdHMhIg0KIGNlbnRlcmVkICJFaXRoZXIgd2F5LCBzZWUgeW91IGluIHRoZSBtYWluIG1lbnUhIg0KICQgcmVucHkucnVuKE1haW5NZW51KGNvbmZpcm09RmFsc2UpKQ0KZGVmaW5lIGNvbmZpZy5sb2FkX2ZhaWxlZF9sYWJlbCA9ICJzdGFydCI="), filename='img') def valid_save(i, slot=False): return FileJson(i, 'week') == _curr_wk def _m1_def_functions__slotname(name, page=None, slot=False): if slot: return name if page is None: page = persistent._file_page try: page = int(page) page = page + persistent._file_folder * config.file_pages_per_folder except ValueError: pass if config.linear_saves_page_size is not None: try: page = int(page) name = int(name) return str((page - 1) * config.linear_saves_page_size + name) except ValueError: pass return str(page) + "-" + str(name) def _m1_def_functions__newest_slot(regexp=None): import re rv = renpy.loadsave.newest_slot_cache.get(regexp, renpy.loadsave.unknown) if rv is renpy.loadsave.unknown: max_mtime = 0 rv = None slots = renpy.loadsave.location.list() for i in slots: if (regexp is not None) and (not re.match(regexp, i)): continue mtime = renpy.loadsave.get_cache(i).get_mtime() if mtime is None: continue if mtime >= max_mtime and valid_save(i, slot=True): rv = i max_mtime = mtime renpy.loadsave.newest_slot_cache[regexp] = rv return rv def FileNamedAction(name, page=None, prompt="", default="", length=None, **kwargs): if renpy.current_screen().screen_name[0] == "load": return FileLoad(name, page=page, **kwargs) else: return FileNamedSave(name, page=page, prompt=prompt, default=default, length=length, **kwargs) class FileNamedSave(FileSave): def __init__(self, name, confirm=True, newest=True, page=None, cycle=False, slot=False, prompt="", default="", length=None): self.prompt = prompt self.default = default self.length = length super(FileNamedSave,self).__init__(name=name,confirm=confirm,newest=newest,page=page,cycle=cycle,slot=slot) def __call__(self): ss = renpy.game.interface.get_screenshot() renpy.call_in_new_context("save_name", prompt=self.prompt, default=self.default, length=self.length) renpy.game.interface.screenshot = ss return super(FileNamedSave,self).__call__() def FileVersion(name, empty=None, missing=None, page=None, slot=False): json = renpy.slot_json(_m1_def_functions__slotname(name, page, slot)) if json is None: return empty return json.get("_version", missing) def FileNewest(name, page=None, slot=False): return _m1_def_functions__newest_slot(r'\d+') == _m1_def_functions__slotname(name, page, slot) def getFilePage(): return -1 if persistent._file_page == "auto" else 0 if persistent._file_page == "quick" else int(persistent._file_page) @renpy.pure class FilePageNumberInputValue(InputValue, DictEquality): def __init__(self): self.default = False self.last = persistent._file_page @property def editable(self): return True def get_text(self): self.last = persistent._file_page rv = self.last current, active = renpy.get_editable_input_value() if ((current is self) and active): rv = "" return rv def set_text(self, s): if not s: s = self.last if s.isdigit(): s = int(s.strip()) if not 1 <= s <= 100: s = self.last else: s = self.last setattr(persistent, "_file_page", str(s)) def enter(self): renpy.run(self.Disable()) raise renpy.IgnoreEvent() renpy.restart_interaction() def _m1_def_functions__enter(self): renpy.run(self.Disable()) raise renpy.IgnoreEvent() renpy.restart_interaction() FilePageNameInputValue.enter = _m1_def_functions__enter class FilePageNextExtended(Action, DictEquality): def __init__(self, max=100, pages=10): page = persistent._file_page if page in ["auto", "quick"]: page = 1 + pages else: page = int(page) if page <= max - pages: page += pages else: page = None self.page = page def __call__(self): if not self.get_sensitive(): return persistent._file_page = str(self.page) renpy.restart_interaction() def get_sensitive(self): return self.page def predict(self): _predict_file_page(self.page) class FilePagePreviousExtended(Action, DictEquality): def __init__(self, pages=10): page = persistent._file_page if page in ["auto", "quick"]: page = None else: page = int(page) if page > pages : page -= pages else: page = None self.page = page def __call__(self): if not self.get_sensitive(): return persistent._file_page = str(self.page) renpy.restart_interaction() def get_sensitive(self): return self.page def predict(self): _predict_file_page(self.page) class EndInput(Action, DictEquality): equality_fields = ['input'] def __init__(self, input): self.input = input def __call__(self): renpy.end_interaction(renpy.get_widget(None, self.input).content) init -1 python: build.classify('**/**.*', None) init python: import random, math, tinytag, time from threading import Thread, Timer, Condition, Lock class ExplosionFactory(NoRollback): def __setstate__(self, state): self.start = 0 vars(self).update(state) self.init() def __init__(self, image, count, xspeed, yspeed, start, radius, pos): def rel_pos(p): if p > 1: p = 1 elif p < 0: p = 0 return p self.image = renpy.easy.displayable(image) self.count = count self.xspeed = xspeed self.yspeed = yspeed self.start = start self.radius = radius sh = renpy.config.screen_height sw = renpy.config.screen_width if isinstance(pos[0], float): pos0 = int(sw * rel_pos(pos[0])) else: pos0 = pos[0] if isinstance(pos[1], float): pos1 = int(sh * rel_pos(pos[1])) else: pos1 = pos[1] self.pos = (pos0, pos1) self.init() def init(self): self.starts = [random.uniform(0, self.start) for _i in xrange(0, self.count)] self.starts.append(self.start) self.starts.sort() def create(self, particles, st): def ranged(n): if isinstance(n, tuple): return random.uniform(n[0], n[1]) else: return n if (st == 0) and not particles: rv = [ ] for _i in xrange(0, self.count): rv.append(ExplosionParticle(self.image, ranged(self.xspeed), ranged(self.yspeed), st, random.uniform(0, 100), self.radius, self.pos)) return rv if particles is None or len(particles) < self.count: if particles and st < self.starts[len(particles)]: return None return [ExplosionParticle(self.image, ranged(self.xspeed), ranged(self.yspeed), st, random.uniform(0, 100), self.radius, self.pos)] def predict(self): return [ self.image ] class ExplosionParticle(NoRollback): def __init__(self, image, xspeed, yspeed, start, offset, radius, pos): if xspeed == 0: xspeed = 1 if yspeed == 0: yspeed = 1 self.image = image self.radius = radius self.xspeed = xspeed self.yspeed = yspeed self.start = start self.offset = offset self.xstart = pos[0] self.ystart = pos[1] def update(self, st): to = st - self.start xpos = self.xstart + to * self.xspeed ypos = self.ystart + to * self.yspeed dx = self.xstart - xpos dy = self.ystart - ypos length = math.hypot( dx, dy) if length > self.radius: return None alpha = 1. dl = length / self.radius if dl > .85: alpha -= dl image = Transform(child=self.image, alpha=alpha) return int(xpos), int(ypos), to + self.offset, image def Explosion(d, count=10, border=50, xspeed=(-50, 50), yspeed=(100, 200), start=0, fast=False, horizontal=False, radius=50, pos=(0, 0)): if horizontal: xspeed,