forked from SilverStudioGames/WTS
Outfit import/export
* Re-implemented image payload injection using Python3-compliant methods * Added sanity checks for image importing and exporting * Added compression for the payload * Added user input for exported image file names * Removed redundant layer for Tonks' ribbon bra * Updated MyMod clothing definition example. * Fixed regression in outfit clone functions
This commit is contained in:
parent
5fdf1e87fe
commit
fb8e3aab0f
BIN
game/characters/tonks/clothes/bra/ribbon/backupskin.webp
(Stored with Git LFS)
BIN
game/characters/tonks/clothes/bra/ribbon/backupskin.webp
(Stored with Git LFS)
Binary file not shown.
@ -1,13 +1,19 @@
|
||||
# Add new hairstyle for character as an instance of DollCloth,
|
||||
# make sure the variable name is unique, preferably starting with mod name.
|
||||
default MyMod_ponytail = DollCloth(
|
||||
modpath="mods/mymod/", # shortened filepath to this file
|
||||
modpath="MyMod", # File path; Usually a mod folder name. (case insensitive)
|
||||
name="hermione", # Character name (case sensitive)
|
||||
categories=("head","hair"), # Main category and subcategory of the item
|
||||
type="hair", # Item type
|
||||
id="ponytail", # Item identificator
|
||||
categories=("head","hair"), # Main category and subcategory of the item (case sensitive)
|
||||
type="hair", # Item type (case sensitive)
|
||||
id="ponytail", # Item identifier (case sensitive)
|
||||
unlocked=True, # True=Item is unlocked by default, False=Item is a part of the outfit and requries to be bought
|
||||
level=0, # Character whoring/friendship level required to wear this cloth. (Optional)
|
||||
armfix=False, # If cloth images intersect with arm layers, set to True. (Optional)
|
||||
color=[[152, 89, 48, 255], [195, 137, 89, 255]] # Python list with default colours in RGBA format applicable for each colourable file layer
|
||||
color=["#985930", "#c38959"], # Python list with default colours in one of the formats listed down below.
|
||||
zorder=None # Item zorder number, or None, if None default zorder for the slot will be used.
|
||||
)
|
||||
|
||||
# Example valid colour formats:
|
||||
# RGB: [(255, 255, 255), (255, 255, 255)]
|
||||
# RGBA: [(255, 255, 255, 255), (255, 255, 255, 255)]
|
||||
# HEX: [("#985930", "#c38959")]
|
||||
# HEXA: [("#985930FF", "#c38959FF")]
|
||||
|
@ -252,8 +252,6 @@ init python:
|
||||
|
||||
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."""
|
||||
if self.parent:
|
||||
return self
|
||||
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, self.modpath, self)
|
||||
|
||||
def is_modded(self):
|
||||
|
@ -183,6 +183,4 @@ init python:
|
||||
|
||||
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."""
|
||||
if self.parent:
|
||||
return self
|
||||
return DollClothDynamic(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, self.modpath, self._tracking, self)
|
||||
|
@ -505,11 +505,11 @@ init python:
|
||||
# Grab data
|
||||
if fromfile:
|
||||
try:
|
||||
imported = image_payload.decode(path)
|
||||
except:
|
||||
if image_payload._file:
|
||||
image_payload._file.close()
|
||||
imported = ImagePayload().extract(path)
|
||||
except Exception as e:
|
||||
renpy.notify("Import failed: Corrupted file.")
|
||||
print(e)
|
||||
renpy.block_rollback()
|
||||
return None
|
||||
else:
|
||||
imported = get_clipboard()
|
||||
@ -518,8 +518,9 @@ init python:
|
||||
if imported:
|
||||
try:
|
||||
imported = make_revertable(evaluate(imported))
|
||||
except:
|
||||
except Exception as e:
|
||||
renpy.notify("Import failed: Corrupted outfit data.")
|
||||
print(e)
|
||||
renpy.block_rollback()
|
||||
return None
|
||||
|
||||
|
@ -86,16 +86,21 @@ init python:
|
||||
def export_data(self, filename, tofile=True):
|
||||
"""Exports outfit to .png file or clipboard text."""
|
||||
exported = [self.group[0].name]
|
||||
exported.extend([x.id, x.color] for x in self.group)
|
||||
|
||||
for i in self.group:
|
||||
if i.color:
|
||||
color = [j.hexcode for j in i.color]
|
||||
exported.append([i.id, color])
|
||||
|
||||
# Encode data
|
||||
if tofile:
|
||||
path = "{}/game/outfits/".format(config.basedir)
|
||||
fn = "{}.png".format(filename)
|
||||
path = os.path.join(config.gamedir, "outfits")
|
||||
|
||||
if not os.path.exists(path):
|
||||
os.makedirs(path)
|
||||
|
||||
path = os.path.join(path, "_temp.png")
|
||||
|
||||
d = Transform(self.image, crop=(210, 200, 700, 1000), anchor=(0.5, 1.0), align=(0.5, 1.0), xsize=310, ysize=470, fit="contain")
|
||||
d = Fixed(
|
||||
"interface/wardrobe/export_background.webp",
|
||||
@ -105,8 +110,9 @@ init python:
|
||||
Text("Ver. {}".format(config.version), size=10, align=(0.99, 0.99))
|
||||
)
|
||||
|
||||
displayable_to_file(d, path+fn, size=(310, 470) )
|
||||
image_payload.encode(filename, str(exported))
|
||||
displayable_to_file(d, path, size=(310, 470) )
|
||||
ImagePayload().inject("_temp.png", filename, str(exported))
|
||||
os.remove(path)
|
||||
else:
|
||||
set_clipboard(exported)
|
||||
renpy.notify("Export successful!")
|
||||
|
@ -97,7 +97,7 @@ init -1 python:
|
||||
try:
|
||||
return __import__('ast').literal_eval(txt)
|
||||
except Exception as e:
|
||||
print("Error evaluating clipboard data:")
|
||||
print("Error evaluating data:")
|
||||
print(e)
|
||||
|
||||
def reset_variables(*args):
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -266,7 +266,12 @@ label wardrobe_menu():
|
||||
|
||||
elif _choice[0] == "export":
|
||||
python:
|
||||
_choice[1].export_data(datetime.datetime.now().strftime("%d %b %Y-%H%M%S"))
|
||||
filename = renpy.input("Save as:", datetime.datetime.now().strftime("%d %b %Y-%H%M%S"))
|
||||
|
||||
if not filename.endswith(".png"):
|
||||
filename += ".png"
|
||||
|
||||
_choice[1].export_data(filename)
|
||||
achievements.unlock("export")
|
||||
|
||||
elif _choice[0] == "import":
|
||||
|
Loading…
Reference in New Issue
Block a user