diff --git a/OpenRA.Mods.Common/Traits/Render/Hovers.cs b/OpenRA.Mods.Common/Traits/Render/Hovers.cs index f930b25d01..1ca4ff2afd 100644 --- a/OpenRA.Mods.Common/Traits/Render/Hovers.cs +++ b/OpenRA.Mods.Common/Traits/Render/Hovers.cs @@ -26,28 +26,65 @@ namespace OpenRA.Mods.Common.Traits.Render public readonly int MinHoveringAltitude = 0; + [Desc("Amount of ticks it takes to reach OffsetModifier.")] + public readonly int Ticks = 25; + + [Desc("Amount of ticks it takes to fall to the ground from the highest point when disabled.")] + public readonly int FallTicks = 12; + + [Desc("Amount of ticks it takes to rise from the ground to InitialHeight.")] + public readonly int RiseTicks = 17; + + public readonly int InitialHeight = 384; + public override object Create(ActorInitializer init) { return new Hovers(this, init.Self); } } - public class Hovers : ConditionalTrait, IRenderModifier + public class Hovers : ConditionalTrait, IRenderModifier, ITick { readonly HoversInfo info; + readonly int stepPercentage; + readonly int fallTickHeight; + + int ticks = 0; + WVec worldVisualOffset = WVec.Zero; public Hovers(HoversInfo info, Actor self) : base(info) { this.info = info; + this.stepPercentage = 256 / info.Ticks; + this.fallTickHeight = (info.InitialHeight + info.OffsetModifier) / info.FallTicks; + } + + void ITick.Tick(Actor self) + { + if (IsTraitDisabled) + { + if (worldVisualOffset.Z < 0) + return; + + var fallTicks = worldVisualOffset.Z / fallTickHeight - 1; + worldVisualOffset = new WVec(0, 0, fallTickHeight * fallTicks); + } + else + ticks++; } IEnumerable IRenderModifier.ModifyRender(Actor self, WorldRenderer wr, IEnumerable r) { - if (self.World.Paused || IsTraitDisabled) - return r; + if (!IsTraitDisabled) + { + var visualOffset = self.World.Map.DistanceAboveTerrain(self.CenterPosition).Length >= info.MinHoveringAltitude + ? new WAngle(ticks % (info.Ticks * 4) * stepPercentage).Sin() : 0; + var currentHeight = info.OffsetModifier * visualOffset / 1024 + info.InitialHeight; - var visualOffset = self.World.Map.DistanceAboveTerrain(self.CenterPosition).Length >= info.MinHoveringAltitude - ? (int)Math.Abs((self.ActorID + Game.LocalTick) / 5 % 4 - 1) - 1 - : 0; - var worldVisualOffset = new WVec(0, 0, info.OffsetModifier * visualOffset); + // This part rises the actor up from disabled state + if (worldVisualOffset.Z < currentHeight) + currentHeight = Math.Min(worldVisualOffset.Z + info.InitialHeight / info.RiseTicks, currentHeight); + + worldVisualOffset = new WVec(0, 0, currentHeight); + } return r.Select(a => a.OffsetBy(worldVisualOffset)); } diff --git a/mods/ts/rules/gdi-vehicles.yaml b/mods/ts/rules/gdi-vehicles.yaml index 34415ba2f4..78d93e6ca9 100644 --- a/mods/ts/rules/gdi-vehicles.yaml +++ b/mods/ts/rules/gdi-vehicles.yaml @@ -67,6 +67,8 @@ HVR: Mobile: Speed: 99 Locomotor: hover + Selectable: + Bounds: 40,24,0,-10 Health: HP: 23000 Armor: @@ -86,6 +88,8 @@ HVR: PauseOnCondition: empdisable WithVoxelTurret: Hovers: + RequiresCondition: !empdisable + OffsetModifier: 64 LeavesTrails: RequiresCondition: !inside-tunnel Image: wake