TUNIC: Give the fox a gun (in logic) (very small PR) (#3790)

* Add bomb wall logic

* Remove option call from can_shop

* Gun for the envoy blocking Quarry

* has_sword -> can_shop on cube cave entrance region
This commit is contained in:
Scipio Wright 2024-08-16 14:53:54 -04:00 committed by GitHub
parent 4af6927e23
commit 474a3181c6
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 43 additions and 7 deletions

View File

@ -75,7 +75,7 @@ portal_mapping: List[Portal] = [
destination="Town Basement", tag="_beach"),
Portal(name="Changing Room Entrance", region="Overworld",
destination="Changing Room", tag="_"),
Portal(name="Cube Cave Entrance", region="Overworld",
Portal(name="Cube Cave Entrance", region="Cube Cave Entrance Region",
destination="CubeRoom", tag="_"),
Portal(name="Stairs from Overworld to Mountain", region="Upper Overworld",
destination="Mountain", tag="_"),
@ -562,6 +562,7 @@ tunic_er_regions: Dict[str, RegionInfo] = {
"Overworld Temple Door": RegionInfo("Overworld Redux"), # the small space betweeen the door and the portal
"Overworld Town Portal": RegionInfo("Overworld Redux"), # being able to go to or come from the portal
"Overworld Spawn Portal": RegionInfo("Overworld Redux"), # being able to go to or come from the portal
"Cube Cave Entrance Region": RegionInfo("Overworld Redux"), # other side of the bomb wall
"Stick House": RegionInfo("Sword Cave", dead_end=DeadEnd.all_cats),
"Windmill": RegionInfo("Windmill"),
"Old House Back": RegionInfo("Overworld Interiors"), # part with the hc door
@ -775,6 +776,8 @@ traversal_requirements: Dict[str, Dict[str, List[List[str]]]] = {
[["UR"]],
"Overworld Old House Door":
[],
"Cube Cave Entrance Region":
[],
},
"East Overworld": {
"Above Ruined Passage":
@ -920,6 +923,10 @@ traversal_requirements: Dict[str, Dict[str, List[List[str]]]] = {
"Overworld":
[],
},
"Cube Cave Entrance Region": {
"Overworld":
[],
},
"Old House Front": {
"Old House Back":
[],

View File

@ -1,6 +1,7 @@
from typing import Dict, Set, List, Tuple, TYPE_CHECKING
from worlds.generic.Rules import set_rule, forbid_item
from .rules import has_ability, has_sword, has_stick, has_ice_grapple_logic, has_lantern, has_mask, can_ladder_storage
from .rules import (has_ability, has_sword, has_stick, has_ice_grapple_logic, has_lantern, has_mask, can_ladder_storage,
bomb_walls)
from .er_data import Portal
from BaseClasses import Region, CollectionState
@ -11,6 +12,7 @@ laurels = "Hero's Laurels"
grapple = "Magic Orb"
ice_dagger = "Magic Dagger"
fire_wand = "Magic Wand"
gun = "Gun"
lantern = "Lantern"
fairies = "Fairy"
coins = "Golden Coin"
@ -31,6 +33,10 @@ def has_ladder(ladder: str, state: CollectionState, world: "TunicWorld") -> bool
return not world.options.shuffle_ladders or state.has(ladder, world.player)
def can_shop(state: CollectionState, world: "TunicWorld") -> bool:
return has_sword(state, world.player) and state.can_reach_region("Shop", world.player)
def set_er_region_rules(world: "TunicWorld", regions: Dict[str, Region], portal_pairs: Dict[Portal, Portal]) -> None:
player = world.player
options = world.options
@ -217,12 +223,12 @@ def set_er_region_rules(world: "TunicWorld", regions: Dict[str, Region], portal_
regions["Overworld"].connect(
connecting_region=regions["Overworld after Envoy"],
rule=lambda state: state.has_any({laurels, grapple}, player)
rule=lambda state: state.has_any({laurels, grapple, gun}, player)
or state.has("Sword Upgrade", player, 4)
or options.logic_rules)
regions["Overworld after Envoy"].connect(
connecting_region=regions["Overworld"],
rule=lambda state: state.has_any({laurels, grapple}, player)
rule=lambda state: state.has_any({laurels, grapple, gun}, player)
or state.has("Sword Upgrade", player, 4)
or options.logic_rules)
@ -329,6 +335,12 @@ def set_er_region_rules(world: "TunicWorld", regions: Dict[str, Region], portal_
connecting_region=regions["Overworld"],
rule=lambda state: state.has_any({grapple, laurels}, player))
regions["Overworld"].connect(
connecting_region=regions["Cube Cave Entrance Region"],
rule=lambda state: state.has(gun, player) or can_shop(state, world))
regions["Cube Cave Entrance Region"].connect(
connecting_region=regions["Overworld"])
# Overworld side areas
regions["Old House Front"].connect(
connecting_region=regions["Old House Back"])
@ -1527,6 +1539,10 @@ def set_er_location_rules(world: "TunicWorld") -> None:
set_rule(world.get_location("Library Fuse"),
lambda state: has_ability(prayer, state, world))
# 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))
# Shop
set_rule(world.get_location("Shop - Potion 1"),
lambda state: has_sword(state, player))

View File

@ -43,7 +43,7 @@ item_table: Dict[str, TunicItemData] = {
"Magic Orb": TunicItemData(ItemClassification.progression, 1, 27),
"Hero's Laurels": TunicItemData(ItemClassification.progression, 1, 28),
"Lantern": TunicItemData(ItemClassification.progression, 1, 29),
"Gun": TunicItemData(ItemClassification.useful, 1, 30, "Weapons"),
"Gun": TunicItemData(ItemClassification.progression, 1, 30, "Weapons"),
"Shield": TunicItemData(ItemClassification.useful, 1, 31),
"Dath Stone": TunicItemData(ItemClassification.useful, 1, 32),
"Hourglass": TunicItemData(ItemClassification.useful, 1, 33),

View File

@ -1,7 +1,7 @@
from random import Random
from typing import Dict, TYPE_CHECKING
from worlds.generic.Rules import set_rule, forbid_item
from worlds.generic.Rules import set_rule, forbid_item, add_rule
from BaseClasses import CollectionState
from .options import TunicOptions
if TYPE_CHECKING:
@ -11,6 +11,7 @@ laurels = "Hero's Laurels"
grapple = "Magic Orb"
ice_dagger = "Magic Dagger"
fire_wand = "Magic Wand"
gun = "Gun"
lantern = "Lantern"
fairies = "Fairy"
coins = "Golden Coin"
@ -26,6 +27,11 @@ green_hexagon = "Green Questagon"
blue_hexagon = "Blue Questagon"
gold_hexagon = "Gold Questagon"
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"]
def randomize_ability_unlocks(random: Random, options: TunicOptions) -> Dict[str, int]:
ability_requirement = [1, 1, 1]
@ -110,7 +116,7 @@ def set_region_rules(world: "TunicWorld") -> None:
lambda state: state.has_any({grapple, laurels}, player) and has_ability(prayer, state, world)
world.get_entrance("Overworld -> Quarry").access_rule = \
lambda state: (has_sword(state, player) or state.has(fire_wand, player)) \
and (state.has_any({grapple, laurels}, player) or can_ladder_storage(state, world))
and (state.has_any({grapple, laurels, gun}, player) or can_ladder_storage(state, world))
world.get_entrance("Quarry Back -> Quarry").access_rule = \
lambda state: has_sword(state, player) or state.has(fire_wand, player)
world.get_entrance("Quarry -> Lower Quarry").access_rule = \
@ -326,6 +332,13 @@ def set_location_rules(world: "TunicWorld") -> None:
set_rule(world.get_location("Hero's Grave - Feathers Relic"),
lambda state: state.has(laurels, player) and has_ability(prayer, state, world))
# 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))
add_rule(world.get_location("Cube Cave - Holy Cross Chest"),
lambda state: state.has(gun, player) or has_sword(state, player))
# Shop
set_rule(world.get_location("Shop - Potion 1"),
lambda state: has_sword(state, player))