fix(logic): exception for vanilla mire key door layout, crystal switches can be reached with two keys, just can't tell which one was chosen
This commit is contained in:
@@ -695,7 +695,7 @@ class CollectionState(object):
|
||||
@staticmethod
|
||||
def valid_crystal(door, new_crystal_state):
|
||||
return (not door.crystal or door.crystal == CrystalBarrier.Either or new_crystal_state == CrystalBarrier.Either
|
||||
or new_crystal_state == door.crystal)
|
||||
or new_crystal_state == door.crystal or door.alternative_crystal_rule)
|
||||
|
||||
def check_key_doors_in_dungeons(self, rrp, player):
|
||||
for dungeon_name, checklist in self.dungeons_to_check[player].items():
|
||||
@@ -1828,6 +1828,7 @@ class Door(object):
|
||||
self.bigKey = False # There's a big key door on this side
|
||||
self.ugly = False # Indicates that it can't be seen from the front (e.g. back of a big key door)
|
||||
self.crystal = CrystalBarrier.Null # How your crystal state changes if you use this door
|
||||
self.alternative_crystal_rule = False
|
||||
self.req_event = None # if a dungeon event is required for this door - swamp palace mostly
|
||||
self.controller = None
|
||||
self.dependents = []
|
||||
@@ -3209,3 +3210,4 @@ class KeyRuleType(FastEnum):
|
||||
WorstCase = 0
|
||||
AllowSmall = 1
|
||||
Lock = 2
|
||||
CrystalAlternative = 3
|
||||
|
||||
@@ -20,7 +20,7 @@ from DungeonGenerator import create_dungeon_builders, split_dungeon_builder, sim
|
||||
from DungeonGenerator import dungeon_portals, dungeon_drops, connect_doors, count_reserved_locations
|
||||
from DungeonGenerator import valid_region_to_explore
|
||||
from KeyDoorShuffle import analyze_dungeon, build_key_layout, validate_key_layout, determine_prize_lock
|
||||
from KeyDoorShuffle import validate_bk_layout
|
||||
from KeyDoorShuffle import validate_bk_layout, DoorRules
|
||||
from Utils import ncr, kth_combination
|
||||
|
||||
|
||||
@@ -279,9 +279,28 @@ def vanilla_key_logic(world, player):
|
||||
if pod_front.new_rules[KeyRuleType.WorstCase] == 6:
|
||||
pod_front.new_rules[KeyRuleType.WorstCase] = 1
|
||||
pod_front.small_key_num = 1
|
||||
# adjust mire key logic - this currently cannot be done dynamically
|
||||
create_alternative_door_rules('Mire Hub Upper Blue Barrier', 2, 'Misery Mire', world, player)
|
||||
create_alternative_door_rules('Mire Hub Lower Blue Barrier', 2, 'Misery Mire', world, player)
|
||||
create_alternative_door_rules('Mire Hub Right Blue Barrier', 2, 'Misery Mire', world, player)
|
||||
create_alternative_door_rules('Mire Hub Top Blue Barrier', 2, 'Misery Mire', world, player)
|
||||
create_alternative_door_rules('Mire Hub Switch Blue Barrier N', 2, 'Misery Mire', world, player)
|
||||
create_alternative_door_rules('Mire Hub Switch Blue Barrier S', 2, 'Misery Mire', world, player)
|
||||
create_alternative_door_rules('Mire Map Spot Blue Barrier', 2, 'Misery Mire', world, player)
|
||||
create_alternative_door_rules('Mire Map Spike Side Blue Barrier', 2, 'Misery Mire', world, player)
|
||||
create_alternative_door_rules('Mire Crystal Dead End Left Barrier', 2, 'Misery Mire', world, player)
|
||||
create_alternative_door_rules('Mire Crystal Dead End Right Barrier', 2, 'Misery Mire', world, player)
|
||||
# gt logic? I'm unsure it needs adjusting
|
||||
|
||||
|
||||
def create_alternative_door_rules(door, amount, dungeon, world, player):
|
||||
rules = DoorRules(0, True)
|
||||
world.key_logic[player][dungeon].door_rules[door] = rules
|
||||
rules.new_rules[KeyRuleType.CrystalAlternative] = amount
|
||||
world.get_door(door, player).alternative_crystal_rule = True
|
||||
|
||||
|
||||
|
||||
def validate_vanilla_reservation(dungeon, world, player):
|
||||
return validate_key_layout(world.key_layout[player][dungeon.name], world, player)
|
||||
|
||||
|
||||
@@ -142,7 +142,7 @@ These are now independent of retro mode and have three options: None, Random, an
|
||||
# Patch Notes
|
||||
|
||||
* 1.4.1.10u
|
||||
* ?
|
||||
* Vanilla key logic: Fix for vanilla layout Misery Mire which allows more complex key logic. Locations blocked by crystal switch access is only locked by 2 keys thanks to that being the minimun in Mire to reach one of two crystal switches.
|
||||
* Autotracking: Fix for chest turn counter with chest containing multiworld items (Thanks Hiimcody)
|
||||
* Rom: Code prettification and fixing byte designations by Codemann
|
||||
* 1.4.1.9u
|
||||
|
||||
16
Rules.py
16
Rules.py
@@ -2332,6 +2332,9 @@ def add_key_logic_rules(world, player):
|
||||
for d_name, d_logic in key_logic.items():
|
||||
for door_name, rule in d_logic.door_rules.items():
|
||||
door_entrance = world.get_entrance(door_name, player)
|
||||
if not door_entrance.door.smallKey and door_entrance.door.crystal == CrystalBarrier.Blue:
|
||||
add_rule(door_entrance, eval_alternative_crystal(door_name, d_name, player), 'or')
|
||||
else:
|
||||
add_rule(door_entrance, eval_func(door_name, d_name, player))
|
||||
if door_entrance.door.dependents:
|
||||
for dep in door_entrance.door.dependents:
|
||||
@@ -2427,6 +2430,15 @@ def eval_small_key_door_strict_main(state, door_name, dungeon, player):
|
||||
return state.has_sm_key_strict(key_layout.key_logic.small_key_name, player, number)
|
||||
|
||||
|
||||
def eval_alternative_crystal_main(state, door_name, dungeon, player):
|
||||
key_logic = state.world.key_logic[player][dungeon]
|
||||
door_rule = key_logic.door_rules[door_name]
|
||||
for ruleType, number in door_rule.new_rules.items():
|
||||
if ruleType == KeyRuleType.CrystalAlternative:
|
||||
return state.has_sm_key(key_logic.small_key_name, player, number)
|
||||
return False
|
||||
|
||||
|
||||
def eval_small_key_door(door_name, dungeon, player):
|
||||
return lambda state: eval_small_key_door_main(state, door_name, dungeon, player)
|
||||
|
||||
@@ -2439,6 +2451,10 @@ def eval_small_key_door_strict(door_name, dungeon, player):
|
||||
return lambda state: eval_small_key_door_strict_main(state, door_name, dungeon, player)
|
||||
|
||||
|
||||
def eval_alternative_crystal(door_name, dungeon, player):
|
||||
return lambda state: eval_alternative_crystal_main(state, door_name, dungeon, player)
|
||||
|
||||
|
||||
def allow_big_key_in_big_chest(bk_name, player):
|
||||
return lambda state, item: item.name == bk_name and item.player == player
|
||||
|
||||
|
||||
Reference in New Issue
Block a user