Ejemplo n.º 1
0
        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
        }
Ejemplo n.º 2
0
        // TODO: Consider using generics, interfaces, or inheritance instead of reflection -> would be easier to debug when something changes/goes wrong.
        // For example, currently we can edit the constructors but they will fail in runtime because the parameters are not changed here.
        // It's also painful to find where the constructors are used, because the references exist only at runtime.
        public static ItemComponent Load(XElement element, Item item, string file, bool errorMessages = true)
        {
            Type   t;
            string type = element.Name.ToString().ToLowerInvariant();

            try
            {
                // Get the type of a specified class.
                t = Type.GetType("Barotrauma.Items.Components." + type + "", false, true);
                if (t == null)
                {
                    if (errorMessages)
                    {
                        DebugConsole.ThrowError("Could not find the component \"" + type + "\" (" + file + ")");
                    }
                    return(null);
                }
            }
            catch (Exception e)
            {
                if (errorMessages)
                {
                    DebugConsole.ThrowError("Could not find the component \"" + type + "\" (" + file + ")", e);
                }
                return(null);
            }

            ConstructorInfo constructor;

            try
            {
                if (t != typeof(ItemComponent) && !t.IsSubclassOf(typeof(ItemComponent)))
                {
                    return(null);
                }
                constructor = t.GetConstructor(new Type[] { typeof(Item), typeof(XElement) });
                if (constructor == null)
                {
                    DebugConsole.ThrowError("Could not find the constructor of the component \"" + type + "\" (" + file + ")");
                    return(null);
                }
            }
            catch (Exception e)
            {
                DebugConsole.ThrowError("Could not find the constructor of the component \"" + type + "\" (" + file + ")", e);
                return(null);
            }
            ItemComponent ic = null;

            try
            {
                object[] lobject   = new object[] { item, element };
                object   component = constructor.Invoke(lobject);
                ic      = (ItemComponent)component;
                ic.name = element.Name.ToString();
            }
            catch (TargetInvocationException e)
            {
                DebugConsole.ThrowError("Error while loading entity of the type " + t + ".", e.InnerException);
                GameAnalyticsManager.AddErrorEventOnce("ItemComponent.Load:TargetInvocationException" + item.Name + element.Name,
                                                       GameAnalyticsSDK.Net.EGAErrorSeverity.Error,
                                                       "Error while loading entity of the type " + t + " (" + e.InnerException + ")\n" + Environment.StackTrace);
            }

            return(ic);
        }
Ejemplo n.º 3
0
        public ItemComponent(Item item, XElement element)
        {
            this.item              = item;
            originalElement        = element;
            name                   = element.Name.ToString();
            SerializableProperties = SerializableProperty.GetProperties(this);
            requiredItems          = new Dictionary <RelatedItem.RelationType, List <RelatedItem> >();
            requiredSkills         = new List <Skill>();

#if CLIENT
            hasSoundsOfType = new bool[Enum.GetValues(typeof(ActionType)).Length];
            sounds          = new Dictionary <ActionType, List <ItemSound> >();
#endif

            SelectKey = InputType.Select;

            try
            {
                string selectKeyStr = element.GetAttributeString("selectkey", "Select");
                selectKeyStr = ToolBox.ConvertInputType(selectKeyStr);
                SelectKey    = (InputType)Enum.Parse(typeof(InputType), selectKeyStr, true);
            }
            catch (Exception e)
            {
                DebugConsole.ThrowError("Invalid select key in " + element + "!", e);
            }

            PickKey = InputType.Select;

            try
            {
                string pickKeyStr = element.GetAttributeString("pickkey", "Select");
                pickKeyStr = ToolBox.ConvertInputType(pickKeyStr);
                PickKey    = (InputType)Enum.Parse(typeof(InputType), pickKeyStr, true);
            }
            catch (Exception e)
            {
                DebugConsole.ThrowError("Invalid pick key in " + element + "!", e);
            }

            SerializableProperties = SerializableProperty.DeserializeProperties(this, element);
            ParseMsg();

            foreach (XElement subElement in element.Elements())
            {
                switch (subElement.Name.ToString().ToLowerInvariant())
                {
                case "requireditem":
                case "requireditems":
                    RelatedItem ri = RelatedItem.Load(subElement, item.Name);
                    if (ri != null)
                    {
                        if (!requiredItems.ContainsKey(ri.Type))
                        {
                            requiredItems.Add(ri.Type, new List <RelatedItem>());
                        }
                        requiredItems[ri.Type].Add(ri);
                    }
                    else
                    {
                        DebugConsole.ThrowError("Error in item config \"" + item.ConfigFile + "\" - component " + GetType().ToString() + " requires an item with no identifiers.");
                    }
                    break;

                case "requiredskill":
                case "requiredskills":
                    if (subElement.Attribute("name") != null)
                    {
                        DebugConsole.ThrowError("Error in item config \"" + item.ConfigFile + "\" - skill requirement in component " + GetType().ToString() + " should use a skill identifier instead of the name of the skill.");
                        continue;
                    }

                    string skillIdentifier = subElement.GetAttributeString("identifier", "");
                    requiredSkills.Add(new Skill(skillIdentifier, subElement.GetAttributeInt("level", 0)));
                    break;

                case "statuseffect":
                    var statusEffect = StatusEffect.Load(subElement, item.Name);

                    if (statusEffectLists == null)
                    {
                        statusEffectLists = new Dictionary <ActionType, List <StatusEffect> >();
                    }

                    List <StatusEffect> effectList;
                    if (!statusEffectLists.TryGetValue(statusEffect.type, out effectList))
                    {
                        effectList = new List <StatusEffect>();
                        statusEffectLists.Add(statusEffect.type, effectList);
                    }

                    effectList.Add(statusEffect);

                    break;

                case "aitarget":
                    AITarget = new AITarget(item, subElement)
                    {
                        Enabled = isActive
                    };
                    break;

                default:
                    if (LoadElemProjSpecific(subElement))
                    {
                        break;
                    }
                    ItemComponent ic = Load(subElement, item, item.ConfigFile, false);
                    if (ic == null)
                    {
                        break;
                    }

                    ic.Parent = this;
                    item.AddComponent(ic);
                    break;
                }
            }
        }
Ejemplo n.º 4
0
        public ItemComponent(Item item, XElement element)
        {
            this.item = item;

            name = element.Name.ToString();

            properties = SerializableProperty.GetProperties(this);

            //canBePicked = ToolBox.GetAttributeBool(element, "canbepicked", false);
            //canBeSelected = ToolBox.GetAttributeBool(element, "canbeselected", false);

            //msg = ToolBox.GetAttributeString(element, "msg", "");

            requiredItems = new List <RelatedItem>();

            requiredSkills = new List <Skill>();

#if CLIENT
            sounds = new Dictionary <ActionType, List <ItemSound> >();
#endif

            SelectKey = InputType.Select;

            try
            {
                string selectKeyStr = element.GetAttributeString("selectkey", "Select");
                selectKeyStr = ToolBox.ConvertInputType(selectKeyStr);
                SelectKey    = (InputType)Enum.Parse(typeof(InputType), selectKeyStr, true);
            }
            catch (Exception e)
            {
                DebugConsole.ThrowError("Invalid select key in " + element + "!", e);
            }

            PickKey = InputType.Select;

            try
            {
                string pickKeyStr = element.GetAttributeString("pickkey", "Select");
                pickKeyStr = ToolBox.ConvertInputType(pickKeyStr);
                PickKey    = (InputType)Enum.Parse(typeof(InputType), pickKeyStr, true);
            }
            catch (Exception e)
            {
                DebugConsole.ThrowError("Invalid pick key in " + element + "!", e);
            }

            properties = SerializableProperty.DeserializeProperties(this, element);

            foreach (XElement subElement in element.Elements())
            {
                switch (subElement.Name.ToString().ToLowerInvariant())
                {
                case "requireditem":
                case "requireditems":
                    RelatedItem ri = RelatedItem.Load(subElement);
                    if (ri != null)
                    {
                        requiredItems.Add(ri);
                    }
                    break;

                case "requiredskill":
                case "requiredskills":
                    string skillName = subElement.GetAttributeString("name", "");
                    requiredSkills.Add(new Skill(skillName, subElement.GetAttributeInt("level", 0)));
                    break;

                case "statuseffect":
                    var statusEffect = StatusEffect.Load(subElement);

                    if (statusEffectLists == null)
                    {
                        statusEffectLists = new Dictionary <ActionType, List <StatusEffect> >();
                    }

                    List <StatusEffect> effectList;
                    if (!statusEffectLists.TryGetValue(statusEffect.type, out effectList))
                    {
                        effectList = new List <StatusEffect>();
                        statusEffectLists.Add(statusEffect.type, effectList);
                    }

                    effectList.Add(statusEffect);

                    break;

                default:
                    if (LoadElemProjSpecific(subElement))
                    {
                        break;
                    }
                    ItemComponent ic = Load(subElement, item, item.ConfigFile, false);
                    if (ic == null)
                    {
                        break;
                    }

                    ic.Parent = this;
                    item.components.Add(ic);
                    break;
                }
            }
        }