First pass on multiworld for enemy drops. Fixed a few graphical enemizer issues.

This commit is contained in:
aerinon
2023-06-26 10:29:37 -06:00
parent 503be6aa91
commit 627168e771
12 changed files with 97 additions and 38 deletions

View File

@@ -8,10 +8,12 @@ import shlex
import urllib.parse import urllib.parse
import websockets import websockets
from BaseClasses import PotItem, PotFlags from BaseClasses import PotItem, PotFlags, LocationType
import Items import Items
import Regions import Regions
import PotShuffle import PotShuffle
import source.dungeon.EnemyList as EnemyList
import source.rom.DataTables as DataTables
class ReceivedItem: class ReceivedItem:
@@ -66,6 +68,9 @@ class Context:
self.lookup_name_to_id = {} self.lookup_name_to_id = {}
self.lookup_id_to_name = {} self.lookup_id_to_name = {}
self.pottery_locations_enabled = None
self.uw_sprite_locations_enabled = None
def color_code(*args): def color_code(*args):
codes = {'reset': 0, 'bold': 1, 'underline': 4, 'black': 30, 'red': 31, 'green': 32, 'yellow': 33, 'blue': 34, codes = {'reset': 0, 'bold': 1, 'underline': 4, 'black': 30, 'red': 31, 'green': 32, 'yellow': 33, 'blue': 34,
'magenta': 35, 'cyan': 36, 'white': 37 , 'black_bg': 40, 'red_bg': 41, 'green_bg': 42, 'yellow_bg': 43, 'magenta': 35, 'cyan': 36, 'white': 37 , 'black_bg': 40, 'red_bg': 41, 'green_bg': 42, 'yellow_bg': 43,
@@ -96,6 +101,9 @@ SHOP_SRAM_START = WRAM_START + 0x0164B8 # 2 bytes?
ITEM_SRAM_SIZE = 0x250 ITEM_SRAM_SIZE = 0x250
SHOP_SRAM_LEN = 0x29 # 41 tracked items SHOP_SRAM_LEN = 0x29 # 41 tracked items
POT_LOCATION_TABLE = 0x142A60
UW_SPRITE_LOCATION_TABLE = 0x142CB0
RECV_PROGRESS_ADDR = SAVEDATA_START + 0x4D0 # 2 bytes RECV_PROGRESS_ADDR = SAVEDATA_START + 0x4D0 # 2 bytes
RECV_ITEM_ADDR = SAVEDATA_START + 0x4D2 # 1 byte RECV_ITEM_ADDR = SAVEDATA_START + 0x4D2 # 1 byte
RECV_ITEM_PLAYER_ADDR = SAVEDATA_START + 0x4D3 # 1 byte RECV_ITEM_PLAYER_ADDR = SAVEDATA_START + 0x4D3 # 1 byte
@@ -826,12 +834,16 @@ def get_location_name_from_address(ctx, address):
def filter_location(ctx, location): def filter_location(ctx, location):
if (not ctx.key_drop_mode and location in PotShuffle.key_drop_data if location in location_table_pot_items:
and PotShuffle.key_drop_data[location][0] == 'Drop'): tile_idx, mask = location_table_pot_items[location]
return True tracking_data = ctx.pottery_locations_enabled
if (not ctx.pottery_mode and location in PotShuffle.key_drop_data tile_pots = tracking_data[tile_idx] | (tracking_data[tile_idx+1] << 8)
and PotShuffle.key_drop_data[location][0] == 'Pot'): return (mask & tile_pots) == 0
return True if location in location_table_sprite_items:
tile_idx, mask = location_table_sprite_items[location]
tracking_data = ctx.uw_sprite_locations_enabled
tile_sprites = tracking_data[tile_idx] | (tracking_data[tile_idx+1] << 8)
return (mask & tile_sprites) == 0
if not ctx.shop_mode and location in Regions.flat_normal_shops: if not ctx.shop_mode and location in Regions.flat_normal_shops:
return True return True
if not ctx.retro_mode and location in Regions.flat_retro_shops: if not ctx.retro_mode and location in Regions.flat_retro_shops:
@@ -842,13 +854,6 @@ def filter_location(ctx, location):
def init_lookups(ctx): def init_lookups(ctx):
ctx.lookup_id_to_name = {x: y for x, y in Regions.lookup_id_to_name.items()} ctx.lookup_id_to_name = {x: y for x, y in Regions.lookup_id_to_name.items()}
ctx.lookup_name_to_id = {x: y for x, y in Regions.lookup_name_to_id.items()} ctx.lookup_name_to_id = {x: y for x, y in Regions.lookup_name_to_id.items()}
for location, datum in PotShuffle.key_drop_data.items():
type = datum[0]
if type == 'Drop':
location_id, super_tile, sprite_index = datum[1]
location_table_sprite_items[location] = (2 * super_tile, 0x8000 >> sprite_index)
ctx.lookup_name_to_id[location] = location_id
ctx.lookup_id_to_name[location_id] = location
for super_tile, pot_list in PotShuffle.vanilla_pots.items(): for super_tile, pot_list in PotShuffle.vanilla_pots.items():
for pot_index, pot in enumerate(pot_list): for pot_index, pot in enumerate(pot_list):
if pot.item != PotItem.Hole: if pot.item != PotItem.Hole:
@@ -862,6 +867,25 @@ def init_lookups(ctx):
location_id = Regions.pot_address(pot_index, super_tile) location_id = Regions.pot_address(pot_index, super_tile)
ctx.lookup_name_to_id[loc_name] = location_id ctx.lookup_name_to_id[loc_name] = location_id
ctx.lookup_id_to_name[location_id] = loc_name ctx.lookup_id_to_name[location_id] = loc_name
logging.info('Init Lookups')
uw_table = DataTables.get_uw_enemy_table()
key_drop_data = {(v[1][1], v[1][2]): k for k, v in PotShuffle.key_drop_data.items() if v[1] == 'Drop'}
for super_tile, enemy_list in uw_table.room_map.items():
index_adj = 0
for index, sprite in enumerate(enemy_list):
if sprite.sub_type == 0x07: # overlord
index_adj += 1
continue
if (super_tile, index) in key_drop_data:
loc_name = key_drop_data[(super_tile, index)]
else:
loc_name = f'{sprite.region} Enemy #{index+1}'
if index < index_adj:
logging.info(f'Problem at {hex(super_tile)} {loc_name}')
location_table_sprite_items[loc_name] = (2 * super_tile, 0x8000 >> (index-index_adj))
location_id = EnemyList.drop_address(index, super_tile)
ctx.lookup_name_to_id[loc_name] = location_id
ctx.lookup_id_to_name[location_id] = loc_name
async def track_locations(ctx : Context, roomid, roomdata): async def track_locations(ctx : Context, roomid, roomdata):
@@ -983,6 +1007,7 @@ async def game_watcher(ctx : Context):
if not ctx.rom: if not ctx.rom:
rom = await snes_read(ctx, ROMNAME_START, ROMNAME_SIZE) rom = await snes_read(ctx, ROMNAME_START, ROMNAME_SIZE)
logging.info(f'Rom name: {rom} @ {hex(ROMNAME_START)}')
if rom is None or rom == bytes([0] * ROMNAME_SIZE): if rom is None or rom == bytes([0] * ROMNAME_SIZE):
continue continue
@@ -996,6 +1021,12 @@ async def game_watcher(ctx : Context):
logging.warning("ROM change detected, please reconnect to the multiworld server") logging.warning("ROM change detected, please reconnect to the multiworld server")
await disconnect(ctx) await disconnect(ctx)
if ctx.pottery_locations_enabled is None:
ctx.pottery_locations_enabled = await snes_read(ctx, POT_LOCATION_TABLE, 0x250)
if ctx.uw_sprite_locations_enabled is None:
ctx.uw_sprite_locations_enabled = await snes_read(ctx, UW_SPRITE_LOCATION_TABLE, 0x250)
gamemode = await snes_read(ctx, WRAM_START + 0x10, 1) gamemode = await snes_read(ctx, WRAM_START + 0x10, 1)
if gamemode is None or gamemode[0] not in INGAME_MODES: if gamemode is None or gamemode[0] not in INGAME_MODES:
continue continue

View File

@@ -16,6 +16,8 @@ import Items
import Regions import Regions
import PotShuffle import PotShuffle
from MultiClient import ReceivedItem, get_item_name_from_id, get_location_name_from_address from MultiClient import ReceivedItem, get_item_name_from_id, get_location_name_from_address
import source.dungeon.EnemyList as EnemyList
import source.rom.DataTables as DataTables
class Client: class Client:
def __init__(self, socket): def __init__(self, socket):
@@ -355,12 +357,6 @@ async def console(ctx : Context):
def init_lookups(ctx): def init_lookups(ctx):
ctx.lookup_id_to_name = {x: y for x, y in Regions.lookup_id_to_name.items()} ctx.lookup_id_to_name = {x: y for x, y in Regions.lookup_id_to_name.items()}
ctx.lookup_name_to_id = {x: y for x, y in Regions.lookup_name_to_id.items()} ctx.lookup_name_to_id = {x: y for x, y in Regions.lookup_name_to_id.items()}
for location, datum in PotShuffle.key_drop_data.items():
type = datum[0]
if type == 'Drop':
location_id = datum[1][0]
ctx.lookup_name_to_id[location] = location_id
ctx.lookup_id_to_name[location_id] = location
for super_tile, pot_list in PotShuffle.vanilla_pots.items(): for super_tile, pot_list in PotShuffle.vanilla_pots.items():
for pot_index, pot in enumerate(pot_list): for pot_index, pot in enumerate(pot_list):
if pot.item != PotItem.Hole: if pot.item != PotItem.Hole:
@@ -373,6 +369,17 @@ def init_lookups(ctx):
location_id = Regions.pot_address(pot_index, super_tile) location_id = Regions.pot_address(pot_index, super_tile)
ctx.lookup_name_to_id[loc_name] = location_id ctx.lookup_name_to_id[loc_name] = location_id
ctx.lookup_id_to_name[location_id] = loc_name ctx.lookup_id_to_name[location_id] = loc_name
uw_table = DataTables.get_uw_enemy_table()
key_drop_data = {(v[1][1], v[1][2]): k for k, v in PotShuffle.key_drop_data.items() if v[1] == 'Drop'}
for super_tile, enemy_list in uw_table.room_map.items():
for index, sprite in enumerate(enemy_list):
if (super_tile, index) in key_drop_data:
loc_name = key_drop_data[(super_tile, index)]
else:
loc_name = f'{sprite.region} Enemy #{index+1}'
location_id = EnemyList.drop_address(index, super_tile)
ctx.lookup_name_to_id[loc_name] = location_id
ctx.lookup_id_to_name[location_id] = loc_name
async def main(): async def main():

2
Rom.py
View File

@@ -40,7 +40,7 @@ from source.enemizer.Enemizer import write_enemy_shuffle_settings
JAP10HASH = '03a63945398191337e896e5771f77173' JAP10HASH = '03a63945398191337e896e5771f77173'
RANDOMIZERBASEHASH = '79a57594c59b3fa2e9cf344fc7437bf9' RANDOMIZERBASEHASH = '563fe28515c5dd9f64270ca475d1c2d3'
class JsonRom(object): class JsonRom(object):

Binary file not shown.

View File

@@ -2107,16 +2107,24 @@ class EnemyTable:
data_pointer += 2 data_pointer += 2
for room in range(0, 0x128): for room in range(0, 0x128):
if room in self.room_map: if room in self.room_map:
tracking_mask = 0x00
data_address = pc_to_snes(data_pointer) & 0xFFFF data_address = pc_to_snes(data_pointer) & 0xFFFF
rom.write_bytes(pointer_address + room * 2, int16_as_bytes(data_address)) rom.write_bytes(pointer_address + room * 2, int16_as_bytes(data_address))
rom.write_byte(data_pointer, 0x01 if room in layered_oam_rooms else 0x00) rom.write_byte(data_pointer, 0x01 if room in layered_oam_rooms else 0x00)
list_offset = 1 list_offset = 1
for sprite in self.room_map[room]: idx_adj = 0
for idx, sprite in enumerate(self.room_map[room]):
data = sprite.sprite_data() data = sprite.sprite_data()
rom.write_bytes(data_pointer + list_offset, data) rom.write_bytes(data_pointer + list_offset, data)
list_offset += len(data) list_offset += len(data)
if sprite.sub_type == 0x07: # overlord
idx_adj += 1
continue
if sprite.location is not None:
tracking_mask |= 1 << (15 - idx + idx_adj)
rom.write_byte(data_pointer + list_offset, 0xff) rom.write_byte(data_pointer + list_offset, 0xff)
data_pointer += list_offset + 1 data_pointer += list_offset + 1
rom.write_bytes(snes_to_pc(0x28ACB0) + room * 2, int16_as_bytes(tracking_mask))
else: else:
rom.write_bytes(pointer_address + room * 2, int16_as_bytes(empty_pointer)) rom.write_bytes(pointer_address + room * 2, int16_as_bytes(empty_pointer))

View File

@@ -46,9 +46,10 @@ class Room:
def find_all_pots(self): def find_all_pots(self):
pots = [] pots = []
pots.extend([x for x in self.layer1 if x.data[2] == 0xFA]) pots.extend([x for x in self.layer1 if x.data[2] in {0xFA, 0xFB} and not x.dummy])
pots.extend([x for x in self.layer2 if x.data[2] == 0xFA]) pots.extend([x for x in self.layer2 if x.data[2] in {0xFA, 0xFB} and not x.dummy])
pots.extend([x for x in self.layer3 if x.data[2] == 0xFA]) if self.layer3:
pots.extend([x for x in self.layer3 if x.data[2] in {0xFA, 0xFB} and not x.dummy])
return pots return pots
@@ -514,12 +515,12 @@ Room0127 = Room([0xE1, 0x00],
RoomObject(0x0AB61E, [0x43, 0xCB, 0xFA]), RoomObject(0x0AB61E, [0x43, 0xCB, 0xFA]),
RoomObject(0x0AB621, [0x4B, 0xCB, 0xFA]), RoomObject(0x0AB621, [0x4B, 0xCB, 0xFA]),
RoomObject(0x0AB624, [0xBF, 0x94, 0xF9]), RoomObject(0x0AB624, [0xBF, 0x94, 0xF9]),
RoomObject(0x0AB627, [0xB3, 0xB3, 0xFA]), RoomObject(0x0AB627, [0xB3, 0xB3, 0xFA], True),
RoomObject(0x0AB62A, [0xCB, 0xB3, 0xFA]), RoomObject(0x0AB62A, [0xCB, 0xB3, 0xFA], True),
RoomObject(0x0AB62D, [0xAD, 0xC8, 0xDF]), RoomObject(0x0AB62D, [0xAD, 0xC8, 0xDF]),
RoomObject(0x0AB630, [0xC4, 0xC8, 0xDF]), RoomObject(0x0AB630, [0xC4, 0xC8, 0xDF]),
RoomObject(0x0AB633, [0xB3, 0xE3, 0xFA]), RoomObject(0x0AB633, [0xB3, 0xE3, 0xFA], True),
RoomObject(0x0AB636, [0xCB, 0xE3, 0xFA]), RoomObject(0x0AB636, [0xCB, 0xE3, 0xFA], True),
RoomObject(0x0AB639, [0x81, 0x93, 0xC0]), RoomObject(0x0AB639, [0x81, 0x93, 0xC0]),
RoomObject(0x0AB63C, [0x81, 0xD2, 0xC0]), RoomObject(0x0AB63C, [0x81, 0xD2, 0xC0]),
RoomObject(0x0AB63F, [0xE1, 0x93, 0xC0]), RoomObject(0x0AB63F, [0xE1, 0x93, 0xC0]),

View File

@@ -8,9 +8,10 @@ Shuffled_Pot = (0xFB, 0, 0) # formerly weird pot, or black diagonal thing
class RoomObject: class RoomObject:
def __init__(self, address, data): def __init__(self, address, data, dummy=False):
self.address = address self.address = address
self.data = data self.data = data
self.dummy = dummy # some room objects are dummies, unreachable
def change_type(self, new_type): def change_type(self, new_type):
type_id, datum_a, datum_b = new_type type_id, datum_a, datum_b = new_type

View File

@@ -75,7 +75,7 @@ def get_possible_sheets(room_id, data_tables, specific, all_sheets, uw_sheets):
req = requirements[key] req = requirements[key]
if isinstance(req, dict): if isinstance(req, dict):
req = req[room_id] req = req[room_id]
if req.static or not req.can_randomize: if req.static or not req.can_randomize or sprite.static:
if req.groups: if req.groups:
match_all_room_groups.intersection_update(req.groups) match_all_room_groups.intersection_update(req.groups)
if not match_all_room_groups: if not match_all_room_groups:
@@ -284,9 +284,6 @@ def randomize_underworld_rooms(data_tables, world, player, custom_uw):
if room_id in {0, 1, 3, 6, 7, 0xd, 0x14, 0x1c, 0x20, 0x29, 0x30, 0x33, if room_id in {0, 1, 3, 6, 7, 0xd, 0x14, 0x1c, 0x20, 0x29, 0x30, 0x33,
0x4d, 0x5a, 0x90, 0xa4, 0xac, 0xc8, 0xde}: 0x4d, 0x5a, 0x90, 0xa4, 0xac, 0xc8, 0xde}:
continue continue
if room_id not in data_tables.uw_enemy_table.room_map:
continue
# sprite_reqs = data_tables.sprite_requirements
current_sprites = data_tables.uw_enemy_table.room_map[room_id] current_sprites = data_tables.uw_enemy_table.room_map[room_id]
sprite_limit = sum(sprite_limiter[x.kind] if x.kind in sprite_limiter else 1 for x in current_sprites) sprite_limit = sum(sprite_limiter[x.kind] if x.kind in sprite_limiter else 1 for x in current_sprites)
randomizeable_sprites = get_randomize_able_sprites(room_id, data_tables) randomizeable_sprites = get_randomize_able_sprites(room_id, data_tables)

View File

@@ -189,7 +189,7 @@ def init_sprite_requirements():
SpriteRequirement(EnemySprite.Ropa).sub_group(0, 0x16), SpriteRequirement(EnemySprite.Ropa).sub_group(0, 0x16),
SpriteRequirement(EnemySprite.RedBari).sub_group(0, 0x1f), SpriteRequirement(EnemySprite.RedBari).sub_group(0, 0x1f),
SpriteRequirement(EnemySprite.BlueBari).sub_group(0, 0x1f), SpriteRequirement(EnemySprite.BlueBari).sub_group(0, 0x1f),
SpriteRequirement(EnemySprite.TalkingTree).affix().sub_group(0, 0x15), SpriteRequirement(EnemySprite.TalkingTree).affix().sub_group(3, [0x15, 0x1B]),
SpriteRequirement(EnemySprite.HardhatBeetle).sub_group(1, 0x1e), SpriteRequirement(EnemySprite.HardhatBeetle).sub_group(1, 0x1e),
SpriteRequirement(EnemySprite.Deadrock).sub_group(3, 0x10).exclude({0x7f, 0x10c}), SpriteRequirement(EnemySprite.Deadrock).sub_group(3, 0x10).exclude({0x7f, 0x10c}),
SpriteRequirement(EnemySprite.DarkWorldHintNpc).affix(), # no groups? SpriteRequirement(EnemySprite.DarkWorldHintNpc).affix(), # no groups?
@@ -700,6 +700,8 @@ def setup_required_overworld_groups(sheets):
[None, 73, 19, None], # allow for green knife guard [None, 73, 19, None], # allow for green knife guard
[22, None, 23, None], # increase odds for snapdragon [22, None, 23, None], # increase odds for snapdragon
[70, 73, None, None], # guards group (ballnchain, redbush, redjav, cannon, bomb, bluesain [70, 73, None, None], # guards group (ballnchain, redbush, redjav, cannon, bomb, bluesain
[None, None, None, 0x15], # an option for talking trees
[None, None, None, 0x1B], # an option for talking trees
] ]
for group in free_sheet_reqs: for group in free_sheet_reqs:

View File

@@ -126,6 +126,7 @@ UwGeneralDeny:
- [ 0x005f, 1, [ "RollerVerticalDown", "RollerHorizontalRight" ] ] #"Ice Palace - Bari University - Blue Bari 2" - [ 0x005f, 1, [ "RollerVerticalDown", "RollerHorizontalRight" ] ] #"Ice Palace - Bari University - Blue Bari 2"
- [ 0x0060, 0, [ "RollerVerticalUp", "RollerHorizontalLeft", "AntiFairyCircle", "BigSpike", "Bumper" ] ] #"Hyrule Castle - West - Blue Guard" - [ 0x0060, 0, [ "RollerVerticalUp", "RollerHorizontalLeft", "AntiFairyCircle", "BigSpike", "Bumper" ] ] #"Hyrule Castle - West - Blue Guard"
- [ 0x0062, 0, [ "RollerVerticalUp", "AntiFairyCircle", "BigSpike", "SpikeBlock", "Bumper" ] ] #"Hyrule Castle - East - Blue Guard" - [ 0x0062, 0, [ "RollerVerticalUp", "AntiFairyCircle", "BigSpike", "SpikeBlock", "Bumper" ] ] #"Hyrule Castle - East - Blue Guard"
- [ 0x0064, 2, [ "Bumper" , "Beamos" ] ] #"Thieves' Town - Attic Hall Left - Keese 2"
- [ 0x0064, 4, [ "RollerHorizontalLeft", "RollerHorizontalRight" ] ] #"Thieves' Town - Attic Hall Left - Rat 1" - [ 0x0064, 4, [ "RollerHorizontalLeft", "RollerHorizontalRight" ] ] #"Thieves' Town - Attic Hall Left - Rat 1"
- [ 0x0065, 0, [ "RollerVerticalUp", "Beamos", "AntiFairyCircle", "BigSpike", "SpikeBlock", "Bumper" ] ] #"Thieves' Town - Attic Window - Rat 1" - [ 0x0065, 0, [ "RollerVerticalUp", "Beamos", "AntiFairyCircle", "BigSpike", "SpikeBlock", "Bumper" ] ] #"Thieves' Town - Attic Window - Rat 1"
- [ 0x0065, 1, [ "RollerHorizontalLeft", "RollerHorizontalRight" ] ] #"Thieves' Town - Attic Window - Rat 2" - [ 0x0065, 1, [ "RollerHorizontalLeft", "RollerHorizontalRight" ] ] #"Thieves' Town - Attic Window - Rat 2"
@@ -224,6 +225,7 @@ UwGeneralDeny:
- [ 0x009e, 3, [ "RollerVerticalUp", "RollerVerticalDown", "RollerHorizontalLeft", "RollerHorizontalRight", "AntiFairyCircle", "BigSpike", "SpikeBlock", "Bumper" ] ] #"Ice Palace - Fairy Drop - blue - Red Bari 3" - [ 0x009e, 3, [ "RollerVerticalUp", "RollerVerticalDown", "RollerHorizontalLeft", "RollerHorizontalRight", "AntiFairyCircle", "BigSpike", "SpikeBlock", "Bumper" ] ] #"Ice Palace - Fairy Drop - blue - Red Bari 3"
- [ 0x00a0, 1, [ "RollerHorizontalLeft", "AntiFairyCircle", "BigSpike", "SpikeBlock", "Bumper" ] ] #"Misery Mire - Boss Antechamber - Antifairy" - [ 0x00a0, 1, [ "RollerHorizontalLeft", "AntiFairyCircle", "BigSpike", "SpikeBlock", "Bumper" ] ] #"Misery Mire - Boss Antechamber - Antifairy"
- [ 0x00a1, 2, [ "Statue", "RollerHorizontalRight", "Beamos", "AntiFairyCircle", "BigSpike", "SpikeBlock", "Bumper" ] ] #"Misery Mire - Fish Room - Spark (Clockwise) 2" - [ 0x00a1, 2, [ "Statue", "RollerHorizontalRight", "Beamos", "AntiFairyCircle", "BigSpike", "SpikeBlock", "Bumper" ] ] #"Misery Mire - Fish Room - Spark (Clockwise) 2"
- [ 0x00a5, 2, [ "BigSpike" ] ] #"GT Wizzrobes 1 - Wizzrobe 3"
- [ 0x00a5, 10, [ "RollerHorizontalLeft", "RollerHorizontalRight", "AntiFairyCircle", "BigSpike", "Bumper" ] ] #"Ganon's Tower - Laser Bridge - Red Spear Guard" - [ 0x00a5, 10, [ "RollerHorizontalLeft", "RollerHorizontalRight", "AntiFairyCircle", "BigSpike", "Bumper" ] ] #"Ganon's Tower - Laser Bridge - Red Spear Guard"
- [ 0x00a8, 1, [ "RollerVerticalUp", "RollerHorizontalLeft" ] ] #"Eastern Palace - West Wing - Top - Stalfos 2" - [ 0x00a8, 1, [ "RollerVerticalUp", "RollerHorizontalLeft" ] ] #"Eastern Palace - West Wing - Top - Stalfos 2"
- [ 0x00a8, 3, [ "RollerVerticalDown", "RollerHorizontalLeft" ] ] #"Eastern Palace - West Wing - Top - Stalfos 4" - [ 0x00a8, 3, [ "RollerVerticalDown", "RollerHorizontalLeft" ] ] #"Eastern Palace - West Wing - Top - Stalfos 4"
@@ -309,6 +311,7 @@ UwGeneralDeny:
- [ 0x00f1, 4, [ "RollerVerticalUp", "RollerVerticalDown", "RollerHorizontalLeft", "RollerHorizontalRight" ] ] #"Old Man Maze - Keese 5" - [ 0x00f1, 4, [ "RollerVerticalUp", "RollerVerticalDown", "RollerHorizontalLeft", "RollerHorizontalRight" ] ] #"Old Man Maze - Keese 5"
- [ 0x00f1, 5, [ "RollerVerticalUp", "RollerVerticalDown", "RollerHorizontalLeft", "RollerHorizontalRight" ] ] #"Old Man Maze - Keese 6" - [ 0x00f1, 5, [ "RollerVerticalUp", "RollerVerticalDown", "RollerHorizontalLeft", "RollerHorizontalRight" ] ] #"Old Man Maze - Keese 6"
OwGeneralDeny: OwGeneralDeny:
- [0x1e, 3, ["Beamos"]] # forbid a beamos here
- [0x5e, 4, ["RollerVerticalUp", "Gibo"]] # forbid that one roller for kiki pod, and the kiki eating Gibo - [0x5e, 4, ["RollerVerticalUp", "Gibo"]] # forbid that one roller for kiki pod, and the kiki eating Gibo
- [0x5e, 5, ["Gibo"]] # kiki eating Gibo - [0x5e, 5, ["Gibo"]] # kiki eating Gibo
UwEnemyDrop: UwEnemyDrop:
@@ -360,7 +363,7 @@ UwEnemyDrop:
"BombGuard", "GreenKnifeGuard"]] "BombGuard", "GreenKnifeGuard"]]
- [0x00c6, 5, ["HardhatBeetle", "Wizzrobe", "MiniHelmasaur", "BlueGuard", "GreenGuard", "RedSpearGuard", - [0x00c6, 5, ["HardhatBeetle", "Wizzrobe", "MiniHelmasaur", "BlueGuard", "GreenGuard", "RedSpearGuard",
"BluesainBolt", "UsainBolt", "BlueArcher", "GreenBushGuard", "RedJavelinGuard", "RedBushGuard", "BluesainBolt", "UsainBolt", "BlueArcher", "GreenBushGuard", "RedJavelinGuard", "RedBushGuard",
"BombGuard", "GreenKnifeGuard"]] "BombGuard", "GreenKnifeGuard", "Bumper"]]
- [0x00c6, 6, ["HardhatBeetle", "Wizzrobe", "MiniHelmasaur", "BlueGuard", "GreenGuard", "RedSpearGuard", - [0x00c6, 6, ["HardhatBeetle", "Wizzrobe", "MiniHelmasaur", "BlueGuard", "GreenGuard", "RedSpearGuard",
"BluesainBolt", "UsainBolt", "BlueArcher", "GreenBushGuard", "RedJavelinGuard", "RedBushGuard", "BluesainBolt", "UsainBolt", "BlueArcher", "GreenBushGuard", "RedJavelinGuard", "RedBushGuard",
"BombGuard", "GreenKnifeGuard"]] "BombGuard", "GreenKnifeGuard"]]

View File

@@ -57,7 +57,6 @@ class DataTables:
choice = SheetChoice(tuple(item['slots']), item['assignments'], item['weight']) choice = SheetChoice(tuple(item['slots']), item['assignments'], item['weight'])
self.sheet_choices.append(choice) self.sheet_choices.append(choice)
def write_to_rom(self, rom, colorize_pots=False, increase_bush_sprite_chance=False): def write_to_rom(self, rom, colorize_pots=False, increase_bush_sprite_chance=False):
if self.pot_secret_table.size() > 0x11c0: if self.pot_secret_table.size() > 0x11c0:
raise Exception('Pot table is too big for current area') raise Exception('Pot table is too big for current area')
@@ -175,3 +174,13 @@ def init_data_tables(world, player):
data_tables.enemy_damage = {k: list(v) for k, v in world.damage_table[player].enemy_damage.items()} data_tables.enemy_damage = {k: list(v) for k, v in world.damage_table[player].enemy_damage.items()}
# todo: more denials based on enemy drops # todo: more denials based on enemy drops
return data_tables return data_tables
def get_uw_enemy_table():
init_vanilla_sprites()
uw_table = EnemyTable()
for room, sprite_list in vanilla_sprites.items():
for sprite in sprite_list:
uw_table.room_map[room].append(sprite.copy())
return uw_table

View File

@@ -109,7 +109,7 @@ def roll_settings(weights):
ret.standardize_palettes = (get_choice('standardize_palettes') if 'standardize_palettes' in weights ret.standardize_palettes = (get_choice('standardize_palettes') if 'standardize_palettes' in weights
else 'standardize') else 'standardize')
goal = get_choice('goals') goal = get_choice_default('goals', default='ganon')
if goal is not None: if goal is not None:
ret.goal = {'ganon': 'ganon', ret.goal = {'ganon': 'ganon',
'fast_ganon': 'crystals', 'fast_ganon': 'crystals',