diff --git a/Barotrauma/BarotraumaShared/Content/Items/Medical/medical.xml b/Barotrauma/BarotraumaShared/Content/Items/Medical/medical.xml
index bf4f57da8..3ff97f98b 100644
--- a/Barotrauma/BarotraumaShared/Content/Items/Medical/medical.xml
+++ b/Barotrauma/BarotraumaShared/Content/Items/Medical/medical.xml
@@ -82,6 +82,7 @@
spritecolor="1.0,1.0,0.7,1.0"
Tags="smallitem,chem,medical"
description="A mild stimulant which is used as an ingredient in the manufacture of various medicines."
+ canuseonself="true"
price="10">
@@ -201,6 +202,27 @@
+ -
+
+
+
+
+
+
+
+
+
+
+
+
+
- List = new List();
+ public static List DelayList = new List();
private float delay;
@@ -25,27 +25,34 @@ namespace Barotrauma
public override void Apply(ActionType type, float deltaTime, Entity entity, List targets)
{
if (this.type != type || !HasRequiredItems(entity)) return;
+ if (!base.Stackable && DelayList.Find(d => d.Parent == this && d.Entity == entity && d.Targets == targets) != null) return;
+
DelayedListElement element = new DelayedListElement();
element.Parent = this;
element.StartTimer = delay;
element.Entity = entity;
element.Targets = targets;
- List.Add(element);
+ DelayList.Add(element);
}
public static void Update(float deltaTime)
{
- for (int i = DelayedEffect.List.Count - 1; i >= 0; i--)
+ for (int i = DelayList.Count - 1; i >= 0; i--)
{
- DelayedListElement element = DelayedEffect.List[i];
+ DelayedListElement element = DelayList[i];
+ if (element.Parent.CheckConditionalAlways && !element.Parent.HasRequiredConditions(element.Targets))
+ {
+ DelayList.Remove(element);
+ continue;
+ }
element.StartTimer -= deltaTime;
if (element.StartTimer > 0.0f) continue;
element.Parent.Apply(1.0f, element.Entity, element.Targets);
- List.Remove(element);
+ DelayList.Remove(element);
}
}
}
diff --git a/Barotrauma/BarotraumaShared/Source/Characters/StatusEffect.cs b/Barotrauma/BarotraumaShared/Source/Characters/StatusEffect.cs
index 9d3a9b7eb..5b5aa1ec3 100644
--- a/Barotrauma/BarotraumaShared/Source/Characters/StatusEffect.cs
+++ b/Barotrauma/BarotraumaShared/Source/Characters/StatusEffect.cs
@@ -9,6 +9,13 @@ using Barotrauma.Particles;
namespace Barotrauma
{
+ class DurationListElement
+ {
+ public StatusEffect Parent;
+ public Entity Entity;
+ public List Targets;
+ public float StartTimer;
+ }
partial class PropertyConditional
{
public string Attribute;
@@ -119,8 +126,14 @@ namespace Barotrauma
private bool disableDeltaTime;
private HashSet onContainingNames;
+ private HashSet tags;
private readonly float duration;
+ public static List DurationList = new List();
+
+ public bool CheckConditionalAlways; //Always do the conditional checks for the duration/delay. If false, only check conditional on apply.
+
+ public bool Stackable; //Can the same status effect be applied several times to the same targets?
private readonly bool useItem;
@@ -145,6 +158,24 @@ namespace Barotrauma
get { return onContainingNames; }
}
+ public string Tags
+ {
+ get { return string.Join(",", tags); }
+ set
+ {
+ tags.Clear();
+ if (value == null) return;
+
+ string[] newTags = value.Split(',');
+ foreach (string tag in newTags)
+ {
+ string newTag = tag.Trim();
+ if (!tags.Contains(newTag)) tags.Add(newTag);
+ }
+
+ }
+ }
+
public static StatusEffect Load(XElement element)
{
if (element.Attribute("delay")!=null)
@@ -158,12 +189,13 @@ namespace Barotrauma
protected StatusEffect(XElement element)
{
requiredItems = new List();
+ tags = new HashSet(element.GetAttributeString("tags", "").Split(','));
#if CLIENT
particleEmitters = new List();
#endif
- IEnumerable attributes = element.Attributes();
+ IEnumerable attributes = element.Attributes();
List propertyAttributes = new List();
propertyConditionals = new List();
@@ -216,12 +248,16 @@ namespace Barotrauma
case "duration":
duration = attribute.GetAttributeFloat(0.0f);
break;
+ case "stackable":
+ Stackable = attribute.GetAttributeBool(true);
+ break;
+ case "checkconditionalalways":
+ CheckConditionalAlways = attribute.GetAttributeBool(false);
+ break;
case "sound":
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:
propertyAttributes.Add(attribute);
break;
@@ -380,6 +416,8 @@ namespace Barotrauma
if (targetNames != null && !targetNames.Contains(target.Name)) return;
+ if (duration > 0.0f && !Stackable && DurationList.Find(d => d.Parent == this && d.Entity == entity && d.Targets.Contains(target)) != null) return;
+
List targets = new List();
targets.Add(target);
@@ -426,26 +464,31 @@ namespace Barotrauma
}
}
- foreach (ISerializableEntity target in targets)
+ if (duration > 0.0f)
{
- for (int i = 0; i < propertyNames.Length; i++)
- {
- SerializableProperty property;
+ DurationListElement element = new DurationListElement();
+ element.Parent = this;
+ element.StartTimer = duration;
+ element.Entity = entity;
+ element.Targets = targets;
- if (target == null || target.SerializableProperties == null || !target.SerializableProperties.TryGetValue(propertyNames[i], out property)) continue;
-
- if (duration > 0.0f)
- {
- CoroutineManager.StartCoroutine(
- ApplyToPropertyOverDuration(duration, property, propertyEffects[i]), "statuseffect");
-
- }
- else
- {
- ApplyToProperty(property, propertyEffects[i], deltaTime);
- }
- }
+ DurationList.Add(element);
}
+ else
+ {
+ foreach (ISerializableEntity target in targets)
+ {
+ for (int i = 0; i < propertyNames.Length; i++)
+ {
+ SerializableProperty property;
+
+ if (target == null || target.SerializableProperties == null || !target.SerializableProperties.TryGetValue(propertyNames[i], out property)) continue;
+
+ ApplyToProperty(property, propertyEffects[i], deltaTime);
+ }
+ }
+ }
+
if (explosion != null) explosion.Explode(entity.WorldPosition);
@@ -475,21 +518,6 @@ namespace Barotrauma
#endif
}
- private IEnumerable