fish-station/Content.Server/_Sunrise/DamageOverlay/DamageOverlaySystem.cs
ThereDrD d07cbcda6e
Красивые циферки урона (#993)
* damage overlay refactor: new visuals and ignored damage types feature

* remove unused popup types

* add horizontal direction movement

* fix default popup type

* fix fix

* fix fix fix

* add damage overlay to structures

* comments + better implementation

* add ui dropdown option

* better values

* fix missing disabled sessions check

* asdasdadasd new commit on my pr

* ЧЕ БЛЯДЬ СЛОЖНО ДА

* ы

---------

Co-authored-by: Vigers Ray <vigersray@gmail.com>
2025-01-05 14:51:20 +03:00

123 lines
3.9 KiB
C#

using System.Numerics;
using Content.Server.Mind;
using Content.Server.Popups;
using Content.Shared._Sunrise.DamageOverlay;
using Content.Shared.Damage;
using Content.Shared.FixedPoint;
using Robust.Shared.Map;
using Robust.Shared.Player;
using Robust.Shared.Random;
namespace Content.Server._Sunrise.DamageOverlay;
public sealed class DamageOverlaySystem : EntitySystem
{
[Dependency] private readonly PopupSystem _popupSystem = default!;
[Dependency] private readonly MindSystem _mindSystem = default!;
[Dependency] private readonly IRobustRandom _random = default!;
private readonly List<ICommonSession> _disabledSessions = [];
private readonly Dictionary<ICommonSession, DamageOverlaySettings> _playerSettings = new ();
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<DamageOverlayComponent, DamageChangedEvent>(OnDamageChange);
SubscribeNetworkEvent<DamageOverlayOptionEvent>(OnDamageOverlayOption);
}
private async void OnDamageOverlayOption(DamageOverlayOptionEvent ev, EntitySessionEventArgs args)
{
if (ev.Enabled)
_disabledSessions.Remove(args.SenderSession);
else
_disabledSessions.Add(args.SenderSession);
_playerSettings[args.SenderSession] = new DamageOverlaySettings(ev.SelfEnabled, ev.StructuresEnabled);
}
private void OnDamageChange(Entity<DamageOverlayComponent> ent, ref DamageChangedEvent args)
{
if (args.DamageDelta == null)
return;
var damageDelta = args.DamageDelta.GetTotal();
var coords = GenerateRandomCoordinates(Transform(ent).Coordinates, ent.Comp.Radius);
if (_mindSystem.TryGetMind(ent, out _, out var mindTarget) && mindTarget.Session != null)
{
if (IsDisabledByClient(mindTarget.Session, ent))
return;
if (damageDelta > 0)
{
_popupSystem.PopupCoordinates($"-{damageDelta}", coords, mindTarget.Session, ent.Comp.DamagePopupType);
}
}
if (args.Origin == null)
return;
if (!_mindSystem.TryGetMind(args.Origin.Value, out _, out var mindOrigin) || mindOrigin.Session == null)
return;
if (IsDisabledByClient(mindOrigin.Session, ent))
return;
if (damageDelta > 0)
{
_popupSystem.PopupCoordinates($"-{damageDelta}", coords, mindOrigin.Session, ent.Comp.DamagePopupType);
}
else
{
_popupSystem.PopupCoordinates($"+{FixedPoint2.Abs(damageDelta)}", coords, mindOrigin.Session, ent.Comp.HealPopupType);
}
}
private EntityCoordinates GenerateRandomCoordinates(EntityCoordinates center, float radius)
{
var angle = _random.NextDouble() * 2 * Math.PI;
var distance = _random.NextDouble() * radius;
var offsetX = (float)(Math.Cos(angle) * distance);
var offsetY = (float)(Math.Sin(angle) * distance);
var newPosition = new Vector2(center.Position.X + offsetX, center.Position.Y + offsetY);
return new EntityCoordinates(center.EntityId, newPosition);
}
private bool IsDisabledByClient(ICommonSession session, Entity<DamageOverlayComponent> target)
{
if (_disabledSessions.Contains(session))
return true;
if (_playerSettings.TryGetValue(session, out var playerSettings))
{
if (target.Comp.IsStructure && !playerSettings.StructureDamage)
return true;
if (target == session.AttachedEntity && !playerSettings.SelfDamage)
return true;
}
return false;
}
private sealed class DamageOverlaySettings
{
public readonly bool StructureDamage;
public readonly bool SelfDamage;
public DamageOverlaySettings(bool evSelfEnabled, bool evStructuresEnabled)
{
SelfDamage = evSelfEnabled;
StructureDamage = evStructuresEnabled;
}
}
}