using Content.Shared.Damage.Components; using Content.Shared.Whitelist; using Robust.Shared.Physics.Components; using Robust.Shared.Physics.Events; using Robust.Shared.Physics.Systems; using Robust.Shared.Timing; namespace Content.Shared.Damage.Systems; public sealed class DamageContactsSystem : EntitySystem { [Dependency] private readonly IGameTiming _timing = default!; [Dependency] private readonly DamageableSystem _damageable = default!; [Dependency] private readonly SharedPhysicsSystem _physics = default!; [Dependency] private readonly EntityWhitelistSystem _whitelistSystem = default!; public override void Initialize() { base.Initialize(); SubscribeLocalEvent(OnEntityEnter); SubscribeLocalEvent(OnEntityExit); } public override void Update(float frameTime) { base.Update(frameTime); var query = EntityQueryEnumerator(); while (query.MoveNext(out var ent, out var damaged)) { if (_timing.CurTime < damaged.NextSecond) continue; damaged.NextSecond = _timing.CurTime + TimeSpan.FromSeconds(1); if (damaged.Damage != null) _damageable.TryChangeDamage(ent, damaged.Damage, interruptsDoAfters: false); } } private void OnEntityExit(EntityUid uid, DamageContactsComponent component, ref EndCollideEvent args) { var otherUid = args.OtherEntity; if (!TryComp(uid, out var body)) return; var damageQuery = GetEntityQuery(); foreach (var ent in _physics.GetContactingEntities(uid, body)) { if (ent == uid) continue; if (damageQuery.HasComponent(ent)) return; } RemComp(otherUid); } private void OnEntityEnter(EntityUid uid, DamageContactsComponent component, ref StartCollideEvent args) { var otherUid = args.OtherEntity; if (HasComp(otherUid)) return; if (_whitelistSystem.IsWhitelistFail(component.IgnoreWhitelist, otherUid)) return; var damagedByContact = EnsureComp(otherUid); damagedByContact.Damage = component.Damage; } }