Merge in door dev unstable

This commit is contained in:
aerinon
2020-09-17 15:23:06 -06:00
18 changed files with 107 additions and 47 deletions

View File

@@ -19,11 +19,13 @@ from RoomData import Room
class World(object): class World(object):
def __init__(self, players, shuffle, doorShuffle, logic, mode, swords, difficulty, difficulty_adjustments, timer, progressive, goal, algorithm, accessibility, shuffle_ganon, retro, custom, customitemarray, hints): def __init__(self, players, shuffle, doorShuffle, logic, mode, swords, difficulty, difficulty_adjustments,
timer, progressive, goal, algorithm, accessibility, shuffle_ganon, retro, custom, customitemarray, hints):
self.players = players self.players = players
self.teams = 1 self.teams = 1
self.shuffle = shuffle.copy() self.shuffle = shuffle.copy()
self.doorShuffle = doorShuffle.copy() self.doorShuffle = doorShuffle.copy()
self.intensity = {}
self.logic = logic.copy() self.logic = logic.copy()
self.mode = mode.copy() self.mode = mode.copy()
self.swords = swords.copy() self.swords = swords.copy()
@@ -1843,6 +1845,7 @@ class Spoiler(object):
'goal': self.world.goal, 'goal': self.world.goal,
'shuffle': self.world.shuffle, 'shuffle': self.world.shuffle,
'door_shuffle': self.world.doorShuffle, 'door_shuffle': self.world.doorShuffle,
'intensity': self.world.intensity,
'item_pool': self.world.difficulty, 'item_pool': self.world.difficulty,
'item_functionality': self.world.difficulty_adjustments, 'item_functionality': self.world.difficulty_adjustments,
'gt_crystals': self.world.crystals_needed_for_gt, 'gt_crystals': self.world.crystals_needed_for_gt,
@@ -1905,6 +1908,7 @@ class Spoiler(object):
outfile.write('Item Functionality: %s\n' % self.metadata['item_functionality'][player]) outfile.write('Item Functionality: %s\n' % self.metadata['item_functionality'][player])
outfile.write('Entrance Shuffle: %s\n' % self.metadata['shuffle'][player]) outfile.write('Entrance Shuffle: %s\n' % self.metadata['shuffle'][player])
outfile.write('Door Shuffle: %s\n' % self.metadata['door_shuffle'][player]) outfile.write('Door Shuffle: %s\n' % self.metadata['door_shuffle'][player])
outfile.write('Intensity: %s\n' % self.metadata['intensity'][player])
outfile.write('Crystals required for GT: %s\n' % self.metadata['gt_crystals'][player]) outfile.write('Crystals required for GT: %s\n' % self.metadata['gt_crystals'][player])
outfile.write('Crystals required for Ganon: %s\n' % self.metadata['ganon_crystals'][player]) outfile.write('Crystals required for Ganon: %s\n' % self.metadata['ganon_crystals'][player])
outfile.write('Pyramid hole pre-opened: %s\n' % ('Yes' if self.metadata['open_pyramid'][player] else 'No')) outfile.write('Pyramid hole pre-opened: %s\n' % ('Yes' if self.metadata['open_pyramid'][player] else 'No'))

3
CLI.py
View File

@@ -90,7 +90,7 @@ def parse_cli(argv, no_defaults=False):
playerargs = parse_cli(shlex.split(getattr(ret,f"p{player}")), True) playerargs = parse_cli(shlex.split(getattr(ret,f"p{player}")), True)
for name in ['logic', 'mode', 'swords', 'goal', 'difficulty', 'item_functionality', for name in ['logic', 'mode', 'swords', 'goal', 'difficulty', 'item_functionality',
'shuffle', 'door_shuffle', 'crystals_ganon', 'crystals_gt', 'openpyramid', 'shuffle', 'door_shuffle', 'intensity', 'crystals_ganon', 'crystals_gt', 'openpyramid',
'mapshuffle', 'compassshuffle', 'keyshuffle', 'bigkeyshuffle', 'startinventory', 'mapshuffle', 'compassshuffle', 'keyshuffle', 'bigkeyshuffle', 'startinventory',
'retro', 'accessibility', 'hints', 'beemizer', 'experimental', 'dungeon_counters', 'retro', 'accessibility', 'hints', 'beemizer', 'experimental', 'dungeon_counters',
'shufflebosses', 'shuffleenemies', 'enemy_health', 'enemy_damage', 'shufflepots', 'shufflebosses', 'shuffleenemies', 'enemy_health', 'enemy_damage', 'shufflepots',
@@ -141,6 +141,7 @@ def parse_settings():
"bigkeyshuffle": False, "bigkeyshuffle": False,
"keysanity": False, "keysanity": False,
"door_shuffle": "basic", "door_shuffle": "basic",
"intensity": 2,
"experimental": False, "experimental": False,
"dungeon_counters": "default", "dungeon_counters": "default",

View File

@@ -35,6 +35,12 @@ def link_doors(world, player):
for ent, ext in ladders: for ent, ext in ladders:
connect_two_way(world, ent, ext, player) connect_two_way(world, ent, ext, player)
if world.intensity[player] < 2:
for entrance, ext in open_edges:
connect_two_way(world, entrance, ext, player)
for entrance, ext in straight_staircases:
connect_two_way(world, entrance, ext, player)
choose_portals(world, player) choose_portals(world, player)
if world.doorShuffle[player] == 'vanilla': if world.doorShuffle[player] == 'vanilla':
@@ -52,18 +58,8 @@ def link_doors(world, player):
connect_one_way(world, ent, ext, player) connect_one_way(world, ent, ext, player)
vanilla_key_logic(world, player) vanilla_key_logic(world, player)
elif world.doorShuffle[player] == 'basic': elif world.doorShuffle[player] == 'basic':
if not world.experimental[player]:
for entrance, ext in open_edges:
connect_two_way(world, entrance, ext, player)
for entrance, ext in straight_staircases:
connect_two_way(world, entrance, ext, player)
within_dungeon(world, player) within_dungeon(world, player)
elif world.doorShuffle[player] == 'crossed': elif world.doorShuffle[player] == 'crossed':
if not world.experimental[player]:
for entrance, ext in open_edges:
connect_two_way(world, entrance, ext, player)
for entrance, ext in straight_staircases:
connect_two_way(world, entrance, ext, player)
cross_dungeon(world, player) cross_dungeon(world, player)
else: else:
logging.getLogger('').error('Invalid door shuffle setting: %s' % world.doorShuffle[player]) logging.getLogger('').error('Invalid door shuffle setting: %s' % world.doorShuffle[player])
@@ -1268,8 +1264,8 @@ def reassign_key_doors(builder, world, player):
dp.pair = False dp.pair = False
if not found: if not found:
world.paired_doors[player].append(PairedDoor(d1.name, d2.name)) world.paired_doors[player].append(PairedDoor(d1.name, d2.name))
change_door_to_small_key(d1, world, player) change_door_to_small_key(d1, world, player)
change_door_to_small_key(d2, world, player) change_door_to_small_key(d2, world, player)
world.spoiler.set_door_type(d1.name+' <-> '+d2.name, 'Key Door', player) world.spoiler.set_door_type(d1.name+' <-> '+d2.name, 'Key Door', player)
logger.debug('Key Door: %s', d1.name+' <-> '+d2.name) logger.debug('Key Door: %s', d1.name+' <-> '+d2.name)
else: else:
@@ -1565,6 +1561,7 @@ logical_connections = [
('Desert Main Lobby Right Path', 'Desert Right Alcove'), ('Desert Main Lobby Right Path', 'Desert Right Alcove'),
('Desert Left Alcove Path', 'Desert Main Lobby'), ('Desert Left Alcove Path', 'Desert Main Lobby'),
('Desert Right Alcove Path', 'Desert Main Lobby'), ('Desert Right Alcove Path', 'Desert Main Lobby'),
('Hera Big Chest Hook Path', 'Hera Big Chest Landing'),
('Hera Big Chest Landing Exit', 'Hera 4F'), ('Hera Big Chest Landing Exit', 'Hera 4F'),
('PoD Pit Room Block Path N', 'PoD Pit Room Blocked'), ('PoD Pit Room Block Path N', 'PoD Pit Room Blocked'),
('PoD Pit Room Block Path S', 'PoD Pit Room'), ('PoD Pit Room Block Path S', 'PoD Pit Room'),

View File

@@ -271,6 +271,7 @@ def create_doors(world, player):
create_door(player, 'Hera 4F Down Stairs', Sprl).dir(Dn, 0x27, 0, HTH).ss(S, 0x62, 0xc0), create_door(player, 'Hera 4F Down Stairs', Sprl).dir(Dn, 0x27, 0, HTH).ss(S, 0x62, 0xc0),
create_door(player, 'Hera 4F Up Stairs', Sprl).dir(Up, 0x27, 1, HTH).ss(A, 0x6b, 0x2c), create_door(player, 'Hera 4F Up Stairs', Sprl).dir(Up, 0x27, 1, HTH).ss(A, 0x6b, 0x2c),
create_door(player, 'Hera 4F Holes', Hole), create_door(player, 'Hera 4F Holes', Hole),
create_door(player, 'Hera Big Chest Hook Path', Lgcl),
create_door(player, 'Hera Big Chest Landing Exit', Lgcl), create_door(player, 'Hera Big Chest Landing Exit', Lgcl),
create_door(player, 'Hera Big Chest Landing Holes', Hole), create_door(player, 'Hera Big Chest Landing Holes', Hole),
create_door(player, 'Hera 5F Down Stairs', Sprl).dir(Dn, 0x17, 1, HTH).ss(A, 0x62, 0x40), create_door(player, 'Hera 5F Down Stairs', Sprl).dir(Dn, 0x17, 1, HTH).ss(A, 0x62, 0x40),

13
Main.py
View File

@@ -24,7 +24,7 @@ from Fill import distribute_items_cutoff, distribute_items_staleness, distribute
from ItemList import generate_itempool, difficulties, fill_prizes from ItemList import generate_itempool, difficulties, fill_prizes
from Utils import output_path, parse_player_names from Utils import output_path, parse_player_names
__version__ = '0.1.0.14-u' __version__ = '0.1.0-dev'
class EnemizerError(RuntimeError): class EnemizerError(RuntimeError):
pass pass
@@ -38,7 +38,9 @@ def main(args, seed=None, fish=None):
start = time.perf_counter() start = time.perf_counter()
# initialize the world # initialize the world
world = World(args.multi, args.shuffle, args.door_shuffle, args.logic, args.mode, args.swords, args.difficulty, args.item_functionality, args.timer, args.progressive, args.goal, args.algorithm, args.accessibility, args.shuffleganon, args.retro, args.custom, args.customitemarray, args.hints) world = World(args.multi, args.shuffle, args.door_shuffle, args.logic, args.mode, args.swords,
args.difficulty, args.item_functionality, args.timer, args.progressive, args.goal, args.algorithm,
args.accessibility, args.shuffleganon, args.retro, args.custom, args.customitemarray, args.hints)
logger = logging.getLogger('') logger = logging.getLogger('')
if seed is None: if seed is None:
random.seed(None) random.seed(None)
@@ -60,6 +62,7 @@ def main(args, seed=None, fish=None):
world.enemy_health = args.enemy_health.copy() world.enemy_health = args.enemy_health.copy()
world.enemy_damage = args.enemy_damage.copy() world.enemy_damage = args.enemy_damage.copy()
world.beemizer = args.beemizer.copy() world.beemizer = args.beemizer.copy()
world.intensity = {player: random.randint(1, 3) if args.intensity[player] == 'random' else int(args.intensity[player]) for player in range(1, world.players + 1)}
world.experimental = args.experimental.copy() world.experimental = args.experimental.copy()
world.dungeon_counters = args.dungeon_counters.copy() world.dungeon_counters = args.dungeon_counters.copy()
world.fish = fish world.fish = fish
@@ -329,7 +332,9 @@ def main(args, seed=None, fish=None):
def copy_world(world): def copy_world(world):
# ToDo: Not good yet # ToDo: Not good yet
ret = World(world.players, world.shuffle, world.doorShuffle, world.logic, world.mode, world.swords, world.difficulty, world.difficulty_adjustments, world.timer, world.progressive, world.goal, world.algorithm, world.accessibility, world.shuffle_ganon, world.retro, world.custom, world.customitemarray, world.hints) ret = World(world.players, world.shuffle, world.doorShuffle, world.logic, world.mode, world.swords,
world.difficulty, world.difficulty_adjustments, world.timer, world.progressive, world.goal, world.algorithm,
world.accessibility, world.shuffle_ganon, world.retro, world.custom, world.customitemarray, world.hints)
ret.teams = world.teams ret.teams = world.teams
ret.player_names = copy.deepcopy(world.player_names) ret.player_names = copy.deepcopy(world.player_names)
ret.remote_items = world.remote_items.copy() ret.remote_items = world.remote_items.copy()
@@ -364,6 +369,8 @@ def copy_world(world):
ret.enemy_health = world.enemy_health.copy() ret.enemy_health = world.enemy_health.copy()
ret.enemy_damage = world.enemy_damage.copy() ret.enemy_damage = world.enemy_damage.copy()
ret.beemizer = world.beemizer.copy() ret.beemizer = world.beemizer.copy()
ret.intensity = world.intensity.copy()
ret.experimental = world.experimental.copy()
for player in range(1, world.players + 1): for player in range(1, world.players + 1):
if world.mode[player] != 'inverted': if world.mode[player] != 'inverted':

View File

@@ -149,6 +149,7 @@ def roll_settings(weights):
ret.shuffle = entrance_shuffle if entrance_shuffle != 'none' else 'vanilla' ret.shuffle = entrance_shuffle if entrance_shuffle != 'none' else 'vanilla'
door_shuffle = get_choice('door_shuffle') door_shuffle = get_choice('door_shuffle')
ret.door_shuffle = door_shuffle if door_shuffle != 'none' else 'vanilla' ret.door_shuffle = door_shuffle if door_shuffle != 'none' else 'vanilla'
ret.intensity = get_choice('intensity')
ret.experimental = get_choice('experimental') == 'on' ret.experimental = get_choice('experimental') == 'on'
ret.dungeon_counters = get_choice('dungeon_counters') if 'dungeon_counters' in weights else 'default' ret.dungeon_counters = get_choice('dungeon_counters') if 'dungeon_counters' in weights else 'default'
@@ -166,7 +167,7 @@ def roll_settings(weights):
ret.crystals_gt = get_choice('tower_open') ret.crystals_gt = get_choice('tower_open')
ret.crystals_ganon = get_choice('ganon_open') ret.crystals_ganon = get_choice('ganon_open')
ret.mode = get_choice('world_state') ret.mode = get_choice('world_state')
if ret.mode == 'retro': if ret.mode == 'retro':

View File

@@ -36,6 +36,16 @@ Doors are shuffled between dungeons as well.
Doors are not shuffled. Doors are not shuffled.
## Intensity
#### Level 1
Normal door and spiral staircases are shuffled
#### Level 2
Same as Level 1 plus open edges and straight staircases are shuffled.
#### Level 3 (Coming soon)
Same as Level 2 plus Dungeon Lobbies are shuffled
## Map/Compass/Small Key/Big Key shuffle (aka Keysanity) ## Map/Compass/Small Key/Big Key shuffle (aka Keysanity)
These settings allow dungeon specific items to be distributed anywhere in the world and not just in their native dungeon. These settings allow dungeon specific items to be distributed anywhere in the world and not just in their native dungeon.
@@ -75,3 +85,9 @@ Show the help message and exit.
``` ```
For specifying the door shuffle you want as above. (default: basic) For specifying the door shuffle you want as above. (default: basic)
```
--intensity
```
For specifying the door shuffle intensity level you want as above. (default: 2)

View File

@@ -343,7 +343,7 @@ def create_dungeon_regions(world, player):
create_dungeon_region(player, 'Hera Beetles', 'Tower of Hera', None, ['Hera Beetles Down Stairs', 'Hera Beetles WS', 'Hera Beetles Holes']), create_dungeon_region(player, 'Hera Beetles', 'Tower of Hera', None, ['Hera Beetles Down Stairs', 'Hera Beetles WS', 'Hera Beetles Holes']),
create_dungeon_region(player, 'Hera Startile Corner', 'Tower of Hera', None, ['Hera Startile Corner ES', 'Hera Startile Corner NW', 'Hera Startile Corner Holes']), create_dungeon_region(player, 'Hera Startile Corner', 'Tower of Hera', None, ['Hera Startile Corner ES', 'Hera Startile Corner NW', 'Hera Startile Corner Holes']),
create_dungeon_region(player, 'Hera Startile Wide', 'Tower of Hera', None, ['Hera Startile Wide SW', 'Hera Startile Wide Up Stairs', 'Hera Startile Wide Holes']), create_dungeon_region(player, 'Hera Startile Wide', 'Tower of Hera', None, ['Hera Startile Wide SW', 'Hera Startile Wide Up Stairs', 'Hera Startile Wide Holes']),
create_dungeon_region(player, 'Hera 4F', 'Tower of Hera', ['Tower of Hera - Compass Chest'], ['Hera 4F Down Stairs', 'Hera 4F Up Stairs', 'Hera 4F Holes']), create_dungeon_region(player, 'Hera 4F', 'Tower of Hera', ['Tower of Hera - Compass Chest'], ['Hera 4F Down Stairs', 'Hera 4F Up Stairs', 'Hera Big Chest Hook Path', 'Hera 4F Holes']),
create_dungeon_region(player, 'Hera Big Chest Landing', 'Tower of Hera', ['Tower of Hera - Big Chest'], ['Hera Big Chest Landing Exit', 'Hera Big Chest Landing Holes']), create_dungeon_region(player, 'Hera Big Chest Landing', 'Tower of Hera', ['Tower of Hera - Big Chest'], ['Hera Big Chest Landing Exit', 'Hera Big Chest Landing Holes']),
create_dungeon_region(player, 'Hera 5F', 'Tower of Hera', None, ['Hera 5F Down Stairs', 'Hera 5F Up Stairs', 'Hera 5F Star Hole', 'Hera 5F Pothole Chain', 'Hera 5F Normal Holes']), create_dungeon_region(player, 'Hera 5F', 'Tower of Hera', None, ['Hera 5F Down Stairs', 'Hera 5F Up Stairs', 'Hera 5F Star Hole', 'Hera 5F Pothole Chain', 'Hera 5F Normal Holes']),
create_dungeon_region(player, 'Hera Fairies', 'Tower of Hera', None, ['Hera Fairies\' Warp']), create_dungeon_region(player, 'Hera Fairies', 'Tower of Hera', None, ['Hera Fairies\' Warp']),

12
Rom.py
View File

@@ -22,7 +22,7 @@ from EntranceShuffle import door_addresses, exit_ids
JAP10HASH = '03a63945398191337e896e5771f77173' JAP10HASH = '03a63945398191337e896e5771f77173'
RANDOMIZERBASEHASH = '150e8e5bdb52e565fa9e2172d98c31ab' RANDOMIZERBASEHASH = 'b9e578ef0af231041070bd9049a55646'
class JsonRom(object): class JsonRom(object):
@@ -602,7 +602,7 @@ def patch_rom(world, rom, player, team, enemized):
# patch doors # patch doors
if world.doorShuffle[player] == 'crossed': if world.doorShuffle[player] == 'crossed':
rom.write_byte(0x139004, 2) rom.write_byte(0x138002, 2)
for name, layout in world.key_layout[player].items(): for name, layout in world.key_layout[player].items():
offset = compass_data[name][4]//2 offset = compass_data[name][4]//2
rom.write_byte(0x13f01c+offset, layout.max_chests + layout.max_drops) rom.write_byte(0x13f01c+offset, layout.max_chests + layout.max_drops)
@@ -627,7 +627,7 @@ def patch_rom(world, rom, player, team, enemized):
if room.player == player and room.palette is not None: if room.player == player and room.palette is not None:
rom.write_byte(0x13f200+room.index, room.palette) rom.write_byte(0x13f200+room.index, room.palette)
if world.doorShuffle[player] == 'basic': if world.doorShuffle[player] == 'basic':
rom.write_byte(0x139004, 1) rom.write_byte(0x138002, 1)
for door in world.doors: for door in world.doors:
if door.dest is not None and door.player == player and door.type in [DoorType.Normal, DoorType.SpiralStairs, if door.dest is not None and door.player == player and door.type in [DoorType.Normal, DoorType.SpiralStairs,
DoorType.Open, DoorType.StraightStairs]: DoorType.Open, DoorType.StraightStairs]:
@@ -648,9 +648,11 @@ def patch_rom(world, rom, player, team, enemized):
dungeon_name = opposite_door.entrance.parent_region.dungeon.name dungeon_name = opposite_door.entrance.parent_region.dungeon.name
dungeon_id = boss_indicator[dungeon_name][0] dungeon_id = boss_indicator[dungeon_name][0]
rom.write_byte(0x13f000+dungeon_id, opposite_door.roomIndex) rom.write_byte(0x13f000+dungeon_id, opposite_door.roomIndex)
rom.write_byte(0x139006, dr_flags.value) elif not opposite_door:
rom.write_byte(0x13f000+dungeon_id, 0) # no supertile preceeding boss
rom.write_byte(0x138004, dr_flags.value)
if dr_flags & DROptions.Town_Portal and world.mode[player] == 'inverted': if dr_flags & DROptions.Town_Portal and world.mode[player] == 'inverted':
rom.write_byte(0x139008, 1) rom.write_byte(0x138006, 1)
for portal in world.dungeon_portals[player]: for portal in world.dungeon_portals[player]:
if not portal.default: if not portal.default:

View File

@@ -159,6 +159,7 @@ def global_rules(world, player):
# Tower of Hera # Tower of Hera
set_rule(world.get_location('Tower of Hera - Big Key Chest', player), lambda state: state.has_fire_source(player)) set_rule(world.get_location('Tower of Hera - Big Key Chest', player), lambda state: state.has_fire_source(player))
set_rule(world.get_entrance('Hera Big Chest Hook Path', player), lambda state: state.has('Hookshot', player))
set_defeat_dungeon_boss_rule(world.get_location('Tower of Hera - Boss', player)) set_defeat_dungeon_boss_rule(world.get_location('Tower of Hera - Boss', player))
set_defeat_dungeon_boss_rule(world.get_location('Tower of Hera - Prize', player)) set_defeat_dungeon_boss_rule(world.get_location('Tower of Hera - Prize', player))
@@ -274,7 +275,7 @@ def global_rules(world, player):
set_rule(world.get_entrance('TR Hub NE', player), lambda state: state.has('Cane of Somaria', player)) set_rule(world.get_entrance('TR Hub NE', player), lambda state: state.has('Cane of Somaria', player))
set_rule(world.get_entrance('TR Torches NW', player), lambda state: state.has('Cane of Somaria', player) and state.has('Fire Rod', player)) set_rule(world.get_entrance('TR Torches NW', player), lambda state: state.has('Cane of Somaria', player) and state.has('Fire Rod', player))
set_rule(world.get_entrance('TR Big Chest Entrance Gap', player), lambda state: state.has('Cane of Somaria', player) or state.has('Hookshot', player)) set_rule(world.get_entrance('TR Big Chest Entrance Gap', player), lambda state: state.has('Cane of Somaria', player) or state.has('Hookshot', player))
set_rule(world.get_entrance('TR Big Chest Gap', player), lambda state: state.has('Cane of Somaria', player) or state.has('Hookshot', player)) set_rule(world.get_entrance('TR Big Chest Gap', player), lambda state: state.has('Cane of Somaria', player) or state.has_Boots(player))
set_rule(world.get_entrance('TR Dark Ride Up Stairs', player), lambda state: state.has('Cane of Somaria', player)) set_rule(world.get_entrance('TR Dark Ride Up Stairs', player), lambda state: state.has('Cane of Somaria', player))
set_rule(world.get_entrance('TR Dark Ride SW', player), lambda state: state.has('Cane of Somaria', player)) set_rule(world.get_entrance('TR Dark Ride SW', player), lambda state: state.has('Cane of Somaria', player))
set_rule(world.get_entrance('TR Crystal Maze Cane Path', player), lambda state: state.has('Cane of Somaria', player)) set_rule(world.get_entrance('TR Crystal Maze Cane Path', player), lambda state: state.has('Cane of Somaria', player))

View File

@@ -14,6 +14,16 @@ incsrc drhooks.asm
;Main Code ;Main Code
org $278000 ;138000 org $278000 ;138000
db $44, $52 ;DR
DRMode:
dw 0
DRFlags:
dw 0
DRScroll:
db 0
OffsetTable:
dw -8, 8
incsrc normal.asm incsrc normal.asm
incsrc scroll.asm incsrc scroll.asm
incsrc spiral.asm incsrc spiral.asm
@@ -22,20 +32,6 @@ incsrc keydoors.asm
incsrc overrides.asm incsrc overrides.asm
incsrc edges.asm incsrc edges.asm
incsrc math.asm incsrc math.asm
warnpc $279000
; Data Section
org $279000
OffsetTable:
dw -8, 8
DRMode:
dw 0
DRFlags:
dw 0
DRScroll:
db 0
org $279030
incsrc hudadditions.asm incsrc hudadditions.asm
warnpc $279700 warnpc $279700

File diff suppressed because one or more lines are too long

View File

@@ -110,6 +110,11 @@
"vanilla" "vanilla"
] ]
}, },
"intensity": {
"choices":[
"3", "2", "1", "random"
]
},
"experimental": { "experimental": {
"action": "store_true", "action": "store_true",
"type": "bool" "type": "bool"
@@ -124,12 +129,12 @@
}, },
"crystals_ganon": { "crystals_ganon": {
"choices": [ "choices": [
7, 6, 5, 4, 3, 2, 1, 0, "random" "7", "6", "5", "4", "3", "2", "1", "0", "random"
] ]
}, },
"crystals_gt": { "crystals_gt": {
"choices": [ "choices": [
7, 6, 5, 4, 3, 2, 1, 0, "random" "7", "6", "5", "4", "3", "2", "1", "0", "random"
] ]
}, },
"openpyramid": { "openpyramid": {

View File

@@ -198,6 +198,13 @@
"Vanilla: All doors are connected the same way they were in the", "Vanilla: All doors are connected the same way they were in the",
" base game." " base game."
], ],
"intensity" : [
"Door Shuffle Intensity Level (default: %(default)s)",
"1: Shuffles normal doors and spiral staircases",
"2: And shuffles open edges and straight staircases",
"3: (Coming soon) And shuffles dungeon lobbies",
"random: Picks one of those at random"
],
"experimental": [ "Enable experimental features. (default: %(default)s)" ], "experimental": [ "Enable experimental features. (default: %(default)s)" ],
"dungeon_counters": [ "Enable dungeon chest counters. (default: %(default)s)" ], "dungeon_counters": [ "Enable dungeon chest counters. (default: %(default)s)" ],
"crystals_ganon": [ "crystals_ganon": [

View File

@@ -58,6 +58,12 @@
"randomizer.dungeon.dungeondoorshuffle.basic": "Basic", "randomizer.dungeon.dungeondoorshuffle.basic": "Basic",
"randomizer.dungeon.dungeondoorshuffle.crossed": "Crossed", "randomizer.dungeon.dungeondoorshuffle.crossed": "Crossed",
"randomizer.dungeon.dungeonintensity": "Intensity Level",
"randomizer.dungeon.dungeonintensity.1": "1: Normal Supertile and Spiral Stairs",
"randomizer.dungeon.dungeonintensity.2": "2: Open Edges and Straight Stairs",
"randomizer.dungeon.dungeonintensity.3": "3: (Coming soon) Dungeon Lobbies",
"randomizer.dungeon.dungeonintensity.random": "Random",
"randomizer.dungeon.experimental": "Enable Experimental Features", "randomizer.dungeon.experimental": "Enable Experimental Features",
"randomizer.dungeon.dungeon_counters": "Dungeon Chest Counters", "randomizer.dungeon.dungeon_counters": "Dungeon Chest Counters",

View File

@@ -9,6 +9,19 @@
"crossed" "crossed"
] ]
}, },
"dungeonintensity": {
"type": "selectbox",
"default": "2",
"options": [
"1",
"2",
"3",
"random"
],
"config": {
"width": 40
}
},
"experimental": { "type": "checkbox" }, "experimental": { "type": "checkbox" },
"dungeon_counters": { "dungeon_counters": {
"type": "selectbox", "type": "selectbox",

View File

@@ -87,6 +87,7 @@ SETTINGSTOPROCESS = {
"smallkeyshuffle": "keyshuffle", "smallkeyshuffle": "keyshuffle",
"bigkeyshuffle": "bigkeyshuffle", "bigkeyshuffle": "bigkeyshuffle",
"dungeondoorshuffle": "door_shuffle", "dungeondoorshuffle": "door_shuffle",
"dungeonintensity": "intensity",
"experimental": "experimental", "experimental": "experimental",
"dungeon_counters": "dungeon_counters" "dungeon_counters": "dungeon_counters"
}, },

View File

@@ -33,7 +33,7 @@ def make_checkbox(self, parent, label, storageVar, manager, managerAttrs):
return self return self
# Make an OptionMenu with a label and pretty option labels # Make an OptionMenu with a label and pretty option labels
def make_selectbox(self, parent, label, options, storageVar, manager, managerAttrs): def make_selectbox(self, parent, label, options, storageVar, manager, managerAttrs, config=None):
self = Frame(parent) self = Frame(parent)
labels = options labels = options
@@ -96,7 +96,7 @@ def make_selectbox(self, parent, label, options, storageVar, manager, managerAtt
else: else:
self.label.pack(side=LEFT) self.label.pack(side=LEFT)
self.selectbox.config(width=20) self.selectbox.config(width=config['width'] if config and config['width'] else 20)
idx = 0 idx = 0
default = self.selectbox.options["values"][idx] default = self.selectbox.options["values"][idx]
if managerAttrs is not None and "default" in managerAttrs: if managerAttrs is not None and "default" in managerAttrs:
@@ -166,7 +166,8 @@ def make_textbox(self, parent, label, storageVar, manager, managerAttrs):
return widget return widget
# Make a generic widget # Make a generic widget
def make_widget(self, type, parent, label, storageVar=None, manager=None, managerAttrs=dict(), options=None): def make_widget(self, type, parent, label, storageVar=None, manager=None, managerAttrs=dict(),
options=None, config=None):
widget = None widget = None
if manager is None: if manager is None:
manager = "pack" manager = "pack"
@@ -184,7 +185,7 @@ def make_widget(self, type, parent, label, storageVar=None, manager=None, manage
elif type == "selectbox": elif type == "selectbox":
if thisStorageVar is None: if thisStorageVar is None:
thisStorageVar = StringVar() thisStorageVar = StringVar()
widget = make_selectbox(self, parent, label, options, thisStorageVar, manager, managerAttrs) widget = make_selectbox(self, parent, label, options, thisStorageVar, manager, managerAttrs, config)
elif type == "spinbox": elif type == "spinbox":
if thisStorageVar is None: if thisStorageVar is None:
thisStorageVar = StringVar() thisStorageVar = StringVar()
@@ -203,13 +204,14 @@ def make_widget_from_dict(self, defn, parent):
manager = defn["manager"] if "manager" in defn else None manager = defn["manager"] if "manager" in defn else None
managerAttrs = defn["managerAttrs"] if "managerAttrs" in defn else None managerAttrs = defn["managerAttrs"] if "managerAttrs" in defn else None
options = defn["options"] if "options" in defn else None options = defn["options"] if "options" in defn else None
config = defn["config"] if "config" in defn else None
if managerAttrs is None and "default" in defn: if managerAttrs is None and "default" in defn:
managerAttrs = {} managerAttrs = {}
if "default" in defn: if "default" in defn:
managerAttrs["default"] = defn["default"] managerAttrs["default"] = defn["default"]
widget = make_widget(self, type, parent, label, None, manager, managerAttrs, options) widget = make_widget(self, type, parent, label, None, manager, managerAttrs, options, config)
widget.type = type widget.type = type
return widget return widget