Refactored Health usage to IHealth.

This commit is contained in:
Andre Mohren
2018-09-27 02:02:08 +02:00
committed by reaperrr
parent 83cd7cf485
commit 640078a2b1
30 changed files with 68 additions and 61 deletions

View File

@@ -38,6 +38,11 @@ namespace OpenRA.Traits
/// </summary>
public sealed class DamageType { DamageType() { } }
public interface IHealthInfo : ITraitInfo
{
int MaxHP { get; }
}
public interface IHealth
{
DamageState DamageState { get; }

View File

@@ -188,10 +188,10 @@ namespace OpenRA.Mods.Common.AI
var sumOfHp = 0;
foreach (var a in actors)
{
if (a.Info.HasTraitInfo<HealthInfo>())
if (a.Info.HasTraitInfo<IHealthInfo>())
{
sumOfMaxHp += a.Trait<Health>().MaxHP;
sumOfHp += a.Trait<Health>().HP;
sumOfMaxHp += a.Trait<IHealth>().MaxHP;
sumOfHp += a.Trait<IHealth>().HP;
}
}

View File

@@ -160,7 +160,7 @@ namespace OpenRA.Mods.Common.AI
return (valueInfo != null) ? valueInfo.Cost * Attractiveness : 0;
case DecisionMetric.Health:
var health = a.TraitOrDefault<Health>();
var health = a.TraitOrDefault<IHealth>();
if (health == null)
return 0;
@@ -193,8 +193,8 @@ namespace OpenRA.Mods.Common.AI
return (valueInfo != null) ? valueInfo.Cost * Attractiveness : 0;
case DecisionMetric.Health:
var healthInfo = fa.Info.TraitInfoOrDefault<HealthInfo>();
return (healthInfo != null) ? fa.HP * Attractiveness / healthInfo.HP : 0;
var healthInfo = fa.Info.TraitInfoOrDefault<IHealthInfo>();
return (healthInfo != null) ? fa.HP * Attractiveness / healthInfo.MaxHP : 0;
default:
return Attractiveness;

View File

@@ -22,7 +22,7 @@ namespace OpenRA.Mods.Common.Activities
readonly Building building;
readonly Capturable capturable;
readonly Captures[] captures;
readonly Health health;
readonly IHealth health;
public CaptureActor(Actor self, Actor target)
: base(self, target, EnterBehaviour.Dispose)
@@ -31,7 +31,7 @@ namespace OpenRA.Mods.Common.Activities
building = actor.TraitOrDefault<Building>();
captures = self.TraitsImplementing<Captures>().ToArray();
capturable = target.Trait<Capturable>();
health = actor.Trait<Health>();
health = actor.Trait<IHealth>();
}
protected override bool CanReserve(Actor self)

View File

@@ -19,7 +19,7 @@ namespace OpenRA.Mods.Common.Activities
{
public class Repair : Activity
{
readonly Health health;
readonly IHealth health;
readonly RepairsUnits[] allRepairsUnits;
readonly Target host;
readonly WDist closeEnough;
@@ -33,7 +33,7 @@ namespace OpenRA.Mods.Common.Activities
this.host = Target.FromActor(host);
this.closeEnough = closeEnough;
allRepairsUnits = host.TraitsImplementing<RepairsUnits>().ToArray();
health = self.TraitOrDefault<Health>();
health = self.TraitOrDefault<IHealth>();
repairable = self.TraitOrDefault<Repairable>();
}

View File

@@ -17,7 +17,7 @@ namespace OpenRA.Mods.Common.Activities
class RepairBuilding : Enter
{
readonly Actor target;
readonly Health health;
readonly IHealth health;
readonly Stance validStances;
public RepairBuilding(Actor self, Actor target, EnterBehaviour enterBehaviour, Stance validStances)
@@ -25,7 +25,7 @@ namespace OpenRA.Mods.Common.Activities
{
this.target = target;
this.validStances = validStances;
health = target.Trait<Health>();
health = target.Trait<IHealth>();
}
protected override bool CanReserve(Actor self)

View File

@@ -18,7 +18,7 @@ namespace OpenRA.Mods.Common.Activities
{
class Sell : Activity
{
readonly Health health;
readonly IHealth health;
readonly SellableInfo sellableInfo;
readonly PlayerResources playerResources;
bool showTicks;
@@ -26,7 +26,7 @@ namespace OpenRA.Mods.Common.Activities
public Sell(Actor self, bool showTicks)
{
this.showTicks = showTicks;
health = self.TraitOrDefault<Health>();
health = self.TraitOrDefault<IHealth>();
sellableInfo = self.Info.TraitInfo<SellableInfo>();
playerResources = self.Owner.PlayerActor.Trait<PlayerResources>();
IsInterruptible = false;

View File

@@ -119,7 +119,7 @@ namespace OpenRA.Mods.Common.Activities
if (Faction != null)
init.Add(new FactionInit(Faction));
var health = self.TraitOrDefault<Health>();
var health = self.TraitOrDefault<IHealth>();
if (health != null)
{
// Cast to long to avoid overflow when multiplying by the health

View File

@@ -22,7 +22,7 @@ namespace OpenRA.Mods.Common.Lint
{
foreach (var actorInfo in rules.Actors)
{
var health = actorInfo.Value.TraitInfoOrDefault<HealthInfo>();
var health = actorInfo.Value.TraitInfoOrDefault<IHealthInfo>();
if (health == null)
continue;

View File

@@ -16,13 +16,13 @@ using OpenRA.Traits;
namespace OpenRA.Mods.Common.Scripting
{
[ScriptPropertyGroup("General")]
public class HealthProperties : ScriptActorProperties, Requires<HealthInfo>
public class HealthProperties : ScriptActorProperties, Requires<IHealthInfo>
{
Health health;
IHealth health;
public HealthProperties(ScriptContext context, Actor self)
: base(context, self)
{
health = self.Trait<Health>();
health = self.Trait<IHealth>();
}
[Desc("Current health of the actor.")]

View File

@@ -18,7 +18,7 @@ using OpenRA.Traits;
namespace OpenRA.Mods.Common.Traits
{
[Desc("Bridge actor that can't be passed underneath.")]
class GroundLevelBridgeInfo : ITraitInfo, IRulesetLoaded, Requires<BuildingInfo>, Requires<HealthInfo>
class GroundLevelBridgeInfo : ITraitInfo, IRulesetLoaded, Requires<BuildingInfo>, Requires<IHealthInfo>
{
public readonly string TerrainType = "Bridge";
@@ -53,13 +53,13 @@ namespace OpenRA.Mods.Common.Traits
readonly Actor self;
readonly BridgeLayer bridgeLayer;
readonly IEnumerable<CPos> cells;
readonly Health health;
readonly IHealth health;
public GroundLevelBridge(Actor self, GroundLevelBridgeInfo info)
{
Info = info;
this.self = self;
health = self.Trait<Health>();
health = self.Trait<IHealth>();
bridgeLayer = self.World.WorldActor.Trait<BridgeLayer>();
var buildingInfo = self.Info.TraitInfo<BuildingInfo>();

View File

@@ -18,7 +18,7 @@ using OpenRA.Traits;
namespace OpenRA.Mods.Common.Traits
{
[Desc("Building can be repaired by the repair button.")]
public class RepairableBuildingInfo : ConditionalTraitInfo, Requires<HealthInfo>
public class RepairableBuildingInfo : ConditionalTraitInfo, Requires<IHealthInfo>
{
[Desc("Cost to fully repair the actor as a percent of its value.")]
public readonly int RepairPercent = 20;
@@ -51,7 +51,7 @@ namespace OpenRA.Mods.Common.Traits
public class RepairableBuilding : ConditionalTrait<RepairableBuildingInfo>, ITick
{
readonly Health health;
readonly IHealth health;
readonly Predicate<Player> isNotActiveAlly;
readonly Stack<int> repairTokens = new Stack<int>();
ConditionManager conditionManager;
@@ -63,7 +63,7 @@ namespace OpenRA.Mods.Common.Traits
public RepairableBuilding(Actor self, RepairableBuildingInfo info)
: base(info)
{
health = self.Trait<Health>();
health = self.Trait<IHealth>();
isNotActiveAlly = player => player.WinState != WinState.Undefined || player.Stances[self.Owner] != Stance.Ally;
}

View File

@@ -108,7 +108,7 @@ namespace OpenRA.Mods.Common.Traits
return false;
}
var health = target.Trait<Health>();
var health = target.Trait<IHealth>();
// Cast to long to avoid overflow when multiplying by the health
var lowEnoughHealth = health.HP <= (int)(c.Info.CaptureThreshold * (long)health.MaxHP / 100);
@@ -130,10 +130,10 @@ namespace OpenRA.Mods.Common.Traits
return false;
}
var health = target.Info.TraitInfoOrDefault<HealthInfo>();
var health = target.Info.TraitInfoOrDefault<IHealthInfo>();
// Cast to long to avoid overflow when multiplying by the health
var lowEnoughHealth = target.HP <= (int)(c.CaptureThreshold * (long)health.HP / 100);
var lowEnoughHealth = target.HP <= (int)(c.CaptureThreshold * (long)health.MaxHP / 100);
cursor = !capturesInfo.Sabotage || lowEnoughHealth || target.Owner.NonCombatant
? capturesInfo.EnterCursor : capturesInfo.SabotageCursor;

View File

@@ -30,7 +30,7 @@ namespace OpenRA.Mods.Common.Traits
static readonly WVec TargetPosVLine = new WVec(128, 0, 0);
readonly DebugVisualizations debugVis;
readonly HealthInfo healthInfo;
readonly IHealthInfo healthInfo;
readonly Lazy<BodyOrientation> coords;
HitShape[] shapes;
@@ -38,7 +38,7 @@ namespace OpenRA.Mods.Common.Traits
public CombatDebugOverlay(Actor self)
{
healthInfo = self.Info.TraitInfoOrDefault<HealthInfo>();
healthInfo = self.Info.TraitInfoOrDefault<IHealthInfo>();
coords = Exts.Lazy(self.Trait<BodyOrientation>);
debugVis = self.World.WorldActor.TraitOrDefault<DebugVisualizations>();
@@ -139,7 +139,7 @@ namespace OpenRA.Mods.Common.Traits
if (healthInfo == null)
return;
var maxHP = healthInfo.HP > 0 ? healthInfo.HP : 1;
var maxHP = healthInfo.MaxHP > 0 ? healthInfo.MaxHP : 1;
var damageText = "{0} ({1}%)".F(-e.Damage.Value, e.Damage.Value * 100 / maxHP);
self.World.AddFrameEndTask(w => w.Add(new FloatingText(self.CenterPosition, e.Attacker.Owner.Color.RGB, damageText, 30)));

View File

@@ -14,7 +14,7 @@ using OpenRA.Traits;
namespace OpenRA.Mods.Common.Traits
{
[Desc("Applies a condition to the actor at specified damage states.")]
public class GrantConditionOnDamageStateInfo : ITraitInfo, Requires<HealthInfo>
public class GrantConditionOnDamageStateInfo : ITraitInfo, Requires<IHealthInfo>
{
[FieldLoader.Require]
[GrantedConditionReference]
@@ -39,7 +39,7 @@ namespace OpenRA.Mods.Common.Traits
public class GrantConditionOnDamageState : INotifyDamageStateChanged, INotifyCreated
{
readonly GrantConditionOnDamageStateInfo info;
readonly Health health;
readonly IHealth health;
ConditionManager conditionManager;
int conditionToken = ConditionManager.InvalidConditionToken;
@@ -47,7 +47,7 @@ namespace OpenRA.Mods.Common.Traits
public GrantConditionOnDamageState(Actor self, GrantConditionOnDamageStateInfo info)
{
this.info = info;
health = self.Trait<Health>();
health = self.Trait<IHealth>();
}
void INotifyCreated.Created(Actor self)

View File

@@ -27,7 +27,7 @@ namespace OpenRA.Mods.Common.Traits
public override void Activate(Actor collector)
{
foreach (var healable in collector.World.ActorsWithTrait<Health>().Where(tp => tp.Actor.Owner == collector.Owner))
foreach (var healable in collector.World.ActorsWithTrait<IHealth>().Where(tp => tp.Actor.Owner == collector.Owner))
if (!healable.Trait.IsDead)
healable.Trait.InflictDamage(healable.Actor, healable.Actor, new Damage(-(healable.Trait.MaxHP - healable.Trait.HP)), true);

View File

@@ -16,7 +16,7 @@ using OpenRA.Traits;
namespace OpenRA.Mods.Common.Traits
{
[Desc("This actor receives damage from the given weapon when on the specified terrain type.")]
class DamagedByTerrainInfo : ConditionalTraitInfo, Requires<HealthInfo>
class DamagedByTerrainInfo : ConditionalTraitInfo, Requires<IHealthInfo>
{
[Desc("Amount of damage received per DamageInterval ticks.")]
[FieldLoader.Require] public readonly int Damage = 0;
@@ -41,14 +41,14 @@ namespace OpenRA.Mods.Common.Traits
class DamagedByTerrain : ConditionalTrait<DamagedByTerrainInfo>, ITick, ISync, INotifyAddedToWorld
{
readonly Health health;
readonly IHealth health;
[Sync] int damageTicks;
[Sync] int damageThreshold;
public DamagedByTerrain(Actor self, DamagedByTerrainInfo info) : base(info)
{
health = self.Trait<Health>();
health = self.Trait<IHealth>();
}
void INotifyAddedToWorld.AddedToWorld(Actor self)

View File

@@ -23,7 +23,7 @@ namespace OpenRA.Mods.Common.Traits
public enum DamageSource { Self, Killer }
[Desc("This actor explodes when killed.")]
public class ExplodesInfo : ConditionalTraitInfo, Requires<HealthInfo>
public class ExplodesInfo : ConditionalTraitInfo, Requires<IHealthInfo>
{
[WeaponReference, FieldLoader.Require, Desc("Default weapon to use for explosion if ammo/payload is loaded.")]
public readonly string Weapon = null;
@@ -81,13 +81,13 @@ namespace OpenRA.Mods.Common.Traits
public class Explodes : ConditionalTrait<ExplodesInfo>, INotifyKilled, INotifyDamage, INotifyCreated
{
readonly Health health;
readonly IHealth health;
BuildingInfo buildingInfo;
public Explodes(ExplodesInfo info, Actor self)
: base(info)
{
health = self.Trait<Health>();
health = self.Trait<IHealth>();
}
void INotifyCreated.Created(Actor self)

View File

@@ -18,7 +18,7 @@ using OpenRA.Traits;
namespace OpenRA.Mods.Common.Traits
{
[Desc("This actor triggers an explosion on itself when transitioning to a specific damage state.")]
public class ExplosionOnDamageTransitionInfo : ITraitInfo, IRulesetLoaded, Requires<HealthInfo>
public class ExplosionOnDamageTransitionInfo : ITraitInfo, IRulesetLoaded, Requires<IHealthInfo>
{
[WeaponReference, FieldLoader.Require, Desc("Weapon to use for explosion.")]
public readonly string Weapon = null;

View File

@@ -15,7 +15,7 @@ using OpenRA.Traits;
namespace OpenRA.Mods.Common.Traits
{
public class HealthInfo : ITraitInfo, UsesInit<HealthInit>, IRulesetLoaded
public class HealthInfo : IHealthInfo, UsesInit<HealthInit>, IRulesetLoaded
{
[Desc("HitPoints")]
public readonly int HP = 0;
@@ -30,6 +30,8 @@ namespace OpenRA.Mods.Common.Traits
if (!ai.HasTraitInfo<HitShapeInfo>())
throw new YamlException("Actors with Health need at least one HitShape trait!");
}
int IHealthInfo.MaxHP { get { return HP; } }
}
public class Health : IHealth, ISync, ITick, INotifyCreated, INotifyOwnerChanged

View File

@@ -82,7 +82,7 @@ namespace OpenRA.Mods.Common.Traits
if (conditionManager != null && !string.IsNullOrEmpty(Info.GrantsCondition))
conditionManager.GrantCondition(self, Info.GrantsCondition);
if (Info.RemoveInstead || !self.Info.HasTraitInfo<HealthInfo>())
if (Info.RemoveInstead || !self.Info.HasTraitInfo<IHealthInfo>())
self.Dispose();
else
self.Kill(self, Info.DamageTypes);

View File

@@ -14,20 +14,20 @@ using OpenRA.Traits;
namespace OpenRA.Mods.Common.Traits
{
[Desc("Scale power amount with the current health.")]
public class ScalePowerWithHealthInfo : ITraitInfo, Requires<PowerInfo>, Requires<HealthInfo>
public class ScalePowerWithHealthInfo : ITraitInfo, Requires<PowerInfo>, Requires<IHealthInfo>
{
public object Create(ActorInitializer init) { return new ScalePowerWithHealth(init.Self); }
}
public class ScalePowerWithHealth : IPowerModifier, INotifyDamage, INotifyOwnerChanged
{
readonly Health health;
readonly IHealth health;
PowerManager power;
public ScalePowerWithHealth(Actor self)
{
power = self.Owner.PlayerActor.Trait<PowerManager>();
health = self.Trait<Health>();
health = self.Trait<IHealth>();
}
int IPowerModifier.GetPowerModifier()

View File

@@ -20,7 +20,7 @@ using OpenRA.Traits;
namespace OpenRA.Mods.Common.Traits
{
[Desc("This actor can be sent to a structure for repairs.")]
class RepairableInfo : ITraitInfo, Requires<HealthInfo>, Requires<IMoveInfo>
class RepairableInfo : ITraitInfo, Requires<IHealthInfo>, Requires<IMoveInfo>
{
public readonly HashSet<string> RepairBuildings = new HashSet<string> { "fix" };
@@ -35,14 +35,14 @@ namespace OpenRA.Mods.Common.Traits
class Repairable : IIssueOrder, IResolveOrder, IOrderVoice
{
public readonly RepairableInfo Info;
readonly Health health;
readonly IHealth health;
readonly IMove movement;
readonly AmmoPool[] ammoPools;
public Repairable(Actor self, RepairableInfo info)
{
Info = info;
health = self.Trait<Health>();
health = self.Trait<IHealth>();
movement = self.Trait<IMove>();
ammoPools = self.TraitsImplementing<AmmoPool>().ToArray();
}

View File

@@ -18,7 +18,7 @@ using OpenRA.Traits;
namespace OpenRA.Mods.Common.Traits
{
class RepairableNearInfo : ITraitInfo, Requires<HealthInfo>, Requires<IMoveInfo>
class RepairableNearInfo : ITraitInfo, Requires<IHealthInfo>, Requires<IMoveInfo>
{
[ActorReference] public readonly HashSet<string> Buildings = new HashSet<string> { "spen", "syrd" };
public readonly WDist CloseEnough = WDist.FromCells(4);

View File

@@ -15,7 +15,7 @@ using OpenRA.Traits;
namespace OpenRA.Mods.Common.Traits
{
[Desc("Attach this to actors which should be able to regenerate their health points.")]
class SelfHealingInfo : ConditionalTraitInfo, Requires<HealthInfo>
class SelfHealingInfo : ConditionalTraitInfo, Requires<IHealthInfo>
{
[Desc("Absolute amount of health points added in each step.")]
public readonly int Step = 5;
@@ -39,7 +39,7 @@ namespace OpenRA.Mods.Common.Traits
class SelfHealing : ConditionalTrait<SelfHealingInfo>, ITick, INotifyDamage
{
readonly Health health;
readonly IHealth health;
[Sync] int ticks;
[Sync] int damageTicks;
@@ -47,7 +47,7 @@ namespace OpenRA.Mods.Common.Traits
public SelfHealing(Actor self, SelfHealingInfo info)
: base(info)
{
health = self.Trait<Health>();
health = self.Trait<IHealth>();
}
void ITick.Tick(Actor self)

View File

@@ -36,7 +36,7 @@ namespace OpenRA.Mods.Common.Traits
public class Sellable : ConditionalTrait<SellableInfo>, IResolveOrder, IProvideTooltipInfo
{
readonly Actor self;
readonly Lazy<Health> health;
readonly Lazy<IHealth> health;
readonly SellableInfo info;
public Sellable(Actor self, SellableInfo info)
@@ -44,7 +44,7 @@ namespace OpenRA.Mods.Common.Traits
{
this.self = self;
this.info = info;
health = Exts.Lazy(() => self.TraitOrDefault<Health>());
health = Exts.Lazy(() => self.TraitOrDefault<IHealth>());
}
public void ResolveOrder(Actor self, Order order)

View File

@@ -55,7 +55,7 @@ namespace OpenRA.Mods.Common.Traits
var valued = self.Info.TraitInfoOrDefault<ValuedInfo>();
var cost = csv != null ? csv.Value : (valued != null ? valued.Cost : 0);
var health = self.TraitOrDefault<Health>();
var health = self.TraitOrDefault<IHealth>();
var dudesValue = Info.ValuePercent * cost / 100;
if (health != null)
{

View File

@@ -80,7 +80,7 @@ namespace OpenRA.Mods.Common.Warheads
if (!AffectsParent && victim == firedBy)
continue;
if (!victim.Info.HasTraitInfo<HealthInfo>())
if (!victim.Info.HasTraitInfo<IHealthInfo>())
continue;
// If the impact position is within any HitShape, we have a direct hit

View File

@@ -43,12 +43,12 @@ namespace OpenRA.Mods.Common.Warheads
if (!IsValidAgainst(victim, firedBy))
return;
var healthInfo = victim.Info.TraitInfoOrDefault<HealthInfo>();
var healthInfo = victim.Info.TraitInfoOrDefault<IHealthInfo>();
if (healthInfo == null)
return;
// Damage is measured as a percentage of the target health
var damage = Util.ApplyPercentageModifiers(healthInfo.HP, damageModifiers.Append(Damage, DamageVersus(victim)));
var damage = Util.ApplyPercentageModifiers(healthInfo.MaxHP, damageModifiers.Append(Damage, DamageVersus(victim)));
victim.InflictDamage(firedBy, new Damage(damage, DamageTypes));
}
}

View File

@@ -56,7 +56,7 @@ namespace OpenRA.Mods.Common.Warheads
foreach (var victim in hitActors)
{
// Cannot be damaged without a Health trait
var healthInfo = victim.Info.TraitInfoOrDefault<HealthInfo>();
var healthInfo = victim.Info.TraitInfoOrDefault<IHealthInfo>();
if (healthInfo == null)
continue;