Skip to content

Commit

Permalink
OSRS: Add missing indirect conditions
Browse files Browse the repository at this point in the history
All entrances to Cooks_Guild and Crafting_Guild and all entrances using
special logic for canoes were missing indirect conditions for the
regions that the cooking, crafting and woodcutting skill rules require
access to.
  • Loading branch information
Mysteryem committed Oct 4, 2024
1 parent 05a6738 commit 51e9b71
Showing 1 changed file with 104 additions and 0 deletions.
104 changes: 104 additions & 0 deletions worlds/osrs/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -190,12 +190,83 @@ def generate_special_rules_for(self, entrance, region_row, outbound_region_name)
cooking_level_rule = self.get_skill_rule("cooking", 32)
entrance.access_rule = lambda state: state.has(item_name, self.player) and \
cooking_level_rule(state)
if self.options.brutal_grinds:
cooking_level_32_regions = {
RegionNames.Milk,
RegionNames.Egg,
RegionNames.Shrimp,
RegionNames.Wheat,
RegionNames.Windmill,
}
else:
# Level 15 cooking and higher requires level 20 fishing.
fishing_level_20_regions = {
RegionNames.Shrimp,
RegionNames.Port_Sarim,
}
cooking_level_32_regions = {
RegionNames.Milk,
RegionNames.Egg,
RegionNames.Shrimp,
RegionNames.Wheat,
RegionNames.Windmill,
RegionNames.Fly_Fish,
*fishing_level_20_regions,
}
for region_name in cooking_level_32_regions:
self.multiworld.register_indirect_condition(self.get_region(region_name), entrance)
return
if outbound_region_name == RegionNames.Crafting_Guild:
item_name = self.region_rows_by_name[outbound_region_name].itemReq.replace('*', '')
crafting_level_rule = self.get_skill_rule("crafting", 40)
entrance.access_rule = lambda state: state.has(item_name, self.player) and \
crafting_level_rule(state)
if self.options.brutal_grinds:
crafting_level_40_regions = {
# can_spin
RegionNames.Sheep,
RegionNames.Spinning_Wheel,
# can_pot
RegionNames.Clay_Rock,
RegionNames.Barbarian_Village,
# can_tan
RegionNames.Milk,
RegionNames.Al_Kharid,
}
else:
mould_access_regions = {
RegionNames.Al_Kharid,
RegionNames.Rimmington,
}
smithing_level_20_regions = {
RegionNames.Bronze_Ores,
RegionNames.Iron_Rock,
RegionNames.Furnace,
RegionNames.Anvil,
}
smithing_level_40_regions = {
*smithing_level_20_regions,
RegionNames.Coal_Rock,
}
crafting_level_40_regions = {
# can_tan
RegionNames.Milk,
RegionNames.Al_Kharid,
# can_silver
RegionNames.Silver_Rock,
RegionNames.Furnace,
*mould_access_regions,
# can_smelt_silver
*smithing_level_20_regions,
# can_gold
RegionNames.Gold_Rock,
RegionNames.Furnace,
*mould_access_regions,
# can_smelt_gold
*smithing_level_40_regions,
}
for region_name in crafting_level_40_regions:
self.multiworld.register_indirect_condition(self.get_region(region_name), entrance)
return
if outbound_region_name == RegionNames.Corsair_Cove:
item_name = self.region_rows_by_name[outbound_region_name].itemReq.replace('*', '')
Expand Down Expand Up @@ -224,6 +295,20 @@ def generate_special_rules_for(self, entrance, region_row, outbound_region_name)
woodcutting_rule_d3 = self.get_skill_rule("woodcutting", 42)
woodcutting_rule_all = self.get_skill_rule("woodcutting", 57)

def add_indirect_conditions_for_woodcutting_levels(entrance, *levels: int):
if self.options.brutal_grinds:
# No access to specific regions required.
return
# Currently, each level requirement requires everything from the previous level requirements, so the
# maximum level requirement can be taken.
max_level = max(levels, default=0)
max_level = min(max_level, self.options.max_woodcutting_level.value)
if 15 <= max_level < 30:
self.multiworld.register_indirect_condition(self.get_region(RegionNames.Oak_Tree), entrance)
elif 30 <= max_level:
self.multiworld.register_indirect_condition(self.get_region(RegionNames.Oak_Tree), entrance)
self.multiworld.register_indirect_condition(self.get_region(RegionNames.Willow_Tree), entrance)

if region_row.name == RegionNames.Lumbridge:
# Canoe Tree access for the Location
if outbound_region_name == RegionNames.Canoe_Tree:
Expand All @@ -236,6 +321,7 @@ def generate_special_rules_for(self, entrance, region_row, outbound_region_name)
and woodcutting_rule_d3(state) and self.options.max_woodcutting_level >= 42) or \
(state.can_reach_region(RegionNames.Wilderness)
and woodcutting_rule_all(state) and self.options.max_woodcutting_level >= 57)
add_indirect_conditions_for_woodcutting_levels(entrance, 12, 27, 42, 57)
self.multiworld.register_indirect_condition(
self.multiworld.get_region(RegionNames.South_Of_Varrock, self.player), entrance)
self.multiworld.register_indirect_condition(
Expand All @@ -249,12 +335,15 @@ def generate_special_rules_for(self, entrance, region_row, outbound_region_name)
if outbound_region_name == RegionNames.Barbarian_Village:
entrance.access_rule = lambda state: woodcutting_rule_d2(state) \
and self.options.max_woodcutting_level >= 27
add_indirect_conditions_for_woodcutting_levels(entrance, 27)
if outbound_region_name == RegionNames.Edgeville:
entrance.access_rule = lambda state: woodcutting_rule_d3(state) \
and self.options.max_woodcutting_level >= 42
add_indirect_conditions_for_woodcutting_levels(entrance, 42)
if outbound_region_name == RegionNames.Wilderness:
entrance.access_rule = lambda state: woodcutting_rule_all(state) \
and self.options.max_woodcutting_level >= 57
add_indirect_conditions_for_woodcutting_levels(entrance, 57)

if region_row.name == RegionNames.South_Of_Varrock:
if outbound_region_name == RegionNames.Canoe_Tree:
Expand All @@ -267,6 +356,7 @@ def generate_special_rules_for(self, entrance, region_row, outbound_region_name)
and woodcutting_rule_d2(state) and self.options.max_woodcutting_level >= 27) or \
(state.can_reach_region(RegionNames.Wilderness)
and woodcutting_rule_d3(state) and self.options.max_woodcutting_level >= 42)
add_indirect_conditions_for_woodcutting_levels(entrance, 12, 27, 42)
self.multiworld.register_indirect_condition(
self.multiworld.get_region(RegionNames.Lumbridge, self.player), entrance)
self.multiworld.register_indirect_condition(
Expand All @@ -280,12 +370,15 @@ def generate_special_rules_for(self, entrance, region_row, outbound_region_name)
if outbound_region_name == RegionNames.Barbarian_Village:
entrance.access_rule = lambda state: woodcutting_rule_d1(state) \
and self.options.max_woodcutting_level >= 12
add_indirect_conditions_for_woodcutting_levels(entrance, 12)
if outbound_region_name == RegionNames.Edgeville:
entrance.access_rule = lambda state: woodcutting_rule_d3(state) \
and self.options.max_woodcutting_level >= 27
add_indirect_conditions_for_woodcutting_levels(entrance, 27)
if outbound_region_name == RegionNames.Wilderness:
entrance.access_rule = lambda state: woodcutting_rule_all(state) \
and self.options.max_woodcutting_level >= 42
add_indirect_conditions_for_woodcutting_levels(entrance, 42)
if region_row.name == RegionNames.Barbarian_Village:
if outbound_region_name == RegionNames.Canoe_Tree:
entrance.access_rule = \
Expand All @@ -297,6 +390,7 @@ def generate_special_rules_for(self, entrance, region_row, outbound_region_name)
and woodcutting_rule_d1(state) and self.options.max_woodcutting_level >= 12) or \
(state.can_reach_region(RegionNames.Wilderness)
and woodcutting_rule_d2(state) and self.options.max_woodcutting_level >= 27)
add_indirect_conditions_for_woodcutting_levels(entrance, 12, 27)
self.multiworld.register_indirect_condition(
self.multiworld.get_region(RegionNames.Lumbridge, self.player), entrance)
self.multiworld.register_indirect_condition(
Expand All @@ -309,13 +403,16 @@ def generate_special_rules_for(self, entrance, region_row, outbound_region_name)
if outbound_region_name == RegionNames.Lumbridge:
entrance.access_rule = lambda state: woodcutting_rule_d2(state) \
and self.options.max_woodcutting_level >= 27
add_indirect_conditions_for_woodcutting_levels(entrance, 27)
if outbound_region_name == RegionNames.South_Of_Varrock:
entrance.access_rule = lambda state: woodcutting_rule_d1(state) \
and self.options.max_woodcutting_level >= 12
add_indirect_conditions_for_woodcutting_levels(entrance, 12)
# Edgeville does not need to be checked, because it's already adjacent
if outbound_region_name == RegionNames.Wilderness:
entrance.access_rule = lambda state: woodcutting_rule_d3(state) \
and self.options.max_woodcutting_level >= 42
add_indirect_conditions_for_woodcutting_levels(entrance, 42)
if region_row.name == RegionNames.Edgeville:
if outbound_region_name == RegionNames.Canoe_Tree:
entrance.access_rule = \
Expand All @@ -327,6 +424,7 @@ def generate_special_rules_for(self, entrance, region_row, outbound_region_name)
and woodcutting_rule_d1(state) and self.options.max_woodcutting_level >= 12) or \
(state.can_reach_region(RegionNames.Wilderness)
and woodcutting_rule_d1(state) and self.options.max_woodcutting_level >= 12)
add_indirect_conditions_for_woodcutting_levels(entrance, 12, 27, 42)
self.multiworld.register_indirect_condition(
self.multiworld.get_region(RegionNames.Lumbridge, self.player), entrance)
self.multiworld.register_indirect_condition(
Expand All @@ -339,9 +437,11 @@ def generate_special_rules_for(self, entrance, region_row, outbound_region_name)
if outbound_region_name == RegionNames.Lumbridge:
entrance.access_rule = lambda state: woodcutting_rule_d3(state) \
and self.options.max_woodcutting_level >= 42
add_indirect_conditions_for_woodcutting_levels(entrance, 42)
if outbound_region_name == RegionNames.South_Of_Varrock:
entrance.access_rule = lambda state: woodcutting_rule_d2(state) \
and self.options.max_woodcutting_level >= 27
add_indirect_conditions_for_woodcutting_levels(entrance, 27)
# Barbarian Village does not need to be checked, because it's already adjacent
# Wilderness does not need to be checked, because it's already adjacent
if region_row.name == RegionNames.Wilderness:
Expand All @@ -355,6 +455,7 @@ def generate_special_rules_for(self, entrance, region_row, outbound_region_name)
and woodcutting_rule_d2(state) and self.options.max_woodcutting_level >= 27) or \
(state.can_reach_region(RegionNames.Edgeville)
and woodcutting_rule_d1(state) and self.options.max_woodcutting_level >= 12)
add_indirect_conditions_for_woodcutting_levels(entrance, 12, 27, 42, 57)
self.multiworld.register_indirect_condition(
self.multiworld.get_region(RegionNames.Lumbridge, self.player), entrance)
self.multiworld.register_indirect_condition(
Expand All @@ -367,12 +468,15 @@ def generate_special_rules_for(self, entrance, region_row, outbound_region_name)
if outbound_region_name == RegionNames.Lumbridge:
entrance.access_rule = lambda state: woodcutting_rule_all(state) \
and self.options.max_woodcutting_level >= 57
add_indirect_conditions_for_woodcutting_levels(entrance, 57)
if outbound_region_name == RegionNames.South_Of_Varrock:
entrance.access_rule = lambda state: woodcutting_rule_d3(state) \
and self.options.max_woodcutting_level >= 42
add_indirect_conditions_for_woodcutting_levels(entrance, 42)
if outbound_region_name == RegionNames.Barbarian_Village:
entrance.access_rule = lambda state: woodcutting_rule_d2(state) \
and self.options.max_woodcutting_level >= 27
add_indirect_conditions_for_woodcutting_levels(entrance, 27)
# Edgeville does not need to be checked, because it's already adjacent

def roll_locations(self):
Expand Down

0 comments on commit 51e9b71

Please sign in to comment.