1
0
mirror of https://github.com/soarqin/DSP_Mods.git synced 2025-12-09 00:13:36 +08:00

use predefined 60 points for illegal shell generation

This commit is contained in:
2025-06-30 00:40:26 +08:00
parent f58bd869fe
commit b093a62e36
2 changed files with 94 additions and 98 deletions

View File

@@ -19,6 +19,7 @@ public static class DysonSphereFunctions
{
I18N.Add("You are not in any system.", "You are not in any system.", "你不在任何星系中");
I18N.Add("There is no Dyson Sphere shell on \"{0}\".", "There is no Dyson Sphere shell on \"{0}\".", "“{0}”上没有可建造的戴森壳");
I18N.Add("There is no Dyson Sphere data on \"{0}\".", "There is no Dyson Sphere data on \"{0}\".", "“{0}”上没有戴森球数据");
I18N.Add("This will complete all Dyson Sphere shells on \"{0}\" instantly. Are you sure?", "This will complete all Dyson Sphere shells on \"{0}\" instantly. Are you sure?", "这将立即完成“{0}”上的所有戴森壳。你确定吗?");
}
@@ -249,18 +250,17 @@ public static class DysonSphereFunctions
}
private static readonly ThreadLocal<Dictionary<int, Vector3>> _vmap = new(() => new(16384));
private static int CalculateTriangleVertCount(DysonNode[] nodes)
private static int CalculateTriangleVertCount(VectorLF3[] polygon)
{
if (nodes.Length != 3) return -1;
VectorLF3[] polygon = [.. nodes.Select(node => node.pos)];
if (polygon.Length != 3) return -1;
VectorLF3 sum = VectorLF3.zero;
double num = 0.0;
for (int i = 0; i < 3; i++)
{
var nodeA = nodes[i];
var nodeB = nodes[(i + 1) % 3];
float num2 = Vector3.Distance(nodeA.pos, nodeB.pos);
VectorLF3 vectorLF2 = (VectorLF3)(nodeA.pos + nodeB.pos) * 0.5;
var nodeApos = polygon[i];
var nodeBpos = polygon[(i + 1) % 3];
float num2 = Vector3.Distance(nodeApos, nodeBpos);
VectorLF3 vectorLF2 = (VectorLF3)(nodeApos + nodeBpos) * 0.5;
sum += vectorLF2 * (double)num2;
num += (double)num2;
}
@@ -1111,7 +1111,7 @@ public static class DysonSphereFunctions
dysonSphere.modelRenderer.RebuildModels();
}
public static void CreatePossibleFramesAndShells()
public static void CreateIllegalDysonShellWithMaxOutput()
{
StarData star = null;
var dysonEditor = UIRoot.instance?.uiGame?.dysonEditor;
@@ -1128,10 +1128,11 @@ public static class DysonSphereFunctions
return;
}
}
UXAssist.Functions.DysonSphereFunctions.InitCurrentDysonLayer(star, 0);
var dysonSphere = GameMain.data?.dysonSpheres[star.index];
if (dysonSphere == null || dysonSphere.layerCount == 0)
if (dysonSphere == null)
{
UIMessageBox.Show("CheatEnabler".Translate(), string.Format("There is no Dyson Sphere shell on \"{0}\".".Translate(), star.displayName), "确定".Translate(), UIMessageBox.ERROR, null);
UIMessageBox.Show("CheatEnabler".Translate(), string.Format("There is no Dyson Sphere data on \"{0}\".".Translate(), star.displayName), "确定".Translate(), UIMessageBox.ERROR, null);
return;
}
DysonShell.s_vmap ??= new Dictionary<int, Vector3>(16384);
@@ -1139,97 +1140,92 @@ public static class DysonSphereFunctions
DysonShell.s_ivmap ??= new Dictionary<int, int>(16384);
var shellsChanged = false;
var mutex = new object();
for (var i = 1; i < dysonSphere.layersIdBased.Length; i++)
Dictionary<(int, int), int> availableFrames = [];
HashSet<int> unusedFrameIds = [];
var layer = dysonSphere.layersIdBased[1];
if (layer != null)
{
Dictionary<(int, int), int> availableFrames = [];
HashSet<int> unusedFrameIds = [];
var layer = dysonSphere.layersIdBased[i];
if (layer == null || layer.id != i) continue;
int nodeCount = layer.nodeCursor;
dysonSphere.RemoveLayer(1);
}
layer = dysonSphere.AddLayerOnId(1, dysonSphere.maxOrbitRadius, Quaternion.Euler(0f, 0f, 0f), Mathf.Sqrt(dysonSphere.gravity / dysonSphere.maxOrbitRadius) / dysonSphere.maxOrbitRadius * 57.2957802f);
if (layer == null) return;
List<SupposedShell> supposedShells = [];
int j;
for (j = 1; j < nodeCount; j++)
var supposedShells = new List<SupposedShell>(60 * 59 * 58);
VectorLF3[] nodePos = new VectorLF3[60];
for (var i = 0; i < 60; i++)
{
nodePos[i] = new VectorLF3(Math.Sin(Math.PI * 2 * i / 60), 0, Math.Cos(Math.PI * 2 * i / 60)) * layer.orbitRadius;
}
for (var i = 0; i < 58; i++)
{
for (var j = i + 1; j < 59; j++)
{
var nodeA = layer.nodePool[j];
if (nodeA == null || nodeA.id != j) continue;
for (var k = j + 1; k < nodeCount; k++)
for (var k = j + 1; k < 60; k++)
{
var nodeB = layer.nodePool[k];
if (nodeB == null || nodeB.id != k) continue;
for (var l = k + 1; l < nodeCount; l++)
{
var nodeC = layer.nodePool[l];
if (nodeC == null || nodeC.id != l) continue;
var area = Vector3.Cross(nodeB.pos - nodeA.pos, nodeC.pos - nodeA.pos).sqrMagnitude;
supposedShells.Add(new SupposedShell { nodeA = nodeA, nodeB = nodeB, nodeC = nodeC, area = area });
}
var area = Vector3.Cross(nodePos[j] - nodePos[i], nodePos[k] - nodePos[i]).sqrMagnitude;
supposedShells.Add(new SupposedShell { posA = nodePos[i], posB = nodePos[j], posC = nodePos[k], area = area });
}
}
supposedShells.Sort((a, b) => b.area.CompareTo(a.area));
CheatEnabler.Logger.LogDebug($"Finished Area Sort");
var maxVertCount = -1;
var maxJ = -1;
var options = new ParallelOptions { MaxDegreeOfParallelism = Environment.ProcessorCount - 1 };
Parallel.For(0, supposedShells.Count, options, (j, loopState) =>
{
var sshell = supposedShells[j];
var vertCount = CalculateTriangleVertCount([sshell.nodeA, sshell.nodeB, sshell.nodeC]);
if (vertCount < 32768)
{
lock (mutex)
{
if (loopState.ShouldExitCurrentIteration) return;
if (vertCount > maxVertCount)
{
maxVertCount = vertCount;
maxJ = j;
if (maxVertCount >= 32000)
{
CheatEnabler.Logger.LogDebug($"!!STOP!! Triangle {j}[{sshell.nodeA.pos:F2} {sshell.nodeB.pos:F2} {sshell.nodeC.pos:F2}] has {vertCount} vertices");
loopState.Stop();
return;
}
CheatEnabler.Logger.LogDebug($"Triangle {j}[{sshell.nodeA.pos:F2} {sshell.nodeB.pos:F2} {sshell.nodeC.pos:F2}] has {vertCount} vertices");
}
}
}
});
if (maxJ >= 0)
{
foreach (var node in layer.nodePool)
{
if (node == null || node.id != j) continue;
dysonSphere.RemoveDysonNodeRData(node);
}
layer.nodePool = new DysonNode[64];
layer.nodeRecycle = new int[64];
layer.nodeRecycleCursor = 0;
layer.nodeCapacity = 64;
layer.nodeCursor = 1;
layer.framePool = new DysonFrame[64];
layer.frameRecycle = new int[64];
layer.frameRecycleCursor = 0;
layer.frameCapacity = 64;
layer.frameCursor = 1;
layer.shellPool = new DysonShell[64];
layer.shellRecycle = new int[64];
layer.shellRecycleCursor = 0;
layer.shellCapacity = 64;
layer.shellCursor = 1;
var sshell = supposedShells[maxJ];
DysonNode[] newNodes = [layer.QuickAddDysonNode(0, sshell.nodeA.pos), layer.QuickAddDysonNode(0, sshell.nodeB.pos), layer.QuickAddDysonNode(0, sshell.nodeC.pos)];
DysonFrame[] newFrames = [layer.QuickAddDysonFrame(0, newNodes[0], newNodes[1], false), layer.QuickAddDysonFrame(0, newNodes[1], newNodes[2], false), layer.QuickAddDysonFrame(0, newNodes[2], newNodes[0], false)];
layer.QuickAddDysonShell(0, newNodes, newFrames, false);
foreach (var node in newNodes)
{
dysonSphere.AddDysonNodeRData(node, true);
node.RecalcSpReq();
node.RecalcCpReq();
}
shellsChanged = true;
}
}
supposedShells.Sort((a, b) => b.area.CompareTo(a.area));
CheatEnabler.Logger.LogDebug($"Finished Area Sort");
var maxVertCount = -1;
var maxJ = -1;
var options = new ParallelOptions { MaxDegreeOfParallelism = Environment.ProcessorCount - 1 };
Parallel.For(0, supposedShells.Count, options, (j, loopState) =>
{
var sshell = supposedShells[j];
var vertCount = CalculateTriangleVertCount([sshell.posA, sshell.posB, sshell.posC]);
if (vertCount < 32768)
{
lock (mutex)
{
if (loopState.ShouldExitCurrentIteration) return;
if (vertCount > maxVertCount)
{
maxVertCount = vertCount;
maxJ = j;
if (maxVertCount >= 32000)
{
CheatEnabler.Logger.LogDebug($"!!STOP!! Triangle {j}[{sshell.posA:F2} {sshell.posB:F2} {sshell.posC:F2}] has {vertCount} vertices");
loopState.Stop();
return;
}
CheatEnabler.Logger.LogDebug($"Triangle {j}[{sshell.posA:F2} {sshell.posB:F2} {sshell.posC:F2}] has {vertCount} vertices");
}
}
}
});
if (maxJ >= 0)
{
layer.nodePool = new DysonNode[64];
layer.nodeRecycle = new int[64];
layer.nodeRecycleCursor = 0;
layer.nodeCapacity = 64;
layer.nodeCursor = 1;
layer.framePool = new DysonFrame[64];
layer.frameRecycle = new int[64];
layer.frameRecycleCursor = 0;
layer.frameCapacity = 64;
layer.frameCursor = 1;
layer.shellPool = new DysonShell[64];
layer.shellRecycle = new int[64];
layer.shellRecycleCursor = 0;
layer.shellCapacity = 64;
layer.shellCursor = 1;
var sshell = supposedShells[maxJ];
DysonNode[] newNodes = [layer.QuickAddDysonNode(0, sshell.posA), layer.QuickAddDysonNode(0, sshell.posB), layer.QuickAddDysonNode(0, sshell.posC)];
DysonFrame[] newFrames = [layer.QuickAddDysonFrame(0, newNodes[0], newNodes[1], false), layer.QuickAddDysonFrame(0, newNodes[1], newNodes[2], false), layer.QuickAddDysonFrame(0, newNodes[2], newNodes[0], false)];
layer.QuickAddDysonShell(0, newNodes, newFrames, false);
foreach (var node in newNodes)
{
dysonSphere.AddDysonNodeRData(node, true);
node.RecalcSpReq();
node.RecalcCpReq();
}
shellsChanged = true;
}
dysonSphere.CheckAutoNodes();
if (dysonSphere.autoNodeCount <= 0) dysonSphere.PickAutoNode();
dysonSphere.modelRenderer.RebuildModels();
@@ -1253,9 +1249,9 @@ public static class DysonSphereFunctions
private class SupposedShell
{
public DysonNode nodeA;
public DysonNode nodeB;
public DysonNode nodeC;
public VectorLF3 posA;
public VectorLF3 posB;
public VectorLF3 posC;
public float area;
}

View File

@@ -303,7 +303,7 @@ public static class UIConfigWindow
y += 72f;
var btn1 = wnd.AddButton(x, y, 300f, tab4, "Generate illegal dyson shell", 16, "button-generate-illegal-dyson-shells", () => {
UIMessageBox.Show("Generate illegal dyson shell".Translate(), "WARNING: This operation can be very slow, continue?".Translate(), "取消".Translate(), "确定".Translate(), UIMessageBox.WARNING, null,
() => { DysonSphereFunctions.CreatePossibleFramesAndShells(); });
() => { DysonSphereFunctions.CreateIllegalDysonShellWithMaxOutput(); });
});
y += 36f;
var btn2 = wnd.AddButton(x, y, 300f, tab4, "Keep max production shells and remove others", 16, "button-keep-max-production-shells", () => {