mirror of
https://github.com/soarqin/DSP_Mods.git
synced 2025-12-09 09:33:36 +08:00
fix various solar sail bugs
This commit is contained in:
@@ -15,25 +15,30 @@ public static class DysonSpherePatch
|
|||||||
public static ConfigEntry<bool> OverclockEjectorEnabled;
|
public static ConfigEntry<bool> OverclockEjectorEnabled;
|
||||||
public static ConfigEntry<bool> OverclockSiloEnabled;
|
public static ConfigEntry<bool> OverclockSiloEnabled;
|
||||||
private static bool _instantAbsorb;
|
private static bool _instantAbsorb;
|
||||||
|
|
||||||
|
private static Harmony _dysonSpherePatch;
|
||||||
|
|
||||||
public static void Init()
|
public static void Init()
|
||||||
{
|
{
|
||||||
SkipBulletEnabled.SettingChanged += (_, _) => SkipBulletPatch.Enable(SkipBulletEnabled.Value);
|
SkipBulletEnabled.SettingChanged += (_, _) => SkipBulletPatch.Enable(SkipBulletEnabled.Value);
|
||||||
SkipAbsorbEnabled.SettingChanged += (_, _) => SkipAbsorbPatch.Enable(SkipBulletEnabled.Value);
|
SkipAbsorbEnabled.SettingChanged += (_, _) => SkipAbsorbPatch.Enable(SkipAbsorbEnabled.Value);
|
||||||
QuickAbsorbEnabled.SettingChanged += (_, _) => QuickAbsorbPatch.Enable(QuickAbsorbEnabled.Value);
|
QuickAbsorbEnabled.SettingChanged += (_, _) => QuickAbsorbPatch.Enable(QuickAbsorbEnabled.Value);
|
||||||
EjectAnywayEnabled.SettingChanged += (_, _) => EjectAnywayPatch.Enable(EjectAnywayEnabled.Value);
|
EjectAnywayEnabled.SettingChanged += (_, _) => EjectAnywayPatch.Enable(EjectAnywayEnabled.Value);
|
||||||
OverclockEjectorEnabled.SettingChanged += (_, _) => OverclockEjector.Enable(OverclockEjectorEnabled.Value);
|
OverclockEjectorEnabled.SettingChanged += (_, _) => OverclockEjector.Enable(OverclockEjectorEnabled.Value);
|
||||||
OverclockSiloEnabled.SettingChanged += (_, _) => OverclockSilo.Enable(OverclockSiloEnabled.Value);
|
OverclockSiloEnabled.SettingChanged += (_, _) => OverclockSilo.Enable(OverclockSiloEnabled.Value);
|
||||||
SkipBulletPatch.Enable(SkipBulletEnabled.Value);
|
SkipBulletPatch.Enable(SkipBulletEnabled.Value);
|
||||||
SkipAbsorbPatch.Enable(SkipBulletEnabled.Value);
|
SkipAbsorbPatch.Enable(SkipAbsorbEnabled.Value);
|
||||||
QuickAbsorbPatch.Enable(QuickAbsorbEnabled.Value);
|
QuickAbsorbPatch.Enable(QuickAbsorbEnabled.Value);
|
||||||
EjectAnywayPatch.Enable(EjectAnywayEnabled.Value);
|
EjectAnywayPatch.Enable(EjectAnywayEnabled.Value);
|
||||||
OverclockEjector.Enable(OverclockEjectorEnabled.Value);
|
OverclockEjector.Enable(OverclockEjectorEnabled.Value);
|
||||||
OverclockSilo.Enable(OverclockSiloEnabled.Value);
|
OverclockSilo.Enable(OverclockSiloEnabled.Value);
|
||||||
|
_dysonSpherePatch ??= Harmony.CreateAndPatchAll(typeof(DysonSpherePatch));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void Uninit()
|
public static void Uninit()
|
||||||
{
|
{
|
||||||
|
_dysonSpherePatch?.UnpatchSelf();
|
||||||
|
_dysonSpherePatch = null;
|
||||||
SkipBulletPatch.Enable(false);
|
SkipBulletPatch.Enable(false);
|
||||||
SkipAbsorbPatch.Enable(false);
|
SkipAbsorbPatch.Enable(false);
|
||||||
QuickAbsorbPatch.Enable(false);
|
QuickAbsorbPatch.Enable(false);
|
||||||
@@ -41,6 +46,40 @@ public static class DysonSpherePatch
|
|||||||
OverclockEjector.Enable(false);
|
OverclockEjector.Enable(false);
|
||||||
OverclockSilo.Enable(false);
|
OverclockSilo.Enable(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[HarmonyTranspiler]
|
||||||
|
[HarmonyPatch(typeof(DysonNode), nameof(DysonNode.OrderConstructCp))]
|
||||||
|
private static IEnumerable<CodeInstruction> DysonNode_OrderConstructCp_Transpiler(IEnumerable<CodeInstruction> instructions, ILGenerator generator)
|
||||||
|
{
|
||||||
|
var matcher = new CodeMatcher(instructions, generator);
|
||||||
|
matcher.MatchForward(false,
|
||||||
|
new CodeMatch(OpCodes.Callvirt, AccessTools.Method(typeof(DysonSwarm), nameof(DysonSwarm.AbsorbSail)))
|
||||||
|
).Advance(1).SetInstructionAndAdvance(
|
||||||
|
new CodeInstruction(OpCodes.Pop)
|
||||||
|
).Insert(
|
||||||
|
new CodeInstruction(OpCodes.Ret)
|
||||||
|
);
|
||||||
|
return matcher.InstructionEnumeration();
|
||||||
|
}
|
||||||
|
|
||||||
|
[HarmonyTranspiler]
|
||||||
|
[HarmonyPatch(typeof(DysonSwarm), nameof(DysonSwarm.AbsorbSail))]
|
||||||
|
private static IEnumerable<CodeInstruction> DysonSwarm_AbsorbSail_Transpiler(IEnumerable<CodeInstruction> instructions, ILGenerator generator)
|
||||||
|
{
|
||||||
|
var matcher = new CodeMatcher(instructions, generator);
|
||||||
|
matcher.MatchForward(false,
|
||||||
|
new CodeMatch(OpCodes.Stfld, AccessTools.Field(typeof(ExpiryOrder), nameof(ExpiryOrder.time)))
|
||||||
|
).Advance(1).Insert(
|
||||||
|
// node.cpOrdered = node.cpOrdered + 1;
|
||||||
|
new CodeInstruction(OpCodes.Ldarg_1),
|
||||||
|
new CodeInstruction(OpCodes.Ldarg_1),
|
||||||
|
new CodeInstruction(OpCodes.Ldfld, AccessTools.Field(typeof(DysonNode), nameof(DysonNode.cpOrdered))),
|
||||||
|
new CodeInstruction(OpCodes.Ldc_I4_1),
|
||||||
|
new CodeInstruction(OpCodes.Add),
|
||||||
|
new CodeInstruction(OpCodes.Stfld, AccessTools.Field(typeof(DysonNode), nameof(DysonNode.cpOrdered)))
|
||||||
|
);
|
||||||
|
return matcher.InstructionEnumeration();
|
||||||
|
}
|
||||||
|
|
||||||
private static class SkipBulletPatch
|
private static class SkipBulletPatch
|
||||||
{
|
{
|
||||||
@@ -201,16 +240,16 @@ public static class DysonSpherePatch
|
|||||||
var llen = sphere.layerCount;
|
var llen = sphere.layerCount;
|
||||||
if (llen > 0)
|
if (llen > 0)
|
||||||
{
|
{
|
||||||
var lidx = time / 16 % llen;
|
var lidx = ((int)time >> 4) % llen;
|
||||||
for (var i = llen - 1; i >= 0; i--)
|
for (var i = llen - 1; i >= 0; i--)
|
||||||
{
|
{
|
||||||
var layer = layers[(lidx + i) % llen];
|
var layer = layers[(lidx + i) % llen];
|
||||||
var nodes = layer.nodePool;
|
var nodes = layer.nodePool;
|
||||||
var nlen = layer.nodeCursor;
|
var nlen = layer.nodeCursor - 1;
|
||||||
var nidx = time % nlen;
|
var nidx = (int)time % nlen;
|
||||||
for (var j = nlen - 1; j >= 0; j--)
|
for (var j = nlen; j > 0; j--)
|
||||||
{
|
{
|
||||||
var nodeIdx = (nidx + j) % nlen;
|
var nodeIdx = (nidx + j) % nlen + 1;
|
||||||
var node = nodes[nodeIdx];
|
var node = nodes[nodeIdx];
|
||||||
if (node == null || node.id != nodeIdx || node.sp < node.spMax) continue;
|
if (node == null || node.id != nodeIdx || node.sp < node.spMax) continue;
|
||||||
while (node.cpReqOrder > 0)
|
while (node.cpReqOrder > 0)
|
||||||
@@ -251,46 +290,21 @@ public static class DysonSpherePatch
|
|||||||
if (on)
|
if (on)
|
||||||
{
|
{
|
||||||
_patch ??= Harmony.CreateAndPatchAll(typeof(SkipAbsorbPatch));
|
_patch ??= Harmony.CreateAndPatchAll(typeof(SkipAbsorbPatch));
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
else
|
_patch?.UnpatchSelf();
|
||||||
{
|
_patch = null;
|
||||||
_patch?.UnpatchSelf();
|
|
||||||
_patch = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[HarmonyTranspiler]
|
|
||||||
[HarmonyPatch(typeof(DysonNode), nameof(DysonNode.OrderConstructCp))]
|
|
||||||
private static IEnumerable<CodeInstruction> DysonNode_OrderConstructCp_Transpiler(IEnumerable<CodeInstruction> instructions, ILGenerator generator)
|
|
||||||
{
|
|
||||||
var matcher = new CodeMatcher(instructions, generator);
|
|
||||||
matcher.MatchForward(false,
|
|
||||||
new CodeMatch(OpCodes.Callvirt, AccessTools.Method(typeof(DysonSwarm), nameof(DysonSwarm.AbsorbSail)))
|
|
||||||
).Advance(1).SetInstructionAndAdvance(
|
|
||||||
new CodeInstruction(OpCodes.Pop)
|
|
||||||
).Insert(
|
|
||||||
new CodeInstruction(OpCodes.Ret)
|
|
||||||
);
|
|
||||||
return matcher.InstructionEnumeration();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[HarmonyTranspiler]
|
[HarmonyTranspiler]
|
||||||
[HarmonyPatch(typeof(DysonSwarm), nameof(DysonSwarm.AbsorbSail))]
|
[HarmonyPatch(typeof(DysonSwarm), nameof(DysonSwarm.AbsorbSail))]
|
||||||
private static IEnumerable<CodeInstruction> DysonSwarm_AbsorbSail_Transpiler(IEnumerable<CodeInstruction> instructions, ILGenerator generator)
|
private static IEnumerable<CodeInstruction> DysonSwarm_AbsorbSail_Transpiler2(IEnumerable<CodeInstruction> instructions, ILGenerator generator)
|
||||||
{
|
{
|
||||||
var matcher = new CodeMatcher(instructions, generator);
|
var matcher = new CodeMatcher(instructions, generator);
|
||||||
var label1 = generator.DefineLabel();
|
var label1 = generator.DefineLabel();
|
||||||
matcher.MatchForward(false,
|
matcher.MatchForward(false,
|
||||||
new CodeMatch(OpCodes.Stfld, AccessTools.Field(typeof(ExpiryOrder), nameof(ExpiryOrder.index)))
|
new CodeMatch(OpCodes.Stfld, AccessTools.Field(typeof(ExpiryOrder), nameof(ExpiryOrder.index)))
|
||||||
).Advance(1).RemoveInstructions(matcher.Length - matcher.Pos).Insert(
|
).Advance(1).RemoveInstructions(matcher.Length - matcher.Pos).Insert(
|
||||||
// node.cpOrdered = node.cpOrdered + 1;
|
|
||||||
new CodeInstruction(OpCodes.Ldarg_1),
|
|
||||||
new CodeInstruction(OpCodes.Ldarg_1),
|
|
||||||
new CodeInstruction(OpCodes.Ldfld, AccessTools.Field(typeof(DysonNode), nameof(DysonNode.cpOrdered))),
|
|
||||||
new CodeInstruction(OpCodes.Ldc_I4_1),
|
|
||||||
new CodeInstruction(OpCodes.Add),
|
|
||||||
new CodeInstruction(OpCodes.Stfld, AccessTools.Field(typeof(DysonNode), nameof(DysonNode.cpOrdered))),
|
|
||||||
|
|
||||||
// if (node.ConstructCp() != null)
|
// if (node.ConstructCp() != null)
|
||||||
// {
|
// {
|
||||||
// this.dysonSphere.productRegister[11903]++;
|
// this.dysonSphere.productRegister[11903]++;
|
||||||
@@ -360,25 +374,19 @@ public static class DysonSpherePatch
|
|||||||
|
|
||||||
private static void DoAbsorb(DysonSphereLayer layer, long gameTick)
|
private static void DoAbsorb(DysonSphereLayer layer, long gameTick)
|
||||||
{
|
{
|
||||||
|
var nodeCount = layer.nodeCursor - 1;
|
||||||
|
if (nodeCount <= 0) return;
|
||||||
|
var nodes = layer.nodePool;
|
||||||
var swarm = layer.dysonSphere.swarm;
|
var swarm = layer.dysonSphere.swarm;
|
||||||
for (var i = layer.nodeCursor - 1; i > 0; i--)
|
var delta = ((int)gameTick >> 6) % nodeCount;
|
||||||
|
for (var i = nodeCount - ((int)gameTick & 0x3F); i > 0; i -= 0x40)
|
||||||
{
|
{
|
||||||
var node = layer.nodePool[i];
|
var idx = (delta + i) % nodeCount + 1;
|
||||||
if (node == null || node.id != i || node.sp < node.spMax) continue;
|
var node = nodes[idx];
|
||||||
var req = node._cpReq;
|
if (node == null || node.id != idx || node.sp < node.spMax) continue;
|
||||||
var ordered = node.cpOrdered;
|
for (var j = node.cpReqOrder; j > 0; j--)
|
||||||
if (req <= ordered) continue;
|
|
||||||
if (!swarm.AbsorbSail(node, gameTick)) return; // No more sails can be absorbed
|
|
||||||
ordered++;
|
|
||||||
while (req > ordered)
|
|
||||||
{
|
{
|
||||||
if (!swarm.AbsorbSail(node, gameTick))
|
if (!swarm.AbsorbSail(node, gameTick)) return; // No more sails can be absorbed
|
||||||
{
|
|
||||||
// No more sails can be absorbed
|
|
||||||
node.cpOrdered = ordered;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
ordered++;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user