using Content.Server.Guardian; using Content.Server.Popups; using Content.Shared.DoAfter; using Content.Shared.IdentityManagement; using Content.Shared.Implants; using Content.Shared.Implants.Components; using Content.Shared.Interaction; using Content.Shared.Mobs.Components; using Content.Shared.Popups; using Robust.Shared.Containers; namespace Content.Server.Implants; public sealed partial class ImplanterSystem : SharedImplanterSystem { [Dependency] private readonly PopupSystem _popup = default!; [Dependency] private readonly SharedDoAfterSystem _doAfter = default!; [Dependency] private readonly SharedContainerSystem _container = default!; public override void Initialize() { base.Initialize(); InitializeImplanted(); SubscribeLocalEvent(OnImplanterAfterInteract); SubscribeLocalEvent(OnImplant); SubscribeLocalEvent(OnDraw); } private void OnImplanterAfterInteract(EntityUid uid, ImplanterComponent component, AfterInteractEvent args) { if (args.Target == null || !args.CanReach || args.Handled) return; //Simplemobs and regular mobs should be injectable, but only regular mobs have mind. //So just don't implant/draw anything that isn't living or is a guardian //TODO: Rework a bit when surgery is in to work with implant cases if (!HasComp(args.Target.Value) || HasComp(args.Target.Value)) return; //TODO: Rework when surgery is in for implant cases if (component.CurrentMode == ImplanterToggleMode.Draw && !component.ImplantOnly) { TryDraw(component, args.User, args.Target.Value, uid); } else { if (!CanImplant(args.User, args.Target.Value, uid, component, out _, out _)) return; //Implant self instantly, otherwise try to inject the target. if (args.User == args.Target) Implant(args.User, args.Target.Value, uid, component); else TryImplant(component, args.User, args.Target.Value, uid); } args.Handled = true; } /// /// Attempt to implant someone else. /// /// Implanter component /// The entity using the implanter /// The entity being implanted /// The implanter being used public void TryImplant(ImplanterComponent component, EntityUid user, EntityUid target, EntityUid implanter) { var args = new DoAfterArgs(EntityManager, user, component.ImplantTime, new ImplantEvent(), implanter, target: target, used: implanter) { BreakOnUserMove = true, BreakOnTargetMove = true, BreakOnDamage = true, NeedHand = true, }; if (!_doAfter.TryStartDoAfter(args)) return; _popup.PopupEntity(Loc.GetString("injector-component-injecting-user"), target, user); var userName = Identity.Entity(user, EntityManager); _popup.PopupEntity(Loc.GetString("implanter-component-implanting-target", ("user", userName)), user, target, PopupType.LargeCaution); } /// /// Try to remove an implant and store it in an implanter /// /// Implanter component /// The entity using the implanter /// The entity getting their implant removed /// The implanter being used //TODO: Remove when surgery is in public void TryDraw(ImplanterComponent component, EntityUid user, EntityUid target, EntityUid implanter) { var args = new DoAfterArgs(EntityManager, user, component.DrawTime, new DrawEvent(), implanter, target: target, used: implanter) { BreakOnUserMove = true, BreakOnTargetMove = true, BreakOnDamage = true, NeedHand = true, }; if (_doAfter.TryStartDoAfter(args)) _popup.PopupEntity(Loc.GetString("injector-component-injecting-user"), target, user); } private void OnImplant(EntityUid uid, ImplanterComponent component, ImplantEvent args) { if (args.Cancelled || args.Handled || args.Target == null || args.Used == null) return; Implant(args.User, args.Target.Value, args.Used.Value, component); args.Handled = true; } private void OnDraw(EntityUid uid, ImplanterComponent component, DrawEvent args) { if (args.Cancelled || args.Handled || args.Used == null || args.Target == null) return; Draw(args.Used.Value, args.User, args.Target.Value, component); args.Handled = true; } }