Add UpgradeOnMovement trait

This provides upgrades when an actor is moving. To avoid 'hiccups' for ground units, air units are considered moving as soon as they are airborne.
This commit is contained in:
reaperrr
2016-08-26 17:21:07 +02:00
parent eabd881ca3
commit 0fcc07cb7b
2 changed files with 76 additions and 0 deletions

View File

@@ -499,6 +499,7 @@
<Compile Include="Traits\Upgrades\UpgradeActorsNear.cs" />
<Compile Include="Traits\Upgrades\UpgradeOnDamageState.cs" />
<Compile Include="Traits\Upgrades\UpgradeOnTerrain.cs" />
<Compile Include="Traits\Upgrades\UpgradeOnMovement.cs" />
<Compile Include="Traits\Upgrades\UpgradeManager.cs" />
<Compile Include="Traits\Valued.cs" />
<Compile Include="Traits\Voiced.cs" />

View File

@@ -0,0 +1,75 @@
#region Copyright & License Information
/*
* Copyright 2007-2016 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.Traits;
namespace OpenRA.Mods.Common.Traits
{
public class UpgradeOnMovementInfo : UpgradableTraitInfo, Requires<UpgradeManagerInfo>, Requires<IMoveInfo>
{
[UpgradeGrantedReference, FieldLoader.Require]
[Desc("The upgrades to grant.")]
public readonly string[] Upgrades = { };
[Desc("Apply upgrades on straight vertical movement as well.")]
public readonly bool ConsiderVerticalMovement = false;
public override object Create(ActorInitializer init) { return new UpgradeOnMovement(init.Self, this); }
}
public class UpgradeOnMovement : UpgradableTrait<UpgradeOnMovementInfo>, ITick
{
readonly UpgradeManager manager;
readonly IMove movement;
bool granted;
public UpgradeOnMovement(Actor self, UpgradeOnMovementInfo info)
: base(info)
{
manager = self.Trait<UpgradeManager>();
movement = self.Trait<IMove>();
}
void Revoke(Actor self)
{
if (!granted)
return;
foreach (var up in Info.Upgrades)
manager.RevokeUpgrade(self, up, this);
granted = false;
}
void ITick.Tick(Actor self)
{
if (IsTraitDisabled)
{
Revoke(self);
return;
}
var isMovingVertically = Info.ConsiderVerticalMovement ? movement.IsMovingVertically : false;
var isMoving = !self.IsDead && (movement.IsMoving || isMovingVertically);
if (isMoving && !granted)
{
foreach (var up in Info.Upgrades)
manager.GrantUpgrade(self, up, this);
granted = true;
}
else if (!isMoving)
Revoke(self);
}
}
}