104 lines
		
	
	
		
			5.4 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
		
		
			
		
	
	
			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) |