diff --git a/pyproject.toml b/pyproject.toml index 3af9438..5c46cac 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -21,6 +21,7 @@ classifiers = [ ] dependencies = [ "jsonschema", + "frozendict", ] [project.optional-dependencies] @@ -65,4 +66,4 @@ files = [ follow_imports = "silent" disallow_untyped_defs = true warn_return_any = true -warn_unreachable = true \ No newline at end of file +warn_unreachable = true diff --git a/src/mars_patcher/item_patcher.py b/src/mars_patcher/item_patcher.py index 87381be..4c257bb 100644 --- a/src/mars_patcher/item_patcher.py +++ b/src/mars_patcher/item_patcher.py @@ -59,6 +59,7 @@ def write_items(self) -> None: prev_area_room = (-1, -1) room_tank_count = 0 total_metroids = 0 + item_messages_to_custom_id: dict[ItemMessages, int] = {} for min_loc in minor_locs: if min_loc.new_item == ItemType.INFANT_METROID: total_metroids += 1 @@ -131,10 +132,20 @@ def write_items(self) -> None: rom.write_8(item_addr + 6, min_loc.item_sprite.value) # Handle custom messages if min_loc.item_messages is not None: - self.write_custom_message( - custom_message_id, message_table_addrs, item_addr, min_loc.item_messages, False - ) - custom_message_id += 1 + # If we already encountered the message before, just write the message id. + messages = min_loc.item_messages + if messages in item_messages_to_custom_id: + rom.write_8(item_addr + 7, item_messages_to_custom_id[messages]) + else: + self.write_custom_message( + custom_message_id, + message_table_addrs, + item_addr, + min_loc.item_messages, + False, + ) + item_messages_to_custom_id[messages] = custom_message_id + custom_message_id += 1 # Handle major locations for maj_loc in self.settings.major_locs: @@ -146,10 +157,20 @@ def write_items(self) -> None: rom.write_8(addr, maj_loc.new_item.value) # Handle custom messages if maj_loc.item_messages is not None: - self.write_custom_message( - custom_message_id, message_table_addrs, addr, maj_loc.item_messages, True - ) - custom_message_id += 1 + # If we already encountered the message before, just write the message id. + messages = maj_loc.item_messages + if messages in item_messages_to_custom_id: + rom.write_8(addr + 1, item_messages_to_custom_id[messages]) + else: + self.write_custom_message( + custom_message_id, + message_table_addrs, + addr, + maj_loc.item_messages, + True, + ) + item_messages_to_custom_id[messages] = custom_message_id + custom_message_id += 1 # Write total metroid count rom.write_8(TOTAL_METROID_COUNT_ADDR, total_metroids) diff --git a/src/mars_patcher/locations.py b/src/mars_patcher/locations.py index bdace40..244bf27 100644 --- a/src/mars_patcher/locations.py +++ b/src/mars_patcher/locations.py @@ -1,7 +1,10 @@ from __future__ import annotations import json -from typing import TYPE_CHECKING +from dataclasses import dataclass +from typing import TYPE_CHECKING, ClassVar + +from frozendict import frozendict from mars_patcher.constants.items import ( ITEM_ENUMS, @@ -86,8 +89,12 @@ def __init__( self.item_messages = item_messages +@dataclass(frozen=True) class ItemMessages: - LANG_ENUMS = { + item_messages: frozendict[Language, str] + centered: bool + + LANG_ENUMS: ClassVar[dict[str, Language]] = { "JapaneseKanji": Language.JAPANESE_KANJI, "JapaneseHiragana": Language.JAPANESE_HIRAGANA, "English": Language.ENGLISH, @@ -97,10 +104,6 @@ class ItemMessages: "Spanish": Language.SPANISH, } - def __init__(self, item_messages: dict[Language, str], centered: bool): - self.item_messages = item_messages - self.centered = centered - @classmethod def from_json(cls, data: Itemmessages) -> ItemMessages: item_messages: dict[Language, str] = {} @@ -108,7 +111,7 @@ def from_json(cls, data: Itemmessages) -> ItemMessages: lang = cls.LANG_ENUMS[lang_name] item_messages[lang] = message centered = data.get(KEY_CENTERED, True) - return cls(item_messages, centered) + return cls(frozendict(item_messages), centered) class LocationSettings: