mirror of
https://github.com/ArchipelagoMW/Archipelago.git
synced 2026-03-30 11:03:21 -07:00
Some early Overworld combat logic
This commit is contained in:
@@ -19,8 +19,8 @@ class EncounterData(NamedTuple):
|
||||
|
||||
# general requirements for enemy encounters in the game, for use in determining whether you can access a chest
|
||||
enemy_encounters: Dict[str, EncounterData] = {
|
||||
# pink slimes are basically free
|
||||
"Blue Slimes": EncounterData(0),
|
||||
# pink and blue slimes really only need a stick
|
||||
"Slimes": EncounterData(0),
|
||||
"Rudelings": EncounterData(4),
|
||||
"Shield Rudelings": EncounterData(6),
|
||||
# just gets stunlocked with a stick
|
||||
@@ -68,7 +68,8 @@ def has_combat_logic(encounters: List[str], state: CollectionState, player: int)
|
||||
return False
|
||||
# if you met the item requirements, and you have enough power, then you may proceed
|
||||
level_req: int = max(data.power_required for data in encounter_data)
|
||||
if sum_power(state, player) >= level_req:
|
||||
# the not level_req is to short circuit early for spots with combat level 0
|
||||
if not level_req or sum_power(state, player) >= level_req:
|
||||
return True
|
||||
|
||||
|
||||
|
||||
@@ -522,7 +522,6 @@ class RegionInfo(NamedTuple):
|
||||
dead_end: int = 0 # if a region has only one exit
|
||||
|
||||
|
||||
# todo: make this work with the new options
|
||||
class DeadEnd(IntEnum):
|
||||
free = 0 # not a dead end
|
||||
all_cats = 1 # dead end in every logic category
|
||||
@@ -555,6 +554,8 @@ tunic_er_regions: Dict[str, RegionInfo] = {
|
||||
"Overworld to West Garden Upper": RegionInfo("Overworld Redux"), # usually leads to garden knight
|
||||
"Overworld to West Garden from Furnace": RegionInfo("Overworld Redux"), # isolated stairway with one chest
|
||||
"Overworld Well Ladder": RegionInfo("Overworld Redux"), # just the ladder entrance itself as a region
|
||||
"Overworld Well Entry Area": RegionInfo("Overworld Redux"), # the page, the bridge, etc.
|
||||
"Overworld Tunnel to Beach": RegionInfo("Overworld Redux"), # the tunnel with the chest
|
||||
"Overworld Beach": RegionInfo("Overworld Redux"), # from the two turrets to invisble maze, and lower atoll entry
|
||||
"Overworld Tunnel Turret": RegionInfo("Overworld Redux"), # the tunnel turret by the southwest beach ladder
|
||||
"Overworld to Atoll Upper": RegionInfo("Overworld Redux"), # the little ledge before the ladder
|
||||
@@ -745,6 +746,8 @@ traversal_requirements: Dict[str, Dict[str, List[List[str]]]] = {
|
||||
"Overworld": {
|
||||
"Overworld Beach":
|
||||
[],
|
||||
"Overworld Tunnel to Beach":
|
||||
[],
|
||||
"Overworld to Atoll Upper":
|
||||
[["Hyperdash"]],
|
||||
"Overworld Belltower":
|
||||
@@ -755,7 +758,7 @@ traversal_requirements: Dict[str, Dict[str, List[List[str]]]] = {
|
||||
[],
|
||||
"Overworld Special Shop Entry":
|
||||
[["Hyperdash"], ["LS1"]],
|
||||
"Overworld Well Ladder":
|
||||
"Overworld Well Entry Area":
|
||||
[],
|
||||
"Overworld Ruined Passage Door":
|
||||
[],
|
||||
@@ -828,6 +831,12 @@ traversal_requirements: Dict[str, Dict[str, List[List[str]]]] = {
|
||||
# "Overworld":
|
||||
# [],
|
||||
# },
|
||||
"Overworld Tunnel to Beach": {
|
||||
# "Overworld":
|
||||
# [],
|
||||
"Overworld Beach":
|
||||
[],
|
||||
},
|
||||
"Overworld Beach": {
|
||||
# "Overworld":
|
||||
# [],
|
||||
@@ -854,9 +863,15 @@ traversal_requirements: Dict[str, Dict[str, List[List[str]]]] = {
|
||||
"Overworld Beach":
|
||||
[],
|
||||
},
|
||||
"Overworld Well Ladder": {
|
||||
"Overworld Well Entry Area": {
|
||||
# "Overworld":
|
||||
# [],
|
||||
"Overworld Well Ladder":
|
||||
[],
|
||||
},
|
||||
"Overworld Well Ladder": {
|
||||
"Overworld Well Entry Area":
|
||||
[],
|
||||
},
|
||||
"Overworld at Patrol Cave": {
|
||||
"East Overworld":
|
||||
|
||||
@@ -52,10 +52,18 @@ def set_er_region_rules(world: "TunicWorld", regions: Dict[str, Region], portal_
|
||||
connecting_region=regions["Overworld Beach"],
|
||||
rule=lambda state: has_ladder("Ladders in Overworld Town", state, world)
|
||||
or state.has_any({laurels, grapple}, player))
|
||||
# regions["Overworld Beach"].connect(
|
||||
# connecting_region=regions["Overworld"],
|
||||
# rule=lambda state: has_ladder("Ladders in Overworld Town", state, world)
|
||||
# or state.has_any({laurels, grapple}, player))
|
||||
|
||||
# region for combat logic, no need to connect it to beach since it would be the same as the ow -> beach cxn
|
||||
ow_tunnel_beach = regions["Overworld"].connect(
|
||||
connecting_region=regions["Overworld Tunnel to Beach"])
|
||||
|
||||
regions["Overworld Beach"].connect(
|
||||
connecting_region=regions["Overworld"],
|
||||
rule=lambda state: has_ladder("Ladders in Overworld Town", state, world)
|
||||
or state.has_any({laurels, grapple}, player))
|
||||
connecting_region=regions["Overworld Tunnel to Beach"],
|
||||
rule=lambda state: state.has(laurels, player) or has_ladder("Ladders in Overworld Town", state, world))
|
||||
|
||||
regions["Overworld Beach"].connect(
|
||||
connecting_region=regions["Overworld West Garden Laurels Entry"],
|
||||
@@ -268,11 +276,17 @@ def set_er_region_rules(world: "TunicWorld", regions: Dict[str, Region], portal_
|
||||
connecting_region=regions["East Overworld"],
|
||||
rule=lambda state: state.has(laurels, player))
|
||||
|
||||
regions["Overworld"].connect(
|
||||
# region made for combat logic
|
||||
ow_to_well_entry = regions["Overworld"].connect(
|
||||
connecting_region=regions["Overworld Well Entry Area"])
|
||||
regions["Overworld Well Entry Area"].connect(
|
||||
connecting_region=regions["Overworld"])
|
||||
|
||||
regions["Overworld Well Entry Area"].connect(
|
||||
connecting_region=regions["Overworld Well Ladder"],
|
||||
rule=lambda state: has_ladder("Ladders in Well", state, world))
|
||||
regions["Overworld Well Ladder"].connect(
|
||||
connecting_region=regions["Overworld"],
|
||||
connecting_region=regions["Overworld Well Entry Area"],
|
||||
rule=lambda state: has_ladder("Ladders in Well", state, world))
|
||||
|
||||
# nmg: can ice grapple through the door
|
||||
@@ -503,7 +517,7 @@ def set_er_region_rules(world: "TunicWorld", regions: Dict[str, Region], portal_
|
||||
regions["West Garden after Boss"].connect(
|
||||
connecting_region=regions["West Garden"],
|
||||
rule=lambda state: state.has(laurels, player))
|
||||
regions["West Garden"].connect(
|
||||
wg_to_after_gk = regions["West Garden"].connect(
|
||||
connecting_region=regions["West Garden after Boss"],
|
||||
rule=lambda state: state.has(laurels, player) or has_sword(state, player))
|
||||
|
||||
@@ -1003,7 +1017,7 @@ def set_er_region_rules(world: "TunicWorld", regions: Dict[str, Region], portal_
|
||||
connecting_region=regions["Far Shore"])
|
||||
|
||||
# Misc
|
||||
regions["Spirit Arena"].connect(
|
||||
heir_fight = regions["Spirit Arena"].connect(
|
||||
connecting_region=regions["Spirit Arena Victory"],
|
||||
rule=lambda state: (state.has(gold_hexagon, player, world.options.hexagon_goal.value) if
|
||||
world.options.hexagon_quest else
|
||||
@@ -1142,6 +1156,23 @@ def set_er_region_rules(world: "TunicWorld", regions: Dict[str, Region], portal_
|
||||
for region in ladder_regions.values():
|
||||
world.multiworld.regions.append(region)
|
||||
|
||||
# for combat logic, easiest to replace or add to existing rules
|
||||
if world.options.combat_logic >= CombatLogic.option_bosses_only:
|
||||
set_rule(wg_to_after_gk,
|
||||
lambda state: state.has(laurels, player)
|
||||
or has_combat_logic(["Garden Knight"], state, player))
|
||||
if not world.options.hexagon_quest:
|
||||
add_rule(heir_fight,
|
||||
lambda state: has_combat_logic(["The Heir"], state, player))
|
||||
|
||||
if world.options.combat_logic == CombatLogic.option_on:
|
||||
# need to fight through the rudelings and turret, or just laurels from near the windmill
|
||||
set_rule(ow_to_well_entry,
|
||||
lambda state: state.has(laurels, player)
|
||||
or has_combat_logic(["Shield Rudelings", "Autobolts"], state, player))
|
||||
set_rule(ow_tunnel_beach,
|
||||
lambda state: has_combat_logic(["Shield Rudelings"], state, player))
|
||||
|
||||
|
||||
def set_er_location_rules(world: "TunicWorld") -> None:
|
||||
player = world.player
|
||||
@@ -1364,9 +1395,7 @@ def set_er_location_rules(world: "TunicWorld") -> None:
|
||||
lambda state: has_sword(state, player))
|
||||
|
||||
if world.options.combat_logic >= CombatLogic.option_bosses_only:
|
||||
set_rule(multiworld.get_entrance("West Garden -> West Garden after Boss", player),
|
||||
lambda state: state.has(laurels, player)
|
||||
or has_combat_logic(["Garden Knight"], state, player))
|
||||
# garden knight is in the regions part above
|
||||
set_rule(multiworld.get_location("Fortress Arena - Siege Engine/Vault Key Pickup", player),
|
||||
lambda state: has_combat_logic(["Siege Engine"], state, player))
|
||||
set_rule(multiworld.get_location("Librarian - Hexagon Green", player),
|
||||
@@ -1375,6 +1404,19 @@ def set_er_location_rules(world: "TunicWorld") -> None:
|
||||
lambda state: has_combat_logic(["Boss Scavenger"], state, player))
|
||||
set_rule(multiworld.get_location("Cathedral Gauntlet - Gauntlet Reward", player),
|
||||
lambda state: has_combat_logic(["Gauntlet"], state, player))
|
||||
if not world.options.hexagon_quest:
|
||||
add_rule(multiworld.get_entrance("Spirit Arena -> Spirit Arena Victory", player),
|
||||
lambda state: has_combat_logic(["The Heir"], state, player))
|
||||
|
||||
if world.options.combat_logic == CombatLogic.option_on:
|
||||
set_rule(multiworld.get_location("Overworld - [East] Between Ladders Near Ruined Passage", player),
|
||||
lambda state: has_combat_logic(["Slimes"], state, player))
|
||||
set_rule(multiworld.get_location("Overworld - [East] Chest Near Pots", player),
|
||||
lambda state: has_combat_logic(["Slimes"], state, player))
|
||||
add_rule(multiworld.get_location("Overworld - [Northeast] Flowers Holy Cross", player),
|
||||
lambda state: has_combat_logic(["Slimes"], state, player))
|
||||
set_rule(multiworld.get_location("Overworld - [Northwest] Chest Near Quarry Gate", player),
|
||||
lambda state: has_combat_logic(["Rudelings"], state, player))
|
||||
set_rule(multiworld.get_location("Overworld - [Northeast] Chest Above Patrol Cave", player),
|
||||
lambda state: has_combat_logic(["Shield Rudelings"], state, player))
|
||||
set_rule(multiworld.get_location("Overworld - [Southwest] West Beach Guarded By Turret", player),
|
||||
lambda state: has_combat_logic(["Autobolts"], state, player))
|
||||
add_rule(multiworld.get_location("Overworld - [Southwest] West Beach Guarded By Turret 2", player),
|
||||
lambda state: has_combat_logic(["Autobolts"], state, player))
|
||||
|
||||
@@ -131,7 +131,7 @@ location_table: Dict[str, TunicLocationData] = {
|
||||
"Overworld - [Southwest] West Beach Guarded By Turret": TunicLocationData("Overworld", "Overworld Beach"),
|
||||
"Overworld - [Southwest] Chest Guarded By Turret": TunicLocationData("Overworld", "Overworld"),
|
||||
"Overworld - [Northwest] Shadowy Corner Chest": TunicLocationData("Overworld", "Overworld"),
|
||||
"Overworld - [Southwest] Obscured In Tunnel To Beach": TunicLocationData("Overworld", "Overworld"),
|
||||
"Overworld - [Southwest] Obscured In Tunnel To Beach": TunicLocationData("Overworld", "Overworld Tunnel to Beach"),
|
||||
"Overworld - [Southwest] Grapple Chest Over Walkway": TunicLocationData("Overworld", "Overworld"),
|
||||
"Overworld - [Northwest] Chest Beneath Quarry Gate": TunicLocationData("Overworld", "Overworld after Envoy"),
|
||||
"Overworld - [Southeast] Chest Near Swamp": TunicLocationData("Overworld", "Overworld Swamp Lower Entry"),
|
||||
@@ -158,7 +158,7 @@ location_table: Dict[str, TunicLocationData] = {
|
||||
"Overworld - [Northwest] Page on Pillar by Dark Tomb": TunicLocationData("Overworld", "Overworld"),
|
||||
"Overworld - [Northwest] Fire Wand Pickup": TunicLocationData("Overworld", "Upper Overworld"),
|
||||
"Overworld - [West] Page On Teleporter": TunicLocationData("Overworld", "Overworld"),
|
||||
"Overworld - [Northwest] Page By Well": TunicLocationData("Overworld", "Overworld"),
|
||||
"Overworld - [Northwest] Page By Well": TunicLocationData("Overworld", "Overworld Well Entry Area"),
|
||||
"Patrol Cave - Normal Chest": TunicLocationData("Overworld", "Patrol Cave"),
|
||||
"Ruined Shop - Chest 1": TunicLocationData("Overworld", "Ruined Shop"),
|
||||
"Ruined Shop - Chest 2": TunicLocationData("Overworld", "Ruined Shop"),
|
||||
|
||||
Reference in New Issue
Block a user