diff --git a/region/lowernorfair/east/Ridley's Room.json b/region/lowernorfair/east/Ridley's Room.json index 6445590339..beb6382a5f 100644 --- a/region/lowernorfair/east/Ridley's Room.json +++ b/region/lowernorfair/east/Ridley's Room.json @@ -167,6 +167,185 @@ "flashSuitChecked": true, "devNote": "FIXME: Ridley could also be used to set up G-mode, but the chaos of the fight makes this difficult." }, + { + "link": [1, 2], + "name": "Side Platform Cross Room Speedy Jump", + "entranceCondition": { + "comeInWithSidePlatform": { + "platforms": [ + { + "minHeight": 1, + "maxHeight": 1, + "minTiles": 17, + "obstructions": [[1, 0]], + "speedBooster": true, + "requires": [ + {"or": [ + {"and": [ + "HiJump", + {"heatFrames": 90} + ]}, + {"and": [ + "canTrickyDashJump", + "canTrickySpringBallJump", + {"heatFrames": 115} + ]} + ]} + ], + "note": ["This applies to Warehouse Entrance."], + "detailNote": [ + "For the spring ball jump, retain forward momentum until the pause hits,", + "in order for the mid-air jump to also get the 'tricky dash' boost in height." + ] + }, + { + "minHeight": 2, + "maxHeight": 2, + "minTiles": 11.4375, + "obstructions": [[1, 0]], + "speedBooster": true, + "requires": [ + "canTrickyDashJump", + "canTrickySpringBallJump", + {"heatFrames": 100} + ], + "note": ["This applies to Ridley Tank Room, Halfie Climb Room, and Dust Torizo Room."], + "detailNote": [ + "Retain forward momentum until the pause hits,", + "in order for the mid-air jump to also get the 'tricky dash' boost in height." + ] + }, + { + "minHeight": 2, + "maxHeight": 2, + "minTiles": 12.4375, + "obstructions": [[1, 0]], + "speedBooster": true, + "requires": [ + "HiJump", + {"heatFrames": 95} + ], + "note": ["This applies to Halfie Climb Room and Dust Torizo Room."] + }, + { + "minHeight": 3, + "maxHeight": 3, + "minTiles": 10.4375, + "obstructions": [[1, 0]], + "speedBooster": true, + "requires": [ + "canTrickyDashJump", + "canTrickySpringBallJump", + {"heatFrames": 120} + ], + "note": ["This applies to Big Boy Room and Mickey Mouse Room."], + "detailNote": [ + "For the spring ball jump, retain forward momentum until the pause hits,", + "in order for the mid-air jump to also get the 'tricky dash' boost in height." + ] + }, + { + "minHeight": 2, + "maxHeight": 2, + "minTiles": 45, + "obstructions": [[2, 0]], + "speedBooster": true, + "requires": [ + "canInsaneJump", + {"heatFrames": 85} + ], + "note": ["This applies to Waterway Energy Tank Room."] + }, + { + "minHeight": 2, + "maxHeight": 2, + "minTiles": 45, + "obstructions": [[3, 0]], + "speedBooster": true, + "requires": [ + "canInsaneJump", + "canMomentumConservingMorph", + {"or": [ + {"and": [ + "HiJump", + "canInsaneMidAirMorph", + {"heatFrames": 80} + ]}, + {"and": [ + "canTrickySpringBallJump", + {"heatFrames": 100} + ]} + ]} + ], + "note": ["This applies to Statues Hallway."] + }, + { + "minHeight": 3, + "maxHeight": 3, + "minTiles": 37.4375, + "obstructions": [[3, 0]], + "speedBooster": true, + "requires": [ + "canInsaneJump", + "canMomentumConservingMorph", + {"or": [ + {"and": [ + "HiJump", + {"heatFrames": 85} + ]}, + {"and": [ + "canTrickySpringBallJump", + {"heatFrames": 100} + ]} + ]} + ], + "note": ["This applies to Flyway."] + }, + { + "minHeight": 2, + "maxHeight": 2, + "minTiles": 45, + "obstructions": [[4, 0]], + "speedBooster": true, + "requires": [ + "canInsaneJump", + "canMomentumConservingMorph", + "canInsaneMidAirMorph", + "canTrickySpringBallJump", + {"heatFrames": 100} + ], + "note": ["This applies to Baby Kraid Room."] + }, + { + "minHeight": 3, + "maxHeight": 3, + "minTiles": 39.4375, + "obstructions": [[3, 2]], + "speedBooster": true, + "requires": [ + "canTrickyJump", + {"or": [ + {"and": [ + "HiJump", + {"heatFrames": 75} + ]}, + {"and": [ + "canTrickySpringBallJump", + {"heatFrames": 115} + ]} + ]} + ], + "note": ["This applies to Metal Pirates Room."] + } + ] + } + }, + "requires": [], + "devNote": [ + "FIXME: Many of the spring ball jump variants can be done more easily with a spring ball bounce,", + "which should be added as a separate strat." + ] + }, { "id": 23, "link": [1, 2], diff --git a/region/maridia/inner-pink/Halfie Climb Room.json b/region/maridia/inner-pink/Halfie Climb Room.json index e85616dbe6..bf77a0bb09 100644 --- a/region/maridia/inner-pink/Halfie Climb Room.json +++ b/region/maridia/inner-pink/Halfie Climb Room.json @@ -1009,6 +1009,17 @@ "The jump could also be done with a shorter runway, with a tricky dash jump using run speed $4.0 or $4.1." ] }, + { + "minHeight": 2, + "maxHeight": 2, + "minTiles": 45, + "obstructions": [[2, 0]], + "speedBooster": true, + "requires": [ + "canInsaneJump" + ], + "note": ["This applies to Waterway Energy Tank Room."] + }, { "minHeight": 3, "maxHeight": 3, @@ -2455,6 +2466,22 @@ "requires": [], "note": ["This applies to Dust Torizo Room."] }, + { + "minHeight": 2, + "maxHeight": 2, + "minTiles": 45, + "obstructions": [[2, 0]], + "speedBooster": true, + "requires": [ + "canInsaneJump", + "canMomentumConservingMorph" + ], + "note": ["This applies to Waterway Energy Tank Room."], + "detailNote": [ + "Gain run speed, and time a pause to unequip Gravity after Samus jumps and aims down;", + "when the unpause black screen hits, press and hold down (and jump) to buffer a morph." + ] + }, { "minHeight": 3, "maxHeight": 3, diff --git a/tests/asserts/keywords.py b/tests/asserts/keywords.py index c51d9cd7e5..789f2512e6 100644 --- a/tests/asserts/keywords.py +++ b/tests/asserts/keywords.py @@ -1068,6 +1068,37 @@ def check_speed_states(strat, err_fn): def strat_err_fn(msg): messages["reds"].append(f"🔴ERROR: {stratRef}:{msg}") messages["counts"]["reds"] += 1 + + def make_and(reqs): + if len(reqs) == 0: + return "free" + elif len(reqs) == 1: + return reqs[0] + else: + return {"and": reqs} + + def make_or(reqs): + if len(reqs) == 0: + return "never" + elif len(reqs) == 1: + return reqs[0] + else: + out = [] + for r in reqs: + if isinstance(r, dict) and "or" in r: + out.extend(r["or"]) + else: + out.append(r) + return {"or": out} + + + requires = strat["requires"] + if "entranceCondition" in strat and "comeInWithSidePlatform" in strat["entranceCondition"]: + reqs = [] + for platform in strat["entranceCondition"]["comeInWithSidePlatform"]["platforms"]: + reqs.append(make_and(platform.get("requires", []))) + requires.append(make_or(reqs)) + for req in strat["requires"]: check_and_or(req, strat_err_fn) if heated and not check_heat_req({"and": strat["requires"]}):