3 using System.Collections.Generic;
6 using System.Globalization;
14 public readonly CustomInterfaceElement BtnElement;
16 public EventData(CustomInterfaceElement btnElement)
18 BtnElement = btnElement;
24 public bool ContinuousSignal;
26 public string ConnectionName;
30 public string Label {
get;
set; }
33 public string Signal {
get;
set; }
35 public Identifier PropertyName {
get; }
36 public bool TargetOnlyParentProperty {
get; }
38 public string NumberInputMin {
get; }
39 public string NumberInputMax {
get; }
40 public string NumberInputStep {
get; }
41 public int NumberInputDecimalPlaces {
get; }
43 public int MaxTextLength {
get; }
45 public const string DefaultNumberInputMin =
"0", DefaultNumberInputMax =
"99", DefaultNumberInputStep =
"1";
46 public const int DefaultNumberInputDecimalPlaces = 0;
47 public bool IsNumberInput {
get; }
49 public bool HasPropertyName {
get; }
50 public bool ShouldSetProperty {
get;
set; }
52 public string Name =>
"CustomInterfaceElement";
56 public List<StatusEffect> StatusEffects =
new List<StatusEffect>();
67 TargetOnlyParentProperty = element.
GetAttributeBool(
"targetonlyparentproperty",
false);
71 NumberInputDecimalPlaces = element.
GetAttributeInt(
"decimalplaces", DefaultNumberInputDecimalPlaces);
74 HasPropertyName = !PropertyName.IsEmpty;
77 string elementName = element.
Name.ToString().ToLowerInvariant();
78 IsNumberInput = elementName ==
"numberinput" || elementName ==
"integerinput";
97 if (element.
GetAttribute(
"signal") is XAttribute attribute)
100 ShouldSetProperty = HasPropertyName;
102 else if (HasPropertyName && parent !=
null)
104 if (TargetOnlyParentProperty)
126 foreach (var subElement
in element.
Elements())
128 if (subElement.Name.ToString().Equals(
"statuseffect", System.StringComparison.OrdinalIgnoreCase))
130 StatusEffects.Add(
StatusEffect.
Load(subElement, parentDebugName:
"custom interface element (label " +
Label +
")"));
136 private string[] labels;
137 [
Serialize(
"",
IsPropertySaveable.Yes, description:
"The texts displayed on the buttons/tickboxes, separated by commas.", alwaysUseInstanceValues:
true)]
140 get {
return string.Join(
",", labels); }
143 if (value ==
null) {
return; }
144 if (customInterfaceElementList.Count > 0)
146 string[] splitValues = value ==
"" ? Array.Empty<
string>() : value.Split(
',');
147 UpdateLabels(splitValues);
152 private string[] signals;
153 [
Serialize(
"",
IsPropertySaveable.Yes, description:
"The signals sent when the buttons are pressed or the tickboxes checked, separated by commas.", alwaysUseInstanceValues:
true)]
158 get {
return signals ==
null ?
string.Empty :
string.Join(
";", signals); }
161 if (value ==
null) {
return; }
162 if (customInterfaceElementList.Count > 0)
164 string[] splitValues = value ==
"" ? Array.Empty<
string>() : value.Split(
';');
165 UpdateSignals(splitValues);
170 private bool[] elementStates;
174 get {
return elementStates ==
null ?
string.Empty :
string.Join(
",", elementStates); }
177 if (value ==
null) {
return; }
178 if (customInterfaceElementList.Count > 0)
180 string[] splitValues = value ==
"" ? Array.Empty<
string>() : value.Split(
',');
181 for (
int i = 0; i < customInterfaceElementList.Count && i < splitValues.Length; i++)
183 if (!
bool.TryParse(splitValues[i], out
bool val)) {
continue; }
184 customInterfaceElementList[i].State = val;
186 if (uiElements !=
null && i < uiElements.Count && uiElements[i] is
GUITickBox tickBox)
188 tickBox.Selected = val;
196 private readonly List<CustomInterfaceElement> customInterfaceElementList =
new List<CustomInterfaceElement>();
199 : base(
item, element)
201 foreach (var subElement
in element.Elements())
203 switch (subElement.Name.ToString().ToLowerInvariant())
209 var button =
new CustomInterfaceElement(
item, subElement,
this)
211 ContinuousSignal =
false
213 if (
string.IsNullOrEmpty(button.Label))
215 button.Label =
"Signal out " + customInterfaceElementList.Count(e => !e.ContinuousSignal);
217 customInterfaceElementList.Add(button);
220 var tickBox =
new CustomInterfaceElement(
item, subElement,
this)
222 ContinuousSignal =
true
224 if (
string.IsNullOrEmpty(tickBox.Label))
226 tickBox.Label =
"Signal out " + customInterfaceElementList.Count(e => e.ContinuousSignal);
228 customInterfaceElementList.Add(tickBox);
235 Labels = element.GetAttributeString(
"labels",
"");
236 Signals = element.GetAttributeString(
"signals",
"");
237 ElementStates = element.GetAttributeString(
"elementstates",
"");
240 private void UpdateLabels(
string[] newLabels)
242 labels =
new string[customInterfaceElementList.Count];
243 for (
int i = 0; i < labels.Length; i++)
245 labels[i] = i < newLabels.Length ? newLabels[i] : customInterfaceElementList[i].Label;
246 customInterfaceElementList[i].Label = labels[i];
248 UpdateLabelsProjSpecific();
251 private void UpdateSignals(
string[] newSignals)
253 signals =
new string[customInterfaceElementList.Count];
254 for (
int i = 0; i < customInterfaceElementList.Count; i++)
256 var element = customInterfaceElementList[i];
257 if (i < newSignals.Length)
259 var newSignal = newSignals[i];
260 signals[i] = newSignal;
261 element.ShouldSetProperty = element.Signal != newSignal;
262 element.Signal = newSignal;
266 signals[i] = element.Signal;
269 if (element.HasPropertyName && element.ShouldSetProperty)
271 if (element.TargetOnlyParentProperty)
282 if (!po.SerializableProperties.ContainsKey(element.PropertyName)) {
continue; }
283 po.SerializableProperties[element.PropertyName].TrySetValue(po, element.Signal);
286 customInterfaceElementList[i].ShouldSetProperty =
false;
289 UpdateSignalsProjSpecific();
294 foreach (CustomInterfaceElement ciElement
in customInterfaceElementList)
296 ciElement.Connection =
item.
Connections?.FirstOrDefault(c => c.Name == ciElement.ConnectionName);
300 if (customInterfaceElementList.Any())
304 CoroutineManager.Invoke(() =>
306 if (!
item.
Removed) { item.CreateServerEvent(this); }
313 partial
void UpdateLabelsProjSpecific();
315 partial
void UpdateSignalsProjSpecific();
317 partial
void InitProjSpecific();
319 private void ButtonClicked(CustomInterfaceElement btnElement)
321 if (btnElement ==
null)
return;
322 if (btnElement.Connection !=
null)
326 foreach (
StatusEffect effect
in btnElement.StatusEffects)
332 private void TickBoxToggled(CustomInterfaceElement tickBoxElement,
bool state)
334 if (tickBoxElement ==
null) {
return; }
335 tickBoxElement.State = state;
338 private void TextChanged(CustomInterfaceElement textElement,
string text)
340 if (textElement ==
null) {
return; }
341 textElement.Signal = text;
342 if (!textElement.TargetOnlyParentProperty)
346 if (!e.SerializableProperties.ContainsKey(textElement.PropertyName)) {
continue; }
347 e.SerializableProperties[textElement.PropertyName].TrySetValue(e, text);
356 private void ValueChanged(CustomInterfaceElement numberInputElement,
int value)
358 if (numberInputElement ==
null) {
return; }
359 numberInputElement.Signal = value.ToString();
360 if (!numberInputElement.TargetOnlyParentProperty)
364 if (!e.SerializableProperties.ContainsKey(numberInputElement.PropertyName)) {
continue; }
365 e.SerializableProperties[numberInputElement.PropertyName].TrySetValue(e, value);
374 private void ValueChanged(CustomInterfaceElement numberInputElement,
float value)
376 if (numberInputElement ==
null) {
return; }
377 numberInputElement.Signal = value.ToString();
378 if (!numberInputElement.TargetOnlyParentProperty)
382 if (!e.SerializableProperties.ContainsKey(numberInputElement.PropertyName)) {
continue; }
383 e.SerializableProperties[numberInputElement.PropertyName].TrySetValue(e, value);
394 foreach (CustomInterfaceElement ciElement
in customInterfaceElementList)
396 if (!ciElement.ContinuousSignal) {
continue; }
398 if (!
string.IsNullOrEmpty(ciElement.Signal) && ciElement.Connection !=
null)
403 foreach (
StatusEffect effect
in ciElement.StatusEffects)
410 public override XElement
Save(XElement parentElement)
412 labels = customInterfaceElementList.Select(ci => ci.Label).ToArray();
413 signals = customInterfaceElementList.Select(ci => ci.Signal).ToArray();
414 elementStates = customInterfaceElementList.Select(ci => ci.State).ToArray();
415 return base.Save(parentElement);
418 private static bool TryParseFloatInvariantCulture(
string s, out
float f)
420 return float.TryParse(s, NumberStyles.Any, CultureInfo.InvariantCulture, out f);
string? GetAttributeString(string key, string? def)
IEnumerable< ContentXElement > Elements()
bool GetAttributeBool(string key, bool def)
int GetAttributeInt(string key, int def)
XAttribute? GetAttribute(string name)
Identifier GetAttributeIdentifier(string key, string def)
void ApplyStatusEffect(StatusEffect effect, ActionType type, float deltaTime, Character character=null, Limb limb=null, Entity useTarget=null, bool isNetworkEvent=false, bool checkCondition=true, Vector2? worldPosition=null)
List< Connection > Connections
Inventory ParentInventory
IReadOnlyList< ISerializableEntity > AllPropertyObjects
bool FullyInitialized
Has everything in the item been loaded/instantiated/initialized (basically, can be used to check if t...
void SendSignal(string signal, string connectionName)
override XElement Save(XElement parentElement)
CustomInterface(Item item, ContentXElement element)
override void Update(float deltaTime, Camera cam)
override void OnItemLoaded()
Called when all the components of the item have been loaded. Use to initialize connections between co...
The base class for components holding the different functionalities of the item
Dictionary< Identifier, SerializableProperty > SerializableProperties
Defines a point in the event that GoTo actions can jump to.
StatusEffects can be used to execute various kinds of effects: modifying the state of some entity in ...
static StatusEffect Load(ContentXElement element, string parentDebugName)
Dictionary< Identifier, SerializableProperty > SerializableProperties
Interface for entities that the clients can send events to the server
Interface for entities that the server can send events to the clients
ActionType
ActionTypes define when a StatusEffect is executed.