using Content.Server.Atmos; using Content.Server.Atmos.EntitySystems; using Content.Server.Body.Components; using Content.Server.DoAfter; using Content.Server.Explosion.EntitySystems; using Content.Server.Nutrition.Components; using Content.Server.Popups; using Content.Shared.Damage; using Content.Shared.DoAfter; using Content.Shared.Emag.Components; using Content.Shared.Emag.Systems; using Content.Shared.IdentityManagement; using Content.Shared.Interaction; using Content.Shared.Nutrition; using System.Threading; using Content.Shared.Atmos; /// /// System for vapes /// namespace Content.Server.Nutrition.EntitySystems { public sealed partial class SmokingSystem { [Dependency] private readonly DoAfterSystem _doAfterSystem = default!; [Dependency] private readonly DamageableSystem _damageableSystem = default!; [Dependency] private readonly EmagSystem _emag = default!; [Dependency] private readonly FoodSystem _foodSystem = default!; [Dependency] private readonly ExplosionSystem _explosionSystem = default!; [Dependency] private readonly PopupSystem _popupSystem = default!; private void InitializeVapes() { SubscribeLocalEvent(OnVapeInteraction); SubscribeLocalEvent(OnVapeDoAfter); SubscribeLocalEvent(OnEmagged); } private void OnVapeInteraction(Entity entity, ref AfterInteractEvent args) { var delay = entity.Comp.Delay; var forced = true; var exploded = false; if (!args.CanReach || !_solutionContainerSystem.TryGetRefillableSolution(entity.Owner, out _, out var solution) || !HasComp(args.Target) || _foodSystem.IsMouthBlocked(args.Target.Value, args.User)) { return; } if (solution.Contents.Count == 0) { _popupSystem.PopupEntity( Loc.GetString("vape-component-vape-empty"), args.Target.Value, args.User); return; } if (args.Target == args.User) { delay = entity.Comp.UserDelay; forced = false; } if (entity.Comp.ExplodeOnUse || _emag.CheckFlag(entity, EmagType.Interaction)) { _explosionSystem.QueueExplosion(entity.Owner, "Default", entity.Comp.ExplosionIntensity, 0.5f, 3, canCreateVacuum: false); EntityManager.DeleteEntity(entity); exploded = true; } else { // All vapes explode if they contain anything other than pure water??? // WTF is this? Why is this? Am I going insane? // Who the fuck vapes pure water? // If this isn't how this is meant to work and this is meant to be for vapes with plasma or something, // just re-use the existing RiggableSystem. foreach (var name in solution.Contents) { if (name.Reagent.Prototype != entity.Comp.SolutionNeeded) { exploded = true; _explosionSystem.QueueExplosion(entity.Owner, "Default", entity.Comp.ExplosionIntensity, 0.5f, 3, canCreateVacuum: false); EntityManager.DeleteEntity(entity); break; } } } if (forced) { var targetName = Identity.Entity(args.Target.Value, EntityManager); var userName = Identity.Entity(args.User, EntityManager); _popupSystem.PopupEntity( Loc.GetString("vape-component-try-use-vape-forced", ("user", userName)), args.Target.Value, args.Target.Value); _popupSystem.PopupEntity( Loc.GetString("vape-component-try-use-vape-forced-user", ("target", targetName)), args.User, args.User); } else { _popupSystem.PopupEntity( Loc.GetString("vape-component-try-use-vape"), args.User, args.User); } if (!exploded) { var vapeDoAfterEvent = new VapeDoAfterEvent(solution, forced); _doAfterSystem.TryStartDoAfter(new DoAfterArgs(EntityManager, args.User, delay, vapeDoAfterEvent, entity.Owner, target: args.Target, used: entity.Owner) { BreakOnMove = false, BreakOnDamage = true }); } args.Handled = true; } private void OnVapeDoAfter(Entity entity, ref VapeDoAfterEvent args) { if (args.Cancelled || args.Handled || args.Args.Target == null) return; var environment = _atmos.GetContainingMixture(args.Args.Target.Value, true, true); if (environment == null) { return; } //Smoking kills(your lungs, but there is no organ damage yet) _damageableSystem.TryChangeDamage(args.Args.Target.Value, entity.Comp.Damage, true); var merger = new GasMixture(1) { Temperature = args.Solution.Temperature }; merger.SetMoles(entity.Comp.GasType, args.Solution.Volume.Value / entity.Comp.ReductionFactor); _atmos.Merge(environment, merger); args.Solution.RemoveAllSolution(); if (args.Forced) { var targetName = Identity.Entity(args.Args.Target.Value, EntityManager); var userName = Identity.Entity(args.Args.User, EntityManager); _popupSystem.PopupEntity( Loc.GetString("vape-component-vape-success-forced", ("user", userName)), args.Args.Target.Value, args.Args.Target.Value); _popupSystem.PopupEntity( Loc.GetString("vape-component-vape-success-user-forced", ("target", targetName)), args.Args.User, args.Args.Target.Value); } else { _popupSystem.PopupEntity( Loc.GetString("vape-component-vape-success"), args.Args.Target.Value, args.Args.Target.Value); } } private void OnEmagged(Entity entity, ref GotEmaggedEvent args) { if (!_emag.CompareFlag(args.Type, EmagType.Interaction)) return; if (_emag.CheckFlag(entity, EmagType.Interaction)) return; args.Handled = true; } } }