using Content.Server.Body.Components; using Content.Server.Medical; using Content.Shared._DV.Abilities; using Content.Shared._DV.Abilities.Felinid; using Content.Shared.Chemistry.EntitySystems; using Content.Shared.Item; using Content.Shared.StatusEffect; using Content.Shared.Throwing; using Robust.Shared.Random; namespace Content.Server._DV.Abilities.Felinid; /// /// Handles felinid logic except for fitting in bags. /// /// /// This could be moved to shared if: /// 1. bloodstream was in shared /// 2. vomiting was in shared /// 3. this didn't use RNG. /// public sealed class FelinidSystem : SharedFelinidSystem { [Dependency] private readonly IRobustRandom _random = default!; [Dependency] private readonly SharedSolutionContainerSystem _solution = default!; [Dependency] private readonly VomitSystem _vomit = default!; public override void Initialize() { base.Initialize(); SubscribeLocalEvent(OnItemCoughedUp); SubscribeLocalEvent(OnHairballHit); SubscribeLocalEvent(OnHairballPickupAttempt); } private void OnItemCoughedUp(Entity ent, ref ItemCoughedUpEvent args) { if (!TryComp(ent, out var blood) || blood.ChemicalSolution is not {} solution) return; var item = args.Item; var hairball = Comp(item); var purged = _solution.SplitSolution(solution, ent.Comp.PurgedQuantity); if (_solution.TryGetSolution(item, hairball.SolutionName, out var hairballSolution)) { _solution.TryAddSolution(hairballSolution.Value, purged); } } private void OnHairballHit(Entity ent, ref ThrowDoHitEvent args) { TryVomit(ent, args.Target); } private void OnHairballPickupAttempt(Entity ent, ref GettingPickedUpAttemptEvent args) { if (TryVomit(ent, args.User)) args.Cancel(); } private bool TryVomit(Entity ent, EntityUid uid) { if (HasComp(uid) || !HasComp(uid)) return false; if (!_random.Prob(ent.Comp.VomitProb)) return false; _vomit.Vomit(uid); return true; } }