From c1788c070db32002b18ce39db663d56e1a1a07af Mon Sep 17 00:00:00 2001 From: Bonta-kun <40473493+Bonta0@users.noreply.github.com> Date: Mon, 16 Dec 2019 15:27:20 +0100 Subject: [PATCH] Individual settings: goal --- BaseClasses.py | 2 +- EntranceRandomizer.py | 2 +- Fill.py | 26 +++++++++++++++----------- ItemList.py | 10 +++++----- Main.py | 13 ++++--------- Plando.py | 2 +- Rom.py | 12 ++++++------ Rules.py | 6 +++--- 8 files changed, 36 insertions(+), 37 deletions(-) diff --git a/BaseClasses.py b/BaseClasses.py index 9b153e8d..40342687 100644 --- a/BaseClasses.py +++ b/BaseClasses.py @@ -18,7 +18,7 @@ class World(object): self.difficulty_adjustments = difficulty_adjustments self.timer = timer self.progressive = progressive - self.goal = goal + self.goal = goal.copy() self.algorithm = algorithm self.dungeons = [] self.regions = [] diff --git a/EntranceRandomizer.py b/EntranceRandomizer.py index b0134025..6e3871cd 100755 --- a/EntranceRandomizer.py +++ b/EntranceRandomizer.py @@ -278,7 +278,7 @@ def parse_arguments(argv, no_defaults=False): for player in range(1, multiargs.multi + 1): playerargs = parse_arguments(shlex.split(getattr(ret,f"p{player}")), True) - for name in ['logic', 'mode', 'swords']: + for name in ['logic', 'mode', 'swords', 'goal']: value = getattr(defaults, name) if getattr(playerargs, name) is None else getattr(playerargs, name) if player == 1: setattr(ret, name, {1: value}) diff --git a/Fill.py b/Fill.py index 4594ba65..dbb5fd78 100644 --- a/Fill.py +++ b/Fill.py @@ -210,7 +210,7 @@ def fill_restrictive(world, base_state, locations, itempool, single_player_place itempool.extend(unplaced_items) -def distribute_items_restrictive(world, gftower_trash_count=0, fill_locations=None): +def distribute_items_restrictive(world, gftower_trash=False, fill_locations=None): # If not passed in, then get a shuffled list of locations to fill in if not fill_locations: fill_locations = world.get_unfilled_locations() @@ -224,16 +224,20 @@ def distribute_items_restrictive(world, gftower_trash_count=0, fill_locations=No # fill in gtower locations with trash first for player in range(1, world.players + 1): - if world.ganonstower_vanilla[player]: - gtower_locations = [location for location in fill_locations if 'Ganons Tower' in location.name and location.player == player] - random.shuffle(gtower_locations) - trashcnt = 0 - while gtower_locations and restitempool and trashcnt < gftower_trash_count: - spot_to_fill = gtower_locations.pop() - item_to_place = restitempool.pop() - world.push_item(spot_to_fill, item_to_place, False) - fill_locations.remove(spot_to_fill) - trashcnt += 1 + if not gftower_trash or not world.ganonstower_vanilla[player]: + continue + + gftower_trash_count = (random.randint(15, 50) if world.goal[player] == 'triforcehunt' else random.randint(0, 15)) + + gtower_locations = [location for location in fill_locations if 'Ganons Tower' in location.name and location.player == player] + random.shuffle(gtower_locations) + trashcnt = 0 + while gtower_locations and restitempool and trashcnt < gftower_trash_count: + spot_to_fill = gtower_locations.pop() + item_to_place = restitempool.pop() + world.push_item(spot_to_fill, item_to_place, False) + fill_locations.remove(spot_to_fill) + trashcnt += 1 random.shuffle(fill_locations) fill_locations.reverse() diff --git a/ItemList.py b/ItemList.py index a9e89d59..e4f9a004 100644 --- a/ItemList.py +++ b/ItemList.py @@ -125,19 +125,19 @@ difficulties = { } def generate_itempool(world, player): - if (world.difficulty not in ['normal', 'hard', 'expert'] or world.goal not in ['ganon', 'pedestal', 'dungeons', 'triforcehunt', 'crystals'] + if (world.difficulty not in ['normal', 'hard', 'expert'] or world.goal[player] not in ['ganon', 'pedestal', 'dungeons', 'triforcehunt', 'crystals'] or world.mode[player] not in ['open', 'standard', 'inverted'] or world.timer not in ['none', 'display', 'timed', 'timed-ohko', 'ohko', 'timed-countdown'] or world.progressive not in ['on', 'off', 'random']): raise NotImplementedError('Not supported yet') if world.timer in ['ohko', 'timed-ohko']: world.can_take_damage = False - if world.goal in ['pedestal', 'triforcehunt']: + if world.goal[player] in ['pedestal', 'triforcehunt']: world.push_item(world.get_location('Ganon', player), ItemFactory('Nothing', player), False) else: world.push_item(world.get_location('Ganon', player), ItemFactory('Triforce', player), False) - if world.goal in ['triforcehunt']: + if world.goal[player] in ['triforcehunt']: if world.mode[player] == 'inverted': region = world.get_region('Light World',player) else: @@ -177,10 +177,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, world.difficulty, world.timer, world.goal, world.mode[player], world.swords[player], world.retro, 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, world.difficulty, world.timer, world.goal[player], world.mode[player], world.swords[player], world.retro, world.customitemarray) world.rupoor_cost = min(world.customitemarray[69], 9999) else: - (pool, placed_items, precollected_items, clock_mode, treasure_hunt_count, treasure_hunt_icon, lamps_needed_for_dark_rooms) = get_pool_core(world.progressive, world.shuffle, world.difficulty, world.timer, world.goal, world.mode[player], world.swords[player], world.retro) + (pool, placed_items, precollected_items, clock_mode, treasure_hunt_count, treasure_hunt_icon, lamps_needed_for_dark_rooms) = get_pool_core(world.progressive, world.shuffle, world.difficulty, world.timer, world.goal[player], world.mode[player], world.swords[player], world.retro) for item in precollected_items: world.push_precollected(ItemFactory(item, player)) diff --git a/Main.py b/Main.py index 307ed889..07c37b26 100644 --- a/Main.py +++ b/Main.py @@ -112,12 +112,12 @@ def main(args, seed=None): elif args.algorithm == 'freshness': distribute_items_staleness(world) elif args.algorithm == 'vt25': - distribute_items_restrictive(world, 0) + distribute_items_restrictive(world, False) elif args.algorithm == 'vt26': - distribute_items_restrictive(world, gt_filler(world), shuffled_locations) + distribute_items_restrictive(world, True, shuffled_locations) elif args.algorithm == 'balanced': - distribute_items_restrictive(world, gt_filler(world)) + distribute_items_restrictive(world, True) if world.players > 1: logger.info('Balancing multiworld progression.') @@ -185,7 +185,7 @@ def main(args, seed=None): outfilesuffix = ('%s%s_%s_%s-%s-%s-%s%s_%s-%s%s%s%s%s' % (f'_P{player}' if world.players > 1 else '', f'_{player_names[player]}' if player in player_names else '', world.logic[player], world.difficulty, world.difficulty_adjustments, - world.mode[player], world.goal, + world.mode[player], world.goal[player], "" if world.timer in ['none', 'display'] else "-" + world.timer, world.shuffle, world.algorithm, mcsb_name, "-retro" if world.retro else "", @@ -213,11 +213,6 @@ def main(args, seed=None): return world -def gt_filler(world): - if world.goal == 'triforcehunt': - return random.randint(15, 50) - return random.randint(0, 15) - def copy_world(world): # ToDo: Not good yet ret = World(world.players, world.shuffle, 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.quickswap, world.fastmenu, world.disable_music, world.retro, world.custom, world.customitemarray, world.boss_shuffle, world.hints) diff --git a/Plando.py b/Plando.py index 490da77d..c559c0d9 100755 --- a/Plando.py +++ b/Plando.py @@ -122,7 +122,7 @@ def fill_world(world, plando, text_patches): world.logic = {1: logicstr.strip()} elif line.startswith('!goal'): _, goalstr = line.split(':', 1) - world.goal = goalstr.strip() + world.goal = {1: goalstr.strip()} elif line.startswith('!light_cone_sewers'): _, sewerstr = line.split(':', 1) world.sewer_light_cone = {1: sewerstr.strip().lower() == 'true'} diff --git a/Rom.py b/Rom.py index ff77fd5a..a8a3db22 100644 --- a/Rom.py +++ b/Rom.py @@ -943,11 +943,11 @@ def patch_rom(world, player, rom, enemized): (0x02 if 'bombs' in world.escape_assist[player] else 0x00) | (0x04 if 'magic' in world.escape_assist[player] else 0x00))) # Escape assist - if world.goal in ['pedestal', 'triforcehunt']: + if world.goal[player] in ['pedestal', 'triforcehunt']: rom.write_byte(0x18003E, 0x01) # make ganon invincible - elif world.goal in ['dungeons']: + elif world.goal[player] in ['dungeons']: rom.write_byte(0x18003E, 0x02) # make ganon invincible until all dungeons are beat - elif world.goal in ['crystals']: + elif world.goal[player] in ['crystals']: rom.write_byte(0x18003E, 0x04) # make ganon invincible until all crystals else: rom.write_byte(0x18003E, 0x03) # make ganon invincible until all crystals and aga 2 are collected @@ -1552,7 +1552,7 @@ def write_strings(rom, world, player): tt['sign_ganons_tower'] = ('You need %d crystal to enter.' if world.crystals_needed_for_gt == 1 else 'You need %d crystals to enter.') % world.crystals_needed_for_gt tt['sign_ganon'] = ('You need %d crystal to beat Ganon.' if world.crystals_needed_for_ganon == 1 else 'You need %d crystals to beat Ganon.') % world.crystals_needed_for_ganon - if world.goal in ['dungeons']: + if world.goal[player] in ['dungeons']: tt['sign_ganon'] = 'You need to complete all the dungeons.' tt['uncle_leaving_text'] = Uncle_texts[random.randint(0, len(Uncle_texts) - 1)] @@ -1563,12 +1563,12 @@ def write_strings(rom, world, player): tt['sahasrahla_quest_have_master_sword'] = Sahasrahla2_texts[random.randint(0, len(Sahasrahla2_texts) - 1)] tt['blind_by_the_light'] = Blind_texts[random.randint(0, len(Blind_texts) - 1)] - if world.goal in ['triforcehunt']: + if world.goal[player] in ['triforcehunt']: tt['ganon_fall_in_alt'] = 'Why are you even here?\n You can\'t even hurt me! Get the Triforce Pieces.' tt['ganon_phase_3_alt'] = 'Seriously? Go Away, I will not Die.' tt['sign_ganon'] = 'Go find the Triforce pieces... Ganon is invincible!' tt['murahdahla'] = "Hello @. I\nam Murahdahla, brother of\nSahasrahla and Aginah. Behold the power of\ninvisibility.\n\n\n\n… … …\n\nWait! you can see me? I knew I should have\nhidden in a hollow tree. If you bring\n%d triforce pieces, I can reassemble it." % world.treasure_hunt_count - elif world.goal in ['pedestal']: + elif world.goal[player] in ['pedestal']: tt['ganon_fall_in_alt'] = 'Why are you even here?\n You can\'t even hurt me! Your goal is at the pedestal.' tt['ganon_phase_3_alt'] = 'Seriously? Go Away, I will not Die.' tt['sign_ganon'] = 'You need to get to the pedestal... Ganon is invincible!' diff --git a/Rules.py b/Rules.py index 7027c96c..a7bd03f4 100644 --- a/Rules.py +++ b/Rules.py @@ -42,10 +42,10 @@ def set_rules(world, player): else: raise NotImplementedError('Not implemented yet') - if world.goal == 'dungeons': + if world.goal[player] == 'dungeons': # require all dungeons to beat ganon add_rule(world.get_location('Ganon', player), lambda state: state.can_reach('Master Sword Pedestal', 'Location', player) and state.has('Beat Agahnim 1', player) and state.has('Beat Agahnim 2', player) and state.has_crystals(7, player)) - elif world.goal == 'ganon': + elif world.goal[player] == 'ganon': # require aga2 to beat ganon add_rule(world.get_location('Ganon', player), lambda state: state.has('Beat Agahnim 2', player)) @@ -106,7 +106,7 @@ def item_name(state, location, player): return (location.item.name, location.item.player) def global_rules(world, player): - if world.goal == 'triforcehunt': + if world.goal[player] == 'triforcehunt': for location in world.get_locations(): if location.player != player: forbid_item(location, 'Triforce Piece', player)