WTS/game/scripts/doll/common.rpy
LoafyLemon 1d3a12f0f6 Wheelmenu, Bug fixes
* Implement disabled state for wheelmenu buttons
* Simplify wheelmenu definitions
* Fix bogus warning for doll elements during stale displayable evaluation (cache)
2024-09-24 19:59:59 +01:00

126 lines
4.4 KiB
Plaintext

init -1 python:
### 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(SlottedObject):
"""Container class for commonly used methods and attributes"""
_loading = Text("Loading", align=(0.5, 0.5))
_image = Null()
_image_cached = False
blacklist_toggles = ("hair", "glasses", "pubes", "piercing", "makeup", "tattoo", "earrings")
blacklist_unequip = ("hair",)
blacklist_strip = ("pubes", "piercing", "tattoo")
multislots = ("makeup", "accessory", "piercing", "tattoo")
extensions = {".webp", ".png", ".jxl", ".avif"}
sizes = (1010, 1200) # Default sizes used for defining rare cases
@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
def is_stale(self):
curr_hash = self.generate_hash()
if (stale := curr_hash != self._hash):
self.remove_disk_cache(self._hash)
self._hash = curr_hash
return stale
def create_disk_cache(self, d, hash, size=None, type="img"):
width, height = size or self.sizes
filepath = os.path.join("cache", type, f"{hash}.png").replace("\\", "/") # Windows bleh
rendpath = os.path.join("game", filepath)
syspath = os.path.join(config.gamedir, "cache", type)
try:
os.makedirs(syspath, exist_ok=True)
except OSError:
print(f"Warning! Failed to create cache directory: {cache_dir}")
try:
if not renpy.loadable(filepath):
renpy.render_to_file(d, rendpath, width=width, height=height, resize=True)
return Image(filepath)
except Exception as e:
print(f"Warning! Failed to return cached file: {filepath} - {e}")
return d
def get_disk_cache(self, hash, type="img"):
filepath = os.path.join("cache", type, f"{hash}.png").replace("\\", "/") # Windows bleh
return Image(filepath) if renpy.loadable(filepath) else None
def remove_disk_cache(self, hash, type="img"):
syspath = os.path.join(config.gamedir, "cache", type, f"{hash}.png")
try:
os.unlink(syspath)
except FileNotFoundError:
print(f"Warning! Cannot remove non-existent cached file: {syspath}")
except PermissionError:
print(f"Warning! Permission denied to remove cached file: {syspath}")
except Exception as e:
print(f"Warning! Failed to remove cached file: {syspath} - {e}")
def DollRebuild():
for i in states.dolls:
doll = getattr(store, i)
if doll.is_stale() and not settings.get("multithreading"):
doll.show(ignore_skipping=True)
renpy.restart_interaction()
config.after_load_callbacks.append(DollRebuild)
end_skip_callbacks.append(DollRebuild)