|
| 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 | +} |
0 commit comments