Added new post-gen option to change TF Piece GFX
This commit is contained in:
@@ -208,6 +208,7 @@ class CustomSettings(object):
|
||||
|
||||
# rom adjust stuff
|
||||
args.sprite[p] = get_setting(settings['sprite'], args.sprite[p])
|
||||
args.triforce_gfx[p] = get_setting(settings['triforce_gfx'], args.triforce_gfx[p])
|
||||
args.disablemusic[p] = get_setting(settings['disablemusic'], args.disablemusic[p])
|
||||
args.quickswap[p] = get_setting(settings['quickswap'], args.quickswap[p])
|
||||
args.reduce_flashing[p] = get_setting(settings['reduce_flashing'], args.reduce_flashing[p])
|
||||
|
||||
121
source/classes/ItemGfxSelector.py
Normal file
121
source/classes/ItemGfxSelector.py
Normal file
@@ -0,0 +1,121 @@
|
||||
from tkinter import Button, Canvas, Label, LabelFrame, Frame, PhotoImage, Scrollbar, Toplevel, LEFT, BOTTOM, X, RIGHT, TOP
|
||||
import os
|
||||
from GuiUtils import ToolTips, set_icon
|
||||
from Utils import local_path
|
||||
|
||||
|
||||
class ItemGfxSelector(object):
|
||||
def __init__(self, parent, callback, valid_items=None):
|
||||
self.parent = parent
|
||||
self.window = Toplevel(parent)
|
||||
self.window.geometry("800x650")
|
||||
self.callback = callback
|
||||
self.valid_items = valid_items if valid_items else []
|
||||
|
||||
self.window.wm_title("Select Triforce Piece Graphics")
|
||||
self.window['padx'] = 5
|
||||
self.window['pady'] = 5
|
||||
|
||||
def open_itemgfx_dir(_evt):
|
||||
from Utils import open_file
|
||||
itemgfx_dir = local_path(os.path.join("data", "itemgfx"))
|
||||
if not os.path.isdir(itemgfx_dir):
|
||||
os.makedirs(itemgfx_dir)
|
||||
open_file(itemgfx_dir)
|
||||
|
||||
frametitle = Frame(self.window)
|
||||
title_text = Label(frametitle, text="Item Graphics")
|
||||
title_text.pack(side=LEFT)
|
||||
local_title_link = Label(frametitle, text="(open folder)", fg="blue", cursor="hand2")
|
||||
local_title_link.pack(side=LEFT)
|
||||
local_title_link.bind("<Button-1>", open_itemgfx_dir)
|
||||
|
||||
self.icon_section(frametitle)
|
||||
|
||||
frame = Frame(self.window)
|
||||
frame.pack(side=BOTTOM, fill=X, pady=5)
|
||||
|
||||
button = Button(frame, text="Default (Triforce)", command=self.use_default)
|
||||
button.pack(side=LEFT, padx=(0, 5))
|
||||
|
||||
set_icon(self.window)
|
||||
self.window.focus()
|
||||
|
||||
def icon_section(self, frame_label):
|
||||
frame = LabelFrame(self.window, labelwidget=frame_label, padx=5, pady=5)
|
||||
canvas = Canvas(frame, borderwidth=0, width=780)
|
||||
y_scrollbar = Scrollbar(frame, orient="vertical", command=canvas.yview)
|
||||
y_scrollbar.pack(side="right", fill="y")
|
||||
content_frame = Frame(canvas)
|
||||
canvas.pack(side="left", fill="both", expand=True)
|
||||
canvas.create_window((4, 4), window=content_frame, anchor="nw")
|
||||
canvas.configure(yscrollcommand=y_scrollbar.set)
|
||||
|
||||
def onFrameConfigure(canvas):
|
||||
"""Reset the scroll region to encompass the inner frame"""
|
||||
canvas.configure(scrollregion=canvas.bbox("all"))
|
||||
|
||||
content_frame.bind("<Configure>", lambda event, canvas=canvas: onFrameConfigure(canvas))
|
||||
frame.pack(side=TOP, fill="both", expand=True)
|
||||
|
||||
itemgfx_dir = local_path(os.path.join("data", "itemgfx"))
|
||||
|
||||
if not os.path.exists(itemgfx_dir):
|
||||
label = Label(content_frame, text='No item graphics found in data/itemgfx folder.')
|
||||
label.pack()
|
||||
return
|
||||
|
||||
# Get all GIF files (converted from PNG)
|
||||
gif_files = []
|
||||
for file in os.listdir(itemgfx_dir):
|
||||
if file.lower().endswith('.gif'):
|
||||
item_name = os.path.splitext(file)[0]
|
||||
# Only include if it's in the valid_items list
|
||||
if item_name in self.valid_items:
|
||||
gif_files.append((file, item_name))
|
||||
|
||||
# Sort by name
|
||||
gif_files.sort(key=lambda x: str.lower(x[1]))
|
||||
|
||||
if len(gif_files) == 0:
|
||||
label = Label(content_frame, text='No valid item graphics found. Items must match names from Tables.py.')
|
||||
label.pack()
|
||||
return
|
||||
|
||||
# Calculate how many columns can fit (assuming ~40px per icon with padding)
|
||||
max_columns = 18
|
||||
|
||||
i = 0
|
||||
for filename, item_name in gif_files:
|
||||
filepath = os.path.join(itemgfx_dir, filename)
|
||||
image = self.get_image_for_item(filepath)
|
||||
if image is None:
|
||||
continue
|
||||
|
||||
button = Button(content_frame, image=image, command=lambda name=item_name: self.select_item(name))
|
||||
ToolTips.register(button, item_name)
|
||||
button.image = image
|
||||
button.grid(row=i // max_columns, column=i % max_columns, padx=2, pady=2)
|
||||
i += 1
|
||||
|
||||
if i == 0:
|
||||
label = Label(content_frame, text='No valid item graphics could be loaded.')
|
||||
label.pack()
|
||||
|
||||
def get_image_for_item(self, filepath):
|
||||
"""Load and prepare an item graphic for display"""
|
||||
try:
|
||||
# Load GIF with native Tkinter PhotoImage (no PIL required)
|
||||
photo = PhotoImage(file=filepath)
|
||||
return photo
|
||||
except Exception as e:
|
||||
print(f"Error loading image {filepath}: {e}")
|
||||
return None
|
||||
|
||||
def use_default(self):
|
||||
self.callback("Triforce")
|
||||
self.window.destroy()
|
||||
|
||||
def select_item(self, item_name):
|
||||
self.callback(item_name)
|
||||
self.window.destroy()
|
||||
@@ -2,6 +2,7 @@ from tkinter import ttk, filedialog, messagebox, StringVar, Button, Entry, Frame
|
||||
from AdjusterMain import adjust, patch
|
||||
from argparse import Namespace
|
||||
from source.classes.SpriteSelector import SpriteSelector
|
||||
from source.classes.ItemGfxSelector import ItemGfxSelector
|
||||
import source.gui.widgets as widgets
|
||||
import json
|
||||
import logging
|
||||
@@ -71,6 +72,30 @@ def adjust_page(top, parent, settings):
|
||||
spriteSelectButton2.pack(side=LEFT)
|
||||
spriteDialogFrame2.pack(anchor=E)
|
||||
|
||||
# Triforce Piece GFX Selection
|
||||
self.triforceGfxNameVar = StringVar()
|
||||
self.triforceGfxNameVar.set('(unchanged)')
|
||||
triforceGfxDialogFrame = Frame(self.frames["leftAdjustFrame"])
|
||||
triforceGfxLabel = Label(triforceGfxDialogFrame, text='Triforce Piece:')
|
||||
triforceGfxEntry = Label(triforceGfxDialogFrame, textvariable=self.triforceGfxNameVar)
|
||||
self.triforce_gfx = None
|
||||
|
||||
def set_triforce_gfx(item_name):
|
||||
self.triforce_gfx = item_name
|
||||
self.triforceGfxNameVar.set(item_name if item_name else '(unchanged)')
|
||||
|
||||
def TriforceGfxSelectAdjuster():
|
||||
from Tables import item_gfx_table
|
||||
valid_items = list(item_gfx_table.keys())
|
||||
ItemGfxSelector(parent, set_triforce_gfx, valid_items=valid_items)
|
||||
|
||||
triforceGfxSelectButton = Button(triforceGfxDialogFrame, text='...', command=TriforceGfxSelectAdjuster)
|
||||
|
||||
triforceGfxLabel.pack(side=LEFT)
|
||||
triforceGfxEntry.pack(side=LEFT)
|
||||
triforceGfxSelectButton.pack(side=LEFT)
|
||||
triforceGfxDialogFrame.pack(anchor=E)
|
||||
|
||||
# Path to game file to Adjust
|
||||
# This one's more-complicated, build it and stuff it
|
||||
adjustRomFrame = Frame(self.frames["bottomAdjustFrame"])
|
||||
@@ -117,6 +142,7 @@ def adjust_page(top, parent, settings):
|
||||
guiargs.rom = self.romVar2.get()
|
||||
guiargs.baserom = top.pages["randomizer"].pages["generation"].widgets["rom"].storageVar.get()
|
||||
guiargs.sprite = self.sprite
|
||||
guiargs.triforce_gfx = self.triforce_gfx
|
||||
guiargs.outputpath = os.path.dirname(guiargs.rom)
|
||||
try:
|
||||
adjust(args=guiargs)
|
||||
@@ -171,6 +197,7 @@ def adjust_page(top, parent, settings):
|
||||
guiargs.patch = self.patchVar.get()
|
||||
guiargs.baserom = top.pages["randomizer"].pages["generation"].widgets["rom"].storageVar.get()
|
||||
guiargs.sprite = self.sprite
|
||||
guiargs.triforce_gfx = self.triforce_gfx
|
||||
guiargs.outputpath = os.path.dirname(guiargs.patch)
|
||||
try:
|
||||
patch(args=guiargs)
|
||||
|
||||
@@ -345,6 +345,9 @@ def create_guiargs(parent):
|
||||
guiargs.sprite = parent.pages["randomizer"].pages["gameoptions"].widgets["sprite"]["spriteObject"]
|
||||
guiargs.randomSprite = parent.randomSprite.get()
|
||||
|
||||
# Get Triforce Piece GFX Selection
|
||||
guiargs.triforce_gfx = parent.pages["randomizer"].pages["gameoptions"].widgets["triforce_gfx"]["selectedItem"]
|
||||
|
||||
# Get output path
|
||||
guiargs.outputpath = parent.settings["outputpath"]
|
||||
|
||||
|
||||
@@ -197,6 +197,13 @@ def loadcliargs(gui, args, settings=None):
|
||||
spriteNameVar=gui.pages["adjust"].content.spriteNameVar2,
|
||||
randomSpriteVar=gui.randomSprite)
|
||||
|
||||
# Figure out Triforce GFX Selection
|
||||
if "triforce_gfx" in args and args["triforce_gfx"] is not None:
|
||||
gui.pages["randomizer"].pages["gameoptions"].widgets["triforce_gfx"]["selectedItem"] = args["triforce_gfx"]
|
||||
gui.pages["randomizer"].pages["gameoptions"].widgets["triforce_gfx"]["itemNameVar"].set(args["triforce_gfx"])
|
||||
gui.pages["adjust"].content.triforce_gfx = args["triforce_gfx"]
|
||||
gui.pages["adjust"].content.triforceGfxNameVar.set(args["triforce_gfx"])
|
||||
|
||||
# Load args/settings for Adjust tab
|
||||
def loadadjustargs(gui, settings):
|
||||
options = {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
from tkinter import ttk, StringVar, Button, Entry, Frame, Label, NE, NW, E, W, LEFT, RIGHT
|
||||
from functools import partial
|
||||
import source.classes.SpriteSelector as spriteSelector
|
||||
import source.classes.ItemGfxSelector as itemGfxSelector
|
||||
import source.gui.widgets as widgets
|
||||
import json
|
||||
import os
|
||||
@@ -66,6 +67,34 @@ def gameoptions_page(top, parent):
|
||||
spriteSelectButton.pack(side=LEFT)
|
||||
spriteDialogFrame.pack(anchor=E)
|
||||
|
||||
## Triforce Piece graphics selection
|
||||
triforcegfxDialogFrame = Frame(self.frames["leftRomOptionsFrame"])
|
||||
triforceGfxLabel = Label(triforcegfxDialogFrame, text='Triforce Piece:')
|
||||
|
||||
self.widgets["triforce_gfx"] = {}
|
||||
self.widgets["triforce_gfx"]["selectedItem"] = None
|
||||
self.widgets["triforce_gfx"]["itemNameVar"] = StringVar()
|
||||
self.widgets["triforce_gfx"]["itemNameVar"].set('Triforce')
|
||||
|
||||
triforceGfxEntry = Label(triforcegfxDialogFrame, textvariable=self.widgets["triforce_gfx"]["itemNameVar"])
|
||||
|
||||
def triforce_gfx_setter(item_name):
|
||||
self.widgets["triforce_gfx"]["selectedItem"] = item_name
|
||||
self.widgets["triforce_gfx"]["itemNameVar"].set(item_name)
|
||||
|
||||
def triforce_gfx_select():
|
||||
# Import Tables to get valid item names
|
||||
from Tables import item_gfx_table
|
||||
valid_items = list(item_gfx_table.keys())
|
||||
itemGfxSelector.ItemGfxSelector(parent, triforce_gfx_setter, valid_items=valid_items)
|
||||
|
||||
triforceGfxSelectButton = Button(triforcegfxDialogFrame, text='...', command=triforce_gfx_select)
|
||||
|
||||
triforceGfxLabel.pack(side=LEFT)
|
||||
triforceGfxEntry.pack(side=LEFT)
|
||||
triforceGfxSelectButton.pack(side=LEFT)
|
||||
triforcegfxDialogFrame.pack(anchor=E)
|
||||
|
||||
return self
|
||||
|
||||
|
||||
|
||||
@@ -261,6 +261,7 @@ def roll_settings(weights):
|
||||
if 'rom' in weights:
|
||||
romweights = weights['rom']
|
||||
ret.sprite = get_choice('sprite', romweights)
|
||||
ret.triforce_gfx = get_choice('triforce_gfx', romweights)
|
||||
ret.disablemusic = get_choice_bool('disablemusic', romweights)
|
||||
ret.quickswap = get_choice_bool('quickswap', romweights)
|
||||
ret.reduce_flashing = get_choice_bool('reduce_flashing', romweights)
|
||||
|
||||
Reference in New Issue
Block a user