From 3c0f6ca0e6d04acc0903607657696b2e29e505de Mon Sep 17 00:00:00 2001 From: aerinon Date: Tue, 27 Sep 2022 14:40:43 -0600 Subject: [PATCH] UW Enemizer work Refinements for data table support --- BaseClasses.py | 8 +- Fill.py | 2 +- Main.py | 3 + PotShuffle.py | 4 +- Regions.py | 11 ++- Rom.py | 15 +--- Utils.py | 5 ++ data/base2current.bps | Bin 93438 -> 98731 bytes source/dungeon/EnemyList.py | 111 ++++++++++++------------- source/dungeon/RoomHeader.py | 3 +- source/dungeon/RoomList.py | 28 ++++--- source/enemizer/EnemizerTestHarness.py | 5 +- source/rom/DataTables.py | 38 ++++++--- 13 files changed, 128 insertions(+), 105 deletions(-) diff --git a/BaseClasses.py b/BaseClasses.py index 60d04d82..c361ef82 100644 --- a/BaseClasses.py +++ b/BaseClasses.py @@ -87,7 +87,7 @@ class World(object): self._portal_cache = {} self.sanc_portal = {} self.fish = BabelFish() - self.pot_contents = {} + self.data_tables = {} for player in range(1, players + 1): def set_player_attr(attr, val): @@ -151,6 +151,7 @@ class World(object): set_player_attr('exp_cache', defaultdict(dict)) set_player_attr('enabled_entrances', {}) + set_player_attr('data_tables', None) def finish_init(self): for player in range(1, self.players + 1): @@ -393,7 +394,7 @@ class World(object): item.location = location item.world = self if location.player != item.player and location.type == LocationType.Pot: - self.pot_contents[location.player].multiworld_count += 1 + self.data_tables[location.player].pot_secret_table.multiworld_count += 1 if collect: self.state.collect(item, location.event, location) @@ -2136,6 +2137,7 @@ class Location(object): self.skip = False self.type = LocationType.Normal if not crystal else LocationType.Prize self.pot = None + self.drop = None def can_fill(self, state, item, check_access=True): if not self.valid_multiworld(state, item): @@ -2144,7 +2146,7 @@ class Location(object): def valid_multiworld(self, state, item): if self.type == LocationType.Pot and self.player != item.player: - return state.world.pot_contents[self.player].multiworld_count < 256 + return state.world.data_tables[self.player].pot_secret_table.multiworld_count < 256 return True def can_reach(self, state): diff --git a/Fill.py b/Fill.py index 4ebd4c04..6ae73dcf 100644 --- a/Fill.py +++ b/Fill.py @@ -581,7 +581,7 @@ def fast_fill_pot_for_multiworld(world, item_pool, fill_locations): if loc.type == LocationType.Pot: pot_fill_locations[loc.player].append(loc) for player in range(1, world.players+1): - flex = 256 - world.pot_contents[player].multiworld_count + flex = 256 - world.data_tables[player].pot_secret_table.multiworld_count fill_count = len(pot_fill_locations[player]) - flex if fill_count > 0: fill_spots = random.sample(pot_fill_locations[player], fill_count) diff --git a/Main.py b/Main.py index 2db44f17..7ed757cc 100644 --- a/Main.py +++ b/Main.py @@ -32,6 +32,8 @@ from source.item.FillUtil import create_item_pool_config, massage_item_pool, dis from source.overworld.EntranceShuffle2 import link_entrances_new from source.tools.BPS import create_bps_from_data from source.classes.CustomSettings import CustomSettings +from source.rom.DataTables import init_data_tables + __version__ = '1.0.1.3-x' @@ -186,6 +188,7 @@ def main(args, seed=None, fish=None): create_doors(world, player) create_rooms(world, player) create_dungeons(world, player) + world.data_tables[player] = init_data_tables(world, player) adjust_locations(world, player) place_bosses(world, player) diff --git a/PotShuffle.py b/PotShuffle.py index ec6536ef..d2d2547a 100644 --- a/PotShuffle.py +++ b/PotShuffle.py @@ -919,14 +919,14 @@ def shuffle_pots(world, player): new_pot_contents.room_map[super_tile] = new_pots - world.pot_contents[player] = new_pot_contents + world.data_tables[player].pot_secret_table = new_pot_contents def shuffle_pot_switches(world, player): import RaceRandom as random for super_tile in vanilla_pots: - new_pots = world.pot_contents[player].room_map[super_tile] + new_pots = world.data_tables[player].pot_secret_table.room_map[super_tile] # sort in the order Hole, Switch, Key, Other, Nothing sort_order = {PotItem.Hole: 4, PotItem.Switch: 3, PotItem.Key: 2, PotItem.Nothing: 0} old_pots = sorted(new_pots, key=lambda pot: sort_order.get(pot.item, 1), reverse=True) diff --git a/Regions.py b/Regions.py index 203a564a..93a88093 100644 --- a/Regions.py +++ b/Regions.py @@ -3,6 +3,8 @@ from Items import ItemFactory from BaseClasses import Region, Location, Entrance, RegionType, Shop, ShopType, LocationType, PotItem, PotFlags from PotShuffle import key_drop_data, vanilla_pots, choose_pots, PotSecretTable +from source.dungeon.EnemyList import setup_enemy_locations + def create_regions(world, player): world.regions += [ @@ -1005,7 +1007,7 @@ def create_shops(world, player): def adjust_locations(world, player): # handle pots - world.pot_contents[player] = PotSecretTable() + world.data_tables[player].pot_secret_table = PotSecretTable() for location, datum in key_drop_data.items(): loc = world.get_location(location, player) drop_location = 'Drop' == datum[0] @@ -1013,6 +1015,7 @@ def adjust_locations(world, player): loc.type = LocationType.Drop snes_address, room, sprite_idx = datum[1] loc.address = snes_address + world.data_tables[player].uw_enemy_table.room_map[room][sprite_idx].location = loc else: loc.type = LocationType.Pot pot, pot_index = next((p, i) for i, p in enumerate(vanilla_pots[datum[1]]) if p.item == PotItem.Key) @@ -1044,7 +1047,7 @@ def adjust_locations(world, player): pot = world.get_location(loc, player).pot else: pot = pot_orig.copy() - world.pot_contents[player].room_map[super_tile].append(pot) + world.data_tables[player].pot_secret_table.room_map[super_tile].append(pot) if valid_pot_location(pot, world.pot_pool[player], world, player): create_pot_location(pot, pot_index, super_tile, world, player) @@ -1057,6 +1060,7 @@ def adjust_locations(world, player): loc.type = LocationType.Shop # player address? it is in the shop table index += 1 + setup_enemy_locations(world, player) # unreal events: for l in ['Ganon', 'Agahnim 1', 'Agahnim 2', 'Dark Blacksmith Ruins', 'Frog', 'Missing Smith', 'Floodgate', 'Trench 1 Switch', 'Trench 2 Switch', 'Swamp Drain', 'Attic Cracked Floor', 'Suspicious Maiden', @@ -1180,7 +1184,7 @@ flooded_keys_reverse = { 'Swamp Palace - Trench 2 Pot Key': 'Trench 2 Switch' } -lookup_id_to_name = {data[0]: name for name, data in location_table.items() if type(data[0]) == int} + location_table = {'Mushroom': (0x180013, 0x186df8, False, 'in the woods'), 'Bottle Merchant': (0x2eb18, 0x186df9, False, 'with a merchant'), 'Flute Spot': (0x18014a, 0x186dfd, False, 'underground'), @@ -1457,6 +1461,7 @@ location_table = {'Mushroom': (0x180013, 0x186df8, False, 'in the woods'), 'Potion Shop - Middle': (None, None, False, 'for sale near potions'), 'Potion Shop - Right': (None, None, False, 'for sale near potions'), } +lookup_id_to_name = {data[0]: name for name, data in location_table.items() if type(data[0]) == int} lookup_id_to_name.update(shop_table_by_location_id) lookup_name_to_id = {name: data[0] for name, data in location_table.items() if type(data[0]) == int} lookup_name_to_id.update(shop_table_by_location) diff --git a/Rom.py b/Rom.py index 26b54dbf..22b534bd 100644 --- a/Rom.py +++ b/Rom.py @@ -37,7 +37,7 @@ from source.dungeon.RoomList import Room0127 JAP10HASH = '03a63945398191337e896e5771f77173' -RANDOMIZERBASEHASH = '61c296effe6180274721d570d2471e1c' +RANDOMIZERBASEHASH = '0587709ac8c5f2abf95b14d1e1264945' class JsonRom(object): @@ -1539,20 +1539,11 @@ def patch_rom(world, rom, player, team, enemized, is_mystery=False): if room.player == player and room.modified: rom.write_bytes(room.address(), room.rom_data()) - if world.pottery[player] not in ['none']: - rom.write_bytes(snes_to_pc(0x1F8375), int32_as_bytes(0x2B8000)) - # make hammer pegs use different tiles - Room0127.write_to_rom(snes_to_pc(0x2B8000), rom) - - if world.pot_contents[player]: + if world.data_tables[player]: colorize_pots = is_mystery or (world.pottery[player] not in ['vanilla', 'lottery'] and (world.colorizepots[player] or world.pottery[player] in ['reduced', 'clustered'])) - if world.pot_contents[player].size() > 0x11c0: - raise Exception('Pot table is too big for current area') - world.pot_contents[player].write_pot_data_to_rom(rom, colorize_pots) - - # todo: write sprites + world.data_tables[player].write_to_rom(rom) write_strings(rom, world, player, team) diff --git a/Utils.py b/Utils.py index a4e3cee2..74e79d61 100644 --- a/Utils.py +++ b/Utils.py @@ -14,6 +14,11 @@ def int16_as_bytes(value): return [value & 0xFF, (value >> 8) & 0xFF] +def int24_as_bytes(value): + value = value & 0xFFFFFF + return [value & 0xFF, (value >> 8) & 0xFF, (value >> 16) & 0xFF] + + def int32_as_bytes(value): value = value & 0xFFFFFFFF return [value & 0xFF, (value >> 8) & 0xFF, (value >> 16) & 0xFF, (value >> 24) & 0xFF] diff --git a/data/base2current.bps b/data/base2current.bps index 03d6471ed59fbc3a0aa2fcb13383c31d53c06f20..52a73adadce6333bac1f62eeae77f1fc00815ef2 100644 GIT binary patch delta 7003 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 delta 1665 zcmWm8eNYo;9>DSEw`;QDJy@!t1PDu7i09R`lmmfEKtQUc(uP{A0r3S)iPKifL0iYT z8;LdT#l+hQi-eHWqAbUqOI&T*P6tnE3tQ?;PTRTajb1UWqq%9tN@or`eR=rfncwI6 zKF>V!j2%?|dPU(iD&3a#%)9+Z%bFnfsOR#M!_7U%xppX4Tnh`Yd%0nV5&E||53yFG z@Ac7NO%KQ8nuEtu{!(xvJg4mID!tRh{Y0!Lx&qvvNCRPIrQPHLp>PrY&^J!FGGzf%u)L4DIvac#!cV7 z8rs8hcT|t&2XN_PT;%5=3*%Z97Oc_`%5k{&k7@<$u>6#ub-3wmr-YSboHZp|^Li()+oQvlcigmjYFO=Xs#N}UOS}@5dJ_yo z?SCGc)iB9o)|}m-ijo=zO7FLd6^zlq%stL&7?){oC3h%+;WE{F^1<@AIg`4GTv6?m zy4By3$%S|RTADqzMDSDOfb?oc#|kB4B3dQG-CWZ^G@jvVDs^P1_D8P0a)NAJ&Tx;J zHfB`Jx-F|O=2%>A3;%Vf<{($O<4Z1J8YDB6horSt9Y9touSw(8W`fuglN7aL@_|5E z%;<1|JneA>)?n@jxd^iob1%pgrU|nR;)vpJ+9I9nBOBg3!=;XRgMoSaRUxl zkoYtnmyl;Y6QINf?9Y(rW_YFe4CY5@6d}hMPTR+&``8D0$9YQJi2EQC%kl6bS>gFK z(1__ma-qj{@mb9MNM3=W2PpALyxEInBd@*~^i{6Y);=giRoq;!PV*0$@ zz!jNy6T4#EpgG&Ld-5#1Bsj=+OgdOq@GRRl`2njI6%4Bj{=iyrWP*d90+v;K93ED{}o)IU_u8a@60v=^Rx`8L?< zRX23vYW|g{ylf#~+Q@Jw`w{lVDFm}b-aKiqxvv4apZRnX3&Mp7t9v1I39Un;I zBUe*kU6Q)5qT>up_%|&-!=k_KedToIu}t_>K_NzPqEUhWB?t8IJx}Mt6;&R4!+5`S z7r}!L^7OXp=`fP-d5h~mBTf?XLNx7g7zJA?`zR4KQg$X~lz*A8(ZLRQgCEgBbLt+` zX*P4r;TCDi?r-Cl=D{{F@|}5LfZP0F9^|U)#^*B_OW7r*jqW@xOx5x;c~Atu@xSFk zG2G>gX(+?vRT`|y#_(9Hu7kf$!%496&U~m&%9fa=Qg8TzZuBC5DIZEe!zb#Y95zJi z^l)xzdf!qs;6ex{_BVx-m}>RW$g&dH1k09}FsV;OkCczNK}jl3ZqNFM*ww&9UMq(d zg(i@ik4Q2tH}`#SpfMjMn&$rhHQz>m8@X+QuT~Z8+c{9Vx3BMkgvs+Fdp%)JC4O;P>^u@yOvB|q2 diff --git a/source/dungeon/EnemyList.py b/source/dungeon/EnemyList.py index 37e5e627..732990cd 100644 --- a/source/dungeon/EnemyList.py +++ b/source/dungeon/EnemyList.py @@ -542,21 +542,21 @@ def init_vanilla_sprites(): create_sprite(0x0004, EnemySprite.Blob, 0x00, 0, 0x1a, 0x1a, 'TR Tongue Pull') create_sprite(0x0004, EnemySprite.Blob, 0x00, 0, 0x15, 0x1b, 'TR Tongue Pull') create_sprite(0x0004, EnemySprite.Pokey, 0x00, 0, 0x07, 0x18, 'TR Dash Room') - create_sprite(0x0006, EnemySprite.Arrghus, 0x00, 0, 0x07, 0x17) - create_sprite(0x0006, EnemySprite.Arrghi, 0x00, 0, 0x07, 0x17) - create_sprite(0x0006, EnemySprite.Arrghi, 0x00, 0, 0x07, 0x17) - create_sprite(0x0006, EnemySprite.Arrghi, 0x00, 0, 0x07, 0x17) - create_sprite(0x0006, EnemySprite.Arrghi, 0x00, 0, 0x07, 0x17) - create_sprite(0x0006, EnemySprite.Arrghi, 0x00, 0, 0x07, 0x17) - create_sprite(0x0006, EnemySprite.Arrghi, 0x00, 0, 0x07, 0x17) - create_sprite(0x0006, EnemySprite.Arrghi, 0x00, 0, 0x07, 0x17) - create_sprite(0x0006, EnemySprite.Arrghi, 0x00, 0, 0x07, 0x17) - create_sprite(0x0006, EnemySprite.Arrghi, 0x00, 0, 0x07, 0x17) - create_sprite(0x0006, EnemySprite.Arrghi, 0x00, 0, 0x07, 0x17) - create_sprite(0x0006, EnemySprite.Arrghi, 0x00, 0, 0x07, 0x17) - create_sprite(0x0006, EnemySprite.Arrghi, 0x00, 0, 0x07, 0x17) - create_sprite(0x0006, EnemySprite.Arrghi, 0x00, 0, 0x07, 0x17) - create_sprite(0x0007, EnemySprite.Moldorm, 0x00, 0, 0x12, 0x0e) + create_sprite(0x0006, EnemySprite.Arrghus, 0x00, 0, 0x07, 0x07) + create_sprite(0x0006, EnemySprite.Arrghi, 0x00, 0, 0x07, 0x07) + create_sprite(0x0006, EnemySprite.Arrghi, 0x00, 0, 0x07, 0x07) + create_sprite(0x0006, EnemySprite.Arrghi, 0x00, 0, 0x07, 0x07) + create_sprite(0x0006, EnemySprite.Arrghi, 0x00, 0, 0x07, 0x07) + create_sprite(0x0006, EnemySprite.Arrghi, 0x00, 0, 0x07, 0x07) + create_sprite(0x0006, EnemySprite.Arrghi, 0x00, 0, 0x07, 0x07) + create_sprite(0x0006, EnemySprite.Arrghi, 0x00, 0, 0x07, 0x07) + create_sprite(0x0006, EnemySprite.Arrghi, 0x00, 0, 0x07, 0x07) + create_sprite(0x0006, EnemySprite.Arrghi, 0x00, 0, 0x07, 0x07) + create_sprite(0x0006, EnemySprite.Arrghi, 0x00, 0, 0x07, 0x07) + create_sprite(0x0006, EnemySprite.Arrghi, 0x00, 0, 0x07, 0x07) + create_sprite(0x0006, EnemySprite.Arrghi, 0x00, 0, 0x07, 0x07) + create_sprite(0x0006, EnemySprite.Arrghi, 0x00, 0, 0x07, 0x07) + create_sprite(0x0007, EnemySprite.Moldorm, 0x00, 0, 0x9, 0x09) create_sprite(0x0008, EnemySprite.BigFairy, 0x00, 0, 0x07, 0x16) create_sprite(0x0009, EnemySprite.Medusa, 0x00, 0, 0x07, 0x08) create_sprite(0x0009, EnemySprite.Medusa, 0x00, 0, 0x08, 0x08) @@ -660,13 +660,13 @@ def init_vanilla_sprites(): create_sprite(0x001b, EnemySprite.RedEyegoreMimic, 0x00, 0, 0x07, 0x14, 'PoD Mimics 2') create_sprite(0x001b, EnemySprite.GreenEyegoreMimic, 0x00, 0, 0x03, 0x1c, 'PoD Mimics 2') create_sprite(0x001b, EnemySprite.GreenEyegoreMimic, 0x00, 0, 0x0c, 0x1c, 'PoD Mimics 2') - create_sprite(0x001c, EnemySprite.ArmosKnight, 0x00, 0, 0x14, 0x15) - create_sprite(0x001c, EnemySprite.ArmosKnight, 0x00, 0, 0x17, 0x15) - create_sprite(0x001c, EnemySprite.ArmosKnight, 0x00, 0, 0x1a, 0x15) - create_sprite(0x001c, EnemySprite.ArmosKnight, 0x00, 0, 0x1a, 0x18) - create_sprite(0x001c, EnemySprite.ArmosKnight, 0x00, 0, 0x17, 0x18) - create_sprite(0x001c, EnemySprite.ArmosKnight, 0x00, 0, 0x14, 0x18) - create_sprite(0x001c, 0x19, SpriteType.Overlord, 0, 0x17, 0x18) + create_sprite(0x001c, EnemySprite.ArmosKnight, 0x00, 0, 0x04, 0x05) + create_sprite(0x001c, EnemySprite.ArmosKnight, 0x00, 0, 0x07, 0x05) + create_sprite(0x001c, EnemySprite.ArmosKnight, 0x00, 0, 0x0a, 0x05) + create_sprite(0x001c, EnemySprite.ArmosKnight, 0x00, 0, 0x0a, 0x08) + create_sprite(0x001c, EnemySprite.ArmosKnight, 0x00, 0, 0x07, 0x08) + create_sprite(0x001c, EnemySprite.ArmosKnight, 0x00, 0, 0x04, 0x08) + create_sprite(0x001c, 0x19, SpriteType.Overlord, 0, 0x07, 0x08) create_sprite(0x001c, EnemySprite.Faerie, 0x00, 0, 0x07, 0x07) create_sprite(0x001c, EnemySprite.Faerie, 0x00, 0, 0x08, 0x07) create_sprite(0x001c, EnemySprite.Faerie, 0x00, 0, 0x07, 0x08) @@ -741,7 +741,7 @@ def init_vanilla_sprites(): create_sprite(0x0028, EnemySprite.Hover, 0x00, 0, 0x0b, 0x0a, 'Swamp Entrance') create_sprite(0x0028, EnemySprite.Hover, 0x00, 0, 0x07, 0x0d, 'Swamp Entrance') create_sprite(0x0028, EnemySprite.SpikeBlock, 0x00, 0, 0x08, 0x10, 'Swamp Entrance') - create_sprite(0x0029, EnemySprite.Mothula, 0x00, 0, 0x18, 0x16) + create_sprite(0x0029, EnemySprite.Mothula, 0x00, 0, 0x08, 0x06) create_sprite(0x0029, 0x07, SpriteType.Overlord, 0, 0x07, 0x16) create_sprite(0x002a, EnemySprite.CrystalSwitch, 0x00, 0, 0x10, 0x17, 'PoD Arena Main') create_sprite(0x002a, EnemySprite.Bumper, 0x00, 0, 0x0f, 0x0f, 'PoD Arena Main') @@ -787,9 +787,9 @@ def init_vanilla_sprites(): create_sprite(0x0032, EnemySprite.Keese, 0x00, 0, 0x13, 0x0d, 'Sewers Dark Cross') create_sprite(0x0032, EnemySprite.Snake, 0x00, 0, 0x10, 0x0e, 'Sewers Dark Cross') create_sprite(0x0032, EnemySprite.Snake, 0x00, 0, 0x12, 0x0f, 'Sewers Dark Cross') - create_sprite(0x0033, EnemySprite.Lanmolas, 0x00, 0, 0x06, 0x17) - create_sprite(0x0033, EnemySprite.Lanmolas, 0x00, 0, 0x09, 0x17) - create_sprite(0x0033, EnemySprite.Lanmolas, 0x00, 0, 0x07, 0x19) + create_sprite(0x0033, EnemySprite.Lanmolas, 0x00, 0, 0x06, 0x07) + create_sprite(0x0033, EnemySprite.Lanmolas, 0x00, 0, 0x09, 0x07) + create_sprite(0x0033, EnemySprite.Lanmolas, 0x00, 0, 0x07, 0x09) create_sprite(0x0034, EnemySprite.Hover, 0x00, 0, 0x0f, 0x0b, 'Swamp West Shallows') create_sprite(0x0034, EnemySprite.Hover, 0x00, 0, 0x10, 0x12, 'Swamp West Shallows') create_sprite(0x0034, EnemySprite.Kyameron, 0x00, 0, 0x0f, 0x15, 'Swamp West Shallows') @@ -965,7 +965,7 @@ def init_vanilla_sprites(): create_sprite(0x004c, EnemySprite.MiniHelmasaur, 0x00, 0, 0x18, 0x0a, 'GT Frozen Over') create_sprite(0x004c, EnemySprite.MiniHelmasaur, 0x00, 0, 0x14, 0x15, 'GT Frozen Over') create_sprite(0x004c, EnemySprite.SpikeBlock, 0x00, 0, 0x13, 0x18, 'GT Frozen Over') - create_sprite(0x004d, EnemySprite.Moldorm, 0x00, 0, 0x0e, 0x0e) + create_sprite(0x004d, EnemySprite.Moldorm, 0x00, 0, 0x09, 0x09) create_sprite(0x004e, EnemySprite.Blob, 0x00, 0, 0x14, 0x08, 'Ice Narrow Corridor') create_sprite(0x004e, EnemySprite.Blob, 0x00, 0, 0x16, 0x08, 'Ice Narrow Corridor') create_sprite(0x004e, EnemySprite.Blob, 0x00, 0, 0x18, 0x08, 'Ice Narrow Corridor') @@ -1056,7 +1056,7 @@ def init_vanilla_sprites(): create_sprite(0x0059, EnemySprite.Gibdo, 0x00, 0, 0x17, 0x14, 'Skull East Bridge') create_sprite(0x0059, EnemySprite.Gibdo, 0x00, 1, 0x15, 0x15, 'Skull East Bridge') create_sprite(0x0059, EnemySprite.Gibdo, 0x00, 1, 0x1a, 0x15, 'Skull East Bridge') - create_sprite(0x005a, EnemySprite.HelmasaurKing, 0x00, 0, 0x17, 0x16) + create_sprite(0x005a, EnemySprite.HelmasaurKing, 0x00, 0, 0x07, 0x06) create_sprite(0x005b, EnemySprite.CrystalSwitch, 0x00, 1, 0x17, 0x0c) create_sprite(0x005b, EnemySprite.CrystalSwitch, 0x00, 1, 0x18, 0x13) create_sprite(0x005b, EnemySprite.SpikeBlock, 0x00, 1, 0x17, 0x15, 'GT Hidden Spikes') @@ -1169,9 +1169,9 @@ def init_vanilla_sprites(): create_sprite(0x006b, EnemySprite.Beamos, 0x00, 0, 0x1b, 0x15, 'GT Mimics 2') create_sprite(0x006b, EnemySprite.Beamos, 0x00, 0, 0x14, 0x1b, 'GT Mimics 2') create_sprite(0x006b, EnemySprite.RedEyegoreMimic, 0x00, 0, 0x18, 0x1b, 'GT Mimics 2') - create_sprite(0x006c, EnemySprite.Lanmolas, 0x00, 0, 0x06, 0x17, 'GT Lanmolas 2') - create_sprite(0x006c, EnemySprite.Lanmolas, 0x00, 0, 0x09, 0x17, 'GT Lanmolas 2') - create_sprite(0x006c, EnemySprite.Lanmolas, 0x00, 0, 0x07, 0x19, 'GT Lanmolas 2') + create_sprite(0x006c, EnemySprite.Lanmolas, 0x00, 0, 0x06, 0x07, 'GT Lanmolas 2') + create_sprite(0x006c, EnemySprite.Lanmolas, 0x00, 0, 0x09, 0x07, 'GT Lanmolas 2') + create_sprite(0x006c, EnemySprite.Lanmolas, 0x00, 0, 0x07, 0x09, 'GT Lanmolas 2') create_sprite(0x006c, EnemySprite.BunnyBeam, 0x00, 0, 0x17, 0x18, 'GT Beam Dash') create_sprite(0x006c, EnemySprite.Medusa, 0x00, 0, 0x03, 0x1c, 'GT Lanmolas 2') create_sprite(0x006d, EnemySprite.RedZazak, 0x00, 0, 0x05, 0x06, 'GT Gauntlet 4') @@ -1369,7 +1369,7 @@ def init_vanilla_sprites(): create_sprite(0x008e, EnemySprite.Blob, 0x00, 0, 0x16, 0x0a, 'Ice Lonely Freezor') create_sprite(0x008e, EnemySprite.Blob, 0x00, 0, 0x14, 0x0b, 'Ice Lonely Freezor') create_sprite(0x008e, EnemySprite.Blob, 0x00, 0, 0x18, 0x0b, 'Ice Lonely Freezor') - create_sprite(0x0090, EnemySprite.Vitreous, 0x00, 0, 0x07, 0x15) + create_sprite(0x0090, EnemySprite.Vitreous, 0x00, 0, 0x07, 0x05) create_sprite(0x0091, EnemySprite.CrystalSwitch, 0x00, 0, 0x18, 0x04, 'Mire Falling Foes') create_sprite(0x0091, EnemySprite.SpikeBlock, 0x00, 0, 0x1b, 0x0e, 'Mire Falling Foes') create_sprite(0x0091, 0x08, SpriteType.Overlord, 0, 0x17, 0x0f) @@ -1475,9 +1475,9 @@ def init_vanilla_sprites(): create_sprite(0x00a1, EnemySprite.Stalfos, 0x00, 0, 0x15, 0x19, 'Mire South Fish') create_sprite(0x00a1, EnemySprite.BunnyBeam, 0x00, 0, 0x17, 0x19, 'Mire South Fish') create_sprite(0x00a1, EnemySprite.Stalfos, 0x00, 0, 0x1b, 0x19, 'Mire South Fish') - create_sprite(0x00a4, EnemySprite.TrinexxRockHead, 0x00, 0, 0x07, 0x15) - create_sprite(0x00a4, EnemySprite.TrinexxFireHead, 0x00, 0, 0x07, 0x15) - create_sprite(0x00a4, EnemySprite.TrinexxIceHead, 0x00, 0, 0x07, 0x15) + create_sprite(0x00a4, EnemySprite.TrinexxRockHead, 0x00, 0, 0x07, 0x05) + create_sprite(0x00a4, EnemySprite.TrinexxFireHead, 0x00, 0, 0x07, 0x05) + create_sprite(0x00a4, EnemySprite.TrinexxIceHead, 0x00, 0, 0x07, 0x05) create_sprite(0x00a5, EnemySprite.Wizzrobe, 0x00, 0, 0x16, 0x05, 'GT Wizzrobes 2') create_sprite(0x00a5, EnemySprite.Wizzrobe, 0x00, 0, 0x19, 0x05, 'GT Wizzrobes 2') create_sprite(0x00a5, EnemySprite.Wizzrobe, 0x00, 0, 0x04, 0x07, 'GT Wizzrobes 1') @@ -1521,7 +1521,7 @@ def init_vanilla_sprites(): create_sprite(0x00ab, EnemySprite.SpikeBlock, 0x00, 0, 0x03, 0x19, 'Thieves Spike Switch') create_sprite(0x00ab, EnemySprite.SpikeBlock, 0x00, 0, 0x0c, 0x1a, 'Thieves Spike Switch') create_sprite(0x00ab, EnemySprite.SpikeBlock, 0x00, 0, 0x03, 0x1b, 'Thieves Spike Switch') - create_sprite(0x00ac, EnemySprite.Blind, 0x00, 0, 0x19, 0x15) + create_sprite(0x00ac, EnemySprite.Blind, 0x00, 0, 0x09, 0x05) create_sprite(0x00ae, EnemySprite.BlueBari, 0x00, 0, 0x13, 0x07, 'Iced T') create_sprite(0x00ae, EnemySprite.BlueBari, 0x00, 0, 0x15, 0x07, 'Iced T') create_sprite(0x00af, EnemySprite.FirebarCW, 0x00, 0, 0x0a, 0x08, 'Ice Catwalk') @@ -1688,13 +1688,13 @@ def init_vanilla_sprites(): create_sprite(0x00c6, EnemySprite.FloatingSkull, 0x00, 0, 0x10, 0x0e, 'TR Hub Ledges') create_sprite(0x00c6, EnemySprite.BlueBari, 0x00, 0, 0x18, 0x14, 'TR Hub Ledges') create_sprite(0x00c6, EnemySprite.BlueBari, 0x00, 0, 0x08, 0x17, 'TR Hub Ledges') - create_sprite(0x00c8, EnemySprite.ArmosKnight, 0x00, 0, 0x14, 0x15) - create_sprite(0x00c8, EnemySprite.ArmosKnight, 0x00, 0, 0x17, 0x15) - create_sprite(0x00c8, EnemySprite.ArmosKnight, 0x00, 0, 0x1a, 0x15) - create_sprite(0x00c8, EnemySprite.ArmosKnight, 0x00, 0, 0x1a, 0x18) - create_sprite(0x00c8, EnemySprite.ArmosKnight, 0x00, 0, 0x17, 0x18) - create_sprite(0x00c8, EnemySprite.ArmosKnight, 0x00, 0, 0x14, 0x18) - create_sprite(0x00c8, 0x19, SpriteType.Overlord, 0, 0x17, 0x18) + create_sprite(0x00c8, EnemySprite.ArmosKnight, 0x00, 0, 0x04, 0x05) + create_sprite(0x00c8, EnemySprite.ArmosKnight, 0x00, 0, 0x07, 0x05) + create_sprite(0x00c8, EnemySprite.ArmosKnight, 0x00, 0, 0x0a, 0x05) + create_sprite(0x00c8, EnemySprite.ArmosKnight, 0x00, 0, 0x0a, 0x08) + create_sprite(0x00c8, EnemySprite.ArmosKnight, 0x00, 0, 0x07, 0x08) + create_sprite(0x00c8, EnemySprite.ArmosKnight, 0x00, 0, 0x04, 0x08) + create_sprite(0x00c8, 0x19, SpriteType.Overlord, 0, 0x07, 0x08) create_sprite(0x00c9, EnemySprite.Popo2, 0x00, 0, 0x10, 0x05, 'Eastern Lobby Bridge') create_sprite(0x00c9, EnemySprite.Popo2, 0x00, 0, 0x0f, 0x06, 'Eastern Lobby Bridge') create_sprite(0x00c9, EnemySprite.Popo2, 0x00, 0, 0x10, 0x07, 'Eastern Lobby Bridge') @@ -1804,9 +1804,9 @@ def init_vanilla_sprites(): create_sprite(0x00dc, EnemySprite.Firesnake, 0x00, 1, 0x16, 0x17, 'Thieves Compass Room') create_sprite(0x00dc, EnemySprite.Firesnake, 0x00, 0, 0x05, 0x1c, 'Thieves Compass Room') create_sprite(0x00dc, EnemySprite.Blob, 0x00, 0, 0x0f, 0x1c, 'Thieves Compass Room') - create_sprite(0x00de, EnemySprite.KholdstareShell, 0x00, 0, 0x17, 0x05) - create_sprite(0x00de, EnemySprite.FallingIce, 0x00, 0, 0x17, 0x05) - create_sprite(0x00de, EnemySprite.Kholdstare, 0x00, 0, 0x17, 0x05) + create_sprite(0x00de, EnemySprite.KholdstareShell, 0x00, 0, 0x07, 0x05) + create_sprite(0x00de, EnemySprite.FallingIce, 0x00, 0, 0x07, 0x05) + create_sprite(0x00de, EnemySprite.Kholdstare, 0x00, 0, 0x07, 0x05) create_sprite(0x00df, EnemySprite.MiniMoldorm, 0x00, 1, 0x0c, 0x15, 'Paradox Cave') create_sprite(0x00df, EnemySprite.MiniMoldorm, 0x00, 1, 0x0c, 0x16, 'Paradox Cave') create_sprite(0x00e0, EnemySprite.BallNChain, 0x00, 0, 0x04, 0x06, 'Tower Gold Knights') @@ -2075,8 +2075,8 @@ class EnemyTable: for sprite in self.room_map[room]: data = sprite.sprite_data() rom.write_bytes(data_pointer + list_offset, data) - list_offset + len(data) - rom.write_byte(data_pointer, 0xff) + list_offset += len(data) + rom.write_byte(data_pointer + list_offset, 0xff) data_pointer += list_offset + 1 else: rom.write_bytes(pointer_address + room * 2, int16_as_bytes(empty_pointer)) @@ -2090,23 +2090,16 @@ class EnemyTable: def setup_enemy_locations(world, player): - world.enemy_list[player] = EnemyTable() - for super_tile, enemy_list in vanilla_sprites.items(): + for super_tile, enemy_list in world.data_tables[player].uw_enemy_table.room_map.items(): for index, sprite in enumerate(enemy_list): - # if sprite.drops_item and sprite.drop_item_kind == 0xe4: - # # normal key drops - # pass - my_sprite = sprite.copy() - world.enemy_list[player].room_map[super_tile].append() - - if valid_drop_location(my_sprite, world, player): - create_drop_location(my_sprite, index, super_tile, world, player) + if valid_drop_location(sprite, world, player): + create_drop_location(sprite, index, super_tile, world, player) def valid_drop_location(sprite, world, player): if world.dropshuffle[player] == 'underworld': if sprite.drops_item and sprite.drop_item_kind == 0xe4: - # already has a location -- hook it up? + # already has a location return False else: stat = enemy_stats[sprite.kind] diff --git a/source/dungeon/RoomHeader.py b/source/dungeon/RoomHeader.py index 13a4f7b7..37272724 100644 --- a/source/dungeon/RoomHeader.py +++ b/source/dungeon/RoomHeader.py @@ -315,7 +315,8 @@ class RoomHeader: self.sprite_sheet = byte_array[3] def write_to_rom(self, rom, base_address): - rom.write_byte(base_address + self.room_id*14 + 3, self.sprite_sheet) + room_offest = self.room_id*14 + rom.write_byte(base_address + room_offest + 3, self.sprite_sheet) def init_room_headers(): diff --git a/source/dungeon/RoomList.py b/source/dungeon/RoomList.py index ceff9405..11dd8a61 100644 --- a/source/dungeon/RoomList.py +++ b/source/dungeon/RoomList.py @@ -17,23 +17,25 @@ class Room: self.doors = doors def write_to_rom(self, address, rom): + offset = 0 rom.write_bytes(address, self.layout) - address += 2 + offset += 2 for obj in self.layer1: - rom.write_bytes(address, obj.data) - address += 3 - rom.write_bytes(address, [0xFF, 0xFF]) - address += 2 + rom.write_bytes(address + offset, obj.data) + offset += 3 + rom.write_bytes(address + offset, [0xFF, 0xFF]) + offset += 2 for obj in self.layer2: - rom.write_bytes(address, obj.data) - address += 3 - rom.write_bytes(address, [0xFF, 0xFF, 0xF0, 0xFF]) - address += 4 + rom.write_bytes(address + offset, obj.data) + offset += 3 + rom.write_bytes(address + offset, [0xFF, 0xFF, 0xF0, 0xFF]) + offset += 4 + door_start = offset for door in self.doors: - rom.write_bytes(address, door.get_bytes()) - address += 2 - rom.write_bytes(address, [0xFF, 0xFF]) - return address + 2 # where the data ended + rom.write_bytes(address + offset, door.get_bytes()) + offset += 2 + rom.write_bytes(address + offset, [0xFF, 0xFF]) + return door_start, offset + 2 # how many bytes were written Room0127 = Room([0xE1, 0x00], diff --git a/source/enemizer/EnemizerTestHarness.py b/source/enemizer/EnemizerTestHarness.py index 09395da1..a05c0d0c 100644 --- a/source/enemizer/EnemizerTestHarness.py +++ b/source/enemizer/EnemizerTestHarness.py @@ -1,3 +1,5 @@ +from types import SimpleNamespace + from source.dungeon.EnemyList import enemy_names, SpriteType from source.enemizer.Enemizer import randomize_underworld_rooms from source.enemizer.SpriteSheets import randomize_underworld_sprite_sheets @@ -6,7 +8,8 @@ import RaceRandom as random if __name__ == '__main__': random.seed(42) - data_tables = init_data_tables(None, None) + world = SimpleNamespace(pottery={1: 'none'}) + data_tables = init_data_tables(world, 1) randomize_underworld_sprite_sheets(data_tables.sprite_sheets) randomize_underworld_rooms(data_tables) diff --git a/source/rom/DataTables.py b/source/rom/DataTables.py index b05b319c..ab946c00 100644 --- a/source/rom/DataTables.py +++ b/source/rom/DataTables.py @@ -1,4 +1,4 @@ -from Utils import snes_to_pc +from Utils import snes_to_pc, int24_as_bytes, int16_as_bytes from source.dungeon.EnemyList import EnemyTable, init_vanilla_sprites, vanilla_sprites from source.dungeon.RoomHeader import init_room_headers @@ -9,32 +9,50 @@ from source.enemizer.SpriteSheets import init_sprite_sheets, init_sprite_require class DataTables: def __init__(self): self.room_headers = None - self.room_list = None # todo: for boss rando + self.room_list = None self.sprite_sheets = None self.uw_enemy_table = None - self.ow_enemy_tables = None # todo : data migration - self.pot_secret_table = None # todo : migrate storage + self.ow_enemy_table = None # todo : data migration + self.pot_secret_table = None # associated data self.sprite_requirements = None - def write_to_rom(self, rom): - for header in self.room_headers.values(): + def write_to_rom(self, rom, colorize_pots=False): + if self.pot_secret_table.size() > 0x11c0: + raise Exception('Pot table is too big for current area') + self.pot_secret_table.write_pot_data_to_rom(rom, colorize_pots) + for room_id, header in self.room_headers.items(): + data_location = (0x30DA00 + room_id * 14) & 0xFFFF + rom.write_bytes(snes_to_pc(0x04F1E2) + room_id * 2, int16_as_bytes(data_location)) header.write_to_rom(rom, snes_to_pc(0x30DA00)) # new header table, bank30, tables.asm - # room list + room_start_address = 0x378000 + for room_id, room in self.room_list.items(): + rom.write_bytes(0x1F8000 + room_id * 3, int24_as_bytes(room_start_address)) + door_start, bytes_written = room.write_to_rom(snes_to_pc(room_start_address), rom) + rom.write_bytes(0x1F83C0 + room_id * 3, int24_as_bytes(room_start_address + door_start)) + room_start_address += bytes_written + # todo: room data doors pointers at 1F83C0 + if room_start_address > 0x380000: + raise Exception('Room list exceeded bank size') + # size notes: bank 03 uses 140E bytes + # bank 0A uses 372A bytes + # bank 1F uses 77CE bytes: total is about a bank and a half + # probably should reuse bank 1F if writing all the rooms out for sheet in self.sprite_sheets.values(): - sheet.write_to_rom(snes_to_pc(0x00DB97)) # bank 00, SheetsTable_AA3 + sheet.write_to_rom(rom, snes_to_pc(0x00DB97)) # bank 00, SheetsTable_AA3 if self.uw_enemy_table.size() > 0x2800: raise Exception('Sprite table is too big for current area') self.uw_enemy_table.write_sprite_data_to_rom(rom) + # todo: write ow enemy table def init_data_tables(world, player): data_tables = DataTables() data_tables.room_headers = init_room_headers() data_tables.room_list = {} - # if world.pottery[player] not in ['none']: - # data_tables.room_list[0x0127] = Room0127 + if world.pottery[player] not in ['none']: + data_tables.room_list[0x0127] = Room0127 data_tables.sprite_requirements = init_sprite_requirements() data_tables.sprite_sheets = init_sprite_sheets(data_tables.sprite_requirements) init_vanilla_sprites()