Merge branch 'main' into breaking_changes
# Conflicts: # BaseClasses.py
This commit is contained in:
commit
567954a17f
78
Fill.py
78
Fill.py
|
@ -42,9 +42,10 @@ def fill_restrictive(world, base_state: CollectionState, locations, itempool, si
|
||||||
for item_to_place in items_to_place:
|
for item_to_place in items_to_place:
|
||||||
perform_access_check = True
|
perform_access_check = True
|
||||||
if world.accessibility[item_to_place.player] == 'none':
|
if world.accessibility[item_to_place.player] == 'none':
|
||||||
perform_access_check = not world.has_beaten_game(maximum_exploration_state, item_to_place.player) if single_player_placement else not has_beaten_game
|
perform_access_check = not world.has_beaten_game(maximum_exploration_state,
|
||||||
|
item_to_place.player) if single_player_placement else not has_beaten_game
|
||||||
for location in locations:
|
for location in locations:
|
||||||
if (not single_player_placement or location.player == item_to_place.player)\
|
if (not single_player_placement or location.player == item_to_place.player) \
|
||||||
and location.can_fill(maximum_exploration_state, item_to_place, perform_access_check):
|
and location.can_fill(maximum_exploration_state, item_to_place, perform_access_check):
|
||||||
spot_to_fill = location
|
spot_to_fill = location
|
||||||
break
|
break
|
||||||
|
@ -70,6 +71,7 @@ def fill_restrictive(world, base_state: CollectionState, locations, itempool, si
|
||||||
|
|
||||||
itempool.extend(unplaced_items)
|
itempool.extend(unplaced_items)
|
||||||
|
|
||||||
|
|
||||||
def distribute_items_restrictive(world, gftower_trash=False, 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 passed in, then get a shuffled list of locations to fill in
|
||||||
if not fill_locations:
|
if not fill_locations:
|
||||||
|
@ -243,15 +245,14 @@ def balance_multiworld_progression(world):
|
||||||
else:
|
else:
|
||||||
logging.info(f'Balancing multiworld progression for {len(balanceable_players)} Players.')
|
logging.info(f'Balancing multiworld progression for {len(balanceable_players)} Players.')
|
||||||
state = CollectionState(world)
|
state = CollectionState(world)
|
||||||
checked_locations = []
|
checked_locations = set()
|
||||||
unchecked_locations = world.get_locations().copy()
|
unchecked_locations = set(world.get_locations())
|
||||||
world.random.shuffle(unchecked_locations)
|
|
||||||
|
|
||||||
reachable_locations_count = {player: 0 for player in world.player_ids}
|
reachable_locations_count = {player: 0 for player in world.player_ids}
|
||||||
|
|
||||||
def get_sphere_locations(sphere_state, locations):
|
def get_sphere_locations(sphere_state, locations):
|
||||||
sphere_state.sweep_for_events(key_only=True, locations=locations)
|
sphere_state.sweep_for_events(key_only=True, locations=locations)
|
||||||
return [loc for loc in locations if sphere_state.can_reach(loc)]
|
return {loc for loc in locations if sphere_state.can_reach(loc)}
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
sphere_locations = get_sphere_locations(state, unchecked_locations)
|
sphere_locations = get_sphere_locations(state, unchecked_locations)
|
||||||
|
@ -261,14 +262,14 @@ def balance_multiworld_progression(world):
|
||||||
|
|
||||||
if checked_locations:
|
if checked_locations:
|
||||||
threshold = max(reachable_locations_count.values()) - 20
|
threshold = max(reachable_locations_count.values()) - 20
|
||||||
balancing_players = [player for player, reachables in reachable_locations_count.items() if
|
balancing_players = {player for player, reachables in reachable_locations_count.items() if
|
||||||
reachables < threshold and player in balanceable_players]
|
reachables < threshold and player in balanceable_players}
|
||||||
if balancing_players:
|
if balancing_players:
|
||||||
balancing_state = state.copy()
|
balancing_state = state.copy()
|
||||||
balancing_unchecked_locations = unchecked_locations.copy()
|
balancing_unchecked_locations = unchecked_locations.copy()
|
||||||
balancing_reachables = reachable_locations_count.copy()
|
balancing_reachables = reachable_locations_count.copy()
|
||||||
balancing_sphere = sphere_locations.copy()
|
balancing_sphere = sphere_locations.copy()
|
||||||
candidate_items = collections.defaultdict(list)
|
candidate_items = collections.defaultdict(set)
|
||||||
while True:
|
while True:
|
||||||
for location in balancing_sphere:
|
for location in balancing_sphere:
|
||||||
if location.event:
|
if location.event:
|
||||||
|
@ -276,7 +277,7 @@ def balance_multiworld_progression(world):
|
||||||
player = location.item.player
|
player = location.item.player
|
||||||
# only replace items that end up in another player's world
|
# only replace items that end up in another player's world
|
||||||
if not location.locked and player in balancing_players and location.player != player:
|
if not location.locked and player in balancing_players and location.player != player:
|
||||||
candidate_items[player].append(location)
|
candidate_items[player].add(location)
|
||||||
balancing_sphere = get_sphere_locations(balancing_state, balancing_unchecked_locations)
|
balancing_sphere = get_sphere_locations(balancing_state, balancing_unchecked_locations)
|
||||||
for location in balancing_sphere:
|
for location in balancing_sphere:
|
||||||
balancing_unchecked_locations.remove(location)
|
balancing_unchecked_locations.remove(location)
|
||||||
|
@ -286,10 +287,10 @@ def balance_multiworld_progression(world):
|
||||||
break
|
break
|
||||||
elif not balancing_sphere:
|
elif not balancing_sphere:
|
||||||
raise RuntimeError('Not all required items reachable. Something went terribly wrong here.')
|
raise RuntimeError('Not all required items reachable. Something went terribly wrong here.')
|
||||||
unlocked_locations = collections.defaultdict(list)
|
unlocked_locations = collections.defaultdict(set)
|
||||||
for l in unchecked_locations:
|
for l in unchecked_locations:
|
||||||
if l not in balancing_unchecked_locations:
|
if l not in balancing_unchecked_locations:
|
||||||
unlocked_locations[l.player].append(l)
|
unlocked_locations[l.player].add(l)
|
||||||
items_to_replace = []
|
items_to_replace = []
|
||||||
for player in balancing_players:
|
for player in balancing_players:
|
||||||
locations_to_test = unlocked_locations[player]
|
locations_to_test = unlocked_locations[player]
|
||||||
|
@ -299,7 +300,6 @@ def balance_multiworld_progression(world):
|
||||||
reducing_state = state.copy()
|
reducing_state = state.copy()
|
||||||
for location in itertools.chain((l for l in items_to_replace if l.item.player == player),
|
for location in itertools.chain((l for l in items_to_replace if l.item.player == player),
|
||||||
items_to_test):
|
items_to_test):
|
||||||
|
|
||||||
reducing_state.collect(location.item, True, location)
|
reducing_state.collect(location.item, True, location)
|
||||||
|
|
||||||
reducing_state.sweep_for_events(locations=locations_to_test)
|
reducing_state.sweep_for_events(locations=locations_to_test)
|
||||||
|
@ -313,33 +313,40 @@ def balance_multiworld_progression(world):
|
||||||
items_to_replace.append(testing)
|
items_to_replace.append(testing)
|
||||||
|
|
||||||
replaced_items = False
|
replaced_items = False
|
||||||
replacement_locations = [l for l in checked_locations if not l.event and not l.locked]
|
|
||||||
|
# sort then shuffle to maintain deterministic behaviour,
|
||||||
|
# while allowing use of set for better algorithm growth behaviour elsewhere
|
||||||
|
replacement_locations = sorted(l for l in checked_locations if not l.event and not l.locked)
|
||||||
|
world.random.shuffle(replacement_locations)
|
||||||
|
items_to_replace.sort()
|
||||||
|
world.random.shuffle(items_to_replace)
|
||||||
|
|
||||||
while replacement_locations and items_to_replace:
|
while replacement_locations and items_to_replace:
|
||||||
new_location = replacement_locations.pop()
|
|
||||||
old_location = items_to_replace.pop()
|
old_location = items_to_replace.pop()
|
||||||
|
for new_location in replacement_locations:
|
||||||
while not new_location.can_fill(state, old_location.item, False) or (
|
if new_location.can_fill(state, old_location.item, False) and \
|
||||||
new_location.item and not old_location.can_fill(state, new_location.item, False)):
|
old_location.can_fill(state, new_location.item, False):
|
||||||
replacement_locations.insert(0, new_location)
|
replacement_locations.remove(new_location)
|
||||||
new_location = replacement_locations.pop()
|
swap_location_item(old_location, new_location)
|
||||||
|
logging.debug(f"Progression balancing moved {new_location.item} to {new_location}, "
|
||||||
swap_location_item(old_location, new_location)
|
f"displacing {old_location.item} into {old_location}")
|
||||||
logging.debug(f"Progression balancing moved {new_location.item} to {new_location}, "
|
state.collect(new_location.item, True, new_location)
|
||||||
f"displacing {old_location.item} into {old_location}")
|
replaced_items = True
|
||||||
state.collect(new_location.item, True, new_location)
|
break
|
||||||
replaced_items = True
|
else:
|
||||||
|
logging.warning(f"Could not Progression Balance {old_location.item}")
|
||||||
|
|
||||||
if replaced_items:
|
if replaced_items:
|
||||||
unlocked = [fresh for player in balancing_players for fresh in unlocked_locations[player]]
|
unlocked = {fresh for player in balancing_players for fresh in unlocked_locations[player]}
|
||||||
for location in get_sphere_locations(state, unlocked):
|
for location in get_sphere_locations(state, unlocked):
|
||||||
unchecked_locations.remove(location)
|
unchecked_locations.remove(location)
|
||||||
reachable_locations_count[location.player] += 1
|
reachable_locations_count[location.player] += 1
|
||||||
sphere_locations.append(location)
|
sphere_locations.add(location)
|
||||||
|
|
||||||
for location in sphere_locations:
|
for location in sphere_locations:
|
||||||
if location.event:
|
if location.event:
|
||||||
state.collect(location.item, True, location)
|
state.collect(location.item, True, location)
|
||||||
checked_locations.extend(sphere_locations)
|
checked_locations |= sphere_locations
|
||||||
|
|
||||||
if world.has_beaten_game(state):
|
if world.has_beaten_game(state):
|
||||||
break
|
break
|
||||||
|
@ -380,7 +387,8 @@ def distribute_planned(world):
|
||||||
set(world.player_ids) - {player}) if location.item_rule(item)
|
set(world.player_ids) - {player}) if location.item_rule(item)
|
||||||
)
|
)
|
||||||
if not unfilled:
|
if not unfilled:
|
||||||
placement.failed(f"Could not find a world with an unfilled location {placement.location}", FillError)
|
placement.failed(f"Could not find a world with an unfilled location {placement.location}",
|
||||||
|
FillError)
|
||||||
continue
|
continue
|
||||||
|
|
||||||
target_world = world.random.choice(unfilled).player
|
target_world = world.random.choice(unfilled).player
|
||||||
|
@ -391,18 +399,22 @@ def distribute_planned(world):
|
||||||
set(world.player_ids)) if location.item_rule(item)
|
set(world.player_ids)) if location.item_rule(item)
|
||||||
)
|
)
|
||||||
if not unfilled:
|
if not unfilled:
|
||||||
placement.failed(f"Could not find a world with an unfilled location {placement.location}", FillError)
|
placement.failed(f"Could not find a world with an unfilled location {placement.location}",
|
||||||
|
FillError)
|
||||||
continue
|
continue
|
||||||
|
|
||||||
target_world = world.random.choice(unfilled).player
|
target_world = world.random.choice(unfilled).player
|
||||||
|
|
||||||
elif type(target_world) == int: # target world by player id
|
elif type(target_world) == int: # target world by player id
|
||||||
if target_world not in range(1, world.players + 1):
|
if target_world not in range(1, world.players + 1):
|
||||||
placement.failed(f"Cannot place item in world {target_world} as it is not in range of (1, {world.players})", ValueError)
|
placement.failed(
|
||||||
|
f"Cannot place item in world {target_world} as it is not in range of (1, {world.players})",
|
||||||
|
ValueError)
|
||||||
continue
|
continue
|
||||||
else: # find world by name
|
else: # find world by name
|
||||||
if target_world not in world_name_lookup:
|
if target_world not in world_name_lookup:
|
||||||
placement.failed(f"Cannot place item to {target_world}'s world as that world does not exist.", ValueError)
|
placement.failed(f"Cannot place item to {target_world}'s world as that world does not exist.",
|
||||||
|
ValueError)
|
||||||
continue
|
continue
|
||||||
target_world = world_name_lookup[target_world]
|
target_world = world_name_lookup[target_world]
|
||||||
|
|
||||||
|
|
|
@ -46,6 +46,7 @@ if __name__ == "__main__":
|
||||||
player_name = multi_mystery_options["player_name"]
|
player_name = multi_mystery_options["player_name"]
|
||||||
meta_file_path = multi_mystery_options["meta_file_path"]
|
meta_file_path = multi_mystery_options["meta_file_path"]
|
||||||
weights_file_path = multi_mystery_options["weights_file_path"]
|
weights_file_path = multi_mystery_options["weights_file_path"]
|
||||||
|
pre_roll = multi_mystery_options["pre_roll"]
|
||||||
teams = multi_mystery_options["teams"]
|
teams = multi_mystery_options["teams"]
|
||||||
rom_file = options["general_options"]["rom_file"]
|
rom_file = options["general_options"]["rom_file"]
|
||||||
host = options["server_options"]["host"]
|
host = options["server_options"]["host"]
|
||||||
|
@ -104,6 +105,8 @@ if __name__ == "__main__":
|
||||||
command += f" --meta {os.path.join(player_files_path, meta_file_path)}"
|
command += f" --meta {os.path.join(player_files_path, meta_file_path)}"
|
||||||
if os.path.exists(weights_file_path):
|
if os.path.exists(weights_file_path):
|
||||||
command += f" --weights {weights_file_path}"
|
command += f" --weights {weights_file_path}"
|
||||||
|
if pre_roll:
|
||||||
|
command += " --pre_roll"
|
||||||
|
|
||||||
logging.info(command)
|
logging.info(command)
|
||||||
import time
|
import time
|
||||||
|
|
37
Mystery.py
37
Mystery.py
|
@ -37,6 +37,7 @@ def mystery_argparse():
|
||||||
parser.add_argument('--teams', default=1, type=lambda value: max(int(value), 1))
|
parser.add_argument('--teams', default=1, type=lambda value: max(int(value), 1))
|
||||||
parser.add_argument('--create_spoiler', action='store_true')
|
parser.add_argument('--create_spoiler', action='store_true')
|
||||||
parser.add_argument('--skip_playthrough', action='store_true')
|
parser.add_argument('--skip_playthrough', action='store_true')
|
||||||
|
parser.add_argument('--pre_roll', action='store_true')
|
||||||
parser.add_argument('--rom')
|
parser.add_argument('--rom')
|
||||||
parser.add_argument('--enemizercli')
|
parser.add_argument('--enemizercli')
|
||||||
parser.add_argument('--outputpath')
|
parser.add_argument('--outputpath')
|
||||||
|
@ -180,6 +181,27 @@ def main(args=None, callback=ERmain):
|
||||||
settings.sprite):
|
settings.sprite):
|
||||||
logging.warning(
|
logging.warning(
|
||||||
f"Warning: The chosen sprite, \"{settings.sprite}\", for yaml \"{path}\", does not exist.")
|
f"Warning: The chosen sprite, \"{settings.sprite}\", for yaml \"{path}\", does not exist.")
|
||||||
|
if args.pre_roll:
|
||||||
|
import yaml
|
||||||
|
if path == args.weights:
|
||||||
|
settings.name = f"Player{player}"
|
||||||
|
elif not settings.name:
|
||||||
|
settings.name = os.path.split(path)[-1].split(".")[0]
|
||||||
|
|
||||||
|
if "-" not in settings.shuffle and settings.shuffle != "vanilla":
|
||||||
|
settings.shuffle += f"-{random.randint(0, 2 ** 64)}"
|
||||||
|
|
||||||
|
pre_rolled = dict()
|
||||||
|
pre_rolled["original_seed_number"] = seed
|
||||||
|
pre_rolled["original_seed_name"] = seedname
|
||||||
|
pre_rolled["pre_rolled"] = vars(settings).copy()
|
||||||
|
if "plando_items" in pre_rolled["pre_rolled"]:
|
||||||
|
pre_rolled["pre_rolled"]["plando_items"] = [item.to_dict() for item in pre_rolled["pre_rolled"]["plando_items"]]
|
||||||
|
if "plando_connections" in pre_rolled["pre_rolled"]:
|
||||||
|
pre_rolled["pre_rolled"]["plando_connections"] = [connection.to_dict() for connection in pre_rolled["pre_rolled"]["plando_connections"]]
|
||||||
|
|
||||||
|
with open(os.path.join(args.outputpath if args.outputpath else ".", f"{os.path.split(path)[-1].split('.')[0]}_pre_rolled.yaml"), "wt") as f:
|
||||||
|
yaml.dump(pre_rolled, f)
|
||||||
for k, v in vars(settings).items():
|
for k, v in vars(settings).items():
|
||||||
if v is not None:
|
if v is not None:
|
||||||
getattr(erargs, k)[player] = v
|
getattr(erargs, k)[player] = v
|
||||||
|
@ -349,6 +371,21 @@ def roll_triggers(weights: dict) -> dict:
|
||||||
return weights
|
return weights
|
||||||
|
|
||||||
def roll_settings(weights: dict, plando_options: typing.Set[str] = frozenset(("bosses"))):
|
def roll_settings(weights: dict, plando_options: typing.Set[str] = frozenset(("bosses"))):
|
||||||
|
if "pre_rolled" in weights:
|
||||||
|
pre_rolled = weights["pre_rolled"]
|
||||||
|
|
||||||
|
if "plando_items" in pre_rolled:
|
||||||
|
pre_rolled["plando_items"] = [PlandoItem(item["item"],
|
||||||
|
item["location"],
|
||||||
|
item["world"],
|
||||||
|
item["from_pool"],
|
||||||
|
item["force"]) for item in pre_rolled["plando_items"]]
|
||||||
|
if "plando_connections" in pre_rolled:
|
||||||
|
pre_rolled["plando_connections"] = [PlandoConnection(connection["entrance"],
|
||||||
|
connection["exit"],
|
||||||
|
connection["direction"]) for connection in pre_rolled["plando_connections"]]
|
||||||
|
return argparse.Namespace(**pre_rolled)
|
||||||
|
|
||||||
if "linked_options" in weights:
|
if "linked_options" in weights:
|
||||||
weights = roll_linked_options(weights)
|
weights = roll_linked_options(weights)
|
||||||
|
|
||||||
|
|
1
Utils.py
1
Utils.py
|
@ -188,6 +188,7 @@ def get_default_options() -> dict:
|
||||||
"players": 0,
|
"players": 0,
|
||||||
"weights_file_path": "weights.yaml",
|
"weights_file_path": "weights.yaml",
|
||||||
"meta_file_path": "meta.yaml",
|
"meta_file_path": "meta.yaml",
|
||||||
|
"pre_roll": False,
|
||||||
"player_name": "",
|
"player_name": "",
|
||||||
"create_spoiler": 1,
|
"create_spoiler": 1,
|
||||||
"zip_roms": 0,
|
"zip_roms": 0,
|
||||||
|
|
|
@ -1602,37 +1602,6 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"triforcehud": {
|
|
||||||
"keyString": "rom.triforcehud",
|
|
||||||
"friendlyName": "Triforce Hud Options",
|
|
||||||
"description": "Hide the triforce hud in certain circumstances.",
|
|
||||||
"inputType": "range",
|
|
||||||
"subOptions": {
|
|
||||||
"normal": {
|
|
||||||
"keyString": "rom.triforcehud.normal",
|
|
||||||
"friendlyName": "Normal",
|
|
||||||
"description": "Always displays HUD as usual.",
|
|
||||||
"defaultValue": 0
|
|
||||||
},
|
|
||||||
"hide_goal": {
|
|
||||||
"keyString": "rom.triforcehud.hide_goal",
|
|
||||||
"friendlyName": "Hide Goal",
|
|
||||||
"description": "Hide Triforce Hud elements until a single triforce piece is acquired or spoken to Murahadala",
|
|
||||||
"defaultValue": 50
|
|
||||||
},
|
|
||||||
"hide_total": {
|
|
||||||
"keyString": "rom.triforcehud.hide_required",
|
|
||||||
"friendlyName": "Hide Required Total",
|
|
||||||
"description": "Hide total amount needed to win the game (unless spoken to Murahadala)",
|
|
||||||
"defaultValue": 0
|
|
||||||
},
|
|
||||||
"hide_both": {
|
|
||||||
"keyString": "rom.triforcehud.hide_both",
|
|
||||||
"friendlyName": "Hide Both",
|
|
||||||
"description": "Hide both of the above options",
|
|
||||||
"defaultValue": 0
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"reduceflashing": {
|
"reduceflashing": {
|
||||||
"keyString": "rom.reduceflashing",
|
"keyString": "rom.reduceflashing",
|
||||||
"friendlyName": "Full-Screen Flashing Effects",
|
"friendlyName": "Full-Screen Flashing Effects",
|
||||||
|
@ -1673,6 +1642,38 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"triforcehud": {
|
||||||
|
"keyString": "rom.triforcehud",
|
||||||
|
"friendlyName": "Triforce Hunt HUD Options",
|
||||||
|
"description": "Hide the triforce hud in certain circumstances.",
|
||||||
|
"inputType": "range",
|
||||||
|
"subOptions": {
|
||||||
|
"normal": {
|
||||||
|
"keyString": "rom.triforcehud.normal",
|
||||||
|
"friendlyName": "Always Show",
|
||||||
|
"description": "Always display HUD",
|
||||||
|
"defaultValue": 50
|
||||||
|
},
|
||||||
|
"hide_goal": {
|
||||||
|
"keyString": "rom.triforcehud.hide_goal",
|
||||||
|
"friendlyName": "Hide HUD",
|
||||||
|
"description": "Hide Triforce HUD elements until a single triforce piece is acquired or you speak to Murahadala",
|
||||||
|
"defaultValue": 0
|
||||||
|
},
|
||||||
|
"hide_total": {
|
||||||
|
"keyString": "rom.triforcehud.hide_required",
|
||||||
|
"friendlyName": "Hide Total",
|
||||||
|
"description": "Hide total triforce pieces needed to win the game until you speak with Murahadala",
|
||||||
|
"defaultValue": 0
|
||||||
|
},
|
||||||
|
"hide_both": {
|
||||||
|
"keyString": "rom.triforcehud.hide_both",
|
||||||
|
"friendlyName": "Hide HUD Total",
|
||||||
|
"description": "Combination of Hide HUD and Hide Total",
|
||||||
|
"defaultValue": 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"menuspeed": {
|
"menuspeed": {
|
||||||
"keyString": "menuspeed",
|
"keyString": "menuspeed",
|
||||||
"friendlyName": "Menu Speed",
|
"friendlyName": "Menu Speed",
|
||||||
|
|
|
@ -20,7 +20,7 @@
|
||||||
# For use with the weighted-settings page on the website. Changing this value will cause all users to be prompted
|
# For use with the weighted-settings page on the website. Changing this value will cause all users to be prompted
|
||||||
# to update their settings. The version number should match the current released version number, and the revision
|
# to update their settings. The version number should match the current released version number, and the revision
|
||||||
# should be updated manually by whoever edits this file.
|
# should be updated manually by whoever edits this file.
|
||||||
ws_version: 4.0.1 rev1
|
ws_version: 4.1.0 rev0
|
||||||
|
|
||||||
description: Template Name # Used to describe your yaml. Useful if you have multiple files
|
description: Template Name # Used to describe your yaml. Useful if you have multiple files
|
||||||
name: YourName # Your name in-game. Spaces will be replaced with underscores and there is a 16 character limit
|
name: YourName # Your name in-game. Spaces will be replaced with underscores and there is a 16 character limit
|
||||||
|
@ -363,6 +363,11 @@ rom:
|
||||||
quickswap: # Enable switching items by pressing the L+R shoulder buttons
|
quickswap: # Enable switching items by pressing the L+R shoulder buttons
|
||||||
on: 50
|
on: 50
|
||||||
off: 0
|
off: 0
|
||||||
|
triforcehud: # Disable visibility of the triforce hud unless collecting a piece or speaking to Murahadala
|
||||||
|
normal: 50 # original behavior (always visible)
|
||||||
|
hide_goal: 0 # hide counter until a piece is collected or speaking to Murahadala
|
||||||
|
hide_required: 0 # Always visible, but required amount is invisible until determined by Murahadala
|
||||||
|
hide_both: 0 # Hide both under above circumstances
|
||||||
reduceflashing: # Reduces instances of flashing such as lightning attacks, weather, ether and more.
|
reduceflashing: # Reduces instances of flashing such as lightning attacks, weather, ether and more.
|
||||||
on: 50
|
on: 50
|
||||||
off: 0
|
off: 0
|
||||||
|
|
|
@ -350,8 +350,9 @@ def getPlayerTracker(tracker: UUID, team: int, player: int):
|
||||||
|
|
||||||
# Add items to player inventory
|
# Add items to player inventory
|
||||||
for (ms_team, ms_player), locations_checked in room.multisave.get("location_checks", {}):
|
for (ms_team, ms_player), locations_checked in room.multisave.get("location_checks", {}):
|
||||||
|
# logging.info(f"{ms_team}, {ms_player}, {locations_checked}")
|
||||||
# Skip teams and players not matching the request
|
# Skip teams and players not matching the request
|
||||||
if ms_team != (team - 1) or ms_player != player:
|
if ms_team != (team - 1):
|
||||||
continue
|
continue
|
||||||
|
|
||||||
# If the player does not have the item, do nothing
|
# If the player does not have the item, do nothing
|
||||||
|
@ -360,7 +361,10 @@ def getPlayerTracker(tracker: UUID, team: int, player: int):
|
||||||
continue
|
continue
|
||||||
|
|
||||||
item, recipient = locations[location, ms_player]
|
item, recipient = locations[location, ms_player]
|
||||||
attribute_item_solo(inventory, item)
|
if recipient == player:
|
||||||
|
attribute_item_solo(inventory, item)
|
||||||
|
if ms_player != player:
|
||||||
|
continue
|
||||||
checks_done[player_location_to_area[location]] += 1
|
checks_done[player_location_to_area[location]] += 1
|
||||||
checks_done["Total"] += 1
|
checks_done["Total"] += 1
|
||||||
|
|
||||||
|
@ -391,7 +395,7 @@ def getPlayerTracker(tracker: UUID, team: int, player: int):
|
||||||
sword_acquired = False
|
sword_acquired = False
|
||||||
sword_names = ['Fighter Sword', 'Master Sword', 'Tempered Sword', 'Golden Sword']
|
sword_names = ['Fighter Sword', 'Master Sword', 'Tempered Sword', 'Golden Sword']
|
||||||
if "Progressive Sword" in acquired_items:
|
if "Progressive Sword" in acquired_items:
|
||||||
sword_url = icons[sword_names[inventory[progressive_items["Progressive Sword"]] - 1]]
|
sword_url = icons[sword_names[min(inventory[progressive_items["Progressive Sword"]], 4) - 1]]
|
||||||
sword_acquired = True
|
sword_acquired = True
|
||||||
else:
|
else:
|
||||||
for sword in reversed(sword_names):
|
for sword in reversed(sword_names):
|
||||||
|
@ -404,7 +408,7 @@ def getPlayerTracker(tracker: UUID, team: int, player: int):
|
||||||
gloves_acquired = False
|
gloves_acquired = False
|
||||||
glove_names = ["Power Glove", "Titan Mitts"]
|
glove_names = ["Power Glove", "Titan Mitts"]
|
||||||
if "Progressive Glove" in acquired_items:
|
if "Progressive Glove" in acquired_items:
|
||||||
gloves_url = icons[glove_names[inventory[progressive_items["Progressive Glove"]] - 1]]
|
gloves_url = icons[glove_names[min(inventory[progressive_items["Progressive Glove"]], 2) - 1]]
|
||||||
gloves_acquired = True
|
gloves_acquired = True
|
||||||
else:
|
else:
|
||||||
for glove in reversed(glove_names):
|
for glove in reversed(glove_names):
|
||||||
|
@ -417,7 +421,7 @@ def getPlayerTracker(tracker: UUID, team: int, player: int):
|
||||||
bow_acquired = False
|
bow_acquired = False
|
||||||
bow_names = ["Bow", "Silver Bow"]
|
bow_names = ["Bow", "Silver Bow"]
|
||||||
if "Progressive Bow" in acquired_items:
|
if "Progressive Bow" in acquired_items:
|
||||||
bow_url = icons[bow_names[inventory[progressive_items["Progressive Bow"]] - 1]]
|
bow_url = icons[bow_names[min(inventory[progressive_items["Progressive Bow"]], 2) - 1]]
|
||||||
bow_acquired = True
|
bow_acquired = True
|
||||||
else:
|
else:
|
||||||
for bow in reversed(bow_names):
|
for bow in reversed(bow_names):
|
||||||
|
@ -429,7 +433,7 @@ def getPlayerTracker(tracker: UUID, team: int, player: int):
|
||||||
mail_url = icons["Green Mail"]
|
mail_url = icons["Green Mail"]
|
||||||
mail_names = ["Blue Mail", "Red Mail"]
|
mail_names = ["Blue Mail", "Red Mail"]
|
||||||
if "Progressive Mail" in acquired_items:
|
if "Progressive Mail" in acquired_items:
|
||||||
mail_url = icons[mail_names[inventory[progressive_items["Progressive Mail"]] - 1]]
|
mail_url = icons[mail_names[min(inventory[progressive_items["Progressive Mail"]], 2) - 1]]
|
||||||
else:
|
else:
|
||||||
for mail in reversed(mail_names):
|
for mail in reversed(mail_names):
|
||||||
if mail in acquired_items:
|
if mail in acquired_items:
|
||||||
|
@ -440,7 +444,7 @@ def getPlayerTracker(tracker: UUID, team: int, player: int):
|
||||||
shield_acquired = False
|
shield_acquired = False
|
||||||
shield_names = ["Blue Shield", "Red Shield", "Mirror Shield"]
|
shield_names = ["Blue Shield", "Red Shield", "Mirror Shield"]
|
||||||
if "Progressive Shield" in acquired_items:
|
if "Progressive Shield" in acquired_items:
|
||||||
shield_url = icons[shield_names[inventory[progressive_items["Progressive Shield"]] - 1]]
|
shield_url = icons[shield_names[min(inventory[progressive_items["Progressive Shield"]], 3) - 1]]
|
||||||
shield_acquired = True
|
shield_acquired = True
|
||||||
else:
|
else:
|
||||||
for shield in reversed(shield_names):
|
for shield in reversed(shield_names):
|
||||||
|
|
|
@ -64,6 +64,10 @@ multi_mystery_options:
|
||||||
weights_file_path: "weights.yaml"
|
weights_file_path: "weights.yaml"
|
||||||
# Meta file name, within the stated player_files_path location
|
# Meta file name, within the stated player_files_path location
|
||||||
meta_file_path: "meta.yaml"
|
meta_file_path: "meta.yaml"
|
||||||
|
# Option to pre-roll a yaml that will be used to roll future seeds with the exact same settings every single time.
|
||||||
|
# If using a pre-rolled yaml fails with "Please fix your yaml.", please file a bug report including both the original yaml
|
||||||
|
# as well as the generated pre-rolled yaml.
|
||||||
|
pre_roll: false
|
||||||
# Automatically launches {player_name}.yaml's ROM file using the OS's default program once generation completes. (likely your emulator)
|
# Automatically launches {player_name}.yaml's ROM file using the OS's default program once generation completes. (likely your emulator)
|
||||||
# Does nothing if the name is not found
|
# Does nothing if the name is not found
|
||||||
# Example: player_name = "Berserker"
|
# Example: player_name = "Berserker"
|
||||||
|
|
|
@ -404,10 +404,10 @@ rom:
|
||||||
quickswap: # Enable switching items by pressing the L+R shoulder buttons
|
quickswap: # Enable switching items by pressing the L+R shoulder buttons
|
||||||
on: 50
|
on: 50
|
||||||
off: 0
|
off: 0
|
||||||
triforcehud: # Disable visibility of the triforce hud unless collecting a piece or speaking to Murahalda
|
triforcehud: # Disable visibility of the triforce hud unless collecting a piece or speaking to Murahadala
|
||||||
normal: 0 # original behavior (always visible)
|
normal: 0 # original behavior (always visible)
|
||||||
hide_goal: 50 # hide counter until a piece is collected or speaking to Murahalda
|
hide_goal: 50 # hide counter until a piece is collected or speaking to Murahadala
|
||||||
hide_required: 0 # Always visible, but required amount is invisible until determined by Murahalda
|
hide_required: 0 # Always visible, but required amount is invisible until determined by Murahadala
|
||||||
hide_both: 0 # Hide both under above circumstances
|
hide_both: 0 # Hide both under above circumstances
|
||||||
reduceflashing: # Reduces instances of flashing such as lightning attacks, weather, ether and more.
|
reduceflashing: # Reduces instances of flashing such as lightning attacks, weather, ether and more.
|
||||||
on: 50
|
on: 50
|
||||||
|
|
Loading…
Reference in New Issue