diff --git a/OpenRA.Game/Traits/Mobile.cs b/OpenRA.Game/Traits/Mobile.cs index df4d86ad07..285a2191d8 100644 --- a/OpenRA.Game/Traits/Mobile.cs +++ b/OpenRA.Game/Traits/Mobile.cs @@ -14,33 +14,49 @@ using System.Drawing; using System.Linq; using OpenRA.Effects; using OpenRA.Traits.Activities; +using OpenRA.FileFormats; namespace OpenRA.Traits { public class MobileInfo : ITraitInfo { - public readonly string[] TerrainTypes; - public readonly float[] TerrainSpeeds; - public readonly string[] TerrainCostOverrides; - public readonly float[] TerrainCosts; - public readonly string[] Crushes; - public readonly int WaitAverage = 60; - public readonly int WaitSpread = 20; - public readonly int InitialFacing = 128; - public readonly int ROT = 255; - public readonly int Speed = 1; - public readonly bool OnRails = false; + [FieldLoader.LoadUsing( "LoadSpeeds" )] + public readonly Dictionary TerrainSpeeds; + [FieldLoader.Load] public readonly string[] Crushes; + [FieldLoader.Load] public readonly int WaitAverage = 60; + [FieldLoader.Load] public readonly int WaitSpread = 20; + [FieldLoader.Load] public readonly int InitialFacing = 128; + [FieldLoader.Load] public readonly int ROT = 255; + [FieldLoader.Load] public readonly int Speed = 1; + [FieldLoader.Load] public readonly bool OnRails = false; public virtual object Create(ActorInitializer init) { return new Mobile(init, this); } + + static object LoadSpeeds( MiniYaml y ) + { + Dictionary ret = new Dictionary(); + foreach (var t in y.NodesDict["TerrainSpeeds"].Nodes) + { + var speed = (float)FieldLoader.GetValue("speed", typeof(float),t.Value.Value); + var cost = t.Value.NodesDict.ContainsKey("PathingCost") ? (float)FieldLoader.GetValue("cost", typeof(float), t.Value.NodesDict["PathingCost"].Value) : 1f/speed; + ret.Add(t.Key, new TerrainInfo{Speed = speed, Cost = cost}); + } + + return ret; + } + + public class TerrainInfo + { + public float Cost = float.PositiveInfinity; + public float Speed = 0; + } } - + public class Mobile : IIssueOrder, IResolveOrder, IOrderCursor, IOrderVoice, IOccupySpace, IMove, IFacing, INudge { public readonly Actor self; public readonly MobileInfo Info; - public readonly Dictionary TerrainCost; - public readonly Dictionary TerrainSpeed; - + [Sync] public int Facing { get; set; } [Sync] @@ -93,26 +109,6 @@ namespace OpenRA.Traits this.Facing = init.Contains() ? init.Get() : info.InitialFacing; this.Altitude = init.Contains() ? init.Get() : 0; - - TerrainCost = new Dictionary(); - TerrainSpeed = new Dictionary(); - - if (info.TerrainTypes.Count() != info.TerrainSpeeds.Count()) - throw new InvalidOperationException("Mobile TerrainType/TerrainSpeed length mismatch"); - - if (info.TerrainCostOverrides != null) - for (int i = 0; i < info.TerrainCostOverrides.Count(); i++) - { - TerrainCost.Add(info.TerrainCostOverrides[i], info.TerrainCosts[i]); - } - - for (int i = 0; i < info.TerrainTypes.Count(); i++) - { - if (!TerrainCost.ContainsKey(info.TerrainTypes[i])) - TerrainCost.Add(info.TerrainTypes[i], 1f/info.TerrainSpeeds[i]); - - TerrainSpeed.Add(info.TerrainTypes[i], info.TerrainSpeeds[i]); - } } public void SetPosition(Actor self, int2 cell) @@ -259,18 +255,24 @@ namespace OpenRA.Traits return float.PositiveInfinity; var type = self.World.GetTerrainType(cell); - return TerrainCost[type]; + if (!Info.TerrainSpeeds.ContainsKey(type)) + return float.PositiveInfinity; + + return Info.TerrainSpeeds[type].Cost; } public virtual float MovementSpeedForCell(Actor self, int2 cell) { var type = self.World.GetTerrainType(cell); - + + if (!Info.TerrainSpeeds.ContainsKey(type)) + return 0; + var modifier = self .TraitsImplementing() .Select(t => t.GetSpeedModifier()) .Product(); - return Info.Speed * TerrainSpeed[type] * modifier; + return Info.Speed * Info.TerrainSpeeds[type].Speed * modifier; } public IEnumerable GetCurrentPath(Actor self) diff --git a/mods/cnc/defaults.yaml b/mods/cnc/defaults.yaml index 9a1dacdae9..859178b254 100644 --- a/mods/cnc/defaults.yaml +++ b/mods/cnc/defaults.yaml @@ -2,8 +2,12 @@ AppearsOnRadar: Mobile: Crushes: crate - TerrainTypes: Clear, Rough, Road, Tree, Water, Rock, Wall, Ore, Beach, River - TerrainSpeeds: 60%, 40%, 100%, 0%, 0%, 0%, 0%, 50%, 40%, 0% + TerrainSpeeds: + Clear: 60% + Rough: 40% + Road: 100% + Ore: 70% + Beach: 40% ROT: 5 Selectable: Voice: VehicleVoice @@ -27,8 +31,12 @@ AppearsOnRadar: Mobile: Crushes: wall, crate - TerrainTypes: Clear, Rough, Road, Tree, Water, Rock, Wall, Ore, Beach, River - TerrainSpeeds: 80%, 70%, 100%, 0%, 0%, 0%, 0%, 70%, 70%, 0% + TerrainSpeeds: + Clear: 80% + Rough: 70% + Road: 100% + Ore: 90% + Beach: 70% ROT: 5 Selectable: Voice: VehicleVoice @@ -75,10 +83,13 @@ Range: 4 Mobile: Crushes: crate - TerrainTypes: Clear, Rough, Road, Tree, Water, Rock, Wall, Ore, Beach, River - TerrainSpeeds: 90%, 80%, 100%, 0%, 0%, 0%, 0%, 90%, 80%, 0% - TerrainCostOverrides: Ore - TerrainCosts: 200 + TerrainSpeeds: + Clear: 90% + Rough: 80% + Road: 100% + Ore: 90% + PathingCost: 200 + Beach: 80% Selectable: Voice: GenericVoice Targetable: @@ -138,8 +149,8 @@ AppearsOnRadar: Mobile: Crushes: crate - TerrainTypes: Clear, Rough, Road, Tree, Water, Rock, Wall, Ore, Beach, River - TerrainSpeeds: 0%, 0%, 0%, 0%, 100%, 0%, 0%, 0%, 0%, 0% + TerrainSpeeds: + Water: 100% Selectable: Voice: GenericVoice Targetable: diff --git a/mods/cnc/vehicles.yaml b/mods/cnc/vehicles.yaml index 87bd1cf061..3a7cd13b11 100644 --- a/mods/cnc/vehicles.yaml +++ b/mods/cnc/vehicles.yaml @@ -594,8 +594,17 @@ LST: Name: Landing Craft Mobile: Crushes: crate - TerrainTypes: Clear, Rough, Road, Tree, Water, Rock, Wall, Ore, Beach, River - TerrainSpeeds: 100%, 100%, 100%, 100%, 100%, 100%, 100%, 100%, 100%, 100% + TerrainSpeeds: + Clear: 100% + Rough: 100% + Road: 100% + Tree: 100% + Water: 100% + Rock: 100% + Wall: 100% + Ore: 100% + Beach: 100% + River: 100% InitialFacing:0 ROT: 4 Speed: 10 diff --git a/mods/ra/defaults.yaml b/mods/ra/defaults.yaml index e3ad1d0d53..db96a2c215 100644 --- a/mods/ra/defaults.yaml +++ b/mods/ra/defaults.yaml @@ -2,8 +2,12 @@ AppearsOnRadar: Mobile: Crushes: atmine, crate - TerrainTypes: Clear, Rough, Road, Tree, Water, Rock, Wall, Ore, Beach, River - TerrainSpeeds: 60%, 40%, 100%, 0%, 0%, 0%, 0%, 90%, 40%, 0% + TerrainSpeeds: + Clear: 60% + Rough: 40% + Road: 100% + Ore: 90% + Beach: 40% ROT: 5 Selectable: Voice: VehicleVoice @@ -25,8 +29,12 @@ AppearsOnRadar: Mobile: Crushes: wall, atmine, crate - TerrainTypes: Clear, Rough, Road, Tree, Water, Rock, Wall, Ore, Beach, River - TerrainSpeeds: 80%, 70%, 100%, 0%, 0%, 0%, 0%, 90%, 70%, 0% + TerrainSpeeds: + Clear: 80% + Rough: 70% + Road: 100% + Ore: 70% + Beach: 70% ROT: 5 Selectable: Voice: VehicleVoice @@ -52,8 +60,12 @@ Range: 4 Mobile: Crushes: apmine, crate - TerrainTypes: Clear, Rough, Road, Tree, Water, Rock, Wall, Ore, Beach, River - TerrainSpeeds: 90%, 80%, 100%, 0%, 0%, 0%, 0%, 100%, 80%, 0% + TerrainSpeeds: + Clear: 90% + Rough: 80% + Road: 100% + Ore: 100% + Beach: 80% Selectable: Voice: GenericVoice Targetable: @@ -74,8 +86,8 @@ AppearsOnRadar: Mobile: Crushes: crate - TerrainTypes: Clear, Rough, Road, Tree, Water, Rock, Wall, Ore, Beach, River - TerrainSpeeds: 0%, 0%, 0%, 0%, 100%, 0%, 0%, 0%, 0%, 0% + TerrainSpeeds: + Water: 100% Selectable: Voice: ShipVoice Targetable: