mirror of
https://github.com/ArchipelagoMW/Archipelago.git
synced 2026-03-27 16:33:27 -07:00
Improve performance for death wish rules
This commit is contained in:
@@ -230,7 +230,7 @@ def create_dw_locations(world: "HatInTimeWorld", dw: Region):
|
||||
dw.locations.append(bonus_stamps)
|
||||
main_stamp.place_locked_item(HatInTimeItem(f"1 Stamp - {dw.name}",
|
||||
ItemClassification.progression, None, world.player))
|
||||
bonus_stamps.place_locked_item(HatInTimeItem(f"2 Stamps - {dw.name}",
|
||||
bonus_stamps.place_locked_item(HatInTimeItem(f"2 Stamp - {dw.name}",
|
||||
ItemClassification.progression, None, world.player))
|
||||
|
||||
if dw.name in world.excluded_dws:
|
||||
|
||||
@@ -5,8 +5,7 @@ from .DeathWishLocations import dw_prereqs, dw_candles
|
||||
from BaseClasses import Entrance, Location, ItemClassification
|
||||
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 .Locations import death_wishes
|
||||
from .Options import EndGoal
|
||||
|
||||
if TYPE_CHECKING:
|
||||
@@ -121,7 +120,7 @@ def set_dw_rules(world: "HatInTimeWorld"):
|
||||
dw = world.multiworld.get_region(name, world.player)
|
||||
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])
|
||||
add_rule(entrance, lambda state, n=name: state.has("Stamps", world.player, 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)
|
||||
@@ -259,36 +258,13 @@ def modify_dw_rules(world: "HatInTimeWorld", name: str):
|
||||
set_candle_dw_rules(name, world)
|
||||
|
||||
|
||||
def get_total_dw_stamps(state: CollectionState, world: "HatInTimeWorld") -> int:
|
||||
if world.options.DWShuffle:
|
||||
return 999 # no stamp costs in death wish shuffle
|
||||
|
||||
count = 0
|
||||
|
||||
for name in death_wishes:
|
||||
if name == "Snatcher Coins in Nyakuza Metro" and not world.is_dlc2():
|
||||
continue
|
||||
|
||||
if state.has(f"1 Stamp - {name}", world.player):
|
||||
count += 1
|
||||
else:
|
||||
continue
|
||||
|
||||
if state.has(f"2 Stamps - {name}", world.player):
|
||||
count += 2
|
||||
elif name not in dw_candles:
|
||||
count += 1
|
||||
|
||||
return count
|
||||
|
||||
|
||||
def set_candle_dw_rules(name: str, world: "HatInTimeWorld"):
|
||||
main_objective = world.multiworld.get_location(f"{name} - Main Objective", world.player)
|
||||
full_clear = world.multiworld.get_location(f"{name} - All Clear", world.player)
|
||||
|
||||
if name == "Zero Jumps":
|
||||
add_rule(main_objective, lambda state: get_zero_jump_clear_count(state, world) >= 1)
|
||||
add_rule(full_clear, lambda state: get_zero_jump_clear_count(state, world) >= 4
|
||||
add_rule(main_objective, lambda state: state.has("Zero Jumps", world.player))
|
||||
add_rule(full_clear, lambda state: state.has("Zero Jumps", world.player, 4)
|
||||
and state.has("Train Rush (Zero Jumps)", world.player) and can_use_hat(state, world, HatType.ICE))
|
||||
|
||||
# No Ice Hat/painting required in Expert for Toilet Zero Jumps
|
||||
@@ -306,11 +282,11 @@ def set_candle_dw_rules(name: str, world: "HatInTimeWorld"):
|
||||
|
||||
elif name == "Snatcher's Hit List":
|
||||
add_rule(main_objective, lambda state: state.has("Mafia Goon", world.player))
|
||||
add_rule(full_clear, lambda state: get_reachable_enemy_count(state, world) >= 12)
|
||||
add_rule(full_clear, lambda state: state.has("Enemy", world.player, 12))
|
||||
|
||||
elif name == "Camera Tourist":
|
||||
add_rule(main_objective, lambda state: get_reachable_enemy_count(state, world) >= 8)
|
||||
add_rule(full_clear, lambda state: can_reach_all_bosses(state, world)
|
||||
add_rule(main_objective, lambda state: state.has("Enemy", world.player, 8))
|
||||
add_rule(full_clear, lambda state: state.has("Boss", world.player, 6)
|
||||
and state.has("Triple Enemy Photo", world.player))
|
||||
|
||||
elif "Snatcher Coins" in name:
|
||||
@@ -325,48 +301,6 @@ def set_candle_dw_rules(name: str, world: "HatInTimeWorld"):
|
||||
or state.has(coins[2], world.player))
|
||||
|
||||
|
||||
def get_zero_jump_clear_count(state: CollectionState, world: "HatInTimeWorld") -> int:
|
||||
total = 0
|
||||
|
||||
for name in act_chapters.keys():
|
||||
n = f"{name} (Zero Jumps)"
|
||||
if n not in zero_jumps:
|
||||
continue
|
||||
|
||||
if get_difficulty(world) < Difficulty.HARD and n in zero_jumps_hard:
|
||||
continue
|
||||
|
||||
if get_difficulty(world) < Difficulty.EXPERT and n in zero_jumps_expert:
|
||||
continue
|
||||
|
||||
if not state.has(n, world.player):
|
||||
continue
|
||||
|
||||
total += 1
|
||||
|
||||
return total
|
||||
|
||||
|
||||
def get_reachable_enemy_count(state: CollectionState, world: "HatInTimeWorld") -> int:
|
||||
count = 0
|
||||
for enemy in hit_list.keys():
|
||||
if enemy in bosses:
|
||||
continue
|
||||
|
||||
if state.has(enemy, world.player):
|
||||
count += 1
|
||||
|
||||
return count
|
||||
|
||||
|
||||
def can_reach_all_bosses(state: CollectionState, world: "HatInTimeWorld") -> bool:
|
||||
for boss in bosses:
|
||||
if not state.has(boss, world.player):
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
|
||||
def create_enemy_events(world: "HatInTimeWorld"):
|
||||
no_tourist = "Camera Tourist" in world.excluded_dws
|
||||
for enemy, regions in hit_list.items():
|
||||
|
||||
@@ -8,8 +8,8 @@ from .Rules import set_rules
|
||||
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
|
||||
from worlds.AutoWorld import World, WebWorld
|
||||
from .DeathWishRules import set_dw_rules, create_enemy_events, hit_list, bosses
|
||||
from worlds.AutoWorld import World, WebWorld, CollectionState
|
||||
from typing import List, Dict, TextIO
|
||||
from worlds.LauncherComponents import Component, components, icon_paths, launch_subprocess, Type
|
||||
from Utils import local_path
|
||||
@@ -288,6 +288,44 @@ class HatInTimeWorld(World):
|
||||
for hat in self.hat_craft_order:
|
||||
spoiler_handle.write("Hat Cost: %s: %i\n" % (hat, self.hat_yarn_costs[hat]))
|
||||
|
||||
def collect(self, state: "CollectionState", item: "Item") -> bool:
|
||||
old_count: int = state.count(item.name, self.player)
|
||||
change = super().collect(state, item)
|
||||
if change and old_count == 0:
|
||||
if "Stamp" in item.name:
|
||||
if "2 Stamp" in item.name:
|
||||
state.prog_items[self.player]["Stamps"] += 2
|
||||
else:
|
||||
state.prog_items[self.player]["Stamps"] += 1
|
||||
elif "(Zero Jumps)" in item.name:
|
||||
state.prog_items[self.player]["Zero Jumps"] += 1
|
||||
elif item.name in hit_list.keys():
|
||||
if item.name not in bosses:
|
||||
state.prog_items[self.player]["Enemy"] += 1
|
||||
else:
|
||||
state.prog_items[self.player]["Boss"] += 1
|
||||
|
||||
return change
|
||||
|
||||
def remove(self, state: "CollectionState", item: "Item") -> bool:
|
||||
old_count: int = state.count(item.name, self.player)
|
||||
change = super().collect(state, item)
|
||||
if change and old_count == 1:
|
||||
if "Stamp" in item.name:
|
||||
if "2 Stamp" in item.name:
|
||||
state.prog_items[self.player]["Stamps"] -= 2
|
||||
else:
|
||||
state.prog_items[self.player]["Stamps"] -= 1
|
||||
elif "(Zero Jumps)" in item.name:
|
||||
state.prog_items[self.player]["Zero Jumps"] -= 1
|
||||
elif item.name in hit_list.keys():
|
||||
if item.name not in bosses:
|
||||
state.prog_items[self.player]["Enemy"] -= 1
|
||||
else:
|
||||
state.prog_items[self.player]["Boss"] -= 1
|
||||
|
||||
return change
|
||||
|
||||
def has_yarn(self) -> bool:
|
||||
return not self.is_dw_only() and not self.options.HatItems
|
||||
|
||||
|
||||
Reference in New Issue
Block a user