From 9118ddcca47cd83e353186a204f5eb1bf9ea67e3 Mon Sep 17 00:00:00 2001 From: InvalidArgument3 Date: Mon, 10 Jun 2024 06:17:06 -0500 Subject: [PATCH 1/4] half working serverside --- .../AsteroidEntities/AsteroidSpawner.cs | 76 +++++++++++-------- .../Scripts/DynamicAsteroids/MainSession.cs | 4 +- .../Invalid_copy to DS and client.bat | 31 ++++++++ 3 files changed, 80 insertions(+), 31 deletions(-) create mode 100644 Dynamic Asteroids/Invalid_copy to DS and client.bat diff --git a/Dynamic Asteroids/Data/Scripts/DynamicAsteroids/AsteroidEntities/AsteroidSpawner.cs b/Dynamic Asteroids/Data/Scripts/DynamicAsteroids/AsteroidEntities/AsteroidSpawner.cs index f5ddd35d..a1aa9efa 100644 --- a/Dynamic Asteroids/Data/Scripts/DynamicAsteroids/AsteroidEntities/AsteroidSpawner.cs +++ b/Dynamic Asteroids/Data/Scripts/DynamicAsteroids/AsteroidEntities/AsteroidSpawner.cs @@ -28,7 +28,7 @@ public void Close() return; Log.Info("Closing AsteroidSpawner"); - _asteroids.Clear(); + _asteroids?.Clear(); } public void UpdateTick() @@ -38,48 +38,63 @@ public void UpdateTick() try { - Vector3D playerPosition = MyAPIGateway.Session?.Player?.GetPosition() ?? Vector3D.MaxValue; + //Log.Info("UpdateTick called in AsteroidSpawner"); - if (playerPosition == Vector3D.MaxValue || !AsteroidSettings.PlayerCanSeeRings(playerPosition)) - return; + // Get all players on the server + List players = new List(); + MyAPIGateway.Players.GetPlayers(players); - foreach (var asteroid in _asteroids.ToArray()) + foreach (var player in players) { - if (Vector3D.DistanceSquared(asteroid.PositionComp.GetPosition(), playerPosition) > - AsteroidSettings.AsteroidSpawnRadius * AsteroidSettings.AsteroidSpawnRadius * 1.1) + Vector3D playerPosition = player.GetPosition(); + //Log.Info($"Player {player.DisplayName} position: {playerPosition}"); + + if (!AsteroidSettings.PlayerCanSeeRings(playerPosition)) { - _asteroids.Remove(asteroid); - asteroid.Close(); + // Log.Info("Player cannot see rings"); continue; } - } - int asteroidsSpawned = 0; - while (_asteroids.Count < AsteroidSettings.MaxAsteroidCount && asteroidsSpawned < 10) - { - Vector3D newPosition = playerPosition + RandVector() * AsteroidSettings.AsteroidSpawnRadius; - Vector3D newVelocity; - if (!AsteroidSettings.CanSpawnAsteroidAtPoint(newPosition, out newVelocity)) - continue; + foreach (var asteroid in _asteroids.ToArray()) + { + if (Vector3D.DistanceSquared(asteroid.PositionComp.GetPosition(), playerPosition) > + AsteroidSettings.AsteroidSpawnRadius * AsteroidSettings.AsteroidSpawnRadius * 1.1) + { + Log.Info($"Removing asteroid at {asteroid.PositionComp.GetPosition()} due to distance from player"); + _asteroids.Remove(asteroid); + asteroid.Close(); + continue; + } + } - if (IsNearVanillaAsteroid(newPosition)) + int asteroidsSpawned = 0; + while (_asteroids.Count < AsteroidSettings.MaxAsteroidCount && asteroidsSpawned < 10) { - Log.Info("Skipped spawning asteroid due to proximity to vanilla asteroid."); - continue; + Vector3D newPosition = playerPosition + RandVector() * AsteroidSettings.AsteroidSpawnRadius; + Vector3D newVelocity; + if (!AsteroidSettings.CanSpawnAsteroidAtPoint(newPosition, out newVelocity)) + continue; + + if (IsNearVanillaAsteroid(newPosition)) + { + // Log.Info("Skipped spawning asteroid due to proximity to vanilla asteroid."); + continue; + } + + // Determine asteroid type to spawn + AsteroidType type = AsteroidSettings.GetRandomAsteroidType(MainSession.I.Rand); + + Log.Info($"Spawning asteroid at {newPosition} with velocity {newVelocity} of type {type}"); + _asteroids.Add(AsteroidEntity.CreateAsteroid(newPosition, RandAsteroidSize, newVelocity, type)); + asteroidsSpawned++; } - // Determine asteroid type to spawn - AsteroidType type = AsteroidSettings.GetRandomAsteroidType(MainSession.I.Rand); + // Show a notification with the number of active asteroids + MyAPIGateway.Utilities.ShowNotification($"Active Asteroids: {_asteroids.Count}", 1000 / 60); - _asteroids.Add(AsteroidEntity.CreateAsteroid(newPosition, RandAsteroidSize, newVelocity, type)); - asteroidsSpawned++; + // Log the number of active asteroids for debugging purposes + // Log.Info($"Active Asteroids: {_asteroids.Count}"); } - - // Show a notification with the number of active asteroids - MyAPIGateway.Utilities.ShowNotification($"Active Asteroids: {_asteroids.Count}", 1000 / 60); - - // Log the number of active asteroids for debugging purposes - Log.Info($"Active Asteroids: {_asteroids.Count}"); } catch (Exception ex) { @@ -96,6 +111,7 @@ private bool IsNearVanillaAsteroid(Vector3D position) { if (Vector3D.DistanceSquared(position, voxelMap.GetPosition()) < MinDistanceFromVanillaAsteroids * MinDistanceFromVanillaAsteroids) { + Log.Info($"Position {position} is near vanilla asteroid {voxelMap.StorageName}"); return true; } } diff --git a/Dynamic Asteroids/Data/Scripts/DynamicAsteroids/MainSession.cs b/Dynamic Asteroids/Data/Scripts/DynamicAsteroids/MainSession.cs index 99d7b388..cf3a1ef0 100644 --- a/Dynamic Asteroids/Data/Scripts/DynamicAsteroids/MainSession.cs +++ b/Dynamic Asteroids/Data/Scripts/DynamicAsteroids/MainSession.cs @@ -68,7 +68,7 @@ public override void UpdateAfterSimulation() _spawner.UpdateTick(); } - if (MyAPIGateway.Session?.Player?.Character != null) + if (MyAPIGateway.Session?.Player?.Character != null && _spawner._asteroids != null) { Vector3D characterPosition = MyAPIGateway.Session.Player.Character.PositionComp.GetPosition(); AsteroidEntity nearestAsteroid = FindNearestAsteroid(characterPosition); @@ -100,6 +100,8 @@ public override void UpdateAfterSimulation() private AsteroidEntity FindNearestAsteroid(Vector3D characterPosition) { + if (_spawner._asteroids == null) return null; + AsteroidEntity nearestAsteroid = null; double minDistance = double.MaxValue; diff --git a/Dynamic Asteroids/Invalid_copy to DS and client.bat b/Dynamic Asteroids/Invalid_copy to DS and client.bat new file mode 100644 index 00000000..aa2c4f77 --- /dev/null +++ b/Dynamic Asteroids/Invalid_copy to DS and client.bat @@ -0,0 +1,31 @@ +@echo off +rem Testing mods in DS by yourself can be done without the need to re-publish every time. +rem You can simply update the files that are on your machine! +rem This will only work for you, anyone else joining the server will of course download the mod from the workshop. + +rem To use: +rem 1. Copy this .bat file in the ROOT folder of your local mod (e.g. %appdata%/SpaceEngineers/Mods/YourLocalMod/) + +rem 2. Edit this variable if applicable (do not add quotes or end with backslash). +set STEAM_PATH=C:\Program Files\Steam + +rem 3. Edit this with your mod's workshop id. +set WORKSHOP_ID=3262577158 + +rem Now you can run it every time you want to update the mod on DS and client. + + + +rem Don't edit the below unless you really need different paths. +rem NOTE: don't add quotes and don't end with a backslash! + +set CLIENT_PATH=O:\SteamLibrary\steamapps\workshop\content\244850\%WORKSHOP_ID% +set DS_PATH=%APPDATA%\SpaceEngineersDedicated\content\244850\%WORKSHOP_ID% + +rmdir "%CLIENT_PATH%" /S /Q +rmdir "%DS_PATH%" /S /Q + +robocopy.exe .\ "%DS_PATH%" *.* /S /xd .git bin obj .vs ignored /xf *.lnk *.git* *.bat *.zip *.7z *.blend* *.md *.log *.sln *.csproj *.csproj.user *.ruleset modinfo.sbmi +robocopy.exe "%DS_PATH%" "%CLIENT_PATH%" *.* /S + +pause \ No newline at end of file From bc9cb0ad4946712316a51fce5be10ae14534e7d2 Mon Sep 17 00:00:00 2001 From: InvalidArgument3 Date: Mon, 10 Jun 2024 07:05:32 -0500 Subject: [PATCH 2/4] like 80% mp working --- .../AsteroidEntities/AsteroidEntity.cs | 21 ++++++++- .../AsteroidEntities/AsteroidSpawner.cs | 22 +++++++-- .../AsteroidNetworkMessage.cs | 46 +++++++++++++++++++ .../Scripts/DynamicAsteroids/MainSession.cs | 44 +++++++++++++++++- 4 files changed, 125 insertions(+), 8 deletions(-) create mode 100644 Dynamic Asteroids/Data/Scripts/DynamicAsteroids/AsteroidNetworkMessage.cs diff --git a/Dynamic Asteroids/Data/Scripts/DynamicAsteroids/AsteroidEntities/AsteroidEntity.cs b/Dynamic Asteroids/Data/Scripts/DynamicAsteroids/AsteroidEntities/AsteroidEntity.cs index c04daa86..bc98a64b 100644 --- a/Dynamic Asteroids/Data/Scripts/DynamicAsteroids/AsteroidEntities/AsteroidEntity.cs +++ b/Dynamic Asteroids/Data/Scripts/DynamicAsteroids/AsteroidEntities/AsteroidEntity.cs @@ -93,7 +93,7 @@ public void SplitAsteroid() splits = (int)Math.Ceiling(Size); float newSize = Size / splits; - MyAPIGateway.Utilities.ShowNotification($"NS: {newSize}"); + // MyAPIGateway.Utilities.ShowNotification($"NS: {newSize}"); // Commented out for less frequent logging if (newSize <= 1) { @@ -103,6 +103,12 @@ public void SplitAsteroid() { MyFloatingObjects.Spawn(new MyPhysicalInventoryItem(1000, newObject), PositionComp.GetPosition() + RandVector() * Size, Vector3D.Forward, Vector3D.Up, Physics); } + + // Send a removal message before closing + var removalMessage1 = new AsteroidNetworkMessage(PositionComp.GetPosition(), Size, Vector3D.Zero, Vector3D.Zero, Type, false, EntityId, true); + var removalMessageBytes1 = MyAPIGateway.Utilities.SerializeToBinary(removalMessage1); + MyAPIGateway.Multiplayer.SendMessageToOthers(1337, removalMessageBytes1); + Close(); return; } @@ -112,9 +118,22 @@ public void SplitAsteroid() Vector3D newPos = PositionComp.GetPosition() + RandVector() * Size; Vector3D newVelocity = RandVector() * AsteroidSettings.GetRandomSubChunkVelocity(MainSession.I.Rand); Vector3D newAngularVelocity = RandVector() * AsteroidSettings.GetRandomSubChunkAngularVelocity(MainSession.I.Rand); + + // Create the sub-chunk asteroid on the server var subChunk = CreateAsteroid(newPos, newSize, newVelocity, Type); subChunk.Physics.AngularVelocity = newAngularVelocity; + + // Send a network message to clients + var message = new AsteroidNetworkMessage(newPos, newSize, newVelocity, newAngularVelocity, Type, true, subChunk.EntityId, false); + var messageBytes = MyAPIGateway.Utilities.SerializeToBinary(message); + MyAPIGateway.Multiplayer.SendMessageToOthers(1337, messageBytes); } + + // Send a removal message before closing + var removalMessage2 = new AsteroidNetworkMessage(PositionComp.GetPosition(), Size, Vector3D.Zero, Vector3D.Zero, Type, false, EntityId, true); + var removalMessageBytes2 = MyAPIGateway.Utilities.SerializeToBinary(removalMessage2); + MyAPIGateway.Multiplayer.SendMessageToOthers(1337, removalMessageBytes2); + Close(); } diff --git a/Dynamic Asteroids/Data/Scripts/DynamicAsteroids/AsteroidEntities/AsteroidSpawner.cs b/Dynamic Asteroids/Data/Scripts/DynamicAsteroids/AsteroidEntities/AsteroidSpawner.cs index a1aa9efa..6ddb8da2 100644 --- a/Dynamic Asteroids/Data/Scripts/DynamicAsteroids/AsteroidEntities/AsteroidSpawner.cs +++ b/Dynamic Asteroids/Data/Scripts/DynamicAsteroids/AsteroidEntities/AsteroidSpawner.cs @@ -5,6 +5,7 @@ using VRage.Game.ModAPI; using VRage.ModAPI; using VRageMath; +using ProtoBuf; namespace DynamicAsteroids.AsteroidEntities { @@ -30,7 +31,6 @@ public void Close() Log.Info("Closing AsteroidSpawner"); _asteroids?.Clear(); } - public void UpdateTick() { if (!MyAPIGateway.Session.IsServer) @@ -51,7 +51,7 @@ public void UpdateTick() if (!AsteroidSettings.PlayerCanSeeRings(playerPosition)) { - // Log.Info("Player cannot see rings"); + //Log.Info("Player cannot see rings"); continue; } @@ -62,6 +62,12 @@ public void UpdateTick() { Log.Info($"Removing asteroid at {asteroid.PositionComp.GetPosition()} due to distance from player"); _asteroids.Remove(asteroid); + + // Send a network message to clients for removal + var removalMessage = new AsteroidNetworkMessage(asteroid.PositionComp.GetPosition(), asteroid.Size, Vector3D.Zero, Vector3D.Zero, asteroid.Type, false, asteroid.EntityId, true); + var removalMessageBytes = MyAPIGateway.Utilities.SerializeToBinary(removalMessage); + MyAPIGateway.Multiplayer.SendMessageToOthers(1337, removalMessageBytes); + asteroid.Close(); continue; } @@ -77,7 +83,7 @@ public void UpdateTick() if (IsNearVanillaAsteroid(newPosition)) { - // Log.Info("Skipped spawning asteroid due to proximity to vanilla asteroid."); + Log.Info("Skipped spawning asteroid due to proximity to vanilla asteroid."); continue; } @@ -85,15 +91,21 @@ public void UpdateTick() AsteroidType type = AsteroidSettings.GetRandomAsteroidType(MainSession.I.Rand); Log.Info($"Spawning asteroid at {newPosition} with velocity {newVelocity} of type {type}"); - _asteroids.Add(AsteroidEntity.CreateAsteroid(newPosition, RandAsteroidSize, newVelocity, type)); + var asteroid = AsteroidEntity.CreateAsteroid(newPosition, RandAsteroidSize, newVelocity, type); + _asteroids.Add(asteroid); asteroidsSpawned++; + + // Send a network message to clients + var message = new AsteroidNetworkMessage(newPosition, RandAsteroidSize, newVelocity, Vector3D.Zero, type, false, asteroid.EntityId, false); + var messageBytes = MyAPIGateway.Utilities.SerializeToBinary(message); + MyAPIGateway.Multiplayer.SendMessageToOthers(1337, messageBytes); } // Show a notification with the number of active asteroids MyAPIGateway.Utilities.ShowNotification($"Active Asteroids: {_asteroids.Count}", 1000 / 60); // Log the number of active asteroids for debugging purposes - // Log.Info($"Active Asteroids: {_asteroids.Count}"); + //Log.Info($"Active Asteroids: {_asteroids.Count}"); } } catch (Exception ex) diff --git a/Dynamic Asteroids/Data/Scripts/DynamicAsteroids/AsteroidNetworkMessage.cs b/Dynamic Asteroids/Data/Scripts/DynamicAsteroids/AsteroidNetworkMessage.cs new file mode 100644 index 00000000..9ff6cbf9 --- /dev/null +++ b/Dynamic Asteroids/Data/Scripts/DynamicAsteroids/AsteroidNetworkMessage.cs @@ -0,0 +1,46 @@ +using DynamicAsteroids.AsteroidEntities; +using VRageMath; +using ProtoBuf; + +namespace DynamicAsteroids +{ + [ProtoContract] + public struct AsteroidNetworkMessage + { + [ProtoMember(1)] + public Vector3D Position; + + [ProtoMember(2)] + public float Size; + + [ProtoMember(3)] + public Vector3D InitialVelocity; + + [ProtoMember(4)] + public Vector3D AngularVelocity; + + [ProtoMember(5)] + public AsteroidType Type; + + [ProtoMember(6)] + public bool IsSubChunk; + + [ProtoMember(7)] + public long EntityId; + + [ProtoMember(8)] + public bool IsRemoval; + + public AsteroidNetworkMessage(Vector3D position, float size, Vector3D initialVelocity, Vector3D angularVelocity, AsteroidType type, bool isSubChunk, long entityId, bool isRemoval) + { + Position = position; + Size = size; + InitialVelocity = initialVelocity; + AngularVelocity = angularVelocity; + Type = type; + IsSubChunk = isSubChunk; + EntityId = entityId; + IsRemoval = isRemoval; + } + } +} \ No newline at end of file diff --git a/Dynamic Asteroids/Data/Scripts/DynamicAsteroids/MainSession.cs b/Dynamic Asteroids/Data/Scripts/DynamicAsteroids/MainSession.cs index cf3a1ef0..8f8e7465 100644 --- a/Dynamic Asteroids/Data/Scripts/DynamicAsteroids/MainSession.cs +++ b/Dynamic Asteroids/Data/Scripts/DynamicAsteroids/MainSession.cs @@ -7,6 +7,8 @@ using VRage.Game.Components; using VRage.Input; using VRageMath; +using ProtoBuf; +using Sandbox.Game.Entities; namespace DynamicAsteroids { @@ -33,6 +35,8 @@ public override void LoadData() { _spawner.Init(); } + + MyAPIGateway.Multiplayer.RegisterMessageHandler(1337, OnMessageReceived); } catch (Exception ex) { @@ -49,6 +53,8 @@ protected override void UnloadData() { _spawner.Close(); } + + MyAPIGateway.Multiplayer.UnregisterMessageHandler(1337, OnMessageReceived); } catch (Exception ex) { @@ -97,6 +103,42 @@ public override void UpdateAfterSimulation() Log.Exception(ex, typeof(MainSession)); } } + private void OnMessageReceived(byte[] message) + { + try + { + var asteroidMessage = MyAPIGateway.Utilities.SerializeFromBinary(message); + Log.Info($"Client: Received message to create/remove asteroid at {asteroidMessage.Position} with velocity {asteroidMessage.InitialVelocity} of type {asteroidMessage.Type}"); + + if (asteroidMessage.IsRemoval) + { + // Find and remove the asteroid with the given EntityId + var asteroid = MyEntities.GetEntityById(asteroidMessage.EntityId) as AsteroidEntity; + if (asteroid != null) + { + asteroid.Close(); + } + } + else + { + if (asteroidMessage.IsSubChunk) + { + // Create the sub-chunk asteroid on the client + var subChunk = AsteroidEntity.CreateAsteroid(asteroidMessage.Position, asteroidMessage.Size, asteroidMessage.InitialVelocity, asteroidMessage.Type); + subChunk.Physics.AngularVelocity = asteroidMessage.AngularVelocity; + } + else + { + // Create the regular asteroid on the client + AsteroidEntity.CreateAsteroid(asteroidMessage.Position, asteroidMessage.Size, asteroidMessage.InitialVelocity, asteroidMessage.Type); + } + } + } + catch (Exception ex) + { + Log.Exception(ex, typeof(MainSession)); + } + } private AsteroidEntity FindNearestAsteroid(Vector3D characterPosition) { @@ -121,8 +163,6 @@ private AsteroidEntity FindNearestAsteroid(Vector3D characterPosition) // This function determines the type of asteroid to spawn private AsteroidType DetermineAsteroidType() { - // Here you can add logic to determine the type of asteroid. - // For example, randomly selecting a type or using some other logic. int randValue = Rand.Next(0, 2); // Adjust as needed for more types return (AsteroidType)randValue; } From d4b2f1c648fa27b81f2726de3fffe092e14b203b Mon Sep 17 00:00:00 2001 From: InvalidArgument3 Date: Mon, 10 Jun 2024 07:10:16 -0500 Subject: [PATCH 3/4] Update AsteroidSpawner.cs --- .../Scripts/DynamicAsteroids/AsteroidEntities/AsteroidSpawner.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/Dynamic Asteroids/Data/Scripts/DynamicAsteroids/AsteroidEntities/AsteroidSpawner.cs b/Dynamic Asteroids/Data/Scripts/DynamicAsteroids/AsteroidEntities/AsteroidSpawner.cs index 6ddb8da2..af0216c2 100644 --- a/Dynamic Asteroids/Data/Scripts/DynamicAsteroids/AsteroidEntities/AsteroidSpawner.cs +++ b/Dynamic Asteroids/Data/Scripts/DynamicAsteroids/AsteroidEntities/AsteroidSpawner.cs @@ -31,6 +31,7 @@ public void Close() Log.Info("Closing AsteroidSpawner"); _asteroids?.Clear(); } + public void UpdateTick() { if (!MyAPIGateway.Session.IsServer) From eaa4b7c19aaea53cfb4e81d1a9a5a9cd7010a0b8 Mon Sep 17 00:00:00 2001 From: InvalidArgument3 Date: Mon, 10 Jun 2024 08:29:28 -0500 Subject: [PATCH 4/4] a --- .../AsteroidEntities/AsteroidEntity.cs | 16 +++++++++++++--- .../AsteroidEntities/AsteroidSpawner.cs | 11 +++-------- .../DynamicAsteroids/AsteroidNetworkMessage.cs | 6 +++++- .../Data/Scripts/DynamicAsteroids/MainSession.cs | 10 +++++++++- 4 files changed, 30 insertions(+), 13 deletions(-) diff --git a/Dynamic Asteroids/Data/Scripts/DynamicAsteroids/AsteroidEntities/AsteroidEntity.cs b/Dynamic Asteroids/Data/Scripts/DynamicAsteroids/AsteroidEntities/AsteroidEntity.cs index bc98a64b..750806e7 100644 --- a/Dynamic Asteroids/Data/Scripts/DynamicAsteroids/AsteroidEntities/AsteroidEntity.cs +++ b/Dynamic Asteroids/Data/Scripts/DynamicAsteroids/AsteroidEntities/AsteroidEntity.cs @@ -105,7 +105,7 @@ public void SplitAsteroid() } // Send a removal message before closing - var removalMessage1 = new AsteroidNetworkMessage(PositionComp.GetPosition(), Size, Vector3D.Zero, Vector3D.Zero, Type, false, EntityId, true); + var removalMessage1 = new AsteroidNetworkMessage(PositionComp.GetPosition(), Size, Vector3D.Zero, Vector3D.Zero, Type, false, EntityId, true, false); var removalMessageBytes1 = MyAPIGateway.Utilities.SerializeToBinary(removalMessage1); MyAPIGateway.Multiplayer.SendMessageToOthers(1337, removalMessageBytes1); @@ -124,13 +124,13 @@ public void SplitAsteroid() subChunk.Physics.AngularVelocity = newAngularVelocity; // Send a network message to clients - var message = new AsteroidNetworkMessage(newPos, newSize, newVelocity, newAngularVelocity, Type, true, subChunk.EntityId, false); + var message = new AsteroidNetworkMessage(newPos, newSize, newVelocity, newAngularVelocity, Type, true, subChunk.EntityId, false, true); var messageBytes = MyAPIGateway.Utilities.SerializeToBinary(message); MyAPIGateway.Multiplayer.SendMessageToOthers(1337, messageBytes); } // Send a removal message before closing - var removalMessage2 = new AsteroidNetworkMessage(PositionComp.GetPosition(), Size, Vector3D.Zero, Vector3D.Zero, Type, false, EntityId, true); + var removalMessage2 = new AsteroidNetworkMessage(PositionComp.GetPosition(), Size, Vector3D.Zero, Vector3D.Zero, Type, false, EntityId, true, false); var removalMessageBytes2 = MyAPIGateway.Utilities.SerializeToBinary(removalMessage2); MyAPIGateway.Multiplayer.SendMessageToOthers(1337, removalMessageBytes2); @@ -225,6 +225,16 @@ private void Init(Vector3D position, float size, Vector3D initialVelocity, Aster Physics.AngularVelocity = RandVector() * AsteroidSettings.GetRandomAngularVelocity(MainSession.I.Rand); // Set initial angular velocity Log.Info($"Asteroid model {ModelString} loaded successfully with initial angular velocity: {Physics.AngularVelocity}"); + + // Ensure the entity is added to the physics world + if (MyAPIGateway.Session.IsServer) + { + SyncFlag = true; + } + else + { + CreatePhysics(); + } } catch (Exception ex) { diff --git a/Dynamic Asteroids/Data/Scripts/DynamicAsteroids/AsteroidEntities/AsteroidSpawner.cs b/Dynamic Asteroids/Data/Scripts/DynamicAsteroids/AsteroidEntities/AsteroidSpawner.cs index af0216c2..488a63d3 100644 --- a/Dynamic Asteroids/Data/Scripts/DynamicAsteroids/AsteroidEntities/AsteroidSpawner.cs +++ b/Dynamic Asteroids/Data/Scripts/DynamicAsteroids/AsteroidEntities/AsteroidSpawner.cs @@ -31,7 +31,6 @@ public void Close() Log.Info("Closing AsteroidSpawner"); _asteroids?.Clear(); } - public void UpdateTick() { if (!MyAPIGateway.Session.IsServer) @@ -39,8 +38,6 @@ public void UpdateTick() try { - //Log.Info("UpdateTick called in AsteroidSpawner"); - // Get all players on the server List players = new List(); MyAPIGateway.Players.GetPlayers(players); @@ -48,11 +45,9 @@ public void UpdateTick() foreach (var player in players) { Vector3D playerPosition = player.GetPosition(); - //Log.Info($"Player {player.DisplayName} position: {playerPosition}"); if (!AsteroidSettings.PlayerCanSeeRings(playerPosition)) { - //Log.Info("Player cannot see rings"); continue; } @@ -65,7 +60,7 @@ public void UpdateTick() _asteroids.Remove(asteroid); // Send a network message to clients for removal - var removalMessage = new AsteroidNetworkMessage(asteroid.PositionComp.GetPosition(), asteroid.Size, Vector3D.Zero, Vector3D.Zero, asteroid.Type, false, asteroid.EntityId, true); + var removalMessage = new AsteroidNetworkMessage(asteroid.PositionComp.GetPosition(), asteroid.Size, Vector3D.Zero, Vector3D.Zero, asteroid.Type, false, asteroid.EntityId, true, false); var removalMessageBytes = MyAPIGateway.Utilities.SerializeToBinary(removalMessage); MyAPIGateway.Multiplayer.SendMessageToOthers(1337, removalMessageBytes); @@ -92,12 +87,12 @@ public void UpdateTick() AsteroidType type = AsteroidSettings.GetRandomAsteroidType(MainSession.I.Rand); Log.Info($"Spawning asteroid at {newPosition} with velocity {newVelocity} of type {type}"); - var asteroid = AsteroidEntity.CreateAsteroid(newPosition, RandAsteroidSize, newVelocity, type); + var asteroid = AsteroidEntity.CreateAsteroid(newPosition, AsteroidSettings.GetRandomAsteroidSize(MainSession.I.Rand), newVelocity, type); _asteroids.Add(asteroid); asteroidsSpawned++; // Send a network message to clients - var message = new AsteroidNetworkMessage(newPosition, RandAsteroidSize, newVelocity, Vector3D.Zero, type, false, asteroid.EntityId, false); + var message = new AsteroidNetworkMessage(newPosition, asteroid.Size, newVelocity, Vector3D.Zero, type, false, asteroid.EntityId, false, true); var messageBytes = MyAPIGateway.Utilities.SerializeToBinary(message); MyAPIGateway.Multiplayer.SendMessageToOthers(1337, messageBytes); } diff --git a/Dynamic Asteroids/Data/Scripts/DynamicAsteroids/AsteroidNetworkMessage.cs b/Dynamic Asteroids/Data/Scripts/DynamicAsteroids/AsteroidNetworkMessage.cs index 9ff6cbf9..21ccfb0c 100644 --- a/Dynamic Asteroids/Data/Scripts/DynamicAsteroids/AsteroidNetworkMessage.cs +++ b/Dynamic Asteroids/Data/Scripts/DynamicAsteroids/AsteroidNetworkMessage.cs @@ -31,7 +31,10 @@ public struct AsteroidNetworkMessage [ProtoMember(8)] public bool IsRemoval; - public AsteroidNetworkMessage(Vector3D position, float size, Vector3D initialVelocity, Vector3D angularVelocity, AsteroidType type, bool isSubChunk, long entityId, bool isRemoval) + [ProtoMember(9)] + public bool IsInitialCreation; + + public AsteroidNetworkMessage(Vector3D position, float size, Vector3D initialVelocity, Vector3D angularVelocity, AsteroidType type, bool isSubChunk, long entityId, bool isRemoval, bool isInitialCreation) { Position = position; Size = size; @@ -41,6 +44,7 @@ public AsteroidNetworkMessage(Vector3D position, float size, Vector3D initialVel IsSubChunk = isSubChunk; EntityId = entityId; IsRemoval = isRemoval; + IsInitialCreation = isInitialCreation; } } } \ No newline at end of file diff --git a/Dynamic Asteroids/Data/Scripts/DynamicAsteroids/MainSession.cs b/Dynamic Asteroids/Data/Scripts/DynamicAsteroids/MainSession.cs index 8f8e7465..74366aa6 100644 --- a/Dynamic Asteroids/Data/Scripts/DynamicAsteroids/MainSession.cs +++ b/Dynamic Asteroids/Data/Scripts/DynamicAsteroids/MainSession.cs @@ -119,6 +119,12 @@ private void OnMessageReceived(byte[] message) asteroid.Close(); } } + else if (asteroidMessage.IsInitialCreation) + { + var asteroid = AsteroidEntity.CreateAsteroid(asteroidMessage.Position, asteroidMessage.Size, asteroidMessage.InitialVelocity, asteroidMessage.Type); + asteroid.Physics.AngularVelocity = asteroidMessage.AngularVelocity; + MyEntities.Add(asteroid); + } else { if (asteroidMessage.IsSubChunk) @@ -130,7 +136,9 @@ private void OnMessageReceived(byte[] message) else { // Create the regular asteroid on the client - AsteroidEntity.CreateAsteroid(asteroidMessage.Position, asteroidMessage.Size, asteroidMessage.InitialVelocity, asteroidMessage.Type); + var asteroid = AsteroidEntity.CreateAsteroid(asteroidMessage.Position, asteroidMessage.Size, asteroidMessage.InitialVelocity, asteroidMessage.Type); + asteroid.Physics.AngularVelocity = asteroidMessage.AngularVelocity; + MyEntities.Add(asteroid); } } }