Merged in DR v0.4.0.11
This commit is contained in:
@@ -139,7 +139,7 @@ class World(object):
|
|||||||
set_player_attr('treasure_hunt_total', 0)
|
set_player_attr('treasure_hunt_total', 0)
|
||||||
set_player_attr('potshuffle', False)
|
set_player_attr('potshuffle', False)
|
||||||
set_player_attr('pot_contents', None)
|
set_player_attr('pot_contents', None)
|
||||||
set_player_attr('fakeboots', False)
|
set_player_attr('pseudoboots', False)
|
||||||
|
|
||||||
set_player_attr('shopsanity', False)
|
set_player_attr('shopsanity', False)
|
||||||
set_player_attr('keydropshuffle', False)
|
set_player_attr('keydropshuffle', False)
|
||||||
|
|||||||
4
CLI.py
4
CLI.py
@@ -98,7 +98,7 @@ def parse_cli(argv, no_defaults=False):
|
|||||||
'shuffle', 'door_shuffle', 'intensity', 'crystals_ganon', 'crystals_gt', 'openpyramid',
|
'shuffle', 'door_shuffle', 'intensity', 'crystals_ganon', 'crystals_gt', 'openpyramid',
|
||||||
'mapshuffle', 'compassshuffle', 'keyshuffle', 'bigkeyshuffle', 'startinventory',
|
'mapshuffle', 'compassshuffle', 'keyshuffle', 'bigkeyshuffle', 'startinventory',
|
||||||
'triforce_pool_min', 'triforce_pool_max', 'triforce_goal_min', 'triforce_goal_max',
|
'triforce_pool_min', 'triforce_pool_max', 'triforce_goal_min', 'triforce_goal_max',
|
||||||
'triforce_min_difference', 'triforce_goal', 'triforce_pool', 'shufflelinks', 'fakeboots',
|
'triforce_min_difference', 'triforce_goal', 'triforce_pool', 'shufflelinks', 'pseudoboots',
|
||||||
'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',
|
||||||
'ow_palettes', 'uw_palettes', 'sprite', 'disablemusic', 'quickswap', 'fastmenu', 'heartcolor', 'heartbeep',
|
'ow_palettes', 'uw_palettes', 'sprite', 'disablemusic', 'quickswap', 'fastmenu', 'heartcolor', 'heartbeep',
|
||||||
@@ -149,7 +149,7 @@ def parse_settings():
|
|||||||
"ow_fluteshuffle": "vanilla",
|
"ow_fluteshuffle": "vanilla",
|
||||||
"shuffle": "vanilla",
|
"shuffle": "vanilla",
|
||||||
"shufflelinks": False,
|
"shufflelinks": False,
|
||||||
"fakeboots": False,
|
"pseudoboots": False,
|
||||||
|
|
||||||
"shufflepots": False,
|
"shufflepots": False,
|
||||||
"shuffleenemies": "none",
|
"shuffleenemies": "none",
|
||||||
|
|||||||
@@ -100,7 +100,7 @@ def link_doors_main(world, player):
|
|||||||
analyze_portals(world, player)
|
analyze_portals(world, player)
|
||||||
for portal in world.dungeon_portals[player]:
|
for portal in world.dungeon_portals[player]:
|
||||||
connect_portal(portal, world, player)
|
connect_portal(portal, world, player)
|
||||||
|
if not world.doorShuffle[player] == 'vanilla':
|
||||||
fix_big_key_doors_with_ugly_smalls(world, player)
|
fix_big_key_doors_with_ugly_smalls(world, player)
|
||||||
if world.doorShuffle[player] == 'vanilla':
|
if world.doorShuffle[player] == 'vanilla':
|
||||||
for entrance, ext in open_edges:
|
for entrance, ext in open_edges:
|
||||||
@@ -1678,7 +1678,7 @@ def change_door_to_small_key(d, world, player):
|
|||||||
def smooth_door_pairs(world, player):
|
def smooth_door_pairs(world, player):
|
||||||
all_doors = [x for x in world.doors if x.player == player]
|
all_doors = [x for x in world.doors if x.player == player]
|
||||||
skip = set()
|
skip = set()
|
||||||
bd_candidates, dashable_counts, bombable_counts = defaultdict(list), defaultdict(int), defaultdict(int)
|
bd_candidates = defaultdict(list)
|
||||||
for door in all_doors:
|
for door in all_doors:
|
||||||
if door.type in [DoorType.Normal, DoorType.Interior] and door not in skip and not door.entranceFlag:
|
if door.type in [DoorType.Normal, DoorType.Interior] and door not in skip and not door.entranceFlag:
|
||||||
partner = door.dest
|
partner = door.dest
|
||||||
@@ -1704,30 +1704,19 @@ def smooth_door_pairs(world, player):
|
|||||||
remove_pair(door, world, player)
|
remove_pair(door, world, player)
|
||||||
if type_b == DoorKind.SmallKey:
|
if type_b == DoorKind.SmallKey:
|
||||||
remove_pair(door, world, player)
|
remove_pair(door, world, player)
|
||||||
elif type_a in [DoorKind.Bombable, DoorKind.Dashable] or type_b in [DoorKind.Bombable, DoorKind.Dashable]:
|
|
||||||
if valid_pair:
|
|
||||||
new_type = type_a
|
|
||||||
if type_a != type_b:
|
|
||||||
new_type = DoorKind.Dashable if type_a == DoorKind.Dashable or type_b == DoorKind.Dashable else DoorKind.Bombable
|
|
||||||
if type_a != new_type:
|
|
||||||
room_a.change(door.doorListPos, new_type)
|
|
||||||
if type_b != new_type:
|
|
||||||
room_b.change(partner.doorListPos, new_type)
|
|
||||||
add_pair(door, partner, world, player)
|
|
||||||
spoiler_type = 'Bomb Door' if new_type == DoorKind.Bombable else 'Dash Door'
|
|
||||||
world.spoiler.set_door_type(door.name + ' <-> ' + partner.name, spoiler_type, player)
|
|
||||||
counter = bombable_counts if new_type == DoorKind.Bombable else dashable_counts
|
|
||||||
counter[door.entrance.parent_region.dungeon] += 1
|
|
||||||
else:
|
else:
|
||||||
|
if valid_pair:
|
||||||
|
bd_candidates[door.entrance.parent_region.dungeon].append(door)
|
||||||
|
elif type_a in [DoorKind.Bombable, DoorKind.Dashable] or type_b in [DoorKind.Bombable, DoorKind.Dashable]:
|
||||||
if type_a in [DoorKind.Bombable, DoorKind.Dashable]:
|
if type_a in [DoorKind.Bombable, DoorKind.Dashable]:
|
||||||
room_a.change(door.doorListPos, DoorKind.Normal)
|
room_a.change(door.doorListPos, DoorKind.Normal)
|
||||||
remove_pair(door, world, player)
|
remove_pair(door, world, player)
|
||||||
elif type_b in [DoorKind.Bombable, DoorKind.Dashable]:
|
else:
|
||||||
room_b.change(partner.doorListPos, DoorKind.Normal)
|
room_b.change(partner.doorListPos, DoorKind.Normal)
|
||||||
remove_pair(partner, world, player)
|
remove_pair(partner, world, player)
|
||||||
elif valid_pair and type_a != DoorKind.SmallKey and type_b != DoorKind.SmallKey:
|
elif valid_pair and type_a != DoorKind.SmallKey and type_b != DoorKind.SmallKey:
|
||||||
bd_candidates[door.entrance.parent_region.dungeon].append(door)
|
bd_candidates[door.entrance.parent_region.dungeon].append(door)
|
||||||
shuffle_bombable_dashable(bd_candidates, bombable_counts, dashable_counts, world, player)
|
shuffle_bombable_dashable(bd_candidates, world, player)
|
||||||
world.paired_doors[player] = [x for x in world.paired_doors[player] if x.pair or x.original]
|
world.paired_doors[player] = [x for x in world.paired_doors[player] if x.pair or x.original]
|
||||||
|
|
||||||
|
|
||||||
@@ -1764,15 +1753,15 @@ def stateful_door(door, kind):
|
|||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
def shuffle_bombable_dashable(bd_candidates, bombable_counts, dashable_counts, world, player):
|
def shuffle_bombable_dashable(bd_candidates, world, player):
|
||||||
if world.doorShuffle[player] == 'basic':
|
if world.doorShuffle[player] == 'basic':
|
||||||
for dungeon, candidates in bd_candidates.items():
|
for dungeon, candidates in bd_candidates.items():
|
||||||
diff = bomb_dash_counts[dungeon.name][1] - dashable_counts[dungeon]
|
diff = bomb_dash_counts[dungeon.name][1]
|
||||||
if diff > 0:
|
if diff > 0:
|
||||||
for chosen in random.sample(candidates, min(diff, len(candidates))):
|
for chosen in random.sample(candidates, min(diff, len(candidates))):
|
||||||
change_pair_type(chosen, DoorKind.Dashable, world, player)
|
change_pair_type(chosen, DoorKind.Dashable, world, player)
|
||||||
candidates.remove(chosen)
|
candidates.remove(chosen)
|
||||||
diff = bomb_dash_counts[dungeon.name][0] - bombable_counts[dungeon]
|
diff = bomb_dash_counts[dungeon.name][0]
|
||||||
if diff > 0:
|
if diff > 0:
|
||||||
for chosen in random.sample(candidates, min(diff, len(candidates))):
|
for chosen in random.sample(candidates, min(diff, len(candidates))):
|
||||||
change_pair_type(chosen, DoorKind.Bombable, world, player)
|
change_pair_type(chosen, DoorKind.Bombable, world, player)
|
||||||
@@ -1781,14 +1770,10 @@ def shuffle_bombable_dashable(bd_candidates, bombable_counts, dashable_counts, w
|
|||||||
remove_pair_type_if_present(excluded, world, player)
|
remove_pair_type_if_present(excluded, world, player)
|
||||||
elif world.doorShuffle[player] == 'crossed':
|
elif world.doorShuffle[player] == 'crossed':
|
||||||
all_candidates = sum(bd_candidates.values(), [])
|
all_candidates = sum(bd_candidates.values(), [])
|
||||||
all_bomb_counts = sum(bombable_counts.values())
|
for chosen in random.sample(all_candidates, min(8, len(all_candidates))):
|
||||||
all_dash_counts = sum(dashable_counts.values())
|
|
||||||
if all_dash_counts < 8:
|
|
||||||
for chosen in random.sample(all_candidates, min(8 - all_dash_counts, len(all_candidates))):
|
|
||||||
change_pair_type(chosen, DoorKind.Dashable, world, player)
|
change_pair_type(chosen, DoorKind.Dashable, world, player)
|
||||||
all_candidates.remove(chosen)
|
all_candidates.remove(chosen)
|
||||||
if all_bomb_counts < 12:
|
for chosen in random.sample(all_candidates, min(12, len(all_candidates))):
|
||||||
for chosen in random.sample(all_candidates, min(12 - all_bomb_counts, len(all_candidates))):
|
|
||||||
change_pair_type(chosen, DoorKind.Bombable, world, player)
|
change_pair_type(chosen, DoorKind.Bombable, world, player)
|
||||||
all_candidates.remove(chosen)
|
all_candidates.remove(chosen)
|
||||||
for excluded in all_candidates:
|
for excluded in all_candidates:
|
||||||
|
|||||||
4
Main.py
4
Main.py
@@ -28,7 +28,7 @@ from Fill import sell_potions, sell_keys, balance_multiworld_progression, balanc
|
|||||||
from ItemList import generate_itempool, difficulties, fill_prizes, customize_shops
|
from ItemList import generate_itempool, difficulties, fill_prizes, customize_shops
|
||||||
from Utils import output_path, parse_player_names
|
from Utils import output_path, parse_player_names
|
||||||
|
|
||||||
__version__ = '0.4.0.9-u'
|
__version__ = '0.4.0.11u'
|
||||||
|
|
||||||
|
|
||||||
class EnemizerError(RuntimeError):
|
class EnemizerError(RuntimeError):
|
||||||
@@ -93,7 +93,7 @@ def main(args, seed=None, fish=None):
|
|||||||
world.treasure_hunt_count = args.triforce_goal.copy()
|
world.treasure_hunt_count = args.triforce_goal.copy()
|
||||||
world.treasure_hunt_total = args.triforce_pool.copy()
|
world.treasure_hunt_total = args.triforce_pool.copy()
|
||||||
world.shufflelinks = args.shufflelinks.copy()
|
world.shufflelinks = args.shufflelinks.copy()
|
||||||
world.fakeboots = args.fakeboots.copy()
|
world.pseudoboots = args.pseudoboots.copy()
|
||||||
|
|
||||||
world.rom_seeds = {player: random.randint(0, 999999999) for player in range(1, world.players + 1)}
|
world.rom_seeds = {player: random.randint(0, 999999999) for player in range(1, world.players + 1)}
|
||||||
|
|
||||||
|
|||||||
@@ -150,7 +150,7 @@ def roll_settings(weights):
|
|||||||
ret.dungeon_counters = 'pickup' if ret.door_shuffle != 'vanilla' or ret.compassshuffle == 'on' else 'off'
|
ret.dungeon_counters = 'pickup' if ret.door_shuffle != 'vanilla' or ret.compassshuffle == 'on' else 'off'
|
||||||
|
|
||||||
ret.shufflelinks = get_choice('shufflelinks') == 'on'
|
ret.shufflelinks = get_choice('shufflelinks') == 'on'
|
||||||
ret.fakeboots = get_choice('fakeboots') == 'on'
|
ret.pseudoboots = get_choice('pseudoboots') == 'on'
|
||||||
ret.shopsanity = get_choice('shopsanity') == 'on'
|
ret.shopsanity = get_choice('shopsanity') == 'on'
|
||||||
ret.keydropshuffle = get_choice('keydropshuffle') == 'on'
|
ret.keydropshuffle = get_choice('keydropshuffle') == 'on'
|
||||||
ret.mixed_travel = get_choice('mixed_travel') if 'mixed_travel' in weights else 'prevent'
|
ret.mixed_travel = get_choice('mixed_travel') if 'mixed_travel' in weights else 'prevent'
|
||||||
|
|||||||
@@ -12,8 +12,22 @@ Links house can now be shuffled in different ER settings. It will be limited to
|
|||||||
|
|
||||||
Thanks to qadan, cheuer, & compiling
|
Thanks to qadan, cheuer, & compiling
|
||||||
|
|
||||||
|
## Pseudo Boots
|
||||||
|
|
||||||
|
Thanks to Bonta. You can now start with pseudo boots that let you move fast, but have no other logical uses (bonking open things, hovering, etc)
|
||||||
|
|
||||||
|
## Pendant/Crystal Indicator
|
||||||
|
|
||||||
|
For accessibility, you now get a C or P indicator to the left of the magic bar on the HUD when instead a Crystal or Pendant. Requires ownership of the map of that dungeon for display. Thanks to kan.
|
||||||
|
|
||||||
# Bug Fixes and Notes.
|
# Bug Fixes and Notes.
|
||||||
|
|
||||||
|
* 0.4.0.11
|
||||||
|
* Some minor base rom fixes
|
||||||
|
* Improved distribution of bombable/dashable doors
|
||||||
|
* 0.4.0.10
|
||||||
|
* Renamed to pseudoboots
|
||||||
|
* Some release note updates
|
||||||
* 0.4.0.9
|
* 0.4.0.9
|
||||||
* Fixes for stats and P/C indicator (thanks Kara)
|
* Fixes for stats and P/C indicator (thanks Kara)
|
||||||
* Swamp lobby fixes (thanks Catobat)
|
* Swamp lobby fixes (thanks Catobat)
|
||||||
@@ -38,7 +52,7 @@ Thanks to qadan, cheuer, & compiling
|
|||||||
* Chest turn tracking (not yet in credits)
|
* Chest turn tracking (not yet in credits)
|
||||||
* Damaged and magic stats in credits (gt bk removed)
|
* Damaged and magic stats in credits (gt bk removed)
|
||||||
* Fix for infinite bombs
|
* Fix for infinite bombs
|
||||||
* Fake boots option
|
* Pseudo boots option
|
||||||
* Always allowed medallions for swordless (no option yet)
|
* Always allowed medallions for swordless (no option yet)
|
||||||
* 0.4.0.7
|
* 0.4.0.7
|
||||||
* Reduce flashing option added
|
* Reduce flashing option added
|
||||||
|
|||||||
4
Rom.py
4
Rom.py
@@ -31,7 +31,7 @@ from OverworldShuffle import default_flute_connections, flute_data
|
|||||||
|
|
||||||
|
|
||||||
JAP10HASH = '03a63945398191337e896e5771f77173'
|
JAP10HASH = '03a63945398191337e896e5771f77173'
|
||||||
RANDOMIZERBASEHASH = '1dc1961e57d4e588a262fa706de6c753'
|
RANDOMIZERBASEHASH = '487a04cf965bb89636f9b1621dd606d1'
|
||||||
|
|
||||||
|
|
||||||
class JsonRom(object):
|
class JsonRom(object):
|
||||||
@@ -1248,7 +1248,7 @@ def patch_rom(world, rom, player, team, enemized, is_mystery=False):
|
|||||||
rom.write_byte(0x18017E, 0x01) # Fairy fountains only trade in bottles
|
rom.write_byte(0x18017E, 0x01) # Fairy fountains only trade in bottles
|
||||||
|
|
||||||
# Starting equipment
|
# Starting equipment
|
||||||
if world.fakeboots[player]:
|
if world.pseudoboots[player]:
|
||||||
rom.write_byte(0x18008E, 0x01)
|
rom.write_byte(0x18008E, 0x01)
|
||||||
|
|
||||||
equip = [0] * (0x340 + 0x4F)
|
equip = [0] * (0x340 + 0x4F)
|
||||||
|
|||||||
@@ -580,8 +580,8 @@ dw $00bc, $00a2, $00a3, $00c2, $001a, $0049, $0014, $008c
|
|||||||
; Ice Many Pots, Swamp Waterfall, GT Gauntlet 3, Eastern Push Block, Eastern Courtyard, Eastern Map Valley
|
; Ice Many Pots, Swamp Waterfall, GT Gauntlet 3, Eastern Push Block, Eastern Courtyard, Eastern Map Valley
|
||||||
; Eastern Cannonball, HC East Hall
|
; Eastern Cannonball, HC East Hall
|
||||||
dw $009f, $0066, $005d, $00a8, $00a9, $00aa, $00b9, $0052
|
dw $009f, $0066, $005d, $00a8, $00a9, $00aa, $00b9, $0052
|
||||||
; HC West Hall, TR Dash Bridge, TR Hub, Pod Arena, GT Petting Zoo
|
; HC West Hall, TR Dash Bridge, TR Hub, Pod Arena, GT Petting Zoo, Ice Spike Cross
|
||||||
dw $0050, $00c5, $00c6, $0009, $0003, $002a, $007d
|
dw $0050, $00c5, $00c6, $0009, $0003, $002a, $007d, $005e
|
||||||
dw $ffff
|
dw $ffff
|
||||||
|
|
||||||
; dungeon tables
|
; dungeon tables
|
||||||
|
|||||||
Binary file not shown.
@@ -354,7 +354,7 @@
|
|||||||
"action": "store_true",
|
"action": "store_true",
|
||||||
"type": "bool"
|
"type": "bool"
|
||||||
},
|
},
|
||||||
"fakeboots": {
|
"pseudoboots": {
|
||||||
"action": "store_true",
|
"action": "store_true",
|
||||||
"type": "bool"
|
"type": "bool"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -290,7 +290,7 @@
|
|||||||
"Keys are universal, shooting arrows costs rupees,",
|
"Keys are universal, shooting arrows costs rupees,",
|
||||||
"and a few other little things make this more like Zelda-1. (default: %(default)s)"
|
"and a few other little things make this more like Zelda-1. (default: %(default)s)"
|
||||||
],
|
],
|
||||||
"fakeboots": [ " Players starts with fake boots that allow dashing but no item checks (default: %(default)s"],
|
"pseudoboots": [ " Players starts with pseudo boots that allow dashing but no item checks (default: %(default)s"],
|
||||||
"startinventory": [ "Specifies a list of items that will be in your starting inventory (separated by commas). (default: %(default)s)" ],
|
"startinventory": [ "Specifies a list of items that will be in your starting inventory (separated by commas). (default: %(default)s)" ],
|
||||||
"usestartinventory": [ "Toggle usage of Starting Inventory." ],
|
"usestartinventory": [ "Toggle usage of Starting Inventory." ],
|
||||||
"custom": [ "Not supported." ],
|
"custom": [ "Not supported." ],
|
||||||
|
|||||||
@@ -206,7 +206,7 @@
|
|||||||
|
|
||||||
"randomizer.item.hints": "Include Helpful Hints",
|
"randomizer.item.hints": "Include Helpful Hints",
|
||||||
"randomizer.item.retro": "Retro mode (universal keys)",
|
"randomizer.item.retro": "Retro mode (universal keys)",
|
||||||
"randomizer.item.fakeboots": "Start with Fake Boots",
|
"randomizer.item.pseudoboots": "Start with Pseudo Boots",
|
||||||
|
|
||||||
"randomizer.item.worldstate": "World State",
|
"randomizer.item.worldstate": "World State",
|
||||||
"randomizer.item.worldstate.standard": "Standard",
|
"randomizer.item.worldstate.standard": "Standard",
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
"hints": {
|
"hints": {
|
||||||
"type": "checkbox"
|
"type": "checkbox"
|
||||||
},
|
},
|
||||||
"fakeboots": { "type": "checkbox" }
|
"pseudoboots": { "type": "checkbox" }
|
||||||
},
|
},
|
||||||
"leftItemFrame": {
|
"leftItemFrame": {
|
||||||
"worldstate": {
|
"worldstate": {
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ SETTINGSTOPROCESS = {
|
|||||||
"hints": "hints",
|
"hints": "hints",
|
||||||
"retro": "retro",
|
"retro": "retro",
|
||||||
"shopsanity": "shopsanity",
|
"shopsanity": "shopsanity",
|
||||||
"fakeboots": "fakeboots",
|
"pseudoboots": "pseudoboots",
|
||||||
"worldstate": "mode",
|
"worldstate": "mode",
|
||||||
"logiclevel": "logic",
|
"logiclevel": "logic",
|
||||||
"goal": "goal",
|
"goal": "goal",
|
||||||
|
|||||||
Reference in New Issue
Block a user