Grant condition by unit stance

This commit is contained in:
atlimit8
2017-05-24 11:29:10 -05:00
committed by Paul Chote
parent 5834d7615b
commit cadfbe8a29
2 changed files with 46 additions and 7 deletions

View File

@@ -169,7 +169,7 @@ namespace OpenRA.Mods.Common.Scripting
if (!Enum<UnitStance>.TryParse(value, true, out stance)) if (!Enum<UnitStance>.TryParse(value, true, out stance))
throw new LuaException("Unknown stance type '{0}'".F(value)); throw new LuaException("Unknown stance type '{0}'".F(value));
autotarget.Stance = stance; autotarget.SetStance(Self, stance);
} }
} }

View File

@@ -32,6 +32,9 @@ namespace OpenRA.Mods.Common.Traits
[Desc("Possible values are HoldFire, ReturnFire, Defend and AttackAnything. Used for human players.")] [Desc("Possible values are HoldFire, ReturnFire, Defend and AttackAnything. Used for human players.")]
public readonly UnitStance InitialStance = UnitStance.Defend; public readonly UnitStance InitialStance = UnitStance.Defend;
[Desc("Stance-condition key-value pairs for specifying condition granting by stance.")]
public readonly Dictionary<UnitStance, string> ConditionByStance = new Dictionary<UnitStance, string>();
[Desc("Allow the player to change the unit stance.")] [Desc("Allow the player to change the unit stance.")]
public readonly bool EnableStances = true; public readonly bool EnableStances = true;
@@ -45,24 +48,54 @@ namespace OpenRA.Mods.Common.Traits
public readonly bool TargetWhenDamaged = true; public readonly bool TargetWhenDamaged = true;
[GrantedConditionReference]
public IEnumerable<string> GrantedConditions { get { return ConditionByStance.Values; } }
public override object Create(ActorInitializer init) { return new AutoTarget(init, this); } public override object Create(ActorInitializer init) { return new AutoTarget(init, this); }
} }
public enum UnitStance { HoldFire, ReturnFire, Defend, AttackAnything } public enum UnitStance { HoldFire, ReturnFire, Defend, AttackAnything }
public class AutoTarget : ConditionalTrait<AutoTargetInfo>, INotifyIdle, INotifyDamage, ITick, IResolveOrder, ISync public class AutoTarget : ConditionalTrait<AutoTargetInfo>, INotifyIdle, INotifyDamage, ITick, IResolveOrder, ISync, INotifyCreated
{ {
readonly IEnumerable<AttackBase> activeAttackBases; readonly IEnumerable<AttackBase> activeAttackBases;
readonly AttackFollow[] attackFollows; readonly AttackFollow[] attackFollows;
[Sync] int nextScanTime = 0; [Sync] int nextScanTime = 0;
public UnitStance Stance; public UnitStance Stance { get { return stance; } }
[Sync] public Actor Aggressor; [Sync] public Actor Aggressor;
[Sync] public Actor TargetedActor; [Sync] public Actor TargetedActor;
// NOT SYNCED: do not refer to this anywhere other than UI code // NOT SYNCED: do not refer to this anywhere other than UI code
public UnitStance PredictedStance; public UnitStance PredictedStance;
UnitStance stance;
ConditionManager conditionManager;
int conditionToken = ConditionManager.InvalidConditionToken;
public void SetStance(Actor self, UnitStance value)
{
if (stance == value)
return;
stance = value;
ApplyStanceCondition(self);
}
void ApplyStanceCondition(Actor self)
{
if (conditionManager == null)
return;
if (conditionToken != ConditionManager.InvalidConditionToken)
conditionToken = conditionManager.RevokeCondition(self, conditionToken);
string condition;
if (Info.ConditionByStance.TryGetValue(stance, out condition))
conditionToken = conditionManager.GrantCondition(self, condition);
}
public AutoTarget(ActorInitializer init, AutoTargetInfo info) public AutoTarget(ActorInitializer init, AutoTargetInfo info)
: base(info) : base(info)
{ {
@@ -70,18 +103,24 @@ namespace OpenRA.Mods.Common.Traits
activeAttackBases = self.TraitsImplementing<AttackBase>().ToArray().Where(Exts.IsTraitEnabled); activeAttackBases = self.TraitsImplementing<AttackBase>().ToArray().Where(Exts.IsTraitEnabled);
if (init.Contains<StanceInit>()) if (init.Contains<StanceInit>())
Stance = init.Get<StanceInit, UnitStance>(); stance = init.Get<StanceInit, UnitStance>();
else else
Stance = self.Owner.IsBot || !self.Owner.Playable ? info.InitialStanceAI : info.InitialStance; stance = self.Owner.IsBot || !self.Owner.Playable ? info.InitialStanceAI : info.InitialStance;
PredictedStance = Stance; PredictedStance = stance;
attackFollows = self.TraitsImplementing<AttackFollow>().ToArray(); attackFollows = self.TraitsImplementing<AttackFollow>().ToArray();
} }
void INotifyCreated.Created(Actor self)
{
conditionManager = self.TraitOrDefault<ConditionManager>();
ApplyStanceCondition(self);
}
public void ResolveOrder(Actor self, Order order) public void ResolveOrder(Actor self, Order order)
{ {
if (order.OrderString == "SetUnitStance" && Info.EnableStances) if (order.OrderString == "SetUnitStance" && Info.EnableStances)
Stance = (UnitStance)order.ExtraData; SetStance(self, (UnitStance)order.ExtraData);
} }
public void Damaged(Actor self, AttackInfo e) public void Damaged(Actor self, AttackInfo e)