diff --git a/Barotrauma/BarotraumaShared/Content/Items/Medical/medical.xml b/Barotrauma/BarotraumaShared/Content/Items/Medical/medical.xml
index 8e1510ba5..029b6f86d 100644
--- a/Barotrauma/BarotraumaShared/Content/Items/Medical/medical.xml
+++ b/Barotrauma/BarotraumaShared/Content/Items/Medical/medical.xml
@@ -380,8 +380,9 @@
-
-
+
+
+
diff --git a/Barotrauma/BarotraumaShared/Source/StatusEffects/PropertyConditional.cs b/Barotrauma/BarotraumaShared/Source/StatusEffects/PropertyConditional.cs
index e910950f9..d8884abd7 100644
--- a/Barotrauma/BarotraumaShared/Source/StatusEffects/PropertyConditional.cs
+++ b/Barotrauma/BarotraumaShared/Source/StatusEffects/PropertyConditional.cs
@@ -1,4 +1,5 @@
using System;
+using System.Collections.Generic;
using System.Globalization;
using System.Xml.Linq;
@@ -30,6 +31,8 @@ namespace Barotrauma
public readonly OperatorType Operator;
public readonly string Value;
+ private readonly int cancelStatusEffect;
+
public PropertyConditional(XAttribute attribute)
{
string attributeString = attribute.Value.ToString();
@@ -81,12 +84,25 @@ namespace Barotrauma
default:
if (op != "==" && op != "!=" && op != ">" && op != "<" && op != ">=" && op != "<=") //Didn't use escape strings or anything
{
- atStr = attributeString; //We probably don't even have an operator
- DebugConsole.ThrowError("Error in property conditional - \"" + op + "\" is not a valid operator.");
+ atStr = attributeString; //We probably don't even have an operator
}
break;
}
+ foreach (XElement subElement in attribute.Parent.Elements())
+ {
+ switch (subElement.Name.ToString().ToLowerInvariant())
+ {
+ case "cancel":
+ case "canceleffect":
+ case "cancelstatuseffect":
+ //This only works if there's a conditional checking for status effect tags. There is no way to cancel *all* status effects atm.
+ cancelStatusEffect = 1;
+ if (subElement.GetAttributeBool("all", false)) cancelStatusEffect = 2;
+ break;
+ }
+ }
+
if (!Enum.TryParse(attribute.Name.ToString(), true, out Type))
{
PropertyName = attribute.Name.ToString();
@@ -95,8 +111,75 @@ namespace Barotrauma
Value = atStr;
}
+
+ public bool Matches(ISerializableEntity target)
+ {
+ string valStr = Value.ToString();
+
+ switch (Type)
+ {
+ case ConditionType.PropertyValue:
+ if (target.SerializableProperties.TryGetValue(PropertyName.ToLowerInvariant(), out SerializableProperty property))
+ {
+ return Matches(property);
+ }
+ return false;
+ case ConditionType.Name:
+ return (Operator == OperatorType.Equals) == (target.Name == valStr);
+ case ConditionType.HasTag:
+ {
+ string[] readTags = valStr.Split(',');
+ int matches = 0;
+ foreach (string tag in readTags)
+ if (((Item)target).HasTag(tag)) matches++;
+
+ //If operator is == then it needs to match everything, otherwise if its != there must be zero matches.
+ return Operator == OperatorType.Equals ? matches >= readTags.Length : matches <= 0;
+ }
+ case ConditionType.HasStatusTag:
+ List durations = StatusEffect.DurationList.FindAll(d => d.Targets.Contains(target));
+ List delays = DelayedEffect.DelayList.FindAll(d => d.Targets.Contains(target));
+
+ bool success = false;
+ if (durations.Count > 0 || delays.Count > 0)
+ {
+ string[] readTags = valStr.Split(',');
+ foreach (DurationListElement duration in durations)
+ {
+ int matches = 0;
+ foreach (string tag in readTags)
+ if (duration.Parent.HasTag(tag)) matches++;
+
+ success = Operator == OperatorType.Equals ? matches >= readTags.Length : matches <= 0;
+ if (cancelStatusEffect > 0 && success)
+ StatusEffect.DurationList.Remove(duration);
+ if (cancelStatusEffect != 2) //cancelStatusEffect 1 = only cancel once, cancelStatusEffect 2 = cancel all of matching tags
+ return success;
+ }
+ foreach (DelayedListElement delay in delays)
+ {
+ int matches = 0;
+ foreach (string tag in readTags)
+ if (delay.Parent.HasTag(tag)) matches++;
+
+ success = Operator == OperatorType.Equals ? matches >= readTags.Length : matches <= 0;
+ if (cancelStatusEffect > 0 && success)
+ DelayedEffect.DelayList.Remove(delay);
+ if (cancelStatusEffect != 2) //ditto
+ return success;
+ }
+ }
+ return success;
+ case ConditionType.SpeciesName:
+ Character targetCharacter = target as Character;
+ if (targetCharacter == null) return false;
+ return (Operator == OperatorType.Equals) == (targetCharacter.SpeciesName == valStr);
+ default:
+ return false;
+ }
+ }
- public bool Matches(SerializableProperty property)
+ private bool Matches(SerializableProperty property)
{
object propertyValue = property.GetValue();
diff --git a/Barotrauma/BarotraumaShared/Source/StatusEffects/StatusEffect.cs b/Barotrauma/BarotraumaShared/Source/StatusEffects/StatusEffect.cs
index 291d343d3..48134bd76 100644
--- a/Barotrauma/BarotraumaShared/Source/StatusEffects/StatusEffect.cs
+++ b/Barotrauma/BarotraumaShared/Source/StatusEffects/StatusEffect.cs
@@ -57,7 +57,6 @@ namespace Barotrauma
public bool Stackable; //Can the same status effect be applied several times to the same targets?
private readonly int useItemCount;
- private readonly int cancelStatusEffect;
public readonly ActionType type;
@@ -212,12 +211,6 @@ namespace Barotrauma
case "useitem":
useItemCount++;
break;
- case "cancel":
- case "cancelstatuseffect":
- //This only works if there's a conditional checking for status effect tags. There is no way to cancel *all* status effects atm.
- cancelStatusEffect = 1;
- if (subElement.GetAttributeBool("all", false)) cancelStatusEffect = 2;
- break;
case "requireditem":
case "requireditems":
RelatedItem newRequiredItem = RelatedItem.Load(subElement);
@@ -270,69 +263,10 @@ namespace Barotrauma
if (!propertyConditionals.Any()) return true;
foreach (ISerializableEntity target in targets)
{
+ if (target == null || target.SerializableProperties == null) continue;
foreach (PropertyConditional pc in propertyConditionals)
- {
- if (target == null || target.SerializableProperties == null) continue;
-
- string valStr = pc.Value.ToString();
-
- switch (pc.Type)
- {
- case PropertyConditional.ConditionType.PropertyValue:
- if (target.SerializableProperties.TryGetValue(pc.PropertyName.ToLowerInvariant(), out SerializableProperty property))
- {
- return pc.Matches(property);
- }
- return false;
- case PropertyConditional.ConditionType.Name:
- return (pc.Operator == PropertyConditional.OperatorType.Equals) == (target.Name == valStr);
- case PropertyConditional.ConditionType.HasTag:
- {
- string[] readTags = valStr.Split(',');
- int matches = 0;
- foreach (string tag in readTags)
- if (((Item)target).HasTag(tag)) matches++;
-
- //If operator is == then it needs to match everything, otherwise if its != there must be zero matches.
- return pc.Operator == PropertyConditional.OperatorType.Equals ? matches >= readTags.Length : matches <= 0;
- }
- case PropertyConditional.ConditionType.HasStatusTag:
- List durations = DurationList.FindAll(d => d.Targets.Contains(target));
- List delays = DelayedEffect.DelayList.FindAll(d => d.Targets.Contains(target));
-
- bool success = false;
- if (durations.Any() || delays.Any())
- {
- string[] readTags = valStr.Split(',');
- foreach (DurationListElement duration in durations)
- {
- int matches = 0;
- foreach (string tag in readTags)
- if (duration.Parent.HasTag(tag)) matches++;
-
- success = pc.Operator == PropertyConditional.OperatorType.Equals ? matches >= readTags.Length : matches <= 0;
- if (cancelStatusEffect > 0 && success)
- DurationList.Remove(duration);
- if (cancelStatusEffect != 2) //cancelStatusEffect 1 = only cancel once, cancelStatusEffect 2 = cancel all of matching tags
- return success;
- }
- foreach (DelayedListElement delay in delays)
- {
- int matches = 0;
- foreach (string tag in readTags)
- if (delay.Parent.HasTag(tag)) matches++;
-
- success = pc.Operator == PropertyConditional.OperatorType.Equals ? matches >= readTags.Length : matches <= 0;
- if (cancelStatusEffect > 0 && success)
- DelayedEffect.DelayList.Remove(delay);
- if (cancelStatusEffect != 2) //ditto
- return success;
- }
- }
- return success;
- case PropertyConditional.ConditionType.SpeciesName:
- return (pc.Operator == PropertyConditional.OperatorType.Equals) == (((Character)target).SpeciesName == valStr);
- }
+ {
+ if (!pc.Matches(target)) return false;
}
}
return true;