Files
tbd-station-14/Content.Server/Gravity/EntitySystems/GravityShakeSystem.cs
Vera Aguilera Puerto 5cd42c9ad6 Inline UID
2021-12-03 15:53:09 +01:00

94 lines
2.9 KiB
C#

using System.Collections.Generic;
using Content.Server.Camera;
using Content.Shared.Gravity;
using Robust.Server.Player;
using Robust.Shared.Audio;
using Robust.Shared.GameObjects;
using Robust.Shared.IoC;
using Robust.Shared.Map;
using Robust.Shared.Maths;
using Robust.Shared.Player;
using Robust.Shared.Random;
namespace Content.Server.Gravity.EntitySystems
{
/// <summary>
/// Handles the grid shake effect used by the gravity generator.
/// </summary>
public sealed class GravityShakeSystem : EntitySystem
{
[Dependency] private readonly IPlayerManager _playerManager = default!;
[Dependency] private readonly IRobustRandom _random = default!;
private Dictionary<GridId, uint> _gridsToShake = new();
private const float GravityKick = 100.0f;
private const uint ShakeTimes = 10;
private float _internalTimer;
public override void Update(float frameTime)
{
if (_gridsToShake.Count > 0)
{
_internalTimer += frameTime;
if (_internalTimer > 0.2f)
{
// TODO: Could just have clients do this themselves via event and save bandwidth.
ShakeGrids();
_internalTimer -= 0.2f;
}
}
else
{
_internalTimer = 0.0f;
}
}
public void ShakeGrid(GridId gridId, GravityComponent comp)
{
_gridsToShake[gridId] = ShakeTimes;
SoundSystem.Play(
Filter.BroadcastGrid(gridId),
comp.GravityShakeSound.GetSound(),
AudioParams.Default.WithVolume(-2f));
}
private void ShakeGrids()
{
// I have to copy this because C# doesn't allow changing collections while they're
// getting enumerated.
var gridsToShake = new Dictionary<GridId, uint>(_gridsToShake);
foreach (var gridId in _gridsToShake.Keys)
{
if (_gridsToShake[gridId] == 0)
{
gridsToShake.Remove(gridId);
continue;
}
ShakeGrid(gridId);
gridsToShake[gridId] -= 1;
}
_gridsToShake = gridsToShake;
}
private void ShakeGrid(GridId gridId)
{
foreach (var player in _playerManager.Sessions)
{
if (player.AttachedEntity == null
|| IoCManager.Resolve<IEntityManager>().GetComponent<TransformComponent>(player.AttachedEntity).GridID != gridId
|| !IoCManager.Resolve<IEntityManager>().TryGetComponent(player.AttachedEntity, out CameraRecoilComponent? recoil))
{
continue;
}
recoil.Kick(new Vector2(_random.NextFloat(), _random.NextFloat()) * GravityKick);
}
}
}
}