Ejemplo n.º 1
0
 /// <summary>
 ///     If the damage in a DamageableComponent was changed, this function should be called.
 /// </summary>
 /// <remarks>
 ///     This updates cached damage information, flags the component as dirty, and raises a damage changed event.
 ///     The damage changed event is used by other systems, such as damage thresholds.
 /// </remarks>
 public void DamageChanged(DamageableComponent component, DamageSpecifier?damageDelta = null)
 {
     component.DamagePerGroup = component.Damage.GetDamagePerGroup();
     component.TotalDamage    = component.Damage.Total;
     component.Dirty();
     RaiseLocalEvent(component.Owner.Uid, new DamageChangedEvent(component, damageDelta), false);
 }
        /// <summary>
        ///     Initialize a damageable component
        /// </summary>
        private void DamageableInit(EntityUid uid, DamageableComponent component, ComponentInit _)
        {
            if (component.DamageContainerID != null &&
                _prototypeManager.TryIndex <DamageContainerPrototype>(component.DamageContainerID,
                                                                      out var damageContainerPrototype))
            {
                // Initialize damage dictionary, using the types and groups from the damage
                // container prototype
                foreach (var type in damageContainerPrototype.SupportedTypes)
                {
                    component.Damage.DamageDict.TryAdd(type, FixedPoint2.Zero);
                }

                foreach (var groupID in damageContainerPrototype.SupportedGroups)
                {
                    var group = _prototypeManager.Index <DamageGroupPrototype>(groupID);
                    foreach (var type in group.DamageTypes)
                    {
                        component.Damage.DamageDict.TryAdd(type, FixedPoint2.Zero);
                    }
                }
            }
            else
            {
                // No DamageContainerPrototype was given. So we will allow the container to support all damage types
                foreach (var type in _prototypeManager.EnumeratePrototypes <DamageTypePrototype>())
                {
                    component.Damage.DamageDict.TryAdd(type.ID, FixedPoint2.Zero);
                }
            }

            component.DamagePerGroup = component.Damage.GetDamagePerGroup();
            component.TotalDamage    = component.Damage.Total;
        }
        /// <summary>
        ///     If the damage in a DamageableComponent was changed, this function should be called.
        /// </summary>
        /// <remarks>
        ///     This updates cached damage information, flags the component as dirty, and raises a damage changed event.
        ///     The damage changed event is used by other systems, such as damage thresholds.
        /// </remarks>
        public void DamageChanged(DamageableComponent component, DamageSpecifier?damageDelta = null,
                                  bool interruptsDoAfters = true)
        {
            component.DamagePerGroup = component.Damage.GetDamagePerGroup();
            component.TotalDamage    = component.Damage.Total;
            component.Dirty();

            if (EntityManager.TryGetComponent <AppearanceComponent>(component.Owner, out var appearance) && damageDelta != null)
            {
                appearance.SetData(DamageVisualizerKeys.DamageUpdateGroups, damageDelta.GetDamagePerGroup().Keys.ToList());
            }
            RaiseLocalEvent(component.Owner, new DamageChangedEvent(component, damageDelta, interruptsDoAfters), false);
        }
        private void OnIrradiated(EntityUid uid, DamageableComponent component, OnIrradiatedEvent args)
        {
            var damageValue = FixedPoint2.New(args.TotalRads);

            // Radiation should really just be a damage group instead of a list of types.
            DamageSpecifier damage = new();

            foreach (var typeId in component.RadiationDamageTypeIDs)
            {
                damage.DamageDict.Add(typeId, damageValue);
            }

            TryChangeDamage(uid, damage);
        }
        /// <summary>
        ///     Sets all damage types supported by a <see cref="DamageableComponent"/> to the specified value.
        /// </summary>
        /// <remakrs>
        ///     Does nothing If the given damage value is negative.
        /// </remakrs>
        public void SetAllDamage(DamageableComponent component, FixedPoint2 newValue)
        {
            if (newValue < 0)
            {
                // invalid value
                return;
            }

            foreach (var type in component.Damage.DamageDict.Keys)
            {
                component.Damage.DamageDict[type] = newValue;
            }

            // Setting damage does not count as 'dealing' damage, even if it is set to a larger value, so we pass an
            // empty damage delta.
            DamageChanged(component, new DamageSpecifier());
        }
Ejemplo n.º 6
0
        public DamageChangedEvent(DamageableComponent damageable, DamageSpecifier?damageDelta)
        {
            Damageable  = damageable;
            DamageDelta = damageDelta;

            if (DamageDelta == null)
            {
                return;
            }

            foreach (var damageChange in DamageDelta.DamageDict.Values)
            {
                if (damageChange > 0)
                {
                    DamageIncreased = true;
                    break;
                }
            }
        }
        public DamageChangedEvent(DamageableComponent damageable, DamageSpecifier?damageDelta, bool interruptsDoAfters)
        {
            Damageable  = damageable;
            DamageDelta = damageDelta;

            if (DamageDelta == null)
            {
                return;
            }

            foreach (var damageChange in DamageDelta.DamageDict.Values)
            {
                if (damageChange > 0)
                {
                    DamageIncreased = true;
                    break;
                }
            }
            InterruptsDoAfters = interruptsDoAfters && DamageIncreased;
        }
        private void DamageableHandleState(EntityUid uid, DamageableComponent component, ref ComponentHandleState args)
        {
            if (args.Current is not DamageableComponentState state)
            {
                return;
            }

            component.DamageModifierSetId = state.ModifierSetId;

            // Has the damage actually changed?
            DamageSpecifier newDamage = new() { DamageDict = new(state.DamageDict) };
            var             delta     = component.Damage - newDamage;

            delta.TrimZeros();

            if (!delta.Empty)
            {
                component.Damage = newDamage;
                DamageChanged(component, delta);
            }
        }
 /// <summary>
 ///     Directly sets the damage specifier of a damageable component.
 /// </summary>
 /// <remarks>
 ///     Useful for some unfriendly folk. Also ensures that cached values are updated and that a damage changed
 ///     event is raised.
 /// </remarks>
 public void SetDamage(DamageableComponent damageable, DamageSpecifier damage)
 {
     damageable.Damage = damage;
     DamageChanged(damageable);
 }
 private void DamageableGetState(EntityUid uid, DamageableComponent component, ref ComponentGetState args)
 {
     args.State = new DamageableComponentState(component.Damage.DamageDict, component.DamageModifierSetId);
 }