Archipelago/worlds/cv64/rules.py

104 lines
5.4 KiB
Python

from typing import Dict, TYPE_CHECKING
from BaseClasses import CollectionState
from worlds.generic.Rules import allow_self_locking_items, CollectionRule
from .options import DraculasCondition
from .entrances import get_entrance_info
from .data import iname, rname
if TYPE_CHECKING:
from . import CV64World
class CV64Rules:
player: int
world: "CV64World"
rules: Dict[str, CollectionRule]
s1s_per_warp: int
required_s2s: int
drac_condition: int
def __init__(self, world: "CV64World") -> None:
self.player = world.player
self.world = world
self.s1s_per_warp = world.s1s_per_warp
self.required_s2s = world.required_s2s
self.drac_condition = world.drac_condition
self.rules = {
iname.left_tower_key: lambda state: state.has(iname.left_tower_key, self.player),
iname.storeroom_key: lambda state: state.has(iname.storeroom_key, self.player),
iname.archives_key: lambda state: state.has(iname.archives_key, self.player),
iname.garden_key: lambda state: state.has(iname.garden_key, self.player),
iname.copper_key: lambda state: state.has(iname.copper_key, self.player),
iname.chamber_key: lambda state: state.has(iname.chamber_key, self.player),
"Bomb 1": lambda state: state.has_all({iname.magical_nitro, iname.mandragora}, self.player),
"Bomb 2": lambda state: state.has(iname.magical_nitro, self.player, 2)
and state.has(iname.mandragora, self.player, 2),
iname.execution_key: lambda state: state.has(iname.execution_key, self.player),
iname.science_key1: lambda state: state.has(iname.science_key1, self.player),
iname.science_key2: lambda state: state.has(iname.science_key2, self.player),
iname.science_key3: lambda state: state.has(iname.science_key3, self.player),
iname.clocktower_key1: lambda state: state.has(iname.clocktower_key1, self.player),
iname.clocktower_key2: lambda state: state.has(iname.clocktower_key2, self.player),
iname.clocktower_key3: lambda state: state.has(iname.clocktower_key3, self.player),
"Dracula": self.can_enter_dracs_chamber
}
def can_enter_dracs_chamber(self, state: CollectionState) -> bool:
drac_object_name = None
if self.drac_condition == DraculasCondition.option_crystal:
drac_object_name = "Crystal"
elif self.drac_condition == DraculasCondition.option_bosses:
drac_object_name = "Trophy"
elif self.drac_condition == DraculasCondition.option_specials:
drac_object_name = "Special2"
if drac_object_name is not None:
return state.has(drac_object_name, self.player, self.required_s2s)
return True
def set_cv64_rules(self) -> None:
multiworld = self.world.multiworld
for region in multiworld.get_regions(self.player):
# Set each entrance's rule if it should have one.
# Warp entrances have their own special handling.
for entrance in region.entrances:
if entrance.parent_region.name == "Menu":
if entrance.name.startswith("Warp "):
entrance.access_rule = lambda state, warp_num=int(entrance.name[5]): \
state.has(iname.special_one, self.player, self.s1s_per_warp * warp_num)
else:
ent_rule = get_entrance_info(entrance.name, "rule")
if ent_rule in self.rules:
entrance.access_rule = self.rules[ent_rule]
multiworld.completion_condition[self.player] = lambda state: state.has(iname.victory, self.player)
if self.world.options.accessibility: # not locations accessibility
self.set_self_locking_items()
def set_self_locking_items(self) -> None:
multiworld = self.world.multiworld
# Do the regions that we know for a fact always exist, and we always do no matter what.
allow_self_locking_items(multiworld.get_region(rname.villa_archives, self.player), iname.archives_key)
allow_self_locking_items(multiworld.get_region(rname.cc_torture_chamber, self.player), iname.chamber_key)
# Add this region if the world doesn't have the Villa Storeroom warp entrance.
if "Villa" not in self.world.active_warp_list[1:]:
allow_self_locking_items(multiworld.get_region(rname.villa_storeroom, self.player), iname.storeroom_key)
# Add this region if Hard Logic is on and Multi Hit Breakables are off.
if self.world.options.hard_logic and not self.world.options.multi_hit_breakables:
allow_self_locking_items(multiworld.get_region(rname.cw_ltower, self.player), iname.left_tower_key)
# Add these regions if Tower of Science is in the world.
if "Tower of Science" in self.world.active_stage_exits:
allow_self_locking_items(multiworld.get_region(rname.tosci_three_doors, self.player), iname.science_key1)
allow_self_locking_items(multiworld.get_region(rname.tosci_key3, self.player), iname.science_key3)
# Add this region if Tower of Execution is in the world and Hard Logic is not on.
if "Tower of Execution" in self.world.active_stage_exits and self.world.options.hard_logic:
allow_self_locking_items(multiworld.get_region(rname.toe_ledge, self.player), iname.execution_key)