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)
 | 
