/// <summary>
        ///     Attempts to remove a status effect from an entity.
        /// </summary>
        /// <param name="uid">The entity to remove an effect from.</param>
        /// <param name="key">The effect ID to remove.</param>
        /// <param name="status">The status effects component to change, if you already have it.</param>
        /// <returns>False if the effect could not be removed, true otherwise.</returns>
        /// <remarks>
        ///     Obviously this doesn't automatically clear any effects a status effect might have.
        ///     That's up to the removed component to handle itself when it's removed.
        /// </remarks>
        public bool TryRemoveStatusEffect(EntityUid uid, string key,
                                          StatusEffectsComponent?status = null)
        {
            if (!Resolve(uid, ref status, false))
            {
                return(false);
            }
            if (!status.ActiveEffects.ContainsKey(key))
            {
                return(false);
            }
            if (!_prototypeManager.TryIndex <StatusEffectPrototype>(key, out var proto))
            {
                return(false);
            }

            var state = status.ActiveEffects[key];

            // There are cases where a status effect component might be server-only, so TryGetRegistration...
            if (state.RelevantComponent != null && _componentFactory.TryGetRegistration(state.RelevantComponent, out var registration))
            {
                var type = registration.Type;

                // Make sure the component is actually there first.
                // Maybe a badmin badminned the component away,
                // or perhaps, on the client, the component deletion sync
                // was faster than prediction could predict. Either way, let's not assume the component exists.
                if (EntityManager.HasComponent(uid, type))
                {
                    EntityManager.RemoveComponent(uid, type);
                }
            }

            if (proto.Alert != null)
            {
                _alertsSystem.ClearAlert(uid, proto.Alert.Value);
            }

            status.ActiveEffects.Remove(key);
            if (status.ActiveEffects.Count == 0)
            {
                RemComp <ActiveStatusEffectsComponent>(uid);
            }

            Dirty(status);
            // event?
            return(true);
        }
예제 #2
0
    private void OnEntityInserted(EntityUid uid, PayloadCaseComponent _, EntInsertedIntoContainerMessage args)
    {
        if (!TryComp(args.Entity, out PayloadTriggerComponent? trigger))
        {
            return;
        }

        trigger.Active = true;

        if (trigger.Components == null)
        {
            return;
        }

        // ANY payload trigger that gets inserted can grant components. It is up to the construction graphs to determine trigger capacity.
        foreach (var(name, data) in trigger.Components)
        {
            if (!_componentFactory.TryGetRegistration(name, out var registration))
            {
                continue;
            }

            if (HasComp(uid, registration.Type))
            {
                continue;
            }

            if (_componentFactory.GetComponent(registration.Type) is not Component component)
            {
                continue;
            }

            component.Owner = uid;

            if (_serializationManager.Copy(data, component, null) is Component copied)
            {
                EntityManager.AddComponent(uid, copied);
            }

            trigger.GrantedComponents.Add(registration.Type);
        }
    }