diff --git a/OpenRA.Mods.Common/Activities/DonateExperience.cs b/OpenRA.Mods.Common/Activities/DonateExperience.cs index 729ea07138..8106ab7949 100644 --- a/OpenRA.Mods.Common/Activities/DonateExperience.cs +++ b/OpenRA.Mods.Common/Activities/DonateExperience.cs @@ -11,44 +11,58 @@ using System.Drawing; using OpenRA.Activities; +using OpenRA.Mods.Common.Effects; using OpenRA.Mods.Common.Traits; +using OpenRA.Traits; namespace OpenRA.Mods.Common.Activities { - class DonateExperience : LegacyEnter + class DonateExperience : Enter { - readonly Actor target; - readonly GainsExperience targetGainsExperience; readonly int level; readonly int playerExperience; - public DonateExperience(Actor self, Actor target, int level, int playerExperience, GainsExperience targetGainsExperience) - : base(self, target, EnterBehaviour.Dispose, targetLineColor: Color.Yellow) + Actor enterActor; + GainsExperience enterGainsExperience; + + public DonateExperience(Actor self, Target target, int level, int playerExperience) + : base(self, target, Color.Yellow) { - this.target = target; this.level = level; this.playerExperience = playerExperience; - this.targetGainsExperience = targetGainsExperience; } - protected override void OnInside(Actor self) + protected override bool TryStartEnter(Actor self, Actor targetActor) { - if (target.IsDead) + enterActor = targetActor; + enterGainsExperience = targetActor.TraitOrDefault(); + + if (enterGainsExperience == null || enterGainsExperience.Level == enterGainsExperience.MaxLevel) + { + Cancel(self, true); + return false; + } + + return true; + } + + protected override void OnEnterComplete(Actor self, Actor targetActor) + { + // Make sure the target hasn't changed while entering + // OnEnterComplete is only called if targetActor is alive + if (targetActor != enterActor) return; - targetGainsExperience.GiveLevels(level); + if (enterGainsExperience.Level == enterGainsExperience.MaxLevel) + return; + + enterGainsExperience.GiveLevels(level); var exp = self.Owner.PlayerActor.TraitOrDefault(); - if (exp != null && target.Owner != self.Owner) + if (exp != null && enterActor.Owner != self.Owner) exp.GiveExperience(playerExperience); - } - public override Activity Tick(Actor self) - { - if (target.IsDead || targetGainsExperience.Level == targetGainsExperience.MaxLevel) - Cancel(self); - - return base.Tick(self); + self.Dispose(); } } } diff --git a/OpenRA.Mods.Common/Scripting/Properties/DeliveryProperties.cs b/OpenRA.Mods.Common/Scripting/Properties/DeliveryProperties.cs index ec82da1ff4..20b4e4a9e2 100644 --- a/OpenRA.Mods.Common/Scripting/Properties/DeliveryProperties.cs +++ b/OpenRA.Mods.Common/Scripting/Properties/DeliveryProperties.cs @@ -65,8 +65,9 @@ namespace OpenRA.Mods.Common.Scripting var level = gainsExperience.Level; - Self.SetTargetLine(Target.FromActor(target), Color.Yellow); - Self.QueueActivity(new DonateExperience(Self, target, level, deliversExperience.PlayerExperience, targetGainsExperience)); + var t = Target.FromActor(target); + Self.SetTargetLine(t, Color.Yellow); + Self.QueueActivity(new DonateExperience(Self, t, level, deliversExperience.PlayerExperience)); } } } diff --git a/OpenRA.Mods.Common/Traits/DeliversExperience.cs b/OpenRA.Mods.Common/Traits/DeliversExperience.cs index df66fc0fe6..ff8153f66c 100644 --- a/OpenRA.Mods.Common/Traits/DeliversExperience.cs +++ b/OpenRA.Mods.Common/Traits/DeliversExperience.cs @@ -71,21 +71,20 @@ namespace OpenRA.Mods.Common.Traits if (order.OrderString != "DeliverExperience") return; - var target = self.ResolveFrozenActorOrder(order, Color.Yellow); - if (target.Type != TargetType.Actor) - return; - - var targetGainsExperience = target.Actor.Trait(); - if (targetGainsExperience.Level == targetGainsExperience.MaxLevel) + if (order.Target.Type == TargetType.Actor) + { + var targetGainsExperience = order.Target.Actor.Trait(); + if (targetGainsExperience.Level == targetGainsExperience.MaxLevel) + return; + } + else if (order.Target.Type != TargetType.FrozenActor) return; if (!order.Queued) self.CancelActivity(); - var level = gainsExperience.Level; - - self.SetTargetLine(target, Color.Yellow); - self.QueueActivity(new DonateExperience(self, target.Actor, level, info.PlayerExperience, targetGainsExperience)); + self.SetTargetLine(order.Target, Color.Yellow); + self.QueueActivity(new DonateExperience(self, order.Target, gainsExperience.Level, info.PlayerExperience)); } public class DeliversExperienceOrderTargeter : UnitOrderTargeter