diff --git a/OpenRA.Game/ActorInitializer.cs b/OpenRA.Game/ActorInitializer.cs index 9ccf316185..7e5c33554a 100755 --- a/OpenRA.Game/ActorInitializer.cs +++ b/OpenRA.Game/ActorInitializer.cs @@ -50,7 +50,7 @@ namespace OpenRA { T Value( World world ); } - + public class FacingInit : IActorInit { [FieldFromYamlKey] @@ -68,7 +68,7 @@ namespace OpenRA return value; } } - + public class AltitudeInit : IActorInit { [FieldFromYamlKey] @@ -105,6 +105,24 @@ namespace OpenRA } } + public class CenterLocationInit : IActorInit + { + [FieldFromYamlKey] + public readonly int2 value = int2.Zero; + + public CenterLocationInit() { } + + public CenterLocationInit( int2 init ) + { + value = init; + } + + public int2 Value( World world ) + { + return value; + } + } + public class OwnerInit : IActorInit { [FieldFromYamlKey] diff --git a/OpenRA.Mods.RA/Husk.cs b/OpenRA.Mods.RA/Husk.cs index 8801be4920..68e599be3d 100644 --- a/OpenRA.Mods.RA/Husk.cs +++ b/OpenRA.Mods.RA/Husk.cs @@ -9,8 +9,10 @@ #endregion using System.Collections.Generic; -using OpenRA.Traits; using OpenRA.FileFormats; +using OpenRA.Traits; +using OpenRA.Mods.RA.Move; +using OpenRA.Traits.Activities; namespace OpenRA.Mods.RA { @@ -23,7 +25,10 @@ namespace OpenRA.Mods.RA { [Sync] int2 location; - + + [Sync] + public int2 PxPosition { get; set; } + [Sync] public int Facing { get; set; } public int ROT { get { return 0; } } @@ -31,13 +36,69 @@ namespace OpenRA.Mods.RA public Husk(ActorInitializer init) { - this.location = init.Get(); - this.Facing = init.Contains() ? init.Get() : 128; + var self = init.self; + location = init.Get(); + PxPosition = init.Get(); + Facing = init.Contains() ? init.Get() : 128; + + var speed = init.Contains() ? init.Get() : 0; + if (speed > 0) + { + var to = Util.CenterOfCell(location); + var length = (int)((to - PxPosition).Length * 3 / speed); + self.QueueActivity(new DragHusk(PxPosition, to, length)); + } } public int2 TopLeft { get { return location; } } public IEnumerable> OccupiedCells() { yield return Pair.New(TopLeft, SubCell.FullCell); } - public int2 PxPosition { get { return Util.CenterOfCell( location ); } } + + class DragHusk : Activity + { + int2 endLocation; + int2 startLocation; + int length; + + public DragHusk(int2 start, int2 end, int length) + { + startLocation = start; + endLocation = end; + this.length = length; + } + + int ticks = 0; + public override Activity Tick( Actor self ) + { + var husk = self.Trait(); + husk.PxPosition = int2.Lerp(startLocation, endLocation, ticks, length - 1); + + if (++ticks >= length) + return NextActivity; + + return this; + } + + public override IEnumerable GetTargets( Actor self ) { yield break; } + public override void Cancel( Actor self ) { } + } + } + + public class HuskSpeedInit : IActorInit + { + [FieldFromYamlKey] + public readonly int value = 0; + + public HuskSpeedInit() { } + + public HuskSpeedInit( int init ) + { + value = init; + } + + public int Value( World world ) + { + return value; + } } } diff --git a/OpenRA.Mods.RA/LeavesHusk.cs b/OpenRA.Mods.RA/LeavesHusk.cs index 621756c8cc..2fbbeb1460 100644 --- a/OpenRA.Mods.RA/LeavesHusk.cs +++ b/OpenRA.Mods.RA/LeavesHusk.cs @@ -8,8 +8,9 @@ */ #endregion -using OpenRA.Traits; using OpenRA.FileFormats; +using OpenRA.Traits; +using OpenRA.Mods.RA.Move; namespace OpenRA.Mods.RA { @@ -24,24 +25,30 @@ namespace OpenRA.Mods.RA public void Killed(Actor self, AttackInfo e) { self.World.AddFrameEndTask(w => + { + var info = self.Info.Traits.Get(); + var td = new TypeDictionary() { - var info = self.Info.Traits.Get(); - var td = new TypeDictionary - { - new LocationInit( self.Location ), - new OwnerInit( self.Owner ), - new SkipMakeAnimsInit() - }; - - if (self.HasTrait()) - td.Add(new FacingInit( self.Trait().Facing )); + new LocationInit( self.Location ), + new CenterLocationInit(self.CenterLocation), + new OwnerInit( self.Owner ), + new SkipMakeAnimsInit() + }; - var husk = w.CreateActor(info.HuskActor, td); - var turreted = self.TraitOrDefault(); - if (turreted != null) - foreach (var p in husk.TraitsImplementing()) - p.InitialFacing = turreted.turretFacing; - }); + if (self.HasTrait()) + td.Add(new FacingInit( self.Trait().Facing )); + + // Allows the husk to drag to its final position + var mobile = self.TraitOrDefault(); + if (mobile != null) + td.Add(new HuskSpeedInit(mobile.MovementSpeedForCell(self, self.Location))); + + var husk = w.CreateActor(info.HuskActor, td); + var turreted = self.TraitOrDefault(); + if (turreted != null) + foreach (var p in husk.TraitsImplementing()) + p.InitialFacing = turreted.turretFacing; + }); } } }