diff --git a/NebulaModel/Packets/Combat/GroundEnemy/DFGRemoveBasePacket.cs b/NebulaModel/Packets/Combat/GroundEnemy/DFGRemoveBasePacket.cs new file mode 100644 index 000000000..a839f4ee0 --- /dev/null +++ b/NebulaModel/Packets/Combat/GroundEnemy/DFGRemoveBasePacket.cs @@ -0,0 +1,15 @@ +namespace NebulaModel.Packets.Combat.GroundEnemy; + +public class DFGRemoveBasePacket +{ + public DFGRemoveBasePacket() { } + + public DFGRemoveBasePacket(int planetId, int baseId) + { + PlanetId = planetId; + BaseId = baseId; + } + + public int PlanetId { get; set; } + public int BaseId { get; set; } +} diff --git a/NebulaNetwork/PacketProcessors/Combat/GroundEnemy/DFGActivateBaseProcessor.cs b/NebulaNetwork/PacketProcessors/Combat/GroundEnemy/DFGActivateBaseProcessor.cs index fdf52527d..b8b00ae19 100644 --- a/NebulaNetwork/PacketProcessors/Combat/GroundEnemy/DFGActivateBaseProcessor.cs +++ b/NebulaNetwork/PacketProcessors/Combat/GroundEnemy/DFGActivateBaseProcessor.cs @@ -1,6 +1,5 @@ #region -using NebulaAPI.DataStructures; using NebulaAPI.Packets; using NebulaModel.Networking; using NebulaModel.Packets; @@ -27,6 +26,7 @@ protected override void ProcessPacket(DFGActivateBasePacket packet, NebulaConnec if (!packet.SetToSeekForm) { var dFBase = factory.enemySystem.bases.buffer[packet.BaseId]; + if (dFBase == null) return; dFBase.activeTick = 3; using (Multiplayer.Session.Combat.IsIncomingRequest.On()) { diff --git a/NebulaNetwork/PacketProcessors/Combat/GroundEnemy/DFGActivateUnitProcessor.cs b/NebulaNetwork/PacketProcessors/Combat/GroundEnemy/DFGActivateUnitProcessor.cs index 7c7f48e72..a7f3e3331 100644 --- a/NebulaNetwork/PacketProcessors/Combat/GroundEnemy/DFGActivateUnitProcessor.cs +++ b/NebulaNetwork/PacketProcessors/Combat/GroundEnemy/DFGActivateUnitProcessor.cs @@ -24,6 +24,7 @@ protected override void ProcessPacket(DFGActivateUnitPacket packet, NebulaConnec { EnemyManager.SetPlanetFactoryNextEnemyId(factory, packet.EnemyId); var dfBase = factory.enemySystem.bases.buffer[packet.BaseId]; + if (dfBase == null) return; var gameTick = GameMain.gameTick; // the value inside enemyFormation.units[portId] is not reliable, so just overwrite it diff --git a/NebulaNetwork/PacketProcessors/Combat/GroundEnemy/DFGDeferredCreateEnemyProcessor.cs b/NebulaNetwork/PacketProcessors/Combat/GroundEnemy/DFGDeferredCreateEnemyProcessor.cs index dad2aecf7..6dde93ef2 100644 --- a/NebulaNetwork/PacketProcessors/Combat/GroundEnemy/DFGDeferredCreateEnemyProcessor.cs +++ b/NebulaNetwork/PacketProcessors/Combat/GroundEnemy/DFGDeferredCreateEnemyProcessor.cs @@ -23,6 +23,7 @@ protected override void ProcessPacket(DFGDeferredCreateEnemyPacket packet, Nebul using (Multiplayer.Session.Combat.IsIncomingRequest.On()) { EnemyManager.SetPlanetFactoryNextEnemyId(factory, packet.EnemyId); + if (factory.enemySystem.bases.buffer[packet.BaseId] == null) return; var enemyId = factory.CreateEnemyFinal(packet.BaseId, packet.BuilderIndex); #if DEBUG diff --git a/NebulaNetwork/PacketProcessors/Combat/GroundEnemy/DFGFormationAddUnitProcessor.cs b/NebulaNetwork/PacketProcessors/Combat/GroundEnemy/DFGFormationAddUnitProcessor.cs index 1d342b8b7..5b929d094 100644 --- a/NebulaNetwork/PacketProcessors/Combat/GroundEnemy/DFGFormationAddUnitProcessor.cs +++ b/NebulaNetwork/PacketProcessors/Combat/GroundEnemy/DFGFormationAddUnitProcessor.cs @@ -5,7 +5,6 @@ using NebulaModel.Packets; using NebulaModel.Packets.Combat.GroundEnemy; using NebulaWorld; -using static UnityEngine.UI.CanvasScaler; #endregion @@ -20,6 +19,7 @@ protected override void ProcessPacket(DFGFormationAddUnitPacket packet, NebulaCo if (factory == null) return; var dFBase = factory.enemySystem.bases.buffer[packet.BaseId]; + if (dFBase == null) return; using (Multiplayer.Session.Combat.IsIncomingRequest.On()) { // Set the next id in EnemyFormation diff --git a/NebulaNetwork/PacketProcessors/Combat/GroundEnemy/DFGLaunchAssaultProcessor.cs b/NebulaNetwork/PacketProcessors/Combat/GroundEnemy/DFGLaunchAssaultProcessor.cs index f40a5062a..59bce266f 100644 --- a/NebulaNetwork/PacketProcessors/Combat/GroundEnemy/DFGLaunchAssaultProcessor.cs +++ b/NebulaNetwork/PacketProcessors/Combat/GroundEnemy/DFGLaunchAssaultProcessor.cs @@ -1,6 +1,5 @@ #region -using System; using NebulaAPI.DataStructures; using NebulaAPI.Packets; using NebulaModel.Networking; @@ -32,6 +31,7 @@ protected override void ProcessPacket(DFGLaunchAssaultPacket packet, NebulaConne EnemyManager.SetPlanetFactoryRecycle(factory, packet.EnemyCursor, packet.EnemyRecyle); var dFBase = factory.enemySystem.bases.buffer[packet.BaseId]; + if (dFBase == null) return; dFBase.turboTicks = 60; dFBase.turboRepress = 0; dFBase.evolve.threat = packet.EvolveThreat; diff --git a/NebulaNetwork/PacketProcessors/Combat/GroundEnemy/DFGRemoveBaseProcessor.cs b/NebulaNetwork/PacketProcessors/Combat/GroundEnemy/DFGRemoveBaseProcessor.cs new file mode 100644 index 000000000..09bded370 --- /dev/null +++ b/NebulaNetwork/PacketProcessors/Combat/GroundEnemy/DFGRemoveBaseProcessor.cs @@ -0,0 +1,27 @@ +#region + +using NebulaAPI.Packets; +using NebulaModel.Networking; +using NebulaModel.Packets; +using NebulaModel.Packets.Combat.GroundEnemy; +using NebulaWorld; + +#endregion + +namespace NebulaNetwork.PacketProcessors.Combat.GroundEnemy; + +[RegisterPacketProcessor] +public class DFGRemoveBaseProcessor : PacketProcessor +{ + protected override void ProcessPacket(DFGRemoveBasePacket packet, NebulaConnection conn) + { + var factory = GameMain.galaxy.PlanetById(packet.PlanetId)?.factory; + if (IsHost || factory == null) return; + + using (Multiplayer.Session.Combat.IsIncomingRequest.On()) + { + // EnemyDFGroundSystem.bases.SetNull(id); + factory.enemySystem.RemoveDFGBaseComponent(packet.BaseId); + } + } +} diff --git a/NebulaPatcher/Patches/Dynamic/EnemyDFGroundSystem_Patch.cs b/NebulaPatcher/Patches/Dynamic/EnemyDFGroundSystem_Patch.cs index 354983b6c..7ab0973ba 100644 --- a/NebulaPatcher/Patches/Dynamic/EnemyDFGroundSystem_Patch.cs +++ b/NebulaPatcher/Patches/Dynamic/EnemyDFGroundSystem_Patch.cs @@ -137,6 +137,23 @@ public static bool RemoveBasePit_Prefix(EnemyDFGroundSystem __instance, int pitR return false; } + [HarmonyPrefix] + [HarmonyPatch(nameof(EnemyDFGroundSystem.RemoveDFGBaseComponent))] + public static bool RemoveDFGBaseComponent_Prefix(EnemyDFGroundSystem __instance, int id) + { + if (!Multiplayer.IsActive) return true; + + if (Multiplayer.Session.IsServer) + { + var packet = new DFGRemoveBasePacket(__instance.factory.planetId, id); + Multiplayer.Session.Network.SendPacketToStar(packet, __instance.factory.planet.star.id); + return true; + } + + // Client should wait for server to approve the removal of base from the base buffer + return Multiplayer.Session.Combat.IsIncomingRequest; + } + [HarmonyPrefix] [HarmonyPatch(nameof(EnemyDFGroundSystem.GameTickLogic))] public static void GameTickLogic_Prefix(EnemyDFGroundSystem __instance, long gameTick)