Fix up conditionals

Make Calyxanide only cure non-turned humans and hurt turned player husks
Make husk eggs not stack infection with more injections
TODO: Allow conditionals to check for non-serialized properties like SpeciesName for absolute POWER
This commit is contained in:
Alex Noir
2017-12-27 23:18:59 +03:00
parent 7b336fc3f4
commit e405c93581
2 changed files with 94 additions and 32 deletions
@@ -325,8 +325,19 @@
<Throwable canBeCombined="true" slots="Any,RightHand,LeftHand" throwforce="4.0" aimpos="35,-10">
<StatusEffect type="OnUse" target="Character" HuskInfectionState="-0.2" setvalue="true">
<Conditional HuskInfectionState="lt 1.0"/>
<RequiredItem name="Medical Syringe" type="Container"/>
</StatusEffect>
<StatusEffect type="OnUse" target="Character" Health="-3.0" duration="10.0">
<!-- Injecting a still-conscious Husk will only piss it off and kill the "conscious" faster -->
<Conditional HuskInfectionState="eq 1.0"/>
<RequiredItem name="Medical Syringe" type="Container"/>
</StatusEffect>
<!-- This is impossible right now because Conditionals are not allowed to check for non-serializable properties :(
<StatusEffect type="OnUse" target="Character" Health="-5.0" duration="10.0">
<Conditional SpeciesName="husk"/>
<RequiredItem name="Medical Syringe" type="Container"/>
</StatusEffect> -->
</Throwable>
</Item>
@@ -444,6 +455,8 @@
<Throwable canBeCombined="true" slots="Any,RightHand,LeftHand" throwforce="4.0" aimpos="35,-10">
<StatusEffect type="OnUse" target="Character" HuskInfectionState="0.01">
<!-- HuskInfectionState must be less than 0.01 so you can't speed up the infection -->
<Conditional HuskInfectionState="lt 0.01"/>
<RequiredItem name="Medical Syringe" type="Container"/>
</StatusEffect>
</Throwable>
@@ -24,63 +24,65 @@ namespace Barotrauma
public bool Matches(SerializableProperty property)
{
Type type = Value.GetType();
if (property.GetValue() == null)
{
DebugConsole.ThrowError("Couldn't compare " + Value.ToString() + " (" + type + ") to property \"" + property.Name + "- property.GetValue() returns null!!");
DebugConsole.ThrowError("Couldn't compare " + Value.ToString() + " (" + Value.GetType() + ") to property \"" + property.Name + "- property.GetValue() returns null!!");
return false;
}
Type type = property.GetValue().GetType();
float? floatValue = null;
if ((type == typeof(float) || type == typeof(int)) && (property.GetValue() is float || property.GetValue() is int))
float? floatProperty = null;
if (type == typeof(float) || type == typeof(int))
{
floatValue = Convert.ToSingle(Value);
floatProperty = Convert.ToSingle(property.GetValue());
}
switch (Operator)
{
case "==":
if (property.GetValue().Equals(Value))
if (property.GetValue().Equals(floatValue == null ? floatValue : Value))
return true;
break;
case "!=":
if (!property.GetValue().Equals(Value))
if (property.GetValue().Equals(floatValue == null ? floatValue : Value))
return true;
break;
case ">":
if (floatValue == null)
{
DebugConsole.ThrowError("Couldn't compare " + Value.ToString() + " (" + type + ") to property \"" + property.Name + "\" (" + property.GetValue().GetType() + ")! "
DebugConsole.ThrowError("Couldn't compare " + Value.ToString() + " (" + Value.GetType() + ") to property \"" + property.Name + "\" (" + type + ")! "
+ "Make sure the type of the value set in the config files matches the type of the property.");
}
else if ((float)property.GetValue() > floatValue)
else if (floatProperty > floatValue)
return true;
break;
case "<":
if (floatValue == null)
{
DebugConsole.ThrowError("Couldn't compare " + Value.ToString() + " (" + type + ") to property \"" + property.Name + "\" (" + property.GetValue().GetType() + ")! "
DebugConsole.ThrowError("Couldn't compare " + Value.ToString() + " (" + Value.GetType() + ") to property \"" + property.Name + "\" (" + type + ")! "
+ "Make sure the type of the value set in the config files matches the type of the property.");
}
else if ((float)property.GetValue() < floatValue)
else if (floatProperty < floatValue)
return true;
break;
case ">=":
if (floatValue == null)
{
DebugConsole.ThrowError("Couldn't compare " + Value.ToString() + " (" + type + ") to property \"" + property.Name + "\" (" + property.GetValue().GetType() + ")! "
DebugConsole.ThrowError("Couldn't compare " + Value.ToString() + " (" + Value.GetType() + ") to property \"" + property.Name + "\" (" + type + ")! "
+ "Make sure the type of the value set in the config files matches the type of the property.");
}
else if ((float)property.GetValue() >= floatValue)
else if (floatProperty >= floatValue)
return true;
break;
case "<=":
if (floatValue == null)
{
DebugConsole.ThrowError("Couldn't compare " + Value.ToString() + " (" + type + ") to property \"" + property.Name + "\" (" + property.GetValue().GetType() + ")! "
DebugConsole.ThrowError("Couldn't compare " + Value.ToString() + " (" + Value.GetType() + ") to property \"" + property.Name + "\" (" + type + ")! "
+ "Make sure the type of the value set in the config files matches the type of the property.");
}
else if ((float)property.GetValue() <= floatValue)
else if (floatProperty <= floatValue)
return true;
break;
}
@@ -218,22 +220,10 @@ namespace Barotrauma
DebugConsole.ThrowError("Error in StatusEffect " + element.Parent.Name.ToString() +
" - sounds should be defined as child elements of the StatusEffect, not as attributes.");
break;
case "if":
break;
default:
object attributeObject = XMLExtensions.GetAttributeObject(attribute);
string attributeString = attributeObject.ToString();
Type type = attributeObject.GetType();
string op = attributeString.Substring(0, Math.Min(2, attributeString.Length));
if (op != "!=" && op != ">=" && op != "<=" && op != "==" && (op.StartsWith(">") || op.StartsWith("<")))
op = op.Substring(0, 1);
if (op == "!=" || op == ">=" || op == "<=" || op == "==" || op == ">" || op == "<") //Oh shit this is a conditional!
{
attributeObject = attributeString.Substring(op.Length, attributeString.Length);
propertyConditionals.Add(new PropertyConditional(attribute.Name.ToString().ToLowerInvariant(), op, attributeObject));
}
else
propertyAttributes.Add(attribute);
propertyAttributes.Add(attribute);
break;
}
}
@@ -272,6 +262,66 @@ namespace Barotrauma
requiredItems.Add(newRequiredItem);
break;
case "conditional":
IEnumerable<XAttribute> conditionalAttributes = subElement.Attributes();
foreach(XAttribute attribute in conditionalAttributes)
{
string attributeString = XMLExtensions.GetAttributeObject(attribute).ToString();
string atStr = attributeString;
string[] splitString = atStr.Split(' ');
string op = splitString[0];
if (splitString.Length > 0)
{
for (int i=1; i<splitString.Length; i++)
{
atStr = splitString[i] + (i > 1 && i < splitString.Length ? " " : "");
}
}
//thanks xml for not letting me use < or > in attributes :(
switch (op)
{
case "e":
case "eq":
case "equals":
op = "==";
break;
case "ne":
case "neq":
case "notequals":
case "!e":
case "!eq":
case "!equals":
op = "!=";
break;
case "gt":
case "greaterthan":
op = ">";
break;
case "lt":
case "lessthan":
op = "<";
break;
case "gte":
case "gteq":
case "greaterthanequals":
op = ">=";
break;
case "lte":
case "lteq":
case "lessthanequals":
op = "<=";
break;
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
op = "==";
}
break;
}
propertyConditionals.Add(new PropertyConditional(attribute.Name.ToString().ToLowerInvariant(), op, atStr));
}
break;
#if CLIENT
case "particleemitter":
particleEmitters.Add(new ParticleEmitter(subElement));
@@ -313,10 +363,9 @@ namespace Barotrauma
{
string op = pc.Operator;
object value = pc.Value;
SerializableProperty property;
if (target == null || target.SerializableProperties == null || !target.SerializableProperties.TryGetValue(pc.Attribute, out property)) continue;
//TODO: Somehow check for non-serialized properties like SpeciesName for even more robust conditional conditioning
if (target == null || target.SerializableProperties == null || !target.SerializableProperties.TryGetValue(pc.Attribute, out SerializableProperty property)) continue;
if (!pc.Matches(property))
return false;