diff --git a/OpenRA.Mods.RA/Traits/Chronoshiftable.cs b/OpenRA.Mods.RA/Traits/Chronoshiftable.cs index b545740166..43246ea059 100644 --- a/OpenRA.Mods.RA/Traits/Chronoshiftable.cs +++ b/OpenRA.Mods.RA/Traits/Chronoshiftable.cs @@ -19,21 +19,29 @@ namespace OpenRA.Mods.RA.Traits [Desc("Can be teleported via Chronoshift power.")] public class ChronoshiftableInfo : ITraitInfo { + [Desc("Should the actor die instead of being teleported?")] public readonly bool ExplodeInstead = false; public readonly string ChronoshiftSound = "chrono2.aud"; + [Desc("Should the actor return to its location after the chronoshift weared out?.")] + public readonly bool ReturnToOrigin = true; + + [Desc("The color the bar of the 'return-to-origin' logic has.")] + public readonly Color TimeBarColor = Color.White; + public object Create(ActorInitializer init) { return new Chronoshiftable(init, this); } } - public class Chronoshiftable : ITick, ISync, ISelectionBar, IDeathActorInitModifier + public class Chronoshiftable : ITick, ISync, ISelectionBar, IDeathActorInitModifier, INotifyCreated { readonly ChronoshiftableInfo info; readonly Actor self; Actor chronosphere; bool killCargo; int duration; + IPositionable iPositionable; - // Return-to-sender logic + // Return-to-origin logic [Sync] public CPos Origin; [Sync] public int ReturnTicks = 0; @@ -54,7 +62,7 @@ namespace OpenRA.Mods.RA.Traits public void Tick(Actor self) { - if (ReturnTicks <= 0) + if (!info.ReturnToOrigin || ReturnTicks <= 0) return; // Return to original location @@ -65,28 +73,33 @@ namespace OpenRA.Mods.RA.Traits } } + public void Created(Actor self) + { + iPositionable = self.TraitOrDefault(); + } + // Can't be used in synced code, except with ignoreVis. public virtual bool CanChronoshiftTo(Actor self, CPos targetLocation) { // TODO: Allow enemy units to be chronoshifted into bad terrain to kill them - return self.Info.HasTraitInfo() && self.Trait().CanEnterCell(targetLocation); + return iPositionable != null && iPositionable.CanEnterCell(targetLocation); } public virtual bool Teleport(Actor self, CPos targetLocation, int duration, bool killCargo, Actor chronosphere) { - // some things appear chronoshiftable, but instead they just die. + // Some things appear chronoshiftable, but instead they just die. if (info.ExplodeInstead) { self.World.AddFrameEndTask(w => { - // damage is inflicted by the chronosphere + // Damage is inflicted by the chronosphere if (!self.Disposed) self.InflictDamage(chronosphere, int.MaxValue, null); }); return true; } - // Set up return-to-sender info + // Set up return-to-origin info Origin = self.Location; ReturnTicks = duration; this.duration = duration; @@ -103,19 +116,23 @@ namespace OpenRA.Mods.RA.Traits // Show the remaining time as a bar public float GetValue() { - // otherwise an empty bar is rendered all the time + if (!info.ReturnToOrigin) + return 0f; + + // Otherwise an empty bar is rendered all the time if (ReturnTicks == 0 || !self.Owner.IsAlliedWith(self.World.RenderPlayer)) return 0f; return (float)ReturnTicks / duration; } - public Color GetColor() { return Color.White; } + public Color GetColor() { return info.TimeBarColor; } public void ModifyDeathActorInit(Actor self, TypeDictionary init) { - if (ReturnTicks <= 0) + if (!info.ReturnToOrigin || ReturnTicks <= 0) return; + init.Add(new ChronoshiftOriginInit(Origin)); init.Add(new ChronoshiftReturnInit(ReturnTicks)); if (chronosphere != self)