diff --git a/starcheat/assets.py b/starcheat/assets.py index 04032c3..08e1b1e 100644 --- a/starcheat/assets.py +++ b/starcheat/assets.py @@ -903,6 +903,11 @@ def val(key): return directives def get_preview_image(self, name, gender): + """Return raw image data for species placeholder pic. + + I don't think this is actually used anywhere in game. Some mods don't + include it.""" + species = self.get_species(name.lower()) try: try: @@ -916,10 +921,13 @@ def get_preview_image(self, name, gender): return None def render_player(self, player): + """Return an Image of a fully rendered player from a save.""" + name = player.get_race() gender = player.get_gender() asset_loc = self.get_species(name)[0][1] + # load up body spritesheets for species body_sprites = self.assets.read("/humanoid/%s/%sbody.png" % (name, gender), asset_loc, True) frontarm_sprites = self.assets.read("/humanoid/%s/frontarm.png" % name, @@ -929,46 +937,59 @@ def render_player(self, player): head_sprites = self.assets.read("/humanoid/%s/%shead.png" % (name, gender), asset_loc, True) + # crop the spritesheets body_img = Image.open(BytesIO(body_sprites)).convert("RGBA").crop((43, 0, 86, 43)) frontarm_img = Image.open(BytesIO(frontarm_sprites)).convert("RGBA").crop((43, 0, 86, 43)) backarm_img = Image.open(BytesIO(backarm_sprites)).convert("RGBA").crop((43, 0, 86, 43)) head_img = Image.open(BytesIO(head_sprites)).convert("RGBA").crop((43, 0, 86, 43)) + # hair image if set hair = player.get_hair() hair_img = None if hair[0] != "": hair_img = self.get_hair_image(name, hair[0], hair[1], gender) + # facial hair if set facial_hair = player.get_facial_hair() facial_hair_img = None if facial_hair[0] != "": facial_hair_img = self.get_hair_image(name, facial_hair[0], facial_hair[1], gender) + # facial mask if set facial_mask = player.get_facial_mask() facial_mask_img = None if facial_mask[0] != "": facial_mask_img = self.get_hair_image(name, facial_mask[0], facial_mask[1], gender) + # new blank canvas! base = Image.new("RGBA", (43, 43)) + # the order of these is important! + + # back arm first base.paste(backarm_img) + # then the head base.paste(head_img, mask=head_img) + # hair if set if hair_img is not None: try: base.paste(hair_img, mask=hair_img) except ValueError: logging.exception("Bad hair image: %s, %s", hair[0], hair[1]) + # body base.paste(body_img, mask=body_img) base.paste(frontarm_img, mask=frontarm_img) + # facial mask if set if facial_mask_img is not None: try: base.paste(facial_mask_img, mask=facial_mask_img) except ValueError: logging.exception("Bad facial mask image: %s, %s", facial_mask[0], facial_mask[1]) + # facial hair if set if facial_hair_img is not None: try: base.paste(facial_hair_img, mask=facial_hair_img) @@ -1005,7 +1026,6 @@ def __init__(self, assets): def get_mode_type(self, name): """Return a mode type key name from its pretty name.""" - # TODO: is there a better way to do this kinda thing? for key in self.mode_types.keys(): if name == self.mode_types[key]: return key diff --git a/starcheat/gui/itemedit.py b/starcheat/gui/itemedit.py index 535a130..0bff056 100644 --- a/starcheat/gui/itemedit.py +++ b/starcheat/gui/itemedit.py @@ -9,7 +9,8 @@ # once that's complete, work can be started on proper item generation. to begin, # we just wanna pull in all the default values of an item -from PyQt5.QtWidgets import QDialog, QTableWidgetItem, QDialogButtonBox, QFileDialog, QListWidgetItem +from PyQt5.QtWidgets import QDialog, QTableWidgetItem, QDialogButtonBox +from PyQt5.QtWidgets import QInputDialog, QListWidgetItem, QFileDialog from PyQt5.QtGui import QPixmap from PIL.ImageQt import ImageQt import json, copy, logging @@ -217,16 +218,42 @@ def clear_item_options(self): self.item["data"] = {} def new_item_edit_options(self, new): + """Edit the selected item option with custom dialog.""" + if new: selected = ItemOptionWidget("", None) else: selected = self.ui.variant.currentItem() # TODO: need a better way to lay this out. it's going to get big + + # this is for the qinputdialog stuff. can't set signals on them + generic = False if selected.option[0] in ["inventoryIcon", "image", "largeImage"]: dialog = ImageBrowser(self.dialog, self.assets) def get_option(): return selected.option[0], dialog.get_key() + elif type(self.item["data"][selected.option[0]]) is str: + generic = True + text, ok = QInputDialog.getText(self.dialog, "Edit Text", selected.option[0], + text=self.item["data"][selected.option[0]]) + if ok: + self.item["data"][selected.option[0]] = text + elif type(self.item["data"][selected.option[0]]) is float: + generic = True + num, ok = QInputDialog.getDouble(self.dialog, "Edit Double", selected.option[0], + self.item["data"][selected.option[0]], decimals=2) + if ok: + self.item["data"][selected.option[0]] = num + elif type(self.item["data"][selected.option[0]]) is int: + generic = True + num, ok = QInputDialog.getDouble(self.dialog, "Edit Integer", selected.option[0], + self.item["data"][selected.option[0]]) + if ok: + self.item["data"][selected.option[0]] = num + elif type(self.item["data"][selected.option[0]]) is bool: + generic = True + self.item["data"][selected.option[0]] = not self.item["data"][selected.option[0]] else: dialog = ItemEditOptions(self.dialog, selected.option[0], selected.option[1]) def get_option(): @@ -236,11 +263,13 @@ def get_option(): def save(): new_option = get_option() self.item["data"][new_option[0]] = new_option[1] - self.populate_options() - self.update_item_info(self.item["name"], self.item["data"]) - dialog.dialog.accepted.connect(save) - dialog.dialog.exec() + if not generic: + dialog.dialog.accepted.connect(save) + dialog.dialog.exec() + + self.populate_options() + self.update_item_info(self.item["name"], self.item["data"]) def remove_option(self): """Remove the currently selected item option."""