11import random
2- from enum import Enum
2+ from enum import Enum , auto
33from typing import TypeAlias
44
55from typing_extensions import Self
1919 TILESET_ANIM_PALS ,
2020)
2121from mars_patcher .mf .constants .sprites import SpriteIdMF
22- from mars_patcher .palette import ColorChange , Palette , SineWave
23- from mars_patcher .rom import Game , Rom
22+ from mars_patcher .palette import PAL_ROW_SIZE , ColorChange , Palette , SineWave
23+ from mars_patcher .rom import Rom
24+ from mars_patcher .tileset import Tileset
25+ from mars_patcher .zm .auto_generated_types import (
26+ MarsschemazmPalettes ,
27+ MarsschemazmPalettesColorspace ,
28+ MarsschemazmPalettesRandomize ,
29+ )
2430from mars_patcher .zm .constants .game_data import statues_cutscene_palette_addr
2531from mars_patcher .zm .constants .palettes import ENEMY_GROUPS_ZM , EXCLUDED_ENEMIES_ZM
2632from mars_patcher .zm .constants .sprites import SpriteIdZM
2733
34+ SchemaPalettes = MarsschemamfPalettes | MarsschemazmPalettes
35+ SchemaPalettesColorspace = MarsschemamfPalettesColorspace | MarsschemazmPalettesColorspace
36+ SchemaPalettesRandomize = MarsschemamfPalettesRandomize | MarsschemazmPalettesRandomize
37+
2838HueRange : TypeAlias = tuple [int , int ]
2939
3040
3141class PaletteType (Enum ):
32- TILESETS = 1
33- ENEMIES = 2
34- SAMUS = 3
35- BEAMS = 4
42+ TILESETS = auto ()
43+ ENEMIES = auto ()
44+ SAMUS = auto ()
45+ BEAMS = auto ()
3646
3747
3848class PaletteSettings :
@@ -47,18 +57,18 @@ def __init__(
4757 self ,
4858 seed : int ,
4959 pal_types : dict [PaletteType , HueRange ],
50- color_space : MarsschemamfPalettesColorspace ,
60+ color_space : SchemaPalettesColorspace ,
5161 symmetric : bool ,
5262 extra_variation : bool ,
5363 ):
5464 self .seed = seed
5565 self .pal_types = pal_types
56- self .color_space : MarsschemamfPalettesColorspace = color_space
66+ self .color_space : SchemaPalettesColorspace = color_space
5767 self .symmetric = symmetric
5868 self .extra_variation = extra_variation
5969
6070 @classmethod
61- def from_json (cls , data : MarsschemamfPalettes ) -> Self :
71+ def from_json (cls , data : SchemaPalettes ) -> Self :
6272 seed = data .get ("Seed" , random .randint (0 , 2 ** 31 - 1 ))
6373 random .seed (seed )
6474 pal_types = {}
@@ -72,7 +82,7 @@ def from_json(cls, data: MarsschemamfPalettes) -> Self:
7282 return cls (seed , pal_types , color_space , symmetric , True )
7383
7484 @classmethod
75- def get_hue_range (cls , data : MarsschemamfPalettesRandomize ) -> HueRange :
85+ def get_hue_range (cls , data : SchemaPalettesRandomize ) -> HueRange :
7686 hue_min = data .get ("HueMin" )
7787 hue_max = data .get ("HueMax" )
7888 if hue_min is None or hue_max is None :
@@ -141,8 +151,8 @@ def randomize(self) -> None:
141151 if PaletteType .BEAMS in pal_types :
142152 self .randomize_beams (pal_types [PaletteType .BEAMS ])
143153 # Fix any sprite/tileset palettes that should be the same
144- # if self.rom.is_zm():
145- # self.fix_zm_palettes()
154+ if self .rom .is_zm ():
155+ self .fix_zm_palettes ()
146156
147157 def change_palettes (self , pals : list [tuple [int , int ]], change : ColorChange ) -> None :
148158 for addr , rows in pals :
@@ -157,7 +167,8 @@ def randomize_samus(self, hue_range: HueRange) -> None:
157167 change = self .generate_palette_change (hue_range )
158168 self .change_palettes (gd .samus_palettes (self .rom ), change )
159169 self .change_palettes (gd .helmet_cursor_palettes (self .rom ), change )
160- self .change_palettes (sax_palettes (self .rom ), change )
170+ if self .rom .is_mf ():
171+ self .change_palettes (sax_palettes (self .rom ), change )
161172
162173 def randomize_beams (self , hue_range : HueRange ) -> None :
163174 change = self .generate_palette_change (hue_range )
@@ -179,7 +190,7 @@ def randomize_tilesets(self, hue_range: HueRange) -> None:
179190 continue
180191 # Get excluded palette rows
181192 excluded_rows = set ()
182- if rom .game == Game . MF :
193+ if rom .is_mf () :
183194 row = MF_TILESET_ALT_PAL_ROWS .get (pal_addr )
184195 if row is not None :
185196 excluded_rows = {row }
@@ -223,6 +234,7 @@ def randomize_enemies(self, hue_range: HueRange) -> None:
223234 raise ValueError (rom .game )
224235 excluded = {en_id .value for en_id in _excluded }
225236 sp_count = gd .sprite_count (rom )
237+ # The first 0x10 sprites have no graphics
226238 to_randomize = set (range (0x10 , sp_count ))
227239 to_randomize -= excluded
228240
@@ -287,9 +299,9 @@ def get_sprite_addr(self, sprite_id: int) -> int:
287299 addr = gd .sprite_palette_ptrs (self .rom ) + (sprite_id - 0x10 ) * 4
288300 return self .rom .read_ptr (addr )
289301
290- def get_tileset_addr (self , sprite_id : int ) -> int :
291- addr = gd . tileset_entries (self .rom ) + sprite_id * 0x14 + 4
292- return self . rom . read_ptr ( addr )
302+ def get_tileset_addr (self , tileset_id : int ) -> int :
303+ tileset = Tileset (self .rom , tileset_id )
304+ return tileset . palette_addr ( )
293305
294306 def fix_nettori (self , change : ColorChange ) -> None :
295307 """Nettori has extra palettes stored separately, so they require the same color change."""
@@ -303,25 +315,25 @@ def fix_zm_palettes(self) -> None:
303315 PaletteType .ENEMIES in self .settings .pal_types
304316 or PaletteType .TILESETS in self .settings .pal_types
305317 ):
306- # Fix kraid's body
318+ # Fix kraid's body (copy row from sprite to tileset)
307319 sp_addr = self .get_sprite_addr (SpriteIdZM .KRAID )
308320 ts_addr = self .get_tileset_addr (9 )
309- self .rom .copy_bytes (sp_addr , ts_addr + 0x100 , 0x20 )
321+ self .rom .copy_bytes (sp_addr , ts_addr + ( 8 * PAL_ROW_SIZE ), PAL_ROW_SIZE )
310322
311323 if PaletteType .TILESETS in self .settings .pal_types :
312324 # Fix kraid elevator statue
313325 sp_addr = self .get_sprite_addr (SpriteIdZM .KRAID_ELEVATOR_STATUE )
314326 ts_addr = self .get_tileset_addr (0x35 )
315- self .rom .copy_bytes (ts_addr + 0x20 , sp_addr , 0x20 )
327+ self .rom .copy_bytes (ts_addr + PAL_ROW_SIZE , sp_addr , PAL_ROW_SIZE )
316328
317329 # Fix ridley elevator statue
318330 ts_addr = self .get_tileset_addr (7 )
319- self .rom .copy_bytes (ts_addr + 0x20 , sp_addr + 0x20 , 0x20 )
331+ self .rom .copy_bytes (ts_addr + PAL_ROW_SIZE , sp_addr + PAL_ROW_SIZE , PAL_ROW_SIZE )
320332
321333 # Fix tourian statues
322334 sp_addr = self .get_sprite_addr (SpriteIdZM .KRAID_STATUE )
323335 ts_addr = self .get_tileset_addr (0x41 )
324- self .rom .copy_bytes (ts_addr + 0x60 , sp_addr , 0x20 )
336+ self .rom .copy_bytes (ts_addr + ( 3 * PAL_ROW_SIZE ) , sp_addr , PAL_ROW_SIZE )
325337 # Fix cutscene
326338 sp_addr = statues_cutscene_palette_addr (self .rom )
327- self .rom .copy_bytes (ts_addr , sp_addr , 0xC0 )
339+ self .rom .copy_bytes (ts_addr , sp_addr , 6 * PAL_ROW_SIZE )
0 commit comments