Merge pull request #122 from StructuralMike/DoorDevUnstable

Change the bomblogic-CLI to bombbags and add it to the example mystery yaml
This commit is contained in:
aerinon
2021-08-12 13:53:58 -06:00
committed by GitHub
14 changed files with 41 additions and 38 deletions

View File

@@ -114,7 +114,7 @@ class World(object):
set_player_attr('compassshuffle', False)
set_player_attr('keyshuffle', False)
set_player_attr('bigkeyshuffle', False)
set_player_attr('bomblogic', False)
set_player_attr('bombbag', False)
set_player_attr('difficulty_requirements', None)
set_player_attr('boss_shuffle', 'none')
set_player_attr('enemy_shuffle', 'none')
@@ -687,7 +687,7 @@ class CollectionState(object):
# In the future, this can be used to check if the player starts without bombs
def can_use_bombs(self, player):
return (not self.world.bomblogic[player] or self.has('Bomb Upgrade (+10)', player))
return (not self.world.bombbag[player] or self.has('Bomb Upgrade (+10)', player))
def can_hit_crystal(self, player):
return (self.can_use_bombs(player)
@@ -2014,7 +2014,7 @@ class Spoiler(object):
'logic': self.world.logic,
'mode': self.world.mode,
'retro': self.world.retro,
'bomblogic': self.world.bomblogic,
'bombbag': self.world.bombbag,
'weapons': self.world.swords,
'goal': self.world.goal,
'shuffle': self.world.shuffle,
@@ -2113,7 +2113,7 @@ class Spoiler(object):
outfile.write('Experimental: %s\n' % ('Yes' if self.metadata['experimental'][player] else 'No'))
outfile.write('Key Drops shuffled: %s\n' % ('Yes' if self.metadata['keydropshuffle'][player] else 'No'))
outfile.write(f"Shopsanity: {'Yes' if self.metadata['shopsanity'][player] else 'No'}\n")
outfile.write('Bomblogic: %s\n' % ('Yes' if self.metadata['bomblogic'][player] else 'No'))
outfile.write('Bombbag: %s\n' % ('Yes' if self.metadata['bombbag'][player] else 'No'))
if self.doors:
outfile.write('\n\nDoors:\n\n')
outfile.write('\n'.join(

4
CLI.py
View File

@@ -96,7 +96,7 @@ def parse_cli(argv, no_defaults=False):
for name in ['logic', 'mode', 'swords', 'goal', 'difficulty', 'item_functionality',
'shuffle', 'door_shuffle', 'intensity', 'crystals_ganon', 'crystals_gt', 'openpyramid',
'mapshuffle', 'compassshuffle', 'keyshuffle', 'bigkeyshuffle', 'startinventory',
'bomblogic',
'bombbag',
'triforce_pool_min', 'triforce_pool_max', 'triforce_goal_min', 'triforce_goal_max',
'triforce_min_difference', 'triforce_goal', 'triforce_pool', 'shufflelinks', 'pseudoboots',
'retro', 'accessibility', 'hints', 'beemizer', 'experimental', 'dungeon_counters',
@@ -127,7 +127,7 @@ def parse_settings():
settings = {
"lang": "en",
"retro": False,
"bomblogic": False,
"bombbag": False,
"mode": "open",
"logic": "noglitches",
"goal": "ganon",

View File

@@ -37,7 +37,7 @@ Difficulty = namedtuple('Difficulty',
['baseitems', 'bottles', 'bottle_count', 'same_bottle', 'progressiveshield',
'basicshield', 'progressivearmor', 'basicarmor', 'swordless',
'progressivesword', 'basicsword', 'basicbow', 'timedohko', 'timedother',
'retro', 'bomblogic',
'retro', 'bombbag',
'extras', 'progressive_sword_limit', 'progressive_shield_limit',
'progressive_armor_limit', 'progressive_bottle_limit',
'progressive_bow_limit', 'heart_piece_limit', 'boss_heart_container_limit'])
@@ -61,7 +61,7 @@ difficulties = {
timedohko = ['Green Clock'] * 25,
timedother = ['Green Clock'] * 20 + ['Blue Clock'] * 10 + ['Red Clock'] * 10,
retro = ['Small Key (Universal)'] * 18 + ['Rupees (20)'] * 10,
bomblogic = ['Bomb Upgrade (+10)'] * 2,
bombbag = ['Bomb Upgrade (+10)'] * 2,
extras = [normalfirst15extra, normalsecond15extra, normalthird10extra, normalfourth5extra, normalfinal25extra],
progressive_sword_limit = 4,
progressive_shield_limit = 3,
@@ -87,7 +87,7 @@ difficulties = {
timedohko = ['Green Clock'] * 25,
timedother = ['Green Clock'] * 20 + ['Blue Clock'] * 10 + ['Red Clock'] * 10,
retro = ['Small Key (Universal)'] * 13 + ['Rupees (5)'] * 15,
bomblogic = ['Bomb Upgrade (+10)'] * 2,
bombbag = ['Bomb Upgrade (+10)'] * 2,
extras = [normalfirst15extra, normalsecond15extra, normalthird10extra, normalfourth5extra, normalfinal25extra],
progressive_sword_limit = 3,
progressive_shield_limit = 2,
@@ -113,7 +113,7 @@ difficulties = {
timedohko = ['Green Clock'] * 20 + ['Red Clock'] * 5,
timedother = ['Green Clock'] * 20 + ['Blue Clock'] * 10 + ['Red Clock'] * 10,
retro = ['Small Key (Universal)'] * 13 + ['Rupees (5)'] * 15,
bomblogic = ['Bomb Upgrade (+10)'] * 2,
bombbag = ['Bomb Upgrade (+10)'] * 2,
extras = [normalfirst15extra, normalsecond15extra, normalthird10extra, normalfourth5extra, normalfinal25extra],
progressive_sword_limit = 2,
progressive_shield_limit = 1,
@@ -254,10 +254,10 @@ def generate_itempool(world, player):
# set up item pool
if world.custom:
(pool, placed_items, precollected_items, clock_mode, treasure_hunt_count, treasure_hunt_icon, lamps_needed_for_dark_rooms) = make_custom_item_pool(world.progressive, world.shuffle[player], world.difficulty[player], world.timer, world.goal[player], world.mode[player], world.swords[player], world.retro[player], world.bomblogic[player], world.customitemarray)
(pool, placed_items, precollected_items, clock_mode, treasure_hunt_count, treasure_hunt_icon, lamps_needed_for_dark_rooms) = make_custom_item_pool(world.progressive, world.shuffle[player], world.difficulty[player], world.timer, world.goal[player], world.mode[player], world.swords[player], world.retro[player], world.bombbag[player], world.customitemarray)
world.rupoor_cost = min(world.customitemarray[player]["rupoorcost"], 9999)
else:
(pool, placed_items, precollected_items, clock_mode, lamps_needed_for_dark_rooms) = get_pool_core(world.progressive, world.shuffle[player], world.difficulty[player], world.treasure_hunt_total[player], world.timer, world.goal[player], world.mode[player], world.swords[player], world.retro[player], world.bomblogic[player], world.doorShuffle[player], world.logic[player])
(pool, placed_items, precollected_items, clock_mode, lamps_needed_for_dark_rooms) = get_pool_core(world.progressive, world.shuffle[player], world.difficulty[player], world.treasure_hunt_total[player], world.timer, world.goal[player], world.mode[player], world.swords[player], world.retro[player], world.bombbag[player], world.doorShuffle[player], world.logic[player])
if player in world.pool_adjustment.keys():
amt = world.pool_adjustment[player]
@@ -287,7 +287,7 @@ def generate_itempool(world, player):
if item in ['Hammer', 'Fire Rod', 'Cane of Somaria', 'Cane of Byrna']:
if item not in possible_weapons:
possible_weapons.append(item)
if not world.bomblogic[player] and item in ['Bombs (10)']:
if not world.bombbag[player] and item in ['Bombs (10)']:
if item not in possible_weapons and world.doorShuffle[player] != 'crossed':
possible_weapons.append(item)
starting_weapon = random.choice(possible_weapons)
@@ -318,7 +318,7 @@ def generate_itempool(world, player):
p_item = next(item for item in items if item.name == potion and item.player == player)
p_item.priority = True # don't beemize one of each potion
if world.bomblogic[player]:
if world.bombbag[player]:
for item in items:
if item.name == 'Bomb Upgrade (+10)' and item.player == player:
item.advancement = True
@@ -528,7 +528,7 @@ def set_up_shops(world, player):
rss.locked = True
cap_shop = world.get_region('Capacity Upgrade', player).shop
cap_shop.inventory[1] = None # remove arrow capacity upgrades in retro
if world.bomblogic[player]:
if world.bombbag[player]:
if world.shopsanity[player]:
removals = [item for item in world.itempool if item.name == 'Bomb Upgrade (+5)' and item.player == player]
for remove in removals:
@@ -536,7 +536,7 @@ def set_up_shops(world, player):
world.itempool.append(ItemFactory('Rupees (50)', player)) # replace the bomb upgrade
else:
cap_shop = world.get_region('Capacity Upgrade', player).shop
cap_shop.inventory[0] = cap_shop.inventory[1] # remove bomb capacity upgrades in bomblogic
cap_shop.inventory[0] = cap_shop.inventory[1] # remove bomb capacity upgrades in bombbag
def customize_shops(world, player):
@@ -578,7 +578,7 @@ def customize_shops(world, player):
shop.shopkeeper_config = shopkeeper
# handle capacity upgrades - randomly choose a bomb bunch or arrow bunch to become capacity upgrades
if world.difficulty[player] == 'normal':
if not found_bomb_upgrade and len(possible_replacements) > 0 and not world.bomblogic[player]:
if not found_bomb_upgrade and len(possible_replacements) > 0 and not world.bombbag[player]:
choices = []
for shop, idx, loc, item in possible_replacements:
if item.name in ['Bombs (3)', 'Bombs (10)']:
@@ -726,7 +726,7 @@ rupee_chart = {'Rupee (1)': 1, 'Rupees (5)': 5, 'Rupees (20)': 20, 'Rupees (50)'
'Rupees (100)': 100, 'Rupees (300)': 300}
def get_pool_core(progressive, shuffle, difficulty, treasure_hunt_total, timer, goal, mode, swords, retro, bomblogic, door_shuffle, logic):
def get_pool_core(progressive, shuffle, difficulty, treasure_hunt_total, timer, goal, mode, swords, retro, bombbag, door_shuffle, logic):
pool = []
placed_items = {}
precollected_items = []
@@ -773,10 +773,10 @@ def get_pool_core(progressive, shuffle, difficulty, treasure_hunt_total, timer,
diff = difficulties[difficulty]
pool.extend(diff.baseitems)
if bomblogic:
if bombbag:
pool = [item.replace('Bomb Upgrade (+5)','Rupees (5)') for item in pool]
pool = [item.replace('Bomb Upgrade (+10)','Rupees (5)') for item in pool]
pool.extend(diff.bomblogic)
pool.extend(diff.bombbag)
# expert+ difficulties produce the same contents for
# all bottles, since only one bottle is available
@@ -872,7 +872,7 @@ def get_pool_core(progressive, shuffle, difficulty, treasure_hunt_total, timer,
pool.extend(['Small Key (Universal)'])
return (pool, placed_items, precollected_items, clock_mode, lamps_needed_for_dark_rooms)
def make_custom_item_pool(progressive, shuffle, difficulty, timer, goal, mode, swords, retro, bomblogic, customitemarray):
def make_custom_item_pool(progressive, shuffle, difficulty, timer, goal, mode, swords, retro, bombbag, customitemarray):
if isinstance(customitemarray,dict) and 1 in customitemarray:
customitemarray = customitemarray[1]
pool = []
@@ -988,9 +988,9 @@ def test():
for shuffle in ['full', 'insanity_legacy']:
for logic in ['noglitches', 'minorglitches', 'owglitches', 'nologic']:
for retro in [True, False]:
for bomblogic in [True, False]:
for bombbag in [True, False]:
for door_shuffle in ['basic', 'crossed', 'vanilla']:
out = get_pool_core(progressive, shuffle, difficulty, 30, timer, goal, mode, swords, retro, bomblogic, door_shuffle, logic)
out = get_pool_core(progressive, shuffle, difficulty, 30, timer, goal, mode, swords, retro, bombbag, door_shuffle, logic)
count = len(out[0]) + len(out[1])
correct_count = total_items_to_place
@@ -1000,7 +1000,7 @@ def test():
if retro:
correct_count += 28
try:
assert count == correct_count, "expected {0} items but found {1} items for {2}".format(correct_count, count, (progressive, shuffle, difficulty, timer, goal, mode, swords, retro, bomblogic))
assert count == correct_count, "expected {0} items but found {1} items for {2}".format(correct_count, count, (progressive, shuffle, difficulty, timer, goal, mode, swords, retro, bombbag))
except AssertionError as e:
print(e)

View File

@@ -79,7 +79,7 @@ def main(args, seed=None, fish=None):
world.compassshuffle = args.compassshuffle.copy()
world.keyshuffle = args.keyshuffle.copy()
world.bigkeyshuffle = args.bigkeyshuffle.copy()
world.bomblogic = args.bomblogic.copy()
world.bombbag = args.bombbag.copy()
world.crystals_needed_for_ganon = {player: random.randint(0, 7) if args.crystals_ganon[player] == 'random' else int(args.crystals_ganon[player]) for player in range(1, world.players + 1)}
world.crystals_needed_for_gt = {player: random.randint(0, 7) if args.crystals_gt[player] == 'random' else int(args.crystals_gt[player]) for player in range(1, world.players + 1)}
world.crystals_ganon_orig = args.crystals_ganon.copy()
@@ -384,7 +384,7 @@ def copy_world(world):
ret.compassshuffle = world.compassshuffle.copy()
ret.keyshuffle = world.keyshuffle.copy()
ret.bigkeyshuffle = world.bigkeyshuffle.copy()
ret.bomblogic = world.bomblogic.copy()
ret.bombbag = world.bombbag.copy()
ret.crystals_needed_for_ganon = world.crystals_needed_for_ganon.copy()
ret.crystals_needed_for_gt = world.crystals_needed_for_gt.copy()
ret.crystals_ganon_orig = world.crystals_ganon_orig.copy()

View File

@@ -176,7 +176,7 @@ def roll_settings(weights):
ret.retro = True
ret.retro = get_choice('retro') == 'on' # this overrides world_state if used
ret.bomblogic = get_choice('bomblogic') == 'on'
ret.bombbag = get_choice('bombbag') == 'on'
ret.hints = get_choice('hints') == 'on'

View File

@@ -10,7 +10,7 @@ CLI: ```--shuffle_sfx```
When enabling this option, you do not start with bomb capacity but rather you must find 1 of 2 bomb bags. (They are represented by the +10 capacity item.) Bomb capacity upgrades are otherwise unavailable.
CLI: ```--bomblogic```
CLI: ```--bombbag```
# Bug Fixes and Notes.
@@ -18,7 +18,7 @@ CLI: ```--bomblogic```
* 0.5.0.2
* --shuffle_sfx option added
* 0.5.0.1
* --bomblogic option added
* --bombbag option added
* 0.5.0.0
* Handles headered roms for enemizer (Thanks compiling)
* Warning added for earlier version of python (Thanks compiling)

6
Rom.py
View File

@@ -1051,7 +1051,7 @@ def patch_rom(world, rom, player, team, enemized, is_mystery=False):
rom.write_bytes(0x184000, [
# original_item, limit, replacement_item, filler
0x12, 0x01, 0x35, 0xFF, # lamp -> 5 rupees
0x51, 0x00 if world.bomblogic[player] else 0x06, 0x31 if world.bomblogic[player] else 0x52, 0xFF, # 6 +5 bomb upgrades -> +10 bomb upgrade. If bomblogic -> turns into Bombs (10)
0x51, 0x00 if world.bombbag[player] else 0x06, 0x31 if world.bombbag[player] else 0x52, 0xFF, # 6 +5 bomb upgrades -> +10 bomb upgrade. If bombbag -> turns into Bombs (10)
0x53, 0x06, 0x54, 0xFF, # 6 +5 arrow upgrades -> +10 arrow upgrade
0x58, 0x01, 0x36 if world.retro[player] else 0x43, 0xFF, # silver arrows -> single arrow (red 20 in retro mode)
0x3E, difficulty.boss_heart_container_limit, 0x47, 0xff, # boss heart -> green 20
@@ -1188,7 +1188,7 @@ def patch_rom(world, rom, player, team, enemized, is_mystery=False):
equip[0x36C] = 0x18
equip[0x36D] = 0x18
equip[0x379] = 0x68
if world.bomblogic[player]:
if world.bombbag[player]:
starting_max_bombs = 0
else:
starting_max_bombs = 10
@@ -1483,7 +1483,7 @@ def patch_rom(world, rom, player, team, enemized, is_mystery=False):
rom.write_bytes(0x180188, [0, 0, 10]) # Zelda respawn refills (magic, bombs, arrows)
rom.write_bytes(0x18018B, [0, 0, 10]) # Mantle respawn refills (magic, bombs, arrows)
bow_max, bow_small = 70, 10
elif uncle_location.item is not None and uncle_location.item.name in ['Bomb Upgrade (+10)' if world.bomblogic[player] else 'Bombs (10)']:
elif uncle_location.item is not None and uncle_location.item.name in ['Bomb Upgrade (+10)' if world.bombbag[player] else 'Bombs (10)']:
rom.write_byte(0x18004E, 2) # Escape Fill (bombs)
rom.write_bytes(0x180185, [0, 50, 0]) # Uncle respawn refills (magic, bombs, arrows)
rom.write_bytes(0x180188, [0, 3, 0]) # Zelda respawn refills (magic, bombs, arrows)

View File

@@ -1162,7 +1162,7 @@ def standard_rules(world, player):
def bomb_escape_rule():
loc = world.get_location("Link's Uncle", player)
return loc.item and loc.item.name in ['Bomb Upgrade (+10)' if world.bomblogic[player] else 'Bombs (10)']
return loc.item and loc.item.name in ['Bomb Upgrade (+10)' if world.bombbag[player] else 'Bombs (10)']
def standard_escape_rule(state):
return state.can_kill_most_things(player) or bomb_escape_rule()

View File

@@ -16,6 +16,9 @@
pot_shuffle:
on: 1
off: 3
bombbag:
on: 1
off: 4
entrance_shuffle:
none: 15
dungeonssimple: 3

View File

@@ -224,7 +224,7 @@
"type": "bool",
"help": "suppress"
},
"bomblogic": {
"bombbag": {
"action": "store_true",
"type": "bool"
},

View File

@@ -264,7 +264,7 @@
"and a few other little things make this more like Zelda-1. (default: %(default)s)"
],
"pseudoboots": [ " Players starts with pseudo boots that allow dashing but no item checks (default: %(default)s"],
"bomblogic": ["Start with 0 bomb capacity. Two capacity upgrades (+10) are added to the pool (default: %(default)s)" ],
"bombbag": ["Start with 0 bomb capacity. Two capacity upgrades (+10) are added to the pool (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." ],
"custom": [ "Not supported." ],

View File

@@ -192,7 +192,7 @@
"randomizer.item.hints": "Include Helpful Hints",
"randomizer.item.retro": "Retro mode (universal keys)",
"randomizer.item.pseudoboots": "Start with Pseudo Boots",
"randomizer.item.bomblogic": "Bomblogic",
"randomizer.item.bombbag": "Bombbag",
"randomizer.item.worldstate": "World State",
"randomizer.item.worldstate.standard": "Standard",

View File

@@ -1,7 +1,7 @@
{
"checkboxes": {
"retro": { "type": "checkbox" },
"bomblogic": { "type": "checkbox" },
"bombbag": { "type": "checkbox" },
"shopsanity": { "type": "checkbox" },
"hints": {
"type": "checkbox"

View File

@@ -57,7 +57,7 @@ SETTINGSTOPROCESS = {
"item": {
"hints": "hints",
"retro": "retro",
"bomblogic": "bomblogic",
"bombbag": "bombbag",
"shopsanity": "shopsanity",
"pseudoboots": "pseudoboots",
"worldstate": "mode",