mirror of
https://github.com/ArchipelagoMW/Archipelago.git
synced 2026-03-28 02:03:33 -07:00
Remove the rest of option.class.value
This commit is contained in:
@@ -7,6 +7,7 @@ from worlds.generic.Rules import add_rule, set_rule
|
||||
from typing import List, Callable, TYPE_CHECKING
|
||||
from .Regions import act_chapters
|
||||
from .Locations import zero_jumps, zero_jumps_expert, zero_jumps_hard, death_wishes
|
||||
from .Options import EndGoal
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from . import HatInTimeWorld
|
||||
@@ -107,7 +108,7 @@ def set_dw_rules(world: "HatInTimeWorld"):
|
||||
set_enemy_rules(world)
|
||||
|
||||
dw_list: List[str] = []
|
||||
if world.options.DWShuffle.value > 0:
|
||||
if world.options.DWShuffle:
|
||||
dw_list = world.dw_shuffle
|
||||
else:
|
||||
for name in death_wishes.keys():
|
||||
@@ -118,16 +119,15 @@ def set_dw_rules(world: "HatInTimeWorld"):
|
||||
continue
|
||||
|
||||
dw = world.multiworld.get_region(name, world.player)
|
||||
if world.options.DWShuffle.value == 0:
|
||||
if name in dw_stamp_costs.keys():
|
||||
for entrance in dw.entrances:
|
||||
add_rule(entrance, lambda state, n=name: get_total_dw_stamps(state, world) >= dw_stamp_costs[n])
|
||||
if not world.options.DWShuffle and name in dw_stamp_costs.keys():
|
||||
for entrance in dw.entrances:
|
||||
add_rule(entrance, lambda state, n=name: get_total_dw_stamps(state, world) >= dw_stamp_costs[n])
|
||||
|
||||
main_objective = world.multiworld.get_location(f"{name} - Main Objective", world.player)
|
||||
all_clear = world.multiworld.get_location(f"{name} - All Clear", world.player)
|
||||
main_stamp = world.multiworld.get_location(f"Main Stamp - {name}", world.player)
|
||||
bonus_stamps = world.multiworld.get_location(f"Bonus Stamps - {name}", world.player)
|
||||
if world.options.DWEnableBonus.value == 0:
|
||||
if not world.options.DWEnableBonus:
|
||||
# place nothing, but let the locations exist still, so we can use them for bonus stamp rules
|
||||
all_clear.address = None
|
||||
all_clear.place_locked_item(HatInTimeItem("Nothing", ItemClassification.filler, None, world.player))
|
||||
@@ -143,10 +143,10 @@ def set_dw_rules(world: "HatInTimeWorld"):
|
||||
add_rule(main_stamp, main_objective.access_rule)
|
||||
add_rule(all_clear, main_objective.access_rule)
|
||||
# Only set bonus stamp rules if we don't auto complete bonuses
|
||||
if world.options.DWAutoCompleteBonuses.value == 0 and not world.is_bonus_excluded(all_clear.name):
|
||||
if not world.options.DWAutoCompleteBonuses and not world.is_bonus_excluded(all_clear.name):
|
||||
add_rule(bonus_stamps, all_clear.access_rule)
|
||||
|
||||
if world.options.DWShuffle.value > 0:
|
||||
if world.options.DWShuffle:
|
||||
for i in range(len(world.dw_shuffle)-1):
|
||||
name = world.dw_shuffle[i+1]
|
||||
prev_dw = world.multiworld.get_region(world.dw_shuffle[i], world.player)
|
||||
@@ -171,7 +171,7 @@ def set_dw_rules(world: "HatInTimeWorld"):
|
||||
for rule in access_rules:
|
||||
add_rule(entrance, rule)
|
||||
|
||||
if world.options.EndGoal.value == 3:
|
||||
if world.options.EndGoal == EndGoal.option_seal_the_deal:
|
||||
world.multiworld.completion_condition[world.player] = lambda state: \
|
||||
state.has("1 Stamp - Seal the Deal", world.player)
|
||||
|
||||
@@ -196,10 +196,10 @@ def add_dw_rules(world: "HatInTimeWorld", loc: Location):
|
||||
for misc in data.misc_required:
|
||||
add_rule(loc, lambda state, item=misc: state.has(item, world.player))
|
||||
|
||||
if data.paintings > 0 and world.options.ShuffleSubconPaintings.value > 0:
|
||||
if data.paintings > 0 and world.options.ShuffleSubconPaintings:
|
||||
add_rule(loc, lambda state, paintings=data.paintings: has_paintings(state, world, paintings))
|
||||
|
||||
if data.hit_type is not HitType.none and world.options.UmbrellaLogic.value > 0:
|
||||
if data.hit_type is not HitType.none and world.options.UmbrellaLogic:
|
||||
if data.hit_type == HitType.umbrella:
|
||||
add_rule(loc, lambda state: state.has("Umbrella", world.player))
|
||||
|
||||
@@ -260,7 +260,7 @@ def modify_dw_rules(world: "HatInTimeWorld", name: str):
|
||||
|
||||
|
||||
def get_total_dw_stamps(state: CollectionState, world: "HatInTimeWorld") -> int:
|
||||
if world.options.DWShuffle.value > 0:
|
||||
if world.options.DWShuffle:
|
||||
return 999 # no stamp costs in death wish shuffle
|
||||
|
||||
count = 0
|
||||
@@ -293,7 +293,7 @@ def set_candle_dw_rules(name: str, world: "HatInTimeWorld"):
|
||||
|
||||
# No Ice Hat/painting required in Expert for Toilet Zero Jumps
|
||||
# This painting wall can only be skipped via cherry hover.
|
||||
if get_difficulty(world) < Difficulty.EXPERT or world.options.NoPaintingSkips.value == 1:
|
||||
if get_difficulty(world) < Difficulty.EXPERT or world.options.NoPaintingSkips:
|
||||
set_rule(world.multiworld.get_location("Toilet of Doom (Zero Jumps)", world.player),
|
||||
lambda state: can_use_hookshot(state, world) and can_hit(state, world)
|
||||
and has_paintings(state, world, 1, False))
|
||||
@@ -377,14 +377,13 @@ def create_enemy_events(world: "HatInTimeWorld"):
|
||||
if (area == "Bon Voyage!" or area == "Time Rift - Deep Sea") and not world.is_dlc1():
|
||||
continue
|
||||
|
||||
if area == "Time Rift - Tour" and (not world.is_dlc1()
|
||||
or world.options.ExcludeTour.value > 0):
|
||||
if area == "Time Rift - Tour" and (not world.is_dlc1() or world.options.ExcludeTour):
|
||||
continue
|
||||
|
||||
if area == "Bluefin Tunnel" and not world.is_dlc2():
|
||||
continue
|
||||
if world.options.DWShuffle.value > 0 and area in death_wishes.keys() \
|
||||
and area not in world.dw_shuffle:
|
||||
|
||||
if world.options.DWShuffle and area in death_wishes.keys() and area not in world.dw_shuffle:
|
||||
continue
|
||||
|
||||
region = world.multiworld.get_region(area, world.player)
|
||||
@@ -394,10 +393,10 @@ def create_enemy_events(world: "HatInTimeWorld"):
|
||||
event.show_in_spoiler = False
|
||||
|
||||
for name in triple_enemy_locations:
|
||||
if name == "Time Rift - Tour" and (not world.is_dlc1() or world.options.ExcludeTour.value > 0):
|
||||
if name == "Time Rift - Tour" and (not world.is_dlc1() or world.options.ExcludeTour):
|
||||
continue
|
||||
|
||||
if world.options.DWShuffle.value > 0 and name in death_wishes.keys() \
|
||||
if world.options.DWShuffle and name in death_wishes.keys() \
|
||||
and name not in world.dw_shuffle:
|
||||
continue
|
||||
|
||||
@@ -421,15 +420,13 @@ def set_enemy_rules(world: "HatInTimeWorld"):
|
||||
if (area == "Bon Voyage!" or area == "Time Rift - Deep Sea") and not world.is_dlc1():
|
||||
continue
|
||||
|
||||
if area == "Time Rift - Tour" and (not world.is_dlc1()
|
||||
or world.options.ExcludeTour.value > 0):
|
||||
if area == "Time Rift - Tour" and (not world.is_dlc1() or world.options.ExcludeTour):
|
||||
continue
|
||||
|
||||
if area == "Bluefin Tunnel" and not world.is_dlc2():
|
||||
continue
|
||||
|
||||
if world.options.DWShuffle.value > 0 and area in death_wishes \
|
||||
and area not in world.dw_shuffle:
|
||||
if world.options.DWShuffle and area in death_wishes and area not in world.dw_shuffle:
|
||||
continue
|
||||
|
||||
event = world.multiworld.get_location(f"{enemy} - {area}", world.player)
|
||||
|
||||
@@ -96,7 +96,7 @@ def calculate_yarn_costs(world: "HatInTimeWorld"):
|
||||
|
||||
extra_yarn = max_cost + world.options.MinExtraYarn - available_yarn
|
||||
if extra_yarn > 0:
|
||||
world.options.YarnAvailable.value += extra_yarn
|
||||
world.options.YarnAvailable.value += extra_yarn
|
||||
|
||||
|
||||
def item_dlc_enabled(world: "HatInTimeWorld", name: str) -> bool:
|
||||
|
||||
@@ -16,20 +16,20 @@ def get_total_locations(world: "HatInTimeWorld") -> int:
|
||||
if is_location_valid(world, name):
|
||||
total += 1
|
||||
|
||||
if world.is_dlc1() and world.options.Tasksanity.value > 0:
|
||||
total += world.options.TasksanityCheckCount.value
|
||||
if world.is_dlc1() and world.options.Tasksanity:
|
||||
total += world.options.TasksanityCheckCount
|
||||
|
||||
if world.is_dw():
|
||||
if world.options.DWShuffle.value > 0:
|
||||
if world.options.DWShuffle:
|
||||
total += len(world.dw_shuffle)
|
||||
if world.options.DWEnableBonus.value > 0:
|
||||
if world.options.DWEnableBonus:
|
||||
total += len(world.dw_shuffle)
|
||||
else:
|
||||
total += 37
|
||||
if world.is_dlc2():
|
||||
total += 1
|
||||
|
||||
if world.options.DWEnableBonus.value > 0:
|
||||
if world.options.DWEnableBonus:
|
||||
total += 37
|
||||
if world.is_dlc2():
|
||||
total += 1
|
||||
@@ -60,39 +60,36 @@ def is_location_valid(world: "HatInTimeWorld", location: str) -> bool:
|
||||
if not location_dlc_enabled(world, location):
|
||||
return False
|
||||
|
||||
if world.options.ShuffleStorybookPages.value == 0 \
|
||||
and location in storybook_pages.keys():
|
||||
if not world.options.ShuffleStorybookPages and location in storybook_pages.keys():
|
||||
return False
|
||||
|
||||
if world.options.ShuffleActContracts.value == 0 \
|
||||
and location in contract_locations.keys():
|
||||
if not world.options.ShuffleActContracts and location in contract_locations.keys():
|
||||
return False
|
||||
|
||||
if location not in world.shop_locs and location in shop_locations:
|
||||
return False
|
||||
|
||||
data = location_table.get(location) or event_locs.get(location)
|
||||
if world.options.ExcludeTour.value > 0 and data.region == "Time Rift - Tour":
|
||||
if world.options.ExcludeTour and data.region == "Time Rift - Tour":
|
||||
return False
|
||||
|
||||
# No need for all those event items if we're not doing candles
|
||||
if data.dlc_flags & HatDLC.death_wish:
|
||||
if world.options.DWExcludeCandles.value > 0 and location in event_locs.keys():
|
||||
if world.options.DWExcludeCandles and location in event_locs.keys():
|
||||
return False
|
||||
|
||||
if world.options.DWShuffle.value > 0 \
|
||||
and data.region in death_wishes and data.region not in world.dw_shuffle:
|
||||
if world.options.DWShuffle and data.region in death_wishes and data.region not in world.dw_shuffle:
|
||||
return False
|
||||
|
||||
if location in zero_jumps:
|
||||
if world.options.DWShuffle.value > 0 and "Zero Jumps" not in world.dw_shuffle:
|
||||
if world.options.DWShuffle and "Zero Jumps" not in world.dw_shuffle:
|
||||
return False
|
||||
|
||||
difficulty: int = world.options.LogicDifficulty.value
|
||||
if location in zero_jumps_hard and difficulty < int(Difficulty.HARD):
|
||||
difficulty: Difficulty = Difficulty(world.options.LogicDifficulty)
|
||||
if location in zero_jumps_hard and difficulty < Difficulty.HARD:
|
||||
return False
|
||||
|
||||
if location in zero_jumps_expert and difficulty < int(Difficulty.EXPERT):
|
||||
if location in zero_jumps_expert and difficulty < Difficulty.EXPERT:
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
@@ -4,6 +4,7 @@ from .Locations import location_table, storybook_pages, event_locs, is_location_
|
||||
shop_locations, TASKSANITY_START_ID, snatcher_coins, zero_jumps, zero_jumps_expert, zero_jumps_hard
|
||||
from typing import TYPE_CHECKING, List, Dict
|
||||
from .Rules import set_rift_rules, get_difficulty
|
||||
from .Options import ActRandomizer, EndGoal
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from . import HatInTimeWorld
|
||||
@@ -453,7 +454,7 @@ def randomize_act_entrances(world: "HatInTimeWorld"):
|
||||
rift_dict: Dict[str, Region] = {}
|
||||
|
||||
# Check if Plando's are valid, if so, map them
|
||||
if len(world.options.ActPlando) > 0:
|
||||
if world.options.ActPlando:
|
||||
player_name = world.multiworld.get_player_name(world.player)
|
||||
for (name1, name2) in world.options.ActPlando.items():
|
||||
region: Region
|
||||
@@ -507,7 +508,7 @@ def randomize_act_entrances(world: "HatInTimeWorld"):
|
||||
first_act_mapped = True
|
||||
break # we can stop here, as we only need one
|
||||
|
||||
if is_valid_act_combo(world, region, c, bool(world.options.ActRandomizer.value == 1), ignore_certain_rules):
|
||||
if is_valid_act_combo(world, region, c, ignore_certain_rules):
|
||||
valid_candidates.append(c)
|
||||
|
||||
if len(valid_candidates) > 0:
|
||||
@@ -598,11 +599,11 @@ def connect_acts(world: "HatInTimeWorld", entrance_act: Region, exit_act: Region
|
||||
|
||||
|
||||
def is_valid_act_combo(world: "HatInTimeWorld", entrance_act: Region,
|
||||
exit_act: Region, separate_rifts: bool, ignore_certain_rules=False) -> bool:
|
||||
exit_act: Region, ignore_certain_rules: bool = False) -> bool:
|
||||
|
||||
# Ignore certain rules that aren't to prevent impossible combos. This is needed for ActPlando.
|
||||
if not ignore_certain_rules:
|
||||
if separate_rifts and not ignore_certain_rules:
|
||||
if world.options.ActRandomizer == ActRandomizer.option_light and not ignore_certain_rules:
|
||||
# Don't map Time Rifts to normal acts
|
||||
if "Time Rift" in entrance_act.name and "Time Rift" not in exit_act.name:
|
||||
return False
|
||||
@@ -616,7 +617,7 @@ def is_valid_act_combo(world: "HatInTimeWorld", entrance_act: Region,
|
||||
or entrance_act.name not in purple_time_rifts and exit_act.name in purple_time_rifts:
|
||||
return False
|
||||
|
||||
if world.options.FinaleShuffle.value > 0 and entrance_act.name in chapter_finales:
|
||||
if world.options.FinaleShuffle and entrance_act.name in chapter_finales:
|
||||
if exit_act.name not in chapter_finales:
|
||||
return False
|
||||
|
||||
@@ -633,7 +634,7 @@ def is_valid_act_combo(world: "HatInTimeWorld", entrance_act: Region,
|
||||
return False
|
||||
|
||||
# Prevent Contractual Obligations from being inaccessible if contracts are not shuffled
|
||||
if world.options.ShuffleActContracts.value == 0:
|
||||
if not world.options.ShuffleActContracts:
|
||||
if (entrance_act.name == "Your Contract has Expired" or entrance_act.name == "The Subcon Well") \
|
||||
and exit_act.name == "Contractual Obligations":
|
||||
return False
|
||||
@@ -646,12 +647,11 @@ def is_valid_first_act(world: "HatInTimeWorld", act: Region) -> bool:
|
||||
return False
|
||||
|
||||
# Not completable without Umbrella
|
||||
if world.options.UmbrellaLogic.value > 0 \
|
||||
and (act.name == "Heating Up Mafia Town" or act.name == "Queen Vanessa's Manor"):
|
||||
if world.options.UmbrellaLogic and (act.name == "Heating Up Mafia Town" or act.name == "Queen Vanessa's Manor"):
|
||||
return False
|
||||
|
||||
# Subcon sphere 1 is too small without painting unlocks, and no acts are completable either
|
||||
if world.options.ShuffleSubconPaintings.value > 0 and "Subcon Forest" in act_entrances[act.name]:
|
||||
if world.options.ShuffleSubconPaintings and "Subcon Forest" in act_entrances[act.name]:
|
||||
return False
|
||||
|
||||
return True
|
||||
@@ -696,13 +696,13 @@ def is_act_blacklisted(world: "HatInTimeWorld", name: str) -> bool:
|
||||
break
|
||||
|
||||
if name == "The Finale":
|
||||
return not plando and world.options.EndGoal.value == 1
|
||||
return not plando and world.options.EndGoal == EndGoal.option_finale
|
||||
|
||||
if name == "Rush Hour":
|
||||
return not plando and world.options.EndGoal.value == 2
|
||||
return not plando and world.options.EndGoal == EndGoal.option_rush_hour
|
||||
|
||||
if name == "Time Rift - Tour":
|
||||
return world.options.ExcludeTour.value > 0
|
||||
return bool(world.options.ExcludeTour)
|
||||
|
||||
return name in blacklisted_acts.values()
|
||||
|
||||
@@ -763,8 +763,7 @@ def create_region(world: "HatInTimeWorld", name: str) -> Region:
|
||||
continue
|
||||
|
||||
if data.region == name:
|
||||
if key in storybook_pages.keys() \
|
||||
and world.options.ShuffleStorybookPages.value == 0:
|
||||
if key in storybook_pages.keys() and not world.options.ShuffleStorybookPages:
|
||||
continue
|
||||
|
||||
location = HatInTimeLocation(world.player, key, data.id, reg)
|
||||
@@ -782,7 +781,7 @@ def create_badge_seller(world: "HatInTimeWorld") -> Region:
|
||||
count = 0
|
||||
max_items = 0
|
||||
|
||||
if world.options.BadgeSellerMaxItems.value > 0:
|
||||
if world.options.BadgeSellerMaxItems > 0:
|
||||
max_items = world.random.randint(world.options.BadgeSellerMinItems.value,
|
||||
world.options.BadgeSellerMaxItems.value)
|
||||
|
||||
@@ -851,7 +850,7 @@ def create_region_and_connect(world: "HatInTimeWorld",
|
||||
|
||||
|
||||
def get_first_chapter_region(world: "HatInTimeWorld") -> Region:
|
||||
start_chapter: ChapterIndex = ChapterIndex(world.options.StartingChapter.value)
|
||||
start_chapter: ChapterIndex = ChapterIndex(world.options.StartingChapter)
|
||||
return world.multiworld.get_region(chapter_regions.get(start_chapter), world.player)
|
||||
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ from .Locations import location_table, zipline_unlocks, is_location_valid, contr
|
||||
from .Types import HatType, ChapterIndex, hat_type_to_item, Difficulty, HitType
|
||||
from BaseClasses import Location, Entrance, Region
|
||||
from typing import TYPE_CHECKING, List, Callable, Union, Dict
|
||||
from .Options import EndGoal, CTRLogic
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from . import HatInTimeWorld
|
||||
@@ -35,7 +36,7 @@ act_connections = {
|
||||
|
||||
|
||||
def can_use_hat(state: CollectionState, world: "HatInTimeWorld", hat: HatType) -> bool:
|
||||
if world.options.HatItems.value > 0:
|
||||
if world.options.HatItems:
|
||||
return state.has(hat_type_to_item[hat], world.player)
|
||||
|
||||
return state.count("Yarn", world.player) >= get_hat_cost(world, hat)
|
||||
@@ -56,19 +57,19 @@ def can_sdj(state: CollectionState, world: "HatInTimeWorld"):
|
||||
|
||||
|
||||
def painting_logic(world: "HatInTimeWorld") -> bool:
|
||||
return world.options.ShuffleSubconPaintings.value > 0
|
||||
return bool(world.options.ShuffleSubconPaintings)
|
||||
|
||||
|
||||
# -1 = Normal, 0 = Moderate, 1 = Hard, 2 = Expert
|
||||
def get_difficulty(world: "HatInTimeWorld") -> Difficulty:
|
||||
return Difficulty(world.options.LogicDifficulty.value)
|
||||
return Difficulty(world.options.LogicDifficulty)
|
||||
|
||||
|
||||
def has_paintings(state: CollectionState, world: "HatInTimeWorld", count: int, allow_skip: bool = True) -> bool:
|
||||
if not painting_logic(world):
|
||||
return True
|
||||
|
||||
if world.options.NoPaintingSkips.value == 0 and allow_skip:
|
||||
if not world.options.NoPaintingSkips and allow_skip:
|
||||
# In Moderate there is a very easy trick to skip all the walls, except for the one guarding the boss arena
|
||||
if get_difficulty(world) >= Difficulty.MODERATE:
|
||||
return True
|
||||
@@ -77,7 +78,7 @@ def has_paintings(state: CollectionState, world: "HatInTimeWorld", count: int, a
|
||||
|
||||
|
||||
def zipline_logic(world: "HatInTimeWorld") -> bool:
|
||||
return world.options.ShuffleAlpineZiplines.value > 0
|
||||
return bool(world.options.ShuffleAlpineZiplines)
|
||||
|
||||
|
||||
def can_use_hookshot(state: CollectionState, world: "HatInTimeWorld"):
|
||||
@@ -85,7 +86,7 @@ def can_use_hookshot(state: CollectionState, world: "HatInTimeWorld"):
|
||||
|
||||
|
||||
def can_hit(state: CollectionState, world: "HatInTimeWorld", umbrella_only: bool = False):
|
||||
if world.options.UmbrellaLogic.value == 0:
|
||||
if not world.options.UmbrellaLogic:
|
||||
return True
|
||||
|
||||
return state.has("Umbrella", world.player) or not umbrella_only and can_use_hat(state, world, HatType.BREWING)
|
||||
@@ -134,7 +135,7 @@ def can_clear_metro(state: CollectionState, world: "HatInTimeWorld") -> bool:
|
||||
|
||||
def set_rules(world: "HatInTimeWorld"):
|
||||
# First, chapter access
|
||||
starting_chapter = ChapterIndex(world.options.StartingChapter.value)
|
||||
starting_chapter = ChapterIndex(world.options.StartingChapter)
|
||||
world.chapter_timepiece_costs[starting_chapter] = 0
|
||||
|
||||
# Chapter costs increase progressively. Randomly decide the chapter order, except for Finale
|
||||
@@ -142,10 +143,10 @@ def set_rules(world: "HatInTimeWorld"):
|
||||
ChapterIndex.SUBCON, ChapterIndex.ALPINE]
|
||||
|
||||
final_chapter = ChapterIndex.FINALE
|
||||
if world.options.EndGoal.value == 2:
|
||||
if world.options.EndGoal == EndGoal.option_rush_hour:
|
||||
final_chapter = ChapterIndex.METRO
|
||||
chapter_list.append(ChapterIndex.FINALE)
|
||||
elif world.options.EndGoal.value == 3:
|
||||
elif world.options.EndGoal == EndGoal.option_seal_the_deal:
|
||||
final_chapter = None
|
||||
chapter_list.append(ChapterIndex.FINALE)
|
||||
|
||||
@@ -203,7 +204,7 @@ def set_rules(world: "HatInTimeWorld"):
|
||||
|
||||
if final_chapter is not None:
|
||||
final_chapter_cost: int
|
||||
if world.options.FinalChapterMinCost.value == world.options.FinalChapterMaxCost.value:
|
||||
if world.options.FinalChapterMinCost == world.options.FinalChapterMaxCost:
|
||||
final_chapter_cost = world.options.FinalChapterMaxCost.value
|
||||
else:
|
||||
final_chapter_cost = world.random.randint(world.options.FinalChapterMinCost.value,
|
||||
@@ -238,7 +239,7 @@ def set_rules(world: "HatInTimeWorld"):
|
||||
and state.has("Time Piece", world.player, world.chapter_timepiece_costs[ChapterIndex.METRO])
|
||||
and can_use_hat(state, world, HatType.DWELLER) and can_use_hat(state, world, HatType.ICE))
|
||||
|
||||
if world.options.ActRandomizer.value == 0:
|
||||
if not world.options.ActRandomizer:
|
||||
set_default_rift_rules(world)
|
||||
|
||||
table = {**location_table, **event_locs}
|
||||
@@ -258,10 +259,10 @@ def set_rules(world: "HatInTimeWorld"):
|
||||
if data.hookshot:
|
||||
add_rule(loc, lambda state: can_use_hookshot(state, world))
|
||||
|
||||
if data.paintings > 0 and world.options.ShuffleSubconPaintings.value > 0:
|
||||
if data.paintings > 0 and world.options.ShuffleSubconPaintings:
|
||||
add_rule(loc, lambda state, paintings=data.paintings: has_paintings(state, world, paintings))
|
||||
|
||||
if data.hit_type is not HitType.none and world.options.UmbrellaLogic.value > 0:
|
||||
if data.hit_type is not HitType.none and world.options.UmbrellaLogic:
|
||||
if data.hit_type == HitType.umbrella:
|
||||
add_rule(loc, lambda state: state.has("Umbrella", world.player))
|
||||
|
||||
@@ -283,7 +284,7 @@ def set_rules(world: "HatInTimeWorld"):
|
||||
# Illness starts the player past the intro
|
||||
alpine_entrance = world.multiworld.get_entrance("AFR -> Alpine Skyline Area", world.player)
|
||||
add_rule(alpine_entrance, lambda state: can_use_hookshot(state, world))
|
||||
if world.options.UmbrellaLogic.value > 0:
|
||||
if world.options.UmbrellaLogic:
|
||||
add_rule(alpine_entrance, lambda state: state.has("Umbrella", world.player))
|
||||
|
||||
if zipline_logic(world):
|
||||
@@ -347,9 +348,9 @@ def set_rules(world: "HatInTimeWorld"):
|
||||
|
||||
set_event_rules(world)
|
||||
|
||||
if world.options.EndGoal.value == 1:
|
||||
if world.options.EndGoal == EndGoal.option_finale:
|
||||
world.multiworld.completion_condition[world.player] = lambda state: state.has("Time Piece Cluster", world.player)
|
||||
elif world.options.EndGoal.value == 2:
|
||||
elif world.options.EndGoal == EndGoal.option_rush_hour:
|
||||
world.multiworld.completion_condition[world.player] = lambda state: state.has("Rush Hour Cleared", world.player)
|
||||
|
||||
|
||||
@@ -472,7 +473,7 @@ def set_moderate_rules(world: "HatInTimeWorld"):
|
||||
and can_use_hat(state, world, HatType.BREWING))
|
||||
|
||||
# Moderate: Bluefin Tunnel + Pink Paw Station without tickets
|
||||
if world.options.NoTicketSkips.value == 0:
|
||||
if not world.options.NoTicketSkips:
|
||||
set_rule(world.multiworld.get_entrance("-> Pink Paw Station", world.player), lambda state: True)
|
||||
set_rule(world.multiworld.get_entrance("-> Bluefin Tunnel", world.player), lambda state: True)
|
||||
|
||||
@@ -523,7 +524,7 @@ def set_hard_rules(world: "HatInTimeWorld"):
|
||||
lambda state: can_use_hat(state, world, HatType.ICE))
|
||||
|
||||
# Hard: clear Rush Hour with Brewing Hat only
|
||||
if world.options.NoTicketSkips.value != 1:
|
||||
if not world.options.NoTicketSkips:
|
||||
set_rule(world.multiworld.get_location("Act Completion (Rush Hour)", world.player),
|
||||
lambda state: can_use_hat(state, world, HatType.BREWING))
|
||||
else:
|
||||
@@ -579,7 +580,7 @@ def set_expert_rules(world: "HatInTimeWorld"):
|
||||
world.multiworld.get_region("Subcon Forest Area", world.player),
|
||||
"Subcon Forest Entrance YCHE", world.player)
|
||||
|
||||
if world.options.NoPaintingSkips.value > 0:
|
||||
if world.options.NoPaintingSkips:
|
||||
add_rule(entrance, lambda state: has_paintings(state, world, 1))
|
||||
|
||||
set_rule(world.multiworld.get_location("Act Completion (Toilet of Doom)", world.player),
|
||||
@@ -603,7 +604,7 @@ def set_expert_rules(world: "HatInTimeWorld"):
|
||||
|
||||
if world.is_dlc2():
|
||||
# Expert: clear Rush Hour with nothing
|
||||
if world.options.NoTicketSkips.value == 0:
|
||||
if not world.options.NoTicketSkips:
|
||||
set_rule(world.multiworld.get_location("Act Completion (Rush Hour)", world.player), lambda state: True)
|
||||
else:
|
||||
set_rule(world.multiworld.get_location("Act Completion (Rush Hour)", world.player),
|
||||
@@ -660,20 +661,19 @@ def set_mafia_town_rules(world: "HatInTimeWorld"):
|
||||
add_rule(world.multiworld.get_location("Mafia Town - Above Boats", world.player),
|
||||
lambda state: state.has("HUMT Access", world.player), "or")
|
||||
|
||||
ctr_logic: int = world.options.CTRLogic.value
|
||||
if ctr_logic == 3:
|
||||
if world.options.CTRLogic == CTRLogic.option_nothing:
|
||||
set_rule(world.multiworld.get_location("Act Completion (Cheating the Race)", world.player), lambda state: True)
|
||||
elif ctr_logic == 2:
|
||||
elif world.options.CTRLogic == CTRLogic.option_sprint:
|
||||
add_rule(world.multiworld.get_location("Act Completion (Cheating the Race)", world.player),
|
||||
lambda state: can_use_hat(state, world, HatType.SPRINT), "or")
|
||||
elif ctr_logic == 1:
|
||||
elif world.options.CTRLogic == CTRLogic.option_scooter:
|
||||
add_rule(world.multiworld.get_location("Act Completion (Cheating the Race)", world.player),
|
||||
lambda state: can_use_hat(state, world, HatType.SPRINT)
|
||||
and state.has("Scooter Badge", world.player), "or")
|
||||
|
||||
|
||||
def set_botb_rules(world: "HatInTimeWorld"):
|
||||
if world.options.UmbrellaLogic.value == 0 and get_difficulty(world) < Difficulty.MODERATE:
|
||||
if not world.options.UmbrellaLogic and get_difficulty(world) < Difficulty.MODERATE:
|
||||
set_rule(world.multiworld.get_location("Dead Bird Studio - DJ Grooves Sign Chest", world.player),
|
||||
lambda state: state.has("Umbrella", world.player) or can_use_hat(state, world, HatType.BREWING))
|
||||
set_rule(world.multiworld.get_location("Dead Bird Studio - Tepee Chest", world.player),
|
||||
|
||||
@@ -5,7 +5,7 @@ from .Regions import create_regions, randomize_act_entrances, chapter_act_info,
|
||||
from .Locations import location_table, contract_locations, is_location_valid, get_location_names, TASKSANITY_START_ID, \
|
||||
get_total_locations
|
||||
from .Rules import set_rules
|
||||
from .Options import AHITOptions, slot_data_options, adjust_options
|
||||
from .Options import AHITOptions, slot_data_options, adjust_options, RandomizeHatOrder, EndGoal
|
||||
from .Types import HatType, ChapterIndex, HatInTimeItem
|
||||
from .DeathWishLocations import create_dw_regions, dw_classes, death_wishes
|
||||
from .DeathWishRules import set_dw_rules, create_enemy_events
|
||||
@@ -87,24 +87,24 @@ class HatInTimeWorld(World):
|
||||
|
||||
# If our starting chapter is 4 and act rando isn't on, force hookshot into inventory
|
||||
# If starting chapter is 3 and painting shuffle is enabled, and act rando isn't, give one free painting unlock
|
||||
start_chapter: int = self.options.StartingChapter.value
|
||||
start_chapter: ChapterIndex = ChapterIndex(self.options.StartingChapter)
|
||||
|
||||
if start_chapter == 4 or start_chapter == 3:
|
||||
if self.options.ActRandomizer.value == 0:
|
||||
if start_chapter == 4:
|
||||
if start_chapter == ChapterIndex.ALPINE or start_chapter == ChapterIndex.SUBCON:
|
||||
if not self.options.ActRandomizer:
|
||||
if start_chapter == ChapterIndex.ALPINE:
|
||||
self.multiworld.push_precollected(self.create_item("Hookshot Badge"))
|
||||
if self.options.UmbrellaLogic.value > 0:
|
||||
if self.options.UmbrellaLogic:
|
||||
self.multiworld.push_precollected(self.create_item("Umbrella"))
|
||||
|
||||
if start_chapter == 3 and self.options.ShuffleSubconPaintings.value > 0:
|
||||
if start_chapter == ChapterIndex.SUBCON and self.options.ShuffleSubconPaintings:
|
||||
self.multiworld.push_precollected(self.create_item("Progressive Painting Unlock"))
|
||||
|
||||
def create_regions(self):
|
||||
# noinspection PyClassVar
|
||||
self.topology_present = bool(self.options.ActRandomizer.value)
|
||||
self.topology_present = bool(self.options.ActRandomizer)
|
||||
|
||||
create_regions(self)
|
||||
if self.options.EnableDeathWish.value > 0:
|
||||
if self.options.EnableDeathWish:
|
||||
create_dw_regions(self)
|
||||
|
||||
if self.is_dw_only():
|
||||
@@ -116,7 +116,7 @@ class HatInTimeWorld(World):
|
||||
create_enemy_events(self)
|
||||
|
||||
# place vanilla contract locations if contract shuffle is off
|
||||
if self.options.ShuffleActContracts.value == 0:
|
||||
if not self.options.ShuffleActContracts:
|
||||
for name in contract_locations.keys():
|
||||
self.multiworld.get_location(name, self.player).place_locked_item(create_item(self, name))
|
||||
|
||||
@@ -124,9 +124,9 @@ class HatInTimeWorld(World):
|
||||
if self.has_yarn():
|
||||
calculate_yarn_costs(self)
|
||||
|
||||
if self.options.RandomizeHatOrder.value > 0:
|
||||
if self.options.RandomizeHatOrder:
|
||||
self.random.shuffle(self.hat_craft_order)
|
||||
if self.options.RandomizeHatOrder.value == 2:
|
||||
if self.options.RandomizeHatOrder == RandomizeHatOrder.option_time_stop_last:
|
||||
self.hat_craft_order.remove(HatType.TIME_STOP)
|
||||
self.hat_craft_order.append(HatType.TIME_STOP)
|
||||
|
||||
@@ -141,12 +141,12 @@ class HatInTimeWorld(World):
|
||||
self.multiworld.completion_condition[self.player] = lambda state: state.has("Death Wish Only Mode",
|
||||
self.player)
|
||||
|
||||
if self.options.DWEnableBonus.value == 0:
|
||||
if not self.options.DWEnableBonus:
|
||||
for name in death_wishes:
|
||||
if name == "Snatcher Coins in Nyakuza Metro" and not self.is_dlc2():
|
||||
continue
|
||||
|
||||
if self.options.DWShuffle.value > 0 and name not in self.dw_shuffle:
|
||||
if self.options.DWShuffle and name not in self.dw_shuffle:
|
||||
continue
|
||||
|
||||
full_clear = self.multiworld.get_location(f"{name} - All Clear", self.player)
|
||||
@@ -156,7 +156,7 @@ class HatInTimeWorld(World):
|
||||
|
||||
return
|
||||
|
||||
if self.options.ActRandomizer.value > 0:
|
||||
if self.options.ActRandomizer:
|
||||
randomize_act_entrances(self)
|
||||
|
||||
set_rules(self)
|
||||
@@ -192,7 +192,7 @@ class HatInTimeWorld(World):
|
||||
slot_data.setdefault("Hat4", int(self.hat_craft_order[3]))
|
||||
slot_data.setdefault("Hat5", int(self.hat_craft_order[4]))
|
||||
|
||||
if self.options.ActRandomizer.value > 0:
|
||||
if self.options.ActRandomizer:
|
||||
for name in self.act_connections.keys():
|
||||
slot_data[name] = self.act_connections[name]
|
||||
|
||||
@@ -203,14 +203,14 @@ class HatInTimeWorld(World):
|
||||
if self.is_dw():
|
||||
i = 0
|
||||
for name in self.excluded_dws:
|
||||
if self.options.EndGoal.value == 3 and name == "Seal the Deal":
|
||||
if self.options.EndGoal.value == EndGoal.option_seal_the_deal and name == "Seal the Deal":
|
||||
continue
|
||||
|
||||
slot_data[f"excluded_dw{i}"] = dw_classes[name]
|
||||
i += 1
|
||||
|
||||
i = 0
|
||||
if self.options.DWAutoCompleteBonuses.value == 0:
|
||||
if not self.options.DWAutoCompleteBonuses:
|
||||
for name in self.excluded_bonuses:
|
||||
if name in self.excluded_dws:
|
||||
continue
|
||||
@@ -218,7 +218,7 @@ class HatInTimeWorld(World):
|
||||
slot_data[f"excluded_bonus{i}"] = dw_classes[name]
|
||||
i += 1
|
||||
|
||||
if self.options.DWShuffle.value > 0:
|
||||
if self.options.DWShuffle:
|
||||
shuffled_dws = self.dw_shuffle
|
||||
for i in range(len(shuffled_dws)):
|
||||
slot_data[f"dw_{i}"] = dw_classes[shuffled_dws[i]]
|
||||
@@ -244,7 +244,7 @@ class HatInTimeWorld(World):
|
||||
return slot_data
|
||||
|
||||
def extend_hint_information(self, hint_data: Dict[int, Dict[int, str]]):
|
||||
if self.is_dw_only() or self.options.ActRandomizer.value == 0:
|
||||
if self.is_dw_only() or not self.options.ActRandomizer:
|
||||
return
|
||||
|
||||
new_hint_data = {}
|
||||
@@ -273,10 +273,10 @@ class HatInTimeWorld(World):
|
||||
|
||||
new_hint_data[location.address] = get_shuffled_region(self, region_name)
|
||||
|
||||
if self.is_dlc1() and self.options.Tasksanity.value > 0:
|
||||
if self.is_dlc1() and self.options.Tasksanity:
|
||||
ship_shape_region = get_shuffled_region(self, "Ship Shape")
|
||||
id_start: int = TASKSANITY_START_ID
|
||||
for i in range(self.options.TasksanityCheckCount.value):
|
||||
for i in range(self.options.TasksanityCheckCount):
|
||||
new_hint_data[id_start+i] = ship_shape_region
|
||||
|
||||
hint_data[self.player] = new_hint_data
|
||||
@@ -289,23 +289,23 @@ class HatInTimeWorld(World):
|
||||
spoiler_handle.write("Hat Cost: %s: %i\n" % (hat, self.hat_yarn_costs[hat]))
|
||||
|
||||
def has_yarn(self) -> bool:
|
||||
return not self.is_dw_only() and self.options.HatItems.value == 0
|
||||
return not self.is_dw_only() and not self.options.HatItems
|
||||
|
||||
def is_dlc1(self) -> bool:
|
||||
return self.options.EnableDLC1.value > 0
|
||||
return bool(self.options.EnableDLC1)
|
||||
|
||||
def is_dlc2(self) -> bool:
|
||||
return self.options.EnableDLC2.value > 0
|
||||
return bool(self.options.EnableDLC2)
|
||||
|
||||
def is_dw(self) -> bool:
|
||||
return self.options.EnableDeathWish.value > 0
|
||||
return bool(self.options.EnableDeathWish)
|
||||
|
||||
def is_dw_only(self) -> bool:
|
||||
return self.is_dw() and self.options.DeathWishOnly.value > 0
|
||||
return self.is_dw() and bool(self.options.DeathWishOnly)
|
||||
|
||||
def is_dw_excluded(self, name: str) -> bool:
|
||||
# don't exclude Seal the Deal if it's our goal
|
||||
if self.options.EndGoal.value == 3 and name == "Seal the Deal" \
|
||||
if self.options.EndGoal.value == EndGoal.option_seal_the_deal and name == "Seal the Deal" \
|
||||
and f"{name} - Main Objective" not in self.options.exclude_locations:
|
||||
return False
|
||||
|
||||
|
||||
Reference in New Issue
Block a user