1 #region Copyright & License Information 2 /* 3 * Copyright 2007-2020 The OpenRA Developers (see AUTHORS) 4 * This file is part of OpenRA, which is free software. It is made 5 * available to you under the terms of the GNU General Public License 6 * as published by the Free Software Foundation, either version 3 of 7 * the License, or (at your option) any later version. For more 8 * information, see COPYING. 9 */ 10 #endregion 11 12 using System.Collections.Generic; 13 using OpenRA.Primitives; 14 using OpenRA.Traits; 15 16 namespace OpenRA.Mods.Common.Orders 17 { 18 public abstract class UnitOrderTargeter : IOrderTargeter 19 { 20 readonly string cursor; 21 readonly bool targetEnemyUnits, targetAllyUnits; 22 UnitOrderTargeter(string order, int priority, string cursor, bool targetEnemyUnits, bool targetAllyUnits)23 public UnitOrderTargeter(string order, int priority, string cursor, bool targetEnemyUnits, bool targetAllyUnits) 24 { 25 OrderID = order; 26 OrderPriority = priority; 27 this.cursor = cursor; 28 this.targetEnemyUnits = targetEnemyUnits; 29 this.targetAllyUnits = targetAllyUnits; 30 } 31 32 public string OrderID { get; private set; } 33 public int OrderPriority { get; private set; } 34 public bool? ForceAttack = null; TargetOverridesSelection(Actor self, Target target, List<Actor> actorsAt, CPos xy, TargetModifiers modifiers)35 public bool TargetOverridesSelection(Actor self, Target target, List<Actor> actorsAt, CPos xy, TargetModifiers modifiers) { return true; } 36 CanTargetActor(Actor self, Actor target, TargetModifiers modifiers, ref string cursor)37 public abstract bool CanTargetActor(Actor self, Actor target, TargetModifiers modifiers, ref string cursor); CanTargetFrozenActor(Actor self, FrozenActor target, TargetModifiers modifiers, ref string cursor)38 public abstract bool CanTargetFrozenActor(Actor self, FrozenActor target, TargetModifiers modifiers, ref string cursor); 39 CanTarget(Actor self, Target target, List<Actor> othersAtTarget, ref TargetModifiers modifiers, ref string cursor)40 public bool CanTarget(Actor self, Target target, List<Actor> othersAtTarget, ref TargetModifiers modifiers, ref string cursor) 41 { 42 var type = target.Type; 43 if (type != TargetType.Actor && type != TargetType.FrozenActor) 44 return false; 45 46 cursor = this.cursor; 47 IsQueued = modifiers.HasModifier(TargetModifiers.ForceQueue); 48 49 if (ForceAttack != null && modifiers.HasModifier(TargetModifiers.ForceAttack) != ForceAttack) 50 return false; 51 52 var owner = type == TargetType.FrozenActor ? target.FrozenActor.Owner : target.Actor.Owner; 53 var playerRelationship = self.Owner.Stances[owner]; 54 55 if (!modifiers.HasModifier(TargetModifiers.ForceAttack) && playerRelationship == Stance.Ally && !targetAllyUnits) 56 return false; 57 58 if (!modifiers.HasModifier(TargetModifiers.ForceAttack) && playerRelationship == Stance.Enemy && !targetEnemyUnits) 59 return false; 60 61 return type == TargetType.FrozenActor ? 62 CanTargetFrozenActor(self, target.FrozenActor, modifiers, ref cursor) : 63 CanTargetActor(self, target.Actor, modifiers, ref cursor); 64 } 65 66 public virtual bool IsQueued { get; protected set; } 67 } 68 69 public class TargetTypeOrderTargeter : UnitOrderTargeter 70 { 71 readonly BitSet<TargetableType> targetTypes; 72 TargetTypeOrderTargeter(BitSet<TargetableType> targetTypes, string order, int priority, string cursor, bool targetEnemyUnits, bool targetAllyUnits)73 public TargetTypeOrderTargeter(BitSet<TargetableType> targetTypes, string order, int priority, string cursor, bool targetEnemyUnits, bool targetAllyUnits) 74 : base(order, priority, cursor, targetEnemyUnits, targetAllyUnits) 75 { 76 this.targetTypes = targetTypes; 77 } 78 CanTargetActor(Actor self, Actor target, TargetModifiers modifiers, ref string cursor)79 public override bool CanTargetActor(Actor self, Actor target, TargetModifiers modifiers, ref string cursor) 80 { 81 return targetTypes.Overlaps(target.GetEnabledTargetTypes()); 82 } 83 CanTargetFrozenActor(Actor self, FrozenActor target, TargetModifiers modifiers, ref string cursor)84 public override bool CanTargetFrozenActor(Actor self, FrozenActor target, TargetModifiers modifiers, ref string cursor) 85 { 86 return target.TargetTypes.Overlaps(targetTypes); 87 } 88 } 89 } 90