diff --git a/OpenRA.Game/GameRules/TerrainCost.cs b/OpenRA.Game/GameRules/TerrainCost.cs index 716bda50e3..28ee1d7c56 100644 --- a/OpenRA.Game/GameRules/TerrainCost.cs +++ b/OpenRA.Game/GameRules/TerrainCost.cs @@ -41,7 +41,7 @@ namespace OpenRA.GameRules public TerrainCost(MiniYaml y) { FieldLoader.Load(this, y); } - public float GetSpeedMultiplier(UnitMovementType umt) + public float GetSpeedModifier(UnitMovementType umt) { switch (umt) /* todo: make this nice */ { diff --git a/OpenRA.Game/Traits/Activities/Fly.cs b/OpenRA.Game/Traits/Activities/Fly.cs index 5632051a5a..4610285551 100644 --- a/OpenRA.Game/Traits/Activities/Fly.cs +++ b/OpenRA.Game/Traits/Activities/Fly.cs @@ -1,4 +1,4 @@ -#region Copyright & License Information +#region Copyright & License Information /* * Copyright 2007,2009,2010 Chris Forbes, Robert Pepperell, Matthew Bowra-Dean, Paul Chote, Alli Witheford. * This file is part of OpenRA. @@ -19,6 +19,7 @@ #endregion using System; +using OpenRA.GameRules; namespace OpenRA.Traits.Activities { @@ -64,7 +65,7 @@ namespace OpenRA.Traits.Activities public static void Fly(Actor self, int desiredAltitude ) { var unit = self.traits.Get(); - var speed = .2f * Util.GetEffectiveSpeed(self); + var speed = .2f * Util.GetEffectiveSpeed(self, UnitMovementType.Fly); var angle = unit.Facing / 128f * Math.PI; self.CenterLocation += speed * -float2.FromAngle((float)angle); diff --git a/OpenRA.Game/Traits/Activities/HeliAttack.cs b/OpenRA.Game/Traits/Activities/HeliAttack.cs index c7eb9618db..da2f24a891 100644 --- a/OpenRA.Game/Traits/Activities/HeliAttack.cs +++ b/OpenRA.Game/Traits/Activities/HeliAttack.cs @@ -1,4 +1,4 @@ -#region Copyright & License Information +#region Copyright & License Information /* * Copyright 2007,2009,2010 Chris Forbes, Robert Pepperell, Matthew Bowra-Dean, Paul Chote, Alli Witheford. * This file is part of OpenRA. @@ -19,6 +19,7 @@ #endregion using System; +using OpenRA.GameRules; namespace OpenRA.Traits.Activities { @@ -55,7 +56,7 @@ namespace OpenRA.Traits.Activities if (!float2.WithinEpsilon(float2.Zero, dist, range * Game.CellSize)) { - var rawSpeed = .2f * Util.GetEffectiveSpeed(self); + var rawSpeed = .2f * Util.GetEffectiveSpeed(self, UnitMovementType.Fly); self.CenterLocation += (rawSpeed / dist.Length) * dist; self.Location = ((1 / 24f) * self.CenterLocation).ToInt2(); } diff --git a/OpenRA.Game/Traits/Activities/HeliFly.cs b/OpenRA.Game/Traits/Activities/HeliFly.cs index 7e30bbf0ce..52a173e6ba 100644 --- a/OpenRA.Game/Traits/Activities/HeliFly.cs +++ b/OpenRA.Game/Traits/Activities/HeliFly.cs @@ -1,4 +1,4 @@ -#region Copyright & License Information +#region Copyright & License Information /* * Copyright 2007,2009,2010 Chris Forbes, Robert Pepperell, Matthew Bowra-Dean, Paul Chote, Alli Witheford. * This file is part of OpenRA. @@ -19,6 +19,7 @@ #endregion using System; +using OpenRA.GameRules; namespace OpenRA.Traits.Activities { @@ -59,7 +60,7 @@ namespace OpenRA.Traits.Activities Util.TickFacing(ref unit.Facing, desiredFacing, self.Info.Traits.Get().ROT); - var rawSpeed = .2f * Util.GetEffectiveSpeed(self); + var rawSpeed = .2f * Util.GetEffectiveSpeed(self, UnitMovementType.Fly); self.CenterLocation += (rawSpeed / dist.Length) * dist; self.Location = ((1 / 24f) * self.CenterLocation).ToInt2(); diff --git a/OpenRA.Game/Traits/Activities/Land.cs b/OpenRA.Game/Traits/Activities/Land.cs index 77e411b8d3..920971cdf3 100644 --- a/OpenRA.Game/Traits/Activities/Land.cs +++ b/OpenRA.Game/Traits/Activities/Land.cs @@ -1,4 +1,4 @@ -#region Copyright & License Information +#region Copyright & License Information /* * Copyright 2007,2009,2010 Chris Forbes, Robert Pepperell, Matthew Bowra-Dean, Paul Chote, Alli Witheford. * This file is part of OpenRA. @@ -19,6 +19,7 @@ #endregion using System; +using OpenRA.GameRules; namespace OpenRA.Traits.Activities { @@ -54,7 +55,7 @@ namespace OpenRA.Traits.Activities var desiredFacing = Util.GetFacing(d, unit.Facing); Util.TickFacing(ref unit.Facing, desiredFacing, self.Info.Traits.Get().ROT); - var speed = .2f * Util.GetEffectiveSpeed(self); + var speed = .2f * Util.GetEffectiveSpeed(self, UnitMovementType.Fly); var angle = unit.Facing / 128f * Math.PI; self.CenterLocation += speed * -float2.FromAngle((float)angle); diff --git a/OpenRA.Game/Traits/Activities/Move.cs b/OpenRA.Game/Traits/Activities/Move.cs index 621873347e..817bc6c588 100755 --- a/OpenRA.Game/Traits/Activities/Move.cs +++ b/OpenRA.Game/Traits/Activities/Move.cs @@ -1,4 +1,4 @@ -#region Copyright & License Information +#region Copyright & License Information /* * Copyright 2007,2009,2010 Chris Forbes, Robert Pepperell, Matthew Bowra-Dean, Paul Chote, Alli Witheford. * This file is part of OpenRA. @@ -23,6 +23,7 @@ using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Drawing; +using OpenRA.GameRules; namespace OpenRA.Traits.Activities { @@ -237,7 +238,8 @@ namespace OpenRA.Traits.Activities public void TickMove( Actor self, Mobile mobile, Move parent ) { - moveFraction += (int)Util.GetEffectiveSpeed(self); + var umt = self.Info.Traits.Get().MovementType; + moveFraction += (int)Util.GetEffectiveSpeed(self, umt); if( moveFraction >= moveFractionTotal ) moveFraction = moveFractionTotal; UpdateCenterLocation( self, mobile ); diff --git a/OpenRA.Game/Traits/Activities/ReturnToBase.cs b/OpenRA.Game/Traits/Activities/ReturnToBase.cs index 3087d91375..349e2357ed 100644 --- a/OpenRA.Game/Traits/Activities/ReturnToBase.cs +++ b/OpenRA.Game/Traits/Activities/ReturnToBase.cs @@ -1,4 +1,4 @@ -#region Copyright & License Information +#region Copyright & License Information /* * Copyright 2007,2009,2010 Chris Forbes, Robert Pepperell, Matthew Bowra-Dean, Paul Chote, Alli Witheford. * This file is part of OpenRA. @@ -20,6 +20,7 @@ using System; using System.Linq; +using OpenRA.GameRules; namespace OpenRA.Traits.Activities { @@ -51,7 +52,7 @@ namespace OpenRA.Traits.Activities var landPos = dest.CenterLocation; var unit = self.traits.Get(); - var speed = .2f * Util.GetEffectiveSpeed(self); + var speed = .2f * Util.GetEffectiveSpeed(self, UnitMovementType.Fly); var approachStart = landPos - new float2(unit.Altitude * speed, 0); var turnRadius = (128f / self.Info.Traits.Get().ROT) * speed / (float)Math.PI; diff --git a/OpenRA.Game/Traits/Bridge.cs b/OpenRA.Game/Traits/Bridge.cs index a1f4039bd9..678f458d19 100644 --- a/OpenRA.Game/Traits/Bridge.cs +++ b/OpenRA.Game/Traits/Bridge.cs @@ -128,7 +128,12 @@ namespace OpenRA.Traits { return Rules.TerrainTypes[Templates[state].TerrainType[Tiles[p]]].GetCost(umt); } - + + public float GetSpeedModifier(int2 p, UnitMovementType umt) + { + return Rules.TerrainTypes[Templates[state].TerrainType[Tiles[p]]].GetSpeedModifier(umt); + } + static bool IsIntact(Bridge b) { return b != null && b.self.IsInWorld && b.self.Health > 0; diff --git a/OpenRA.Game/Traits/Mobile.cs b/OpenRA.Game/Traits/Mobile.cs index b02127be44..86d5d92195 100644 --- a/OpenRA.Game/Traits/Mobile.cs +++ b/OpenRA.Game/Traits/Mobile.cs @@ -85,8 +85,8 @@ namespace OpenRA.Traits if (!mi.Modifiers.HasModifier(Modifiers.Alt)) return null; if (!self.World.IsActorCrushableByActor(underCursor, self)) return null; } - - if (Util.GetEffectiveSpeed(self) == 0) return null; /* allow disabling move orders from modifiers */ + var umt = self.Info.Traits.Get().MovementType; + if (Util.GetEffectiveSpeed(self,umt) == 0) return null; /* allow disabling move orders from modifiers */ if (xy == toCell) return null; return new Order("Move", self, xy); } diff --git a/OpenRA.Game/Traits/TraitsInterfaces.cs b/OpenRA.Game/Traits/TraitsInterfaces.cs index 2f5a7976a6..67fe015f9f 100644 --- a/OpenRA.Game/Traits/TraitsInterfaces.cs +++ b/OpenRA.Game/Traits/TraitsInterfaces.cs @@ -45,7 +45,11 @@ namespace OpenRA.Traits public interface IAcceptThief { void OnSteal(Actor self, Actor thief); } public interface IAcceptSpy { void OnInfiltrate(Actor self, Actor spy); } - public interface ICustomTerrain { float GetCost(int2 p, UnitMovementType umt); } + public interface ICustomTerrain + { + float GetCost(int2 p, UnitMovementType umt); + float GetSpeedModifier(int2 p, UnitMovementType umt); + } public interface IDisable { bool Disabled { get; set; } } diff --git a/OpenRA.Game/Traits/Util.cs b/OpenRA.Game/Traits/Util.cs index 589ffaf7d7..c4ad5d2798 100755 --- a/OpenRA.Game/Traits/Util.cs +++ b/OpenRA.Game/Traits/Util.cs @@ -22,6 +22,7 @@ using System; using System.Drawing; using System.Linq; using OpenRA.Graphics; +using OpenRA.GameRules; namespace OpenRA.Traits { @@ -138,16 +139,25 @@ namespace OpenRA.Traits return new Renderable(s, loc.Round(), pal); } - public static float GetEffectiveSpeed(Actor self) - { + public static float GetEffectiveSpeed(Actor self, UnitMovementType umt) + { var unitInfo = self.Info.Traits.GetOrDefault(); if( unitInfo == null ) return 0f; - + + var terrain = 1f; + if (umt != UnitMovementType.Fly) + { + var tt = self.World.GetTerrainType(self.Location); + terrain = Rules.TerrainTypes[tt].GetSpeedModifier(umt)*self.World.WorldActor.traits + .WithInterface() + .Select(t => t.GetSpeedModifier(self.Location, umt)) + .Product(); + } var modifier = self.traits .WithInterface() .Select(t => t.GetSpeedModifier()) .Product(); - return unitInfo.Speed * modifier; + return unitInfo.Speed * terrain * modifier; } public static IActivity SequenceActivities(params IActivity[] acts) diff --git a/OpenRA.Game/Traits/World/BridgeLayer.cs b/OpenRA.Game/Traits/World/BridgeLayer.cs index 78ccb6a418..cea14db3f1 100644 --- a/OpenRA.Game/Traits/World/BridgeLayer.cs +++ b/OpenRA.Game/Traits/World/BridgeLayer.cs @@ -95,7 +95,13 @@ namespace OpenRA.Traits return customTerrain[p.X,p.Y].GetCost(p,umt); return 1f; } - + public float GetSpeedModifier(int2 p, UnitMovementType umt) + { + if (customTerrain[p.X, p.Y] != null) + return customTerrain[p.X,p.Y].GetSpeedModifier(p,umt); + return 1f; + } + static bool IsBridge(World w, ushort t) { return w.TileSet.walk[t].Bridge != null; diff --git a/OpenRA.Game/Traits/World/ResourceLayer.cs b/OpenRA.Game/Traits/World/ResourceLayer.cs index 3c1ef7faf3..fcc296c080 100644 --- a/OpenRA.Game/Traits/World/ResourceLayer.cs +++ b/OpenRA.Game/Traits/World/ResourceLayer.cs @@ -88,11 +88,11 @@ namespace OpenRA.Traits content[x, y].density = GetIdealDensity(x, y); } - public float GetSpeedMultiplier(UnitMovementType umt, int2 p) + public float GetSpeedModifier(int2 p, UnitMovementType umt) { if (content[p.X,p.Y].type == null) return 1.0f; - return content[p.X,p.Y].type.GetSpeedMultiplier(umt); + return content[p.X,p.Y].type.GetSpeedModifier(umt); } public float GetCost(int2 p,UnitMovementType umt) diff --git a/OpenRA.Game/Traits/World/ResourceType.cs b/OpenRA.Game/Traits/World/ResourceType.cs index 42e9cbb4ff..3a19685614 100644 --- a/OpenRA.Game/Traits/World/ResourceType.cs +++ b/OpenRA.Game/Traits/World/ResourceType.cs @@ -56,7 +56,7 @@ namespace OpenRA.Traits for (var umt = UnitMovementType.Foot; umt <= UnitMovementType.Float; umt++ ) { // HACK: hardcode "ore" terraintype for now - movementSpeed[(int)umt] = (info.MovementTerrainType != null) ? (float)Rules.TerrainTypes[TerrainType.Ore].GetSpeedMultiplier(umt) : 1.0f; + movementSpeed[(int)umt] = (info.MovementTerrainType != null) ? (float)Rules.TerrainTypes[TerrainType.Ore].GetSpeedModifier(umt) : 1.0f; pathCost[(int)umt] = (info.PathingTerrainType != null) ? (float)Rules.TerrainTypes[TerrainType.Ore].GetCost(umt) : (info.MovementTerrainType != null) ? (float)Rules.TerrainTypes[TerrainType.Ore].GetCost(umt) : 1.0f; } @@ -64,7 +64,7 @@ namespace OpenRA.Traits this.info = info; } - public float GetSpeedMultiplier(UnitMovementType umt) + public float GetSpeedModifier(UnitMovementType umt) { return movementSpeed[(int)umt]; }