Skip to content

Commit d61defa

Browse files
authored
Merge pull request #721 from starfi5h/pr-update
Nebula 0.9.13 for DSP 0.10.32.25552 Update
2 parents 1da704e + f177ce1 commit d61defa

21 files changed

+474
-64
lines changed

.github/scripts/thunderstore_bundle.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -117,13 +117,13 @@ function generateManifest() {
117117
const manifest = {
118118
name: pluginInfo.name,
119119
description:
120-
"With this mod you will be able to play with your friends in the same game! Now supports combat mode in game version 0.10.30",
120+
"With this mod you will be able to play with your friends in the same game! Now supports combat mode in game version 0.10.32",
121121
version_number: pluginInfo.version,
122122
dependencies: [
123123
BEPINEX_DEPENDENCY,
124124
`nebula-${apiPluginInfo.name}-${apiPluginInfo.version}`,
125125
"PhantomGamers-IlLine-1.0.0",
126-
"starfi5h-BulletTime-1.5.1",
126+
"starfi5h-BulletTime-1.5.3",
127127
],
128128
website_url: "https://github.com/hubastard/nebula"
129129
};

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
## Changelog
22

3+
0.9.13:
4+
- Compatible with game version 0.10.32.25552
5+
- @starfi5h: Sync ejector auto orbit and blueprint paste foundation
6+
- @starfi5h: Force enable drone and shield brust for client
7+
- Note: The dashboard is not synced. Clients will lose their custom stats when they leave the star system
8+
39
0.9.12:
410
- Compatible with game version 0.10.31.24697
511
- @starfi5h: Client can now use metadata to unlock tech. Sandbox unlock by client is now synced
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
namespace NebulaModel.Packets.Factory.Ejector;
2+
3+
public class EjectorAutoOrbitUpdatePacket
4+
{
5+
public EjectorAutoOrbitUpdatePacket() { }
6+
7+
public EjectorAutoOrbitUpdatePacket(int ejectorIndex, bool autoOrbit, int planetId)
8+
{
9+
EjectorIndex = ejectorIndex;
10+
AutoOrbit = autoOrbit;
11+
PlanetId = planetId;
12+
}
13+
14+
public int EjectorIndex { get; set; }
15+
public bool AutoOrbit { get; set; }
16+
public int PlanetId { get; set; }
17+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
using System.Collections.Generic;
2+
3+
namespace NebulaModel.Packets.Factory.Foundation;
4+
5+
public class FoundationBlueprintPastePacket
6+
{
7+
public FoundationBlueprintPastePacket() { }
8+
9+
public FoundationBlueprintPastePacket(int planetId, Dictionary<int, byte> reformGridIds,
10+
Dictionary<int, int> levelChanges, int reformType, int reformColor)
11+
{
12+
PlanetId = planetId;
13+
ReformGridIds = reformGridIds;
14+
LevelChanges = levelChanges;
15+
ReformType = reformType;
16+
ReformColor = reformColor;
17+
}
18+
19+
public int PlanetId { get; set; }
20+
public Dictionary<int, byte> ReformGridIds { get; set; }
21+
public Dictionary<int, int> LevelChanges { get; set; }
22+
public int ReformType { get; set; }
23+
public int ReformColor { get; set; }
24+
}

NebulaNetwork/PacketProcessors/Factory/Belt/BeltSignalIconProcessor.cs

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,9 @@ protected override void ProcessPacket(BeltSignalIconPacket packet, NebulaConnect
1717
{
1818
using (Multiplayer.Session.Factories.IsIncomingRequest.On())
1919
{
20-
var cargoTraffic = GameMain.galaxy.PlanetById(packet.PlanetId)?.factory?.cargoTraffic;
21-
if (cargoTraffic == null)
22-
{
23-
return;
24-
}
25-
cargoTraffic.SetBeltSignalIcon(packet.EntityId, packet.SignalId);
20+
var factory = GameMain.galaxy.PlanetById(packet.PlanetId)?.factory;
21+
if (factory == null || packet.EntityId >= factory.entityCursor) return;
22+
factory.cargoTraffic.SetBeltSignalIcon(packet.EntityId, packet.SignalId);
2623
}
2724
}
2825
}

NebulaNetwork/PacketProcessors/Factory/Belt/BeltSignalNumberProcessor.cs

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,9 @@ protected override void ProcessPacket(BeltSignalNumberPacket packet, NebulaConne
1717
{
1818
using (Multiplayer.Session.Factories.IsIncomingRequest.On())
1919
{
20-
var cargoTraffic = GameMain.galaxy.PlanetById(packet.PlanetId)?.factory?.cargoTraffic;
21-
if (cargoTraffic == null)
22-
{
23-
return;
24-
}
25-
cargoTraffic.SetBeltSignalNumber(packet.EntityId, packet.Number);
20+
var factory = GameMain.galaxy.PlanetById(packet.PlanetId)?.factory;
21+
if (factory == null || packet.EntityId >= factory.entityCursor) return;
22+
factory.cargoTraffic.SetBeltSignalNumber(packet.EntityId, packet.Number);
2623
}
2724
}
2825
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
#region
2+
3+
using NebulaAPI.Packets;
4+
using NebulaModel.Networking;
5+
using NebulaModel.Packets;
6+
using NebulaModel.Packets.Factory.Ejector;
7+
8+
#endregion
9+
10+
namespace NebulaNetwork.PacketProcessors.Factory.Ejector;
11+
12+
[RegisterPacketProcessor]
13+
internal class EjectorAutoOrbitUpdateProcessor : PacketProcessor<EjectorAutoOrbitUpdatePacket>
14+
{
15+
protected override void ProcessPacket(EjectorAutoOrbitUpdatePacket packet, NebulaConnection conn)
16+
{
17+
var ejectorPool = GameMain.galaxy.PlanetById(packet.PlanetId)?.factory?.factorySystem?.ejectorPool;
18+
if (ejectorPool == null) return;
19+
20+
if (packet.EjectorIndex == -1) // Set whole planet ejector event
21+
{
22+
for (var i = 1; i < ejectorPool.Length; i++)
23+
{
24+
if (ejectorPool[i].id == i) ejectorPool[i].autoOrbit = packet.AutoOrbit;
25+
}
26+
}
27+
else if (packet.EjectorIndex > 0 && packet.EjectorIndex < ejectorPool.Length)
28+
{
29+
ejectorPool[packet.EjectorIndex].autoOrbit = packet.AutoOrbit;
30+
}
31+
}
32+
}
Lines changed: 212 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,212 @@
1+
#region
2+
3+
using System.Collections.Generic;
4+
using NebulaAPI;
5+
using NebulaAPI.Packets;
6+
using NebulaModel.Networking;
7+
using NebulaModel.Packets;
8+
using NebulaModel.Packets.Factory.Foundation;
9+
using NebulaWorld;
10+
using UnityEngine;
11+
#pragma warning disable IDE0007 // Use implicit type
12+
13+
#endregion
14+
15+
namespace NebulaNetwork.PacketProcessors.Factory.Foundation;
16+
17+
[RegisterPacketProcessor]
18+
internal class FoundationBlueprintPasteProcessor : PacketProcessor<FoundationBlueprintPastePacket>
19+
{
20+
protected override void ProcessPacket(FoundationBlueprintPastePacket packet, NebulaConnection conn)
21+
{
22+
var planet = GameMain.galaxy.PlanetById(packet.PlanetId);
23+
var factory = planet?.factory;
24+
if (factory == null) return;
25+
26+
using (Multiplayer.Session.Planets.IsIncomingRequest.On())
27+
{
28+
Multiplayer.Session.Factories.TargetPlanet = packet.PlanetId;
29+
Multiplayer.Session.Factories.AddPlanetTimer(packet.PlanetId);
30+
var specifyPlanet = GameMain.gpuiManager.specifyPlanet;
31+
GameMain.gpuiManager.specifyPlanet = planet;
32+
33+
// Split BuildTool_BlueprintPaste.DetermineReforms into following functions
34+
SetReform(factory, packet.ReformGridIds, packet.ReformType, packet.ReformColor);
35+
AlterHeightMap(planet, packet.LevelChanges);
36+
RemoveVeges(factory, packet.LevelChanges);
37+
UpdateGeothermalStrength(factory);
38+
AlterVeinModels(factory);
39+
40+
GameMain.gpuiManager.specifyPlanet = specifyPlanet;
41+
Multiplayer.Session.Factories.TargetPlanet = NebulaModAPI.PLANET_NONE;
42+
}
43+
}
44+
45+
static void SetReform(PlanetFactory factory, Dictionary<int, byte> reformGridIds, int brushType, int brushColor)
46+
{
47+
PlatformSystem platformSystem = factory.platformSystem;
48+
platformSystem.EnsureReformData();
49+
50+
foreach (int key in reformGridIds.Keys)
51+
{
52+
int reformIndex = factory.platformSystem.GetReformIndex(key >> 16, key & 65535);
53+
byte reformData = reformGridIds[key];
54+
int num17 = reformData >> 5;
55+
int num18 = (reformData & 3);
56+
if (reformIndex >= 0)
57+
{
58+
int reformType = platformSystem.GetReformType(reformIndex);
59+
int reformColor = platformSystem.GetReformColor(reformIndex);
60+
if (reformType != ((num17 == 0) ? brushType : num17) || reformColor != ((num18 == 0) ? brushColor : num18))
61+
{
62+
factory.platformSystem.SetReformType(reformIndex, brushType);
63+
factory.platformSystem.SetReformColor(reformIndex, brushColor);
64+
}
65+
}
66+
}
67+
}
68+
static void AlterHeightMap(PlanetData planet, Dictionary<int, int> heightLevelChanges)
69+
{
70+
PlanetRawData planetRawData = planet.data;
71+
bool isPlanetLevelized = planet.levelized;
72+
73+
// Calculate the maximum height threshold for terrain modifications
74+
int heightThreshold = (int)(planet.realRadius * 100f + 20f) - 60;
75+
76+
ushort[] heightMap = planetRawData.heightData;
77+
78+
foreach (KeyValuePair<int, int> heightChange in heightLevelChanges)
79+
{
80+
if (heightChange.Value > 0)
81+
{
82+
if (isPlanetLevelized)
83+
{
84+
if (heightMap[heightChange.Key] >= heightThreshold)
85+
{
86+
if (planetRawData.GetModLevel(heightChange.Key) < 3)
87+
{
88+
planetRawData.SetModPlane(heightChange.Key, 0);
89+
}
90+
planet.AddHeightMapModLevel(heightChange.Key, heightChange.Value);
91+
}
92+
}
93+
else
94+
{
95+
planet.AddHeightMapModLevel(heightChange.Key, heightChange.Value);
96+
}
97+
}
98+
}
99+
100+
bool meshesUpdated = planet.UpdateDirtyMeshes();
101+
if (GameMain.isRunning && meshesUpdated && planet == GameMain.localPlanet)
102+
{
103+
planet.factory?.RenderLocalPlanetHeightmap();
104+
}
105+
}
106+
107+
static void RemoveVeges(PlanetFactory planetFactory, Dictionary<int, int> heightLevelChanges)
108+
{
109+
PlanetRawData planetRawData = planetFactory.planet.data;
110+
VegeData[] vegePool = planetFactory.vegePool;
111+
int vegeCursor = planetFactory.vegeCursor;
112+
113+
for (int vegetationIndex = 1; vegetationIndex < vegeCursor; vegetationIndex++)
114+
{
115+
if (vegePool[vegetationIndex].id != 0)
116+
{
117+
int terrainIndex = planetRawData.QueryIndex(vegePool[vegetationIndex].pos);
118+
if (heightLevelChanges.TryGetValue(terrainIndex, out int modificationLevel) && modificationLevel >= 3)
119+
{
120+
planetFactory.RemoveVegeWithComponents(vegetationIndex);
121+
}
122+
}
123+
}
124+
}
125+
126+
static void UpdateGeothermalStrength(PlanetFactory factory)
127+
{
128+
if (factory.planet.waterItemId != -1) return;
129+
130+
PowerSystem powerSystem = factory.powerSystem;
131+
PowerGeneratorComponent[] generatorPool = powerSystem.genPool;
132+
int generatorCount = powerSystem.genCursor;
133+
EntityData[] entityPool = factory.entityPool;
134+
135+
for (int generatorIndex = 1; generatorIndex < generatorCount; generatorIndex++)
136+
{
137+
ref PowerGeneratorComponent generator = ref generatorPool[generatorIndex];
138+
if (generator.id == generatorIndex && generator.geothermal && generator.entityId > 0)
139+
{
140+
generator.gthStrength = powerSystem.CalculateGeothermalStrenth(
141+
entityPool[generator.entityId].pos,
142+
entityPool[generator.entityId].rot,
143+
generator.baseRuinId
144+
);
145+
}
146+
}
147+
}
148+
149+
static void AlterVeinModels(PlanetFactory factory)
150+
{
151+
PlanetData planet = factory.planet;
152+
PlanetRawData data = planet.data;
153+
154+
VeinData[] veinPool = factory.veinPool;
155+
int veinCursor = factory.veinCursor;
156+
float veinSurfaceThreshold = planet.realRadius - 50f + 5f;
157+
PlanetPhysics physics = planet.physics;
158+
for (int veinId = 1; veinId < veinCursor; veinId++)
159+
{
160+
ref VeinData veinPtr = ref veinPool[veinId];
161+
if (veinPtr.id == veinId)
162+
{
163+
Vector3 pos = veinPtr.pos;
164+
float magnitude = pos.magnitude;
165+
if (magnitude >= veinSurfaceThreshold)
166+
{
167+
float veinHeight = data.QueryModifiedHeight(pos) - 0.13f;
168+
int colliderId = veinPtr.colliderId;
169+
Vector3 vector = physics.GetColliderData(colliderId).pos.normalized * (veinHeight + 0.4f);
170+
int chunkId = colliderId >> 20;
171+
colliderId &= 1048575;
172+
physics.colChunks[chunkId].colliderPool[colliderId].pos = vector;
173+
Vector3 vectorNormal = pos / magnitude;
174+
veinPtr.pos = vectorNormal * veinHeight;
175+
physics.SetPlanetPhysicsColliderDirty();
176+
if (Mathf.Abs(magnitude - veinSurfaceThreshold) > 0.1f)
177+
{
178+
Quaternion quaternion = Maths.SphericalRotation(pos, Random.value * 360f);
179+
GameMain.gpuiManager.AlterModel(veinPtr.modelIndex, veinPtr.modelId, veinId, pos, quaternion, false);
180+
}
181+
else
182+
{
183+
GameMain.gpuiManager.AlterModel(veinPtr.modelIndex, veinPtr.modelId, veinId, pos, false);
184+
}
185+
VeinProto veinProto = LDB.veins.Select((int)veinPool[veinId].type);
186+
if (veinProto != null)
187+
{
188+
if (veinPool[veinId].minerId0 > 0)
189+
{
190+
GameMain.gpuiManager.AlterModel(veinProto.MinerBaseModelIndex, veinPtr.minerBaseModelId, veinPtr.minerId0, vectorNormal * (veinHeight + 0.1f), false);
191+
GameMain.gpuiManager.AlterModel(veinProto.MinerCircleModelIndex, veinPtr.minerCircleModelId0, veinPtr.minerId0, vectorNormal * (veinHeight + 0.4f), false);
192+
}
193+
if (veinPool[veinId].minerId1 > 0)
194+
{
195+
GameMain.gpuiManager.AlterModel(veinProto.MinerCircleModelIndex, veinPtr.minerCircleModelId1, veinPtr.minerId1, vectorNormal * (veinHeight + 0.6f), false);
196+
}
197+
if (veinPool[veinId].minerId2 > 0)
198+
{
199+
GameMain.gpuiManager.AlterModel(veinProto.MinerCircleModelIndex, veinPtr.minerCircleModelId2, veinPtr.minerId2, vectorNormal * (veinHeight + 0.8f), false);
200+
}
201+
if (veinPool[veinId].minerId3 > 0)
202+
{
203+
GameMain.gpuiManager.AlterModel(veinProto.MinerCircleModelIndex, veinPtr.minerCircleModelId3, veinPtr.minerId3, vectorNormal * (veinHeight + 1f), false);
204+
}
205+
}
206+
}
207+
}
208+
}
209+
}
210+
211+
212+
}

NebulaNetwork/PacketProcessors/Factory/Foundation/FoundationBuildUpdateProcessor.cs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,18 +45,20 @@ protected override void ProcessPacket(FoundationBuildUpdatePacket packet, Nebula
4545
//Perform terrain operation
4646
var center = packet.ExtraCenter.ToVector3();
4747
var area = packet.CirclePointCount;
48+
var costSandCount = 0; // dummy value, won't use
49+
var getSandCount = 0; // dummy value, won't use
4850
if (!packet.IsCircle) //Normal reform
4951
{
5052
var reformPointsCount = factory.planet.aux.ReformSnap(packet.GroundTestPos.ToVector3(), packet.ReformSize,
5153
packet.ReformType, packet.ReformColor, reformPoints, packet.ReformIndices, factory.platformSystem,
5254
out var reformCenterPoint);
53-
factory.ComputeFlattenTerrainReform(reformPoints, reformCenterPoint, packet.Radius, reformPointsCount);
55+
factory.ComputeFlattenTerrainReform(reformPoints, reformCenterPoint, packet.Radius, reformPointsCount, ref costSandCount, ref getSandCount);
5456
center = reformCenterPoint;
5557
area = packet.ReformSize * packet.ReformSize;
5658
}
5759
else //Remove pit
5860
{
59-
factory.ComputeFlattenTerrainReform(reformPoints, center, packet.Radius, packet.CirclePointCount, 3f, 1f);
61+
factory.ComputeFlattenTerrainReform(reformPoints, center, packet.Radius, packet.CirclePointCount, ref costSandCount, ref getSandCount, 3f, 1f);
6062
}
6163
using (Multiplayer.Session.Factories.IsIncomingRequest.On())
6264
{

NebulaPatcher/Patches/Dynamic/CargoTraffic_Patch.cs

Lines changed: 0 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -122,27 +122,4 @@ public static void ConnectToSpraycoater(int spraycoaterId, int cargoBeltId, int
122122
incBeltId, GameMain.data.localPlanet.id));
123123
}
124124
}
125-
126-
[HarmonyPostfix]
127-
[HarmonyPatch(nameof(CargoTraffic.SetBeltSignalIcon))]
128-
public static void SetBeltSignalIcon_Postfix(int entityId, int signalId)
129-
{
130-
// Notify others about belt memo icon changes
131-
if (Multiplayer.IsActive && !Multiplayer.Session.Factories.IsIncomingRequest.Value)
132-
{
133-
Multiplayer.Session.Network.SendPacketToLocalStar(new BeltSignalIconPacket(entityId, signalId,
134-
GameMain.data.localPlanet.id));
135-
}
136-
}
137-
138-
[HarmonyPostfix]
139-
[HarmonyPatch(nameof(CargoTraffic.SetBeltSignalNumber))]
140-
public static void SetBeltSignalNumber_Postfix(int entityId, float number)
141-
{
142-
if (Multiplayer.IsActive && !Multiplayer.Session.Factories.IsIncomingRequest.Value)
143-
{
144-
Multiplayer.Session.Network.SendPacketToLocalStar(new BeltSignalNumberPacket(entityId, number,
145-
GameMain.data.localPlanet.id));
146-
}
147-
}
148125
}

0 commit comments

Comments
 (0)