Client LuaCsForBarotrauma
CheckConditionalAction.cs
2 using System.Collections.Generic;
3 using System.Collections.Immutable;
4 using System.Linq;
5 using System.Xml.Linq;
6 
7 namespace Barotrauma
8 {
9 
14  {
15  [Serialize("", IsPropertySaveable.Yes, description: "Tag of the target to check.")]
16  public Identifier TargetTag { get; set; }
17 
18  [Serialize(PropertyConditional.LogicalOperatorType.Or, IsPropertySaveable.Yes, description: "Do all of the conditions need to be met, or is it enough if at least one is? Only valid if there are multiple conditionals.")]
20 
21  private ImmutableArray<PropertyConditional> Conditionals { get; }
22 
23  [Serialize("", IsPropertySaveable.Yes, description: "A tag to apply to the hull the target is currently in when the check succeeds, as well as all the hulls linked to it.")]
24  public Identifier ApplyTagToLinkedHulls { get; set; }
25 
26  [Serialize("", IsPropertySaveable.Yes, description: "A tag to apply to the hull the target is currently in when the check succeeds.")]
27  public Identifier ApplyTagToHull { get; set; }
28 
29  public CheckConditionalAction(ScriptedEvent parentEvent, ContentXElement element) : base(parentEvent, element)
30  {
31  if (TargetTag.IsEmpty)
32  {
33  DebugConsole.LogError($"CheckConditionalAction error: {GetEventDebugName()} uses a CheckConditionalAction with no target tag! This will cause the check to automatically succeed.",
34  contentPackage: parentEvent.Prefab.ContentPackage);
35  }
36  var conditionalElements = element.GetChildElements("Conditional");
37  if (conditionalElements.None())
38  {
39  //backwards compatibility
40  Conditionals = PropertyConditional.FromXElement(element, IsConditionalAttribute).ToImmutableArray();
41  }
42  else
43  {
44  var conditionalList = new List<PropertyConditional>();
45  foreach (ContentXElement subElement in conditionalElements)
46  {
47  conditionalList.AddRange(PropertyConditional.FromXElement(subElement));
48  break;
49  }
50  Conditionals = conditionalList.ToImmutableArray();
51  }
52 
53  if (Conditionals.None())
54  {
55  DebugConsole.LogError($"CheckConditionalAction error: {GetEventDebugName()} uses a CheckConditionalAction with no valid PropertyConditional! This will cause the check to automatically succeed.",
56  contentPackage: parentEvent.Prefab.ContentPackage);
57  }
58 
59  static bool IsConditionalAttribute(XAttribute attribute)
60  {
61  var nameAsIdentifier = attribute.NameAsIdentifier();
62  return
63  nameAsIdentifier != nameof(TargetTag) &&
64  nameAsIdentifier != nameof(LogicalOperator) &&
65  nameAsIdentifier != nameof(ApplyTagToLinkedHulls) &&
66  nameAsIdentifier != nameof(ApplyTagToHull);
67  }
68  }
69 
70  protected override bool? DetermineSuccess()
71  {
72  IEnumerable<ISerializableEntity> targets = null;
73  if (!TargetTag.IsEmpty)
74  {
76  }
77 
78  if (targets.None())
79  {
80  DebugConsole.LogError($"{nameof(CheckConditionalAction)} error: {GetEventDebugName()} uses a {nameof(CheckConditionalAction)} but no valid target was found for tag \"{TargetTag}\"! This will cause the check to automatically succeed.",
81  contentPackage: ParentEvent.Prefab.ContentPackage);
82  }
83 
84  if (targets.None() || Conditionals.None())
85  {
86  foreach (var target in targets)
87  {
89  }
90  return true;
91  }
92  else
93  {
94  bool success = false;
95  foreach (var target in targets)
96  {
97  if (ConditionalsMatch(target))
98  {
99  success = true;
101  }
102  }
103  return success;
104  }
105  }
106 
107  private bool ConditionalsMatch(ISerializableEntity target)
108  {
110  {
111  return Conditionals.All(c => ConditionalMatches(target, c));
112  }
113  else
114  {
115  return Conditionals.Any(c => ConditionalMatches(target, c));
116  }
117  }
118 
119  private static bool ConditionalMatches(ISerializableEntity target, PropertyConditional conditional)
120  {
121  if (target is Item item)
122  {
123  if (!conditional.TargetItemComponent.IsNullOrEmpty() &&
124  item.Components.None(ic => ic.Name == conditional.TargetItemComponent))
125  {
126  return false;
127  }
128  return item.ConditionalMatches(conditional);
129  }
130  return conditional.Matches(target);
131  }
132  }
133 }
Checks whether an arbitrary condition is met. The conditionals work the same way as they do in Status...
PropertyConditional.LogicalOperatorType LogicalOperator
CheckConditionalAction(ScriptedEvent parentEvent, ContentXElement element)
IEnumerable< ContentXElement > GetChildElements(string name)
readonly ScriptedEvent ParentEvent
Definition: EventAction.cs:102
void ApplyTagsToHulls(Entity entity, Identifier hullTag, Identifier linkedHullTag)
Definition: EventAction.cs:177
EventPrefab Prefab
Definition: Event.cs:16
ContentPackage? ContentPackage
Definition: Prefab.cs:37
Conditionals are used by some in-game mechanics to require one or more conditions to be met for those...
static IEnumerable< PropertyConditional > FromXElement(ContentXElement element, Predicate< XAttribute >? predicate=null)
IEnumerable< Entity > GetTargets(Identifier tag)