]> git.deb.at Git - rhonda/impostor.git/commitdiff
Implement airship spawning, closes #376
authorjs6pak <kubastaron@hotmail.com>
Sun, 4 Apr 2021 21:27:10 +0000 (23:27 +0200)
committerjs6pak <kubastaron@hotmail.com>
Sun, 4 Apr 2021 21:27:39 +0000 (23:27 +0200)
src/Impostor.Api/Innersloth/MapSpawn.cs [deleted file]
src/Impostor.Server/Net/Inner/Objects/Components/InnerCustomNetworkTransform.cs
src/Impostor.Server/Net/Inner/Objects/ShipStatus/InnerAirshipStatus.cs
src/Impostor.Server/Net/Inner/Objects/ShipStatus/InnerMiraShipStatus.cs
src/Impostor.Server/Net/Inner/Objects/ShipStatus/InnerPolusShipStatus.cs
src/Impostor.Server/Net/Inner/Objects/ShipStatus/InnerShipStatus.cs
src/Impostor.Server/Net/Inner/Objects/ShipStatus/InnerSkeldShipStatus.cs
src/Impostor.Server/Net/State/Game.Data.cs
src/Impostor.Server/Net/State/Game.cs

diff --git a/src/Impostor.Api/Innersloth/MapSpawn.cs b/src/Impostor.Api/Innersloth/MapSpawn.cs
deleted file mode 100644 (file)
index 3f59f0a..0000000
+++ /dev/null
@@ -1,46 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Numerics;
-
-namespace Impostor.Api.Innersloth
-{
-    public class MapSpawn
-    {
-        private MapSpawn(float spawnRadius, Vector2 initialSpawnCenter, Vector2 meetingSpawnCenter)
-        {
-            SpawnRadius = spawnRadius;
-            InitialSpawnCenter = initialSpawnCenter;
-            MeetingSpawnCenter = meetingSpawnCenter;
-        }
-
-        public static Dictionary<MapTypes, MapSpawn> Maps { get; } = new Dictionary<MapTypes, MapSpawn>
-        {
-            [MapTypes.Skeld] = new MapSpawn(1.6f, new Vector2(-0.72f, 0.62f), new Vector2(-0.72f, 0.62f)),
-            [MapTypes.MiraHQ] = new MapSpawn(1.55f, new Vector2(-4.4f, 2.2f), new Vector2(24.043f, 1.72f)),
-            [MapTypes.Polus] = new MapSpawn(1f, new Vector2(16.64f, -2.46f), new Vector2(17.726f, -16.286f)),
-            [MapTypes.Airship] = new MapSpawn(0f, new Vector2(-0.66f, -0.5f), new Vector2(-0.66f, -0.5f)),
-        };
-
-        public float SpawnRadius { get; }
-
-        public Vector2 InitialSpawnCenter { get; }
-
-        public Vector2 MeetingSpawnCenter { get; }
-
-        public Vector2 GetSpawnLocation(int playerId, int numPlayer, bool initialSpawn)
-        {
-            var vector = new Vector2(0, 1);
-            vector = Rotate(vector, (playerId - 1) * (360f / numPlayer));
-            vector *= this.SpawnRadius;
-            return (initialSpawn ? this.InitialSpawnCenter : this.MeetingSpawnCenter) + vector + new Vector2(0f, 0.3636f);
-        }
-
-        private static Vector2 Rotate(Vector2 self, float degrees)
-        {
-            var f = 0.017453292f * degrees;
-            var num = (float)Math.Cos(f);
-            var num2 = (float)Math.Sin(f);
-            return new Vector2((self.X * num) - (num2 * self.Y), (self.X * num2) + (num * self.Y));
-        }
-    }
-}
index d1a48a3a0b7dbd1285a4265f00615f624866c118..5df6b8a98425aef3d712d5e721c8b2e183da8ecf 100644 (file)
@@ -1,4 +1,5 @@
-using System.Numerics;
+using System.Linq;
+using System.Numerics;
 using System.Threading.Tasks;
 using Impostor.Api;
 using Impostor.Api.Events.Managers;
@@ -7,6 +8,7 @@ using Impostor.Api.Net.Inner;
 using Impostor.Api.Net.Messages;
 using Impostor.Api.Net.Messages.Rpcs;
 using Impostor.Server.Events.Player;
+using Impostor.Server.Net.Inner.Objects.ShipStatus;
 using Impostor.Server.Net.State;
 using Microsoft.Extensions.Logging;
 using Microsoft.Extensions.ObjectPool;
@@ -21,6 +23,7 @@ namespace Impostor.Server.Net.Inner.Objects.Components
         private readonly ObjectPool<PlayerMovementEvent> _pool;
 
         private ushort _lastSequenceId;
+        private bool _spawnSnapAllowed;
 
         public InnerCustomNetworkTransform(Game game, ILogger<InnerCustomNetworkTransform> logger, InnerPlayerControl playerControl, IEventManager eventManager, ObjectPool<PlayerMovementEvent> pool) : base(game)
         {
@@ -83,13 +86,34 @@ namespace Impostor.Server.Net.Inner.Objects.Components
         {
             if (call == RpcCalls.SnapTo)
             {
-                if (!await ValidateOwnership(call, sender) || !await ValidateImpostor(call, sender, _playerControl.PlayerInfo))
+                if (!await ValidateOwnership(call, sender))
                 {
                     return false;
                 }
 
                 Rpc21SnapTo.Deserialize(reader, out var position, out var minSid);
 
+                if (Game.GameNet.ShipStatus is InnerAirshipStatus airshipStatus)
+                {
+                    // As part of airship spawning, clients are sending snap to -25 40 for no reason(?), cancelling it works just fine
+                    if (Approximately(position, airshipStatus.PreSpawnLocation))
+                    {
+                        return false;
+                    }
+
+                    if (_spawnSnapAllowed && airshipStatus.SpawnLocations.Any(location => Approximately(position, location)))
+                    {
+                        _spawnSnapAllowed = false;
+                        return true;
+                    }
+                }
+
+                if (!await ValidateImpostor(call, sender, _playerControl.PlayerInfo))
+                {
+                    return false;
+                }
+
+                // TODO validate vent location
                 await SnapToAsync(sender, position, minSid);
                 return true;
             }
@@ -108,6 +132,11 @@ namespace Impostor.Server.Net.Inner.Objects.Components
             _pool.Return(playerMovementEvent);
         }
 
+        internal void OnPlayerSpawn()
+        {
+            _spawnSnapAllowed = true;
+        }
+
         private static bool SidGreaterThan(ushort newSid, ushort prevSid)
         {
             var num = (ushort)(prevSid + (uint)short.MaxValue);
@@ -117,6 +146,12 @@ namespace Impostor.Server.Net.Inner.Objects.Components
                 : newSid > prevSid || newSid <= num;
         }
 
+        private static bool Approximately(Vector2 a, Vector2 b, float tolerance = 0.1f)
+        {
+            var abs = Vector2.Abs(a - b);
+            return abs.X <= tolerance && abs.Y <= tolerance;
+        }
+
         private ValueTask SnapToAsync(IClientPlayer sender, Vector2 position, ushort minSid)
         {
             if (!SidGreaterThan(minSid, _lastSequenceId))
index 8776a8c4923e976aa4966e7be585d8e2ad04810a..7f8562809a78cf787529675f1e6a009d8b54c11b 100644 (file)
@@ -1,4 +1,6 @@
+using System;
 using System.Collections.Generic;
+using System.Numerics;
 using Impostor.Api.Innersloth;
 using Impostor.Api.Net.Inner.Objects.ShipStatus;
 using Impostor.Server.Net.Inner.Objects.Systems;
@@ -15,6 +17,29 @@ namespace Impostor.Server.Net.Inner.Objects.ShipStatus
 
         public override Dictionary<int, bool> Doors { get; } = new Dictionary<int, bool>(21);
 
+        public override float SpawnRadius => throw new NotSupportedException();
+
+        public override Vector2 InitialSpawnCenter => throw new NotSupportedException();
+
+        public override Vector2 MeetingSpawnCenter => throw new NotSupportedException();
+
+        public Vector2 PreSpawnLocation { get; } = new Vector2(-25f, 40f);
+
+        public Vector2[] SpawnLocations { get; } =
+        {
+            new Vector2(-0.7f, 8.5f), // Brig
+            new Vector2(-0.7f, -1.0f), // Engine
+            new Vector2(15.5f, 0.0f), // MainHall
+            new Vector2(-7.0f, -11.5f), // Kitchen
+            new Vector2(20.0f, 10.5f), // Records
+            new Vector2(33.5f, -1.5f), // CargoBay
+        };
+
+        public override Vector2 GetSpawnLocation(InnerPlayerControl player, int numPlayers, bool initialSpawn)
+        {
+            return new Vector2(-25, 40);
+        }
+
         protected override void AddSystems(Dictionary<SystemTypes, ISystemType> systems)
         {
             base.AddSystems(systems);
index 04d033fb15500e25a0ccdcc6b84587f178d5ceb7..02daf3160b5e1168b93761b2c88037ec4053b02a 100644 (file)
@@ -1,4 +1,5 @@
 using System.Collections.Generic;
+using System.Numerics;
 using Impostor.Api.Innersloth;
 using Impostor.Api.Net.Inner.Objects.ShipStatus;
 using Impostor.Server.Net.Inner.Objects.Systems;
@@ -15,6 +16,12 @@ namespace Impostor.Server.Net.Inner.Objects.ShipStatus
 
         public override Dictionary<int, bool> Doors { get; } = new Dictionary<int, bool>(0);
 
+        public override float SpawnRadius => 1.55f;
+
+        public override Vector2 InitialSpawnCenter { get; } = new Vector2(-4.4f, 2.2f);
+
+        public override Vector2 MeetingSpawnCenter { get; } = new Vector2(24.043f, 1.72f);
+
         protected override void AddSystems(Dictionary<SystemTypes, ISystemType> systems)
         {
             base.AddSystems(systems);
index 7ec077d28765c1a95db59cf35a23118ce7306c3f..262b313b89dad01f70501244b1f1d10ba96b7147 100644 (file)
@@ -1,4 +1,5 @@
 using System.Collections.Generic;
+using System.Numerics;
 using Impostor.Api.Innersloth;
 using Impostor.Api.Net.Inner.Objects.ShipStatus;
 using Impostor.Server.Net.Inner.Objects.Systems;
@@ -15,6 +16,34 @@ namespace Impostor.Server.Net.Inner.Objects.ShipStatus
 
         public override Dictionary<int, bool> Doors { get; } = new Dictionary<int, bool>(12);
 
+        public override float SpawnRadius => 1f;
+
+        public override Vector2 InitialSpawnCenter { get; } = new Vector2(16.64f, -2.46f);
+
+        public override Vector2 MeetingSpawnCenter { get; } = new Vector2(17.726f, -16.286f);
+
+        public Vector2 MeetingSpawnCenter2 { get; } = new Vector2(-17.7f, -17.5f);
+
+        public override Vector2 GetSpawnLocation(InnerPlayerControl player, int numPlayers, bool initialSpawn)
+        {
+            if (initialSpawn)
+            {
+                return base.GetSpawnLocation(player, numPlayers, initialSpawn);
+            }
+
+            Vector2 position;
+            if (player.PlayerId < 5)
+            {
+                position = this.MeetingSpawnCenter + (new Vector2(1, 0) * player.PlayerId);
+            }
+            else
+            {
+                position = this.MeetingSpawnCenter2 + (new Vector2(1, 0) * (player.PlayerId - 5));
+            }
+
+            return position;
+        }
+
         protected override void AddSystems(Dictionary<SystemTypes, ISystemType> systems)
         {
             base.AddSystems(systems);
index 418adef342ee46cc32a86535c81c0943e72b8c82..dcfa24f08255e1a7dec4e6db90722169f6165578 100644 (file)
@@ -1,6 +1,7 @@
 using System;
 using System.Collections.Generic;
 using System.Linq;
+using System.Numerics;
 using System.Threading.Tasks;
 using Impostor.Api;
 using Impostor.Api.Innersloth;
@@ -26,6 +27,12 @@ namespace Impostor.Server.Net.Inner.Objects.ShipStatus
 
         public abstract Dictionary<int, bool> Doors { get; }
 
+        public abstract float SpawnRadius { get; }
+
+        public abstract Vector2 InitialSpawnCenter { get; }
+
+        public abstract Vector2 MeetingSpawnCenter { get; }
+
         public override ValueTask OnSpawnAsync()
         {
             for (var i = 0; i < Doors.Count; i++)
@@ -101,10 +108,27 @@ namespace Impostor.Server.Net.Inner.Objects.ShipStatus
             return true;
         }
 
+        public virtual Vector2 GetSpawnLocation(InnerPlayerControl player, int numPlayers, bool initialSpawn)
+        {
+            var vector = new Vector2(0, 1);
+            vector = Rotate(vector, (player.PlayerId - 1) * (360f / numPlayers));
+            vector *= this.SpawnRadius;
+            return (initialSpawn ? this.InitialSpawnCenter : this.MeetingSpawnCenter) + vector + new Vector2(0f, 0.3636f);
+        }
+
         protected virtual void AddSystems(Dictionary<SystemTypes, ISystemType> systems)
         {
             systems.Add(SystemTypes.Electrical, new SwitchSystem());
             systems.Add(SystemTypes.MedBay, new MedScanSystem());
         }
+
+        private static Vector2 Rotate(Vector2 self, float degrees)
+        {
+            var f = 0.017453292f * degrees;
+            var cos = MathF.Cos(f);
+            var sin = MathF.Sin(f);
+
+            return new Vector2((self.X * cos) - (sin * self.Y), (self.X * sin) + (cos * self.Y));
+        }
     }
 }
index 12df2f35450f5eade50cb834532d2927988879d2..9580b7be47f431fc6372701e1f091334cd384090 100644 (file)
@@ -1,4 +1,5 @@
 using System.Collections.Generic;
+using System.Numerics;
 using Impostor.Api.Innersloth;
 using Impostor.Api.Net.Inner.Objects.ShipStatus;
 using Impostor.Server.Net.Inner.Objects.Systems;
@@ -15,6 +16,12 @@ namespace Impostor.Server.Net.Inner.Objects.ShipStatus
 
         public override Dictionary<int, bool> Doors { get; } = new Dictionary<int, bool>(13);
 
+        public override float SpawnRadius => 1.6f;
+
+        public override Vector2 InitialSpawnCenter { get; } = new Vector2(-0.72f, 0.62f);
+
+        public override Vector2 MeetingSpawnCenter { get; } = new Vector2(-0.72f, 0.62f);
+
         protected override void AddSystems(Dictionary<SystemTypes, ISystemType> systems)
         {
             base.AddSystems(systems);
index 74b3c7bba6f2381f0e297cb7eba9b99a6af9f422..9a09c1b770f54fb8d7aa95da7ad85f2ff68fc61f 100644 (file)
@@ -346,6 +346,11 @@ namespace Impostor.Server.Net.State
 
                 case InnerMeetingHud meetingHud:
                 {
+                    foreach (var player in _players.Values)
+                    {
+                        player.Character?.NetworkTransform.OnPlayerSpawn();
+                    }
+
                     await _eventManager.CallAsync(new MeetingStartedEvent(this, meetingHud));
                     break;
                 }
index 823c049f45b98101075c1f5d55b1cadd904affb6..20f6c01b2c5e143d220d18267c02c7ee26678d5a 100644 (file)
@@ -105,10 +105,10 @@ namespace Impostor.Server.Net.State
         {
             if (GameState == GameStates.Starting)
             {
-                for (var i = 0; i < _players.Values.Count; i++)
+                foreach (var player in _players.Values)
                 {
-                    var player = _players.Values.ElementAt(i);
-                    await player.Character!.NetworkTransform.SetPositionAsync(player, MapSpawn.Maps[Options.Map].GetSpawnLocation(i, PlayerCount, true), Vector2.Zero);
+                    player.Character?.NetworkTransform.OnPlayerSpawn();
+                    await player.Character!.NetworkTransform.SetPositionAsync(player, GameNet.ShipStatus!.GetSpawnLocation(player.Character, PlayerCount, true), Vector2.Zero);
                 }
 
                 GameState = GameStates.Started;