Merge pull request #12996 from atlimit8/RemoveIDisable-part2

Remove IDisable - part 2
This commit is contained in:
Paul Chote
2017-05-07 08:38:09 +01:00
committed by GitHub
23 changed files with 199 additions and 93 deletions

View File

@@ -53,6 +53,7 @@ namespace OpenRA.Mods.Common.Commands
register("all", "toggles all cheats and gives you some cash for your trouble.");
register("crash", "crashes the game.");
register("levelup", "adds a specified number of levels to the selected actors.");
register("poweroutage", "causes owners of selected actors to have a 5 second power outage.");
}
public void InvokeCommand(string name, string arg)
@@ -123,6 +124,11 @@ namespace OpenRA.Mods.Common.Commands
}
break;
case "poweroutage":
foreach (var player in world.Selection.Actors.Select(a => a.Owner.PlayerActor).Distinct())
world.IssueOrder(new Order("PowerOutage", player, false) { ExtraData = 250 });
break;
}
}

View File

@@ -15,23 +15,39 @@ using OpenRA.Traits;
namespace OpenRA.Mods.Common.Traits
{
[Desc("Disables the actor when a power outage is triggered (see `InfiltrateForPowerOutage` for more information).")]
public class AffectedByPowerOutageInfo : ITraitInfo
public class AffectedByPowerOutageInfo : ConditionalTraitInfo
{
public object Create(ActorInitializer init) { return new AffectedByPowerOutage(init.Self); }
[GrantedConditionReference]
[Desc("The condition to grant while there is a power outage.")]
public readonly string Condition = null;
public override object Create(ActorInitializer init) { return new AffectedByPowerOutage(init.Self, this); }
}
public class AffectedByPowerOutage : INotifyOwnerChanged, ISelectionBar, IPowerModifier, IDisable
public class AffectedByPowerOutage : ConditionalTrait<AffectedByPowerOutageInfo>, INotifyOwnerChanged, ISelectionBar, INotifyCreated, INotifyAddedToWorld
{
PowerManager playerPower;
ConditionManager conditionManager;
int token = ConditionManager.InvalidConditionToken;
public AffectedByPowerOutage(Actor self)
public AffectedByPowerOutage(Actor self, AffectedByPowerOutageInfo info)
: base(info)
{
playerPower = self.Owner.PlayerActor.Trait<PowerManager>();
}
void INotifyAddedToWorld.AddedToWorld(Actor self) { UpdateStatus(self); }
protected override void TraitEnabled(Actor self) { UpdateStatus(self); }
protected override void TraitDisabled(Actor self) { Revoke(self); }
void INotifyCreated.Created(Actor self)
{
conditionManager = self.TraitOrDefault<ConditionManager>();
}
float ISelectionBar.GetValue()
{
if (playerPower.PowerOutageRemainingTicks <= 0)
if (IsTraitDisabled || playerPower.PowerOutageRemainingTicks <= 0)
return 0;
return (float)playerPower.PowerOutageRemainingTicks / playerPower.PowerOutageTotalTicks;
@@ -44,19 +60,30 @@ namespace OpenRA.Mods.Common.Traits
bool ISelectionBar.DisplayWhenEmpty { get { return false; } }
int IPowerModifier.GetPowerModifier()
public void UpdateStatus(Actor self)
{
return playerPower.PowerOutageRemainingTicks > 0 ? 0 : 100;
if (!IsTraitDisabled && playerPower.PowerOutageRemainingTicks > 0)
Grant(self);
else
Revoke(self);
}
public bool Disabled
void Grant(Actor self)
{
get { return playerPower.PowerOutageRemainingTicks > 0; }
if (token == ConditionManager.InvalidConditionToken)
token = conditionManager.GrantCondition(self, Info.Condition);
}
void Revoke(Actor self)
{
if (token != ConditionManager.InvalidConditionToken)
token = conditionManager.RevokeCondition(self, token);
}
void INotifyOwnerChanged.OnOwnerChanged(Actor self, Player oldOwner, Player newOwner)
{
playerPower = newOwner.PlayerActor.Trait<PowerManager>();
UpdateStatus(self);
}
}
}

View File

@@ -9,6 +9,7 @@
*/
#endregion
using System;
using System.Collections.Generic;
using System.Linq;
using OpenRA.Traits;
@@ -24,7 +25,7 @@ namespace OpenRA.Mods.Common.Traits
public object Create(ActorInitializer init) { return new PowerManager(init.Self, this); }
}
public class PowerManager : ITick, ISync
public class PowerManager : ITick, ISync, IResolveOrder
{
readonly Actor self;
readonly PowerManagerInfo info;
@@ -140,11 +141,17 @@ namespace OpenRA.Mods.Common.Traits
void UpdatePowerOutageActors()
{
var actors = self.World.ActorsHavingTrait<AffectedByPowerOutage>()
.Where(a => !a.IsDead && a.IsInWorld && a.Owner == self.Owner);
var traitPairs = self.World.ActorsWithTrait<AffectedByPowerOutage>()
.Where(p => !p.Actor.IsDead && p.Actor.IsInWorld && p.Actor.Owner == self.Owner);
foreach (var a in actors)
UpdateActor(a);
foreach (var p in traitPairs)
p.Trait.UpdateStatus(p.Actor);
}
void IResolveOrder.ResolveOrder(Actor self, Order order)
{
if (devMode.Enabled && order.OrderString == "PowerOutage")
TriggerPowerOutage((int)order.ExtraData);
}
}
}

View File

@@ -21,9 +21,6 @@ namespace OpenRA.Mods.Common.Traits.Render
public readonly int Interval = 750;
[Desc("Pause when the actor is disabled. Deprecated. Use conditions instead.")]
public readonly bool PauseOnLowPower = false;
public override object Create(ActorInitializer init) { return new WithIdleAnimation(init.Self, this); }
}
@@ -48,8 +45,7 @@ namespace OpenRA.Mods.Common.Traits.Render
if (--ticks <= 0)
{
if (!(Info.PauseOnLowPower && self.IsDisabled()))
wsb.PlayCustomAnimation(self, Info.Sequences.Random(Game.CosmeticRandom), () => wsb.CancelCustomAnimation(self));
wsb.PlayCustomAnimation(self, Info.Sequences.Random(Game.CosmeticRandom), () => wsb.CancelCustomAnimation(self));
ticks = Info.Interval;
}
}

View File

@@ -18,7 +18,7 @@ using OpenRA.Traits;
namespace OpenRA.Mods.Common.Traits.Render
{
[Desc("Renders a decorative animation on units and buildings.")]
public class WithIdleOverlayInfo : ConditionalTraitInfo, IRenderActorPreviewSpritesInfo, Requires<RenderSpritesInfo>, Requires<BodyOrientationInfo>
public class WithIdleOverlayInfo : PausableConditionalTraitInfo, IRenderActorPreviewSpritesInfo, Requires<RenderSpritesInfo>, Requires<BodyOrientationInfo>
{
[Desc("Animation to play when the actor is created.")]
[SequenceReference] public readonly string StartSequence = null;
@@ -35,8 +35,6 @@ namespace OpenRA.Mods.Common.Traits.Render
[Desc("Custom palette is a player palette BaseName")]
public readonly bool IsPlayerPalette = false;
public readonly bool PauseOnLowPower = false;
public override object Create(ActorInitializer init) { return new WithIdleOverlay(init.Self, this); }
public IEnumerable<IActorPreview> RenderPreviewSprites(ActorPreviewInitializer init, RenderSpritesInfo rs, string image, int facings, PaletteReference p)
@@ -72,7 +70,7 @@ namespace OpenRA.Mods.Common.Traits.Render
}
}
public class WithIdleOverlay : ConditionalTrait<WithIdleOverlayInfo>, INotifyDamageStateChanged, INotifyBuildComplete, INotifySold, INotifyTransform
public class WithIdleOverlay : PausableConditionalTrait<WithIdleOverlayInfo>, INotifyDamageStateChanged, INotifyBuildComplete, INotifySold, INotifyTransform
{
readonly Animation overlay;
bool buildComplete;
@@ -84,8 +82,7 @@ namespace OpenRA.Mods.Common.Traits.Render
var body = self.Trait<BodyOrientation>();
buildComplete = !self.Info.HasTraitInfo<BuildingInfo>(); // always render instantly for units
overlay = new Animation(self.World, rs.GetImage(self),
() => (info.PauseOnLowPower && self.IsDisabled()) || !buildComplete);
overlay = new Animation(self.World, rs.GetImage(self), () => IsTraitPaused || !buildComplete);
if (info.StartSequence != null)
overlay.PlayThen(RenderSprites.NormalizeSequence(overlay, self.GetDamageState(), info.StartSequence),
() => overlay.PlayRepeating(RenderSprites.NormalizeSequence(overlay, self.GetDamageState(), info.Sequence)));

View File

@@ -14,32 +14,29 @@ using OpenRA.Traits;
namespace OpenRA.Mods.Common.Traits.Render
{
[Desc("Replaces the building animation when it rearms a unit.")]
public class WithRearmAnimationInfo : ITraitInfo, Requires<WithSpriteBodyInfo>
public class WithRearmAnimationInfo : ConditionalTraitInfo, Requires<WithSpriteBodyInfo>
{
[Desc("Sequence name to use")]
[SequenceReference] public readonly string Sequence = "active";
public readonly bool PauseOnLowPower = false;
public object Create(ActorInitializer init) { return new WithRearmAnimation(init.Self, this); }
public override object Create(ActorInitializer init) { return new WithRearmAnimation(init.Self, this); }
}
public class WithRearmAnimation : INotifyRearm, INotifyBuildComplete, INotifySold
public class WithRearmAnimation : ConditionalTrait<WithRearmAnimationInfo>, INotifyRearm, INotifyBuildComplete, INotifySold
{
readonly WithRearmAnimationInfo info;
readonly WithSpriteBody spriteBody;
bool buildComplete;
public WithRearmAnimation(Actor self, WithRearmAnimationInfo info)
: base(info)
{
this.info = info;
spriteBody = self.TraitOrDefault<WithSpriteBody>();
}
void INotifyRearm.Rearming(Actor self, Actor target)
{
if (buildComplete && spriteBody != null && !(info.PauseOnLowPower && self.IsDisabled()))
spriteBody.PlayCustomAnimation(self, info.Sequence, () => spriteBody.CancelCustomAnimation(self));
if (buildComplete && spriteBody != null && !IsTraitDisabled)
spriteBody.PlayCustomAnimation(self, Info.Sequence, () => spriteBody.CancelCustomAnimation(self));
}
void INotifyBuildComplete.BuildingComplete(Actor self)

View File

@@ -14,32 +14,29 @@ using OpenRA.Traits;
namespace OpenRA.Mods.Common.Traits.Render
{
[Desc("Replaces the building animation when it repairs a unit.")]
public class WithRepairAnimationInfo : ITraitInfo, Requires<WithSpriteBodyInfo>
public class WithRepairAnimationInfo : ConditionalTraitInfo, Requires<WithSpriteBodyInfo>
{
[Desc("Sequence name to use")]
[SequenceReference] public readonly string Sequence = "active";
public readonly bool PauseOnLowPower = false;
public object Create(ActorInitializer init) { return new WithRepairAnimation(init.Self, this); }
public override object Create(ActorInitializer init) { return new WithRepairAnimation(init.Self, this); }
}
public class WithRepairAnimation : INotifyRepair, INotifyBuildComplete, INotifySold
public class WithRepairAnimation : ConditionalTrait<WithRepairAnimationInfo>, INotifyRepair, INotifyBuildComplete, INotifySold
{
readonly WithRepairAnimationInfo info;
readonly WithSpriteBody spriteBody;
bool buildComplete;
public WithRepairAnimation(Actor self, WithRepairAnimationInfo info)
: base(info)
{
this.info = info;
spriteBody = self.TraitOrDefault<WithSpriteBody>();
}
void INotifyRepair.Repairing(Actor self, Actor target)
{
if (buildComplete && spriteBody != null && !(info.PauseOnLowPower && self.IsDisabled()))
spriteBody.PlayCustomAnimation(self, info.Sequence, () => spriteBody.CancelCustomAnimation(self));
if (buildComplete && spriteBody != null && !IsTraitDisabled)
spriteBody.PlayCustomAnimation(self, Info.Sequence, () => spriteBody.CancelCustomAnimation(self));
}
void INotifyBuildComplete.BuildingComplete(Actor self)

View File

@@ -16,7 +16,7 @@ using OpenRA.Traits;
namespace OpenRA.Mods.Common.Traits.Render
{
[Desc("Displays an overlay when the building is being repaired by the player.")]
public class WithRepairOverlayInfo : ITraitInfo, Requires<RenderSpritesInfo>, Requires<BodyOrientationInfo>
public class WithRepairOverlayInfo : PausableConditionalTraitInfo, Requires<RenderSpritesInfo>, Requires<BodyOrientationInfo>
{
[Desc("Sequence name to use")]
[SequenceReference] public readonly string Sequence = "active";
@@ -30,30 +30,28 @@ namespace OpenRA.Mods.Common.Traits.Render
[Desc("Custom palette is a player palette BaseName")]
public readonly bool IsPlayerPalette = false;
public readonly bool PauseOnLowPower = false;
public object Create(ActorInitializer init) { return new WithRepairOverlay(init.Self, this); }
public override object Create(ActorInitializer init) { return new WithRepairOverlay(init.Self, this); }
}
public class WithRepairOverlay : INotifyDamageStateChanged, INotifyBuildComplete, INotifySold, INotifyRepair
public class WithRepairOverlay : PausableConditionalTrait<WithRepairOverlayInfo>, INotifyDamageStateChanged, INotifyBuildComplete, INotifySold, INotifyRepair
{
readonly Animation overlay;
bool buildComplete;
bool visible;
public WithRepairOverlay(Actor self, WithRepairOverlayInfo info)
: base(info)
{
var rs = self.Trait<RenderSprites>();
var body = self.Trait<BodyOrientation>();
buildComplete = !self.Info.HasTraitInfo<BuildingInfo>(); // always render instantly for units
overlay = new Animation(self.World, rs.GetImage(self),
() => info.PauseOnLowPower && self.IsDisabled());
overlay = new Animation(self.World, rs.GetImage(self), () => IsTraitPaused);
overlay.PlayThen(info.Sequence, () => visible = false);
var anim = new AnimationWithOffset(overlay,
() => body.LocalToWorld(info.Offset.Rotate(body.QuantizeOrientation(self, self.Orientation))),
() => !visible || !buildComplete,
() => IsTraitDisabled || !visible || !buildComplete,
p => RenderUtils.ZOffsetFromCenter(self, p, 1));
rs.Add(anim, info.Palette, info.IsPlayerPalette);

View File

@@ -13,7 +13,7 @@ using OpenRA.Traits;
namespace OpenRA.Mods.Common.Traits
{
public abstract class SupportPowerInfo : ConditionalTraitInfo
public abstract class SupportPowerInfo : PausableConditionalTraitInfo
{
[Desc("Measured in seconds.")]
public readonly int ChargeTime = 0;
@@ -76,7 +76,7 @@ namespace OpenRA.Mods.Common.Traits
public SupportPowerInfo() { OrderName = GetType().Name + "Order"; }
}
public class SupportPower : ConditionalTrait<SupportPowerInfo>
public class SupportPower : PausableConditionalTrait<SupportPowerInfo>
{
public readonly Actor Self;
readonly SupportPowerInfo info;

View File

@@ -179,11 +179,6 @@ namespace OpenRA.Mods.Common.Traits
prereqsAvailable = available;
}
static bool InstanceDisabled(SupportPower sp)
{
return sp.Self.IsDisabled();
}
bool notifiedCharging;
bool notifiedReady;
public void Tick()
@@ -192,7 +187,7 @@ namespace OpenRA.Mods.Common.Traits
if (!instancesEnabled)
RemainingTime = TotalTime;
Active = !Disabled && Instances.Any(i => !i.Self.IsDisabled());
Active = !Disabled && Instances.Any(i => !i.IsTraitPaused);
if (!Active)
return;
@@ -224,7 +219,7 @@ namespace OpenRA.Mods.Common.Traits
if (!Ready)
return;
var power = Instances.FirstOrDefault();
var power = Instances.FirstOrDefault(i => !i.IsTraitPaused);
if (power == null)
return;
@@ -236,7 +231,7 @@ namespace OpenRA.Mods.Common.Traits
if (!Ready)
return;
var power = Instances.Where(i => !InstanceDisabled(i))
var power = Instances.Where(i => !i.IsTraitPaused)
.MinByOrDefault(a =>
{
if (a.Self.OccupiesSpace == null)

View File

@@ -601,6 +601,40 @@ namespace OpenRA.Mods.Common.UtilityCommands
if (node.Key == "SoundFile" && parent.Key.StartsWith("AmbientSound", StringComparison.Ordinal))
RenameNodeKey(node, "SoundFiles");
// PauseOnLowPower property has been replaced with PauseOnCondition/RequiresCondition
if (engineVersion < 20170501)
{
if (node.Key.StartsWith("WithRearmAnimation", StringComparison.Ordinal) || node.Key.StartsWith("WithRepairAnimation", StringComparison.Ordinal)
|| node.Key.StartsWith("WithIdleAnimation", StringComparison.Ordinal))
{
var pauseOnLowPowerNode = node.Value.Nodes.FirstOrDefault(n => n.Key == "PauseOnLowPower");
if (pauseOnLowPowerNode != null)
{
node.Value.Nodes.Remove(pauseOnLowPowerNode);
Console.WriteLine("PauseOnLowPower has been removed from {0}; use RequiresCondition instead.".F(node.Key));
}
}
else if (node.Key.StartsWith("WithIdleOverlay", StringComparison.Ordinal) || node.Key.StartsWith("WithRepairOverlay", StringComparison.Ordinal))
{
var pauseOnLowPowerNode = node.Value.Nodes.FirstOrDefault(n => n.Key == "PauseOnLowPower");
if (pauseOnLowPowerNode != null)
{
node.Value.Nodes.Remove(pauseOnLowPowerNode);
Console.WriteLine("PauseOnLowPower has been removed from {0}; use PauseOnCondition or RequiresCondition instead.".F(node.Key));
}
}
else if (node.Key.StartsWith("AffectedByPowerOutage", StringComparison.Ordinal))
{
Console.WriteLine("Actor {0} has AffectedByPowerOutage; use the Condition property to apply its effects.".F(node.Key));
}
else if (node.Key.StartsWith("IonCannonPower", StringComparison.Ordinal) || node.Key.StartsWith("ProduceActorPower", StringComparison.Ordinal)
|| node.Key.StartsWith("NukePower", StringComparison.Ordinal) || node.Key.StartsWith("AttackOrderPower", StringComparison.Ordinal)
|| node.Key.StartsWith("GpsPower", StringComparison.Ordinal))
{
Console.WriteLine("{0} requires PauseOnCondition for pausing.".F(node.Key));
}
}
UpgradeActorRules(modData, engineVersion, ref node.Value.Nodes, node, depth + 1);
}