The Messenger: Various small logic fix (#6337)

This commit is contained in:
Jérémie Bolduc
2026-08-05 00:24:35 +02:00
committed by GitHub
parent e759562506
commit 8b3557cd6c
4 changed files with 98 additions and 55 deletions
+10 -7
View File
@@ -37,7 +37,7 @@ CONNECTIONS: dict[str, dict[str, list[str]]] = {
"Autumn Hills - Lakeside Checkpoint",
],
"Dimension Climb Shop": [
"Autumn Hills - Lakeside Checkpoint",
"Autumn Hills - Lakeside Checkpoint", # Only possible in 16 bits
"Autumn Hills - Portal",
"Autumn Hills - Double Swing Checkpoint",
],
@@ -60,7 +60,7 @@ CONNECTIONS: dict[str, dict[str, list[str]]] = {
"Double Swing Checkpoint": [
"Autumn Hills - Dimension Climb Shop",
"Autumn Hills - Spike Ball Swing Checkpoint",
"Autumn Hills - Bottom",
"Autumn Hills - Bottom", # Only possible in 16 bits
],
"Spike Ball Swing Checkpoint": [
"Autumn Hills - Double Swing Checkpoint",
@@ -135,6 +135,7 @@ CONNECTIONS: dict[str, dict[str, list[str]]] = {
],
"Triple Spike Crushers Shop": [
"Catacombs - Bottom Left",
"Catacombs - Top Left",
"Catacombs - Death Trap Checkpoint",
],
"Ruxxtin Shop": [
@@ -153,7 +154,7 @@ CONNECTIONS: dict[str, dict[str, list[str]]] = {
"Catacombs - Bottom",
"Catacombs - Death Trap Checkpoint",
"Catacombs - Crusher Gauntlet Checkpoint",
"Catacombs - Ruxxtin Shop",
"Catacombs - Ruxxtin Shop", # In 16 bits, requires rope dart (to reach the Dirty Pond Seal as well)
],
},
"Bamboo Creek": {
@@ -486,8 +487,7 @@ CONNECTIONS: dict[str, dict[str, list[str]]] = {
"Barm'athaziel Shop": [
"Underworld - Hot Tub Checkpoint",
],
"Key of Chaos Shop": [
],
"Key of Chaos Shop": [],
"Hot Dip Checkpoint": [
"Underworld - Left Shop",
"Underworld - Fireball Wave Shop",
@@ -536,8 +536,7 @@ CONNECTIONS: dict[str, dict[str, list[str]]] = {
"Restock Shop": [
"Riviere Turquoise - Butterfly Matriarch Shop",
],
"Butterfly Matriarch Shop": [
],
"Butterfly Matriarch Shop": [],
"Flower Flight Checkpoint": [
"Riviere Turquoise - Waterfall Shop",
"Riviere Turquoise - Launch of Faith Shop",
@@ -556,6 +555,7 @@ CONNECTIONS: dict[str, dict[str, list[str]]] = {
"Elemental Skylands - Air Generator Shop",
],
"Air Generator Shop": [
"Elemental Skylands - Air Seal Checkpoint",
"Elemental Skylands - Earth Shmup",
],
"Earth Shmup": [
@@ -574,6 +574,7 @@ CONNECTIONS: dict[str, dict[str, list[str]]] = {
"Elemental Skylands - Water Generator Shop",
],
"Water Generator Shop": [
"Elemental Skylands - Water Intro Shop",
"Elemental Skylands - Fire Shmup",
],
"Fire Shmup": [
@@ -639,6 +640,7 @@ CONNECTIONS: dict[str, dict[str, list[str]]] = {
},
}
# fmt: off
RANDOMIZED_CONNECTIONS: dict[str, str] = {
"Ninja Village - Right": "Autumn Hills - Left",
"Autumn Hills - Left": "Ninja Village - Right",
@@ -678,6 +680,7 @@ RANDOMIZED_CONNECTIONS: dict[str, str] = {
"Dark Cave - Left": "Riviere Turquoise - Right",
"Sunken Shrine - Left": "Howling Grotto - Bottom",
}
# fmt: on
TRANSITIONS: list[str] = [
"Ninja Village - Right",
+3 -3
View File
@@ -96,10 +96,10 @@ SHOP_POINTS: dict[str, list[str]] = {
"Air Generator",
"Earth Intro",
"Earth Generator",
"Fire Intro",
"Fire Generator",
"Water Intro",
"Water Generator",
"Fire Intro",
"Fire Generator",
],
"Sunken Shrine": [
"Above Portal",
@@ -107,7 +107,7 @@ SHOP_POINTS: dict[str, list[str]] = {
"Sun Path",
"Tabi Gauntlet",
"Moon Path",
]
],
}
CHECKPOINTS: dict[str, list[str]] = {
+32 -25
View File
@@ -1,7 +1,8 @@
from typing import TYPE_CHECKING
from BaseClasses import CollectionState, CollectionRule, Region
from BaseClasses import CollectionRule, CollectionState, Region
from worlds.generic.Rules import add_rule, allow_self_locking_items
from .constants import NOTES, PHOBEKINS
from .options import MessengerAccessibility
@@ -30,6 +31,7 @@ class MessengerRules:
self.required_seals = world.required_seals
# dict of connection names and requirements to traverse the exit
# fmt: off
self.connection_rules = {
# from ToTHQ
"Artificer's Portal":
@@ -131,7 +133,7 @@ class MessengerRules:
lambda state: state.has("Magic Firefly", self.player)
and state.multiworld.get_location("Quillshroom Marsh - Queen of Quills", self.player)
.can_reach(state),
"Glacial Peak - Tower Entrance Shop -> Glacial Peak - Top":
"Glacial Peak - Top -> Cloud Ruins - Left":
lambda state: state.has("Ruxxtin's Amulet", self.player),
"Glacial Peak - Projectile Spike Pit Checkpoint -> Glacial Peak - Left":
lambda state: self.has_dart(state) or (self.can_dboost(state) and self.has_wingsuit(state)),
@@ -173,7 +175,7 @@ class MessengerRules:
lambda state: self.has_wingsuit(state) and self.can_dboost(state),
# Underworld
"Underworld - Left -> Underworld - Left Shop":
self.has_tabi,
lambda state: self.has_tabi(state) or self.has_vertical(state),
"Underworld - Left Shop -> Underworld - Left":
self.has_tabi,
"Underworld - Hot Dip Checkpoint -> Underworld - Lava Run Checkpoint":
@@ -208,6 +210,10 @@ class MessengerRules:
self.has_wingsuit,
"Elemental Skylands - Air Intro Shop -> Elemental Skylands - Air Generator Shop":
self.has_wingsuit,
"Elemental Skylands - Earth Intro Shop -> Elemental Skylands - Earth Generator Shop":
self.has_dart,
"Elemental Skylands - Water Generator Shop -> Elemental Skylands - Water Intro Shop":
self.can_destroy_projectiles,
# Sunken Shrine
"Sunken Shrine - Portal -> Sunken Shrine - Sun Path Shop":
self.has_tabi,
@@ -220,6 +226,7 @@ class MessengerRules:
"Sunken Shrine - Tabi Gauntlet Shop -> Sunken Shrine - Sun Path Shop":
lambda state: self.can_dboost(state) or self.has_dart(state),
}
# fmt: on
# dict of connection names and the regions checked in the requirements to traverse the exit
self.indirect_conditions = {
@@ -231,6 +238,7 @@ class MessengerRules:
],
}
# fmt: off
self.location_rules = {
# hq
"Money Wrench": self.can_shop,
@@ -261,7 +269,7 @@ class MessengerRules:
"Howling Grotto Seal - Windy Saws and Balls":
self.has_wingsuit,
"Howling Grotto Seal - Crushing Pits":
lambda state: self.has_wingsuit(state) and self.has_dart(state),
self.has_dart,
"Howling Grotto - Emerald Golem":
self.has_wingsuit,
# searing crags
@@ -280,7 +288,8 @@ class MessengerRules:
"Tower of Time Seal - Time Waster":
self.has_dart,
# corrupted future
"Corrupted Future - Key of Courage": lambda state: state.has("Magic Firefly", self.player),
"Corrupted Future - Key of Courage":
lambda state: state.has("Magic Firefly", self.player),
# cloud ruins
"Time Warp Mega Shard":
lambda state: self.has_vertical(state) or self.can_dboost(state),
@@ -312,21 +321,18 @@ class MessengerRules:
"Riviere Turquoise Seal - Bounces and Balls":
self.can_dboost,
"Riviere Turquoise Seal - Launch of Faith":
lambda state: self.has_vertical(state),
self.has_vertical,
# elemental skylands
"Elemental Skylands - Key of Symbiosis":
self.has_dart,
"Elemental Skylands Seal - Air":
self.has_wingsuit,
"Elemental Skylands Seal - Water":
lambda state: self.has_dart(state) and state.has("Currents Master", self.player),
lambda state: state.has("Currents Master", self.player),
"Elemental Skylands Seal - Fire":
lambda state: self.has_dart(state) and self.can_destroy_projectiles(state) and self.is_aerobatic(state),
lambda state: self.can_destroy_projectiles(state) and self.is_aerobatic(state),
"Earth Mega Shard":
self.has_dart,
"Water Mega Shard":
self.has_dart,
}
# fmt: on
if self.required_seals:
self.connection_rules["Shrink Down"] = self.has_enough_seals
@@ -393,6 +399,7 @@ class MessengerHardRules(MessengerRules):
def __init__(self, world: "MessengerWorld") -> None:
super().__init__(world)
# fmt: off
self.connection_rules.update(
{
# Autumn Hills
@@ -439,6 +446,8 @@ class MessengerHardRules(MessengerRules):
# Elemental Skylands
"Elemental Skylands - Air Intro Shop -> Elemental Skylands - Air Generator Shop":
self.true,
"Elemental Skylands - Earth Intro Shop -> Elemental Skylands - Earth Generator Shop":
self.true,
# Riviere Turquoise
"Riviere Turquoise - Waterfall Shop -> Riviere Turquoise - Flower Flight Checkpoint":
self.true,
@@ -448,29 +457,31 @@ class MessengerHardRules(MessengerRules):
self.can_double_dboost,
}
)
# fmt: on
# fmt: off
self.location_rules.update(
{
"Autumn Hills Seal - Spike Ball Darts":
lambda state: self.has_vertical(state) and self.has_windmill(state) or self.is_aerobatic(state),
lambda state: (self.has_vertical(state) and self.has_windmill(state)) or self.is_aerobatic(state),
"Autumn Hills Seal - Double Swing Saws":
lambda state: self.has_vertical(state) or self.can_destroy_projectiles(state),
"Bamboo Creek - Claustro":
self.has_wingsuit,
"Bamboo Creek Seal - Spike Ball Pits":
self.true,
"Above Entrance Mega Shard": # Just reset to the menu and you can get it with full health
self.true,
"Howling Grotto Seal - Windy Saws and Balls":
self.true,
"Howling Grotto Seal - Crushing Pits":
self.has_vertical,
"Searing Crags Seal - Triple Ball Spinner":
self.true,
"Glacial Peak Seal - Ice Climbers":
lambda state: self.has_vertical(state) or self.can_dboost(state),
"Glacial Peak Seal - Projectile Spike Pit":
lambda state: self.can_dboost(state) or self.can_destroy_projectiles(state),
"Glacial Peak Seal - Glacial Air Swag":
lambda state: self.has_windmill(state) or self.has_vertical(state),
"Glacial Peak Mega Shard":
lambda state: self.has_windmill(state) or self.has_vertical(state),
"Cloud Ruins Seal - Ghost Pit":
self.true,
"Cloud Ruins Seal - Toothbrush Alley":
@@ -483,26 +494,22 @@ class MessengerHardRules(MessengerRules):
self.true,
"Riviere Turquoise Seal - Launch of Faith":
lambda state: self.can_dboost(state) or self.has_vertical(state),
"Elemental Skylands - Key of Symbiosis":
lambda state: self.has_dart(state) or self.can_dboost(state) or self.has_windmill(state),
"Elemental Skylands Seal - Water":
lambda state: self.has_dart(state) or self.can_dboost(state) or self.has_windmill(state),
self.true,
"Elemental Skylands Seal - Fire":
lambda state: (self.has_dart(state) or self.can_dboost(state) or self.has_windmill(state))
and self.can_destroy_projectiles(state),
self.can_destroy_projectiles,
"Earth Mega Shard":
lambda state: self.has_dart(state) or self.can_dboost(state) or self.has_windmill(state),
"Water Mega Shard":
lambda state: self.has_dart(state) or self.can_dboost(state) or self.has_windmill(state),
}
)
# fmt: on
def has_windmill(self, state: CollectionState) -> bool:
return state.has("Windmill Shuriken", self.player)
def can_dboost(self, state: CollectionState) -> bool:
return state.has("Second Wind", self.player) # who really needs meditation
def can_destroy_projectiles(self, state: CollectionState) -> bool:
return super().can_destroy_projectiles(state) or self.has_windmill(state)
+53 -20
View File
@@ -1,7 +1,7 @@
import typing
from . import MessengerTestBase
from ..constants import NOTES, PHOBEKINS
from . import MessengerTestBase
class AccessTest(MessengerTestBase):
@@ -52,25 +52,58 @@ class AccessTest(MessengerTestBase):
def test_wingsuit(self) -> None:
"""locations that hard require the Wingsuit"""
locations = [
"Ninja Village - Candle", "Ninja Village Seal - Tree House", "Autumn Hills - Climbing Claws",
"Autumn Hills - Key of Hope", "Autumn Hills Seal - Trip Saws", "Autumn Hills Seal - Double Swing Saws",
"Autumn Hills Seal - Spike Ball Swing", "Autumn Hills Seal - Spike Ball Darts", "Catacombs - Necro",
"Catacombs - Ruxxtin's Amulet", "Catacombs Seal - Triple Spike Crushers",
"Catacombs Seal - Crusher Gauntlet", "Catacombs Seal - Dirty Pond", "Bamboo Creek - Claustro",
"Cloud Ruins - Acro", "Bamboo Creek Seal - Spike Crushers and Doors", "Bamboo Creek Seal - Spike Ball Pits",
"Bamboo Creek Seal - Spike Crushers and Doors v2", "Howling Grotto Seal - Crushing Pits",
"Howling Grotto Seal - Windy Saws and Balls", "Tower of Time Seal - Lantern Climb",
"Forlorn Temple - Demon King", "Cloud Ruins Seal - Ghost Pit", "Cloud Ruins Seal - Toothbrush Alley",
"Cloud Ruins Seal - Saw Pit", "Cloud Ruins Seal - Money Farm Room", "Tower of Time Seal - Lantern Climb",
"Tower of Time Seal - Arcane Orbs", "Underworld Seal - Sharp and Windy Climb",
"Underworld Seal - Fireball Wave", "Elemental Skylands Seal - Air", "Elemental Skylands Seal - Water",
"Elemental Skylands Seal - Fire", "Elemental Skylands - Key of Symbiosis",
"Forlorn Temple Seal - Rocket Maze", "Forlorn Temple Seal - Rocket Sunset", "Ninja Village - Astral Seed",
"Searing Crags - Astral Tea Leaves", "Autumn Hills Mega Shard", "Hidden Entrance Mega Shard",
"Sunny Day Mega Shard", "Down Under Mega Shard", "Catacombs Mega Shard", "Above Entrance Mega Shard",
"Abandoned Mega Shard", "Time Loop Mega Shard", "Earth Mega Shard", "Water Mega Shard",
"Money Farm Room Mega Shard 1", "Money Farm Room Mega Shard 2",
"Autumn Hills - Leaf Golem", "Catacombs - Ruxxtin", "Howling Grotto - Emerald Golem"
"Ninja Village - Candle",
"Ninja Village Seal - Tree House",
"Autumn Hills - Climbing Claws",
"Autumn Hills - Key of Hope",
"Autumn Hills Seal - Trip Saws",
"Autumn Hills Seal - Double Swing Saws",
"Autumn Hills Seal - Spike Ball Swing",
"Autumn Hills Seal - Spike Ball Darts",
"Catacombs - Necro",
"Catacombs - Ruxxtin's Amulet",
"Catacombs Seal - Triple Spike Crushers",
"Catacombs Seal - Crusher Gauntlet",
"Catacombs Seal - Dirty Pond",
"Bamboo Creek - Claustro",
"Cloud Ruins - Acro",
"Bamboo Creek Seal - Spike Crushers and Doors",
"Bamboo Creek Seal - Spike Ball Pits",
"Bamboo Creek Seal - Spike Crushers and Doors v2",
"Howling Grotto Seal - Windy Saws and Balls",
"Tower of Time Seal - Lantern Climb",
"Forlorn Temple - Demon King",
"Cloud Ruins Seal - Ghost Pit",
"Cloud Ruins Seal - Toothbrush Alley",
"Cloud Ruins Seal - Saw Pit",
"Cloud Ruins Seal - Money Farm Room",
"Tower of Time Seal - Lantern Climb",
"Tower of Time Seal - Arcane Orbs",
"Underworld Seal - Sharp and Windy Climb",
"Underworld Seal - Fireball Wave",
"Elemental Skylands Seal - Air",
"Elemental Skylands Seal - Water",
"Elemental Skylands Seal - Fire",
"Elemental Skylands - Key of Symbiosis",
"Forlorn Temple Seal - Rocket Maze",
"Forlorn Temple Seal - Rocket Sunset",
"Ninja Village - Astral Seed",
"Searing Crags - Astral Tea Leaves",
"Autumn Hills Mega Shard",
"Hidden Entrance Mega Shard",
"Sunny Day Mega Shard",
"Down Under Mega Shard",
"Catacombs Mega Shard",
"Above Entrance Mega Shard",
"Abandoned Mega Shard",
"Time Loop Mega Shard",
"Earth Mega Shard",
"Water Mega Shard",
"Money Farm Room Mega Shard 1",
"Money Farm Room Mega Shard 2",
"Autumn Hills - Leaf Golem",
"Catacombs - Ruxxtin",
"Howling Grotto - Emerald Golem",
]
items = [["Wingsuit"]]
self.assertAccessDependency(locations, items)