Skip to content

Commit

Permalink
Implement airship spawning, closes Impostor#376
Browse files Browse the repository at this point in the history
  • Loading branch information
js6pak committed Apr 4, 2021
1 parent 13bddeb commit 4866a35
Show file tree
Hide file tree
Showing 9 changed files with 137 additions and 51 deletions.
46 changes: 0 additions & 46 deletions src/Impostor.Api/Innersloth/MapSpawn.cs

This file was deleted.

Original file line number Diff line number Diff line change
@@ -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;
Expand All @@ -7,6 +8,7 @@
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;
Expand All @@ -21,6 +23,7 @@ internal partial class InnerCustomNetworkTransform : InnerNetObject
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)
{
Expand Down Expand Up @@ -83,13 +86,34 @@ public override async ValueTask<bool> HandleRpcAsync(ClientPlayer sender, Client
{
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;
}
Expand All @@ -108,6 +132,11 @@ internal async ValueTask SetPositionAsync(IClientPlayer sender, Vector2 position
_pool.Return(playerMovementEvent);
}

internal void OnPlayerSpawn()
{
_spawnSnapAllowed = true;
}

private static bool SidGreaterThan(ushort newSid, ushort prevSid)
{
var num = (ushort)(prevSid + (uint)short.MaxValue);
Expand All @@ -117,6 +146,12 @@ private static bool SidGreaterThan(ushort newSid, ushort prevSid)
: 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))
Expand Down
Original file line number Diff line number Diff line change
@@ -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;
Expand All @@ -15,6 +17,29 @@ public InnerAirshipStatus(Game game) : base(game)

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);
Expand Down
Original file line number Diff line number Diff line change
@@ -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;
Expand All @@ -15,6 +16,12 @@ public InnerMiraShipStatus(Game game) : base(game)

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);
Expand Down
Original file line number Diff line number Diff line change
@@ -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;
Expand All @@ -15,6 +16,34 @@ public InnerPolusShipStatus(Game game) : base(game)

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);
Expand Down
Original file line number Diff line number Diff line change
@@ -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;
Expand All @@ -26,6 +27,12 @@ protected InnerShipStatus(Game game) : base(game)

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++)
Expand Down Expand Up @@ -101,10 +108,27 @@ public override async ValueTask<bool> HandleRpcAsync(ClientPlayer sender, Client
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));
}
}
}
Original file line number Diff line number Diff line change
@@ -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;
Expand All @@ -15,6 +16,12 @@ public InnerSkeldShipStatus(Game game) : base(game)

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);
Expand Down
5 changes: 5 additions & 0 deletions src/Impostor.Server/Net/State/Game.Data.cs
Original file line number Diff line number Diff line change
Expand Up @@ -346,6 +346,11 @@ private async ValueTask OnSpawnAsync(InnerNetObject netObj)

case InnerMeetingHud meetingHud:
{
foreach (var player in _players.Values)
{
player.Character?.NetworkTransform.OnPlayerSpawn();
}

await _eventManager.CallAsync(new MeetingStartedEvent(this, meetingHud));
break;
}
Expand Down
6 changes: 3 additions & 3 deletions src/Impostor.Server/Net/State/Game.cs
Original file line number Diff line number Diff line change
Expand Up @@ -105,10 +105,10 @@ internal async ValueTask StartedAsync()
{
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;
Expand Down

0 comments on commit 4866a35

Please sign in to comment.