init python: class DollFace(DollMethods): blacklist_blink = {None, "closed", "happyCl", "wink"} def __init__(self, obj, face): self.char = obj self.name = self.char.name self.face = face self.imagepath = "characters/{}/face/".format(self.name) def build_image(self): sprites = [] ### TODO: This piece of code needs to be simplified. # Add facial expressions for k, v in self.face.iteritems(): if v[0] and k not in ("eyes", "pupils"): sprites.append(("{}{}/{}.webp".format(self.imagepath, k, v[0]), v[1])) eyes = self.face["eyes"][0] pupils = self.face["pupils"][0] if eyes not in self.blacklist_blink: blink_path = "{}eyes/closed.webp".format(self.imagepath) eyes_path = "{}eyes/{}.webp".format(self.imagepath, eyes) mask_path = "{}eyes/{}_mask.webp".format(self.imagepath, eyes) pupils_path = "{}pupils/{}.webp".format(self.imagepath, pupils) if pupils: if renpy.loadable(blink_path): normal = Fixed(eyes_path, AlphaMask(pupils_path, mask_path), fit_first=True) sprites.append( (doll_blink(normal, blink_path), self.face["eyes"][1]) ) else: sprites.append((eyes_path, self.face["eyes"][1])) if renpy.loadable(mask_path): sprites.append((AlphaMask(pupils_path, mask_path), self.face["pupils"][1])) else: if eyes: eyes_path = "{}eyes/{}.webp".format(self.imagepath, eyes) sprites.append((eyes_path, self.face["eyes"][1])) mask_path = "{}eyes/{}_mask.webp".format(self.imagepath, eyes) if renpy.loadable(mask_path): pupils_path = "{}pupils/{}.webp".format(self.imagepath, pupils) sprites.append((AlphaMask(pupils_path, mask_path), self.face["pupils"][1])) sprites.sort(key=itemgetter(1)) sprites = tuple(x[0] for x in sprites) return sprites def get_skin(self): for k, v in self.face.iteritems(): skin_path = "{}{}/{}_skin.webp".format(self.imagepath, k, v[0]) if renpy.loadable(skin_path): yield skin_path def get_face(self): return dict((k, v[0]) for k, v in self.face.iteritems()) def set_face(self, **kwargs): """Takes keyword argument(s) with the string name of expression file(s). Returns True if image is changed.""" changed = False for arg, value in kwargs.iteritems(): if value not in (self.face[str(arg)][0], False): self.face[str(arg)][0] = value changed = True if changed: self.rebuild_image() return changed def set_pose(self, pose): if pose is None: self.imagepath = "characters/{}/face/".format(self.name) else: self.imagepath = "characters/{}/poses/{}/face/".format(self.name, pose) self.rebuild_image() return def set_zorder(self, **kwargs): """Takes keyword argument(s) with the string name of face type(s) and int value(s). Returns True if image is changed.""" changed = False for arg, value in kwargs.iteritems(): if value != self.face[str(arg)][1]: self.face[str(arg)][1] = value changed = True if changed: self.rebuild_image() return changed