Beispiel #1
0
        public virtual void Apply(ActionType type, float deltaTime, Entity entity, ISerializableEntity target)
        {
            if (this.type != type || !HasRequiredItems(entity))
            {
                return;
            }

            if (targetIdentifiers != null && !IsValidTarget(target))
            {
                return;
            }

            if (duration > 0.0f && !Stackable)
            {
                //ignore if not stackable and there's already an identical statuseffect
                DurationListElement existingEffect = DurationList.Find(d => d.Parent == this && d.Targets.FirstOrDefault() == target);
                if (existingEffect != null)
                {
                    existingEffect.Timer = Math.Max(existingEffect.Timer, duration);
                    return;
                }
            }

            List <ISerializableEntity> targets = new List <ISerializableEntity> {
                target
            };

            if (!HasRequiredConditions(targets))
            {
                return;
            }

            Apply(deltaTime, entity, targets);
        }
        public virtual void Apply(ActionType type, float deltaTime, Entity entity, List <ISerializableEntity> targets, Character causecharacter = null, string identifier = "")
        {
            if (this.type != type)
            {
                return;
            }

            //remove invalid targets
            if (targetNames != null)
            {
                targets.RemoveAll(t =>
                {
                    Item item = t as Item;
                    if (item == null)
                    {
                        return(!targetNames.Contains(t.Name));
                    }
                    else
                    {
                        if (item.HasTag(targetNames))
                        {
                            return(false);
                        }
                        if (item.Prefab.NameMatches(targetNames))
                        {
                            return(false);
                        }
                    }
                    return(true);
                });
                if (targets.Count == 0)
                {
                    return;
                }
            }

            if (!HasRequiredItems(entity) || !HasRequiredConditions(targets))
            {
                return;
            }

            if (duration > 0.0f && !Stackable)
            {
                //ignore if not stackable and there's already an identical statuseffect
                DurationListElement existingEffect = DurationList.Find(d => d.Parent == this && d.Targets.SequenceEqual(targets));
                if (existingEffect != null)
                {
                    existingEffect.Timer          = Math.Max(existingEffect.Timer, duration);
                    existingEffect.causecharacter = causecharacter;
                    return;
                }
            }

            Apply(deltaTime, entity, targets, null, causecharacter, identifier);
        }
Beispiel #3
0
        public virtual void Apply(ActionType type, float deltaTime, Entity entity, IEnumerable <ISerializableEntity> targets)
        {
            if (this.type != type)
            {
                return;
            }

            currentTargets.Clear();
            foreach (ISerializableEntity target in targets)
            {
                if (targetIdentifiers != null)
                {
                    //ignore invalid targets
                    if (!IsValidTarget(target))
                    {
                        continue;
                    }
                }
                currentTargets.Add(target);
            }

            if (targetIdentifiers != null && currentTargets.Count == 0)
            {
                return;
            }

            if (!HasRequiredItems(entity) || !HasRequiredConditions(currentTargets))
            {
                return;
            }

            if (duration > 0.0f && !Stackable)
            {
                //ignore if not stackable and there's already an identical statuseffect
                DurationListElement existingEffect = DurationList.Find(d => d.Parent == this && d.Targets.SequenceEqual(currentTargets));
                if (existingEffect != null)
                {
                    existingEffect.Timer = Math.Max(existingEffect.Timer, duration);
                    existingEffect.User  = user;
                    return;
                }
            }

            Apply(deltaTime, entity, currentTargets);
        }
Beispiel #4
0
        public static void UpdateAll(float deltaTime)
        {
            DelayedEffect.Update(deltaTime);
            for (int i = DurationList.Count - 1; i >= 0; i--)
            {
                DurationListElement element = DurationList[i];

                if (element.Parent.CheckConditionalAlways && !element.Parent.HasRequiredConditions(element.Targets))
                {
                    DurationList.RemoveAt(i);
                    continue;
                }

                element.Targets.RemoveAll(t => t is Entity entity && entity.Removed);
                if (element.Targets.Count == 0)
                {
                    DurationList.RemoveAt(i);
                    continue;
                }

                foreach (ISerializableEntity target in element.Targets)
                {
                    for (int n = 0; n < element.Parent.propertyNames.Length; n++)
                    {
                        if (target == null || target.SerializableProperties == null || !target.SerializableProperties.TryGetValue(element.Parent.propertyNames[n], out SerializableProperty property))
                        {
                            continue;
                        }

                        element.Parent.ApplyToProperty(property, element.Parent.propertyEffects[n], CoroutineManager.UnscaledDeltaTime);
                    }
                }

                element.Timer -= deltaTime;

                if (element.Timer > 0.0f)
                {
                    continue;
                }
                DurationList.Remove(element);
            }
        }
        public virtual void Apply(ActionType type, float deltaTime, Entity entity, ISerializableEntity target, Character causecharacter = null, string identifier = "")
        {
            if (this.type != type || !HasRequiredItems(entity))
            {
                return;
            }

            if (targetNames != null && !targetNames.Contains(target.Name))
            {
                return;
            }

            if (duration > 0.0f && !Stackable)
            {
                //ignore if not stackable and there's already an identical statuseffect
                //if (DurationList.Any(d => d.Parent == this && d.Entity == entity && d.Targets.Count == 1 && d.Targets[0] == target)) return;

                DurationListElement existingEffect = DurationList.Find(d => d.Parent == this && d.Targets.Count == 1 && d.Targets[0] == target);
                if (existingEffect != null)
                {
                    existingEffect.Timer          = Math.Max(existingEffect.Timer, duration);
                    existingEffect.causecharacter = causecharacter;
                    return;
                }
            }

            List <ISerializableEntity> targets = new List <ISerializableEntity>();

            targets.Add(target);

            if (!HasRequiredConditions(targets))
            {
                return;
            }

            Apply(deltaTime, entity, targets, null, causecharacter, identifier);
        }
Beispiel #6
0
        public static void UpdateAll(float deltaTime)
        {
            UpdateAllProjSpecific(deltaTime);

            DelayedEffect.Update(deltaTime);
            for (int i = DurationList.Count - 1; i >= 0; i--)
            {
                DurationListElement element = DurationList[i];

                if (element.Parent.CheckConditionalAlways && !element.Parent.HasRequiredConditions(element.Targets))
                {
                    DurationList.RemoveAt(i);
                    continue;
                }

                element.Targets.RemoveAll(t =>
                                          (t is Entity entity && entity.Removed) ||
                                          (t is Limb limb && (limb.character == null || limb.character.Removed)));
                if (element.Targets.Count == 0)
                {
                    DurationList.RemoveAt(i);
                    continue;
                }

                foreach (ISerializableEntity target in element.Targets)
                {
                    for (int n = 0; n < element.Parent.propertyNames.Length; n++)
                    {
                        if (target == null ||
                            target.SerializableProperties == null ||
                            !target.SerializableProperties.TryGetValue(element.Parent.propertyNames[n], out SerializableProperty property))
                        {
                            continue;
                        }
                        element.Parent.ApplyToProperty(target, property, element.Parent.propertyEffects[n], CoroutineManager.UnscaledDeltaTime);
                    }

                    foreach (Affliction affliction in element.Parent.Afflictions)
                    {
                        Affliction multipliedAffliction = affliction;
                        if (!element.Parent.disableDeltaTime)
                        {
                            multipliedAffliction = affliction.CreateMultiplied(deltaTime);
                        }

                        if (target is Character character)
                        {
                            character.AddDamage(character.WorldPosition, new List <Affliction>()
                            {
                                multipliedAffliction
                            }, stun: 0.0f, playSound: false);
                        }
                        else if (target is Limb limb)
                        {
                            limb.character.DamageLimb(limb.WorldPosition, limb, new List <Affliction>()
                            {
                                multipliedAffliction
                            }, stun: 0.0f, playSound: false, attackImpulse: 0.0f);
                        }
                    }

                    foreach (Pair <string, float> reduceAffliction in element.Parent.ReduceAffliction)
                    {
                        Limb      targetLimb      = null;
                        Character targetCharacter = null;
                        if (target is Character character)
                        {
                            targetCharacter = character;
                        }
                        else if (target is Limb limb)
                        {
                            targetLimb      = limb;
                            targetCharacter = limb.character;
                        }
                        if (targetCharacter != null)
                        {
                            float prevVitality = targetCharacter.Vitality;
                            targetCharacter.CharacterHealth.ReduceAffliction(targetLimb, reduceAffliction.First, reduceAffliction.Second * deltaTime);
#if SERVER
                            GameMain.Server.KarmaManager.OnCharacterHealthChanged(targetCharacter, element.Parent.user, prevVitality - targetCharacter.Vitality);
#endif
                        }
                    }
                }

                element.Timer -= deltaTime;

                if (element.Timer > 0.0f)
                {
                    continue;
                }
                DurationList.Remove(element);
            }
        }
Beispiel #7
0
        protected void Apply(float deltaTime, Entity entity, List <ISerializableEntity> targets)
        {
            Hull hull = null;

            if (entity is Character)
            {
                hull = ((Character)entity).AnimController.CurrentHull;
            }
            else if (entity is Item)
            {
                hull = ((Item)entity).CurrentHull;
            }

            foreach (ISerializableEntity serializableEntity in targets)
            {
                if (!(serializableEntity is Item item))
                {
                    continue;
                }

                Character targetCharacter = targets.FirstOrDefault(t => t is Character character && !character.Removed) as Character;
                if (targetCharacter == null)
                {
                    foreach (var target in targets)
                    {
                        if (target is Limb limb && limb.character != null && !limb.character.Removed)
                        {
                            targetCharacter = ((Limb)target).character;
                        }
                    }
                }
                for (int i = 0; i < useItemCount; i++)
                {
                    if (item.Removed)
                    {
                        continue;
                    }
                    item.Use(deltaTime, targetCharacter, targets.FirstOrDefault(t => t is Limb) as Limb);
                }
            }

            if (removeItem)
            {
                foreach (Item item in targets.Where(t => t is Item).Cast <Item>())
                {
                    Entity.Spawner?.AddToRemoveQueue(item);
                }
            }

            if (duration > 0.0f)
            {
                DurationListElement element = new DurationListElement
                {
                    Parent  = this,
                    Timer   = duration,
                    Entity  = entity,
                    Targets = targets
                };

                DurationList.Add(element);
            }
            else
            {
                foreach (ISerializableEntity target in targets)
                {
                    if (target is Entity targetEntity)
                    {
                        if (targetEntity.Removed)
                        {
                            continue;
                        }
                    }

                    for (int i = 0; i < propertyNames.Length; i++)
                    {
                        if (target == null || target.SerializableProperties == null ||
                            !target.SerializableProperties.TryGetValue(propertyNames[i], out SerializableProperty property))
                        {
                            continue;
                        }
                        ApplyToProperty(target, property, propertyEffects[i], deltaTime);
                    }
                }
            }

            if (explosion != null && entity != null)
            {
                explosion.Explode(entity.WorldPosition, damageSource: entity, attacker: user);
            }

            foreach (ISerializableEntity target in targets)
            {
                foreach (Affliction affliction in Afflictions)
                {
                    Affliction multipliedAffliction = affliction;
                    if (!disableDeltaTime)
                    {
                        multipliedAffliction = affliction.CreateMultiplied(deltaTime);
                    }

                    if (target is Character character)
                    {
                        character.LastDamageSource = entity;
                        foreach (Limb limb in character.AnimController.Limbs)
                        {
                            limb.character.DamageLimb(entity.WorldPosition, limb, new List <Affliction>()
                            {
                                multipliedAffliction
                            }, stun: 0.0f, playSound: false, attackImpulse: 0.0f, attacker: affliction.Source);
                            //only apply non-limb-specific afflictions to the first limb
                            if (!affliction.Prefab.LimbSpecific)
                            {
                                break;
                            }
                        }
                    }
                    else if (target is Limb limb)
                    {
                        limb.character.DamageLimb(entity.WorldPosition, limb, new List <Affliction>()
                        {
                            multipliedAffliction
                        }, stun: 0.0f, playSound: false, attackImpulse: 0.0f, attacker: affliction.Source);
                    }
                }

                foreach (Pair <string, float> reduceAffliction in ReduceAffliction)
                {
                    float     reduceAmount    = disableDeltaTime ? reduceAffliction.Second : reduceAffliction.Second * deltaTime;
                    Limb      targetLimb      = null;
                    Character targetCharacter = null;
                    if (target is Character character)
                    {
                        targetCharacter = character;
                    }
                    else if (target is Limb limb)
                    {
                        targetLimb      = limb;
                        targetCharacter = limb.character;
                    }
                    if (targetCharacter != null)
                    {
                        float prevVitality = targetCharacter.Vitality;
                        targetCharacter.CharacterHealth.ReduceAffliction(targetLimb, reduceAffliction.First, reduceAmount);
#if SERVER
                        GameMain.Server.KarmaManager.OnCharacterHealthChanged(targetCharacter, user, prevVitality - targetCharacter.Vitality);
#endif
                    }
                }
            }

            if (FireSize > 0.0f && entity != null)
            {
                var fire = new FireSource(entity.WorldPosition, hull);
                fire.Size = new Vector2(FireSize, fire.Size.Y);
            }

            bool isNotClient = GameMain.NetworkMember == null || !GameMain.NetworkMember.IsClient;
            if (isNotClient && entity != null && Entity.Spawner != null) //clients are not allowed to spawn items
            {
                foreach (ItemSpawnInfo itemSpawnInfo in spawnItems)
                {
                    switch (itemSpawnInfo.SpawnPosition)
                    {
                    case ItemSpawnInfo.SpawnPositionType.This:
                        Entity.Spawner.AddToSpawnQueue(itemSpawnInfo.ItemPrefab, entity.WorldPosition);
                        break;

                    case ItemSpawnInfo.SpawnPositionType.ThisInventory:
                    {
                        if (entity is Character character)
                        {
                            if (character.Inventory != null && character.Inventory.Items.Any(it => it == null))
                            {
                                Entity.Spawner.AddToSpawnQueue(itemSpawnInfo.ItemPrefab, character.Inventory);
                            }
                        }
                        else if (entity is Item item)
                        {
                            var inventory = item?.GetComponent <ItemContainer>()?.Inventory;
                            if (inventory != null && inventory.Items.Any(it => it == null))
                            {
                                Entity.Spawner.AddToSpawnQueue(itemSpawnInfo.ItemPrefab, inventory);
                            }
                        }
                    }
                    break;

                    case ItemSpawnInfo.SpawnPositionType.ContainedInventory:
                    {
                        Inventory thisInventory = null;
                        if (entity is Character character)
                        {
                            thisInventory = character.Inventory;
                        }
                        else if (entity is Item item)
                        {
                            thisInventory = item?.GetComponent <ItemContainer>()?.Inventory;
                        }
                        if (thisInventory != null)
                        {
                            foreach (Item item in thisInventory.Items)
                            {
                                if (item == null)
                                {
                                    continue;
                                }
                                Inventory containedInventory = item.GetComponent <ItemContainer>()?.Inventory;
                                if (containedInventory == null || !containedInventory.Items.Any(i => i == null))
                                {
                                    continue;
                                }
                                Entity.Spawner.AddToSpawnQueue(itemSpawnInfo.ItemPrefab, containedInventory);
                                break;
                            }
                        }
                    }
                    break;
                    }
                }
            }

            ApplyProjSpecific(deltaTime, entity, targets, hull);
        }
        public static void UpdateAll(float deltaTime)
        {
            DelayedEffect.Update(deltaTime);
            for (int i = DurationList.Count - 1; i >= 0; i--)
            {
                DurationListElement element = DurationList[i];

                if (element.Parent.CheckConditionalAlways && !element.Parent.HasRequiredConditions(element.Targets))
                {
                    DurationList.RemoveAt(i);
                    continue;
                }

                element.Targets.RemoveAll(t => t is Entity entity && entity.Removed);
                if (element.Targets.Count == 0)
                {
                    DurationList.RemoveAt(i);
                    continue;
                }

                foreach (ISerializableEntity target in element.Targets)
                {
                    if (target is Character)
                    {
                        for (int n = 0; n < element.Parent.propertyNames.Length; n++)
                        {
                            if (element.CancelledEffects.Contains(n))
                            {
                                continue;
                            }
                            if (target == null || target.SerializableProperties == null || !target.SerializableProperties.TryGetValue(element.Parent.propertyNames[n], out SerializableProperty property))
                            {
                                continue;
                            }

                            if (element.Parent.propertyEffects[n].GetType() == typeof(float))
                            {
                                Character targetcharacter = target as Character;
                                float     propertyfloat   = Convert.ToSingle(element.Parent.propertyEffects[n]);

                                switch (property.Name.ToLowerInvariant())
                                {
                                case "health":
                                    if (propertyfloat < 0f)
                                    {
                                        targetcharacter.charRecord.DamageStat("health", -(propertyfloat * CoroutineManager.UnscaledDeltaTime), element.causecharacter, element.identifier);
                                    }
                                    break;

                                case "bleeding":
                                    if (propertyfloat > 0f)
                                    {
                                        targetcharacter.charRecord.DamageStat("bleeding", (propertyfloat * CoroutineManager.UnscaledDeltaTime), element.causecharacter, element.identifier);
                                    }
                                    break;

                                case "oxygen":
                                    if (propertyfloat < 0f)
                                    {
                                        targetcharacter.charRecord.DamageStat("oxygen", -(propertyfloat * CoroutineManager.UnscaledDeltaTime), element.causecharacter, element.identifier);
                                    }
                                    break;

                                default:
                                    break;
                                }
                            }

                            element.Parent.ApplyToProperty(property, element.Parent.propertyEffects[n], CoroutineManager.UnscaledDeltaTime);
                        }
                    }
                    else
                    {
                        for (int n = 0; n < element.Parent.propertyNames.Length; n++)
                        {
                            if (element.CancelledEffects.Contains(n))
                            {
                                continue;
                            }
                            SerializableProperty property;

                            if (target == null || target.SerializableProperties == null || !target.SerializableProperties.TryGetValue(element.Parent.propertyNames[n], out property))
                            {
                                continue;
                            }

                            element.Parent.ApplyToProperty(property, element.Parent.propertyEffects[n], CoroutineManager.UnscaledDeltaTime);
                        }
                    }
                }

                element.Timer -= deltaTime;

                if (element.Timer > 0.0f)
                {
                    continue;
                }
                DurationList.Remove(element);
            }
        }
        protected void Apply(float deltaTime, Entity entity, List <ISerializableEntity> targets, List <int> cancelledEffects = null, Character causecharacter = null, string identifier = "")
        {
#if CLIENT
            if (sound != null)
            {
                if (loopSound)
                {
                    if (!Sounds.SoundManager.IsPlaying(sound))
                    {
                        sound.Play(entity.WorldPosition);
                    }
                    else
                    {
                        sound.UpdatePosition(entity.WorldPosition);
                    }
                }
                else
                {
                    sound.Play(entity.WorldPosition);
                }
            }
#endif

            if (identifier == "")
            {
                identifier = "statuseffect";
            }

            for (int i = 0; i < useItemCount; i++)
            {
                foreach (Item item in targets.FindAll(t => t is Item).Cast <Item>())
                {
                    if (item.Removed)
                    {
                        continue;
                    }
                    item.Use(deltaTime, targets.FirstOrDefault(t => t is Character) as Character, causecharacter, identifier);
                }
            }

            if (removeItem)
            {
                foreach (Item item in targets.FindAll(t => t is Item).Cast <Item>())
                {
                    Entity.Spawner?.AddToRemoveQueue(item);
                }
            }

            if (duration > 0.0f)
            {
                DurationListElement element = new DurationListElement();
                element.Parent  = this;
                element.Timer   = duration;
                element.Entity  = entity;
                element.Targets = targets;
                if (cancelledEffects != null)
                {
                    element.CancelledEffects = cancelledEffects;
                }
                element.causecharacter = causecharacter;
                element.identifier     = identifier;

/*                    if (!target.SerializableProperties.TryGetValue(propertyNames[i], out property)) continue;
 *
 *                  if (duration > 0.0f)
 *                  {
 *                      if (GameMain.Server != null)
 *                      {
 *                          if (target is Character)
 *                          {
 *                              Character effectedcharacter = (Character)target;
 *
 *                              if (GameMain.NilMod.LogStatusEffectStun && property.Name.ToLowerInvariant() == "health" && propertyEffects[i] is float && (float)propertyEffects[i] < 0f)
 *                              {
 *                                  Barotrauma.Networking.GameServer.Log(effectedcharacter.Name + " Poisoned for " + Math.Round((float)propertyEffects[i], 2) + " health per second for " + ToolBox.SecondsToReadableTime(duration) + ".", Networking.ServerLog.MessageType.Attack);
 *                              }
 *                              else if (GameMain.NilMod.LogStatusEffectHealth && property.Name.ToLowerInvariant() == "health" && propertyEffects[i] is float && (float)propertyEffects[i] < 0f)
 *                              {
 *                                  Barotrauma.Networking.GameServer.Log(effectedcharacter.Name + " Poisoned for " + Math.Round((float)propertyEffects[i], 2) + " health per second for " + ToolBox.SecondsToReadableTime(duration) + ".", Networking.ServerLog.MessageType.Attack);
 *                              }
 *                              else if (GameMain.NilMod.LogStatusEffectBleed && property.Name.ToLowerInvariant() == "bleeding" && propertyEffects[i] is float && (float)propertyEffects[i] < 0f)
 *                              {
 *                                  Barotrauma.Networking.GameServer.Log(effectedcharacter.Name + " Poisoned for " + Math.Round((float)propertyEffects[i], 2) + " bleed per second for " + ToolBox.SecondsToReadableTime(duration) + ".", Networking.ServerLog.MessageType.Attack);
 *                              }
 *                              else if (GameMain.NilMod.LogStatusEffectOxygen && property.Name.ToLowerInvariant() == "oxygen" && propertyEffects[i] is float && (float)propertyEffects[i] < 0f)
 *                              {
 *                                  Barotrauma.Networking.GameServer.Log(effectedcharacter.Name + " Poisoned for " + Math.Round((float)propertyEffects[i], 2) + " oxygen per second for " + ToolBox.SecondsToReadableTime(duration) + ".", Networking.ServerLog.MessageType.Attack);
 *                              }
 *                          }
 *                      }*/

                DurationList.Add(element);
            }
            else
            {
/*                        if (GameMain.Server != null)
 *                      {
 *                          if (target is Character)
 *                          {
 *                              Character effectedcharacter = (Character)target;
 *
 *                              //Only show values that are not continous to a character over time, that'd get rediculous fast.
 *                              if (deltaTime == 1f)
 *                              {
 *                                  if (GameMain.NilMod.LogStatusEffectStun && property.Name.ToLowerInvariant() == "stun" && propertyEffects[i] is float && (float)propertyEffects[i] > 5f)
 *                                  {
 *                                      Barotrauma.Networking.GameServer.Log(effectedcharacter.Name + " Stunned for " + (Math.Round((float)propertyEffects[i] * (1f - effectedcharacter.Stunresistance), 2)) + " (" + Math.Round(effectedcharacter.Stunresistance * 100f, 2) + "% Resisted).", Networking.ServerLog.MessageType.Attack);
 *                                  }
 *                                  else if (GameMain.NilMod.LogStatusEffectHealth && property.Name.ToLowerInvariant() == "health" && propertyEffects[i] is float && (float)propertyEffects[i] < 5f)
 *                                  {
 *                                      Barotrauma.Networking.GameServer.Log(effectedcharacter.Name + " Poisoned for " + Math.Round((float)propertyEffects[i], 2) + " health.", Networking.ServerLog.MessageType.Attack);
 *                                  }
 *                                  else if (GameMain.NilMod.LogStatusEffectBleed && property.Name.ToLowerInvariant() == "bleeding" && propertyEffects[i] is float && (float)propertyEffects[i] < 5f)
 *                                  {
 *                                      Barotrauma.Networking.GameServer.Log(effectedcharacter.Name + " Poisoned for " + Math.Round((float)propertyEffects[i], 2) + " bleed.", Networking.ServerLog.MessageType.Attack);
 *                                  }
 *                                  else if (GameMain.NilMod.LogStatusEffectOxygen && property.Name.ToLowerInvariant() == "oxygen" && propertyEffects[i] is float && (float)propertyEffects[i] < 5f)
 *                                  {
 *                                      Barotrauma.Networking.GameServer.Log(effectedcharacter.Name + " Poisoned for " + Math.Round((float)propertyEffects[i], 2) + " oxygen.", Networking.ServerLog.MessageType.Attack);
 *                                  }
 *                              }
 *                          }
 *                      }*/

                foreach (ISerializableEntity target in targets)
                {
                    if (target is Entity targetEntity)
                    {
                        if (targetEntity.Removed)
                        {
                            continue;
                        }
                    }

                    if (target is Character)
                    {
                        for (int i = 0; i < propertyNames.Length; i++)
                        {
                            SerializableProperty property;
                            if (cancelledEffects != null && cancelledEffects.Contains(i))
                            {
                                continue;
                            }
                            if (target == null || target.SerializableProperties == null || !target.SerializableProperties.TryGetValue(propertyNames[i], out property))
                            {
                                continue;
                            }
                            float     prevstat        = 0f;
                            Character targetcharacter = target as Character;
                            Boolean   prevdead        = targetcharacter.IsDead;

                            if (propertyEffects[i].GetType() == typeof(float))
                            {
                                float propertyfloat = Convert.ToSingle(propertyEffects[i]);

                                switch (property.Name.ToLowerInvariant())
                                {
                                case "health":
                                    prevstat = targetcharacter.Health;
                                    if (propertyfloat < 0f)
                                    {
                                        targetcharacter.charRecord.DamageStat("health", -(propertyfloat * CoroutineManager.UnscaledDeltaTime), causecharacter, identifier);
                                    }
                                    break;

                                case "bleeding":
                                    if (propertyfloat > 0f)
                                    {
                                        targetcharacter.charRecord.DamageStat("bleeding", (propertyfloat * CoroutineManager.UnscaledDeltaTime), causecharacter, identifier);
                                    }
                                    break;

                                case "oxygen":
                                    prevstat = targetcharacter.Oxygen;
                                    if (propertyfloat < 0f)
                                    {
                                        targetcharacter.charRecord.DamageStat("oxygen", -(propertyfloat * CoroutineManager.UnscaledDeltaTime), causecharacter, identifier);
                                    }
                                    break;

                                case "stun":
                                    if (propertyfloat > 0f)
                                    {
                                        targetcharacter.charRecord.DamageStat("stun", (propertyfloat * CoroutineManager.UnscaledDeltaTime), causecharacter, identifier);
                                    }
                                    break;

                                case "huskinfectionstate":
                                    if (propertyfloat > 0f)
                                    {
                                        targetcharacter.charRecord.DamageStat("huskinfectionstate", (propertyfloat * CoroutineManager.UnscaledDeltaTime), causecharacter, identifier);
                                    }
                                    break;

                                default:
                                    break;
                                }
                            }

                            ApplyToProperty(property, propertyEffects[i], deltaTime);

                            if (GameMain.NilMod.EnableGriefWatcher && GameMain.Server != null && causecharacter != null)
                            {
                                Barotrauma.Networking.Client targetclient    = GameMain.Server.ConnectedClients.Find(c => c.Character == targetcharacter);
                                Barotrauma.Networking.Client attackingclient = GameMain.Server.ConnectedClients.Find(c => c.Character == causecharacter);
                                if (attackingclient != null && targetclient != null)
                                {
                                    switch (property.Name.ToLowerInvariant())
                                    {
                                    case "health":
                                        if (NilMod.NilModGriefWatcher.PlayerIncapaciteDamage)
                                        {
                                            if (!prevdead)
                                            {
                                                if (targetcharacter.IsDead)
                                                {
                                                    NilMod.NilModGriefWatcher.SendWarning(attackingclient.Character.LogName
                                                                                          + " Killed player " + targetclient.Character.LogName
                                                                                          + " via " + identifier, attackingclient);
                                                }
                                                else if (prevstat > 0f && targetcharacter.Health < 0f)
                                                {
                                                    NilMod.NilModGriefWatcher.SendWarning(attackingclient.Character.LogName
                                                                                          + " Incapacitated player " + targetclient.Character.LogName
                                                                                          + " via " + identifier, attackingclient);
                                                }
                                            }
                                        }
                                        break;

                                    case "oxygen":
                                        if (NilMod.NilModGriefWatcher.PlayerIncapaciteOxygen)
                                        {
                                            if (!prevdead)
                                            {
                                                if (targetcharacter.IsDead)
                                                {
                                                    NilMod.NilModGriefWatcher.SendWarning(attackingclient.Character.LogName
                                                                                          + " Killed player " + targetclient.Character.LogName
                                                                                          + " via " + identifier, attackingclient);
                                                }
                                                else if (prevstat > 0f && targetcharacter.Oxygen < 0f)
                                                {
                                                    NilMod.NilModGriefWatcher.SendWarning(attackingclient.Character.LogName
                                                                                          + " Incapacitated player " + targetclient.Character.LogName
                                                                                          + " via " + identifier, attackingclient);
                                                }
                                            }
                                        }
                                        break;

                                    default:
                                        break;
                                    }
                                }
                            }
                        }
                    }
                    else if (target is Items.Components.ItemComponent && GameMain.Server != null && causecharacter != null)
                    {
                        for (int i = 0; i < propertyNames.Length; i++)
                        {
                            SerializableProperty property;
                            if (cancelledEffects != null && cancelledEffects.Contains(i))
                            {
                                continue;
                            }
                            if (target == null || target.SerializableProperties == null || !target.SerializableProperties.TryGetValue(propertyNames[i], out property))
                            {
                                continue;
                            }
                            Items.Components.ItemComponent targetitemcomponent = target as Items.Components.ItemComponent;
                            Networking.Client attackingclient = GameMain.Server.ConnectedClients.Find(c => c.Character == causecharacter);

                            Items.Components.Door door = targetitemcomponent as Items.Components.Door;
                            Boolean previsStuck        = false;
                            //Door stuck griefing here
                            if (door != null)
                            {
                                if (propertyNames[i].ToLowerInvariant() == "stuck")
                                {
                                    previsStuck = door.IsStuck;
                                }
                            }

                            ApplyToProperty(property, propertyEffects[i], deltaTime);

                            //Door stuck griefing here
                            if (door != null)
                            {
                                if (propertyNames[i].ToLowerInvariant() == "stuck")
                                {
                                    if (previsStuck != door.IsStuck)
                                    {
                                        if (door.IsStuck)
                                        {
                                            Networking.GameServer.Log(causecharacter.LogName
                                                                      + (door.LinkedGap != null && door.LinkedGap.IsRoomToRoom ? " sealed interior " : " sealed exterior ")
                                                                      + door.Item.Name, Networking.ServerLog.MessageType.ItemInteraction);

                                            if (GameMain.NilMod.EnableGriefWatcher && NilMod.NilModGriefWatcher.DoorStuck && attackingclient != null)
                                            {
                                                NilMod.NilModGriefWatcher.SendWarning(
                                                    attackingclient.Character.LogName
                                                    + (door.LinkedGap != null && door.LinkedGap.IsRoomToRoom ? " sealed interior " : " sealed exterior ")
                                                    + door.Item.Name
                                                    + " via " + identifier, attackingclient);
                                            }
                                        }
                                        else
                                        {
                                            Networking.GameServer.Log(causecharacter.LogName
                                                                      + (door.LinkedGap != null && door.LinkedGap.IsRoomToRoom ? " unsealed interior " : " unsealed exterior ")
                                                                      + door.Item.Name, Networking.ServerLog.MessageType.ItemInteraction);
                                        }
                                    }
                                }
                            }
                        }
                    }
                    else
                    {
                        for (int i = 0; i < propertyNames.Length; i++)
                        {
                            SerializableProperty property;
                            if (cancelledEffects != null && cancelledEffects.Contains(i))
                            {
                                continue;
                            }
                            if (target == null || target.SerializableProperties == null || !target.SerializableProperties.TryGetValue(propertyNames[i], out property))
                            {
                                continue;
                            }

                            ApplyToProperty(property, propertyEffects[i], deltaTime);
                        }
                    }
                }
            }

            if (explosion != null)
            {
                if (identifier == "statuseffect")
                {
                    explosion.Explode(entity.WorldPosition, causecharacter, "");
                }
                else
                {
                    explosion.Explode(entity.WorldPosition, causecharacter, identifier);
                }
            }


            Hull hull = null;
            if (entity is Character)
            {
                hull = ((Character)entity).AnimController.CurrentHull;
            }
            else if (entity is Item)
            {
                hull = ((Item)entity).CurrentHull;
            }

            if (FireSize > 0.0f)
            {
                var fire = new FireSource(entity.WorldPosition, hull);

                fire.Size = new Vector2(FireSize, fire.Size.Y);
            }

#if CLIENT
            foreach (ParticleEmitter emitter in particleEmitters)
            {
                emitter.Emit(deltaTime, entity.WorldPosition, hull);
            }
#endif
        }
Beispiel #10
0
        protected void Apply(float deltaTime, Entity entity, List <ISerializableEntity> targets)
        {
            Hull hull = null;

            if (entity is Character)
            {
                hull = ((Character)entity).AnimController.CurrentHull;
            }
            else if (entity is Item)
            {
                hull = ((Item)entity).CurrentHull;
            }
#if CLIENT
            if (entity != null && sounds.Count > 0)
            {
                if (soundChannel == null || !soundChannel.IsPlaying)
                {
                    if (soundSelectionMode == SoundSelectionMode.All)
                    {
                        foreach (RoundSound sound in sounds)
                        {
                            soundChannel = SoundPlayer.PlaySound(sound.Sound, sound.Volume, sound.Range, entity.WorldPosition, hull);
                            if (soundChannel != null)
                            {
                                soundChannel.Looping = loopSound;
                            }
                        }
                    }
                    else
                    {
                        int selectedSoundIndex = 0;
                        if (soundSelectionMode == SoundSelectionMode.ItemSpecific && entity is Item item)
                        {
                            selectedSoundIndex = item.ID % sounds.Count;
                        }
                        else if (soundSelectionMode == SoundSelectionMode.CharacterSpecific && entity is Character user)
                        {
                            selectedSoundIndex = user.ID % sounds.Count;
                        }
                        else
                        {
                            selectedSoundIndex = Rand.Int(sounds.Count);
                        }
                        var selectedSound = sounds[selectedSoundIndex];
                        soundChannel = SoundPlayer.PlaySound(selectedSound.Sound, selectedSound.Volume, selectedSound.Range, entity.WorldPosition, hull);
                        if (soundChannel != null)
                        {
                            soundChannel.Looping = loopSound;
                        }
                    }
                }
            }
#endif

            foreach (ISerializableEntity serializableEntity in targets)
            {
                Item item = serializableEntity as Item;
                if (item == null)
                {
                    continue;
                }

                Character targetCharacter = targets.FirstOrDefault(t => t is Character character && !character.Removed) as Character;
                if (targetCharacter == null)
                {
                    foreach (var target in targets)
                    {
                        if (target is Limb limb && limb.character != null && !limb.character.Removed)
                        {
                            targetCharacter = ((Limb)target).character;
                        }
                    }
                }
                for (int i = 0; i < useItemCount; i++)
                {
                    if (item.Removed)
                    {
                        continue;
                    }
                    item.Use(deltaTime, targetCharacter, targets.FirstOrDefault(t => t is Limb) as Limb);
                }
            }

            if (removeItem)
            {
                foreach (Item item in targets.Where(t => t is Item).Cast <Item>())
                {
                    Entity.Spawner?.AddToRemoveQueue(item);
                }
            }

            if (duration > 0.0f)
            {
                DurationListElement element = new DurationListElement
                {
                    Parent  = this,
                    Timer   = duration,
                    Entity  = entity,
                    Targets = targets
                };

                DurationList.Add(element);
            }
            else
            {
                foreach (ISerializableEntity target in targets)
                {
                    if (target is Entity targetEntity)
                    {
                        if (targetEntity.Removed)
                        {
                            continue;
                        }
                    }

                    for (int i = 0; i < propertyNames.Length; i++)
                    {
                        if (target == null || target.SerializableProperties == null ||
                            !target.SerializableProperties.TryGetValue(propertyNames[i], out SerializableProperty property))
                        {
                            continue;
                        }
                        ApplyToProperty(target, property, propertyEffects[i], deltaTime);
                    }
                }
            }

            if (explosion != null && entity != null)
            {
                explosion.Explode(entity.WorldPosition, entity);
            }

            foreach (ISerializableEntity target in targets)
            {
                foreach (Affliction affliction in Afflictions)
                {
                    Affliction multipliedAffliction = affliction;
                    if (!disableDeltaTime)
                    {
                        multipliedAffliction = affliction.CreateMultiplied(deltaTime);
                    }

                    if (target is Character character)
                    {
                        character.LastDamageSource = entity;
                        foreach (Limb limb in character.AnimController.Limbs)
                        {
                            limb.character.DamageLimb(entity.WorldPosition, limb, new List <Affliction>()
                            {
                                multipliedAffliction
                            }, stun: 0.0f, playSound: false, attackImpulse: 0.0f);
                            //only apply non-limb-specific afflictions to the first limb
                            if (!affliction.Prefab.LimbSpecific)
                            {
                                break;
                            }
                        }
                    }
                    else if (target is Limb limb)
                    {
                        limb.character.DamageLimb(entity.WorldPosition, limb, new List <Affliction>()
                        {
                            multipliedAffliction
                        }, stun: 0.0f, playSound: false, attackImpulse: 0.0f);
                    }
                }

                foreach (Pair <string, float> reduceAffliction in ReduceAffliction)
                {
                    float reduceAmount = disableDeltaTime ? reduceAffliction.Second : reduceAffliction.Second * deltaTime;
                    if (target is Character character)
                    {
                        character.CharacterHealth.ReduceAffliction(null, reduceAffliction.First, reduceAmount);
                    }
                    else if (target is Limb limb)
                    {
                        limb.character.CharacterHealth.ReduceAffliction(limb, reduceAffliction.First, reduceAmount);
                    }
                }
            }

            if (FireSize > 0.0f && entity != null)
            {
                var fire = new FireSource(entity.WorldPosition, hull);
                fire.Size = new Vector2(FireSize, fire.Size.Y);
            }

            bool isNotClient = true;
#if CLIENT
            isNotClient = GameMain.Client == null;
#endif

            if (isNotClient && entity != null && Entity.Spawner != null) //clients are not allowed to spawn items
            {
                foreach (ItemSpawnInfo itemSpawnInfo in spawnItems)
                {
                    switch (itemSpawnInfo.SpawnPosition)
                    {
                    case ItemSpawnInfo.SpawnPositionType.This:
                        Entity.Spawner.AddToSpawnQueue(itemSpawnInfo.ItemPrefab, entity.WorldPosition);
                        break;

                    case ItemSpawnInfo.SpawnPositionType.ThisInventory:
                    {
                        if (entity is Character character)
                        {
                            if (character.Inventory != null && character.Inventory.Items.Any(it => it == null))
                            {
                                Entity.Spawner.AddToSpawnQueue(itemSpawnInfo.ItemPrefab, character.Inventory);
                            }
                        }
                        else if (entity is Item item)
                        {
                            var inventory = item?.GetComponent <ItemContainer>()?.Inventory;
                            if (inventory != null && inventory.Items.Any(it => it == null))
                            {
                                Entity.Spawner.AddToSpawnQueue(itemSpawnInfo.ItemPrefab, inventory);
                            }
                        }
                    }
                    break;

                    case ItemSpawnInfo.SpawnPositionType.ContainedInventory:
                    {
                        Inventory thisInventory = null;
                        if (entity is Character character)
                        {
                            thisInventory = character.Inventory;
                        }
                        else if (entity is Item item)
                        {
                            thisInventory = item?.GetComponent <ItemContainer>()?.Inventory;
                        }
                        if (thisInventory != null)
                        {
                            foreach (Item item in thisInventory.Items)
                            {
                                if (item == null)
                                {
                                    continue;
                                }
                                Inventory containedInventory = item.GetComponent <ItemContainer>()?.Inventory;
                                if (containedInventory == null || !containedInventory.Items.Any(i => i == null))
                                {
                                    continue;
                                }
                                Entity.Spawner.AddToSpawnQueue(itemSpawnInfo.ItemPrefab, containedInventory);
                                break;
                            }
                        }
                    }
                    break;
                    }
                }
            }

#if CLIENT
            if (entity != null)
            {
                foreach (ParticleEmitter emitter in particleEmitters)
                {
                    float angle = 0.0f;
                    if (emitter.Prefab.CopyEntityAngle)
                    {
                        if (entity is Item it)
                        {
                            angle = it.body == null ? 0.0f : it.body.Rotation;
                        }
                    }

                    emitter.Emit(deltaTime, entity.WorldPosition, hull, angle);
                }
            }
#endif
        }
        protected void Apply(float deltaTime, Entity entity, List <ISerializableEntity> targets)
        {
#if CLIENT
            if (sound != null)
            {
                if (loopSound)
                {
                    if (!Sounds.SoundManager.IsPlaying(sound))
                    {
                        sound.Play(entity.WorldPosition);
                    }
                    else
                    {
                        sound.UpdatePosition(entity.WorldPosition);
                    }
                }
                else
                {
                    sound.Play(entity.WorldPosition);
                }
            }
#endif

            for (int i = 0; i < useItemCount; i++)
            {
                foreach (Item item in targets.FindAll(t => t is Item).Cast <Item>())
                {
                    item.Use(deltaTime, targets.FirstOrDefault(t => t is Character) as Character);
                }
            }

            if (removeItem)
            {
                foreach (Item item in targets.FindAll(t => t is Item).Cast <Item>())
                {
                    Entity.Spawner?.AddToRemoveQueue(item);
                }
            }

            if (duration > 0.0f)
            {
                DurationListElement element = new DurationListElement();
                element.Parent  = this;
                element.Timer   = duration;
                element.Entity  = entity;
                element.Targets = targets;

                DurationList.Add(element);
            }
            else
            {
                foreach (ISerializableEntity target in targets)
                {
                    for (int i = 0; i < propertyNames.Length; i++)
                    {
                        SerializableProperty property;

                        if (target == null || target.SerializableProperties == null || !target.SerializableProperties.TryGetValue(propertyNames[i], out property))
                        {
                            continue;
                        }

                        ApplyToProperty(property, propertyEffects[i], deltaTime);
                    }
                }
            }


            if (explosion != null)
            {
                explosion.Explode(entity.WorldPosition);
            }


            Hull hull = null;
            if (entity is Character)
            {
                hull = ((Character)entity).AnimController.CurrentHull;
            }
            else if (entity is Item)
            {
                hull = ((Item)entity).CurrentHull;
            }

            if (FireSize > 0.0f)
            {
                var fire = new FireSource(entity.WorldPosition, hull);

                fire.Size = new Vector2(FireSize, fire.Size.Y);
            }

#if CLIENT
            foreach (ParticleEmitter emitter in particleEmitters)
            {
                emitter.Emit(deltaTime, entity.WorldPosition, hull);
            }
#endif
        }