mirror of
https://github.com/ArchipelagoMW/Archipelago.git
synced 2026-03-29 07:43:22 -07:00
# Conflicts:
# worlds/tunic/__init__.py # worlds/tunic/er_data.py # worlds/tunic/er_rules.py # worlds/tunic/er_scripts.py # worlds/tunic/rules.py # worlds/tunic/test/test_access.py
This commit is contained in:
@@ -164,7 +164,7 @@ def check_combat_reqs(area_name: str, state: CollectionState, player: int, alt_d
|
||||
data.hp_level, data.sp_level, data.mp_level + extra_mp_needed, data.potion_count)
|
||||
if not has_required_stats(modified_stats, state, player):
|
||||
# we may need to check if you would have the required stats if you were missing a weapon
|
||||
# if someone has a better way of doing this, please tell me lmao
|
||||
# it's kinda janky, but these only get hit in less than once per 100 generations, so whatever
|
||||
if sword_bool and "Sword" in data.equipment and "Magic" in data.equipment:
|
||||
# we need to check if you would have the required stats if you didn't have melee
|
||||
equip_list = [item for item in data.equipment if item != "Sword"]
|
||||
|
||||
@@ -83,8 +83,6 @@ Notes:
|
||||
- The `direction` field is not supported. Connections are always coupled.
|
||||
- For a list of entrance names, check `er_data.py` in the TUNIC world folder or generate a game with the Entrance Randomizer option enabled and check the spoiler log.
|
||||
- There is no limit to the number of Shops you can plando.
|
||||
- If you have more than one shop in a scene, you may be wrong warped when exiting a shop.
|
||||
- If you have a shop in every scene, and you have an odd number of shops, it will error out.
|
||||
|
||||
See the [Archipelago Plando Guide](../../../tutorial/Archipelago/plando/en) for more information on Plando and Connection Plando.
|
||||
|
||||
|
||||
@@ -833,6 +833,9 @@ traversal_requirements: Dict[str, Dict[str, List[List[str]]]] = {
|
||||
[],
|
||||
"Cube Cave Entrance Region":
|
||||
[],
|
||||
# drop a rudeling, icebolt or ice bomb
|
||||
"Overworld to West Garden from Furnace":
|
||||
[["IG3"]],
|
||||
},
|
||||
"East Overworld": {
|
||||
"Above Ruined Passage":
|
||||
@@ -1080,7 +1083,7 @@ traversal_requirements: Dict[str, Dict[str, List[List[str]]]] = {
|
||||
|
||||
"Forest Grave Path Main": {
|
||||
"Forest Grave Path Upper":
|
||||
[["Hyperdash"], ["LS2"]],
|
||||
[["Hyperdash"], ["LS2"], ["IG3"]],
|
||||
"Forest Grave Path by Grave":
|
||||
[],
|
||||
},
|
||||
@@ -1090,7 +1093,7 @@ traversal_requirements: Dict[str, Dict[str, List[List[str]]]] = {
|
||||
},
|
||||
"Forest Grave Path by Grave": {
|
||||
"Forest Hero's Grave":
|
||||
[],
|
||||
[],
|
||||
"Forest Grave Path Main":
|
||||
[["IG1"]],
|
||||
},
|
||||
@@ -1373,7 +1376,7 @@ traversal_requirements: Dict[str, Dict[str, List[List[str]]]] = {
|
||||
|
||||
"Fortress Exterior from East Forest": {
|
||||
"Fortress Exterior from Overworld":
|
||||
[],
|
||||
[],
|
||||
"Fortress Courtyard Upper":
|
||||
[["LS2"]],
|
||||
"Fortress Courtyard":
|
||||
@@ -1381,9 +1384,9 @@ traversal_requirements: Dict[str, Dict[str, List[List[str]]]] = {
|
||||
},
|
||||
"Fortress Exterior from Overworld": {
|
||||
"Fortress Exterior from East Forest":
|
||||
[["Hyperdash"]],
|
||||
[["Hyperdash"]],
|
||||
"Fortress Exterior near cave":
|
||||
[],
|
||||
[],
|
||||
"Fortress Courtyard":
|
||||
[["Hyperdash"], ["IG1"], ["LS1"]],
|
||||
},
|
||||
@@ -1642,6 +1645,9 @@ traversal_requirements: Dict[str, Dict[str, List[List[str]]]] = {
|
||||
"Swamp Front": {
|
||||
"Swamp Mid":
|
||||
[],
|
||||
# get one pillar from the gate, then dash onto the gate, very tricky
|
||||
"Back of Swamp Laurels Area":
|
||||
[["Hyperdash", "Zip"]],
|
||||
},
|
||||
"Swamp Mid": {
|
||||
"Swamp Front":
|
||||
@@ -1672,12 +1678,21 @@ traversal_requirements: Dict[str, Dict[str, List[List[str]]]] = {
|
||||
[["Hyperdash"], ["LS2"]],
|
||||
"Swamp Hero's Grave Region":
|
||||
[],
|
||||
"Swamp Mid":
|
||||
[["LS2"]],
|
||||
"Swamp Front":
|
||||
[["LS1"]],
|
||||
"Swamp to Cathedral Main Entrance Region":
|
||||
[["LS3"]],
|
||||
"Swamp to Cathedral Treasure Room":
|
||||
[["LS3"]]
|
||||
},
|
||||
"Back of Swamp Laurels Area": {
|
||||
"Back of Swamp":
|
||||
[["Hyperdash"]],
|
||||
# get one pillar from the gate, then dash onto the gate, very tricky
|
||||
"Swamp Mid":
|
||||
[["IG1", "Hyperdash"]],
|
||||
[["IG1", "Hyperdash"], ["Hyperdash", "Zip"]],
|
||||
},
|
||||
"Swamp Hero's Grave Region": {
|
||||
"Back of Swamp":
|
||||
|
||||
@@ -151,10 +151,13 @@ def set_er_region_rules(world: "TunicWorld", regions: Dict[str, Region], portal_
|
||||
connecting_region=regions["Overworld"],
|
||||
rule=lambda state: has_ladder("Ladders near Weathervane", state, world))
|
||||
|
||||
# for the hard ice grapple, get to the chest after the bomb wall, grab a slime, and grapple push down
|
||||
# you can ice grapple through the bomb wall, so no need for shop logic checking
|
||||
regions["Overworld"].connect(
|
||||
connecting_region=regions["Above Ruined Passage"],
|
||||
rule=lambda state: has_ladder("Ladders near Weathervane", state, world)
|
||||
or state.has(laurels, player))
|
||||
or state.has(laurels, player)
|
||||
or has_ice_grapple_logic(False, IceGrappling.option_hard, state, world))
|
||||
regions["Above Ruined Passage"].connect(
|
||||
connecting_region=regions["Overworld"],
|
||||
rule=lambda state: has_ladder("Ladders near Weathervane", state, world)
|
||||
@@ -238,9 +241,11 @@ def set_er_region_rules(world: "TunicWorld", regions: Dict[str, Region], portal_
|
||||
connecting_region=regions["Upper Overworld"],
|
||||
rule=lambda state: state.has_any({grapple, laurels}, player))
|
||||
|
||||
# ice grapple push guard captain down the ledge
|
||||
regions["Upper Overworld"].connect(
|
||||
connecting_region=regions["Overworld after Temple Rafters"],
|
||||
rule=lambda state: has_ladder("Ladder near Temple Rafters", state, world))
|
||||
rule=lambda state: has_ladder("Ladder near Temple Rafters", state, world)
|
||||
or has_ice_grapple_logic(True, IceGrappling.option_medium, state, world))
|
||||
regions["Overworld after Temple Rafters"].connect(
|
||||
connecting_region=regions["Upper Overworld"],
|
||||
rule=lambda state: has_ladder("Ladder near Temple Rafters", state, world)
|
||||
@@ -327,7 +332,6 @@ def set_er_region_rules(world: "TunicWorld", regions: Dict[str, Region], portal_
|
||||
connecting_region=regions["Overworld"],
|
||||
rule=lambda state: has_ability(holy_cross, state, world))
|
||||
|
||||
# not including ice grapple through this because we're not including it on the other door
|
||||
regions["Overworld"].connect(
|
||||
connecting_region=regions["Overworld Fountain Cross Door"],
|
||||
rule=lambda state: has_ability(holy_cross, state, world)
|
||||
@@ -381,6 +385,11 @@ def set_er_region_rules(world: "TunicWorld", regions: Dict[str, Region], portal_
|
||||
regions["Cube Cave Entrance Region"].connect(
|
||||
connecting_region=regions["Overworld"])
|
||||
|
||||
# drop a rudeling down, icebolt or ice bomb
|
||||
regions["Overworld"].connect(
|
||||
connecting_region=regions["Overworld to West Garden from Furnace"],
|
||||
rule=lambda state: has_ice_grapple_logic(True, IceGrappling.option_hard, state, world))
|
||||
|
||||
# Overworld side areas
|
||||
regions["Old House Front"].connect(
|
||||
connecting_region=regions["Old House Back"])
|
||||
@@ -428,7 +437,7 @@ def set_er_region_rules(world: "TunicWorld", regions: Dict[str, Region], portal_
|
||||
connecting_region=regions["Forest Belltower Lower"],
|
||||
rule=lambda state: has_ladder("Ladder to East Forest", state, world))
|
||||
|
||||
# nmg: ice grapple up to dance fox spot, and vice versa
|
||||
# ice grapple up to dance fox spot, and vice versa
|
||||
regions["East Forest"].connect(
|
||||
connecting_region=regions["East Forest Dance Fox Spot"],
|
||||
rule=lambda state: state.has(laurels, player)
|
||||
@@ -465,18 +474,20 @@ def set_er_region_rules(world: "TunicWorld", regions: Dict[str, Region], portal_
|
||||
connecting_region=regions["Guard House 2 Upper"],
|
||||
rule=lambda state: has_ladder("Ladders to Lower Forest", state, world))
|
||||
|
||||
# nmg: ice grapple from upper grave path exit to the rest of it
|
||||
# ice grapple from upper grave path exit to the rest of it
|
||||
regions["Forest Grave Path Upper"].connect(
|
||||
connecting_region=regions["Forest Grave Path Main"],
|
||||
rule=lambda state: state.has(laurels, player)
|
||||
or has_ice_grapple_logic(True, IceGrappling.option_easy, state, world))
|
||||
# for the ice grapple, lure a rudeling up top, then grapple push it across
|
||||
regions["Forest Grave Path Main"].connect(
|
||||
connecting_region=regions["Forest Grave Path Upper"],
|
||||
rule=lambda state: state.has(laurels, player))
|
||||
rule=lambda state: state.has(laurels, player)
|
||||
or has_ice_grapple_logic(False, IceGrappling.option_hard, state, world))
|
||||
|
||||
regions["Forest Grave Path Main"].connect(
|
||||
connecting_region=regions["Forest Grave Path by Grave"])
|
||||
# nmg: ice grapple or laurels through the gate
|
||||
# ice grapple or laurels through the gate
|
||||
regions["Forest Grave Path by Grave"].connect(
|
||||
connecting_region=regions["Forest Grave Path Main"],
|
||||
rule=lambda state: has_ice_grapple_logic(False, IceGrappling.option_easy, state, world)
|
||||
@@ -565,12 +576,18 @@ def set_er_region_rules(world: "TunicWorld", regions: Dict[str, Region], portal_
|
||||
connecting_region=regions["West Garden Laurels Exit Region"],
|
||||
rule=lambda state: state.has(laurels, player))
|
||||
|
||||
regions["West Garden after Boss"].connect(
|
||||
# laurels past, or ice grapple it off, or ice grapple to it then fight
|
||||
after_gk_to_wg = regions["West Garden after Boss"].connect(
|
||||
connecting_region=regions["West Garden before Boss"],
|
||||
rule=lambda state: state.has(laurels, player))
|
||||
rule=lambda state: state.has(laurels, player)
|
||||
or has_ice_grapple_logic(False, IceGrappling.option_medium, state, world)
|
||||
or (has_ice_grapple_logic(False, IceGrappling.option_easy, state, world)
|
||||
and has_sword(state, player)))
|
||||
# ice grapple push Garden Knight off the side
|
||||
wg_to_after_gk = regions["West Garden before Boss"].connect(
|
||||
connecting_region=regions["West Garden after Boss"],
|
||||
rule=lambda state: state.has(laurels, player) or has_sword(state, player))
|
||||
rule=lambda state: state.has(laurels, player) or has_sword(state, player)
|
||||
or has_ice_grapple_logic(False, IceGrappling.option_medium, state, world))
|
||||
|
||||
regions["West Garden before Terry"].connect(
|
||||
connecting_region=regions["West Garden Hero's Grave Region"],
|
||||
@@ -600,7 +617,7 @@ def set_er_region_rules(world: "TunicWorld", regions: Dict[str, Region], portal_
|
||||
rule=lambda state: has_ice_grapple_logic(True, IceGrappling.option_medium, state, world))
|
||||
|
||||
# Atoll and Frog's Domain
|
||||
# nmg: ice grapple the bird below the portal
|
||||
# ice grapple the bird below the portal
|
||||
regions["Ruined Atoll"].connect(
|
||||
connecting_region=regions["Ruined Atoll Lower Entry Area"],
|
||||
rule=lambda state: state.has(laurels, player)
|
||||
@@ -645,7 +662,8 @@ def set_er_region_rules(world: "TunicWorld", regions: Dict[str, Region], portal_
|
||||
|
||||
regions["Frog Stairs Eye Exit"].connect(
|
||||
connecting_region=regions["Frog Stairs Upper"],
|
||||
rule=lambda state: has_ladder("Ladders to Frog's Domain", state, world))
|
||||
rule=lambda state: has_ladder("Ladders to Frog's Domain", state, world)
|
||||
or has_ice_grapple_logic(True, IceGrappling.option_easy, state, world))
|
||||
regions["Frog Stairs Upper"].connect(
|
||||
connecting_region=regions["Frog Stairs Eye Exit"],
|
||||
rule=lambda state: has_ladder("Ladders to Frog's Domain", state, world))
|
||||
@@ -1038,9 +1056,11 @@ def set_er_region_rules(world: "TunicWorld", regions: Dict[str, Region], portal_
|
||||
connecting_region=regions["Swamp Mid"],
|
||||
rule=lambda state: has_ice_grapple_logic(False, IceGrappling.option_easy, state, world))
|
||||
|
||||
# grapple push the enemy by the door down, then grapple to it. Really jank
|
||||
regions["Swamp Mid"].connect(
|
||||
connecting_region=regions["Swamp Ledge under Cathedral Door"],
|
||||
rule=lambda state: has_ladder("Ladders in Swamp", state, world))
|
||||
rule=lambda state: has_ladder("Ladders in Swamp", state, world)
|
||||
or has_ice_grapple_logic(True, IceGrappling.option_hard, state, world))
|
||||
# ice grapple enemy standing at the door
|
||||
regions["Swamp Ledge under Cathedral Door"].connect(
|
||||
connecting_region=regions["Swamp Mid"],
|
||||
@@ -1060,11 +1080,17 @@ def set_er_region_rules(world: "TunicWorld", regions: Dict[str, Region], portal_
|
||||
connecting_region=regions["Back of Swamp"],
|
||||
rule=lambda state: state.has(laurels, player))
|
||||
|
||||
# nmg: can ice grapple down while you're on the pillars
|
||||
# ice grapple down from the pillar, or do that really annoying laurels zip
|
||||
# the zip goes to front or mid, just doing mid since mid -> front can be done with laurels alone
|
||||
regions["Back of Swamp Laurels Area"].connect(
|
||||
connecting_region=regions["Swamp Mid"],
|
||||
rule=lambda state: state.has(laurels, player)
|
||||
and has_ice_grapple_logic(True, IceGrappling.option_easy, state, world))
|
||||
rule=lambda state: laurels_zip(state, world)
|
||||
or (state.has(laurels, player)
|
||||
and has_ice_grapple_logic(True, IceGrappling.option_easy, state, world)))
|
||||
# get one pillar from the gate, then dash onto the gate, very tricky
|
||||
regions["Swamp Front"].connect(
|
||||
connecting_region=regions["Back of Swamp Laurels Area"],
|
||||
rule=lambda state: laurels_zip(state, world))
|
||||
|
||||
regions["Back of Swamp"].connect(
|
||||
connecting_region=regions["Swamp Hero's Grave Region"],
|
||||
@@ -1238,9 +1264,10 @@ def set_er_region_rules(world: "TunicWorld", regions: Dict[str, Region], portal_
|
||||
connecting_region=regions[dest_region],
|
||||
name=portal_name + " (LS) " + ls_info.origin,
|
||||
rule=lambda state: can_ladder_storage(state, world)
|
||||
and (state.has("Ladders in South Atoll", player)
|
||||
or not options.shuffle_ladders # if ladder shuffle is off, don't gotta worry about ladders
|
||||
and (has_ladder("Ladders in South Atoll", state, world)
|
||||
or state.has(key, player, 2) # can do it from the rope
|
||||
# ice grapple push a crab into the door
|
||||
or has_ice_grapple_logic(False, IceGrappling.option_medium, state, world)
|
||||
or options.ladder_storage >= LadderStorage.option_medium)) # use the little ladder
|
||||
# holy cross mid-ls to get in here
|
||||
elif ls_info.destination == "Swamp Redux 2, Cathedral Redux_secret":
|
||||
@@ -1249,7 +1276,7 @@ def set_er_region_rules(world: "TunicWorld", regions: Dict[str, Region], portal_
|
||||
connecting_region=regions[dest_region],
|
||||
name=portal_name + " (LS) " + ls_info.origin,
|
||||
rule=lambda state: can_ladder_storage(state, world) and has_ability(holy_cross, state, world)
|
||||
and (state.has("Ladders in Swamp", player) or not options.shuffle_ladders))
|
||||
and has_ladder("Ladders in Swamp", state, world))
|
||||
else:
|
||||
regions[ls_info.origin].connect(
|
||||
connecting_region=regions[dest_region],
|
||||
@@ -1275,7 +1302,15 @@ def set_er_region_rules(world: "TunicWorld", regions: Dict[str, Region], portal_
|
||||
if world.options.combat_logic >= CombatLogic.option_bosses_only:
|
||||
set_rule(wg_to_after_gk,
|
||||
lambda state: state.has(laurels, player)
|
||||
or has_ice_grapple_logic(False, IceGrappling.option_medium, state, world)
|
||||
or has_combat_reqs("Garden Knight", state, player))
|
||||
# laurels past, or ice grapple it off, or ice grapple to it and fight
|
||||
set_rule(after_gk_to_wg,
|
||||
lambda state: state.has(laurels, player)
|
||||
or has_ice_grapple_logic(False, IceGrappling.option_medium, state, world)
|
||||
or (has_ice_grapple_logic(False, IceGrappling.option_easy, state, world)
|
||||
and has_combat_reqs("Garden Knight", state, player)))
|
||||
|
||||
if not world.options.hexagon_quest:
|
||||
add_rule(heir_fight,
|
||||
lambda state: has_combat_reqs("The Heir", state, player))
|
||||
@@ -1565,10 +1600,13 @@ def set_er_location_rules(world: "TunicWorld") -> None:
|
||||
# Ruined Atoll
|
||||
set_rule(world.get_location("Ruined Atoll - [West] Near Kevin Block"),
|
||||
lambda state: state.has(laurels, player))
|
||||
# ice grapple push a crab through the door
|
||||
set_rule(world.get_location("Ruined Atoll - [East] Locked Room Lower Chest"),
|
||||
lambda state: state.has(laurels, player) or state.has(key, player, 2))
|
||||
lambda state: state.has(laurels, player) or state.has(key, player, 2)
|
||||
or has_ice_grapple_logic(False, IceGrappling.option_medium, state, world))
|
||||
set_rule(world.get_location("Ruined Atoll - [East] Locked Room Upper Chest"),
|
||||
lambda state: state.has(laurels, player) or state.has(key, player, 2))
|
||||
lambda state: state.has(laurels, player) or state.has(key, player, 2)
|
||||
or has_ice_grapple_logic(False, IceGrappling.option_medium, state, world))
|
||||
|
||||
# Frog's Domain
|
||||
set_rule(world.get_location("Frog's Domain - Side Room Grapple Secret"),
|
||||
@@ -1605,8 +1643,11 @@ def set_er_location_rules(world: "TunicWorld") -> None:
|
||||
set_rule(world.get_location("Librarian - Hexagon Green"),
|
||||
lambda state: has_sword(state, player)
|
||||
and has_ladder("Ladders in Library", state, world))
|
||||
# can ice grapple boss scav off the side
|
||||
# the grapple from the other side of the bridge isn't in logic 'cause we don't have a misc tricks option
|
||||
set_rule(world.get_location("Rooted Ziggurat Lower - Hexagon Blue"),
|
||||
lambda state: has_sword(state, player))
|
||||
lambda state: has_sword(state, player)
|
||||
or has_ice_grapple_logic(False, IceGrappling.option_medium, state, world))
|
||||
|
||||
# Swamp
|
||||
set_rule(world.get_location("Cathedral Gauntlet - Gauntlet Reward"),
|
||||
@@ -1666,7 +1707,13 @@ def set_er_location_rules(world: "TunicWorld") -> None:
|
||||
|
||||
# Bombable Walls
|
||||
for location_name in bomb_walls:
|
||||
set_rule(world.get_location(location_name), lambda state: state.has(gun, player) or can_shop(state, world))
|
||||
set_rule(world.get_location(location_name),
|
||||
lambda state: state.has(gun, player)
|
||||
or can_shop(state, world)
|
||||
or has_ice_grapple_logic(False, IceGrappling.option_hard, state, world))
|
||||
# not enough space to ice grapple into here
|
||||
set_rule(world.get_location("Quarry - [East] Bombable Wall"),
|
||||
lambda state: state.has(gun, player) or can_shop(state, world))
|
||||
|
||||
# Shop
|
||||
set_rule(world.get_location("Shop - Potion 1"),
|
||||
@@ -1701,6 +1748,9 @@ def set_er_location_rules(world: "TunicWorld") -> None:
|
||||
rule=lambda state: has_combat_reqs("The Librarian", state, player)
|
||||
and has_ladder("Ladders in Library", state, world))
|
||||
combat_logic_to_loc("Rooted Ziggurat Lower - Hexagon Blue", "Boss Scavenger", set_instead=True)
|
||||
if world.options.ice_grappling >= IceGrappling.option_medium:
|
||||
add_rule(world.get_location("Rooted Ziggurat Lower - Hexagon Blue"),
|
||||
lambda state: has_ice_grapple_logic(False, IceGrappling.option_medium, state, world))
|
||||
combat_logic_to_loc("Cathedral Gauntlet - Gauntlet Reward", "Gauntlet", set_instead=True)
|
||||
|
||||
if world.options.combat_logic == CombatLogic.option_on:
|
||||
|
||||
@@ -81,6 +81,8 @@ easy_ls: List[LadderInfo] = [
|
||||
LadderInfo("West Garden before Boss", "Archipelagos Redux, Overworld Redux_upper"),
|
||||
# West Garden laurels exit
|
||||
LadderInfo("West Garden after Terry", "Archipelagos Redux, Overworld Redux_lowest"),
|
||||
# Magic dagger house, only relevant with combat logic on
|
||||
LadderInfo("West Garden after Terry", "Archipelagos Redux, archipelagos_house_"),
|
||||
|
||||
# Atoll, use the little ladder you fix at the beginning
|
||||
LadderInfo("Ruined Atoll", "Atoll Redux, Overworld Redux_lower"),
|
||||
@@ -100,6 +102,9 @@ easy_ls: List[LadderInfo] = [
|
||||
# Fortress main entry and grave path lower entry, ls at the ladder by the telescope
|
||||
LadderInfo("Fortress Exterior from Overworld", "Fortress Courtyard, Fortress Main_Big Door"),
|
||||
LadderInfo("Fortress Exterior from Overworld", "Fortress Courtyard, Fortress Reliquary_Lower"),
|
||||
# Use the top of the ladder by the telescope
|
||||
LadderInfo("Fortress Exterior from Overworld", "Fortress Courtyard, Fortress Reliquary_Upper"),
|
||||
LadderInfo("Fortress Exterior from Overworld", "Fortress Courtyard, Fortress East_"),
|
||||
|
||||
# same as above, except from the east side of the area
|
||||
LadderInfo("Fortress Exterior from East Forest", "Fortress Courtyard, Overworld Redux_"),
|
||||
@@ -126,9 +131,7 @@ easy_ls: List[LadderInfo] = [
|
||||
medium_ls: List[LadderInfo] = [
|
||||
# region-destination versions of easy ls spots
|
||||
LadderInfo("East Forest", "East Forest Dance Fox Spot", dest_is_region=True),
|
||||
LadderInfo("Fortress Exterior from Overworld", "Fortress Courtyard", dest_is_region=True),
|
||||
LadderInfo("Fortress Exterior from East Forest", "Fortress Courtyard", dest_is_region=True),
|
||||
LadderInfo("Fortress Exterior near cave", "Fortress Courtyard", "Ladder to Beneath the Vault", dest_is_region=True),
|
||||
# fortress courtyard knockdowns are never logically relevant, the fuse requires upper
|
||||
LadderInfo("Back of Swamp", "Swamp Mid", dest_is_region=True),
|
||||
LadderInfo("Back of Swamp", "Swamp Front", dest_is_region=True),
|
||||
|
||||
@@ -139,8 +142,6 @@ medium_ls: List[LadderInfo] = [
|
||||
LadderInfo("Forest Grave Path Main", "Sword Access, East Forest Redux_upper"),
|
||||
|
||||
# Upper exits from the courtyard. Use the ramp in the courtyard, then the blocks north of the first fuse
|
||||
LadderInfo("Fortress Exterior from Overworld", "Fortress Courtyard, Fortress Reliquary_Upper"),
|
||||
LadderInfo("Fortress Exterior from Overworld", "Fortress Courtyard, Fortress East_"),
|
||||
LadderInfo("Fortress Exterior from Overworld", "Fortress Courtyard Upper", dest_is_region=True),
|
||||
LadderInfo("Fortress Exterior from East Forest", "Fortress Courtyard, Fortress Reliquary_Upper"),
|
||||
LadderInfo("Fortress Exterior from East Forest", "Fortress Courtyard, Fortress East_"),
|
||||
@@ -175,8 +176,10 @@ hard_ls: List[LadderInfo] = [
|
||||
LadderInfo("Beneath the Well Front", "Beneath the Well Back", "Ladders in Well", dest_is_region=True),
|
||||
# go through the hexagon engraving above the vault door
|
||||
LadderInfo("Frog's Domain Front", "frog cave main, Frog Stairs_Exit", "Ladders to Frog's Domain"),
|
||||
# maybe a little egregious -- ice grapple a spider off, then use it to push into the portal room
|
||||
LadderInfo("Rooted Ziggurat Lower Back", "ziggurat2020_3, ziggurat2020_FTRoom_"),
|
||||
# the turret at the end here is not affected by enemy rando
|
||||
LadderInfo("Frog's Domain Front", "Frog's Domain Back", "Ladders to Frog's Domain", dest_is_region=True),
|
||||
# todo: see if we can use that new laurels strat here
|
||||
# LadderInfo("Rooted Ziggurat Lower Back", "ziggurat2020_3, ziggurat2020_FTRoom_"),
|
||||
# go behind the cathedral to reach the door, pretty easily doable
|
||||
LadderInfo("Swamp Mid", "Swamp Redux 2, Cathedral Redux_main", "Ladders in Swamp"),
|
||||
LadderInfo("Back of Swamp", "Swamp Redux 2, Cathedral Redux_main"),
|
||||
|
||||
@@ -235,8 +235,8 @@ class IceGrappling(Choice):
|
||||
Easy includes ice grappling enemies that are in range without luring them. May include clips through terrain.
|
||||
Medium includes using ice grapples to push enemies through doors or off ledges without luring them. Also includes bringing an enemy over to the Temple Door to grapple through it.
|
||||
Hard includes luring or grappling enemies to get to where you want to go.
|
||||
The Medium and Hard options will give the player the Torch to return to the Overworld checkpoint to avoid softlocks.
|
||||
Note: You will still be expected to ice grapple to the slime in East Forest even with this option off.
|
||||
The Medium and Hard options will give the player the Torch to return to the Overworld checkpoint to avoid softlocks. Using the Torch is considered in logic.
|
||||
Note: You will still be expected to ice grapple to the slime in East Forest from below with this option off.
|
||||
"""
|
||||
internal_name = "ice_grappling"
|
||||
display_name = "Ice Grapple Logic"
|
||||
@@ -272,7 +272,7 @@ class LadderStorageWithoutItems(Toggle):
|
||||
If enabled, you will be expected to perform Ladder Storage without progression items.
|
||||
This can be done with the plushie code, a Golden Coin, Prayer, and many other options.
|
||||
|
||||
This option has no effect if you do not have Ladder Storage Logic enabled
|
||||
This option has no effect if you do not have Ladder Storage Logic enabled.
|
||||
"""
|
||||
internal_name = "ladder_storage_without_items"
|
||||
display_name = "Ladder Storage without Items"
|
||||
|
||||
@@ -27,10 +27,10 @@ green_hexagon = "Green Questagon"
|
||||
blue_hexagon = "Blue Questagon"
|
||||
gold_hexagon = "Gold Questagon"
|
||||
|
||||
# "Quarry - [East] Bombable Wall" is excluded from this list since it has slightly different rules
|
||||
bomb_walls = ["East Forest - Bombable Wall", "Eastern Vault Fortress - [East Wing] Bombable Wall",
|
||||
"Overworld - [Central] Bombable Wall", "Overworld - [Southwest] Bombable Wall Near Fountain",
|
||||
"Quarry - [West] Upper Area Bombable Wall", "Quarry - [East] Bombable Wall",
|
||||
"Ruined Atoll - [Northwest] Bombable Wall"]
|
||||
"Quarry - [West] Upper Area Bombable Wall", "Ruined Atoll - [Northwest] Bombable Wall"]
|
||||
|
||||
|
||||
def randomize_ability_unlocks(random: Random, options: TunicOptions) -> Dict[str, int]:
|
||||
@@ -102,9 +102,11 @@ def set_region_rules(world: "TunicWorld") -> None:
|
||||
lambda state: has_melee(state, player) or state.has(fire_wand, player)
|
||||
world.get_entrance("Overworld -> Dark Tomb").access_rule = \
|
||||
lambda state: has_lantern(state, world)
|
||||
# laurels in, ladder storage in through the furnace, or ice grapple down the belltower
|
||||
world.get_entrance("Overworld -> West Garden").access_rule = \
|
||||
lambda state: state.has(laurels, player) \
|
||||
or can_ladder_storage(state, world)
|
||||
lambda state: (state.has(laurels, player)
|
||||
or can_ladder_storage(state, world)
|
||||
or has_ice_grapple_logic(False, IceGrappling.option_hard, state, world))
|
||||
world.get_entrance("Overworld -> Eastern Vault Fortress").access_rule = \
|
||||
lambda state: state.has(laurels, player) \
|
||||
or has_ice_grapple_logic(True, IceGrappling.option_easy, state, world) \
|
||||
@@ -275,10 +277,13 @@ def set_location_rules(world: "TunicWorld") -> None:
|
||||
# Ruined Atoll
|
||||
set_rule(world.get_location("Ruined Atoll - [West] Near Kevin Block"),
|
||||
lambda state: state.has(laurels, player))
|
||||
# ice grapple push a crab through the door
|
||||
set_rule(world.get_location("Ruined Atoll - [East] Locked Room Lower Chest"),
|
||||
lambda state: state.has(laurels, player) or state.has(key, player, 2))
|
||||
lambda state: state.has(laurels, player) or state.has(key, player, 2)
|
||||
or has_ice_grapple_logic(False, IceGrappling.option_medium, state, world))
|
||||
set_rule(world.get_location("Ruined Atoll - [East] Locked Room Upper Chest"),
|
||||
lambda state: state.has(laurels, player) or state.has(key, player, 2))
|
||||
lambda state: state.has(laurels, player) or state.has(key, player, 2)
|
||||
or has_ice_grapple_logic(False, IceGrappling.option_medium, state, world))
|
||||
set_rule(world.get_location("Librarian - Hexagon Green"),
|
||||
lambda state: has_sword(state, player))
|
||||
|
||||
@@ -347,8 +352,16 @@ def set_location_rules(world: "TunicWorld") -> None:
|
||||
# Bombable Walls
|
||||
for location_name in bomb_walls:
|
||||
# has_sword is there because you can buy bombs in the shop
|
||||
set_rule(world.get_location(location_name), lambda state: state.has(gun, player) or has_sword(state, player))
|
||||
set_rule(world.get_location(location_name),
|
||||
lambda state: state.has(gun, player)
|
||||
or has_sword(state, player)
|
||||
or has_ice_grapple_logic(False, IceGrappling.option_hard, state, world))
|
||||
add_rule(world.get_location("Cube Cave - Holy Cross Chest"),
|
||||
lambda state: state.has(gun, player)
|
||||
or has_sword(state, player)
|
||||
or has_ice_grapple_logic(False, IceGrappling.option_hard, state, world))
|
||||
# can't ice grapple to this one, not enough space
|
||||
set_rule(world.get_location("Quarry - [East] Bombable Wall"),
|
||||
lambda state: state.has(gun, player) or has_sword(state, player))
|
||||
|
||||
# Shop
|
||||
|
||||
Reference in New Issue
Block a user