using Content.Server._Sunrise.CryoTeleport; using Content.Shared.Damage; using Content.Shared.DoAfter; using Content.Shared.Interaction; using Content.Shared.Mech; using Content.Shared.Mech.Components; using Content.Shared.Mech.EntitySystems; using Content.Shared.Popups; using Content.Shared.Verbs; using Content.Shared.Whitelist; using Robust.Shared.Utility; using PaintDoAfterEvent = Content.Shared._Sunrise.Paint.PaintDoAfterEvent; using Robust.Shared.Audio.Systems; using Content.Shared.Nutrition.EntitySystems; using Content.Server.Emp; using Robust.Shared.Timing; using Content.Shared._Sunrise.Mech; using Content.Shared.Coordinates; using Content.Shared.Emp; using Content.Shared.Damage.Systems; namespace Content.Server._Sunrise.Mech; /// public sealed partial class SunriseMechSystem : EntitySystem { [Dependency] private readonly DamageableSystem _damageable = default!; [Dependency] private readonly SharedDoAfterSystem _doAfter = default!; [Dependency] private readonly SharedPopupSystem _popup = default!; [Dependency] private readonly EntityWhitelistSystem _whitelistSystem = default!; [Dependency] private readonly SharedAudioSystem _audio = default!; [Dependency] private readonly OpenableSystem _openable = default!; [Dependency] private readonly IGameTiming _timing = default!; [Dependency] private readonly SharedAppearanceSystem _appearance = default!; [Dependency] private readonly SharedMechSystem _mech = default!; /// public override void Initialize() { base.Initialize(); SubscribeLocalEvent(OnInteract); SubscribeLocalEvent>(OnPaintVerb); SubscribeLocalEvent(OnEmpPulse); SubscribeLocalEvent(OnPaint); SubscribeLocalEvent(OnCryoTeleportAttemptEvent); } // Sunrise-start private void OnCryoTeleportAttemptEvent(EntityUid uid, MechPilotComponent component, BeforeCryoTeleportEvent args) { if (!TryComp(component.Mech, out var mechComponent)) return; _mech.TryEject(uid, mechComponent); } // Sunrise-end public override void Update(float frameTime) { base.Update(frameTime); var query = EntityQueryEnumerator(); while (query.MoveNext(out var uid, out var comp, out var emp)) { var curTime = _timing.CurTime; if (emp.NextEffectTime > curTime) continue; emp.NextEffectTime = curTime + emp.EffectInterval; SpawnAttachedTo(comp.EffectEMP, uid.ToCoordinates()); if (curTime > comp.NextPulseTime) RemComp(uid); } } private void OnEmpPulse(Entity ent, ref EmpPulseEvent args) { var curTime = _timing.CurTime; if (curTime < ent.Comp.NextPulseTime) return; ent.Comp.NextPulseTime = curTime + ent.Comp.CooldownTime; _damageable.TryChangeDamage(ent.Owner, ent.Comp.EmpDamage); EnsureComp(ent); } private void OnPaintVerb(EntityUid uid, MechPaintComponent component, GetVerbsEvent args) { if (!args.CanInteract || !args.CanAccess) return; if (!HasComp(args.Target)) return; var paintText = Loc.GetString("paint-verb"); var verb = new UtilityVerb() { Act = () => { PrepPaint(uid, component, args.Target, args.User); }, Text = paintText, Icon = new SpriteSpecifier.Texture(new("/Textures/Interface/VerbIcons/paint.svg.192dpi.png")) }; args.Verbs.Add(verb); } private void OnInteract(EntityUid uid, MechPaintComponent component, AfterInteractEvent args) { if (!args.CanReach) return; if (!Exists(args.Target)) return; if (!HasComp(args.Target)) return; PrepPaint(uid, component, args.Target, args.User); } private void OnPaint(Entity entity, ref PaintDoAfterEvent args) { if (args.Used == null || !HasComp(args.Target)) return; if (args.Handled || args.Cancelled) return; if (args.Target is not { Valid: true } target) return; if (!TryComp(target, out var appearance)) return; if (_openable.IsClosed(entity)) { _popup.PopupEntity(Loc.GetString("paint-closed", ("used", args.Used)), args.User, args.User, PopupType.Medium); return; } if (_whitelistSystem.IsWhitelistFailOrNull(entity.Comp.Whitelist, target)) { _popup.PopupEntity(Loc.GetString("paint-failure", ("target", args.Target)), args.User, args.User, PopupType.Medium); return; } if (entity.Comp.Used) { _popup.PopupEntity(Loc.GetString("paint-empty", ("used", args.Used)), args.User, args.User, PopupType.Medium); return; } _audio.PlayPvs(entity.Comp.Spray, entity); _popup.PopupEntity(Loc.GetString("paint-success", ("target", args.Target)), args.User, args.User, PopupType.Medium); entity.Comp.Used = true; args.Handled = true; _appearance.SetData(target, MechVisualLayers.Base, entity.Comp.BaseState, appearance); _appearance.SetData(target, MechVisualLayers.Open, entity.Comp.OpenState, appearance); _appearance.SetData(target, MechVisualLayers.Broken, entity.Comp.BrokenState, appearance); } private void PrepPaint(EntityUid uid, MechPaintComponent component, EntityUid? target, EntityUid user) { var doAfterEventArgs = new DoAfterArgs(EntityManager, user, component.Delay, new PaintDoAfterEvent(), uid, target: target, used: uid) { BreakOnMove = true, BreakOnDamage = true, NeedHand = true, BreakOnHandChange = true }; _doAfter.TryStartDoAfter(doAfterEventArgs); } }