WTS/game/scripts/doll/common.rpy
LoafyLemon c1b04f6ccd IO Overhaul, Refactoring, and more
* Refactored DollFace
* Refactored DollBody
* Refactored DollCum
* Refactored DollCloth
* Refactored Doll
* Refactored clothing item zorders
* Refactored implementation of body, face, cum, clothing layers
* Refactored function calls
* Removed DollLipstick
* Added DollMakeup class, allowing adding dynamic clothes tracking face states
* Added DollClothDynamic, allowing dynamic clothes tracking other cloth states with bangs support
* Added cache to frequently called functions, drastically reducing the overhead
* Added hash system, reducing clone redundancy
* Added layer modifiers support for all types (face, body, cum, clothes etc.)
* Added support for an arbitrary number of equipped multislot clothing items (makeup, tattoos, piercings, etc.)
* Simplified initialization for clothing items and dolls
* Simplified class function calls
* Reduced the number of image creation calls
* Added hue support for additional skin layers
* Added displayable support to image cropping function
* Replaced store cache with built-in functools cache for _list_files function
* Refactored all character files
* and more...
2023-01-14 23:04:54 +00:00

91 lines
2.8 KiB
Plaintext

init -1 python:
### Global Functions ###
def get_character_emote(char, emote):
return "characters/{}/emotes/{}.webp".format(char, emote) if emote else None
def get_character_pos(char):
global sprite_pos
flip = getattr(renpy.store, char+"_flip", None)
use_head = getattr(renpy.store, "use_"+char+"_head", None)
# Resolve X position for head state
if use_head:
xpos = sprite_pos["x"]["far_right"] if flip == 1 else sprite_pos["x"]["far_left"]
else:
xpos = getattr(renpy.store, char+"_xpos", None)
ypos = getattr(renpy.store, char+"_ypos", None)
return (xpos, ypos)
### Classes ###
class DollDisplayable(renpy.Displayable):
def __init__(self, child, **properties):
super(DollDisplayable, self).__init__(**properties)
self.focusable = None
self.child = child
def render(self, width, height, st, at):
rv = renpy.Render(width, height)
c = self.child
cr = renpy.render(c, width, height, st, at)
# We need to find the 'true' size of the displayable
# otherwise it may end up being the size of a null,
# or any other irrelevant element.
xsize, ysize = cr.get_size()
xoffset, yoffset = c.place(rv, 0, 0, width, height, cr)
width = max(xoffset + xsize, width)
height = max(yoffset + ysize, height)
rv.width = width
rv.height = height
return rv
def event(self, ev, x, y, st):
return None
#raise renpy.IgnoreEvent() # Seems to work similar to NullAction
def focus(self, default=False):
raise Exception("Not Implemented")
def unfocus(self, default=False):
raise Exception("Not Implemented")
def is_focused(self):
return False
def visit_all(self, callback, seen=None):
return
def visit(self):
return []
class DollMethods(object):
"""Container class for commonly used methods and attributes"""
_image = Null()
_image_cached = False
blacklist_toggles = ("hair", "glasses", "pubes", "piercing", "makeup", "tattoo", "earrings")
blacklist_unequip = ("hair",)
multislots = ("makeup", "accessory", "piercing", "tattoo")
extensions = {".webp", ".png", ".jxl"}
sizes = (1010, 1200) # Default sizes used for defining rare cases
def rebuild_image(self):
self._image_cached = True
@property
def image(self):
if not renpy.is_skipping():
if not self._image_cached:
self._image_cached = True
self._image = self.build_image()
return self._image