179 lines
11 KiB
C#
179 lines
11 KiB
C#
using Archipelago.HollowKnight.SlotDataModel;
|
|
using ItemChanger;
|
|
using System.Collections.Generic;
|
|
using SD = ItemChanger.Util.SceneDataUtil;
|
|
|
|
namespace Archipelago.HollowKnight.IC.RM
|
|
{
|
|
public static class HelperPlatformBuilder
|
|
{
|
|
public static IBool hasWalljump = new PDBool(nameof(PlayerData.hasWalljump));
|
|
public static IBool hasWalljumpLeft = new PDBool(nameof(ItemChanger.Modules.SplitClaw.hasWalljumpLeft));
|
|
public static IBool hasWalljumpRight = new PDBool(nameof(ItemChanger.Modules.SplitClaw.hasWalljumpRight));
|
|
public static IBool hasDoubleJump = new PDBool(nameof(PlayerData.hasDoubleJump));
|
|
|
|
public static IBool lacksLeftClaw = new Negation(new Disjunction(hasWalljump, hasWalljumpLeft));
|
|
public static IBool lacksLeftVertical = new Negation(new Disjunction(hasWalljump, hasDoubleJump, hasWalljumpLeft));
|
|
public static IBool lacksRightClaw = new Negation(new Disjunction(hasWalljump, hasWalljumpRight));
|
|
public static IBool lacksRightVertical = new Negation(new Disjunction(hasWalljump, hasDoubleJump, hasWalljumpRight));
|
|
public static IBool lacksAnyClaw = new Negation(new Disjunction(hasWalljump, hasWalljumpLeft, hasWalljumpRight));
|
|
public static IBool lacksAnyVertical = new Negation(new Disjunction(hasWalljump, hasDoubleJump, hasWalljumpLeft, hasWalljumpRight));
|
|
|
|
public static void AddStartLocationRequiredPlatforms(SlotOptions options)
|
|
{
|
|
string startLocationName = options.StartLocationName ?? StartLocationNames.Kings_Pass;
|
|
|
|
switch (startLocationName)
|
|
{
|
|
// Platforms to allow escaping the Hive start regardless of difficulty or initial items
|
|
case StartLocationNames.Hive:
|
|
ItemChangerMod.AddDeployer(new SmallPlatform { SceneName = SceneNames.Hive_03, X = 58.5f, Y = 134f, Test = lacksRightClaw });
|
|
ItemChangerMod.AddDeployer(new SmallPlatform { SceneName = SceneNames.Hive_03, X = 58.5f, Y = 138.5f, Test = lacksAnyVertical });
|
|
break;
|
|
|
|
// Drop the vine platforms and add small platforms for jumping up.
|
|
case StartLocationNames.Far_Greenpath:
|
|
ItemChangerMod.AddDeployer(new SmallPlatform { SceneName = SceneNames.Fungus1_13, X = 45f, Y = 16.5f, Test = lacksLeftClaw });
|
|
ItemChangerMod.AddDeployer(new SmallPlatform { SceneName = SceneNames.Fungus1_13, X = 64f, Y = 16.5f, Test = lacksRightClaw });
|
|
SD.Save(SceneNames.Fungus1_13, "Vine Platform (1)");
|
|
SD.Save(SceneNames.Fungus1_13, "Vine Platform (2)");
|
|
break;
|
|
|
|
// With the Lower Greenpath start, getting to the rest of Greenpath requires
|
|
// cutting the vine to the right of the vessel fragment.
|
|
case StartLocationNames.Lower_Greenpath:
|
|
if (options.RandomizeNail)
|
|
{
|
|
SD.Save(SceneNames.Fungus1_13, "Vine Platform");
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
public static void AddConveniencePlatforms(SlotOptions options)
|
|
{
|
|
// FUTURE: when we support room rando, this should be updated based on transition placements.
|
|
HashSet<string> targetNames = new();
|
|
string startLocationName = options.StartLocationName ?? StartLocationNames.Kings_Pass;
|
|
|
|
if (!options.ExtraPlatforms)
|
|
{
|
|
return;
|
|
}
|
|
|
|
// Platforms to climb out from basin wanderer's journal
|
|
ItemChangerMod.AddDeployer(new SmallPlatform() { SceneName = SceneNames.Abyss_02, X = 128.3f, Y = 7f, Test = lacksLeftClaw });
|
|
ItemChangerMod.AddDeployer(new SmallPlatform() { SceneName = SceneNames.Abyss_02, X = 128.3f, Y = 11f, Test = lacksLeftClaw });
|
|
|
|
// Platforms to climb up to tram in basin from left with no items
|
|
if (!targetNames.Contains($"{SceneNames.Abyss_03}[bot1]"))
|
|
{
|
|
ItemChangerMod.AddDeployer(new SmallPlatform() { SceneName = SceneNames.Abyss_03, X = 34f, Y = 7f, Test = lacksRightVertical });
|
|
}
|
|
|
|
// Platform to climb out of Abyss with only wings
|
|
ItemChangerMod.AddDeployer(new SmallPlatform() { SceneName = SceneNames.Abyss_06_Core, X = 88.6f, Y = 263f, Test = lacksLeftClaw });
|
|
|
|
// Platforms to climb back up from pale ore with no items
|
|
ItemChangerMod.AddDeployer(new SmallPlatform() { SceneName = SceneNames.Abyss_17, X = 164.7f, Y = 30f, Test = lacksRightVertical });
|
|
ItemChangerMod.AddDeployer(new SmallPlatform() { SceneName = SceneNames.Abyss_17, X = 99.5f, Y = 12.5f, Test = lacksRightVertical });
|
|
ItemChangerMod.AddDeployer(new SmallPlatform() { SceneName = SceneNames.Abyss_17, X = 117.7f, Y = 18.8f, Test = lacksRightClaw });
|
|
ItemChangerMod.AddDeployer(new SmallPlatform() { SceneName = SceneNames.Abyss_17, X = 114.3f, Y = 23f, Test = lacksAnyVertical });
|
|
ItemChangerMod.AddDeployer(new SmallPlatform() { SceneName = SceneNames.Abyss_17, X = 117.7f, Y = 7f, Test = lacksAnyClaw });
|
|
ItemChangerMod.AddDeployer(new SmallPlatform() { SceneName = SceneNames.Abyss_17, X = 117.7f, Y = 10.8f, Test = lacksAnyClaw });
|
|
|
|
// Platforms to remove softlock with wings at simple key in basin
|
|
ItemChangerMod.AddDeployer(new SmallPlatform() { SceneName = SceneNames.Abyss_20, X = 26.5f, Y = 13f, Test = lacksAnyClaw });
|
|
|
|
// Platform for returning to Gorb landing
|
|
ItemChangerMod.AddDeployer(new SmallPlatform() { SceneName = SceneNames.Cliffs_02, X = 32.3f, Y = 27.7f, Test = lacksAnyVertical });
|
|
|
|
// Platform to return from Deepnest mimic grub room
|
|
if (!targetNames.Contains($"{SceneNames.Deepnest_01b}[right2]")
|
|
&& !targetNames.Contains($"{SceneNames.Deepnest_02}[left1]")
|
|
&& !targetNames.Contains($"{SceneNames.Deepnest_02}[right1]"))
|
|
{
|
|
ItemChangerMod.AddDeployer(new SmallPlatform() { SceneName = SceneNames.Deepnest_01b, X = 48.3f, Y = 40f, Test = lacksAnyVertical });
|
|
}
|
|
|
|
// Platforms to return from the Deepnest_02 geo rocks without vertical
|
|
ItemChangerMod.AddDeployer(new SmallPlatform() { SceneName = SceneNames.Deepnest_02, X = 26f, Y = 12f, Test = lacksAnyClaw });
|
|
ItemChangerMod.AddDeployer(new SmallPlatform() { SceneName = SceneNames.Deepnest_02, X = 26f, Y = 16f, Test = lacksAnyClaw });
|
|
|
|
// Platform to escape the Deepnest mimic room when mimics may not be present
|
|
if (options.RandomizeMimics)
|
|
{
|
|
ItemChangerMod.AddDeployer(new SmallPlatform() { SceneName = SceneNames.Deepnest_36, X = 26f, Y = 11f, Test = lacksLeftVertical });
|
|
}
|
|
|
|
// Platforms to climb back up from Mantis Lords with only wings
|
|
if (!targetNames.Contains($"{SceneNames.Fungus2_15}[left1]")
|
|
&& !targetNames.Contains($"{SceneNames.Fungus2_25}[top1]")
|
|
&& !targetNames.Contains($"{SceneNames.Fungus2_25}[top2]"))
|
|
{
|
|
for (int i = 0; i < 2; i++)
|
|
{
|
|
ItemChangerMod.AddDeployer(new SmallPlatform() { SceneName = SceneNames.Fungus2_15, X = 48f + 2 * i, Y = 15f + 10 * i, Test = lacksRightClaw });
|
|
}
|
|
}
|
|
|
|
// Platforms to prevent softlock on lever on the way to love key.
|
|
for (int i = 0; i < 2; i++)
|
|
{
|
|
ItemChangerMod.AddDeployer(new SmallPlatform() { SceneName = SceneNames.Fungus3_05, X = 65.7f, Y = 11f + 4.5f * i, Test = lacksRightClaw });
|
|
}
|
|
|
|
if (startLocationName != StartLocationNames.Hive)
|
|
{
|
|
ItemChangerMod.AddDeployer(new SmallPlatform() { SceneName = SceneNames.Hive_03, X = 58.5f, Y = 134f, Test = lacksAnyVertical });
|
|
ItemChangerMod.AddDeployer(new SmallPlatform() { SceneName = SceneNames.Hive_03, X = 58.5f, Y = 138.5f, Test = lacksAnyVertical });
|
|
}
|
|
|
|
// Move the load in colo downward to prevent bench soft lock
|
|
if (!targetNames.Contains($"{SceneNames.Room_Colosseum_02}[top2]")
|
|
&& !targetNames.Contains($"{SceneNames.Room_Colosseum_Spectate}[right1]"))
|
|
{
|
|
ItemChangerMod.AddDeployer(new SmallPlatform() { SceneName = SceneNames.Room_Colosseum_02, X = 43.5f, Y = 45f, Test = lacksAnyClaw });
|
|
ItemChangerMod.AddDeployer(new SmallPlatform() { SceneName = SceneNames.Room_Colosseum_02, X = 43.5f, Y = 49.5f, Test = lacksAnyClaw });
|
|
}
|
|
|
|
// Platform to escape from the geo rock above Lemm
|
|
ItemChangerMod.AddDeployer(new SmallPlatform() { SceneName = SceneNames.Ruins1_05c, X = 26.6f, Y = 73.2f, Test = lacksAnyVertical });
|
|
|
|
// Platforms to climb back up to King's Pass with no items
|
|
if (!targetNames.Contains($"{SceneNames.Town}[right1]") && startLocationName == StartLocationNames.Kings_Pass)
|
|
{
|
|
for (int i = 0; i < 6; i++)
|
|
{
|
|
ItemChangerMod.AddDeployer(new SmallPlatform() { SceneName = SceneNames.Town, X = 20f - 2 * (i % 2), Y = 5f * i + 15f, Test = lacksLeftClaw });
|
|
}
|
|
}
|
|
|
|
// Platforms to prevent itemless softlock when checking left waterways
|
|
if (!targetNames.Contains($"{SceneNames.Waterways_04}[left1]")
|
|
&& !targetNames.Contains($"{SceneNames.Waterways_04}[left2]")
|
|
&& !targetNames.Contains($"{SceneNames.Waterways_04b}[left1]")
|
|
&& !targetNames.Contains($"{SceneNames.Waterways_09}[left1]")
|
|
&& startLocationName != StartLocationNames.West_Waterways)
|
|
{
|
|
ItemChangerMod.AddDeployer(new SmallPlatform() { SceneName = SceneNames.Waterways_04, X = 148f, Y = 23.1f, Test = lacksAnyVertical });
|
|
ItemChangerMod.AddDeployer(new SmallPlatform() { SceneName = SceneNames.Waterways_04, X = 139f, Y = 32f, Test = lacksAnyVertical });
|
|
ItemChangerMod.AddDeployer(new SmallPlatform()
|
|
{
|
|
SceneName = SceneNames.Waterways_04,
|
|
X = 107f,
|
|
Y = 10f,
|
|
Test = options.RandomizeSwim ? new PDBool("canSwim") : null
|
|
});
|
|
ItemChangerMod.AddDeployer(new SmallPlatform()
|
|
{
|
|
SceneName = SceneNames.Waterways_04,
|
|
X = 107f,
|
|
Y = 15f,
|
|
Test = options.RandomizeSwim ? new PDBool("canSwim") : null
|
|
});
|
|
}
|
|
}
|
|
}
|
|
}
|