diff --git a/OpenRA.Mods.Common/AI/HackyAI.cs b/OpenRA.Mods.Common/AI/HackyAI.cs index e7ebfc0623..faf9e02078 100644 --- a/OpenRA.Mods.Common/AI/HackyAI.cs +++ b/OpenRA.Mods.Common/AI/HackyAI.cs @@ -688,39 +688,15 @@ namespace OpenRA.Mods.Common.AI .OrderByDescending(target => target.Actor.GetSellValue()) .Take(maximumCaptureTargetOptions); - var externalCapturableTargetOptions = targetOptions - .Select(a => new CaptureTarget(a, "ExternalCaptureActor")) - .Where(target => - { - if (target.Info == null) - return false; - - var externalCapturable = target.Actor.TraitOrDefault(); - if (externalCapturable == null) - return false; - - return capturers.Any(tp => externalCapturable.CanBeTargetedBy(tp.Actor, target.Actor.Owner)); - }) - .OrderByDescending(target => target.Actor.GetSellValue()) - .Take(maximumCaptureTargetOptions); - if (Info.CapturableActorTypes.Any()) - { capturableTargetOptions = capturableTargetOptions.Where(target => Info.CapturableActorTypes.Contains(target.Actor.Info.Name.ToLowerInvariant())); - externalCapturableTargetOptions = externalCapturableTargetOptions.Where(target => Info.CapturableActorTypes.Contains(target.Actor.Info.Name.ToLowerInvariant())); - } - if (!capturableTargetOptions.Any() && !externalCapturableTargetOptions.Any()) + if (!capturableTargetOptions.Any()) return; var capturesCapturers = capturers.Where(tp => tp.Actor.Info.HasTraitInfo()); - var externalCapturers = capturers.Except(capturesCapturers).Where(tp => tp.Actor.Info.HasTraitInfo()); - foreach (var tp in capturesCapturers) QueueCaptureOrderFor(tp.Actor, GetCapturerTargetClosestToOrDefault(tp.Actor, capturableTargetOptions)); - - foreach (var tp in externalCapturers) - QueueCaptureOrderFor(tp.Actor, GetCapturerTargetClosestToOrDefault(tp.Actor, externalCapturableTargetOptions)); } void QueueCaptureOrderFor(Actor capturer, CaptureTarget target) where TTargetType : class, ITraitInfoInterface diff --git a/OpenRA.Mods.Common/Activities/ExternalCaptureActor.cs b/OpenRA.Mods.Common/Activities/ExternalCaptureActor.cs deleted file mode 100644 index ca29a52cb2..0000000000 --- a/OpenRA.Mods.Common/Activities/ExternalCaptureActor.cs +++ /dev/null @@ -1,110 +0,0 @@ -#region Copyright & License Information -/* - * Copyright 2007-2018 The OpenRA Developers (see AUTHORS) - * This file is part of OpenRA, which is free software. It is made - * available to you under the terms of the GNU General Public License - * as published by the Free Software Foundation, either version 3 of - * the License, or (at your option) any later version. For more - * information, see COPYING. - */ -#endregion - -using System.Linq; -using OpenRA.Activities; -using OpenRA.Mods.Common.Effects; -using OpenRA.Mods.Common.Traits; -using OpenRA.Traits; - -namespace OpenRA.Mods.Common.Activities -{ - class ExternalCaptureActor : Activity - { - readonly ExternalCapturable capturable; - readonly ExternalCapturesInfo capturesInfo; - readonly Mobile mobile; - readonly Target target; - readonly ConditionManager conditionManager; - int capturingToken = ConditionManager.InvalidConditionToken; - - public ExternalCaptureActor(Actor self, Target target) - { - this.target = target; - capturable = target.Actor.Trait(); - capturesInfo = self.Info.TraitInfo(); - mobile = self.Trait(); - conditionManager = self.TraitOrDefault(); - } - - public override Activity Tick(Actor self) - { - if (IsCanceled || !self.IsInWorld || self.IsDead || target.Type != TargetType.Actor || !target.IsValidFor(self)) - { - EndCapture(self); - return NextActivity; - } - - if (!Util.AdjacentCells(self.World, target).Contains(mobile.ToCell)) - return ActivityUtils.SequenceActivities(new MoveAdjacentTo(self, target), this); - - if (!capturable.CaptureInProgress) - BeginCapture(self); - else - { - if (capturable.Captor != self) - return NextActivity; - - if (capturable.CaptureProgressTime % 25 == 0) - { - self.World.Add(new FlashTarget(target.Actor, self.Owner)); - self.World.Add(new FlashTarget(self)); - } - - if (capturable.CaptureProgressTime == capturable.Info.CaptureCompleteTime * 25) - { - self.World.AddFrameEndTask(w => - { - if (target.Actor.IsDead) - return; - - var oldOwner = target.Actor.Owner; - - foreach (var t in target.Actor.TraitsImplementing()) - t.OnCapture(target.Actor, self, oldOwner, self.Owner); - - EndCapture(self); - - if (self.Owner.Stances[oldOwner].HasStance(capturesInfo.PlayerExperienceStances)) - { - var exp = self.Owner.PlayerActor.TraitOrDefault(); - if (exp != null) - exp.GiveExperience(capturesInfo.PlayerExperience); - } - - if (capturesInfo != null && capturesInfo.ConsumeActor) - self.Dispose(); - - target.Actor.ChangeOwnerSync(self.Owner); - }); - } - } - - return this; - } - - void BeginCapture(Actor self) - { - capturable.BeginCapture(self); - if (conditionManager != null && !string.IsNullOrEmpty(capturesInfo.CapturingCondition) && capturingToken == ConditionManager.InvalidConditionToken) - capturingToken = conditionManager.GrantCondition(self, capturesInfo.CapturingCondition); - } - - void EndCapture(Actor self) - { - if (capturable.CaptureInProgress) - capturable.EndCapture(); - - if (capturingToken != ConditionManager.InvalidConditionToken) - capturingToken = conditionManager.RevokeCondition(self, capturingToken); - } - } -} diff --git a/OpenRA.Mods.Common/OpenRA.Mods.Common.csproj b/OpenRA.Mods.Common/OpenRA.Mods.Common.csproj index 41e5777df6..bfe04ed1b6 100644 --- a/OpenRA.Mods.Common/OpenRA.Mods.Common.csproj +++ b/OpenRA.Mods.Common/OpenRA.Mods.Common.csproj @@ -93,7 +93,6 @@ - @@ -363,9 +362,6 @@ - - - diff --git a/OpenRA.Mods.Common/Scripting/Properties/CaptureProperties.cs b/OpenRA.Mods.Common/Scripting/Properties/CaptureProperties.cs index ccdc4de4e9..9913458f99 100644 --- a/OpenRA.Mods.Common/Scripting/Properties/CaptureProperties.cs +++ b/OpenRA.Mods.Common/Scripting/Properties/CaptureProperties.cs @@ -23,35 +23,22 @@ namespace OpenRA.Mods.Common.Scripting public class CaptureProperties : ScriptActorProperties { readonly Captures[] captures; - readonly ExternalCapturesInfo externalInfo; public CaptureProperties(ScriptContext context, Actor self) : base(context, self) { captures = Self.TraitsImplementing().ToArray(); - externalInfo = Self.Info.TraitInfoOrDefault(); } [Desc("Captures the target actor.")] public void Capture(Actor target) { var capturable = target.Info.TraitInfoOrDefault(); - - if (capturable != null) - { - if (captures.Any(x => !x.IsTraitDisabled && x.Info.CaptureTypes.Overlaps(capturable.Types))) - { - Self.QueueActivity(new CaptureActor(Self, target)); - return; - } - } - - var externalCapturable = target.Info.TraitInfoOrDefault(); - - if (externalInfo != null && externalCapturable != null && externalInfo.CaptureTypes.Overlaps(externalCapturable.Types)) - Self.QueueActivity(new ExternalCaptureActor(Self, Target.FromActor(target))); - else + if (capturable == null) throw new LuaException("Actor '{0}' cannot capture actor '{1}'!".F(Self, target)); + + if (captures.Any(x => !x.IsTraitDisabled && x.Info.CaptureTypes.Overlaps(capturable.Types))) + Self.QueueActivity(new CaptureActor(Self, target)); } } } diff --git a/OpenRA.Mods.Common/Traits/ExternalCapturable.cs b/OpenRA.Mods.Common/Traits/ExternalCapturable.cs deleted file mode 100644 index 8d47d59729..0000000000 --- a/OpenRA.Mods.Common/Traits/ExternalCapturable.cs +++ /dev/null @@ -1,105 +0,0 @@ -#region Copyright & License Information -/* - * Copyright 2007-2018 The OpenRA Developers (see AUTHORS) - * This file is part of OpenRA, which is free software. It is made - * available to you under the terms of the GNU General Public License - * as published by the Free Software Foundation, either version 3 of - * the License, or (at your option) any later version. For more - * information, see COPYING. - */ -#endregion - -using System.Collections.Generic; -using OpenRA.Traits; - -namespace OpenRA.Mods.Common.Traits -{ - [Desc("This actor can be captured by a unit with ExternalCaptures: trait.")] - public class ExternalCapturableInfo : ConditionalTraitInfo - { - [Desc("CaptureTypes (from the ExternalCaptures trait) that are able to capture this.")] - public readonly HashSet Types = new HashSet() { "building" }; - - [Desc("What diplomatic stances can be captured by this actor.")] - public readonly Stance ValidStances = Stance.Neutral | Stance.Enemy; - - [Desc("Seconds it takes to change the owner.", "You might want to add a ExternalCapturableBar: trait, too.")] - public readonly int CaptureCompleteTime = 15; - - [Desc("Whether to prevent autotargeting this actor while it is being captured by an ally.")] - public readonly bool PreventsAutoTarget = true; - - public bool CanBeTargetedBy(Actor captor, Player owner) - { - var c = captor.Info.TraitInfoOrDefault(); - if (c == null) - return false; - - var stance = owner.Stances[captor.Owner]; - if (!ValidStances.HasStance(stance)) - return false; - - if (!c.CaptureTypes.Overlaps(Types)) - return false; - - return true; - } - - public override object Create(ActorInitializer init) { return new ExternalCapturable(init.Self, this); } - } - - public class ExternalCapturable : ConditionalTrait, ITick, ISync, IPreventsAutoTarget - { - [Sync] public int CaptureProgressTime = 0; - [Sync] public Actor Captor; - public bool CaptureInProgress { get { return Captor != null; } } - - readonly Building building; - - public ExternalCapturable(Actor self, ExternalCapturableInfo info) - : base(info) - { - building = self.TraitOrDefault(); - } - - public void BeginCapture(Actor captor) - { - if (building != null) - building.Lock(); - - Captor = captor; - } - - public void EndCapture() - { - if (building != null) - building.Unlock(); - - Captor = null; - } - - void ITick.Tick(Actor self) - { - if (Captor != null && (!Captor.IsInWorld || Captor.IsDead)) - EndCapture(); - - if (!CaptureInProgress) - CaptureProgressTime = 0; - else - CaptureProgressTime++; - } - - public bool PreventsAutoTarget(Actor self, Actor attacker) - { - return Info.PreventsAutoTarget && Captor != null && attacker.AppearsFriendlyTo(Captor); - } - - public bool CanBeTargetedBy(Actor captor, Player owner) - { - if (IsTraitDisabled) - return false; - - return Info.CanBeTargetedBy(captor, owner); - } - } -} diff --git a/OpenRA.Mods.Common/Traits/ExternalCapturableBar.cs b/OpenRA.Mods.Common/Traits/ExternalCapturableBar.cs deleted file mode 100644 index 24bc86b248..0000000000 --- a/OpenRA.Mods.Common/Traits/ExternalCapturableBar.cs +++ /dev/null @@ -1,44 +0,0 @@ -#region Copyright & License Information -/* - * Copyright 2007-2018 The OpenRA Developers (see AUTHORS) - * This file is part of OpenRA, which is free software. It is made - * available to you under the terms of the GNU General Public License - * as published by the Free Software Foundation, either version 3 of - * the License, or (at your option) any later version. For more - * information, see COPYING. - */ -#endregion - -using System.Drawing; -using OpenRA.Traits; - -namespace OpenRA.Mods.Common.Traits -{ - [Desc("Visualize the remaining CaptureCompleteTime from ExternalCapturable: trait.")] - class ExternalCapturableBarInfo : ITraitInfo, Requires - { - public object Create(ActorInitializer init) { return new ExternalCapturableBar(init.Self); } - } - - class ExternalCapturableBar : ISelectionBar - { - readonly ExternalCapturable capturable; - - public ExternalCapturableBar(Actor self) - { - capturable = self.Trait(); - } - - float ISelectionBar.GetValue() - { - // only show when building is being captured - if (!capturable.CaptureInProgress) - return 0f; - - return (float)capturable.CaptureProgressTime / (capturable.Info.CaptureCompleteTime * 25); - } - - Color ISelectionBar.GetColor() { return Color.Orange; } - bool ISelectionBar.DisplayWhenEmpty { get { return false; } } - } -} diff --git a/OpenRA.Mods.Common/Traits/ExternalCaptures.cs b/OpenRA.Mods.Common/Traits/ExternalCaptures.cs deleted file mode 100644 index 2b42b08048..0000000000 --- a/OpenRA.Mods.Common/Traits/ExternalCaptures.cs +++ /dev/null @@ -1,139 +0,0 @@ -#region Copyright & License Information -/* - * Copyright 2007-2018 The OpenRA Developers (see AUTHORS) - * This file is part of OpenRA, which is free software. It is made - * available to you under the terms of the GNU General Public License - * as published by the Free Software Foundation, either version 3 of - * the License, or (at your option) any later version. For more - * information, see COPYING. - */ -#endregion - -using System.Collections.Generic; -using System.Drawing; -using OpenRA.Mods.Common.Activities; -using OpenRA.Mods.Common.Orders; -using OpenRA.Traits; - -namespace OpenRA.Mods.Common.Traits -{ - [Desc("This actor can capture other actors which have the ExternalCapturable: trait.")] - class ExternalCapturesInfo : ITraitInfo - { - [Desc("Types of actors that it can capture, as long as the type also exists in the ExternalCapturable Type: trait.")] - public readonly HashSet CaptureTypes = new HashSet { "building" }; - - [Desc("Destroy the unit after capturing.")] - public readonly bool ConsumeActor = false; - - [Desc("Experience granted to the capturing player.")] - public readonly int PlayerExperience = 0; - - [Desc("Stance that the structure's previous owner needs to have for the capturing player to receive Experience.")] - public readonly Stance PlayerExperienceStances = Stance.Enemy; - - [VoiceReference] public readonly string Voice = "Action"; - - [GrantedConditionReference] - [Desc("Condition granted when capturing.")] - public readonly string CapturingCondition = null; - - public readonly string CaptureCursor = "ability"; - public readonly string CaptureBlockedCursor = "move-blocked"; - - public object Create(ActorInitializer init) { return new ExternalCaptures(init.Self, this); } - } - - class ExternalCaptures : IIssueOrder, IResolveOrder, IOrderVoice - { - public readonly ExternalCapturesInfo Info; - - public ExternalCaptures(Actor self, ExternalCapturesInfo info) - { - Info = info; - } - - public IEnumerable Orders - { - get - { - yield return new ExternalCaptureOrderTargeter(); - } - } - - public Order IssueOrder(Actor self, IOrderTargeter order, Target target, bool queued) - { - if (order.OrderID != "ExternalCaptureActor") - return null; - - return new Order(order.OrderID, self, target, queued); - } - - static bool IsValidOrder(Actor self, Order order) - { - if (order.Target.Type == TargetType.FrozenActor) - { - var frozen = order.Target.FrozenActor; - var ci = frozen.Info.TraitInfoOrDefault(); - return ci != null && ci.CanBeTargetedBy(self, frozen.Owner); - } - - if (order.Target.Type == TargetType.Actor) - { - var c = order.Target.Actor.TraitOrDefault(); - return c != null && !c.CaptureInProgress && c.CanBeTargetedBy(self, order.Target.Actor.Owner); - } - - return false; - } - - public string VoicePhraseForOrder(Actor self, Order order) - { - return order.OrderString == "ExternalCaptureActor" && IsValidOrder(self, order) - ? Info.Voice : null; - } - - public void ResolveOrder(Actor self, Order order) - { - if (order.OrderString != "ExternalCaptureActor" || !IsValidOrder(self, order)) - return; - - var target = self.ResolveFrozenActorOrder(order, Color.Red); - if (target.Type != TargetType.Actor) - return; - - if (!order.Queued) - self.CancelActivity(); - - self.SetTargetLine(target, Color.Red); - self.QueueActivity(new ExternalCaptureActor(self, target)); - } - } - - class ExternalCaptureOrderTargeter : UnitOrderTargeter - { - public ExternalCaptureOrderTargeter() : base("ExternalCaptureActor", 6, "enter", true, true) { } - - public override bool CanTargetActor(Actor self, Actor target, TargetModifiers modifiers, ref string cursor) - { - var c = target.TraitOrDefault(); - - var canTargetActor = c != null && !c.CaptureInProgress && c.CanBeTargetedBy(self, target.Owner); - var capturesInfo = self.Trait().Info; - cursor = canTargetActor ? capturesInfo.CaptureCursor : capturesInfo.CaptureBlockedCursor; - return canTargetActor; - } - - public override bool CanTargetFrozenActor(Actor self, FrozenActor target, TargetModifiers modifiers, ref string cursor) - { - // TODO: This doesn't account for disabled traits. - // Actors with FrozenUnderFog should not disable the ExternalCapturable trait. - var c = target.Info.TraitInfoOrDefault(); - - var canTargetActor = c != null && c.CanBeTargetedBy(self, target.Owner); - var capturesInfo = self.Trait().Info; - cursor = canTargetActor ? capturesInfo.CaptureCursor : capturesInfo.CaptureBlockedCursor; - return canTargetActor; - } - } -} diff --git a/OpenRA.Mods.Common/Traits/GivesCashOnCapture.cs b/OpenRA.Mods.Common/Traits/GivesCashOnCapture.cs index 2ac3999379..42fca3c84b 100644 --- a/OpenRA.Mods.Common/Traits/GivesCashOnCapture.cs +++ b/OpenRA.Mods.Common/Traits/GivesCashOnCapture.cs @@ -67,14 +67,7 @@ namespace OpenRA.Mods.Common.Traits return true; var capturesInfo = captor.Info.TraitInfoOrDefault(); - if (capturesInfo != null && info.CaptureTypes.Overlaps(capturesInfo.CaptureTypes)) - return true; - - var externalCapturesInfo = captor.Info.TraitInfoOrDefault(); - if (externalCapturesInfo != null && info.CaptureTypes.Overlaps(externalCapturesInfo.CaptureTypes)) - return true; - - return false; + return capturesInfo != null && info.CaptureTypes.Overlaps(capturesInfo.CaptureTypes); } } } diff --git a/OpenRA.Mods.Common/Traits/TransformOnCapture.cs b/OpenRA.Mods.Common/Traits/TransformOnCapture.cs index 95221faa8c..5b40278844 100644 --- a/OpenRA.Mods.Common/Traits/TransformOnCapture.cs +++ b/OpenRA.Mods.Common/Traits/TransformOnCapture.cs @@ -59,14 +59,7 @@ namespace OpenRA.Mods.Common.Traits return true; var capturesInfo = captor.Info.TraitInfoOrDefault(); - if (capturesInfo != null && info.CaptureTypes.Overlaps(capturesInfo.CaptureTypes)) - return true; - - var externalCapturesInfo = captor.Info.TraitInfoOrDefault(); - if (externalCapturesInfo != null && info.CaptureTypes.Overlaps(externalCapturesInfo.CaptureTypes)) - return true; - - return false; + return capturesInfo != null && info.CaptureTypes.Overlaps(capturesInfo.CaptureTypes); } } }