Esempio n. 1
0
        public LevelTrigger(XElement element, Vector2 position, float rotation, float scale = 1.0f)
        {
            physicsBody = new PhysicsBody(element, scale);
            physicsBody.CollisionCategories       = Physics.CollisionLevel;
            physicsBody.CollidesWith              = Physics.CollisionCharacter | Physics.CollisionItem | Physics.CollisionProjectile | Physics.CollisionWall;
            physicsBody.FarseerBody.OnCollision  += PhysicsBody_OnCollision;
            physicsBody.FarseerBody.OnSeparation += PhysicsBody_OnSeparation;
            physicsBody.FarseerBody.IsSensor      = true;
            physicsBody.FarseerBody.IsStatic      = true;
            physicsBody.FarseerBody.IsKinematic   = true;

            physicsBody.SetTransform(ConvertUnits.ToSimUnits(position), rotation);

            cameraShake = element.GetAttributeFloat("camerashake", 0.0f);

            force = element.GetAttributeVector2("force", Vector2.Zero);

            foreach (XElement subElement in element.Elements())
            {
                switch (subElement.Name.ToString().ToLowerInvariant())
                {
                case "statuseffect":
                    statusEffects.Add(StatusEffect.Load(subElement));
                    break;

                case "attack":
                case "damage":
                    attacks.Add(new Attack(subElement));
                    break;
                }
            }
        }
Esempio n. 2
0
            public Effect(XElement element, string parentDebugName)
            {
                SerializableProperty.DeserializeProperties(this, element);

                resistanceFor = element.GetAttributeStringArray("resistancefor", new string[0], convertToLowerInvariant: true);

                foreach (XElement subElement in element.Elements())
                {
                    switch (subElement.Name.ToString().ToLowerInvariant())
                    {
                    case "statuseffect":
                        StatusEffects.Add(StatusEffect.Load(subElement, parentDebugName));
                        break;

                    case "statvalue":
                        var statType = CharacterAbilityGroup.ParseStatType(subElement.GetAttributeString("stattype", ""), parentDebugName);

                        float defaultValue = subElement.GetAttributeFloat("value", 0f);
                        float minValue     = subElement.GetAttributeFloat("minvalue", defaultValue);
                        float maxValue     = subElement.GetAttributeFloat("maxvalue", defaultValue);

                        AfflictionStatValues.TryAdd(statType, (minValue, maxValue));
                        break;

                    case "abilityflag":
                        var flagType = CharacterAbilityGroup.ParseFlagType(subElement.GetAttributeString("flagtype", ""), parentDebugName);
                        AfflictionAbilityFlags.Add(flagType);
                        break;
                    }
                }
            }
Esempio n. 3
0
        public Attack(XElement element, string parentDebugName)
        {
            Deserialize(element);

            if (element.Attribute("damage") != null ||
                element.Attribute("bluntdamage") != null ||
                element.Attribute("burndamage") != null ||
                element.Attribute("bleedingdamage") != null)
            {
                DebugConsole.ThrowError("Error in Attack (" + parentDebugName + ") - Define damage as afflictions instead of using the damage attribute (e.g. <Affliction identifier=\"internaldamage\" strength=\"10\" />).");
            }

            InitProjSpecific(element);

            foreach (XElement subElement in element.Elements())
            {
                switch (subElement.Name.ToString().ToLowerInvariant())
                {
                case "statuseffect":
                    statusEffects.Add(StatusEffect.Load(subElement, parentDebugName));
                    break;

                case "affliction":
                    AfflictionPrefab afflictionPrefab;
                    if (subElement.Attribute("name") != null)
                    {
                        DebugConsole.ThrowError("Error in Attack (" + parentDebugName + ") - define afflictions using identifiers instead of names.");
                        string afflictionName = subElement.GetAttributeString("name", "").ToLowerInvariant();
                        afflictionPrefab = AfflictionPrefab.List.FirstOrDefault(ap => ap.Name.Equals(afflictionName, System.StringComparison.OrdinalIgnoreCase));
                        if (afflictionPrefab == null)
                        {
                            DebugConsole.ThrowError("Error in Attack (" + parentDebugName + ") - Affliction prefab \"" + afflictionName + "\" not found.");
                            continue;
                        }
                    }
                    else
                    {
                        string afflictionIdentifier = subElement.GetAttributeString("identifier", "").ToLowerInvariant();
                        afflictionPrefab = AfflictionPrefab.List.FirstOrDefault(ap => ap.Identifier.Equals(afflictionIdentifier, System.StringComparison.OrdinalIgnoreCase));
                        if (afflictionPrefab == null)
                        {
                            DebugConsole.ThrowError("Error in Attack (" + parentDebugName + ") - Affliction prefab \"" + afflictionIdentifier + "\" not found.");
                            continue;
                        }
                    }
                    break;

                case "conditional":
                    foreach (XAttribute attribute in subElement.Attributes())
                    {
                        if (PropertyConditional.IsValid(attribute))
                        {
                            Conditionals.Add(new PropertyConditional(attribute));
                        }
                    }
                    break;
                }
            }
        }
Esempio n. 4
0
        private static XElement ParseMedical(ItemPrefab prefab)
        {
            XElement?itemMeleeWeapon = prefab.ConfigElement.GetChildElement(nameof(MeleeWeapon));
            // affliction, amount, duration
            List <Tuple <string, float, float> > onSuccessAfflictions = new List <Tuple <string, float, float> >();
            List <Tuple <string, float, float> > onFailureAfflictions = new List <Tuple <string, float, float> >();
            int medicalRequiredSkill = 0;

            if (itemMeleeWeapon != null)
            {
                List <StatusEffect> statusEffects = new List <StatusEffect>();
                foreach (XElement subElement in itemMeleeWeapon.Elements())
                {
                    string name = subElement.Name.ToString();
                    if (name.Equals(nameof(StatusEffect), StringComparison.OrdinalIgnoreCase))
                    {
                        StatusEffect statusEffect = StatusEffect.Load(subElement, debugIdentifier);
                        if (statusEffect == null || !statusEffect.HasTag("medical"))
                        {
                            continue;
                        }

                        statusEffects.Add(statusEffect);
                    }
                    else if (IsRequiredSkill(subElement, out Skill? skill) && skill != null)
                    {
                        medicalRequiredSkill = (int)skill.Level;
                    }
                }

                List <StatusEffect> successEffects = statusEffects.Where(se => se.type == ActionType.OnUse).ToList();
                List <StatusEffect> failureEffects = statusEffects.Where(se => se.type == ActionType.OnFailure).ToList();

                foreach (StatusEffect statusEffect in successEffects)
                {
                    float duration = statusEffect.Duration;
                    onSuccessAfflictions.AddRange(statusEffect.ReduceAffliction.Select(pair => Tuple.Create(GetAfflictionName(pair.affliction), -pair.amount, duration)));
                    onSuccessAfflictions.AddRange(statusEffect.Afflictions.Select(affliction => Tuple.Create(affliction.Prefab.Name, affliction.NonClampedStrength, duration)));
                }

                foreach (StatusEffect statusEffect in failureEffects)
                {
                    float duration = statusEffect.Duration;
                    onFailureAfflictions.AddRange(statusEffect.ReduceAffliction.Select(pair => Tuple.Create(GetAfflictionName(pair.affliction), -pair.amount, duration)));
                    onFailureAfflictions.AddRange(statusEffect.Afflictions.Select(affliction => Tuple.Create(affliction.Prefab.Name, affliction.NonClampedStrength, duration)));
                }
            }

            return(new XElement("Medical",
                                new XAttribute("skillamount", medicalRequiredSkill),
                                new XAttribute("successafflictions", FormatArray(onSuccessAfflictions.Select(tpl => tpl.Item1))),
                                new XAttribute("successamounts", FormatArray(onSuccessAfflictions.Select(tpl => FormatFloat(tpl.Item2)))),
                                new XAttribute("successdurations", FormatArray(onSuccessAfflictions.Select(tpl => FormatFloat(tpl.Item3)))),
                                new XAttribute("failureafflictions", FormatArray(onFailureAfflictions.Select(tpl => tpl.Item1))),
                                new XAttribute("failureamounts", FormatArray(onFailureAfflictions.Select(tpl => FormatFloat(tpl.Item2)))),
                                new XAttribute("failuredurations", FormatArray(onFailureAfflictions.Select(tpl => FormatFloat(tpl.Item3))))
                                ));
        }
Esempio n. 5
0
        public Attack(XElement element)
        {
            try
            {
                DamageType = (DamageType)Enum.Parse(typeof(DamageType), ToolBox.GetAttributeString(element, "damagetype", "None"), true);
            }
            catch
            {
                DamageType = DamageType.None;
            }

            damage          = ToolBox.GetAttributeFloat(element, "damage", 0.0f);
            structureDamage = ToolBox.GetAttributeFloat(element, "structuredamage", 0.0f);
            bleedingDamage  = ToolBox.GetAttributeFloat(element, "bleedingdamage", 0.0f);
            Stun            = ToolBox.GetAttributeFloat(element, "stun", 0.0f);

            SeverLimbsProbability = ToolBox.GetAttributeFloat(element, "severlimbsprobability", 0.0f);

            Force       = ToolBox.GetAttributeFloat(element, "force", 0.0f);
            TargetForce = ToolBox.GetAttributeFloat(element, "targetforce", 0.0f);
            Torque      = ToolBox.GetAttributeFloat(element, "torque", 0.0f);

            Range    = ToolBox.GetAttributeFloat(element, "range", 0.0f);
            Duration = ToolBox.GetAttributeFloat(element, "duration", 0.0f);

            priority = ToolBox.GetAttributeFloat(element, "priority", 1.0f);

            InitProjSpecific(element);

            string limbIndicesStr = ToolBox.GetAttributeString(element, "applyforceonlimbs", "");

            if (!string.IsNullOrWhiteSpace(limbIndicesStr))
            {
                ApplyForceOnLimbs = new List <int>();
                foreach (string limbIndexStr in limbIndicesStr.Split(','))
                {
                    int limbIndex;
                    if (int.TryParse(limbIndexStr, out limbIndex))
                    {
                        ApplyForceOnLimbs.Add(limbIndex);
                    }
                }
            }

            foreach (XElement subElement in element.Elements())
            {
                switch (subElement.Name.ToString().ToLowerInvariant())
                {
                case "statuseffect":
                    if (statusEffects == null)
                    {
                        statusEffects = new List <StatusEffect>();
                    }
                    statusEffects.Add(StatusEffect.Load(subElement));
                    break;
                }
            }
        }
Esempio n. 6
0
        public Attack(XElement element)
        {
            try
            {
                DamageType = (DamageType)Enum.Parse(typeof(DamageType), ToolBox.GetAttributeString(element, "damagetype", "None"), true);
            }
            catch
            {
                DamageType = DamageType.None;
            }


            damage          = ToolBox.GetAttributeFloat(element, "damage", 0.0f);
            structureDamage = ToolBox.GetAttributeFloat(element, "structuredamage", 0.0f);
            bleedingDamage  = ToolBox.GetAttributeFloat(element, "bleedingdamage", 0.0f);

            Force       = ToolBox.GetAttributeFloat(element, "force", 0.0f);
            TargetForce = ToolBox.GetAttributeFloat(element, "targetforce", 0.0f);

            Torque = ToolBox.GetAttributeFloat(element, "torque", 0.0f);

            Stun = ToolBox.GetAttributeFloat(element, "stun", 0.0f);

            string soundPath = ToolBox.GetAttributeString(element, "sound", "");

            if (!string.IsNullOrWhiteSpace(soundPath))
            {
                sound = Sound.Load(soundPath);
            }

            Range = ToolBox.GetAttributeFloat(element, "range", 0.0f);

            Duration = ToolBox.GetAttributeFloat(element, "duration", 0.0f);

            priority = ToolBox.GetAttributeFloat(element, "priority", 1.0f);

            foreach (XElement subElement in element.Elements())
            {
                switch (subElement.Name.ToString().ToLowerInvariant())
                {
                case "particleemitter":
                    particleEmitterPrefab = new ParticleEmitterPrefab(subElement);
                    break;

                case "statuseffect":
                    if (statusEffects == null)
                    {
                        statusEffects = new List <StatusEffect>();
                    }
                    statusEffects.Add(StatusEffect.Load(subElement));
                    break;
                }
            }
        }
Esempio n. 7
0
            public Effect(XElement element, string parentDebugName)
            {
                MinStrength = element.GetAttributeFloat("minstrength", 0);
                MaxStrength = element.GetAttributeFloat("maxstrength", 0);

                MultiplyByMaxVitality = element.GetAttributeBool("multiplybymaxvitality", false);

                MinVitalityDecrease = element.GetAttributeFloat("minvitalitydecrease", 0.0f);
                MaxVitalityDecrease = element.GetAttributeFloat("maxvitalitydecrease", 0.0f);
                MaxVitalityDecrease = Math.Max(MinVitalityDecrease, MaxVitalityDecrease);

                MinScreenDistortStrength = element.GetAttributeFloat("minscreendistort", 0.0f);
                MaxScreenDistortStrength = element.GetAttributeFloat("maxscreendistort", 0.0f);
                MaxScreenDistortStrength = Math.Max(MinScreenDistortStrength, MaxScreenDistortStrength);

                MinRadialDistortStrength = element.GetAttributeFloat("minradialdistort", 0.0f);
                MaxRadialDistortStrength = element.GetAttributeFloat("maxradialdistort", 0.0f);
                MaxRadialDistortStrength = Math.Max(MinRadialDistortStrength, MaxRadialDistortStrength);

                MinChromaticAberrationStrength = element.GetAttributeFloat("minchromaticaberration", 0.0f);
                MaxChromaticAberrationStrength = element.GetAttributeFloat("maxchromaticaberration", 0.0f);
                MaxChromaticAberrationStrength = Math.Max(MinChromaticAberrationStrength, MaxChromaticAberrationStrength);

                MinScreenBlurStrength = element.GetAttributeFloat("minscreenblur", 0.0f);
                MaxScreenBlurStrength = element.GetAttributeFloat("maxscreenblur", 0.0f);
                MaxScreenBlurStrength = Math.Max(MinScreenBlurStrength, MaxScreenBlurStrength);

                ResistanceFor = element.GetAttributeString("resistancefor", "");
                MinResistance = element.GetAttributeFloat("minresistance", 0.0f);
                MaxResistance = element.GetAttributeFloat("maxresistance", 0.0f);
                MaxResistance = Math.Max(MinResistance, MaxResistance);

                MinSpeedMultiplier = element.GetAttributeFloat("minspeedmultiplier", 1.0f);
                MaxSpeedMultiplier = element.GetAttributeFloat("maxspeedmultiplier", 1.0f);
                MaxSpeedMultiplier = Math.Max(MinSpeedMultiplier, MaxSpeedMultiplier);

                MinBuffMultiplier = element.GetAttributeFloat("minbuffmultiplier", 1.0f);
                MaxBuffMultiplier = element.GetAttributeFloat("maxbuffmultiplier", 1.0f);
                MaxBuffMultiplier = Math.Max(MinBuffMultiplier, MaxBuffMultiplier);

                DialogFlag = element.GetAttributeString("dialogflag", "");

                StrengthChange = element.GetAttributeFloat("strengthchange", 0.0f);

                foreach (XElement subElement in element.Elements())
                {
                    switch (subElement.Name.ToString().ToLowerInvariant())
                    {
                    case "statuseffect":
                        StatusEffects.Add(StatusEffect.Load(subElement, parentDebugName));
                        break;
                    }
                }
            }
Esempio n. 8
0
            public PeriodicEffect(XElement element, string parentDebugName)
            {
                foreach (XElement subElement in element.Elements())
                {
                    StatusEffects.Add(StatusEffect.Load(subElement, parentDebugName));
                }

                if (element.Attribute("interval") != null)
                {
                    MinInterval = MaxInterval = Math.Max(element.GetAttributeFloat("interval", 1.0f), 1.0f);
                }
                else
                {
                    MinInterval = Math.Max(element.GetAttributeFloat("mininterval", 1.0f), 1.0f);
                    MaxInterval = Math.Max(element.GetAttributeFloat("maxinterval", 1.0f), MinInterval);
                }
            }
        public StatusEffectAction(ScriptedEvent parentEvent, XElement element) : base(parentEvent, element)
        {
            actionIndex = 0;
            foreach (XElement subElement in parentEvent.Prefab.ConfigElement.Descendants())
            {
                if (subElement == element)
                {
                    break;
                }
                actionIndex++;
            }

            foreach (XElement subElement in element.Elements())
            {
                switch (subElement.Name.ToString().ToLowerInvariant())
                {
                case "statuseffect":
                    effects.Add(StatusEffect.Load(subElement, $"{nameof(StatusEffectAction)} ({parentEvent.Prefab.Identifier})"));
                    break;
                }
            }
        }
Esempio n. 10
0
        public Attack(XElement element)
        {
            SerializableProperty.DeserializeProperties(this, element);

            DamageRange = element.GetAttributeFloat("damagerange", Range);

            InitProjSpecific(element);

            string limbIndicesStr = element.GetAttributeString("applyforceonlimbs", "");

            if (!string.IsNullOrWhiteSpace(limbIndicesStr))
            {
                ApplyForceOnLimbs = new List <int>();
                foreach (string limbIndexStr in limbIndicesStr.Split(','))
                {
                    int limbIndex;
                    if (int.TryParse(limbIndexStr, out limbIndex))
                    {
                        ApplyForceOnLimbs.Add(limbIndex);
                    }
                }
            }

            foreach (XElement subElement in element.Elements())
            {
                switch (subElement.Name.ToString().ToLowerInvariant())
                {
                case "statuseffect":
                    if (statusEffects == null)
                    {
                        statusEffects = new List <StatusEffect>();
                    }
                    statusEffects.Add(StatusEffect.Load(subElement));
                    break;
                }
            }
        }
        public static RelatedItem Load(XElement element)
        {
            string nameString = element.GetAttributeString("name", "");

            if (nameString == "")
            {
                return(null);
            }

            string[] names = nameString.Split(',');

            RelatedItem ri = new RelatedItem(names);

            try
            {
                ri.type = (RelationType)Enum.Parse(typeof(RelationType), element.GetAttributeString("type", "None"));
            }

            catch
            {
                ri.type = RelationType.None;
            }

            ri.Msg = element.GetAttributeString("msg", "");

            foreach (XElement subElement in element.Elements())
            {
                if (subElement.Name.ToString().ToLowerInvariant() != "statuseffect")
                {
                    continue;
                }

                ri.statusEffects.Add(StatusEffect.Load(subElement));
            }

            return(ri);
        }
Esempio n. 12
0
 public static void LoadStatusEffect(List <StatusEffect> statusEffects, XElement element, string parentDebugName)
 {
     statusEffects.Add(StatusEffect.Load(element, parentDebugName));
 }
Esempio n. 13
0
        protected override void StartMissionSpecific(Level level)
        {
            if (items.Any())
            {
#if DEBUG
                throw new Exception($"items.Count > 0 ({items.Count})");
#else
                DebugConsole.AddWarning("Item list was not empty at the start of a nest mission. The mission instance may not have been ended correctly on previous rounds.");
                items.Clear();
#endif
            }

            if (!IsClient)
            {
                //ruin/cave/wreck items are allowed to spawn close to the sub
                float minDistance = spawnPositionType == Level.PositionType.Ruin || spawnPositionType == Level.PositionType.Cave || spawnPositionType == Level.PositionType.Wreck ?
                                    0.0f : Level.Loaded.Size.X * 0.3f;

                nestPosition = Level.Loaded.GetRandomItemPos(spawnPositionType, 100.0f, minDistance, 30.0f);
                List <GraphEdge> spawnEdges = new List <GraphEdge>();
                if (spawnPositionType == Level.PositionType.Cave)
                {
                    Level.Cave closestCave     = null;
                    float      closestCaveDist = float.PositiveInfinity;
                    foreach (var cave in Level.Loaded.Caves)
                    {
                        float dist = Vector2.DistanceSquared(nestPosition, cave.Area.Center.ToVector2());
                        if (dist < closestCaveDist)
                        {
                            closestCave     = cave;
                            closestCaveDist = dist;
                        }
                    }
                    if (closestCave != null)
                    {
                        closestCave.DisplayOnSonar = true;
                        SpawnNestObjects(level, closestCave);
#if SERVER
                        selectedCave = closestCave;
#endif
                    }
                    var nearbyCells = Level.Loaded.GetCells(nestPosition, searchDepth: 3);
                    if (nearbyCells.Any())
                    {
                        List <GraphEdge> validEdges = new List <GraphEdge>();
                        foreach (var edge in nearbyCells.SelectMany(c => c.Edges))
                        {
                            if (!edge.NextToCave || !edge.IsSolid)
                            {
                                continue;
                            }
                            if (Level.Loaded.ExtraWalls.Any(w => w.IsPointInside(edge.Center + edge.GetNormal(edge.Cell1 ?? edge.Cell2) * 100.0f)))
                            {
                                continue;
                            }
                            validEdges.Add(edge);
                        }

                        if (validEdges.Any())
                        {
                            spawnEdges.AddRange(validEdges.Where(e => MathUtils.LineSegmentToPointDistanceSquared(e.Point1.ToPoint(), e.Point2.ToPoint(), nestPosition.ToPoint()) < itemSpawnRadius * itemSpawnRadius).Distinct());
                        }
                        //no valid edges found close enough to the nest position, find the closest one
                        if (!spawnEdges.Any())
                        {
                            GraphEdge closestEdge    = null;
                            float     closestDistSqr = float.PositiveInfinity;
                            foreach (var edge in nearbyCells.SelectMany(c => c.Edges))
                            {
                                if (!edge.NextToCave || !edge.IsSolid)
                                {
                                    continue;
                                }
                                float dist = Vector2.DistanceSquared(edge.Center, nestPosition);
                                if (dist < closestDistSqr)
                                {
                                    closestEdge    = edge;
                                    closestDistSqr = dist;
                                }
                            }
                            if (closestEdge != null)
                            {
                                spawnEdges.Add(closestEdge);
                                itemSpawnRadius = Math.Max(itemSpawnRadius, (float)Math.Sqrt(closestDistSqr) * 1.5f);
                            }
                        }
                    }
                }

                foreach (XElement subElement in itemConfig.Elements())
                {
                    string itemIdentifier = subElement.GetAttributeString("identifier", "");
                    if (!(MapEntityPrefab.Find(null, itemIdentifier) is ItemPrefab itemPrefab))
                    {
                        DebugConsole.ThrowError("Couldn't spawn item for nest mission: item prefab \"" + itemIdentifier + "\" not found");
                        continue;
                    }

                    Vector2 spawnPos = nestPosition;
                    float   rotation = 0.0f;
                    if (spawnEdges.Any())
                    {
                        var edge = spawnEdges.GetRandom(Rand.RandSync.Server);
                        spawnPos = Vector2.Lerp(edge.Point1, edge.Point2, Rand.Range(0.1f, 0.9f, Rand.RandSync.Server));
                        Vector2 normal = Vector2.UnitY;
                        if (edge.Cell1 != null && edge.Cell1.CellType == CellType.Solid)
                        {
                            normal = edge.GetNormal(edge.Cell1);
                        }
                        else if (edge.Cell2 != null && edge.Cell2.CellType == CellType.Solid)
                        {
                            normal = edge.GetNormal(edge.Cell2);
                        }
                        spawnPos += normal * 10.0f;
                        rotation  = MathUtils.VectorToAngle(normal) - MathHelper.PiOver2;
                    }

                    var item = new Item(itemPrefab, spawnPos, null);
                    item.body.FarseerBody.BodyType = BodyType.Kinematic;
                    item.body.SetTransformIgnoreContacts(item.body.SimPosition, rotation);
                    item.FindHull();
                    items.Add(item);

                    var statusEffectElement = subElement.Element("StatusEffectOnApproach") ?? subElement.Element("statuseffectonapproach");
                    if (statusEffectElement != null)
                    {
                        statusEffectOnApproach.Add(item, StatusEffect.Load(statusEffectElement, Prefab.Identifier));
                    }
                }
            }
        }
Esempio n. 14
0
        public SalvageMission(MissionPrefab prefab, Location[] locations)
            : base(prefab, locations)
        {
            containerTag = prefab.ConfigElement.GetAttributeString("containertag", "");

            if (prefab.ConfigElement.Attribute("itemname") != null)
            {
                DebugConsole.ThrowError("Error in SalvageMission - use item identifier instead of the name of the item.");
                string itemName = prefab.ConfigElement.GetAttributeString("itemname", "");
                itemPrefab = MapEntityPrefab.Find(itemName) as ItemPrefab;
                if (itemPrefab == null)
                {
                    DebugConsole.ThrowError("Error in SalvageMission: couldn't find an item prefab with the name " + itemName);
                }
            }
            else
            {
                string itemIdentifier = prefab.ConfigElement.GetAttributeString("itemidentifier", "");
                itemPrefab = MapEntityPrefab.Find(null, itemIdentifier) as ItemPrefab;
                if (itemPrefab == null)
                {
                    DebugConsole.ThrowError("Error in SalvageMission - couldn't find an item prefab with the identifier " + itemIdentifier);
                }
            }

            existingItemTag         = prefab.ConfigElement.GetAttributeString("existingitemtag", "");
            showMessageWhenPickedUp = prefab.ConfigElement.GetAttributeBool("showmessagewhenpickedup", false);

            string spawnPositionTypeStr = prefab.ConfigElement.GetAttributeString("spawntype", "");

            if (string.IsNullOrWhiteSpace(spawnPositionTypeStr) ||
                !Enum.TryParse(spawnPositionTypeStr, true, out spawnPositionType))
            {
                spawnPositionType = Level.PositionType.Cave | Level.PositionType.Ruin;
            }

            foreach (XElement element in prefab.ConfigElement.Elements())
            {
                switch (element.Name.ToString().ToLowerInvariant())
                {
                case "statuseffect":
                {
                    var newEffect = StatusEffect.Load(element, parentDebugName: prefab.Name);
                    if (newEffect == null)
                    {
                        continue;
                    }
                    statusEffects.Add(new List <StatusEffect> {
                            newEffect
                        });
                    break;
                }

                case "chooserandom":
                    statusEffects.Add(new List <StatusEffect>());
                    foreach (XElement subElement in element.Elements())
                    {
                        var newEffect = StatusEffect.Load(subElement, parentDebugName: prefab.Name);
                        if (newEffect == null)
                        {
                            continue;
                        }
                        statusEffects.Last().Add(newEffect);
                    }
                    break;
                }
            }
        }
Esempio n. 15
0
        public Attack(XElement element, string parentDebugName)
        {
            SourceElement = element;
            Deserialize();

            if (element.Attribute("damage") != null ||
                element.Attribute("bluntdamage") != null ||
                element.Attribute("burndamage") != null ||
                element.Attribute("bleedingdamage") != null)
            {
                DebugConsole.ThrowError("Error in Attack (" + parentDebugName + ") - Define damage as afflictions instead of using the damage attribute (e.g. <Affliction identifier=\"internaldamage\" strength=\"10\" />).");
            }

            DamageRange = element.GetAttributeFloat("damagerange", 0f);

            InitProjSpecific(element);

            foreach (XElement subElement in element.Elements())
            {
                switch (subElement.Name.ToString().ToLowerInvariant())
                {
                case "statuseffect":
                    if (statusEffects == null)
                    {
                        statusEffects = new List <StatusEffect>();
                    }
                    statusEffects.Add(StatusEffect.Load(subElement, parentDebugName));
                    break;

                case "affliction":
                    AfflictionPrefab afflictionPrefab;
                    if (subElement.Attribute("name") != null)
                    {
                        DebugConsole.ThrowError("Error in Attack (" + parentDebugName + ") - define afflictions using identifiers instead of names.");
                        string afflictionName = subElement.GetAttributeString("name", "").ToLowerInvariant();
                        afflictionPrefab = AfflictionPrefab.List.Find(ap => ap.Name.ToLowerInvariant() == afflictionName);
                        if (afflictionPrefab == null)
                        {
                            DebugConsole.ThrowError("Error in Attack (" + parentDebugName + ") - Affliction prefab \"" + afflictionName + "\" not found.");
                            continue;
                        }
                    }
                    else
                    {
                        string afflictionIdentifier = subElement.GetAttributeString("identifier", "").ToLowerInvariant();
                        afflictionPrefab = AfflictionPrefab.List.Find(ap => ap.Identifier.ToLowerInvariant() == afflictionIdentifier);
                        if (afflictionPrefab == null)
                        {
                            DebugConsole.ThrowError("Error in Attack (" + parentDebugName + ") - Affliction prefab \"" + afflictionIdentifier + "\" not found.");
                            continue;
                        }
                    }

                    float afflictionStrength = subElement.GetAttributeFloat(1.0f, "amount", "strength");
                    var   affliction         = afflictionPrefab.Instantiate(afflictionStrength);
                    affliction.ApplyProbability = subElement.GetAttributeFloat("probability", 1.0f);
                    Afflictions.Add(affliction);

                    break;

                case "conditional":
                    foreach (XAttribute attribute in subElement.Attributes())
                    {
                        Conditionals.Add(new PropertyConditional(attribute));
                    }
                    break;
                }
            }
        }
Esempio n. 16
0
        public static RelatedItem Load(XElement element, bool returnEmpty, string parentDebugName)
        {
            string[] identifiers;
            if (element.Attribute("name") != null)
            {
                //backwards compatibility + a console warning
                DebugConsole.ThrowError("Error in RelatedItem config (" + (string.IsNullOrEmpty(parentDebugName) ? element.ToString() : parentDebugName) + ") - use item tags or identifiers instead of names.");
                string[] itemNames = element.GetAttributeStringArray("name", new string[0]);
                //attempt to convert to identifiers and tags
                List <string> convertedIdentifiers = new List <string>();
                foreach (string itemName in itemNames)
                {
                    var matchingItem = ItemPrefab.Prefabs.Find(me => me.Name == itemName);
                    if (matchingItem != null)
                    {
                        convertedIdentifiers.Add(matchingItem.Identifier);
                    }
                    else
                    {
                        //no matching item found, this must be a tag
                        convertedIdentifiers.Add(itemName);
                    }
                }
                identifiers = convertedIdentifiers.ToArray();
            }
            else
            {
                identifiers = element.GetAttributeStringArray("items", null, convertToLowerInvariant: true) ?? element.GetAttributeStringArray("item", null, convertToLowerInvariant: true);
                if (identifiers == null)
                {
                    identifiers = element.GetAttributeStringArray("identifiers", null, convertToLowerInvariant: true) ?? element.GetAttributeStringArray("tags", null, convertToLowerInvariant: true);
                    if (identifiers == null)
                    {
                        identifiers = element.GetAttributeStringArray("identifier", null, convertToLowerInvariant: true) ?? element.GetAttributeStringArray("tag", new string[0], convertToLowerInvariant: true);
                    }
                }
            }

            string[] excludedIdentifiers = element.GetAttributeStringArray("excludeditems", null, convertToLowerInvariant: true) ?? element.GetAttributeStringArray("excludeditem", null, convertToLowerInvariant: true);
            if (excludedIdentifiers == null)
            {
                excludedIdentifiers = element.GetAttributeStringArray("excludedidentifiers", null, convertToLowerInvariant: true) ?? element.GetAttributeStringArray("excludedtags", null, convertToLowerInvariant: true);
                if (excludedIdentifiers == null)
                {
                    excludedIdentifiers = element.GetAttributeStringArray("excludedidentifier", null, convertToLowerInvariant: true) ?? element.GetAttributeStringArray("excludedtag", new string[0], convertToLowerInvariant: true);
                }
            }

            if (identifiers.Length == 0 && excludedIdentifiers.Length == 0 && !returnEmpty)
            {
                return(null);
            }

            RelatedItem ri      = new RelatedItem(identifiers, excludedIdentifiers);
            string      typeStr = element.GetAttributeString("type", "");

            if (string.IsNullOrEmpty(typeStr))
            {
                switch (element.Name.ToString().ToLowerInvariant())
                {
                case "containable":
                    typeStr = "Contained";
                    break;

                case "suitablefertilizer":
                case "suitableseed":
                    typeStr = "None";
                    break;
                }
            }
            if (!Enum.TryParse(typeStr, true, out ri.type))
            {
                DebugConsole.ThrowError("Error in RelatedItem config (" + parentDebugName + ") - \"" + typeStr + "\" is not a valid relation type.");
                return(null);
            }

            ri.MsgTag = element.GetAttributeString("msg", "");
            string msg = TextManager.Get(ri.MsgTag, true);

            if (msg == null)
            {
                ri.Msg = ri.MsgTag;
            }
            else
            {
#if CLIENT
                foreach (InputType inputType in Enum.GetValues(typeof(InputType)))
                {
                    msg = msg.Replace("[" + inputType.ToString().ToLowerInvariant() + "]", GameMain.Config.KeyBindText(inputType));
                }
                ri.Msg = msg;
#endif
            }

            foreach (XElement subElement in element.Elements())
            {
                if (!subElement.Name.ToString().Equals("statuseffect", StringComparison.OrdinalIgnoreCase))
                {
                    continue;
                }
                ri.statusEffects.Add(StatusEffect.Load(subElement, parentDebugName));
            }

            ri.IsOptional     = element.GetAttributeBool("optional", false);
            ri.IgnoreInEditor = element.GetAttributeBool("ignoreineditor", false);
            ri.MatchOnEmpty   = element.GetAttributeBool("matchonempty", false);
            return(ri);
        }
Esempio n. 17
0
        public static RelatedItem Load(XElement element, string parentDebugName)
        {
            string[] identifiers;
            if (element.Attribute("name") != null)
            {
                //backwards compatibility + a console warning
                DebugConsole.ThrowError("Error in RelatedItem config (" + (string.IsNullOrEmpty(parentDebugName) ? element.ToString() : parentDebugName) + ") - use item identifiers or tags instead of names.");
                string[] itemNames = element.GetAttributeStringArray("name", new string[0]);
                //attempt to convert to identifiers and tags
                List <string> convertedIdentifiers = new List <string>();
                foreach (string itemName in itemNames)
                {
                    if (MapEntityPrefab.List.Find(me => me.Name == itemName) is ItemPrefab matchingItem)
                    {
                        convertedIdentifiers.Add(matchingItem.Identifier);
                    }
                    else
                    {
                        //no matching item found, this must be a tag
                        convertedIdentifiers.Add(itemName);
                    }
                }
                identifiers = convertedIdentifiers.ToArray();
            }
            else
            {
                identifiers = element.GetAttributeStringArray("identifiers", new string[0]);
                if (identifiers.Length == 0)
                {
                    identifiers = element.GetAttributeStringArray("identifier", new string[0]);
                }
            }

            string[] excludedIdentifiers = element.GetAttributeStringArray("excludedidentifiers", new string[0]);
            if (excludedIdentifiers.Length == 0)
            {
                excludedIdentifiers = element.GetAttributeStringArray("excludedidentifier", new string[0]);
            }

            if (identifiers.Length == 0 && excludedIdentifiers.Length == 0)
            {
                return(null);
            }

            RelatedItem ri = new RelatedItem(identifiers, excludedIdentifiers);

            string typeStr = element.GetAttributeString("type", "");

            if (string.IsNullOrEmpty(typeStr))
            {
                if (element.Name.ToString().ToLowerInvariant() == "containable")
                {
                    typeStr = "Contained";
                }
            }
            if (!Enum.TryParse(typeStr, true, out ri.type))
            {
                DebugConsole.ThrowError("Error in RelatedItem config (" + parentDebugName + ") - \"" + typeStr + "\" is not a valid relation type.");
                return(null);
            }

            string msgTag = element.GetAttributeString("msg", "");
            string msg    = TextManager.Get(msgTag, true);

            if (msg == null)
            {
                ri.Msg = msgTag;
            }
            else
            {
#if CLIENT
                foreach (InputType inputType in Enum.GetValues(typeof(InputType)))
                {
                    msg = msg.Replace("[" + inputType.ToString().ToLowerInvariant() + "]", GameMain.Config.KeyBind(inputType).ToString());
                }
                ri.Msg = msg;
#endif
            }

            foreach (XElement subElement in element.Elements())
            {
                if (subElement.Name.ToString().ToLowerInvariant() != "statuseffect")
                {
                    continue;
                }
                ri.statusEffects.Add(StatusEffect.Load(subElement, parentDebugName));
            }

            ri.IsOptional = element.GetAttributeBool("optional", false);
            return(ri);
        }
Esempio n. 18
0
        public LevelTrigger(XElement element, Vector2 position, float rotation, float scale = 1.0f, string parentDebugName = "")
        {
            TriggererPosition = new Dictionary <Entity, Vector2>();

            worldPosition = position;
            if (element.Attributes("radius").Any() || element.Attributes("width").Any() || element.Attributes("height").Any())
            {
                physicsBody = new PhysicsBody(element, scale)
                {
                    CollisionCategories = Physics.CollisionLevel,
                    CollidesWith        = Physics.CollisionCharacter | Physics.CollisionItem | Physics.CollisionProjectile | Physics.CollisionWall
                };
                physicsBody.FarseerBody.OnCollision  += PhysicsBody_OnCollision;
                physicsBody.FarseerBody.OnSeparation += PhysicsBody_OnSeparation;
                physicsBody.FarseerBody.IsSensor      = true;
                physicsBody.FarseerBody.IsStatic      = true;
                physicsBody.FarseerBody.IsKinematic   = true;

                ColliderRadius = ConvertUnits.ToDisplayUnits(Math.Max(Math.Max(PhysicsBody.radius, PhysicsBody.width / 2.0f), PhysicsBody.height / 2.0f));

                physicsBody.SetTransform(ConvertUnits.ToSimUnits(position), rotation);
            }

            cameraShake = element.GetAttributeFloat("camerashake", 0.0f);

            stayTriggeredDelay       = element.GetAttributeFloat("staytriggereddelay", 0.0f);
            randomTriggerInterval    = element.GetAttributeFloat("randomtriggerinterval", 0.0f);
            randomTriggerProbability = element.GetAttributeFloat("randomtriggerprobability", 0.0f);

            UseNetworkSyncing = element.GetAttributeBool("networksyncing", false);

            unrotatedForce =
                element.Attribute("force") != null && element.Attribute("force").Value.Contains(',') ?
                element.GetAttributeVector2("force", Vector2.Zero) :
                new Vector2(element.GetAttributeFloat("force", 0.0f), 0.0f);

            ForceFluctuationInterval = element.GetAttributeFloat("forcefluctuationinterval", 0.01f);
            ForceFluctuationStrength = Math.Max(element.GetAttributeFloat("forcefluctuationstrength", 0.0f), 0.0f);
            ForceFalloff             = element.GetAttributeBool("forcefalloff", true);

            ForceVelocityLimit = ConvertUnits.ToSimUnits(element.GetAttributeFloat("forcevelocitylimit", float.MaxValue));
            string forceModeStr = element.GetAttributeString("forcemode", "Force");

            if (!Enum.TryParse(forceModeStr, out forceMode))
            {
                DebugConsole.ThrowError("Error in LevelTrigger config: \"" + forceModeStr + "\" is not a valid force mode.");
            }
            CalculateDirectionalForce();

            string triggeredByStr = element.GetAttributeString("triggeredby", "Character");

            if (!Enum.TryParse(triggeredByStr, out triggeredBy))
            {
                DebugConsole.ThrowError("Error in LevelTrigger config: \"" + triggeredByStr + "\" is not a valid triggerer type.");
            }
            UpdateCollisionCategories();
            triggerOthersDistance = element.GetAttributeFloat("triggerothersdistance", 0.0f);

            var tagsArray = element.GetAttributeStringArray("tags", new string[0]);

            foreach (string tag in tagsArray)
            {
                tags.Add(tag.ToLower());
            }

            if (triggeredBy.HasFlag(TriggererType.OtherTrigger))
            {
                var otherTagsArray = element.GetAttributeStringArray("allowedothertriggertags", new string[0]);
                foreach (string tag in otherTagsArray)
                {
                    allowedOtherTriggerTags.Add(tag.ToLower());
                }
            }

            foreach (XElement subElement in element.Elements())
            {
                switch (subElement.Name.ToString().ToLowerInvariant())
                {
                case "statuseffect":
                    statusEffects.Add(StatusEffect.Load(subElement, string.IsNullOrEmpty(parentDebugName) ? "LevelTrigger" : "LevelTrigger in " + parentDebugName));
                    break;

                case "attack":
                case "damage":
                    var attack = new Attack(subElement, string.IsNullOrEmpty(parentDebugName) ? "LevelTrigger" : "LevelTrigger in " + parentDebugName);
                    var multipliedAfflictions = attack.GetMultipliedAfflictions((float)Timing.Step);
                    attack.Afflictions.Clear();
                    foreach (Affliction affliction in multipliedAfflictions)
                    {
                        attack.Afflictions.Add(affliction, null);
                    }
                    attacks.Add(attack);
                    break;
                }
            }

            forceFluctuationTimer = Rand.Range(0.0f, ForceFluctuationInterval);
            randomTriggerTimer    = Rand.Range(0.0f, randomTriggerInterval);
        }
Esempio n. 19
0
        private static XElement ParseWeapon(ItemPrefab prefab)
        {
            float stun             = 0;
            bool  isAoE            = false;
            float?structDamage     = null;
            int   skillRequirement = 0;

            // affliction, amount
            List <Tuple <string, float> > damages = new List <Tuple <string, float> >();

            string[] validNames = { nameof(Projectile), nameof(MeleeWeapon), nameof(RepairTool), nameof(ItemComponent), nameof(RangedWeapon) };
            foreach (XElement icElement in prefab.ConfigElement.Elements())
            {
                string icName = icElement.Name.ToString();
                if (!validNames.Any(name => icName.Equals(name, StringComparison.OrdinalIgnoreCase)))
                {
                    continue;
                }

                foreach (XElement icChildElement in icElement.Elements())
                {
                    string name = icChildElement.Name.ToString();
                    if (IsRequiredSkill(icChildElement, out Skill? skill) && skill != null)
                    {
                        skillRequirement = (int)skill.Level;
                    }
                    else if (name.Equals(nameof(Attack), StringComparison.OrdinalIgnoreCase))
                    {
                        ParseAttack(new Attack(icChildElement, debugIdentifier));
                    }
                    else if (name.Equals(nameof(Explosion), StringComparison.OrdinalIgnoreCase))
                    {
                        ParseExplosion(new[] { new Explosion(icChildElement, debugIdentifier) });
                    }
                    else if (name.Equals(nameof(StatusEffect), StringComparison.OrdinalIgnoreCase))
                    {
                        ParseStatusEffect(new[] { StatusEffect.Load(icChildElement, debugIdentifier) });
                    }

                    void ParseStatusEffect(IEnumerable <StatusEffect> statusEffects)
                    {
                        foreach (StatusEffect effect in statusEffects)
                        {
                            if (effect.HasTargetType(StatusEffect.TargetType.Character))
                            {
                                continue;
                            }

                            ParseAfflictions(effect.Afflictions);
                            ParseExplosion(effect.Explosions);
                        }
                    }

                    void ParseExplosion(IEnumerable <Explosion> explosions)
                    {
                        foreach (Explosion explosion in explosions)
                        {
                            isAoE = true;
                            ParseAttack(explosion.Attack);
                            ParseStatusEffect(explosion.Attack.StatusEffects);
                        }
                    }

                    void ParseAttack(Attack attack)
                    {
                        structDamage ??= attack.StructureDamage;
                        ParseAfflictions(attack.Afflictions.Keys);
                        ParseStatusEffect(attack.StatusEffects);
                    }

                    void ParseAfflictions(IEnumerable <Affliction> afflictions)
                    {
                        foreach (Affliction affliction in afflictions)
                        {
                            // Exclude stuns
                            if (affliction.Prefab == AfflictionPrefab.Stun)
                            {
                                stun += affliction.NonClampedStrength;
                                continue;
                            }

                            damages.Add(Tuple.Create(affliction.Prefab.Name, affliction.NonClampedStrength));
                        }
                    }
                }
            }

            return(new XElement("Weapon",
                                new XAttribute("damagenames", FormatArray(damages.Select(tpl => tpl.Item1))),
                                new XAttribute("damageamounts", FormatArray(damages.Select(tpl => FormatFloat(tpl.Item2)))),
                                new XAttribute("isaoe", isAoE),
                                new XAttribute("structuredamage", structDamage ?? 0),
                                new XAttribute("stun", FormatFloat(stun)),
                                new XAttribute("skillrequirement", skillRequirement)
                                ));
        }