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; } } }
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; } } }
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; } } }
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)))) )); }
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; } } }
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; } } }
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; } } }
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; } } }
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); }
public static void LoadStatusEffect(List <StatusEffect> statusEffects, XElement element, string parentDebugName) { statusEffects.Add(StatusEffect.Load(element, parentDebugName)); }
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)); } } } }
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; } } }
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; } } }
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); }
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); }
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); }
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) )); }