Added new post-gen option to change TF Piece GFX

This commit is contained in:
codemann8
2025-11-19 09:54:31 -06:00
parent 2b7a9e3bf8
commit fb99d33007
149 changed files with 354 additions and 102 deletions

View File

@@ -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])

View 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()

View File

@@ -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)

View File

@@ -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"]

View File

@@ -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 = {

View File

@@ -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

View File

@@ -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)