2022-05-16 23:48:22 +00:00
init python:
2023-04-20 18:59:55 +00:00
class DollCloth(DollMethods):
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
layer_types = {
"mask": "-1",
2023-02-07 19:22:05 +00:00
"skin": 10,
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
"armfix": "+1",
"outline": None,
"extra": None,
"overlay": None,
}
layer_modifiers = {
"back": "-300",
"front": "+300",
"zorder": None,
}
2023-07-11 21:57:49 +00:00
_loading = Fixed(Text("Loading", align=(0.5, 0.5)), xysize=(96, 96))
2023-04-20 18:59:55 +00:00
__slots__ = ("name", "categories", "type", "id", "color", "unlocked", "level", "blacklist", "modpath", "parent", "char", "color_default", "zorder", "seen", "_hash")
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
def __init__(self, name, categories, type, id, color, zorder=None, unlocked=False, level=0, blacklist=[], modpath=None, parent=None):
2022-05-16 23:48:22 +00:00
self.name = name
self.categories = categories
self.type = type
self.id = id
2023-02-08 21:40:28 +00:00
self.color = [Color( (tuple(x) if isinstance(x, list) else x) ) for x in color] if color else None
2022-05-16 23:48:22 +00:00
self.unlocked = unlocked
self.level = level
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
self.blacklist = blacklist
2023-02-08 17:37:12 +00:00
self.modpath = "mods/" + posixpath.normpath(modpath) if modpath else ""
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
self.parent = parent
2022-05-16 23:48:22 +00:00
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
self.char = eval(name)
2023-02-08 21:40:28 +00:00
self.color_default = [x for x in self.color] if self.color else None
2023-02-07 19:22:05 +00:00
self.zorder = zorder or self.char.states[type][1]
2022-05-16 23:48:22 +00:00
self.seen = self.unlocked
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
self._hash = self.generate_hash()
2023-07-11 21:57:49 +00:00
self._button = DefaultQueue()
2022-05-16 23:48:22 +00:00
2023-07-12 22:25:53 +00:00
if config.developer:
self._loading = Fixed(Text(self.id, size=8), self._loading, xysize=(96, 96))
2022-05-16 23:48:22 +00:00
# Add to character wardrobe and unordered list
if not parent:
self.char.wardrobe.setdefault(self.categories[0], {}).setdefault(self.categories[1], []).append(self)
self.char.wardrobe_list.append(self)
2023-02-07 19:22:05 +00:00
# Define new item slot type if doesn't exist
self.char.states.setdefault(self.type, [None, (self.zorder or 1), True])
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
def __repr__(self):
return f"DollCloth(name={self.name}, categories={self.categories}, type={self.type}, id={self.id}, color={self.color}, zorder={self.zorder}, unlocked={self.unlocked}, level={self.level}, blacklist={self.blacklist}, parent={self.parent}, modpath={self.modpath or None})"
def __hash__(self):
return self._hash
2023-01-18 20:22:59 +00:00
def __eq__(self, obj):
if not isinstance(obj, DollCloth):
return NotImplemented
return self._hash == obj._hash
2023-05-14 16:31:31 +00:00
def __lt__(self, obj):
if not isinstance(obj, DollCloth):
return NotImplemented
return self._hash < obj._hash
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
def generate_hash(self):
2023-01-18 20:22:59 +00:00
salt = str( [self.name, self.char.pose, self.type, self.id, str(self.color), str(self.char.body._hash)] )
2024-09-05 09:00:09 +00:00
return hashstring(salt)
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
2023-10-18 11:48:35 +00:00
@functools.cache # <- TODO: Reevaluate if this function should allow multiple caches (aside from different subpaths)
2023-02-19 02:56:26 +00:00
def get_layers(self, hash, subpath=""):
2023-02-22 17:50:13 +00:00
path = posixpath.join(self.modpath, "characters", self.name, "poses", self.char.pose, subpath, "clothes", self.type, self.id)
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
extensions = self.extensions
types = self.layer_types
modifiers = self.layer_modifiers
layers = {}
for f in renpy.list_files():
fp, fn = os.path.split(f)
fn, ext = os.path.splitext(fn)
if not fp == path or not ext in extensions:
continue
# For user's sake, simplicty, and compatibility reasons,
# we sort the layers in the code instead.
#
# Each file name part represents the following:
# layertype_subtype*_zorder*_INT*
#
# Parts marked with * are optional and can be inserted out of order,
# with the exception of zorder, which requires an integer appendix.
#
# Example valid file name combinations:
#
# 0.webp
# 0_zorder_15.webp
# 0_front.webp
# outline.webp
# outline_back.webp
#
# If multiple files exist but with different extension,
# only the first file will be added to the dictionary.
ltype, *tails = fn.rsplit("_")
if not ltype.isdigit() and not ltype in types:
2024-03-26 19:31:41 +00:00
print(f"Invalid layer type for file: {f}")
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
continue
zorder = z if (z := types.get(ltype)) is not None else self.zorder
if isinstance(zorder, str):
# Note: Layer uses relative zorder if it's passed as a string
zorder = self.zorder + int(zorder)
if tails:
lmodifier, *tails = tails
if not lmodifier in modifiers:
2024-03-26 19:31:41 +00:00
print(f"Invalid modifier for file: {f}")
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
continue
2022-12-23 16:26:49 +00:00
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
zorder_mod = modifiers.get(lmodifier)
zorder = (zorder + int(zorder_mod)) if lmodifier != "zorder" else int(tails[-1])
2023-07-26 17:54:30 +00:00
layers.setdefault("_".join([ltype, lmodifier, str(zorder)]), [f, zorder])
2022-12-23 16:26:49 +00:00
else:
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
layers.setdefault(ltype, [f, zorder])
2022-05-16 23:48:22 +00:00
2023-10-18 11:48:35 +00:00
return dict(sorted(layers.items(), key=lambda x: (extract_number(x[0]), x[0])))
2022-05-16 23:48:22 +00:00
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
@functools.cache
2023-06-18 22:18:50 +00:00
def build_image(self, hash, subpath="", matrix=None, maxsize=(1010, 1200)):
# Note to self: This function is called from within the new chibi class during clothes iteration,
# as a bridge to enable colourable clothing for chibis, double-check the changes before submitting them.
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
if matrix is None:
2023-07-26 23:56:37 +00:00
matrix = self.char.body.matrix
2022-05-16 23:48:22 +00:00
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
processors = {
2023-06-18 22:18:50 +00:00
"skin": lambda file, _: Transform(file, maxsize=maxsize, matrixcolor=matrix),
"armfix": lambda file, _: Transform(file, maxsize=maxsize, matrixcolor=matrix),
"colored": lambda file, n: self.apply_color(file, int(n), maxsize),
"default": lambda file, _: Transform(file, maxsize=maxsize),
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
}
2022-05-16 23:48:22 +00:00
2023-02-19 02:56:26 +00:00
layers = self.get_layers(hash, subpath)
2023-01-18 20:22:59 +00:00
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
sprites = []
for identifier, (file, zorder) in layers.items():
2022-05-16 23:48:22 +00:00
2023-07-26 17:54:30 +00:00
if ((n := identifier.split("_", 1)[0]).isdigit()):
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
processor = processors["colored"]
else:
processor = processors.get(identifier, processors["default"])
2022-05-16 23:48:22 +00:00
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
processed_file = processor(file, n)
sprites.append((identifier, processed_file, zorder))
2022-05-16 23:48:22 +00:00
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
return sprites
2022-05-16 23:48:22 +00:00
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
@property
def image(self):
2023-01-18 20:22:59 +00:00
if not renpy.is_skipping() and self.is_stale():
hash = self._hash
2022-05-16 23:48:22 +00:00
2023-01-18 20:22:59 +00:00
sprites = self.build_image(hash)
sprites.sort(key=itemgetter(2))
sprites = [x[1] for x in sprites]
2022-05-16 23:48:22 +00:00
2023-01-18 20:22:59 +00:00
self._image = Fixed(*sprites, fit_first=True)
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
return self._image
2022-05-16 23:48:22 +00:00
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
@functools.cache
def build_icon(self, hash):
2024-09-10 13:31:48 +00:00
if (d := self.get_disk_cache(hash)):
return d
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
matrix = SaturationMatrix(0.0)
sprites = [i for i in self.build_image(hash, matrix=matrix) if not i[0] == "mask"]
2023-02-07 19:22:05 +00:00
2024-10-16 19:59:14 +00:00
icon_sprite = Fixed(*[i[1] for i in sprites], fit_first=True)
2023-03-07 19:30:15 +00:00
sprites.extend(self.char.body.build_image(self.char.body._hash, matrix=matrix))
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
sprites.sort(key=itemgetter(2))
2023-01-20 20:21:39 +00:00
2022-05-16 23:48:22 +00:00
wmax, hmax = self.sizes
2024-10-16 19:59:14 +00:00
wmin = hmin = 128
padding = 32
2022-05-16 23:48:22 +00:00
2024-10-16 19:59:14 +00:00
x, y, w, h = crop_whitespace_surface(icon_sprite)
xoffset, yoffset = w//2, h//2
w = h = max(w, h)
2022-05-16 23:48:22 +00:00
2024-10-16 19:59:14 +00:00
if w == 0 or h == 0:
return Null()
2022-05-16 23:48:22 +00:00
2024-10-16 19:59:14 +00:00
w = max(wmin, w + padding)
h = max(hmin, h + padding)
2022-05-16 23:48:22 +00:00
2024-10-16 19:59:14 +00:00
x = clamp( (x - w//2) + xoffset, 0, wmax)
y = clamp( (y - h//2) + yoffset, 0, hmax)
2022-05-16 23:48:22 +00:00
# Forbid exceeding the image height.
if y+h > hmax:
y = hmax-h
2024-09-10 13:31:48 +00:00
d = Transform(Fixed(*[i[1] for i in sprites], fit_first=True), crop=(x, y, w, h), size=(256, 256), fit="contain", align=(0.5, 0.5))
return self.create_disk_cache(d, hash)
2022-05-16 23:48:22 +00:00
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
@property
def icon(self):
return self.build_icon(self._hash)
2022-05-16 23:48:22 +00:00
2023-07-11 21:57:49 +00:00
def _build_button(self, _hash):
2024-10-13 08:38:11 +00:00
style = "wardrobe_item_button"
2023-07-11 21:57:49 +00:00
is_seen = self.seen
is_equipped = self.char.is_equipped_item(self)
is_inadequate = bool(get_character_progression(self.char.name) < self.level)
is_blacklisted = self.char.is_blacklisted(self.type)
is_blacklister = any(self.char.is_equipped(x) for x in self.blacklist)
is_modded = bool(self.modpath)
warnings = []
if is_blacklisted or is_blacklister:
blacklisted = [x for x in self.blacklist if self.char.is_equipped(x)] # Offender (List currently blacklisted clothing types by this item)
blacklister = self.char.get_blacklister(self.type) # Victim (List clothing types blacklisting this item )
warnings.append("Incompatible with:{size=-4}\n" + "\n".join(set(blacklisted + blacklister)) + "{/size}")
2024-10-13 08:38:11 +00:00
child = AlphaMask(Transform(self.icon, xysize=(96, 96)), Transform("wheelmenu_button_opaque", xysize=(96, 96)))
2023-07-11 21:57:49 +00:00
hbox = []
overlay = []
2024-10-15 16:22:38 +00:00
action = [Function(wardrobe.equip, self), self.build_button]
2023-07-11 21:57:49 +00:00
unhovered = None
if is_inadequate:
warnings.append("Character level too low")
if is_modded:
warnings.append("Item belongs to a mod:\n{size=-4}{color=#35aae2}" + self.get_modname() + "{/color}{/size}")
hbox.append(Text("M", color="#00b200", style="wardrobe_button_text"))
if is_blacklisted or is_blacklister:
hbox.append(Text("!", color="#b20000", style="wardrobe_button_text"))
for i in self.char.wardrobe_list:
if i.unlocked and i.type == self.type:
action.append(i.build_button)
if config.developer and self.level > 0:
hbox.append(Text(str(self.level), color="#00ffff", style="wardrobe_button_text"))
if not is_seen:
unhovered = [Function(self.mark_as_seen), self.clear_button_cache, self.build_button]
overlay.append(Text("NEW", align=(1.0, 1.0), offset=(-6, -6), style="wardrobe_button_text"))
2024-10-13 08:38:11 +00:00
# if is_equipped:
# overlay.append(Transform("interface/topbar/icon_check.webp", align=(1.0, 1.0), offset=(-6, -6), size=(24, 24)))
2023-07-11 21:57:49 +00:00
if hbox:
overlay.append(HBox(*hbox, offset=(6, 6)))
if overlay:
child = Fixed(child, *overlay, fit_first=True)
if is_inadequate:
2024-10-15 16:22:38 +00:00
style = "wardrobe_item_button_inadequate"
2023-07-11 21:57:49 +00:00
2024-10-13 08:38:11 +00:00
return Button(child=child, focus_mask=None, xysize=(96, 96), action=action, tooltip=("\n".join(warnings)), unhovered=unhovered, style=style, selected=is_equipped)
2023-07-11 21:57:49 +00:00
@functools.cache
def build_button(self, _=None):
def _func(self, hash):
result = self._build_button(self._hash)
self._button.put(result)
thread = DollThread(target=_func, args=(self, self._hash))
thread.start()
2023-07-14 22:52:27 +00:00
@property
def button(self):
if settings.get("multithreading"):
2023-07-14 01:33:58 +00:00
return self._button.get_with_default(self._loading)
2023-07-14 22:52:27 +00:00
else:
2023-07-14 01:33:58 +00:00
return self._build_button(self._hash)
2023-07-11 21:57:49 +00:00
def clear_button_cache(self):
2023-07-14 01:33:58 +00:00
if not settings.get("multithreading"):
return
2023-07-11 21:57:49 +00:00
self.build_button.cache_clear()
2023-06-18 22:18:50 +00:00
def apply_color(self, img, n, maxsize):
2022-05-16 23:48:22 +00:00
"""Takes image and int layer number. Used internally."""
2023-02-13 22:59:46 +00:00
try:
2023-05-14 16:31:31 +00:00
c = self.color[n]
2023-06-08 16:41:06 +00:00
# Method 1
# r,g,b = c.rgb
# average = max(min((r + g + b) / 3, 0.6666), 0.3333)
# Method 2
# lightness = max(min(c.hls[1], 0.6666), 0.3333)
# average = (lightness, lightness, lightness)
# Method 3
# r,g,b = c.rgb
# luster = (max(r,g,b)+min(r,g,b)) / 2
# c = c.replace_lightness(luster)
# average = (luster, luster, luster)
# Method 4
average = (0.3333, 0.3333, 0.3333)
2024-03-26 19:31:41 +00:00
2023-06-18 22:18:50 +00:00
return Transform(img, maxsize=maxsize, matrixcolor=SepiaMatrix(c, desat=average)*OpacityMatrix(c.alpha))
2023-06-08 16:41:06 +00:00
2023-03-13 21:18:40 +00:00
except TypeError:
print(f"Item doesn't support colors but was supplied with a list; Try removing numbered files in its directory:\n{self.__repr__()}")
d = At(Frame(Text("TypeErr", color="#ffff00"), tile=True), blink_repeat)
return Transform(AlphaMask(d, img))
2023-02-13 22:59:46 +00:00
except IndexError:
2023-03-13 21:18:40 +00:00
print(f"Mismatched number of textures and colors; Try reducing number of supplied colours in item definition:\n{self.__repr__()}")
2023-02-13 22:59:46 +00:00
d = At(Frame(Text("IndxErr", color="#ff0000"), tile=True), blink_repeat)
return Transform(AlphaMask(d, img))
2022-05-16 23:48:22 +00:00
def set_color(self, n):
"""Takes int layer number for manual color picking or a list to replace the cloth color in its entirety."""
if isinstance(n, int):
2023-02-08 21:40:28 +00:00
col = self.color[n]
dcol = self.color_default[n]
2022-07-05 20:38:03 +00:00
cp.live_replace(col)
cp.start_replace(col)
cp.default_replace(dcol)
renpy.show_screen("colorpickerscreen", self)
while True:
2023-02-08 21:40:28 +00:00
try:
action, value = ui.interact()
except:
print(f"{ui.interact()}")
break
2022-07-05 20:38:03 +00:00
if action == "layer":
n = value
2023-02-08 21:40:28 +00:00
col = self.color[value]
dcol = self.color_default[value]
2022-07-05 20:38:03 +00:00
cp.live_replace(col)
cp.start_replace(col)
cp.default_replace(dcol)
elif action == "released":
2023-02-08 21:40:28 +00:00
self.color[n] = value
2023-01-18 20:22:59 +00:00
self.is_stale()
2022-07-05 20:38:03 +00:00
elif action == "replace":
2023-02-08 21:40:28 +00:00
self.color[n] = value
2022-07-05 20:38:03 +00:00
cp.live_replace(value)
2023-01-18 20:22:59 +00:00
self.is_stale()
2022-07-05 20:38:03 +00:00
elif action == "finish":
break
renpy.hide_screen("colorpickerscreen")
2022-05-16 23:48:22 +00:00
elif isinstance(n, list):
2023-02-08 21:40:28 +00:00
self.color = [Color( (tuple(x) if isinstance(x, list) else x) ) for x in n]
2023-02-07 19:22:05 +00:00
self.is_stale()
2022-05-16 23:48:22 +00:00
def reset_color(self, n=None):
"""Reset cloth color. Takes optional int layer number to reset only specific layer color."""
if n:
2023-02-08 21:40:28 +00:00
self.color[n] = self.color_default[n]
2022-05-16 23:48:22 +00:00
else:
2023-02-08 21:40:28 +00:00
self.color = [x for x in self.color_default]
2023-01-18 20:22:59 +00:00
self.is_stale()
2022-05-16 23:48:22 +00:00
def clone(self):
"""Creates a clone of this cloth object. Since it requires a parent object it should be used internally only to avoid object depth issue."""
2023-07-20 21:11:17 +00:00
modpath = self.modpath.lstrip("mods/")
return DollCloth(self.name, self.categories, self.type, self.id, [x for x in self.color] if self.color else None, self.zorder, self.unlocked, self.level, self.blacklist, modpath, self)
2022-05-16 23:48:22 +00:00
def is_modded(self):
"""Returns True if item comes from a mod."""
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
return bool(self.modpath)
2022-05-16 23:48:22 +00:00
def get_modname(self):
"""Return the name of the mod directory if exists."""
return self.modpath.split("/")[1] if self.is_modded() else None
def mark_as_seen(self):
self.seen = True
def is_multislot(self):
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
return self.type in self.multislots
2022-05-16 23:48:22 +00:00
def unlock(self):
self.unlocked = True
if self.parent:
self.parent.unlock()