Esempio n. 1
0
    /// <summary>
    ///     Pushes gas from the lungs to a gas mixture.
    /// </summary>
    public void PushGasTo(EntityUid uid, GasMixture to,
                          LungComponent?lung      = null,
                          MechanismComponent?mech = null)
    {
        if (!Resolve(uid, ref lung, ref mech))
        {
            return;
        }

        // TODO: Make the bloodstream separately pump toxins into the lungs, making the lungs' only job to empty.
        if (mech.Body == null)
        {
            return;
        }

        if (!EntityManager.TryGetComponent((mech.Body).Owner, out BloodstreamComponent? bloodstream))
        {
            return;
        }

        _bloodstreamSystem.PumpToxins((mech.Body).Owner, lung.Air, bloodstream);

        var lungRemoved = lung.Air.RemoveRatio(0.5f);

        _atmosSys.Merge(to, lungRemoved);
    }
Esempio n. 2
0
    /// <summary>
    ///     Inhales directly from a given mixture.
    /// </summary>
    public void TakeGasFrom(EntityUid uid, float frameTime, GasMixture from,
                            LungComponent?lung      = null,
                            MechanismComponent?mech = null)
    {
        if (!Resolve(uid, ref lung, ref mech))
        {
            return;
        }

        var ratio = (Atmospherics.BreathVolume / from.Volume) * frameTime;

        _atmosSys.Merge(lung.Air, from.RemoveRatio(ratio));

        // Push to bloodstream
        if (mech.Body == null)
        {
            return;
        }

        if (!EntityManager.TryGetComponent((mech.Body).Owner, out BloodstreamComponent? bloodstream))
        {
            return;
        }

        var to = bloodstream.Air;

        _atmosSys.Merge(to, lung.Air);
        lung.Air.Clear();
    }
Esempio n. 3
0
    /// <summary>
    ///     Tries to find an air mixture to inhale from, then inhales from it.
    /// </summary>
    public void Inhale(EntityUid uid, float frameTime,
                       LungComponent?lung      = null,
                       MechanismComponent?mech = null)
    {
        if (!Resolve(uid, ref lung, ref mech))
        {
            return;
        }

        // TODO Jesus Christ make this event based.
        if (mech.Body != null &&
            EntityManager.TryGetComponent((mech.Body).Owner, out InternalsComponent? internals) &&
            internals.BreathToolEntity != null &&
            internals.GasTankEntity != null &&
            EntityManager.TryGetComponent(internals.BreathToolEntity, out BreathToolComponent? breathTool) &&
            breathTool.IsFunctional &&
            EntityManager.TryGetComponent(internals.GasTankEntity, out GasTankComponent? gasTank))
        {
            TakeGasFrom(uid, frameTime, gasTank.RemoveAirVolume(Atmospherics.BreathVolume), lung);
            return;
        }

        if (_atmosSys.GetTileMixture(EntityManager.GetComponent <TransformComponent>(uid).Coordinates, true) is not {
        } tileAir)
        {
            return;
        }

        TakeGasFrom(uid, frameTime, tileAir, lung);
    }
Esempio n. 4
0
    public void UpdateLung(EntityUid uid,
                           LungComponent?lung      = null,
                           MechanismComponent?mech = null)
    {
        if (!Resolve(uid, ref lung, ref mech))
        {
            return;
        }

        if (mech.Body != null && EntityManager.TryGetComponent((mech.Body).Owner, out MobStateComponent? mobState) && mobState.IsCritical())
        {
            return;
        }

        if (lung.Status == LungStatus.None)
        {
            lung.Status = LungStatus.Inhaling;
        }

        lung.AccumulatedFrametime += lung.Status switch
        {
            LungStatus.Inhaling => 1,
            LungStatus.Exhaling => - 1,
            _ => throw new ArgumentOutOfRangeException()
        };

        var absoluteTime = Math.Abs(lung.AccumulatedFrametime);
        var delay        = lung.CycleDelay;

        if (absoluteTime < delay)
        {
            return;
        }

        switch (lung.Status)
        {
        case LungStatus.Inhaling:
            Inhale(uid, absoluteTime);
            lung.Status = LungStatus.Exhaling;
            break;

        case LungStatus.Exhaling:
            Exhale(uid, absoluteTime);
            lung.Status = LungStatus.Inhaling;
            break;

        default:
            throw new ArgumentOutOfRangeException();
        }

        lung.AccumulatedFrametime = absoluteTime - delay;
    }
Esempio n. 5
0
    /// <summary>
    ///     Tries to find a gas mixture to exhale to, then pushes gas to it.
    /// </summary>
    public void Exhale(EntityUid uid, float frameTime,
                       LungComponent?lung      = null,
                       MechanismComponent?mech = null)
    {
        if (!Resolve(uid, ref lung, ref mech))
        {
            return;
        }

        if (_atmosSys.GetTileMixture(EntityManager.GetComponent <TransformComponent>(uid).Coordinates, true) is not {
        } tileAir)
        {
            return;
        }

        PushGasTo(uid, tileAir, lung, mech);
    }
    public void Gasp(EntityUid uid,
                     LungComponent?lung            = null,
                     SharedMechanismComponent?mech = null)
    {
        if (!Resolve(uid, ref lung))
        {
            return;
        }

        if (_gameTiming.CurTime >= lung.LastGaspPopupTime + lung.GaspPopupCooldown)
        {
            lung.LastGaspPopupTime = _gameTiming.CurTime;
            _popupSystem.PopupEntity(Loc.GetString("lung-behavior-gasp"), uid, Filter.Pvs(uid));
        }

        Inhale(uid, lung.CycleDelay);
    }
Esempio n. 7
0
    public void Gasp(EntityUid uid,
                     LungComponent?lung      = null,
                     MechanismComponent?mech = null)
    {
        if (!Resolve(uid, ref lung, ref mech))
        {
            return;
        }

        if (_gameTiming.CurTime >= lung.LastGaspPopupTime + lung.GaspPopupCooldown)
        {
            lung.LastGaspPopupTime = _gameTiming.CurTime;
            _popupSystem.PopupEntity(Loc.GetString("lung-behavior-gasp"), uid, Filter.Pvs(uid));
        }

        if (mech.Body != null && TryComp((mech.Body).Owner, out MobStateComponent? mobState) && !mobState.IsAlive())
        {
            return;
        }

        Inhale(uid, lung.CycleDelay);
    }