Refactor PowerManager and RequiresPower to use conditions
Instead of Actor.IsDisabled. Added INotifyPowerLevelChanged interface to do so as efficiently as possible.
This commit is contained in:
@@ -24,7 +24,14 @@ using OpenRA.Widgets;
|
|||||||
|
|
||||||
namespace OpenRA
|
namespace OpenRA
|
||||||
{
|
{
|
||||||
public enum PowerState { Normal, Low, Critical }
|
[Flags]
|
||||||
|
public enum PowerState
|
||||||
|
{
|
||||||
|
Normal = 1,
|
||||||
|
Low = 2,
|
||||||
|
Critical = 4
|
||||||
|
}
|
||||||
|
|
||||||
public enum WinState { Undefined, Won, Lost }
|
public enum WinState { Undefined, Won, Lost }
|
||||||
|
|
||||||
public class Player : IScriptBindable, IScriptNotifyBind, ILuaTableBinding, ILuaEqualityBinding, ILuaToStringBinding
|
public class Player : IScriptBindable, IScriptNotifyBind, ILuaTableBinding, ILuaEqualityBinding, ILuaToStringBinding
|
||||||
|
|||||||
@@ -403,7 +403,7 @@
|
|||||||
<Compile Include="Traits\Power\CanPowerDown.cs" />
|
<Compile Include="Traits\Power\CanPowerDown.cs" />
|
||||||
<Compile Include="Traits\Power\Player\PowerManager.cs" />
|
<Compile Include="Traits\Power\Player\PowerManager.cs" />
|
||||||
<Compile Include="Traits\Power\Power.cs" />
|
<Compile Include="Traits\Power\Power.cs" />
|
||||||
<Compile Include="Traits\Power\RequiresPower.cs" />
|
<Compile Include="Traits\Conditions\GrantConditionOnPowerState.cs" />
|
||||||
<Compile Include="Traits\Power\ScalePowerWithHealth.cs" />
|
<Compile Include="Traits\Power\ScalePowerWithHealth.cs" />
|
||||||
<Compile Include="Traits\Production.cs" />
|
<Compile Include="Traits\Production.cs" />
|
||||||
<Compile Include="Traits\ProductionFromMapEdge.cs" />
|
<Compile Include="Traits\ProductionFromMapEdge.cs" />
|
||||||
|
|||||||
@@ -0,0 +1,88 @@
|
|||||||
|
#region Copyright & License Information
|
||||||
|
/*
|
||||||
|
* Copyright 2007-2017 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 OpenRA.Traits;
|
||||||
|
|
||||||
|
namespace OpenRA.Mods.Common.Traits
|
||||||
|
{
|
||||||
|
[Desc("Grants condition as long as a valid power state is maintained.")]
|
||||||
|
public class GrantConditionOnPowerStateInfo : ConditionalTraitInfo
|
||||||
|
{
|
||||||
|
[FieldLoader.Require]
|
||||||
|
[GrantedConditionReference]
|
||||||
|
[Desc("Condition to grant.")]
|
||||||
|
public readonly string Condition = null;
|
||||||
|
|
||||||
|
[FieldLoader.Require]
|
||||||
|
[Desc("PowerStates at which the condition is granted. Options are Normal, Low and Critical.")]
|
||||||
|
public readonly PowerState ValidPowerStates = PowerState.Low | PowerState.Critical;
|
||||||
|
|
||||||
|
public override object Create(ActorInitializer init) { return new GrantConditionOnPowerState(init.Self, this); }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class GrantConditionOnPowerState : ConditionalTrait<GrantConditionOnPowerStateInfo>, INotifyOwnerChanged, INotifyPowerLevelChanged
|
||||||
|
{
|
||||||
|
PowerManager playerPower;
|
||||||
|
ConditionManager conditionManager;
|
||||||
|
int conditionToken = ConditionManager.InvalidConditionToken;
|
||||||
|
|
||||||
|
bool validPowerState;
|
||||||
|
|
||||||
|
public GrantConditionOnPowerState(Actor self, GrantConditionOnPowerStateInfo info)
|
||||||
|
: base(info)
|
||||||
|
{
|
||||||
|
playerPower = self.Owner.PlayerActor.Trait<PowerManager>();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void Created(Actor self)
|
||||||
|
{
|
||||||
|
base.Created(self);
|
||||||
|
|
||||||
|
conditionManager = self.TraitOrDefault<ConditionManager>();
|
||||||
|
|
||||||
|
Update(self);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void TraitEnabled(Actor self)
|
||||||
|
{
|
||||||
|
Update(self);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void TraitDisabled(Actor self)
|
||||||
|
{
|
||||||
|
Update(self);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Update(Actor self)
|
||||||
|
{
|
||||||
|
if (conditionManager == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
validPowerState = !IsTraitDisabled && Info.ValidPowerStates.HasFlag(playerPower.PowerState);
|
||||||
|
|
||||||
|
if (validPowerState && conditionToken == ConditionManager.InvalidConditionToken)
|
||||||
|
conditionToken = conditionManager.GrantCondition(self, Info.Condition);
|
||||||
|
else if (!validPowerState && conditionToken != ConditionManager.InvalidConditionToken)
|
||||||
|
conditionToken = conditionManager.RevokeCondition(self, conditionToken);
|
||||||
|
}
|
||||||
|
|
||||||
|
void INotifyPowerLevelChanged.PowerLevelChanged(Actor self)
|
||||||
|
{
|
||||||
|
Update(self);
|
||||||
|
}
|
||||||
|
|
||||||
|
void INotifyOwnerChanged.OnOwnerChanged(Actor self, Player oldOwner, Player newOwner)
|
||||||
|
{
|
||||||
|
playerPower = newOwner.PlayerActor.Trait<PowerManager>();
|
||||||
|
Update(self);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -32,6 +32,7 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
readonly DeveloperMode devMode;
|
readonly DeveloperMode devMode;
|
||||||
|
|
||||||
readonly Dictionary<Actor, int> powerDrain = new Dictionary<Actor, int>();
|
readonly Dictionary<Actor, int> powerDrain = new Dictionary<Actor, int>();
|
||||||
|
|
||||||
[Sync] int totalProvided;
|
[Sync] int totalProvided;
|
||||||
public int PowerProvided { get { return totalProvided; } }
|
public int PowerProvided { get { return totalProvided; } }
|
||||||
|
|
||||||
@@ -43,6 +44,11 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
public int PowerOutageRemainingTicks { get; private set; }
|
public int PowerOutageRemainingTicks { get; private set; }
|
||||||
public int PowerOutageTotalTicks { get; private set; }
|
public int PowerOutageTotalTicks { get; private set; }
|
||||||
|
|
||||||
|
int nextPowerAdviceTime = 0;
|
||||||
|
bool lowPower = false;
|
||||||
|
bool wasLowPower = false;
|
||||||
|
bool wasHackEnabled;
|
||||||
|
|
||||||
public PowerManager(Actor self, PowerManagerInfo info)
|
public PowerManager(Actor self, PowerManagerInfo info)
|
||||||
{
|
{
|
||||||
this.self = self;
|
this.self = self;
|
||||||
@@ -86,10 +92,6 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
totalDrained += amount;
|
totalDrained += amount;
|
||||||
}
|
}
|
||||||
|
|
||||||
int nextPowerAdviceTime = 0;
|
|
||||||
bool wasLowPower = false;
|
|
||||||
bool wasHackEnabled;
|
|
||||||
|
|
||||||
void ITick.Tick(Actor self)
|
void ITick.Tick(Actor self)
|
||||||
{
|
{
|
||||||
if (wasHackEnabled != devMode.UnlimitedPower)
|
if (wasHackEnabled != devMode.UnlimitedPower)
|
||||||
@@ -107,15 +109,21 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
wasHackEnabled = devMode.UnlimitedPower;
|
wasHackEnabled = devMode.UnlimitedPower;
|
||||||
}
|
}
|
||||||
|
|
||||||
var lowPower = totalProvided < totalDrained;
|
lowPower = ExcessPower < 0;
|
||||||
|
|
||||||
|
if (lowPower != wasLowPower)
|
||||||
|
UpdateRequiresPowerActors();
|
||||||
|
|
||||||
if (lowPower && !wasLowPower)
|
if (lowPower && !wasLowPower)
|
||||||
nextPowerAdviceTime = 0;
|
nextPowerAdviceTime = 0;
|
||||||
|
|
||||||
wasLowPower = lowPower;
|
wasLowPower = lowPower;
|
||||||
|
|
||||||
if (--nextPowerAdviceTime <= 0)
|
if (--nextPowerAdviceTime <= 0)
|
||||||
{
|
{
|
||||||
if (lowPower)
|
if (lowPower)
|
||||||
Game.Sound.PlayNotification(self.World.Map.Rules, self.Owner, "Speech", info.SpeechNotification, self.Owner.Faction.InternalName);
|
Game.Sound.PlayNotification(self.World.Map.Rules, self.Owner, "Speech", info.SpeechNotification, self.Owner.Faction.InternalName);
|
||||||
|
|
||||||
nextPowerAdviceTime = info.AdviceInterval;
|
nextPowerAdviceTime = info.AdviceInterval;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -148,6 +156,15 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
p.Trait.UpdateStatus(p.Actor);
|
p.Trait.UpdateStatus(p.Actor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void UpdateRequiresPowerActors()
|
||||||
|
{
|
||||||
|
var traitPairs = self.World.ActorsWithTrait<INotifyPowerLevelChanged>()
|
||||||
|
.Where(p => !p.Actor.IsDead && p.Actor.IsInWorld && p.Actor.Owner == self.Owner);
|
||||||
|
|
||||||
|
foreach (var p in traitPairs)
|
||||||
|
p.Trait.PowerLevelChanged(p.Actor);
|
||||||
|
}
|
||||||
|
|
||||||
void IResolveOrder.ResolveOrder(Actor self, Order order)
|
void IResolveOrder.ResolveOrder(Actor self, Order order)
|
||||||
{
|
{
|
||||||
if (devMode.Enabled && order.OrderString == "PowerOutage")
|
if (devMode.Enabled && order.OrderString == "PowerOutage")
|
||||||
|
|||||||
@@ -1,42 +0,0 @@
|
|||||||
#region Copyright & License Information
|
|
||||||
/*
|
|
||||||
* Copyright 2007-2017 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 OpenRA.Traits;
|
|
||||||
|
|
||||||
namespace OpenRA.Mods.Common.Traits
|
|
||||||
{
|
|
||||||
[Desc("Needs power to operate.")]
|
|
||||||
class RequiresPowerInfo : ConditionalTraitInfo, ITraitInfo
|
|
||||||
{
|
|
||||||
public override object Create(ActorInitializer init) { return new RequiresPower(init.Self, this); }
|
|
||||||
}
|
|
||||||
|
|
||||||
class RequiresPower : ConditionalTrait<RequiresPowerInfo>, IDisable, INotifyOwnerChanged
|
|
||||||
{
|
|
||||||
PowerManager playerPower;
|
|
||||||
|
|
||||||
public RequiresPower(Actor self, RequiresPowerInfo info)
|
|
||||||
: base(info)
|
|
||||||
{
|
|
||||||
playerPower = self.Owner.PlayerActor.Trait<PowerManager>();
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool Disabled
|
|
||||||
{
|
|
||||||
get { return playerPower.PowerProvided < playerPower.PowerDrained && !IsTraitDisabled; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public void OnOwnerChanged(Actor self, Player oldOwner, Player newOwner)
|
|
||||||
{
|
|
||||||
playerPower = newOwner.PlayerActor.Trait<PowerManager>();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -95,6 +95,9 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
void AfterRepair(Actor self, Actor target);
|
void AfterRepair(Actor self, Actor target);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[RequireExplicitImplementation]
|
||||||
|
public interface INotifyPowerLevelChanged { void PowerLevelChanged(Actor self); }
|
||||||
|
|
||||||
public interface INotifyBuildingPlaced { void BuildingPlaced(Actor self); }
|
public interface INotifyBuildingPlaced { void BuildingPlaced(Actor self); }
|
||||||
public interface INotifyNuke { void Launching(Actor self); }
|
public interface INotifyNuke { void Launching(Actor self); }
|
||||||
public interface INotifyBurstComplete { void FiredBurst(Actor self, Target target, Armament a); }
|
public interface INotifyBurstComplete { void FiredBurst(Actor self, Target target, Armament a); }
|
||||||
|
|||||||
Reference in New Issue
Block a user