UW Enemizer work
Refinements for data table support
This commit is contained in:
@@ -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):
|
||||
|
||||
2
Fill.py
2
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)
|
||||
|
||||
3
Main.py
3
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)
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
11
Regions.py
11
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)
|
||||
|
||||
15
Rom.py
15
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)
|
||||
|
||||
|
||||
5
Utils.py
5
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]
|
||||
|
||||
Binary file not shown.
@@ -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]
|
||||
|
||||
@@ -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():
|
||||
|
||||
@@ -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],
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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()
|
||||
|
||||
Reference in New Issue
Block a user