forked from mirror/Archipelago
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
163 lines
5.9 KiB
Python
163 lines
5.9 KiB
Python
import pkgutil
|
|
from typing import Any
|
|
|
|
from settings import get_settings
|
|
from .. import patching
|
|
from ..Options import OracleOfSeasonsLinkedHerosCave
|
|
from ..common.patching.RomData import RomData
|
|
from ..common.patching.rooms.decoding import decompress_rooms
|
|
from ..common.patching.rooms.encoding import write_room_data
|
|
|
|
|
|
### How rooms work:
|
|
# Room number 0xYZZ = group Y, room ZZ
|
|
# Groups 0-3 are seasons spring to winter (usually 0ZZ)
|
|
# Group 4 is subrosia/maku/grottos (usually 1ZZ/2ZZ/3ZZ)
|
|
# Group 5-6 are the big rooms (usually 4ZZ/6ZZ and 5ZZ/7ZZ)
|
|
|
|
# Positions are assessed with YX format
|
|
# Positions in small rooms are written in decimal, as a line is 10 tiles long
|
|
# Positions in big rooms are written in hew, as a line is 16 tiles long (last tile is always 0)
|
|
|
|
def apply_room_edits(rom_data: RomData, patch_data: dict[str, Any]) -> list[bytearray]:
|
|
room_data = decompress_rooms(rom_data, True)
|
|
|
|
apply_d0_alt_entrance_edits(room_data, patch_data)
|
|
apply_d2_alt_entrance_edits(room_data, patch_data)
|
|
apply_samasa_dungeon_edits(room_data, patch_data)
|
|
apply_anti_softlock_edits(room_data)
|
|
apply_misc_edits(room_data)
|
|
|
|
return room_data
|
|
|
|
|
|
def apply_d0_alt_entrance_edits(room_data: list[bytearray], patch_data: dict[str, Any]) -> None:
|
|
if not patch_data["options"]["remove_d0_alt_entrance"]:
|
|
return
|
|
for room_id in range(0x0d4, 0x400, 0x100):
|
|
# Remove the grass and the soil in all seasons
|
|
room_data[room_id][17] = 0x11
|
|
room_data[room_id][26] = 0x11
|
|
room_data[room_id][27] = 0x11
|
|
room_data[room_id][28] = 0x11
|
|
|
|
# Remove the chimney
|
|
room_data[room_id][57] = 0xaf
|
|
|
|
# Add stairs to the chest
|
|
room_data[0x505][0x5a] = 0x53
|
|
|
|
|
|
def apply_d2_alt_entrance_edits(room_data: list[bytearray], patch_data: dict[str, Any]) -> None:
|
|
for room_id in range(0x08e, 0x400, 0x100):
|
|
# Replace the vines by stairs in all seasons
|
|
room_data[room_id][34] = 0x36
|
|
room_data[room_id][35] = 0xd0
|
|
room_data[room_id][36] = 0x35
|
|
room_data[room_id][44] = 0x51
|
|
room_data[room_id][45] = 0xd0
|
|
room_data[room_id][46] = 0x50
|
|
if not patch_data["options"]["remove_d2_alt_entrance"]:
|
|
continue
|
|
|
|
# Remove the stairs
|
|
room_data[room_id][12] = 0x04
|
|
room_data[room_id - 1][18] = 0x04
|
|
|
|
|
|
def apply_samasa_dungeon_edits(room_data: list[bytearray], patch_data: dict[str, Any]) -> None:
|
|
if patch_data["options"]["linked_heros_cave"] & OracleOfSeasonsLinkedHerosCave.samasa:
|
|
# Add the dungeon entrance
|
|
room_data[0x1cf] = bytearray(pkgutil.get_data(patching.__name__, "rooms/samasa_dungeon.dat"))
|
|
if patch_data["options"]["linked_heros_cave"] & OracleOfSeasonsLinkedHerosCave.no_alt_entrance:
|
|
room_data[0x1cf][28] = 0x04 # Remove the grass
|
|
room_data[0x1cf][48] = 0xaf # Remove the chimney
|
|
|
|
if patch_data["options"]["linked_heros_cave"] & OracleOfSeasonsLinkedHerosCave.no_alt_entrance:
|
|
room_data[0x62c][0x42] = 0x52 # Add stairs to the alt entrance chest
|
|
|
|
|
|
def apply_anti_softlock_edits(room_data: list[bytearray]) -> None:
|
|
# In room 016, move the tree in front of the door left to avoid locking the player
|
|
for room_id in range(0x016, 0x300, 0x100):
|
|
room_data[room_id][16] = 0x70
|
|
room_data[room_id][17] = 0x71
|
|
room_data[room_id][18] = 0x0f
|
|
room_data[room_id][26] = 0x80
|
|
room_data[room_id][27] = 0x81
|
|
room_data[room_id][28] = 0x70
|
|
# In winter, it needs to be different
|
|
room_data[0x316][16] = 0x65
|
|
room_data[0x316][17] = 0x66
|
|
room_data[0x316][18] = 0x0f
|
|
room_data[0x316][26] = 0x55
|
|
room_data[0x316][27] = 0x56
|
|
room_data[0x316][28] = 0x65
|
|
|
|
# Remove the natzu bridge lever
|
|
room_data[0x156][66] = 0x04 # Ricky
|
|
room_data[0x356][66] = 0x04 # Moosh
|
|
|
|
# Shallow water to leave d4
|
|
for room_id in range(0x01d, 0x300, 0x100):
|
|
room_data[room_id][31] = 0xfa
|
|
room_data[room_id][32] = 0xfa
|
|
room_data[room_id][33] = 0xfa
|
|
room_data[room_id][34] = 0xfa
|
|
room_data[room_id][35] = 0xfa
|
|
room_data[room_id][36] = 0xfa
|
|
# Ice for winter
|
|
room_data[0x31d][31] = 0xdc
|
|
room_data[0x31d][32] = 0xdc
|
|
room_data[0x31d][33] = 0xdc
|
|
room_data[0x31d][34] = 0xdc
|
|
room_data[0x31d][35] = 0xdc
|
|
|
|
# Spool swamp had one to leave to east in spring, but it wasn't kept
|
|
|
|
# Some snow piles in suburbs to WoW were removed, but this change wasn't kept
|
|
|
|
# Remove a snow pile to prevent the statue blocking the path in winter if pushed left
|
|
room_data[0x301][54] = 0x04
|
|
|
|
# Remove a snow pile in front of Holly's house to avoid a needless softlock
|
|
room_data[0x37f][56] = 0x04
|
|
|
|
# D7 snow piles aren't removed, warp isn't far, and this impacts logic positively
|
|
|
|
for room_id in range(0x09a, 0x400, 0x100):
|
|
# Remove rock across pit blocking exit from D5
|
|
room_data[room_id][14] = 0x12
|
|
|
|
# Remove bush next to rosa portal
|
|
room_data[room_id][34] = 0x04
|
|
|
|
# Add rock at bottom of cliff to block ricky
|
|
for room_id in range(0x08a, 0x400, 0x100):
|
|
room_data[room_id][66] = 0x64
|
|
|
|
# Add a ledge from lower portal
|
|
for room_id in range(0x025, 0x400, 0x100):
|
|
room_data[room_id][32] = 0x3a
|
|
room_data[room_id][33] = 0xcf
|
|
room_data[room_id][34] = 0x4b
|
|
|
|
|
|
def apply_misc_edits(room_data: list[bytearray]) -> None:
|
|
# Remove access to first refill room on 4 essences
|
|
for i in range(2, 80, 10):
|
|
for j in range(6):
|
|
room_data[0x41c][i + j] = 0x62 + j
|
|
|
|
# Remove access to second refill room on 6 essences
|
|
room_data[0x44b][3] = 0x63
|
|
|
|
# Reveal hidden subrosia digging spots if required
|
|
if get_settings()["tloz_oos_options"]["reveal_hidden_subrosia_digging_spots"]:
|
|
room_data[0x406][18] = 0x2f
|
|
room_data[0x457][38] = 0x2f
|
|
room_data[0x447][33] = 0x2f
|
|
room_data[0x43a][46] = 0x2f
|
|
room_data[0x407][13] = 0x2f
|
|
room_data[0x420][68] = 0x2f
|
|
room_data[0x442][14] = 0x2f |