Move Factorio, Hollow Knight and Minecraft Options into AutoWorld
This commit is contained in:
parent
cc85edafc4
commit
7f8bb10fc5
|
@ -147,6 +147,9 @@ class MultiWorld():
|
||||||
for option_set in Options.option_sets:
|
for option_set in Options.option_sets:
|
||||||
for option in option_set:
|
for option in option_set:
|
||||||
setattr(self, option, getattr(args, option, {}))
|
setattr(self, option, getattr(args, option, {}))
|
||||||
|
for world in AutoWorld.AutoWorldRegister.world_types.values():
|
||||||
|
for option in world.options:
|
||||||
|
setattr(self, option, getattr(args, option, {}))
|
||||||
for player in self.player_ids:
|
for player in self.player_ids:
|
||||||
self.custom_data[player] = {}
|
self.custom_data[player] = {}
|
||||||
self.worlds[player] = AutoWorld.AutoWorldRegister.world_types[self.game[player]](self, player)
|
self.worlds[player] = AutoWorld.AutoWorldRegister.world_types[self.game[player]](self, player)
|
||||||
|
@ -1501,22 +1504,14 @@ class Spoiler(object):
|
||||||
outfile.write('Progression Balanced: %s\n' % (
|
outfile.write('Progression Balanced: %s\n' % (
|
||||||
'Yes' if self.metadata['progression_balancing'][player] else 'No'))
|
'Yes' if self.metadata['progression_balancing'][player] else 'No'))
|
||||||
outfile.write('Accessibility: %s\n' % self.metadata['accessibility'][player])
|
outfile.write('Accessibility: %s\n' % self.metadata['accessibility'][player])
|
||||||
if player in self.world.hk_player_ids:
|
options = self.world.worlds[player].options
|
||||||
for hk_option in Options.hollow_knight_options:
|
if options:
|
||||||
res = getattr(self.world, hk_option)[player]
|
for f_option in options:
|
||||||
outfile.write(f'{hk_option+":":33}{res}\n')
|
|
||||||
|
|
||||||
elif player in self.world.factorio_player_ids:
|
|
||||||
for f_option in Options.factorio_options:
|
|
||||||
res = getattr(self.world, f_option)[player]
|
res = getattr(self.world, f_option)[player]
|
||||||
outfile.write(f'{f_option+":":33}{bool_to_text(res) if type(res) == Options.Toggle else res.get_option_name()}\n')
|
outfile.write(f'{f_option+":":33}{bool_to_text(res) if type(res) == Options.Toggle else res.get_option_name()}\n')
|
||||||
|
|
||||||
elif player in self.world.minecraft_player_ids:
|
|
||||||
for mc_option in Options.minecraft_options:
|
|
||||||
res = getattr(self.world, mc_option)[player]
|
|
||||||
outfile.write(f'{mc_option+":":33}{bool_to_text(res) if type(res) == Options.Toggle else res.get_option_name()}\n')
|
|
||||||
|
|
||||||
elif player in self.world.alttp_player_ids:
|
if player in self.world.alttp_player_ids:
|
||||||
for team in range(self.world.teams):
|
for team in range(self.world.teams):
|
||||||
outfile.write('%s%s\n' % (
|
outfile.write('%s%s\n' % (
|
||||||
f"Hash - {self.world.player_names[player][team]} (Team {team + 1}): " if
|
f"Hash - {self.world.player_names[player][team]} (Team {team + 1}): " if
|
||||||
|
|
3
Main.py
3
Main.py
|
@ -519,10 +519,9 @@ def main(args, seed=None):
|
||||||
if player not in world.alttp_player_ids:
|
if player not in world.alttp_player_ids:
|
||||||
connect_names[name] = (i, player)
|
connect_names[name] = (i, player)
|
||||||
if world.hk_player_ids:
|
if world.hk_player_ids:
|
||||||
import Options
|
|
||||||
for slot in world.hk_player_ids:
|
for slot in world.hk_player_ids:
|
||||||
slots_data = slot_data[slot] = {}
|
slots_data = slot_data[slot] = {}
|
||||||
for option_name in Options.hollow_knight_options:
|
for option_name in world.worlds[slot].options:
|
||||||
option = getattr(world, option_name)[slot]
|
option = getattr(world, option_name)[slot]
|
||||||
slots_data[option_name] = int(option.value)
|
slots_data[option_name] = int(option.value)
|
||||||
for slot in world.minecraft_player_ids:
|
for slot in world.minecraft_player_ids:
|
||||||
|
|
38
Mystery.py
38
Mystery.py
|
@ -548,35 +548,27 @@ def roll_settings(weights: dict, plando_options: typing.Set[str] = frozenset(("b
|
||||||
|
|
||||||
if ret.game == "A Link to the Past":
|
if ret.game == "A Link to the Past":
|
||||||
roll_alttp_settings(ret, game_weights, plando_options)
|
roll_alttp_settings(ret, game_weights, plando_options)
|
||||||
elif ret.game == "Hollow Knight":
|
elif ret.game in AutoWorldRegister.world_types:
|
||||||
for option_name, option in Options.hollow_knight_options.items():
|
for option_name, option in AutoWorldRegister.world_types[ret.game].options.items():
|
||||||
setattr(ret, option_name, option.from_any(get_choice(option_name, game_weights)))
|
|
||||||
elif ret.game == "Factorio":
|
|
||||||
for option_name, option in Options.factorio_options.items():
|
|
||||||
if option_name in game_weights:
|
if option_name in game_weights:
|
||||||
if issubclass(option, Options.OptionDict): # get_choice should probably land in the Option class
|
if issubclass(option, Options.OptionDict):
|
||||||
setattr(ret, option_name, option.from_any(game_weights[option_name]))
|
setattr(ret, option_name, option.from_any(game_weights[option_name]))
|
||||||
else:
|
else:
|
||||||
setattr(ret, option_name, option.from_any(get_choice(option_name, game_weights)))
|
setattr(ret, option_name, option.from_any(get_choice(option_name, game_weights)))
|
||||||
else:
|
else:
|
||||||
setattr(ret, option_name, option(option.default))
|
setattr(ret, option_name, option(option.default))
|
||||||
elif ret.game == "Minecraft":
|
if ret.game == "Minecraft":
|
||||||
for option_name, option in Options.minecraft_options.items():
|
# bad hardcoded behavior to make this work for now
|
||||||
if option_name in game_weights:
|
ret.plando_connections = []
|
||||||
setattr(ret, option_name, option.from_any(get_choice(option_name, game_weights)))
|
if "connections" in plando_options:
|
||||||
else:
|
options = game_weights.get("plando_connections", [])
|
||||||
setattr(ret, option_name, option(option.default))
|
for placement in options:
|
||||||
# bad hardcoded behavior to make this work for now
|
if roll_percentage(get_choice("percentage", placement, 100)):
|
||||||
ret.plando_connections = []
|
ret.plando_connections.append(PlandoConnection(
|
||||||
if "connections" in plando_options:
|
get_choice("entrance", placement),
|
||||||
options = game_weights.get("plando_connections", [])
|
get_choice("exit", placement),
|
||||||
for placement in options:
|
get_choice("direction", placement, "both")
|
||||||
if roll_percentage(get_choice("percentage", placement, 100)):
|
))
|
||||||
ret.plando_connections.append(PlandoConnection(
|
|
||||||
get_choice("entrance", placement),
|
|
||||||
get_choice("exit", placement),
|
|
||||||
get_choice("direction", placement, "both")
|
|
||||||
))
|
|
||||||
else:
|
else:
|
||||||
raise Exception(f"Unsupported game {ret.game}")
|
raise Exception(f"Unsupported game {ret.game}")
|
||||||
return ret
|
return ret
|
||||||
|
|
153
Options.py
153
Options.py
|
@ -296,157 +296,12 @@ alttp_options: typing.Dict[str, type(Option)] = {
|
||||||
"shop_item_slots": ShopItemSlots,
|
"shop_item_slots": ShopItemSlots,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# replace with World.options
|
||||||
|
|
||||||
hollow_knight_randomize_options: typing.Dict[str, type(Option)] = {
|
|
||||||
"RandomizeDreamers": DefaultOnToggle,
|
|
||||||
"RandomizeSkills": DefaultOnToggle,
|
|
||||||
"RandomizeCharms": DefaultOnToggle,
|
|
||||||
"RandomizeKeys": DefaultOnToggle,
|
|
||||||
"RandomizeGeoChests": Toggle,
|
|
||||||
"RandomizeMaskShards": DefaultOnToggle,
|
|
||||||
"RandomizeVesselFragments": DefaultOnToggle,
|
|
||||||
"RandomizeCharmNotches": Toggle,
|
|
||||||
"RandomizePaleOre": DefaultOnToggle,
|
|
||||||
"RandomizeRancidEggs": Toggle,
|
|
||||||
"RandomizeRelics": DefaultOnToggle,
|
|
||||||
"RandomizeMaps": Toggle,
|
|
||||||
"RandomizeStags": Toggle,
|
|
||||||
"RandomizeGrubs": Toggle,
|
|
||||||
"RandomizeWhisperingRoots": Toggle,
|
|
||||||
"RandomizeRocks": Toggle,
|
|
||||||
"RandomizeSoulTotems": Toggle,
|
|
||||||
"RandomizePalaceTotems": Toggle,
|
|
||||||
"RandomizeLoreTablets": Toggle,
|
|
||||||
"RandomizeLifebloodCocoons": Toggle,
|
|
||||||
"RandomizeFlames": Toggle
|
|
||||||
}
|
|
||||||
|
|
||||||
hollow_knight_skip_options: typing.Dict[str, type(Option)] = {
|
|
||||||
"MILDSKIPS": Toggle,
|
|
||||||
"SPICYSKIPS": Toggle,
|
|
||||||
"FIREBALLSKIPS": Toggle,
|
|
||||||
"ACIDSKIPS": Toggle,
|
|
||||||
"SPIKETUNNELS": Toggle,
|
|
||||||
"DARKROOMS": Toggle,
|
|
||||||
"CURSED": Toggle,
|
|
||||||
"SHADESKIPS": Toggle,
|
|
||||||
}
|
|
||||||
|
|
||||||
hollow_knight_options: typing.Dict[str, type(Option)] = {**hollow_knight_randomize_options,
|
|
||||||
**hollow_knight_skip_options}
|
|
||||||
|
|
||||||
|
|
||||||
class MaxSciencePack(Choice):
|
|
||||||
option_automation_science_pack = 0
|
|
||||||
option_logistic_science_pack = 1
|
|
||||||
option_military_science_pack = 2
|
|
||||||
option_chemical_science_pack = 3
|
|
||||||
option_production_science_pack = 4
|
|
||||||
option_utility_science_pack = 5
|
|
||||||
option_space_science_pack = 6
|
|
||||||
default = 6
|
|
||||||
|
|
||||||
def get_allowed_packs(self):
|
|
||||||
return {option.replace("_", "-") for option, value in self.options.items() if value <= self.value} - \
|
|
||||||
{"space-science-pack"} # with rocket launch being the goal, post-launch techs don't make sense
|
|
||||||
|
|
||||||
|
|
||||||
class TechCost(Choice):
|
|
||||||
option_very_easy = 0
|
|
||||||
option_easy = 1
|
|
||||||
option_kind = 2
|
|
||||||
option_normal = 3
|
|
||||||
option_hard = 4
|
|
||||||
option_very_hard = 5
|
|
||||||
option_insane = 6
|
|
||||||
default = 3
|
|
||||||
|
|
||||||
|
|
||||||
class FreeSamples(Choice):
|
|
||||||
option_none = 0
|
|
||||||
option_single_craft = 1
|
|
||||||
option_half_stack = 2
|
|
||||||
option_stack = 3
|
|
||||||
default = 3
|
|
||||||
|
|
||||||
|
|
||||||
class TechTreeLayout(Choice):
|
|
||||||
option_single = 0
|
|
||||||
option_small_diamonds = 1
|
|
||||||
option_medium_diamonds = 2
|
|
||||||
option_large_diamonds = 3
|
|
||||||
option_small_pyramids = 4
|
|
||||||
option_medium_pyramids = 5
|
|
||||||
option_large_pyramids = 6
|
|
||||||
option_small_funnels = 7
|
|
||||||
option_medium_funnels = 8
|
|
||||||
option_large_funnels = 9
|
|
||||||
option_funnels = 4
|
|
||||||
alias_pyramid = 6
|
|
||||||
alias_funnel = 9
|
|
||||||
default = 0
|
|
||||||
|
|
||||||
|
|
||||||
class TechTreeInformation(Choice):
|
|
||||||
option_none = 0
|
|
||||||
option_advancement = 1
|
|
||||||
option_full = 2
|
|
||||||
default = 2
|
|
||||||
|
|
||||||
|
|
||||||
class RecipeTime(Choice):
|
|
||||||
option_vanilla = 0
|
|
||||||
option_fast = 1
|
|
||||||
option_normal = 2
|
|
||||||
option_slow = 4
|
|
||||||
option_chaos = 5
|
|
||||||
|
|
||||||
|
|
||||||
class FactorioStartItems(OptionDict):
|
|
||||||
default = {"burner-mining-drill": 19, "stone-furnace": 19}
|
|
||||||
|
|
||||||
|
|
||||||
factorio_options: typing.Dict[str, type(Option)] = {
|
|
||||||
"max_science_pack": MaxSciencePack,
|
|
||||||
"tech_tree_layout": TechTreeLayout,
|
|
||||||
"tech_cost": TechCost,
|
|
||||||
"free_samples": FreeSamples,
|
|
||||||
"tech_tree_information": TechTreeInformation,
|
|
||||||
"starting_items": FactorioStartItems,
|
|
||||||
"recipe_time": RecipeTime,
|
|
||||||
"imported_blueprints": DefaultOnToggle,
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
class AdvancementGoal(Choice):
|
|
||||||
option_few = 0
|
|
||||||
option_normal = 1
|
|
||||||
option_many = 2
|
|
||||||
default = 1
|
|
||||||
|
|
||||||
|
|
||||||
class CombatDifficulty(Choice):
|
|
||||||
option_easy = 0
|
|
||||||
option_normal = 1
|
|
||||||
option_hard = 2
|
|
||||||
default = 1
|
|
||||||
|
|
||||||
|
|
||||||
minecraft_options: typing.Dict[str, type(Option)] = {
|
|
||||||
"advancement_goal": AdvancementGoal,
|
|
||||||
"combat_difficulty": CombatDifficulty,
|
|
||||||
"include_hard_advancements": Toggle,
|
|
||||||
"include_insane_advancements": Toggle,
|
|
||||||
"include_postgame_advancements": Toggle,
|
|
||||||
"shuffle_structures": Toggle
|
|
||||||
}
|
|
||||||
|
|
||||||
option_sets = (
|
option_sets = (
|
||||||
minecraft_options,
|
# minecraft_options,
|
||||||
factorio_options,
|
# factorio_options,
|
||||||
alttp_options,
|
alttp_options,
|
||||||
hollow_knight_options
|
# hollow_knight_options
|
||||||
)
|
)
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import worlds.hk.Options
|
||||||
from BaseClasses import MultiWorld
|
from BaseClasses import MultiWorld
|
||||||
from worlds.hk.Regions import create_regions
|
from worlds.hk.Regions import create_regions
|
||||||
from worlds.hk import gen_hollow
|
from worlds.hk import gen_hollow
|
||||||
|
@ -9,10 +10,9 @@ class TestVanilla(TestBase):
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
self.world = MultiWorld(1)
|
self.world = MultiWorld(1)
|
||||||
self.world.game[1] = "Hollow Knight"
|
self.world.game[1] = "Hollow Knight"
|
||||||
import Options
|
for hk_option in worlds.hk.Options.hollow_knight_randomize_options:
|
||||||
for hk_option in Options.hollow_knight_randomize_options:
|
|
||||||
setattr(self.world, hk_option, {1: True})
|
setattr(self.world, hk_option, {1: True})
|
||||||
for hk_option, option in Options.hollow_knight_skip_options.items():
|
for hk_option, option in worlds.hk.Options.hollow_knight_skip_options.items():
|
||||||
setattr(self.world, hk_option, {1: option.default})
|
setattr(self.world, hk_option, {1: option.default})
|
||||||
create_regions(self.world, 1)
|
create_regions(self.world, 1)
|
||||||
gen_hollow(self.world, 1)
|
gen_hollow(self.world, 1)
|
|
@ -1,3 +1,4 @@
|
||||||
|
import worlds.minecraft.Options
|
||||||
from test.TestBase import TestBase
|
from test.TestBase import TestBase
|
||||||
from BaseClasses import MultiWorld
|
from BaseClasses import MultiWorld
|
||||||
from worlds.minecraft import minecraft_gen_item_pool
|
from worlds.minecraft import minecraft_gen_item_pool
|
||||||
|
@ -31,9 +32,9 @@ class TestMinecraft(TestBase):
|
||||||
exclusion_pools = ['hard', 'insane', 'postgame']
|
exclusion_pools = ['hard', 'insane', 'postgame']
|
||||||
for pool in exclusion_pools:
|
for pool in exclusion_pools:
|
||||||
setattr(self.world, f"include_{pool}_advancements", [False, False])
|
setattr(self.world, f"include_{pool}_advancements", [False, False])
|
||||||
setattr(self.world, "advancement_goal", [0, Options.AdvancementGoal(value=0)])
|
setattr(self.world, "advancement_goal", [0, worlds.minecraft.Options.AdvancementGoal(value=0)])
|
||||||
setattr(self.world, "shuffle_structures", [False, False])
|
setattr(self.world, "shuffle_structures", [False, False])
|
||||||
setattr(self.world, "combat_difficulty", [0, Options.CombatDifficulty(value=1)])
|
setattr(self.world, "combat_difficulty", [0, worlds.minecraft.Options.CombatDifficulty(value=1)])
|
||||||
minecraft_create_regions(self.world, 1)
|
minecraft_create_regions(self.world, 1)
|
||||||
link_minecraft_structures(self.world, 1)
|
link_minecraft_structures(self.world, 1)
|
||||||
minecraft_gen_item_pool(self.world, 1)
|
minecraft_gen_item_pool(self.world, 1)
|
||||||
|
|
|
@ -27,6 +27,7 @@ class World(metaclass=AutoWorldRegister):
|
||||||
|
|
||||||
world: MultiWorld
|
world: MultiWorld
|
||||||
player: int
|
player: int
|
||||||
|
options: dict = {}
|
||||||
|
|
||||||
def __init__(self, world: MultiWorld, player: int):
|
def __init__(self, world: MultiWorld, player: int):
|
||||||
self.world = world
|
self.world = world
|
||||||
|
|
|
@ -751,18 +751,11 @@ bonk_addresses = [0x4CF6C, 0x4CFBA, 0x4CFE0, 0x4CFFB, 0x4D018, 0x4D01B, 0x4D028,
|
||||||
0x4D3F8, 0x4D416, 0x4D420, 0x4D423, 0x4D42D, 0x4D449, 0x4D48C, 0x4D4D9, 0x4D4DC, 0x4D4E3,
|
0x4D3F8, 0x4D416, 0x4D420, 0x4D423, 0x4D42D, 0x4D449, 0x4D48C, 0x4D4D9, 0x4D4DC, 0x4D4E3,
|
||||||
0x4D504, 0x4D507, 0x4D55E, 0x4D56A]
|
0x4D504, 0x4D507, 0x4D55E, 0x4D56A]
|
||||||
|
|
||||||
def get_nonnative_item_sprite(game: str) -> int:
|
|
||||||
|
def get_nonnative_item_sprite(item: str) -> int:
|
||||||
return 0x6B # set all non-native sprites to Power Star as per 13 to 2 vote at
|
return 0x6B # set all non-native sprites to Power Star as per 13 to 2 vote at
|
||||||
# https://discord.com/channels/731205301247803413/827141303330406408/852102450822905886
|
# https://discord.com/channels/731205301247803413/827141303330406408/852102450822905886
|
||||||
|
|
||||||
# def get_nonnative_item_sprite(game):
|
|
||||||
# game_to_id = {
|
|
||||||
# "Factorio": 0x09, # Hammer
|
|
||||||
# "Hollow Knight": 0x21, # Bug Catching Net
|
|
||||||
# "Minecraft": 0x13, # Shovel
|
|
||||||
# }
|
|
||||||
# return game_to_id.get(game, 0x6B) # default to Power Star
|
|
||||||
|
|
||||||
|
|
||||||
def patch_rom(world, rom, player, team, enemized):
|
def patch_rom(world, rom, player, team, enemized):
|
||||||
local_random = world.slot_seeds[player]
|
local_random = world.slot_seeds[player]
|
||||||
|
@ -1724,20 +1717,7 @@ def write_custom_shops(rom, world, player):
|
||||||
if item is None:
|
if item is None:
|
||||||
break
|
break
|
||||||
if not item['item'] in item_table: # item not native to ALTTP
|
if not item['item'] in item_table: # item not native to ALTTP
|
||||||
# This is a terrible way to do this, please fix later
|
item_code = get_nonnative_item_sprite(item['item'])
|
||||||
from worlds.hk.Items import lookup_id_to_name as hk_lookup
|
|
||||||
from worlds.factorio.Technologies import lookup_id_to_name as factorio_lookup
|
|
||||||
from worlds.minecraft.Items import lookup_id_to_name as mc_lookup
|
|
||||||
item_name = item['item']
|
|
||||||
if item_name in hk_lookup.values():
|
|
||||||
item_game = 'Hollow Knight'
|
|
||||||
elif item_name in factorio_lookup.values():
|
|
||||||
item_game = 'Factorio'
|
|
||||||
elif item_name in mc_lookup.values():
|
|
||||||
item_game = 'Minecraft'
|
|
||||||
else:
|
|
||||||
item_game = 'Generic'
|
|
||||||
item_code = get_nonnative_item_sprite(item_game)
|
|
||||||
else:
|
else:
|
||||||
item_code = ItemFactory(item['item'], player).code
|
item_code = ItemFactory(item['item'], player).code
|
||||||
if item['item'] == 'Single Arrow' and item['player'] == 0 and world.retro[player]:
|
if item['item'] == 'Single Arrow' and item['player'] == 0 and world.retro[player]:
|
||||||
|
|
|
@ -9,7 +9,7 @@ import json
|
||||||
import jinja2
|
import jinja2
|
||||||
import Utils
|
import Utils
|
||||||
import shutil
|
import shutil
|
||||||
import Options
|
from . import Options
|
||||||
from BaseClasses import MultiWorld
|
from BaseClasses import MultiWorld
|
||||||
from .Technologies import tech_table, rocket_recipes, recipes, free_sample_blacklist
|
from .Technologies import tech_table, rocket_recipes, recipes, free_sample_blacklist
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,85 @@
|
||||||
|
import typing
|
||||||
|
|
||||||
|
from Options import Choice, OptionDict, Option, DefaultOnToggle
|
||||||
|
|
||||||
|
|
||||||
|
class MaxSciencePack(Choice):
|
||||||
|
option_automation_science_pack = 0
|
||||||
|
option_logistic_science_pack = 1
|
||||||
|
option_military_science_pack = 2
|
||||||
|
option_chemical_science_pack = 3
|
||||||
|
option_production_science_pack = 4
|
||||||
|
option_utility_science_pack = 5
|
||||||
|
option_space_science_pack = 6
|
||||||
|
default = 6
|
||||||
|
|
||||||
|
def get_allowed_packs(self):
|
||||||
|
return {option.replace("_", "-") for option, value in self.options.items() if value <= self.value} - \
|
||||||
|
{"space-science-pack"} # with rocket launch being the goal, post-launch techs don't make sense
|
||||||
|
|
||||||
|
|
||||||
|
class TechCost(Choice):
|
||||||
|
option_very_easy = 0
|
||||||
|
option_easy = 1
|
||||||
|
option_kind = 2
|
||||||
|
option_normal = 3
|
||||||
|
option_hard = 4
|
||||||
|
option_very_hard = 5
|
||||||
|
option_insane = 6
|
||||||
|
default = 3
|
||||||
|
|
||||||
|
|
||||||
|
class FreeSamples(Choice):
|
||||||
|
option_none = 0
|
||||||
|
option_single_craft = 1
|
||||||
|
option_half_stack = 2
|
||||||
|
option_stack = 3
|
||||||
|
default = 3
|
||||||
|
|
||||||
|
|
||||||
|
class TechTreeLayout(Choice):
|
||||||
|
option_single = 0
|
||||||
|
option_small_diamonds = 1
|
||||||
|
option_medium_diamonds = 2
|
||||||
|
option_large_diamonds = 3
|
||||||
|
option_small_pyramids = 4
|
||||||
|
option_medium_pyramids = 5
|
||||||
|
option_large_pyramids = 6
|
||||||
|
option_small_funnels = 7
|
||||||
|
option_medium_funnels = 8
|
||||||
|
option_large_funnels = 9
|
||||||
|
option_funnels = 4
|
||||||
|
alias_pyramid = 6
|
||||||
|
alias_funnel = 9
|
||||||
|
default = 0
|
||||||
|
|
||||||
|
|
||||||
|
class TechTreeInformation(Choice):
|
||||||
|
option_none = 0
|
||||||
|
option_advancement = 1
|
||||||
|
option_full = 2
|
||||||
|
default = 2
|
||||||
|
|
||||||
|
|
||||||
|
class RecipeTime(Choice):
|
||||||
|
option_vanilla = 0
|
||||||
|
option_fast = 1
|
||||||
|
option_normal = 2
|
||||||
|
option_slow = 4
|
||||||
|
option_chaos = 5
|
||||||
|
|
||||||
|
|
||||||
|
class FactorioStartItems(OptionDict):
|
||||||
|
default = {"burner-mining-drill": 19, "stone-furnace": 19}
|
||||||
|
|
||||||
|
|
||||||
|
factorio_options: typing.Dict[str, type(Option)] = {
|
||||||
|
"max_science_pack": MaxSciencePack,
|
||||||
|
"tech_tree_layout": TechTreeLayout,
|
||||||
|
"tech_cost": TechCost,
|
||||||
|
"free_samples": FreeSamples,
|
||||||
|
"tech_tree_information": TechTreeInformation,
|
||||||
|
"starting_items": FactorioStartItems,
|
||||||
|
"recipe_time": RecipeTime,
|
||||||
|
"imported_blueprints": DefaultOnToggle,
|
||||||
|
}
|
|
@ -1,7 +1,6 @@
|
||||||
from typing import Dict, List, Set
|
from typing import Dict, List, Set
|
||||||
|
|
||||||
from BaseClasses import MultiWorld
|
from worlds.factorio.Options import TechTreeLayout
|
||||||
from Options import TechTreeLayout
|
|
||||||
|
|
||||||
funnel_layers = {TechTreeLayout.option_small_funnels: 3,
|
funnel_layers = {TechTreeLayout.option_small_funnels: 3,
|
||||||
TechTreeLayout.option_medium_funnels: 4,
|
TechTreeLayout.option_medium_funnels: 4,
|
||||||
|
|
|
@ -4,11 +4,12 @@ from typing import Dict, Set, FrozenSet
|
||||||
import os
|
import os
|
||||||
import json
|
import json
|
||||||
|
|
||||||
import Options
|
|
||||||
import Utils
|
import Utils
|
||||||
import logging
|
import logging
|
||||||
import functools
|
import functools
|
||||||
|
|
||||||
|
from . import Options
|
||||||
|
|
||||||
factorio_id = 2 ** 17
|
factorio_id = 2 ** 17
|
||||||
source_folder = Utils.local_path("data", "factorio")
|
source_folder = Utils.local_path("data", "factorio")
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@ from .Technologies import tech_table, recipe_sources, technology_table, advancem
|
||||||
all_ingredient_names, required_technologies, get_rocket_requirements, rocket_recipes
|
all_ingredient_names, required_technologies, get_rocket_requirements, rocket_recipes
|
||||||
from .Shapes import get_shapes
|
from .Shapes import get_shapes
|
||||||
from .Mod import generate_mod
|
from .Mod import generate_mod
|
||||||
|
from .Options import factorio_options
|
||||||
|
|
||||||
class Factorio(World):
|
class Factorio(World):
|
||||||
game: str = "Factorio"
|
game: str = "Factorio"
|
||||||
|
@ -80,6 +80,8 @@ class Factorio(World):
|
||||||
|
|
||||||
world.completion_condition[player] = lambda state: state.has('Victory', player)
|
world.completion_condition[player] = lambda state: state.has('Victory', player)
|
||||||
|
|
||||||
|
options = factorio_options
|
||||||
|
|
||||||
def set_custom_technologies(world: MultiWorld, player: int):
|
def set_custom_technologies(world: MultiWorld, player: int):
|
||||||
custom_technologies = {}
|
custom_technologies = {}
|
||||||
allowed_packs = world.max_science_pack[player].get_allowed_packs()
|
allowed_packs = world.max_science_pack[player].get_allowed_packs()
|
||||||
|
|
|
@ -0,0 +1,39 @@
|
||||||
|
import typing
|
||||||
|
|
||||||
|
from Options import Option, DefaultOnToggle, Toggle
|
||||||
|
|
||||||
|
hollow_knight_randomize_options: typing.Dict[str, type(Option)] = {
|
||||||
|
"RandomizeDreamers": DefaultOnToggle,
|
||||||
|
"RandomizeSkills": DefaultOnToggle,
|
||||||
|
"RandomizeCharms": DefaultOnToggle,
|
||||||
|
"RandomizeKeys": DefaultOnToggle,
|
||||||
|
"RandomizeGeoChests": Toggle,
|
||||||
|
"RandomizeMaskShards": DefaultOnToggle,
|
||||||
|
"RandomizeVesselFragments": DefaultOnToggle,
|
||||||
|
"RandomizeCharmNotches": Toggle,
|
||||||
|
"RandomizePaleOre": DefaultOnToggle,
|
||||||
|
"RandomizeRancidEggs": Toggle,
|
||||||
|
"RandomizeRelics": DefaultOnToggle,
|
||||||
|
"RandomizeMaps": Toggle,
|
||||||
|
"RandomizeStags": Toggle,
|
||||||
|
"RandomizeGrubs": Toggle,
|
||||||
|
"RandomizeWhisperingRoots": Toggle,
|
||||||
|
"RandomizeRocks": Toggle,
|
||||||
|
"RandomizeSoulTotems": Toggle,
|
||||||
|
"RandomizePalaceTotems": Toggle,
|
||||||
|
"RandomizeLoreTablets": Toggle,
|
||||||
|
"RandomizeLifebloodCocoons": Toggle,
|
||||||
|
"RandomizeFlames": Toggle
|
||||||
|
}
|
||||||
|
hollow_knight_skip_options: typing.Dict[str, type(Option)] = {
|
||||||
|
"MILDSKIPS": Toggle,
|
||||||
|
"SPICYSKIPS": Toggle,
|
||||||
|
"FIREBALLSKIPS": Toggle,
|
||||||
|
"ACIDSKIPS": Toggle,
|
||||||
|
"SPIKETUNNELS": Toggle,
|
||||||
|
"DARKROOMS": Toggle,
|
||||||
|
"CURSED": Toggle,
|
||||||
|
"SHADESKIPS": Toggle,
|
||||||
|
}
|
||||||
|
hollow_knight_options: typing.Dict[str, type(Option)] = {**hollow_knight_randomize_options,
|
||||||
|
**hollow_knight_skip_options}
|
|
@ -0,0 +1,27 @@
|
||||||
|
import typing
|
||||||
|
|
||||||
|
from Options import Choice, Option, Toggle
|
||||||
|
|
||||||
|
|
||||||
|
class AdvancementGoal(Choice):
|
||||||
|
option_few = 0
|
||||||
|
option_normal = 1
|
||||||
|
option_many = 2
|
||||||
|
default = 1
|
||||||
|
|
||||||
|
|
||||||
|
class CombatDifficulty(Choice):
|
||||||
|
option_easy = 0
|
||||||
|
option_normal = 1
|
||||||
|
option_hard = 2
|
||||||
|
default = 1
|
||||||
|
|
||||||
|
|
||||||
|
minecraft_options: typing.Dict[str, type(Option)] = {
|
||||||
|
"advancement_goal": AdvancementGoal,
|
||||||
|
"combat_difficulty": CombatDifficulty,
|
||||||
|
"include_hard_advancements": Toggle,
|
||||||
|
"include_insane_advancements": Toggle,
|
||||||
|
"include_postgame_advancements": Toggle,
|
||||||
|
"shuffle_structures": Toggle
|
||||||
|
}
|
|
@ -1,17 +1,16 @@
|
||||||
from ..generic.Rules import set_rule
|
from ..generic.Rules import set_rule
|
||||||
from .Locations import exclusion_table, events_table
|
from .Locations import exclusion_table, events_table
|
||||||
from BaseClasses import Region, Entrance, Location, MultiWorld, Item
|
from BaseClasses import MultiWorld
|
||||||
from Options import AdvancementGoal
|
|
||||||
|
|
||||||
def set_rules(world: MultiWorld, player: int):
|
def set_rules(world: MultiWorld, player: int):
|
||||||
|
|
||||||
def reachable_locations(state):
|
def reachable_locations(state):
|
||||||
postgame_advancements = set(exclusion_table['postgame'].keys())
|
postgame_advancements = set(exclusion_table['postgame'].keys())
|
||||||
postgame_advancements.add('Free the End')
|
postgame_advancements.add('Free the End')
|
||||||
for event in events_table.keys():
|
for event in events_table.keys():
|
||||||
postgame_advancements.add(event)
|
postgame_advancements.add(event)
|
||||||
return [location for location in world.get_locations() if
|
return [location for location in world.get_locations() if
|
||||||
(player is None or location.player == player) and
|
(player is None or location.player == player) and
|
||||||
(location.name not in postgame_advancements) and
|
(location.name not in postgame_advancements) and
|
||||||
location.can_reach(state)]
|
location.can_reach(state)]
|
||||||
|
|
||||||
|
@ -19,18 +18,22 @@ def set_rules(world: MultiWorld, player: int):
|
||||||
goal_map = {
|
goal_map = {
|
||||||
'few': 30,
|
'few': 30,
|
||||||
'normal': 50,
|
'normal': 50,
|
||||||
'many': 70
|
'many': 70
|
||||||
}
|
}
|
||||||
goal = goal_map[getattr(world, 'advancement_goal')[player].get_option_name()]
|
goal = goal_map[getattr(world, 'advancement_goal')[player].get_option_name()]
|
||||||
can_complete = lambda state: len(reachable_locations(state)) >= goal and state.can_reach('The End', 'Region', player) and state.can_kill_ender_dragon(player)
|
can_complete = lambda state: len(reachable_locations(state)) >= goal and state.can_reach('The End', 'Region',
|
||||||
|
player) and state.can_kill_ender_dragon(
|
||||||
|
player)
|
||||||
|
|
||||||
if world.logic[player] != 'nologic':
|
if world.logic[player] != 'nologic':
|
||||||
world.completion_condition[player] = lambda state: state.has('Victory', player)
|
world.completion_condition[player] = lambda state: state.has('Victory', player)
|
||||||
|
|
||||||
set_rule(world.get_entrance("Nether Portal", player), lambda state: state.has('Flint and Steel', player) and
|
set_rule(world.get_entrance("Nether Portal", player), lambda state: state.has('Flint and Steel', player) and
|
||||||
(state.has('Bucket', player) or state.has('Progressive Tools', player, 3)) and
|
(state.has('Bucket', player) or state.has(
|
||||||
|
'Progressive Tools', player, 3)) and
|
||||||
state.has_iron_ingots(player))
|
state.has_iron_ingots(player))
|
||||||
set_rule(world.get_entrance("End Portal", player), lambda state: state.enter_stronghold(player) and state.has('3 Ender Pearls', player, 4))
|
set_rule(world.get_entrance("End Portal", player),
|
||||||
|
lambda state: state.enter_stronghold(player) and state.has('3 Ender Pearls', player, 4))
|
||||||
set_rule(world.get_entrance("Overworld Structure 1", player), lambda state: state.can_adventure(player))
|
set_rule(world.get_entrance("Overworld Structure 1", player), lambda state: state.can_adventure(player))
|
||||||
set_rule(world.get_entrance("Overworld Structure 2", player), lambda state: state.can_adventure(player))
|
set_rule(world.get_entrance("Overworld Structure 2", player), lambda state: state.can_adventure(player))
|
||||||
set_rule(world.get_entrance("Nether Structure 1", player), lambda state: state.can_adventure(player))
|
set_rule(world.get_entrance("Nether Structure 1", player), lambda state: state.can_adventure(player))
|
||||||
|
@ -41,108 +44,178 @@ def set_rules(world: MultiWorld, player: int):
|
||||||
|
|
||||||
set_rule(world.get_location("Who is Cutting Onions?", player), lambda state: state.can_piglin_trade(player))
|
set_rule(world.get_location("Who is Cutting Onions?", player), lambda state: state.can_piglin_trade(player))
|
||||||
set_rule(world.get_location("Oh Shiny", player), lambda state: state.can_piglin_trade(player))
|
set_rule(world.get_location("Oh Shiny", player), lambda state: state.can_piglin_trade(player))
|
||||||
set_rule(world.get_location("Suit Up", player), lambda state: state.has("Progressive Armor", player) and state.has_iron_ingots(player))
|
set_rule(world.get_location("Suit Up", player),
|
||||||
set_rule(world.get_location("Very Very Frightening", player), lambda state: state.has("Channeling Book", player) and state.can_use_anvil(player) and state.can_enchant(player) and \
|
lambda state: state.has("Progressive Armor", player) and state.has_iron_ingots(player))
|
||||||
((world.get_region('Village', player).entrances[0].parent_region.name != 'The End' and state.can_reach('Village', 'Region', player)) or state.can_reach('Zombie Doctor', 'Location', player))) # need villager into the overworld for lightning strike
|
set_rule(world.get_location("Very Very Frightening", player),
|
||||||
set_rule(world.get_location("Hot Stuff", player), lambda state: state.has("Bucket", player) and state.has_iron_ingots(player))
|
lambda state: state.has("Channeling Book", player) and state.can_use_anvil(player) and state.can_enchant(
|
||||||
set_rule(world.get_location("Free the End", player), lambda state: can_complete(state) and state.has('Ingot Crafting', player) and state.can_reach('The Nether', 'Region', player))
|
player) and \
|
||||||
set_rule(world.get_location("A Furious Cocktail", player), lambda state: state.can_brew_potions(player) and
|
((world.get_region('Village', player).entrances[
|
||||||
state.has("Fishing Rod", player) and # Water Breathing
|
0].parent_region.name != 'The End' and state.can_reach('Village', 'Region',
|
||||||
state.can_reach('The Nether', 'Region', player) and # Regeneration, Fire Resistance, gold nuggets
|
player)) or state.can_reach(
|
||||||
state.can_reach('Village', 'Region', player) and # Night Vision, Invisibility
|
'Zombie Doctor', 'Location',
|
||||||
state.can_reach('Bring Home the Beacon', 'Location', player)) # Resistance
|
player))) # need villager into the overworld for lightning strike
|
||||||
|
set_rule(world.get_location("Hot Stuff", player),
|
||||||
|
lambda state: state.has("Bucket", player) and state.has_iron_ingots(player))
|
||||||
|
set_rule(world.get_location("Free the End", player),
|
||||||
|
lambda state: can_complete(state) and state.has('Ingot Crafting', player) and state.can_reach('The Nether',
|
||||||
|
'Region',
|
||||||
|
player))
|
||||||
|
set_rule(world.get_location("A Furious Cocktail", player), lambda state: state.can_brew_potions(player) and
|
||||||
|
state.has("Fishing Rod",
|
||||||
|
player) and # Water Breathing
|
||||||
|
state.can_reach('The Nether', 'Region',
|
||||||
|
player) and # Regeneration, Fire Resistance, gold nuggets
|
||||||
|
state.can_reach('Village', 'Region',
|
||||||
|
player) and # Night Vision, Invisibility
|
||||||
|
state.can_reach('Bring Home the Beacon',
|
||||||
|
'Location',
|
||||||
|
player)) # Resistance
|
||||||
set_rule(world.get_location("Best Friends Forever", player), lambda state: True)
|
set_rule(world.get_location("Best Friends Forever", player), lambda state: True)
|
||||||
set_rule(world.get_location("Bring Home the Beacon", player), lambda state: state.can_kill_wither(player) and state.has_diamond_pickaxe(player) and
|
set_rule(world.get_location("Bring Home the Beacon", player),
|
||||||
state.has("Ingot Crafting", player) and state.has("Resource Blocks", player))
|
lambda state: state.can_kill_wither(player) and state.has_diamond_pickaxe(player) and
|
||||||
set_rule(world.get_location("Not Today, Thank You", player), lambda state: state.has("Shield", player) and state.has_iron_ingots(player))
|
state.has("Ingot Crafting", player) and state.has("Resource Blocks", player))
|
||||||
set_rule(world.get_location("Isn't It Iron Pick", player), lambda state: state.has("Progressive Tools", player, 2) and state.has_iron_ingots(player))
|
set_rule(world.get_location("Not Today, Thank You", player),
|
||||||
|
lambda state: state.has("Shield", player) and state.has_iron_ingots(player))
|
||||||
|
set_rule(world.get_location("Isn't It Iron Pick", player),
|
||||||
|
lambda state: state.has("Progressive Tools", player, 2) and state.has_iron_ingots(player))
|
||||||
set_rule(world.get_location("Local Brewery", player), lambda state: state.can_brew_potions(player))
|
set_rule(world.get_location("Local Brewery", player), lambda state: state.can_brew_potions(player))
|
||||||
set_rule(world.get_location("The Next Generation", player), lambda state: can_complete(state))
|
set_rule(world.get_location("The Next Generation", player), lambda state: can_complete(state))
|
||||||
set_rule(world.get_location("Fishy Business", player), lambda state: state.has("Fishing Rod", player))
|
set_rule(world.get_location("Fishy Business", player), lambda state: state.has("Fishing Rod", player))
|
||||||
set_rule(world.get_location("Hot Tourist Destinations", player), lambda state: True)
|
set_rule(world.get_location("Hot Tourist Destinations", player), lambda state: True)
|
||||||
set_rule(world.get_location("This Boat Has Legs", player), lambda state: (state.fortress_loot(player) or state.complete_raid(player)) and state.has("Fishing Rod", player))
|
set_rule(world.get_location("This Boat Has Legs", player),
|
||||||
|
lambda state: (state.fortress_loot(player) or state.complete_raid(player)) and state.has("Fishing Rod",
|
||||||
|
player))
|
||||||
set_rule(world.get_location("Sniper Duel", player), lambda state: state.has("Archery", player))
|
set_rule(world.get_location("Sniper Duel", player), lambda state: state.has("Archery", player))
|
||||||
set_rule(world.get_location("Nether", player), lambda state: True)
|
set_rule(world.get_location("Nether", player), lambda state: True)
|
||||||
set_rule(world.get_location("Great View From Up Here", player), lambda state: state.basic_combat(player))
|
set_rule(world.get_location("Great View From Up Here", player), lambda state: state.basic_combat(player))
|
||||||
set_rule(world.get_location("How Did We Get Here?", player), lambda state: state.can_brew_potions(player) and state.has_gold_ingots(player) and # most effects; Absorption
|
set_rule(world.get_location("How Did We Get Here?", player),
|
||||||
state.can_reach('End City', 'Region', player) and state.can_reach('The Nether', 'Region', player) and # Levitation; potion ingredients
|
lambda state: state.can_brew_potions(player) and state.has_gold_ingots(
|
||||||
state.has("Fishing Rod", player) and state.has("Archery", player) and # Pufferfish, Nautilus Shells; spectral arrows
|
player) and # most effects; Absorption
|
||||||
state.can_reach("Bring Home the Beacon", "Location", player) and # Haste
|
state.can_reach('End City', 'Region', player) and state.can_reach('The Nether', 'Region',
|
||||||
state.can_reach("Hero of the Village", "Location", player)) # Bad Omen, Hero of the Village
|
player) and # Levitation; potion ingredients
|
||||||
set_rule(world.get_location("Bullseye", player), lambda state: state.has("Archery", player) and state.has("Progressive Tools", player, 2) and state.has_iron_ingots(player))
|
state.has("Fishing Rod", player) and state.has("Archery",
|
||||||
|
player) and # Pufferfish, Nautilus Shells; spectral arrows
|
||||||
|
state.can_reach("Bring Home the Beacon", "Location", player) and # Haste
|
||||||
|
state.can_reach("Hero of the Village", "Location", player)) # Bad Omen, Hero of the Village
|
||||||
|
set_rule(world.get_location("Bullseye", player),
|
||||||
|
lambda state: state.has("Archery", player) and state.has("Progressive Tools", player,
|
||||||
|
2) and state.has_iron_ingots(player))
|
||||||
set_rule(world.get_location("Spooky Scary Skeleton", player), lambda state: state.basic_combat(player))
|
set_rule(world.get_location("Spooky Scary Skeleton", player), lambda state: state.basic_combat(player))
|
||||||
set_rule(world.get_location("Two by Two", player), lambda state: state.has_iron_ingots(player) and state.can_adventure(player)) # shears > seagrass > turtles; nether > striders; gold carrots > horses skips ingots
|
set_rule(world.get_location("Two by Two", player),
|
||||||
|
lambda state: state.has_iron_ingots(player) and state.can_adventure(
|
||||||
|
player)) # shears > seagrass > turtles; nether > striders; gold carrots > horses skips ingots
|
||||||
set_rule(world.get_location("Stone Age", player), lambda state: True)
|
set_rule(world.get_location("Stone Age", player), lambda state: True)
|
||||||
set_rule(world.get_location("Two Birds, One Arrow", player), lambda state: state.craft_crossbow(player) and state.can_enchant(player))
|
set_rule(world.get_location("Two Birds, One Arrow", player),
|
||||||
|
lambda state: state.craft_crossbow(player) and state.can_enchant(player))
|
||||||
set_rule(world.get_location("We Need to Go Deeper", player), lambda state: True)
|
set_rule(world.get_location("We Need to Go Deeper", player), lambda state: True)
|
||||||
set_rule(world.get_location("Who's the Pillager Now?", player), lambda state: state.craft_crossbow(player))
|
set_rule(world.get_location("Who's the Pillager Now?", player), lambda state: state.craft_crossbow(player))
|
||||||
set_rule(world.get_location("Getting an Upgrade", player), lambda state: state.has("Progressive Tools", player))
|
set_rule(world.get_location("Getting an Upgrade", player), lambda state: state.has("Progressive Tools", player))
|
||||||
set_rule(world.get_location("Tactical Fishing", player), lambda state: state.has("Bucket", player) and state.has_iron_ingots(player))
|
set_rule(world.get_location("Tactical Fishing", player),
|
||||||
set_rule(world.get_location("Zombie Doctor", player), lambda state: state.can_brew_potions(player) and state.has_gold_ingots(player))
|
lambda state: state.has("Bucket", player) and state.has_iron_ingots(player))
|
||||||
|
set_rule(world.get_location("Zombie Doctor", player),
|
||||||
|
lambda state: state.can_brew_potions(player) and state.has_gold_ingots(player))
|
||||||
set_rule(world.get_location("The City at the End of the Game", player), lambda state: True)
|
set_rule(world.get_location("The City at the End of the Game", player), lambda state: True)
|
||||||
set_rule(world.get_location("Ice Bucket Challenge", player), lambda state: state.has_diamond_pickaxe(player))
|
set_rule(world.get_location("Ice Bucket Challenge", player), lambda state: state.has_diamond_pickaxe(player))
|
||||||
set_rule(world.get_location("Remote Getaway", player), lambda state: True)
|
set_rule(world.get_location("Remote Getaway", player), lambda state: True)
|
||||||
set_rule(world.get_location("Into Fire", player), lambda state: state.basic_combat(player))
|
set_rule(world.get_location("Into Fire", player), lambda state: state.basic_combat(player))
|
||||||
set_rule(world.get_location("War Pigs", player), lambda state: state.basic_combat(player))
|
set_rule(world.get_location("War Pigs", player), lambda state: state.basic_combat(player))
|
||||||
set_rule(world.get_location("Take Aim", player), lambda state: state.has("Archery", player))
|
set_rule(world.get_location("Take Aim", player), lambda state: state.has("Archery", player))
|
||||||
set_rule(world.get_location("Total Beelocation", player), lambda state: state.has("Silk Touch Book", player) and state.can_use_anvil(player) and state.can_enchant(player))
|
set_rule(world.get_location("Total Beelocation", player),
|
||||||
set_rule(world.get_location("Arbalistic", player), lambda state: state.craft_crossbow(player) and state.has("Piercing IV Book", player) and
|
lambda state: state.has("Silk Touch Book", player) and state.can_use_anvil(player) and state.can_enchant(
|
||||||
state.can_use_anvil(player) and state.can_enchant(player))
|
player))
|
||||||
set_rule(world.get_location("The End... Again...", player), lambda state: can_complete(state) and state.has("Ingot Crafting", player) and state.can_reach('The Nether', 'Region', player)) # furnace for glass, nether for ghast tears
|
set_rule(world.get_location("Arbalistic", player),
|
||||||
|
lambda state: state.craft_crossbow(player) and state.has("Piercing IV Book", player) and
|
||||||
|
state.can_use_anvil(player) and state.can_enchant(player))
|
||||||
|
set_rule(world.get_location("The End... Again...", player),
|
||||||
|
lambda state: can_complete(state) and state.has("Ingot Crafting", player) and state.can_reach('The Nether',
|
||||||
|
'Region',
|
||||||
|
player)) # furnace for glass, nether for ghast tears
|
||||||
set_rule(world.get_location("Acquire Hardware", player), lambda state: state.has_iron_ingots(player))
|
set_rule(world.get_location("Acquire Hardware", player), lambda state: state.has_iron_ingots(player))
|
||||||
set_rule(world.get_location("Not Quite \"Nine\" Lives", player), lambda state: state.can_piglin_trade(player) and state.has("Resource Blocks", player))
|
set_rule(world.get_location("Not Quite \"Nine\" Lives", player),
|
||||||
set_rule(world.get_location("Cover Me With Diamonds", player), lambda state: state.has("Progressive Armor", player, 2) and state.can_reach("Diamonds!", "Location", player))
|
lambda state: state.can_piglin_trade(player) and state.has("Resource Blocks", player))
|
||||||
|
set_rule(world.get_location("Cover Me With Diamonds", player),
|
||||||
|
lambda state: state.has("Progressive Armor", player, 2) and state.can_reach("Diamonds!", "Location",
|
||||||
|
player))
|
||||||
set_rule(world.get_location("Sky's the Limit", player), lambda state: state.basic_combat(player))
|
set_rule(world.get_location("Sky's the Limit", player), lambda state: state.basic_combat(player))
|
||||||
set_rule(world.get_location("Hired Help", player), lambda state: state.has("Resource Blocks", player) and state.has_iron_ingots(player))
|
set_rule(world.get_location("Hired Help", player),
|
||||||
|
lambda state: state.has("Resource Blocks", player) and state.has_iron_ingots(player))
|
||||||
set_rule(world.get_location("Return to Sender", player), lambda state: True)
|
set_rule(world.get_location("Return to Sender", player), lambda state: True)
|
||||||
set_rule(world.get_location("Sweet Dreams", player), lambda state: state.has("Bed", player) or state.can_reach('Village', 'Region', player))
|
set_rule(world.get_location("Sweet Dreams", player),
|
||||||
set_rule(world.get_location("You Need a Mint", player), lambda state: can_complete(state) and state.has_bottle_mc(player))
|
lambda state: state.has("Bed", player) or state.can_reach('Village', 'Region', player))
|
||||||
|
set_rule(world.get_location("You Need a Mint", player),
|
||||||
|
lambda state: can_complete(state) and state.has_bottle_mc(player))
|
||||||
set_rule(world.get_location("Adventure", player), lambda state: True)
|
set_rule(world.get_location("Adventure", player), lambda state: True)
|
||||||
set_rule(world.get_location("Monsters Hunted", player), lambda state: can_complete(state) and state.can_kill_wither(player) and state.has("Fishing Rod", player)) # pufferfish for Water Breathing
|
set_rule(world.get_location("Monsters Hunted", player),
|
||||||
|
lambda state: can_complete(state) and state.can_kill_wither(player) and state.has("Fishing Rod",
|
||||||
|
player)) # pufferfish for Water Breathing
|
||||||
set_rule(world.get_location("Enchanter", player), lambda state: state.can_enchant(player))
|
set_rule(world.get_location("Enchanter", player), lambda state: state.can_enchant(player))
|
||||||
set_rule(world.get_location("Voluntary Exile", player), lambda state: state.basic_combat(player))
|
set_rule(world.get_location("Voluntary Exile", player), lambda state: state.basic_combat(player))
|
||||||
set_rule(world.get_location("Eye Spy", player), lambda state: state.enter_stronghold(player))
|
set_rule(world.get_location("Eye Spy", player), lambda state: state.enter_stronghold(player))
|
||||||
set_rule(world.get_location("The End", player), lambda state: True)
|
set_rule(world.get_location("The End", player), lambda state: True)
|
||||||
set_rule(world.get_location("Serious Dedication", player), lambda state: state.can_reach("Hidden in the Depths", "Location", player) and state.has_gold_ingots(player))
|
set_rule(world.get_location("Serious Dedication", player),
|
||||||
|
lambda state: state.can_reach("Hidden in the Depths", "Location", player) and state.has_gold_ingots(
|
||||||
|
player))
|
||||||
set_rule(world.get_location("Postmortal", player), lambda state: state.complete_raid(player))
|
set_rule(world.get_location("Postmortal", player), lambda state: state.complete_raid(player))
|
||||||
set_rule(world.get_location("Monster Hunter", player), lambda state: True)
|
set_rule(world.get_location("Monster Hunter", player), lambda state: True)
|
||||||
set_rule(world.get_location("Adventuring Time", player), lambda state: state.can_adventure(player))
|
set_rule(world.get_location("Adventuring Time", player), lambda state: state.can_adventure(player))
|
||||||
set_rule(world.get_location("A Seedy Place", player), lambda state: True)
|
set_rule(world.get_location("A Seedy Place", player), lambda state: True)
|
||||||
set_rule(world.get_location("Those Were the Days", player), lambda state: True)
|
set_rule(world.get_location("Those Were the Days", player), lambda state: True)
|
||||||
set_rule(world.get_location("Hero of the Village", player), lambda state: state.complete_raid(player))
|
set_rule(world.get_location("Hero of the Village", player), lambda state: state.complete_raid(player))
|
||||||
set_rule(world.get_location("Hidden in the Depths", player), lambda state: state.can_brew_potions(player) and state.has("Bed", player) and state.has_diamond_pickaxe(player)) # bed mining :)
|
set_rule(world.get_location("Hidden in the Depths", player),
|
||||||
set_rule(world.get_location("Beaconator", player), lambda state: state.can_kill_wither(player) and state.has_diamond_pickaxe(player) and
|
lambda state: state.can_brew_potions(player) and state.has("Bed", player) and state.has_diamond_pickaxe(
|
||||||
state.has("Ingot Crafting", player) and state.has("Resource Blocks", player))
|
player)) # bed mining :)
|
||||||
|
set_rule(world.get_location("Beaconator", player),
|
||||||
|
lambda state: state.can_kill_wither(player) and state.has_diamond_pickaxe(player) and
|
||||||
|
state.has("Ingot Crafting", player) and state.has("Resource Blocks", player))
|
||||||
set_rule(world.get_location("Withering Heights", player), lambda state: state.can_kill_wither(player))
|
set_rule(world.get_location("Withering Heights", player), lambda state: state.can_kill_wither(player))
|
||||||
set_rule(world.get_location("A Balanced Diet", player), lambda state: state.has_bottle_mc(player) and state.has_gold_ingots(player) and # honey bottle; gapple
|
set_rule(world.get_location("A Balanced Diet", player),
|
||||||
state.has("Resource Blocks", player) and state.can_reach('The End', 'Region', player)) # notch apple, chorus fruit
|
lambda state: state.has_bottle_mc(player) and state.has_gold_ingots(player) and # honey bottle; gapple
|
||||||
|
state.has("Resource Blocks", player) and state.can_reach('The End', 'Region',
|
||||||
|
player)) # notch apple, chorus fruit
|
||||||
set_rule(world.get_location("Subspace Bubble", player), lambda state: state.has_diamond_pickaxe(player))
|
set_rule(world.get_location("Subspace Bubble", player), lambda state: state.has_diamond_pickaxe(player))
|
||||||
set_rule(world.get_location("Husbandry", player), lambda state: True)
|
set_rule(world.get_location("Husbandry", player), lambda state: True)
|
||||||
set_rule(world.get_location("Country Lode, Take Me Home", player), lambda state: state.can_reach("Hidden in the Depths", "Location", player) and state.has_gold_ingots(player))
|
set_rule(world.get_location("Country Lode, Take Me Home", player),
|
||||||
set_rule(world.get_location("Bee Our Guest", player), lambda state: state.has("Campfire", player) and state.has_bottle_mc(player))
|
lambda state: state.can_reach("Hidden in the Depths", "Location", player) and state.has_gold_ingots(
|
||||||
|
player))
|
||||||
|
set_rule(world.get_location("Bee Our Guest", player),
|
||||||
|
lambda state: state.has("Campfire", player) and state.has_bottle_mc(player))
|
||||||
set_rule(world.get_location("What a Deal!", player), lambda state: True)
|
set_rule(world.get_location("What a Deal!", player), lambda state: True)
|
||||||
set_rule(world.get_location("Uneasy Alliance", player), lambda state: state.has_diamond_pickaxe(player) and state.has('Fishing Rod', player))
|
set_rule(world.get_location("Uneasy Alliance", player),
|
||||||
set_rule(world.get_location("Diamonds!", player), lambda state: state.has("Progressive Tools", player, 2) and state.has_iron_ingots(player))
|
lambda state: state.has_diamond_pickaxe(player) and state.has('Fishing Rod', player))
|
||||||
set_rule(world.get_location("A Terrible Fortress", player), lambda state: True) # since you don't have to fight anything
|
set_rule(world.get_location("Diamonds!", player),
|
||||||
set_rule(world.get_location("A Throwaway Joke", player), lambda state: True) # kill drowned
|
lambda state: state.has("Progressive Tools", player, 2) and state.has_iron_ingots(player))
|
||||||
|
set_rule(world.get_location("A Terrible Fortress", player),
|
||||||
|
lambda state: True) # since you don't have to fight anything
|
||||||
|
set_rule(world.get_location("A Throwaway Joke", player), lambda state: True) # kill drowned
|
||||||
set_rule(world.get_location("Minecraft", player), lambda state: True)
|
set_rule(world.get_location("Minecraft", player), lambda state: True)
|
||||||
set_rule(world.get_location("Sticky Situation", player), lambda state: state.has("Campfire", player) and state.has_bottle_mc(player))
|
set_rule(world.get_location("Sticky Situation", player),
|
||||||
|
lambda state: state.has("Campfire", player) and state.has_bottle_mc(player))
|
||||||
set_rule(world.get_location("Ol' Betsy", player), lambda state: state.craft_crossbow(player))
|
set_rule(world.get_location("Ol' Betsy", player), lambda state: state.craft_crossbow(player))
|
||||||
set_rule(world.get_location("Cover Me in Debris", player), lambda state: state.has("Progressive Armor", player, 2) and
|
set_rule(world.get_location("Cover Me in Debris", player),
|
||||||
state.has("8 Netherite Scrap", player, 2) and state.has("Ingot Crafting", player) and
|
lambda state: state.has("Progressive Armor", player, 2) and
|
||||||
state.can_reach("Diamonds!", "Location", player) and state.can_reach("Hidden in the Depths", "Location", player))
|
state.has("8 Netherite Scrap", player, 2) and state.has("Ingot Crafting", player) and
|
||||||
|
state.can_reach("Diamonds!", "Location", player) and state.can_reach("Hidden in the Depths",
|
||||||
|
"Location", player))
|
||||||
set_rule(world.get_location("The End?", player), lambda state: True)
|
set_rule(world.get_location("The End?", player), lambda state: True)
|
||||||
set_rule(world.get_location("The Parrots and the Bats", player), lambda state: True)
|
set_rule(world.get_location("The Parrots and the Bats", player), lambda state: True)
|
||||||
set_rule(world.get_location("A Complete Catalogue", player), lambda state: True) # kill fish for raw
|
set_rule(world.get_location("A Complete Catalogue", player), lambda state: True) # kill fish for raw
|
||||||
set_rule(world.get_location("Getting Wood", player), lambda state: True)
|
set_rule(world.get_location("Getting Wood", player), lambda state: True)
|
||||||
set_rule(world.get_location("Time to Mine!", player), lambda state: True)
|
set_rule(world.get_location("Time to Mine!", player), lambda state: True)
|
||||||
set_rule(world.get_location("Hot Topic", player), lambda state: state.has("Ingot Crafting", player))
|
set_rule(world.get_location("Hot Topic", player), lambda state: state.has("Ingot Crafting", player))
|
||||||
set_rule(world.get_location("Bake Bread", player), lambda state: True)
|
set_rule(world.get_location("Bake Bread", player), lambda state: True)
|
||||||
set_rule(world.get_location("The Lie", player), lambda state: state.has_iron_ingots(player) and state.has("Bucket", player))
|
set_rule(world.get_location("The Lie", player),
|
||||||
set_rule(world.get_location("On a Rail", player), lambda state: state.has_iron_ingots(player) and state.has('Progressive Tools', player, 2)) # powered rails
|
lambda state: state.has_iron_ingots(player) and state.has("Bucket", player))
|
||||||
|
set_rule(world.get_location("On a Rail", player),
|
||||||
|
lambda state: state.has_iron_ingots(player) and state.has('Progressive Tools', player, 2)) # powered rails
|
||||||
set_rule(world.get_location("Time to Strike!", player), lambda state: True)
|
set_rule(world.get_location("Time to Strike!", player), lambda state: True)
|
||||||
set_rule(world.get_location("Cow Tipper", player), lambda state: True)
|
set_rule(world.get_location("Cow Tipper", player), lambda state: True)
|
||||||
set_rule(world.get_location("When Pigs Fly", player), lambda state: (state.fortress_loot(player) or state.complete_raid(player)) and state.has("Fishing Rod", player) and state.can_adventure(player))
|
set_rule(world.get_location("When Pigs Fly", player),
|
||||||
set_rule(world.get_location("Overkill", player), lambda state: state.can_brew_potions(player) and (state.has("Progressive Weapons", player) or state.can_reach('The Nether', 'Region', player))) # strength 1 + stone axe crit OR strength 2 + wood axe crit
|
lambda state: (state.fortress_loot(player) or state.complete_raid(player)) and state.has("Fishing Rod",
|
||||||
|
player) and state.can_adventure(
|
||||||
|
player))
|
||||||
|
set_rule(world.get_location("Overkill", player), lambda state: state.can_brew_potions(player) and (
|
||||||
|
state.has("Progressive Weapons", player) or state.can_reach('The Nether', 'Region',
|
||||||
|
player))) # strength 1 + stone axe crit OR strength 2 + wood axe crit
|
||||||
set_rule(world.get_location("Librarian", player), lambda state: state.has("Enchanting", player))
|
set_rule(world.get_location("Librarian", player), lambda state: state.has("Enchanting", player))
|
||||||
set_rule(world.get_location("Overpowered", player), lambda state: state.has("Resource Blocks", player) and state.has_gold_ingots(player))
|
set_rule(world.get_location("Overpowered", player),
|
||||||
|
lambda state: state.has("Resource Blocks", player) and state.has_gold_ingots(player))
|
||||||
|
|
|
@ -1,16 +1,16 @@
|
||||||
from random import Random
|
|
||||||
from .Items import MinecraftItem, item_table, item_frequencies
|
from .Items import MinecraftItem, item_table, item_frequencies
|
||||||
from .Locations import exclusion_table, events_table
|
from .Locations import exclusion_table, events_table
|
||||||
from .Regions import link_minecraft_structures
|
from .Regions import link_minecraft_structures
|
||||||
from .Rules import set_rules
|
from .Rules import set_rules
|
||||||
|
|
||||||
from BaseClasses import MultiWorld
|
from BaseClasses import MultiWorld
|
||||||
from Options import minecraft_options
|
from .Options import minecraft_options
|
||||||
from ..AutoWorld import World
|
from ..AutoWorld import World
|
||||||
|
|
||||||
|
|
||||||
class MinecraftWorld(World):
|
class MinecraftWorld(World):
|
||||||
game: str = "Minecraft"
|
game: str = "Minecraft"
|
||||||
|
options = minecraft_options
|
||||||
|
|
||||||
|
|
||||||
client_version = (0, 3)
|
client_version = (0, 3)
|
||||||
|
|
Loading…
Reference in New Issue