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