Merged DR v0.4.0.5
This commit is contained in:
@@ -2170,6 +2170,7 @@ class Spoiler(object):
|
|||||||
'enemy_shuffle': self.world.enemy_shuffle,
|
'enemy_shuffle': self.world.enemy_shuffle,
|
||||||
'enemy_health': self.world.enemy_health,
|
'enemy_health': self.world.enemy_health,
|
||||||
'enemy_damage': self.world.enemy_damage,
|
'enemy_damage': self.world.enemy_damage,
|
||||||
|
'potshuffle': self.world.potshuffle,
|
||||||
'players': self.world.players,
|
'players': self.world.players,
|
||||||
'teams': self.world.teams,
|
'teams': self.world.teams,
|
||||||
'experimental': self.world.experimental,
|
'experimental': self.world.experimental,
|
||||||
@@ -2249,6 +2250,7 @@ class Spoiler(object):
|
|||||||
outfile.write('Enemy shuffle:'.ljust(line_width) + '%s\n' % self.metadata['enemy_shuffle'][player])
|
outfile.write('Enemy shuffle:'.ljust(line_width) + '%s\n' % self.metadata['enemy_shuffle'][player])
|
||||||
outfile.write('Enemy health:'.ljust(line_width) + '%s\n' % self.metadata['enemy_health'][player])
|
outfile.write('Enemy health:'.ljust(line_width) + '%s\n' % self.metadata['enemy_health'][player])
|
||||||
outfile.write('Enemy damage:'.ljust(line_width) + '%s\n' % self.metadata['enemy_damage'][player])
|
outfile.write('Enemy damage:'.ljust(line_width) + '%s\n' % self.metadata['enemy_damage'][player])
|
||||||
|
outfile.write('Pot shuffle:'.ljust(line_width) + '%s\n' % ('Yes' if self.metadata['potshuffle'][player] else 'No'))
|
||||||
outfile.write('Hints:'.ljust(line_width) + '%s\n' % ('Yes' if self.metadata['hints'][player] else 'No'))
|
outfile.write('Hints:'.ljust(line_width) + '%s\n' % ('Yes' if self.metadata['hints'][player] else 'No'))
|
||||||
outfile.write('Experimental:'.ljust(line_width) + '%s\n' % ('Yes' if self.metadata['experimental'][player] else 'No'))
|
outfile.write('Experimental:'.ljust(line_width) + '%s\n' % ('Yes' if self.metadata['experimental'][player] else 'No'))
|
||||||
outfile.write('Key Drops shuffled:'.ljust(line_width) + '%s\n' % ('Yes' if self.metadata['keydropshuffle'][player] else 'No'))
|
outfile.write('Key Drops shuffled:'.ljust(line_width) + '%s\n' % ('Yes' if self.metadata['keydropshuffle'][player] else 'No'))
|
||||||
|
|||||||
@@ -174,7 +174,7 @@ def place_bosses(world, player):
|
|||||||
boss_locations.remove(['Ice Palace', None])
|
boss_locations.remove(['Ice Palace', None])
|
||||||
placeable_bosses.remove('Kholdstare')
|
placeable_bosses.remove('Kholdstare')
|
||||||
|
|
||||||
if world.boss_shuffle[player] == "basic": # vanilla bosses shuffled
|
if world.boss_shuffle[player] == "simple": # vanilla bosses shuffled
|
||||||
bosses = placeable_bosses + ['Armos Knights', 'Lanmolas', 'Moldorm']
|
bosses = placeable_bosses + ['Armos Knights', 'Lanmolas', 'Moldorm']
|
||||||
else: # all bosses present, the three duplicates chosen at random
|
else: # all bosses present, the three duplicates chosen at random
|
||||||
bosses = all_bosses + [random.choice(placeable_bosses) for _ in range(3)]
|
bosses = all_bosses + [random.choice(placeable_bosses) for _ in range(3)]
|
||||||
|
|||||||
@@ -1308,12 +1308,28 @@ def link_entrances(world, player):
|
|||||||
|
|
||||||
# place remaining doors
|
# place remaining doors
|
||||||
connect_doors(world, doors, door_targets, player)
|
connect_doors(world, doors, door_targets, player)
|
||||||
elif not invFlag and world.shuffle[player] == 'insanity_legacy':
|
elif world.shuffle[player] == 'insanity_legacy':
|
||||||
world.fix_fake_world[player] = False
|
world.fix_fake_world[player] = False
|
||||||
# beware ye who enter here
|
# beware ye who enter here
|
||||||
|
|
||||||
entrances = LW_Entrances + LW_Dungeon_Entrances + DW_Entrances + DW_Dungeon_Entrances + Old_Man_Entrances + ['Skull Woods Second Section Door (East)', 'Skull Woods First Section Door', 'Kakariko Well Cave', 'Bat Cave Cave', 'North Fairy Cave', 'Sanctuary', 'Lost Woods Hideout Stump', 'Lumberjack Tree Cave']
|
if not invFlag:
|
||||||
entrances_must_exits = DW_Entrances_Must_Exit + DW_Dungeon_Entrances_Must_Exit + LW_Dungeon_Entrances_Must_Exit + ['Skull Woods Second Section Door (West)']
|
entrances_must_exits = DW_Entrances_Must_Exit + DW_Dungeon_Entrances_Must_Exit + LW_Dungeon_Entrances_Must_Exit + ['Skull Woods Second Section Door (West)']
|
||||||
|
|
||||||
|
doors = LW_Entrances + LW_Dungeon_Entrances + DW_Entrances + DW_Dungeon_Entrances + Old_Man_Entrances + ['Skull Woods Second Section Door (East)', 'Skull Woods First Section Door', 'Kakariko Well Cave', 'Bat Cave Cave', 'North Fairy Cave', 'Sanctuary', 'Lost Woods Hideout Stump', 'Lumberjack Tree Cave']
|
||||||
|
else:
|
||||||
|
entrances_must_exits = Inverted_LW_Entrances_Must_Exit + Inverted_LW_Dungeon_Entrances_Must_Exit
|
||||||
|
|
||||||
|
doors = Inverted_LW_Entrances + Inverted_LW_Dungeon_Entrances + Inverted_LW_Entrances_Must_Exit + Inverted_LW_Dungeon_Entrances_Must_Exit + ['Kakariko Well Cave', 'Bat Cave Cave', 'North Fairy Cave', 'Sanctuary', 'Lost Woods Hideout Stump', 'Lumberjack Tree Cave', 'Hyrule Castle Secret Entrance Stairs'] + Inverted_Old_Man_Entrances +\
|
||||||
|
Inverted_DW_Entrances + Inverted_DW_Dungeon_Entrances + ['Skull Woods First Section Door', 'Skull Woods Second Section Door (East)', 'Skull Woods Second Section Door (West)'] +\
|
||||||
|
Inverted_LW_Single_Cave_Doors + Inverted_DW_Single_Cave_Doors + ['Desert Palace Entrance (West)', 'Desert Palace Entrance (North)']
|
||||||
|
|
||||||
|
exit_pool = list(doors)
|
||||||
|
|
||||||
|
# randomize which desert ledge door is a must-exit
|
||||||
|
if random.randint(0, 1) == 0:
|
||||||
|
entrances_must_exits.append('Desert Palace Entrance (North)')
|
||||||
|
else:
|
||||||
|
entrances_must_exits.append('Desert Palace Entrance (West)')
|
||||||
|
|
||||||
doors = LW_Entrances + LW_Dungeon_Entrances + LW_Dungeon_Entrances_Must_Exit + ['Kakariko Well Cave', 'Bat Cave Cave', 'North Fairy Cave', 'Sanctuary', 'Lost Woods Hideout Stump', 'Lumberjack Tree Cave'] + Old_Man_Entrances +\
|
doors = LW_Entrances + LW_Dungeon_Entrances + LW_Dungeon_Entrances_Must_Exit + ['Kakariko Well Cave', 'Bat Cave Cave', 'North Fairy Cave', 'Sanctuary', 'Lost Woods Hideout Stump', 'Lumberjack Tree Cave'] + Old_Man_Entrances +\
|
||||||
DW_Entrances + DW_Dungeon_Entrances + DW_Entrances_Must_Exit + DW_Dungeon_Entrances_Must_Exit + ['Skull Woods First Section Door', 'Skull Woods Second Section Door (East)', 'Skull Woods Second Section Door (West)']
|
DW_Entrances + DW_Dungeon_Entrances + DW_Entrances_Must_Exit + DW_Dungeon_Entrances_Must_Exit + ['Skull Woods First Section Door', 'Skull Woods Second Section Door (East)', 'Skull Woods Second Section Door (West)']
|
||||||
@@ -1333,6 +1349,9 @@ def link_entrances(world, player):
|
|||||||
hole_targets = ['Kakariko Well (top)', 'Bat Cave (right)', 'North Fairy Cave', 'Lost Woods Hideout (top)', 'Lumberjack Tree (top)', 'Sewer Drop', 'Skull Back Drop',
|
hole_targets = ['Kakariko Well (top)', 'Bat Cave (right)', 'North Fairy Cave', 'Lost Woods Hideout (top)', 'Lumberjack Tree (top)', 'Sewer Drop', 'Skull Back Drop',
|
||||||
'Skull Left Drop', 'Skull Pinball', 'Skull Pot Circle']
|
'Skull Left Drop', 'Skull Pinball', 'Skull Pot Circle']
|
||||||
|
|
||||||
|
# tavern back door cannot be shuffled yet
|
||||||
|
connect_doors(world, ['Tavern North'], ['Tavern'], player)
|
||||||
|
|
||||||
if world.mode[player] == 'standard':
|
if world.mode[player] == 'standard':
|
||||||
# cannot move uncle cave
|
# cannot move uncle cave
|
||||||
connect_entrance(world, 'Hyrule Castle Secret Entrance Drop', 'Hyrule Castle Secret Entrance', player)
|
connect_entrance(world, 'Hyrule Castle Secret Entrance Drop', 'Hyrule Castle Secret Entrance', player)
|
||||||
@@ -1342,24 +1361,32 @@ def link_entrances(world, player):
|
|||||||
hole_entrances.append('Hyrule Castle Secret Entrance Drop')
|
hole_entrances.append('Hyrule Castle Secret Entrance Drop')
|
||||||
hole_targets.append('Hyrule Castle Secret Entrance')
|
hole_targets.append('Hyrule Castle Secret Entrance')
|
||||||
doors.append('Hyrule Castle Secret Entrance Stairs')
|
doors.append('Hyrule Castle Secret Entrance Stairs')
|
||||||
entrances.append('Hyrule Castle Secret Entrance Stairs')
|
|
||||||
caves.append('Hyrule Castle Secret Entrance Exit')
|
caves.append('Hyrule Castle Secret Entrance Exit')
|
||||||
|
|
||||||
if not world.shuffle_ganon:
|
if not world.shuffle_ganon:
|
||||||
connect_two_way(world, 'Ganons Tower', 'Ganons Tower Exit', player)
|
connect_two_way(world, 'Ganons Tower', 'Ganons Tower Exit', player)
|
||||||
connect_two_way(world, 'Pyramid Entrance', 'Pyramid Exit', player)
|
if not invFlag:
|
||||||
connect_entrance(world, 'Pyramid Hole', 'Pyramid', player)
|
connect_two_way(world, 'Pyramid Entrance', 'Pyramid Exit', player)
|
||||||
|
connect_entrance(world, 'Pyramid Hole', 'Pyramid', player)
|
||||||
|
else:
|
||||||
|
connect_two_way(world, 'Inverted Pyramid Entrance', 'Pyramid Exit', player)
|
||||||
|
connect_entrance(world, 'Inverted Pyramid Hole', 'Pyramid', player)
|
||||||
else:
|
else:
|
||||||
entrances.append('Ganons Tower')
|
|
||||||
caves.extend(['Ganons Tower Exit', 'Pyramid Exit'])
|
caves.extend(['Ganons Tower Exit', 'Pyramid Exit'])
|
||||||
hole_entrances.append('Pyramid Hole')
|
|
||||||
hole_targets.append('Pyramid')
|
hole_targets.append('Pyramid')
|
||||||
entrances_must_exits.append('Pyramid Entrance')
|
if not invFlag:
|
||||||
doors.extend(['Ganons Tower', 'Pyramid Entrance'])
|
hole_entrances.append('Pyramid Hole')
|
||||||
|
doors.extend(['Agahnims Tower', 'Pyramid Entrance'])
|
||||||
|
exit_pool.extend(['Agahnims Tower', 'Pyramid Entrance'])
|
||||||
|
else:
|
||||||
|
hole_entrances.append('Inverted Pyramid Hole')
|
||||||
|
doors.extend(['Agahnims Tower', 'Inverted Pyramid Entrance'])
|
||||||
|
exit_pool.extend(['Agahnims Tower', 'Inverted Pyramid Entrance'])
|
||||||
|
|
||||||
random.shuffle(hole_entrances)
|
random.shuffle(hole_entrances)
|
||||||
random.shuffle(hole_targets)
|
random.shuffle(hole_targets)
|
||||||
random.shuffle(entrances)
|
random.shuffle(exit_pool)
|
||||||
|
|
||||||
# fill up holes
|
# fill up holes
|
||||||
for hole in hole_entrances:
|
for hole in hole_entrances:
|
||||||
@@ -1375,6 +1402,31 @@ def link_entrances(world, player):
|
|||||||
doors.append('Hyrule Castle Entrance (South)')
|
doors.append('Hyrule Castle Entrance (South)')
|
||||||
entrances.append('Hyrule Castle Entrance (South)')
|
entrances.append('Hyrule Castle Entrance (South)')
|
||||||
caves.append(('Hyrule Castle Exit (South)', 'Hyrule Castle Exit (West)', 'Hyrule Castle Exit (East)'))
|
caves.append(('Hyrule Castle Exit (South)', 'Hyrule Castle Exit (West)', 'Hyrule Castle Exit (East)'))
|
||||||
|
|
||||||
|
if not world.shufflelinks[player]:
|
||||||
|
if not invFlag:
|
||||||
|
links_house = 'Links House'
|
||||||
|
else:
|
||||||
|
links_house = 'Big Shop Shop'
|
||||||
|
else:
|
||||||
|
if not invFlag:
|
||||||
|
links_house_doors = [i for i in doors if i not in Sanctuary_Doors + Isolated_LH_Doors]
|
||||||
|
else:
|
||||||
|
links_house_doors = [i for i in doors if i not in Inverted_Dark_Sanctuary_Doors + Isolated_LH_Doors]
|
||||||
|
links_house = random.choice(links_house_doors)
|
||||||
|
connect_two_way(world, links_house, 'Links House Exit', player)
|
||||||
|
doors.remove(links_house)
|
||||||
|
exit_pool.remove(links_house)
|
||||||
|
|
||||||
|
if not invFlag:
|
||||||
|
sanc_doors = [door for door in Sanctuary_Doors if door in exit_pool]
|
||||||
|
else:
|
||||||
|
sanc_doors = [door for door in Inverted_Dark_Sanctuary_Doors if door in exit_pool]
|
||||||
|
sanc_door = random.choice(sanc_doors)
|
||||||
|
exit_pool.remove(sanc_door)
|
||||||
|
doors.remove(sanc_door)
|
||||||
|
connect_entrance(world, sanc_door, 'Dark Sanctuary Hint', player)
|
||||||
|
world.get_entrance('Dark Sanctuary Hint Exit', player).connect(world.get_entrance(sanc_door, player).parent_region)
|
||||||
|
|
||||||
# now let's deal with mandatory reachable stuff
|
# now let's deal with mandatory reachable stuff
|
||||||
def extract_reachable_exit(cavelist):
|
def extract_reachable_exit(cavelist):
|
||||||
@@ -1393,7 +1445,7 @@ def link_entrances(world, player):
|
|||||||
cavelist.remove(candidate)
|
cavelist.remove(candidate)
|
||||||
return candidate
|
return candidate
|
||||||
|
|
||||||
def connect_reachable_exit(entrance, caves, doors):
|
def connect_reachable_exit(entrance, caves, doors, exit_pool):
|
||||||
cave = extract_reachable_exit(caves)
|
cave = extract_reachable_exit(caves)
|
||||||
|
|
||||||
exit = cave[-1]
|
exit = cave[-1]
|
||||||
@@ -1401,18 +1453,19 @@ def link_entrances(world, player):
|
|||||||
connect_exit(world, exit, entrance, player)
|
connect_exit(world, exit, entrance, player)
|
||||||
connect_entrance(world, doors.pop(), exit, player)
|
connect_entrance(world, doors.pop(), exit, player)
|
||||||
# rest of cave now is forced to be in this world
|
# rest of cave now is forced to be in this world
|
||||||
|
exit_pool.remove(entrance)
|
||||||
caves.append(cave)
|
caves.append(cave)
|
||||||
|
|
||||||
# connect mandatory exits
|
# connect mandatory exits
|
||||||
for entrance in entrances_must_exits:
|
for entrance in entrances_must_exits:
|
||||||
connect_reachable_exit(entrance, caves, doors)
|
connect_reachable_exit(entrance, caves, doors, exit_pool)
|
||||||
|
|
||||||
# place old man, has limited options
|
# place old man, has limited options
|
||||||
# exit has to come from specific set of doors, the entrance is free to move about
|
# exit has to come from specific set of doors, the entrance is free to move about
|
||||||
old_man_entrances = [entrance for entrance in old_man_entrances if entrance in entrances]
|
old_man_entrances = [entrance for entrance in old_man_entrances if entrance in exit_pool]
|
||||||
random.shuffle(old_man_entrances)
|
random.shuffle(old_man_entrances)
|
||||||
old_man_exit = old_man_entrances.pop()
|
old_man_exit = old_man_entrances.pop()
|
||||||
entrances.remove(old_man_exit)
|
exit_pool.remove(old_man_exit)
|
||||||
|
|
||||||
connect_exit(world, 'Old Man Cave Exit (East)', old_man_exit, player)
|
connect_exit(world, 'Old Man Cave Exit (East)', old_man_exit, player)
|
||||||
connect_entrance(world, doors.pop(), 'Old Man Cave Exit (East)', player)
|
connect_entrance(world, doors.pop(), 'Old Man Cave Exit (East)', player)
|
||||||
@@ -1438,16 +1491,24 @@ def link_entrances(world, player):
|
|||||||
random.shuffle(blacksmith_doors)
|
random.shuffle(blacksmith_doors)
|
||||||
blacksmith_hut = blacksmith_doors.pop()
|
blacksmith_hut = blacksmith_doors.pop()
|
||||||
connect_entrance(world, blacksmith_hut, 'Blacksmiths Hut', player)
|
connect_entrance(world, blacksmith_hut, 'Blacksmiths Hut', player)
|
||||||
bomb_shop_doors.extend(blacksmith_doors)
|
doors.remove(blacksmith_hut)
|
||||||
|
exit_pool.remove(blacksmith_hut)
|
||||||
|
|
||||||
# place dam and pyramid fairy, have limited options
|
# place dam and pyramid fairy, have limited options
|
||||||
random.shuffle(bomb_shop_doors)
|
random.shuffle(bomb_shop_doors)
|
||||||
bomb_shop = bomb_shop_doors.pop()
|
bomb_shop = bomb_shop_doors.pop()
|
||||||
connect_entrance(world, bomb_shop, 'Big Bomb Shop', player)
|
connect_entrance(world, bomb_shop, 'Big Bomb Shop', player)
|
||||||
single_doors.extend(bomb_shop_doors)
|
doors.remove(bomb_shop)
|
||||||
|
exit_pool.remove(bomb_shop)
|
||||||
|
|
||||||
# tavern back door cannot be shuffled yet
|
# handle remaining caves
|
||||||
connect_doors(world, ['Tavern North'], ['Tavern'], player)
|
for cave in caves:
|
||||||
|
if isinstance(cave, str):
|
||||||
|
cave = (cave,)
|
||||||
|
|
||||||
|
for exit in cave:
|
||||||
|
connect_exit(world, exit, exit_pool.pop(), player)
|
||||||
|
connect_entrance(world, doors.pop(), exit, player)
|
||||||
|
|
||||||
# place remaining doors
|
# place remaining doors
|
||||||
connect_doors(world, single_doors, door_targets, player)
|
connect_doors(world, single_doors, door_targets, player)
|
||||||
|
|||||||
2
Main.py
2
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.4-u'
|
__version__ = '0.4.0.5-u'
|
||||||
|
|
||||||
|
|
||||||
class EnemizerError(RuntimeError):
|
class EnemizerError(RuntimeError):
|
||||||
|
|||||||
@@ -190,9 +190,9 @@ def roll_settings(weights):
|
|||||||
|
|
||||||
ret.item_functionality = get_choice('item_functionality')
|
ret.item_functionality = get_choice('item_functionality')
|
||||||
|
|
||||||
old_style_bosses = {'simple': 'basic',
|
old_style_bosses = {'basic': 'simple',
|
||||||
'full': 'normal',
|
'normal': 'full',
|
||||||
'random': 'chaos'}
|
'chaos': 'random'}
|
||||||
boss_choice = get_choice('boss_shuffle')
|
boss_choice = get_choice('boss_shuffle')
|
||||||
if boss_choice in old_style_bosses.keys():
|
if boss_choice in old_style_bosses.keys():
|
||||||
boss_choice = old_style_bosses[boss_choice]
|
boss_choice = old_style_bosses[boss_choice]
|
||||||
|
|||||||
@@ -295,7 +295,7 @@ def shuffle_pots(world, player):
|
|||||||
elif old_pot.item == PotItem.Switch:
|
elif old_pot.item == PotItem.Switch:
|
||||||
available_pots = (pot for pot in new_pots if (pot.room == old_pot.room or pot.room in movable_switch_rooms[old_pot.room]) and not (pot.flags & PotFlags.NoSwitch))
|
available_pots = (pot for pot in new_pots if (pot.room == old_pot.room or pot.room in movable_switch_rooms[old_pot.room]) and not (pot.flags & PotFlags.NoSwitch))
|
||||||
elif old_pot.item == PotItem.Key:
|
elif old_pot.item == PotItem.Key:
|
||||||
if world.doorShuffle[player] == 'vanilla' and not world.retro[player] and not world.keydropshuffle[player] and world.logic != 'nologic':
|
if world.doorShuffle[player] == 'vanilla' and not world.retro[player] and not world.keydropshuffle[player] and world.logic[player] != 'nologic':
|
||||||
available_pots = (pot for pot in new_pots if pot.room not in invalid_key_rooms)
|
available_pots = (pot for pot in new_pots if pot.room not in invalid_key_rooms)
|
||||||
else:
|
else:
|
||||||
available_pots = new_pots
|
available_pots = new_pots
|
||||||
|
|||||||
@@ -10,6 +10,12 @@ Thanks to qadan, cheuer, & compiling
|
|||||||
|
|
||||||
# Bug Fixes and Notes.
|
# Bug Fixes and Notes.
|
||||||
|
|
||||||
|
* 0.4.0.5
|
||||||
|
* Insanity - less restrictions on exiting (all modes)
|
||||||
|
* Fix for simple bosses shuffle
|
||||||
|
* Fix for boss shuffle from Mystery.py
|
||||||
|
* Minor msu fade out bug (thanks codemann8)
|
||||||
|
* Other bug fixes (thanks Catobat)
|
||||||
* 0.4.0.4
|
* 0.4.0.4
|
||||||
* Added --shufflelinks option
|
* Added --shufflelinks option
|
||||||
* Moved spawning as a bunny indoors to experimental
|
* Moved spawning as a bunny indoors to experimental
|
||||||
|
|||||||
3
Rom.py
3
Rom.py
@@ -1347,9 +1347,6 @@ def patch_rom(world, rom, player, team, enemized, is_mystery=False):
|
|||||||
if item.name != 'Piece of Heart' or equip[0x36B] == 0:
|
if item.name != 'Piece of Heart' or equip[0x36B] == 0:
|
||||||
equip[0x36C] = min(equip[0x36C] + 0x08, 0xA0)
|
equip[0x36C] = min(equip[0x36C] + 0x08, 0xA0)
|
||||||
equip[0x36D] = min(equip[0x36D] + 0x08, 0xA0)
|
equip[0x36D] = min(equip[0x36D] + 0x08, 0xA0)
|
||||||
elif item.name == 'Pegasus Boots':
|
|
||||||
rom.write_byte(0x183015, 0x01)
|
|
||||||
ability_flags |= 0b00000100
|
|
||||||
else:
|
else:
|
||||||
raise RuntimeError(f'Unsupported item in starting equipment: {item.name}')
|
raise RuntimeError(f'Unsupported item in starting equipment: {item.name}')
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user