From c3f04cc32e520ff2904b1c1493c7cf7093856da4 Mon Sep 17 00:00:00 2001 From: Paul Chote Date: Sun, 21 Jul 2013 13:42:25 +1200 Subject: [PATCH] Convert non-aircraft positioning to world coords. This removes the incomplete and unused hover code on Mobile, which would be more trouble that it is currently worth to carry over. --- OpenRA.FileFormats/WVec.cs | 1 + OpenRA.Game/Actor.cs | 5 ++-- OpenRA.Game/Traits/TraitsInterfaces.cs | 5 +--- OpenRA.Game/Traits/Waypoint.cs | 5 +--- OpenRA.Mods.RA/Activities/Leap.cs | 2 +- OpenRA.Mods.RA/Air/Aircraft.cs | 4 +-- OpenRA.Mods.RA/Air/EjectOnDeath.cs | 12 +++++---- OpenRA.Mods.RA/Armament.cs | 6 ++--- OpenRA.Mods.RA/Buildings/Building.cs | 10 +++---- OpenRA.Mods.RA/Cargo.cs | 9 +++---- OpenRA.Mods.RA/CarpetBomb.cs | 8 +++--- OpenRA.Mods.RA/Crate.cs | 36 ++++++++++++-------------- OpenRA.Mods.RA/Effects/Missile.cs | 6 ++--- OpenRA.Mods.RA/Husk.cs | 3 +-- OpenRA.Mods.RA/Mine.cs | 6 ++--- OpenRA.Mods.RA/Move/Mobile.cs | 26 +++++++------------ OpenRA.Mods.RA/Move/Move.cs | 9 ------- OpenRA.Mods.RA/Render/WithRotor.cs | 2 +- OpenRA.Mods.RA/Render/WithShadow.cs | 6 ++--- mods/d2k/rules/aircraft.yaml | 2 +- 20 files changed, 67 insertions(+), 96 deletions(-) diff --git a/OpenRA.FileFormats/WVec.cs b/OpenRA.FileFormats/WVec.cs index ab96bea054..72b2df78b9 100644 --- a/OpenRA.FileFormats/WVec.cs +++ b/OpenRA.FileFormats/WVec.cs @@ -39,6 +39,7 @@ namespace OpenRA public long LengthSquared { get { return (long)X * X + (long)Y * Y + (long)Z * Z; } } public int Length { get { return (int)Math.Sqrt(LengthSquared); } } public long HorizontalLengthSquared { get { return (long)X * X + (long)Y * Y; } } + public int HorizontalLength { get { return (int)Math.Sqrt(HorizontalLengthSquared); } } public WVec Rotate(WRot rot) { diff --git a/OpenRA.Game/Actor.cs b/OpenRA.Game/Actor.cs index bb0a5413ad..dc77cd1e13 100755 --- a/OpenRA.Game/Actor.cs +++ b/OpenRA.Game/Actor.cs @@ -135,10 +135,11 @@ namespace OpenRA var ios = occupySpace.Value; if (ios != null) { - loc -= new PVecInt(0, ios.Altitude); + var altitude = ios.CenterPosition.Z * Game.CellSize / 1024; + loc -= new PVecInt(0, altitude); if (useAltitude) - size = new PVecInt(size.X, size.Y + ios.Altitude); + size = new PVecInt(size.X, size.Y + altitude); } return new Rectangle(loc.X, loc.Y, size.X, size.Y); diff --git a/OpenRA.Game/Traits/TraitsInterfaces.cs b/OpenRA.Game/Traits/TraitsInterfaces.cs index 8b0f1a404d..e979a7ce14 100755 --- a/OpenRA.Game/Traits/TraitsInterfaces.cs +++ b/OpenRA.Game/Traits/TraitsInterfaces.cs @@ -97,15 +97,12 @@ namespace OpenRA.Traits public interface IVisibilityModifier { bool IsVisible(Actor self, Player byPlayer); } public interface IRadarColorModifier { Color RadarColorOverride(Actor self); } + public interface IOccupySpaceInfo { } public interface IOccupySpace { WPos CenterPosition { get; } CPos TopLeft { get; } IEnumerable> OccupiedCells(); - - // TODO: We shouldn't expose the setter here - // This will be going away soon, so isn't a big deal - int Altitude { get; set; } } public static class IOccupySpaceExts diff --git a/OpenRA.Game/Traits/Waypoint.cs b/OpenRA.Game/Traits/Waypoint.cs index 0223fa9fda..2ea8e2a381 100644 --- a/OpenRA.Game/Traits/Waypoint.cs +++ b/OpenRA.Game/Traits/Waypoint.cs @@ -13,7 +13,7 @@ using OpenRA.FileFormats; namespace OpenRA.Traits { - class WaypointInfo : ITraitInfo + class WaypointInfo : ITraitInfo, IOccupySpaceInfo { public object Create( ActorInitializer init ) { return new Waypoint( init ); } } @@ -28,10 +28,7 @@ namespace OpenRA.Traits } public CPos TopLeft { get { return location; } } - public IEnumerable> OccupiedCells() { yield break; } public WPos CenterPosition { get { return location.CenterPosition; } } - public PPos PxPosition { get { return Util.CenterOfCell(location); } } - public int Altitude { get { return 0; } set { } } } } diff --git a/OpenRA.Mods.RA/Activities/Leap.cs b/OpenRA.Mods.RA/Activities/Leap.cs index 2d403cece1..9ab86d9335 100644 --- a/OpenRA.Mods.RA/Activities/Leap.cs +++ b/OpenRA.Mods.RA/Activities/Leap.cs @@ -55,7 +55,7 @@ namespace OpenRA.Mods.RA.Activities if (ticks == 0 && IsCanceled) return NextActivity; - mobile.AdjustPxPosition(self, PPos.FromWPosHackZ(WPos.LerpQuadratic(from, to, angle, ++ticks, length))); + mobile.SetVisualPosition(self, WPos.LerpQuadratic(from, to, angle, ++ticks, length)); if (ticks >= length) { mobile.SetLocation(mobile.toCell, mobile.toSubCell, mobile.toCell, mobile.toSubCell); diff --git a/OpenRA.Mods.RA/Air/Aircraft.cs b/OpenRA.Mods.RA/Air/Aircraft.cs index 9a1ad6394c..c4a454ef14 100755 --- a/OpenRA.Mods.RA/Air/Aircraft.cs +++ b/OpenRA.Mods.RA/Air/Aircraft.cs @@ -20,7 +20,7 @@ using OpenRA.Traits; namespace OpenRA.Mods.RA.Air { - public class AircraftInfo : ITraitInfo, IFacingInfo, UsesInit, UsesInit, UsesInit + public class AircraftInfo : ITraitInfo, IFacingInfo, IOccupySpaceInfo, UsesInit, UsesInit, UsesInit { public readonly int CruiseAltitude = 30; [ActorReference] @@ -78,7 +78,7 @@ namespace OpenRA.Mods.RA.Air public Actor GetActorBelow() { - if (self.Trait().Altitude != 0) + if (Altitude != 0) return null; // not on the ground. return self.World.FindActorsInBox(self.CenterPosition, self.CenterPosition) diff --git a/OpenRA.Mods.RA/Air/EjectOnDeath.cs b/OpenRA.Mods.RA/Air/EjectOnDeath.cs index 24e357239b..e6d213c0e6 100644 --- a/OpenRA.Mods.RA/Air/EjectOnDeath.cs +++ b/OpenRA.Mods.RA/Air/EjectOnDeath.cs @@ -20,6 +20,7 @@ namespace OpenRA.Mods.RA public readonly string PilotActor = "E1"; public readonly int SuccessRate = 50; public readonly string ChuteSound = "chute1.aud"; + public readonly WRange MinimumEjectHeight = new WRange(427); } public class EjectOnDeath : INotifyKilled @@ -29,14 +30,15 @@ namespace OpenRA.Mods.RA var info = self.Info.Traits.Get(); var pilot = self.World.CreateActor(false, info.PilotActor.ToLowerInvariant(), new TypeDictionary { new OwnerInit(self.Owner) }); - var r = self.World.SharedRandom.Next(1, 100); - var aircraft = self.Trait(); - if (IsSuitableCell(pilot, self.Location) && r > 100 - info.SuccessRate && aircraft.Altitude > 10 + var r = self.World.SharedRandom.Next(1, 100); + var cp = self.CenterPosition; + + if (IsSuitableCell(pilot, self.Location) && r > 100 - info.SuccessRate && cp.Z > info.MinimumEjectHeight.Range && self.Owner.WinState != WinState.Lost) { - self.World.AddFrameEndTask(w => w.Add(new Parachute(pilot, self.CenterPosition))); - Sound.Play(info.ChuteSound, self.CenterPosition); + self.World.AddFrameEndTask(w => w.Add(new Parachute(pilot, cp))); + Sound.Play(info.ChuteSound, cp); } else pilot.Destroy(); diff --git a/OpenRA.Mods.RA/Armament.cs b/OpenRA.Mods.RA/Armament.cs index 5bee9aaa0a..7eb5faf061 100755 --- a/OpenRA.Mods.RA/Armament.cs +++ b/OpenRA.Mods.RA/Armament.cs @@ -120,8 +120,6 @@ namespace OpenRA.Mods.RA return; var barrel = Barrels[Burst % Barrels.Length]; - var destios = target.IsActor ? target.Actor.TraitOrDefault() : null; - var muzzlePosition = self.CenterPosition + MuzzleOffset(self, barrel); var legacyMuzzlePosition = PPos.FromWPos(muzzlePosition); var legacyMuzzleAltitude = Game.CellSize*muzzlePosition.Z/1024; @@ -135,8 +133,8 @@ namespace OpenRA.Mods.RA src = legacyMuzzlePosition, srcAltitude = legacyMuzzleAltitude, - dest = target.CenterLocation, - destAltitude = destios != null ? destios.Altitude : 0, + dest = PPos.FromWPos(target.CenterPosition), + destAltitude = target.CenterPosition.Z * Game.CellSize / 1024, facing = legacyFacing, diff --git a/OpenRA.Mods.RA/Buildings/Building.cs b/OpenRA.Mods.RA/Buildings/Building.cs index 114809e683..ef99c3eb38 100755 --- a/OpenRA.Mods.RA/Buildings/Building.cs +++ b/OpenRA.Mods.RA/Buildings/Building.cs @@ -20,7 +20,7 @@ namespace OpenRA.Mods.RA.Buildings public class GivesBuildableAreaInfo : TraitInfo {} public class GivesBuildableArea {} - public class BuildingInfo : ITraitInfo, UsesInit + public class BuildingInfo : ITraitInfo, IOccupySpaceInfo, UsesInit { [Desc("If negative, it will drain power, if positive, it will provide power.")] public readonly int Power = 0; @@ -96,7 +96,6 @@ namespace OpenRA.Mods.RA.Buildings [Sync] readonly CPos topLeft; PowerManager PlayerPower; - PPos pxPosition; [Sync] public bool Locked; /* shared activity lock: undeploy, sell, capture, etc */ @@ -110,9 +109,7 @@ namespace OpenRA.Mods.RA.Buildings public void Unlock() { Locked = false; } public CPos TopLeft { get { return topLeft; } } - public WPos CenterPosition { get { return PxPosition.ToWPos(0); } } - public PPos PxPosition { get { return pxPosition; } } - public int Altitude { get { return 0; } set { } } + public WPos CenterPosition { get; private set; } public IEnumerable ProvidesPrerequisites { get { yield return self.Info.Name; } } @@ -126,8 +123,7 @@ namespace OpenRA.Mods.RA.Buildings occupiedCells = FootprintUtils.UnpathableTiles( self.Info.Name, Info, TopLeft ) .Select(c => Pair.New(c, SubCell.FullCell)).ToArray(); - var position = topLeft.CenterPosition + FootprintUtils.CenterOffset(Info); - pxPosition = PPos.FromWPosHackZ(position); + CenterPosition = topLeft.CenterPosition + FootprintUtils.CenterOffset(Info); } public int GetPowerUsage() diff --git a/OpenRA.Mods.RA/Cargo.cs b/OpenRA.Mods.RA/Cargo.cs index 3be939620f..af77268715 100644 --- a/OpenRA.Mods.RA/Cargo.cs +++ b/OpenRA.Mods.RA/Cargo.cs @@ -17,14 +17,14 @@ using OpenRA.Traits; namespace OpenRA.Mods.RA { - public class CargoInfo : ITraitInfo + public class CargoInfo : ITraitInfo, Requires { public readonly int MaxWeight = 0; public readonly int PipCount = 0; public readonly string[] Types = { }; public readonly int UnloadFacing = 0; public readonly string[] InitialUnits = { }; - public readonly int minimalUnloadAltitude = 0; + public readonly WRange MaximumUnloadAltitude = WRange.Zero; public object Create( ActorInitializer init ) { return new Cargo( init, this ); } } @@ -93,7 +93,7 @@ namespace OpenRA.Mods.RA // Cannot unload mid-air var ios = self.TraitOrDefault(); - if (ios != null && ios.Altitude > info.minimalUnloadAltitude) + if (ios != null && ios.CenterPosition.Z > info.MaximumUnloadAltitude.Range) return false; // TODO: Check if there is a free tile to unload to @@ -106,8 +106,7 @@ namespace OpenRA.Mods.RA return false; // Cannot load mid-air - var ios = self.TraitOrDefault(); - return ios == null || ios.Altitude == info.minimalUnloadAltitude; + return self.CenterPosition.Z < info.MaximumUnloadAltitude.Range; } public string CursorForOrder(Actor self, Order order) diff --git a/OpenRA.Mods.RA/CarpetBomb.cs b/OpenRA.Mods.RA/CarpetBomb.cs index cfdcb607f8..13a40c98ae 100644 --- a/OpenRA.Mods.RA/CarpetBomb.cs +++ b/OpenRA.Mods.RA/CarpetBomb.cs @@ -56,12 +56,14 @@ namespace OpenRA.Mods.RA var weapon = Rules.Weapons[info.Weapon.ToLowerInvariant()]; dropDelay = weapon.ROF; + var centerLocation = PPos.FromWPos(self.CenterPosition); + var altitude = self.CenterPosition.Z * Game.CellSize / 1024; var args = new ProjectileArgs { - srcAltitude = self.Trait().Altitude, + srcAltitude = altitude, destAltitude = 0, - src = self.CenterLocation, - dest = self.CenterLocation, + src = centerLocation, + dest = centerLocation, facing = self.Trait().Facing, firedBy = self, weapon = weapon diff --git a/OpenRA.Mods.RA/Crate.cs b/OpenRA.Mods.RA/Crate.cs index db7de2a24b..b1ab283250 100644 --- a/OpenRA.Mods.RA/Crate.cs +++ b/OpenRA.Mods.RA/Crate.cs @@ -11,12 +11,12 @@ using System.Collections.Generic; using System.Linq; using OpenRA.FileFormats; -using OpenRA.Traits; using OpenRA.Mods.RA.Buildings; +using OpenRA.Traits; namespace OpenRA.Mods.RA { - class CrateInfo : ITraitInfo, Requires + class CrateInfo : ITraitInfo, IOccupySpaceInfo, Requires { public readonly int Lifetime = 5; // Seconds public readonly string[] TerrainTypes = { }; @@ -27,23 +27,22 @@ namespace OpenRA.Mods.RA class Crate : ITick, IPositionable, ICrushable, ISync, INotifyParachuteLanded { readonly Actor self; + readonly CrateInfo info; + bool collected; + [Sync] int ticks; [Sync] public CPos Location; - CrateInfo Info; - bool collected; public Crate(ActorInitializer init, CrateInfo info) { this.self = init.self; + this.info = info; + if (init.Contains()) - { - this.Location = init.Get(); - PxPosition = Util.CenterOfCell(Location); - } - this.Info = info; + SetPosition(self, init.Get()); } - public void WarnCrush(Actor crusher) {} + public void WarnCrush(Actor crusher) { } public void OnCrush(Actor crusher) { @@ -78,17 +77,14 @@ namespace OpenRA.Mods.RA public void Tick(Actor self) { - if( ++ticks >= Info.Lifetime * 25 ) + if (++ticks >= info.Lifetime * 25) self.Destroy(); } public CPos TopLeft { get { return Location; } } - public IEnumerable> OccupiedCells() { yield return Pair.New( Location, SubCell.FullCell); } - - public WPos CenterPosition { get { return PxPosition.ToWPos(Altitude); } } - public PPos PxPosition { get; private set; } - public int Altitude { get { return 0; } set { } } + public IEnumerable> OccupiedCells() { yield return Pair.New(Location, SubCell.FullCell); } + public WPos CenterPosition { get; private set; } public void SetPosition(Actor self, WPos pos) { SetPosition(self, pos.ToCPos()); } public void SetVisualPosition(Actor self, WPos pos) { SetPosition(self, pos.ToCPos()); } @@ -96,7 +92,7 @@ namespace OpenRA.Mods.RA { if (!self.World.Map.IsInMap(cell.X, cell.Y)) return false; var type = self.World.GetTerrainType(cell); - if (!Info.TerrainTypes.Contains(type)) + if (!info.TerrainTypes.Contains(type)) return false; if (self.World.WorldActor.Trait().GetBuildingAt(cell) != null) return false; @@ -107,18 +103,18 @@ namespace OpenRA.Mods.RA public void SetPosition(Actor self, CPos cell) { - if( self.IsInWorld ) + if (self.IsInWorld) self.World.ActorMap.Remove(self, this); Location = cell; - PxPosition = Util.CenterOfCell(cell); + CenterPosition = cell.CenterPosition; var seq = self.World.GetTerrainInfo(cell).IsWater ? "water" : "land"; var rs = self.Trait(); if (seq != rs.anim.CurrentSequence.Name) rs.anim.PlayRepeating(seq); - if( self.IsInWorld ) + if (self.IsInWorld) self.World.ActorMap.Add(self, this); } diff --git a/OpenRA.Mods.RA/Effects/Missile.cs b/OpenRA.Mods.RA/Effects/Missile.cs index 1c8297e1ed..7eae2bffdb 100755 --- a/OpenRA.Mods.RA/Effects/Missile.cs +++ b/OpenRA.Mods.RA/Effects/Missile.cs @@ -97,9 +97,9 @@ namespace OpenRA.Mods.RA.Effects // In pixels var dist = Args.target.CenterLocation + offset - PxPosition; - var targetAltitude = 0; - if (Args.target.IsValid && Args.target.IsActor && Args.target.Actor.HasTrait()) - targetAltitude = Args.target.Actor.Trait().Altitude; + var targetAltitude = 0; + if (Args.target.IsValid) + targetAltitude = Args.target.CenterPosition.Z * Game.CellSize / 1024; var jammed = Info.Jammable && world.ActorsWithTrait().Any(tp => (tp.Actor.CenterLocation - PxPosition).ToCVec().Length <= tp.Trait.Range diff --git a/OpenRA.Mods.RA/Husk.cs b/OpenRA.Mods.RA/Husk.cs index 9e18197c68..a46f577362 100644 --- a/OpenRA.Mods.RA/Husk.cs +++ b/OpenRA.Mods.RA/Husk.cs @@ -16,7 +16,7 @@ using OpenRA.Traits; namespace OpenRA.Mods.RA { - class HuskInfo : ITraitInfo, IFacingInfo + class HuskInfo : ITraitInfo, IOccupySpaceInfo, IFacingInfo { public readonly string[] AllowedTerrain = { }; @@ -35,7 +35,6 @@ namespace OpenRA.Mods.RA [Sync] public int Facing { get; set; } public int ROT { get { return 0; } } - public int Altitude { get { return 0; } set { } } public Husk(ActorInitializer init, HuskInfo info) { diff --git a/OpenRA.Mods.RA/Mine.cs b/OpenRA.Mods.RA/Mine.cs index 9b34282c07..3c3ad8df31 100644 --- a/OpenRA.Mods.RA/Mine.cs +++ b/OpenRA.Mods.RA/Mine.cs @@ -17,7 +17,7 @@ using OpenRA.FileFormats; namespace OpenRA.Mods.RA { - class MineInfo : ITraitInfo + class MineInfo : ITraitInfo, IOccupySpaceInfo { public readonly string[] CrushClasses = { }; public readonly bool AvoidFriendly = true; @@ -61,9 +61,7 @@ namespace OpenRA.Mods.RA public CPos TopLeft { get { return location; } } public IEnumerable> OccupiedCells() { yield return Pair.New(TopLeft, SubCell.FullCell); } - public WPos CenterPosition { get { return PxPosition.ToWPos(0); } } - public PPos PxPosition { get { return Util.CenterOfCell( location ); } } - public int Altitude { get { return 0; } set { } } + public WPos CenterPosition { get { return location.CenterPosition; } } } /* tag trait for stuff that shouldnt trigger mines */ diff --git a/OpenRA.Mods.RA/Move/Mobile.cs b/OpenRA.Mods.RA/Move/Mobile.cs index 95d56dca94..86ef2231a8 100755 --- a/OpenRA.Mods.RA/Move/Mobile.cs +++ b/OpenRA.Mods.RA/Move/Mobile.cs @@ -19,7 +19,7 @@ using OpenRA.Traits; namespace OpenRA.Mods.RA.Move { [Desc("Unit is able to move.")] - public class MobileInfo : ITraitInfo, IFacingInfo, UsesInit, UsesInit, UsesInit + public class MobileInfo : ITraitInfo, IOccupySpaceInfo, IFacingInfo, UsesInit, UsesInit, UsesInit { [FieldLoader.LoadUsing("LoadSpeeds")] [Desc("Set Water: 0 for ground units and lower the value on rough terrain.")] @@ -35,7 +35,6 @@ namespace OpenRA.Mods.RA.Move public readonly bool OnRails = false; [Desc("Allow multiple (infantry) units in one cell.")] public readonly bool SharesCell = false; - public readonly int Altitude; public virtual object Create(ActorInitializer init) { return new Mobile(init, this); } @@ -163,12 +162,9 @@ namespace OpenRA.Mods.RA.Move set { __facing = value; } } - [Sync] public int Altitude { get; set; } - public int ROT { get { return Info.ROT; } } - public WPos CenterPosition { get { return PxPosition.ToWPos(Altitude); } } - [Sync] public PPos PxPosition { get; private set; } + [Sync] public WPos CenterPosition { get; private set; } [Sync] public CPos fromCell { get { return __fromCell; } } [Sync] public CPos toCell { get { return __toCell; } } @@ -209,7 +205,12 @@ namespace OpenRA.Mods.RA.Move } this.Facing = init.Contains() ? init.Get() : info.InitialFacing; - this.Altitude = init.Contains() ? init.Get() : 0; + + if (init.Contains()) + { + var z = init.Get() * 1024 / Game.CellSize; + SetVisualPosition(self, CenterPosition + new WVec(0, 0, z - CenterPosition.Z)); + } } public void SetPosition(Actor self, CPos cell) @@ -219,24 +220,17 @@ namespace OpenRA.Mods.RA.Move FinishedMoving(self); } - public void AdjustPxPosition(Actor self, PPos px) /* visual hack only */ - { - PxPosition = px; - } - public void SetPosition(Actor self, WPos pos) { - // TODO: Handle altitude var cell = pos.ToCPos(); SetLocation(cell,fromSubCell, cell,fromSubCell); - PxPosition = PPos.FromWPos(pos); + SetVisualPosition(self, pos); FinishedMoving(self); } public void SetVisualPosition(Actor self, WPos pos) { - // TODO: Handle altitude - AdjustPxPosition(self, PPos.FromWPos(pos)); + CenterPosition = pos; } public IEnumerable Orders { get { yield return new MoveOrderTargeter(Info); } } diff --git a/OpenRA.Mods.RA/Move/Move.cs b/OpenRA.Mods.RA/Move/Move.cs index f8c972911c..e3d8e79e0e 100755 --- a/OpenRA.Mods.RA/Move/Move.cs +++ b/OpenRA.Mods.RA/Move/Move.cs @@ -111,15 +111,6 @@ namespace OpenRA.Mods.RA.Move public override Activity Tick(Actor self) { var mobile = self.Trait(); - var info = self.Info.Traits.Get(); - - if (mobile.Altitude != info.Altitude) - { - if (mobile.Altitude < info.Altitude) - ++mobile.Altitude; - - return this; - } if (destination == mobile.toCell) return NextActivity; diff --git a/OpenRA.Mods.RA/Render/WithRotor.cs b/OpenRA.Mods.RA/Render/WithRotor.cs index 5135be0fd4..9a7202a23a 100755 --- a/OpenRA.Mods.RA/Render/WithRotor.cs +++ b/OpenRA.Mods.RA/Render/WithRotor.cs @@ -40,7 +40,7 @@ namespace OpenRA.Mods.RA.Render public void Tick(Actor self) { - var isFlying = self.Trait().Altitude > 0 && !self.IsDead(); + var isFlying = self.CenterPosition.Z > 0 && !self.IsDead(); if (isFlying ^ (rotorAnim.CurrentSequence.Name != "rotor")) return; diff --git a/OpenRA.Mods.RA/Render/WithShadow.cs b/OpenRA.Mods.RA/Render/WithShadow.cs index 685f8fad8a..6cde2c7c3c 100644 --- a/OpenRA.Mods.RA/Render/WithShadow.cs +++ b/OpenRA.Mods.RA/Render/WithShadow.cs @@ -14,7 +14,6 @@ using System.Linq; using OpenRA.Graphics; using OpenRA.Traits; using OpenRA.Mods.RA.Air; -using OpenRA.Mods.RA.Move; namespace OpenRA.Mods.RA.Render { @@ -27,13 +26,14 @@ namespace OpenRA.Mods.RA.Render var ios = self.Trait(); /* rude hack */ - var visualOffset = ((ios is Helicopter || ios is Mobile) && ios.Altitude > 0) + var flying = ios.CenterPosition.Z > 0; + var visualOffset = (ios is Helicopter && flying) ? (int)Math.Abs((self.ActorID + Game.LocalTick) / 5 % 4 - 1) - 1 : 0; var shadowSprites = r.Select(a => a.WithPalette(wr.Palette("shadow")) .WithPos(a.Pos - new WVec(0, 0, a.Pos.Z)).WithZOffset(a.ZOffset + a.Pos.Z)); - var flyingSprites = (ios.Altitude <= 0) ? r : + var flyingSprites = !flying ? r : r.Select(a => a.WithPos(a.Pos - new WVec(0,0,43*visualOffset))); return shadowSprites.Concat(flyingSprites); diff --git a/mods/d2k/rules/aircraft.yaml b/mods/d2k/rules/aircraft.yaml index c7194ccde4..abcb74c285 100644 --- a/mods/d2k/rules/aircraft.yaml +++ b/mods/d2k/rules/aircraft.yaml @@ -28,7 +28,7 @@ Types: Vehicle MaxWeight: 1 PipCount: 1 - minimalUnloadAltitude: 25 + MaximumUnloadAltitude: 800 LeavesHusk: HuskActor: CARRYALL.Husk