1
0
mirror of https://github.com/soarqin/DSP_Mods.git synced 2025-12-09 14:13:31 +08:00
This commit is contained in:
2023-09-11 02:39:18 +08:00
parent 07a32f7fd0
commit 9c5523fb37
7 changed files with 466 additions and 29 deletions

View File

@@ -1,8 +1,8 @@
using System.Collections.Generic;
using System;
using System.Collections.Generic;
using System.Reflection.Emit;
using BepInEx.Configuration;
using HarmonyLib;
using PowerNetworkStructures;
namespace CheatEnabler;
@@ -62,6 +62,9 @@ public static class DysonSpherePatch
_skipBulletPatch.UnpatchSelf();
_skipBulletPatch = null;
}
SkipBulletPatch.UpdateSailLifeTime();
SkipBulletPatch.UpdateSailsCacheForThisGame();
_skipBulletPatch = Harmony.CreateAndPatchAll(typeof(SkipBulletPatch));
}
else if (_skipBulletPatch != null)
@@ -127,13 +130,148 @@ public static class DysonSpherePatch
private static class SkipBulletPatch
{
private static long _sailLifeTime;
private static DysonSailCache[][] _sailsCache;
private static int[] _sailsCacheLen, _sailsCacheCapacity;
private struct DysonSailCache
{
public DysonSail Sail;
public int OrbitId;
}
public static void UpdateSailLifeTime()
{
if (GameMain.history == null) return;
_sailLifeTime = (long)(GameMain.history.solarSailLife * 60f + 0.1f);
}
public static void UpdateSailsCacheForThisGame()
{
var galaxy = GameMain.data?.galaxy;
if (galaxy == null) return;
var starCount = GameMain.data.galaxy.starCount;
_sailsCache = new DysonSailCache[starCount][];
_sailsCacheLen = new int[starCount];
_sailsCacheCapacity = new int[starCount];
Array.Clear(_sailsCacheLen, 0, starCount);
Array.Clear(_sailsCacheCapacity, 0, starCount);
}
private static void SetSailsCacheCapacity(int index, int capacity)
{
var newCache = new DysonSailCache[capacity];
var len = _sailsCacheLen[index];
if (len > 0)
{
Array.Copy(_sailsCache[index], newCache, len);
}
_sailsCache[index] = newCache;
_sailsCacheCapacity[index] = capacity;
}
[HarmonyPostfix]
[HarmonyPatch(typeof(GameData), nameof(GameData.NewGame))]
[HarmonyPatch(typeof(GameData), nameof(GameData.Import))]
private static void GameData_NewGame_Postfix()
{
UpdateSailsCacheForThisGame();
}
[HarmonyPostfix]
[HarmonyPatch(typeof(GameHistoryData), nameof(GameHistoryData.SetForNewGame))]
[HarmonyPatch(typeof(GameHistoryData), nameof(GameHistoryData.Import))]
private static void GameHistoryData_SetForNewGame_Postfix()
{
UpdateSailLifeTime();
}
[HarmonyPostfix]
[HarmonyPatch(typeof(GameHistoryData), nameof(GameHistoryData.UnlockTechFunction))]
private static void GameHistoryData_SetForNewGame_Postfix(int func)
{
if (func == 12)
{
UpdateSailLifeTime();
}
}
[HarmonyTranspiler]
[HarmonyPatch(typeof(EjectorComponent), nameof(EjectorComponent.InternalUpdate))]
private static IEnumerable<CodeInstruction> EjectorComponent_InternalUpdate_Patch(IEnumerable<CodeInstruction> instructions, ILGenerator generator)
{
var matcher = new CodeMatcher(instructions, generator);
matcher.MatchForward(false,
new CodeMatch(OpCodes.Ldc_R4, 10f)
).Advance(2);
var start = matcher.Pos;
matcher.MatchForward(false,
new CodeMatch(OpCodes.Pop)
).Advance(1);
var end = matcher.Pos;
matcher.Start().Advance(start).RemoveInstructions(end - start).Insert(
new CodeInstruction(OpCodes.Ldarg_2),
new CodeInstruction(OpCodes.Ldarg_0),
new CodeInstruction(OpCodes.Ldfld, AccessTools.Field(typeof(EjectorComponent), nameof(EjectorComponent.orbitId))),
new CodeInstruction(OpCodes.Ldloc_S, 8),
new CodeInstruction(OpCodes.Ldloc_S, 10),
new CodeInstruction(OpCodes.Call, AccessTools.Method(typeof(SkipBulletPatch), nameof(SkipBulletPatch.AddDysonSail)))
);
return matcher.InstructionEnumeration();
}
private static void AddDysonSail(DysonSwarm swarm, int orbitId, VectorLF3 uPos, VectorLF3 endVec)
{
var index = swarm.starData.index;
var delta1 = endVec - swarm.starData.uPosition;
var delta2 = VectorLF3.Cross(endVec - uPos, swarm.orbits[orbitId].up).normalized * Math.Sqrt(swarm.dysonSphere.gravity / swarm.orbits[orbitId].radius)
+ RandomTable.SphericNormal(ref swarm.randSeed, 0.5);
lock(swarm)
{
var cache = _sailsCache[index];
var len = _sailsCacheLen[index];
if (cache == null)
{
SetSailsCacheCapacity(index, 256);
cache = _sailsCache[index];
}
else
{
var capacity = _sailsCacheCapacity[index];
if (len >= capacity)
{
SetSailsCacheCapacity(index, capacity * 2);
cache = _sailsCache[index];
}
}
_sailsCacheLen[index] = len + 1;
ref var sailCache = ref cache[len];
ref var ss = ref sailCache.Sail;
ss.px = (float)delta1.x;
ss.py = (float)delta1.y;
ss.pz = (float)delta1.z;
ss.vx = (float)delta2.x;
ss.vy = (float)delta2.y;
ss.vz = (float)delta2.z;
ss.gs = 1f;
sailCache.OrbitId = orbitId;
}
}
[HarmonyPrefix]
[HarmonyPatch(typeof(DysonSwarm), "GameTick")]
public static void DysonSwarm_GameTick_Prefix(DysonSwarm __instance, long time)
{
var index = __instance.starData.index;
var len = _sailsCacheLen[index];
if (len == 0) return;
_sailsCacheLen[index] = 0;
var cache = _sailsCache[index];
var deadline = time + _sailLifeTime;
for (var i = len - 1; i >= 0; i--)
{
__instance.AddSolarSail(cache[i].Sail, cache[i].OrbitId, deadline);
}
}
}
private static class SkipAbsorbPatch
@@ -188,17 +326,49 @@ public static class DysonSpherePatch
private static class QuickAbsortPatch
{
// [HarmonyPrefix]
// [HarmonyPatch(typeof(DysonSphereLayer), "GameTick")]
// public static void DysonSphereLayerGameTick(ref DysonSphereLayer __instance, long gameTick)
// {
// DysonSwarm swarm = __instance.dysonSphere.swarm;
// for (int i = __instance.nodeCursor - 1; i > 0; i--)
// {
// DysonNode dysonNode = __instance.nodePool[i];
// if (dysonNode != null && dysonNode.id == i && dysonNode.sp == dysonNode.spMax)
// {
// dysonNode.OrderConstructCp(gameTick, swarm);
// }
// }
// }
[HarmonyTranspiler]
[HarmonyPatch(typeof(DysonSphereLayer), nameof(DysonSphereLayer.GameTick))]
private static IEnumerable<CodeInstruction> DysonSphereLayer_GameTick_Patch(IEnumerable<CodeInstruction> instructions, ILGenerator generator)
{
var matcher = new CodeMatcher(instructions, generator);
/* Remove `dysonNode.id % 120 == num` */
matcher.MatchForward(false,
new CodeMatch(OpCodes.Ldc_I4_S, 120)
).Advance(-2).RemoveInstructions(6);
matcher.Start().InsertAndAdvance(
new CodeInstruction(OpCodes.Ldarg_0),
new CodeInstruction(OpCodes.Ldarg_1),
new CodeInstruction(OpCodes.Call, AccessTools.Method(typeof(QuickAbsortPatch), nameof(QuickAbsortPatch.DoAbsorb)))
).MatchForward(false,
new CodeMatch(OpCodes.Ldarg_0),
new CodeMatch(OpCodes.Ldfld, AccessTools.Field(typeof(DysonSphereLayer), nameof(DysonSphereLayer.dysonSphere))),
new CodeMatch(OpCodes.Ldfld, AccessTools.Field(typeof(DysonSphere), nameof(DysonSphere.swarm)))
).Insert(new CodeInstruction(OpCodes.Ret));
return matcher.InstructionEnumeration();
}
private static void DoAbsorb(DysonSphereLayer layer, long gameTick)
{
var swarm = layer.dysonSphere.swarm;
for (var i = layer.nodeCursor - 1; i > 0; i--)
{
var node = layer.nodePool[i];
if (node != null && node.id == i && node.sp == node.spMax)
{
node.OrderConstructCp(gameTick, swarm);
}
}
}
}
private static class EjectAnywayPatch