From 29009fe3a402d57a3ea502e5055e7b5555222480 Mon Sep 17 00:00:00 2001 From: Paul Chote Date: Sun, 21 Jul 2013 13:12:42 +1200 Subject: [PATCH] Allow husks to chronoshift and return to their parent actors location. --- OpenRA.Mods.RA/Chronoshiftable.cs | 66 +++++++++++++++++++++---------- OpenRA.Mods.RA/LeavesHusk.cs | 23 ++++++----- mods/ra/rules/defaults.yaml | 1 + 3 files changed, 60 insertions(+), 30 deletions(-) diff --git a/OpenRA.Mods.RA/Chronoshiftable.cs b/OpenRA.Mods.RA/Chronoshiftable.cs index 2c70fffd64..da7311defe 100755 --- a/OpenRA.Mods.RA/Chronoshiftable.cs +++ b/OpenRA.Mods.RA/Chronoshiftable.cs @@ -9,6 +9,7 @@ #endregion using System.Drawing; +using OpenRA.FileFormats; using OpenRA.Mods.RA.Activities; using OpenRA.Traits; @@ -19,38 +20,43 @@ namespace OpenRA.Mods.RA public readonly bool ExplodeInstead = false; public readonly string ChronoshiftSound = "chrono2.aud"; - public object Create(ActorInitializer init) { return new Chronoshiftable(this); } + public object Create(ActorInitializer init) { return new Chronoshiftable(init, this); } } public class Chronoshiftable : ITick, ISync, ISelectionBar { - // Return-to-sender logic - [Sync] CPos chronoshiftOrigin; - [Sync] int chronoshiftReturnTicks = 0; + readonly ChronoshiftableInfo info; Actor chronosphere; bool killCargo; - int TotalTicks; - readonly ChronoshiftableInfo info; + int duration; - public Chronoshiftable(ChronoshiftableInfo info) + // Return-to-sender logic + [Sync] public CPos Origin; + [Sync] public int ReturnTicks = 0; + + public Chronoshiftable(ActorInitializer init, ChronoshiftableInfo info) { this.info = info; + + if (init.Contains()) + ReturnTicks = init.Get(); + + if (init.Contains()) + Origin = init.Get(); } public void Tick(Actor self) { - if (chronoshiftReturnTicks <= 0) + if (ReturnTicks <= 0) return; - if (chronoshiftReturnTicks > 0) - chronoshiftReturnTicks--; - // Return to original location - if (chronoshiftReturnTicks == 0) + if (--ReturnTicks == 0) { self.CancelActivity(); + // TODO: need a new Teleport method that will move to the closest available cell - self.QueueActivity(new Teleport(chronosphere, chronoshiftOrigin, killCargo, info.ChronoshiftSound)); + self.QueueActivity(new Teleport(chronosphere, Origin, killCargo, info.ChronoshiftSound)); } } @@ -58,25 +64,27 @@ namespace OpenRA.Mods.RA public virtual bool CanChronoshiftTo(Actor self, CPos targetLocation) { // TODO: Allow enemy units to be chronoshifted into bad terrain to kill them - return (self.HasTrait() && self.Trait().CanEnterCell(targetLocation)); + return self.HasTrait() && self.Trait().CanEnterCell(targetLocation); } public virtual bool Teleport(Actor self, CPos targetLocation, int duration, bool killCargo, Actor chronosphere) { - if (info.ExplodeInstead) // 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 - if (!self.Destroyed) self.InflictDamage(chronosphere, int.MaxValue, null); + if (!self.Destroyed) + self.InflictDamage(chronosphere, int.MaxValue, null); }); return true; } /// Set up return-to-sender info - chronoshiftOrigin = self.Location; - chronoshiftReturnTicks = duration; - TotalTicks = duration; + Origin = self.Location; + ReturnTicks = duration; + this.duration = duration; this.chronosphere = chronosphere; this.killCargo = killCargo; @@ -90,11 +98,27 @@ namespace OpenRA.Mods.RA // Show the remaining time as a bar public float GetValue() { - if (chronoshiftReturnTicks == 0) // otherwise an empty bar is rendered all the time + if (ReturnTicks == 0) // otherwise an empty bar is rendered all the time return 0f; - return (float)chronoshiftReturnTicks / TotalTicks; + return (float)ReturnTicks / duration; } + public Color GetColor() { return Color.White; } } + + public class ChronoshiftReturnInit : IActorInit + { + [FieldFromYamlKey] readonly int value = 0; + public ChronoshiftReturnInit() { } + public ChronoshiftReturnInit(int init) { value = init; } + public int Value(World world) { return value; } + } + + public class ChronoshiftOriginInit : IActorInit + { + [FieldFromYamlKey] readonly CPos value; + public ChronoshiftOriginInit(CPos init) { value = init; } + public CPos Value(World world) { return value; } + } } diff --git a/OpenRA.Mods.RA/LeavesHusk.cs b/OpenRA.Mods.RA/LeavesHusk.cs index 7b04b1d9c2..8dce4cdb42 100644 --- a/OpenRA.Mods.RA/LeavesHusk.cs +++ b/OpenRA.Mods.RA/LeavesHusk.cs @@ -21,16 +21,14 @@ namespace OpenRA.Mods.RA [ActorReference] public readonly string HuskActor = null; - public object Create( ActorInitializer init ) { return new LeavesHusk(this); } + public object Create(ActorInitializer init) { return new LeavesHusk(this); } } public class LeavesHusk : INotifyKilled { - LeavesHuskInfo Info; - public LeavesHusk(LeavesHuskInfo info) - { - Info = info; - } + LeavesHuskInfo info; + + public LeavesHusk(LeavesHuskInfo info) { this.info = info; } public void Killed(Actor self, AttackInfo e) { @@ -58,19 +56,26 @@ namespace OpenRA.Mods.RA var facing = self.TraitOrDefault(); if (facing != null) - td.Add(new FacingInit( facing.Facing )); + td.Add(new FacingInit(facing.Facing)); // TODO: This will only take the first turret if there are multiple // This isn't a problem with the current units, but may be a problem for mods var turreted = self.TraitsImplementing().FirstOrDefault(); if (turreted != null) - td.Add( new TurretFacingInit(turreted.turretFacing) ); + td.Add(new TurretFacingInit(turreted.turretFacing)); + + var chronoshiftable = self.TraitOrDefault(); + if (chronoshiftable != null && chronoshiftable.ReturnTicks > 0) + { + td.Add(new ChronoshiftOriginInit(chronoshiftable.Origin)); + td.Add(new ChronoshiftReturnInit(chronoshiftable.ReturnTicks)); + } var huskActor = self.TraitsImplementing() .Select(ihm => ihm.HuskActor(self)) .FirstOrDefault(a => a != null); - w.CreateActor(huskActor ?? Info.HuskActor, td); + w.CreateActor(huskActor ?? info.HuskActor, td); }); } } diff --git a/mods/ra/rules/defaults.yaml b/mods/ra/rules/defaults.yaml index d43f5c585e..e5259b6b02 100644 --- a/mods/ra/rules/defaults.yaml +++ b/mods/ra/rules/defaults.yaml @@ -386,6 +386,7 @@ Types:Husk BelowUnits: BodyOrientation: + Chronoshiftable: ^HelicopterHusk: Inherits: ^Husk