From ff883ae8824abed9e208c1535c8abb257ae05e63 Mon Sep 17 00:00:00 2001 From: Joonas Rikkonen Date: Mon, 12 Feb 2018 11:25:40 +0200 Subject: [PATCH] Bunch of fixes to statuseffects: - Fixed the multi-target StatusEffect.Apply method ignoring target names and always allowing stacking. - Fixed delayed effects not working if the single-target StatusEffect.Apply method is used. - Fixed delayed effects ignoring target names. - Fixed delayed effects comparing the equality of the target lists, not the elements in the list (if the contents of the lists are identical the statuseffects should be considered identical). --- .../Source/StatusEffects/DelayedEffect.cs | 40 ++++++++++++++++--- .../Source/StatusEffects/StatusEffect.cs | 27 +++++++++++-- 2 files changed, 57 insertions(+), 10 deletions(-) diff --git a/Barotrauma/BarotraumaShared/Source/StatusEffects/DelayedEffect.cs b/Barotrauma/BarotraumaShared/Source/StatusEffects/DelayedEffect.cs index 7dd32eca7..db754da57 100644 --- a/Barotrauma/BarotraumaShared/Source/StatusEffects/DelayedEffect.cs +++ b/Barotrauma/BarotraumaShared/Source/StatusEffects/DelayedEffect.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using System.Linq; using System.Xml.Linq; namespace Barotrauma @@ -22,16 +23,43 @@ namespace Barotrauma delay = element.GetAttributeFloat("delay", 1.0f); } + public override void Apply(ActionType type, float deltaTime, Entity entity, ISerializableEntity target) + { + if (this.type != type || !HasRequiredItems(entity)) return; + if (!Stackable && DelayList.Any(d => d.Parent == this && d.Entity == entity && d.Targets.Count == 1 && d.Targets[0] == target)) return; + + if (targetNames != null && !targetNames.Contains(target.Name)) return; + + DelayedListElement element = new DelayedListElement + { + Parent = this, + StartTimer = delay, + Entity = entity, + Targets = new List() { target } + }; + + DelayList.Add(element); + } + 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; + if (!Stackable && DelayList.Any(d => d.Parent == this && d.Entity == entity && d.Targets.SequenceEqual(targets))) return; - DelayedListElement element = new DelayedListElement(); - element.Parent = this; - element.StartTimer = delay; - element.Entity = entity; - element.Targets = targets; + //remove invalid targets + if (targetNames != null) + { + targets.RemoveAll(t => !targetNames.Contains(t.Name)); + if (targets.Count == 0) return; + } + + DelayedListElement element = new DelayedListElement + { + Parent = this, + StartTimer = delay, + Entity = entity, + Targets = targets + }; DelayList.Add(element); } diff --git a/Barotrauma/BarotraumaShared/Source/StatusEffects/StatusEffect.cs b/Barotrauma/BarotraumaShared/Source/StatusEffects/StatusEffect.cs index 48134bd76..4578f3831 100644 --- a/Barotrauma/BarotraumaShared/Source/StatusEffects/StatusEffect.cs +++ b/Barotrauma/BarotraumaShared/Source/StatusEffects/StatusEffect.cs @@ -26,7 +26,7 @@ namespace Barotrauma } private TargetType targetTypes; - private HashSet targetNames; + protected HashSet targetNames; private List requiredItems; @@ -278,19 +278,38 @@ 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; + if (duration > 0.0f && !Stackable) + { + //ignore if not stackable and there's already an identical statuseffect + if (DurationList.Any(d => d.Parent == this && d.Entity == entity && d.Targets.Count == 1 && d.Targets[0] == target)) return; + } List targets = new List(); targets.Add(target); if (!HasRequiredConditions(targets)) return; - Apply(type, deltaTime, entity, targets); + Apply(deltaTime, entity, targets); } public virtual void Apply(ActionType type, float deltaTime, Entity entity, List targets) { - if (this.type != type || !HasRequiredItems(entity) || !HasRequiredConditions(targets)) return; + if (this.type != type) return; + + //remove invalid targets + if (targetNames != null) + { + targets.RemoveAll(t => !targetNames.Contains(t.Name)); + if (targets.Count == 0) return; + } + + if (!HasRequiredItems(entity) || !HasRequiredConditions(targets)) return; + + if (duration > 0.0f && !Stackable) + { + //ignore if not stackable and there's already an identical statuseffect + if (DurationList.Any(d => d.Parent == this && d.Entity == entity && d.Targets.SequenceEqual(targets))) return; + } Apply(deltaTime, entity, targets); }