Files
Jonathan Tinney 7971961166
Some checks failed
Analyze modified files / flake8 (push) Failing after 2m28s
Build / build-win (push) Has been cancelled
Build / build-ubuntu2204 (push) Has been cancelled
ctest / Test C++ ubuntu-latest (push) Has been cancelled
ctest / Test C++ windows-latest (push) Has been cancelled
Analyze modified files / mypy (push) Has been cancelled
Build and Publish Docker Images / Push Docker image to Docker Hub (push) Successful in 5m4s
Native Code Static Analysis / scan-build (push) Failing after 5m2s
type check / pyright (push) Successful in 1m7s
unittests / Test Python 3.11.2 ubuntu-latest (push) Failing after 16m23s
unittests / Test Python 3.12 ubuntu-latest (push) Failing after 28m19s
unittests / Test Python 3.13 ubuntu-latest (push) Failing after 14m49s
unittests / Test hosting with 3.13 on ubuntu-latest (push) Successful in 5m0s
unittests / Test Python 3.13 macos-latest (push) Has been cancelled
unittests / Test Python 3.11 windows-latest (push) Has been cancelled
unittests / Test Python 3.13 windows-latest (push) Has been cancelled
add schedule I, sonic 1/frontiers/heroes, spirit island
2026-04-02 23:46:36 -07:00

123 lines
5.8 KiB
Python

"""All code associated with updating textures for puzzles."""
from randomizer.Settings import Settings
from randomizer.Patching.Library.Image import writeColorImageToROM, TextureFormat, getImageFile, getNumberImage
from randomizer.Patching.Patcher import LocalROM
from PIL import Image
def updateMillLeverTexture(settings: Settings, ROM_COPY: LocalROM) -> None:
"""Update the 21132 texture."""
if settings.mill_levers[0] > 0:
# Get Number bounds
base_num_texture = getImageFile(ROM_COPY, 25, 0x7CA, True, 64, 32, TextureFormat.RGBA5551)
number_textures = [None, None, None]
number_x_bounds = (
(18, 25),
(5, 16),
(36, 47),
)
modified_tex = getImageFile(ROM_COPY, 25, 0x7CA, True, 64, 32, TextureFormat.RGBA5551)
for tex in range(3):
number_textures[tex] = base_num_texture.crop((number_x_bounds[tex][0], 7, number_x_bounds[tex][1], 25))
total_width = 0
for x in range(5):
if settings.mill_levers[x] > 0:
idx = settings.mill_levers[x] - 1
total_width += number_x_bounds[idx][1] - number_x_bounds[idx][0]
# Overwrite old panel
overwrite_panel = Image.new(mode="RGBA", size=(58, 26), color=(131, 65, 24))
modified_tex.paste(overwrite_panel, (3, 3), overwrite_panel)
# Generate new number texture
new_num_texture = Image.new(mode="RGBA", size=(total_width, 18))
x_pos = 0
for num in range(5):
if settings.mill_levers[num] > 0:
num_val = settings.mill_levers[num] - 1
new_num_texture.paste(number_textures[num_val], (x_pos, 0), number_textures[num_val])
x_pos += number_x_bounds[num_val][1] - number_x_bounds[num_val][0]
scale_x = 58 / total_width
scale_y = 26 / 18
scale = min(scale_x, scale_y)
x_size = int(total_width * scale)
y_size = int(18 * scale)
new_num_texture = new_num_texture.resize((x_size, y_size))
x_offset = int((58 - x_size) / 2)
modified_tex.paste(new_num_texture, (3 + x_offset, 3), new_num_texture)
writeColorImageToROM(modified_tex, 25, 0x7CA, 64, 32, False, TextureFormat.RGBA5551, ROM_COPY)
def updateDiddyDoors(settings: Settings, ROM_COPY: LocalROM):
"""Update the textures for the doors."""
enable_code = False
for code in settings.diddy_rnd_doors:
if sum(code) > 0: # Has a non-zero element
enable_code = True
SEG_WIDTH = 48
SEG_HEIGHT = 42
NUMBERS_START = (27, 33)
if enable_code:
# Order: 4231, 3124, 1342
starts = (0xCE8, 0xCE4, 0xCE0)
for index, code in enumerate(settings.diddy_rnd_doors):
start = starts[index]
total = Image.new(mode="RGBA", size=(SEG_WIDTH * 2, SEG_HEIGHT * 2))
for img_index in range(4):
img = getImageFile(ROM_COPY, 25, start + img_index, True, SEG_WIDTH, SEG_HEIGHT, TextureFormat.RGBA5551)
x_offset = SEG_WIDTH * (img_index & 1)
y_offset = SEG_HEIGHT * ((img_index & 2) >> 1)
total.paste(img, (x_offset, y_offset), img)
total = total.transpose(Image.FLIP_TOP_BOTTOM)
# Overlay color
cover = Image.new(mode="RGBA", size=(42, 20), color=(115, 98, 65))
total.paste(cover, NUMBERS_START, cover)
# Paste numbers
number_images = []
number_offsets = []
total_length = 0
for num in code:
num_img = getNumberImage(num + 1, ROM_COPY)
w, h = num_img.size
number_offsets.append(total_length)
total_length += w
number_images.append(num_img)
total_numbers = Image.new(mode="RGBA", size=(total_length, 24))
for img_index, img in enumerate(number_images):
total_numbers.paste(img, (number_offsets[img_index], 0), img)
total.paste(total_numbers, (SEG_WIDTH - int(total_length / 2), SEG_HEIGHT - 12), total_numbers)
total = total.transpose(Image.FLIP_TOP_BOTTOM)
for img_index in range(4):
x_offset = SEG_WIDTH * (img_index & 1)
y_offset = SEG_HEIGHT * ((img_index & 2) >> 1)
sub_img = total.crop((x_offset, y_offset, x_offset + SEG_WIDTH, y_offset + SEG_HEIGHT))
writeColorImageToROM(sub_img, 25, start + img_index, SEG_WIDTH, SEG_HEIGHT, False, TextureFormat.RGBA5551, ROM_COPY)
def updateCryptLeverTexture(settings: Settings, ROM_COPY: LocalROM) -> None:
"""Update the two textures for Donkey Minecart entry."""
if settings.crypt_levers[0] > 0:
# Get a blank texture
texture_0 = getImageFile(ROM_COPY, 25, 0x999, True, 32, 64, TextureFormat.RGBA5551)
blank = texture_0.crop((8, 5, 23, 22))
texture_0.paste(blank, (8, 42), blank)
texture_1 = texture_0.copy()
for xi, x in enumerate(settings.crypt_levers):
corrected = x - 1
y_slot = corrected % 3
num = getNumberImage(xi + 1, ROM_COPY)
num = num.transpose(Image.FLIP_TOP_BOTTOM)
w, h = num.size
scale = 2 / 3
y_offset = int((h * scale) / 2)
x_offset = int((w * scale) / 2)
num = num.resize((int(w * scale), int(h * scale)))
y_pos = (51, 33, 14)
tl_y = y_pos[y_slot] - y_offset
tl_x = 16 - x_offset
if corrected < 3:
texture_0.paste(num, (tl_x, tl_y), num)
else:
texture_1.paste(num, (tl_x, tl_y), num)
writeColorImageToROM(texture_0, 25, 0x99A, 32, 64, False, TextureFormat.RGBA5551, ROM_COPY)
writeColorImageToROM(texture_1, 25, 0x999, 32, 64, False, TextureFormat.RGBA5551, ROM_COPY)