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  }
49  Conditionals = conditionalList.ToImmutableArray();
50  }
51 
52  if (Conditionals.None())
53  {
54  DebugConsole.LogError($"CheckConditionalAction error: {GetEventDebugName()} uses a CheckConditionalAction with no valid PropertyConditional! This will cause the check to automatically succeed.",
55  contentPackage: parentEvent.Prefab.ContentPackage);
56  }
57 
58  static bool IsConditionalAttribute(XAttribute attribute)
59  {
60  var nameAsIdentifier = attribute.NameAsIdentifier();
61  return
62  nameAsIdentifier != nameof(TargetTag) &&
63  nameAsIdentifier != nameof(LogicalOperator) &&
64  nameAsIdentifier != nameof(ApplyTagToLinkedHulls) &&
65  nameAsIdentifier != nameof(ApplyTagToHull);
66  }
67  }
68 
69  protected override bool? DetermineSuccess()
70  {
71  IEnumerable<ISerializableEntity> targets = null;
72  if (!TargetTag.IsEmpty)
73  {
75  }
76 
77  if (targets.None())
78  {
79  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.",
80  contentPackage: ParentEvent.Prefab.ContentPackage);
81  }
82 
83  if (targets.None() || Conditionals.None())
84  {
85  foreach (var target in targets)
86  {
88  }
89  return true;
90  }
91  else
92  {
93  bool success = false;
94  foreach (var target in targets)
95  {
96  if (ConditionalsMatch(target))
97  {
98  success = true;
100  }
101  }
102  return success;
103  }
104  }
105 
106  private bool ConditionalsMatch(ISerializableEntity target)
107  {
109  {
110  return Conditionals.All(c => ConditionalMatches(target, c));
111  }
112  else
113  {
114  return Conditionals.Any(c => ConditionalMatches(target, c));
115  }
116  }
117 
118  private static bool ConditionalMatches(ISerializableEntity target, PropertyConditional conditional)
119  {
120  if (target is Item item)
121  {
122  if (!conditional.TargetItemComponent.IsNullOrEmpty() &&
123  item.Components.None(ic => ic.Name == conditional.TargetItemComponent))
124  {
125  return false;
126  }
127  return item.ConditionalMatches(conditional);
128  }
129  return conditional.Matches(target);
130  }
131  }
132 }
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:106
void ApplyTagsToHulls(Entity entity, Identifier hullTag, Identifier linkedHullTag)
Definition: EventAction.cs:181
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)