diff --git a/OpenRa.FileFormats/TileSet.cs b/OpenRa.FileFormats/TileSet.cs index 6ea58a157d..6f2e05df1d 100644 --- a/OpenRa.FileFormats/TileSet.cs +++ b/OpenRa.FileFormats/TileSet.cs @@ -8,8 +8,8 @@ namespace OpenRa.FileFormats { public readonly Dictionary tiles = new Dictionary(); - readonly Dictionary> walk = - new Dictionary>(); // cjf will fix + public readonly Dictionary walk = + new Dictionary(); // cjf will fix string NextLine( StreamReader reader ) { @@ -82,7 +82,7 @@ namespace OpenRa.FileFormats if (r.tile == 0xff || r.tile == 0xffff) r.image = 0; - return walk[r.tile][r.image]; + return walk[r.tile].TerrainType[r.image]; } } } diff --git a/OpenRa.FileFormats/Walkability.cs b/OpenRa.FileFormats/Walkability.cs index 7ddfceab71..5095c49a3a 100644 --- a/OpenRa.FileFormats/Walkability.cs +++ b/OpenRa.FileFormats/Walkability.cs @@ -1,35 +1,51 @@ using System.Collections.Generic; using System.Text.RegularExpressions; +using System.Linq; namespace OpenRa.FileFormats { - public class Walkability + public class TileTemplate { - Dictionary> walkability = - new Dictionary>(); + public int Index; + public string Name; + public int2 Size; + public bool IsBridge; + public float HP; + public Dictionary TerrainType = new Dictionary(); + } + + class Walkability + { + public Dictionary walkability + = new Dictionary(); public Walkability() { - IniFile file = new IniFile( FileSystem.Open( "templates.ini" ) ); - Regex pattern = new Regex(@"tiletype(\d+)"); + var file = new IniFile( FileSystem.Open( "templates.ini" ) ); - foreach (IniSection section in file.Sections) + foreach (var section in file.Sections) { - string name = section.GetValue("Name", null).ToLowerInvariant(); - - Dictionary tileWalkability = new Dictionary(); - foreach (KeyValuePair p in section) + var tile = new TileTemplate { - Match m = pattern.Match(p.Key); - if (m != null && m.Success) - tileWalkability.Add(int.Parse(m.Groups[1].Value), int.Parse(p.Value)); - } + Size = new int2( + int.Parse(section.GetValue("width", "0")), + int.Parse(section.GetValue("height", "0"))), + TerrainType = section + .Where(p => p.Key.StartsWith("tiletype")) + .ToDictionary( + p => int.Parse(p.Key.Substring(8)), + p => int.Parse(p.Value)), + Name = section.GetValue("Name", null).ToLowerInvariant(), + Index = int.Parse(section.Name.Substring(3)), + IsBridge = section.GetValue("bridge", "no") != "no", + HP = float.Parse(section.GetValue("hp", "0")) + }; - walkability[name] = tileWalkability; + walkability[tile.Name] = tile; } } - public Dictionary GetWalkability(string terrainName) + public TileTemplate GetWalkability(string terrainName) { return walkability[terrainName]; } diff --git a/OpenRa.Game/Bridges.cs b/OpenRa.Game/Bridges.cs new file mode 100644 index 0000000000..dd53c32d51 --- /dev/null +++ b/OpenRa.Game/Bridges.cs @@ -0,0 +1,63 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using OpenRa.Traits; + +namespace OpenRa +{ + static class Bridges + { + public static void MakeBridges(World w) + { + var mini = w.Map.XOffset; var maxi = w.Map.XOffset + w.Map.Width; + var minj = w.Map.YOffset; var maxj = w.Map.YOffset + w.Map.Height; + + for (var j = minj; j < maxj; j++) + for (var i = mini; i < maxi; i++) + if (IsBridge(w, w.Map.MapTiles[i, j].tile)) + ConvertBridgeToActor(w, i, j); + } + + static void ConvertBridgeToActor(World w, int i, int j) + { + var tile = w.Map.MapTiles[i, j].tile; + var image = w.Map.MapTiles[i, j].image; + var template = w.TileSet.walk[tile]; + + // base position of the tile + var ni = i - image % template.Size.X; + var nj = j - image / template.Size.X; + + var replacedTiles = new Dictionary(); + for (var y = nj; y < nj + template.Size.Y; y++) + for (var x = ni; x < ni + template.Size.X; x++) + { + var n = (x - ni) + template.Size.X * (y - nj); + if (!template.TerrainType.ContainsKey(n)) continue; + + if (w.Map.IsInMap(x, y)) + if (w.Map.MapTiles[x, y].tile == tile) + { + // stash it + replacedTiles[new int2(x, y)] = w.Map.MapTiles[x, y].image; + // remove the tile from the actual map + w.Map.MapTiles[x, y].tile = 0xff; + w.Map.MapTiles[x, y].image = 0; + } + } + + if (replacedTiles.Any()) + { + var a = w.CreateActor("Bridge", new int2(ni, nj), null); + var br = a.traits.Get(); + br.SetTiles(template, replacedTiles); + } + } + + static bool IsBridge(World w, ushort t) + { + return w.TileSet.walk[t].IsBridge; + } + } +} diff --git a/OpenRa.Game/Graphics/SequenceProvider.cs b/OpenRa.Game/Graphics/SequenceProvider.cs index 66a45e2f43..64e0ab4e1f 100644 --- a/OpenRa.Game/Graphics/SequenceProvider.cs +++ b/OpenRa.Game/Graphics/SequenceProvider.cs @@ -107,8 +107,6 @@ namespace OpenRa.Graphics public static Sprite GetImageFromCollection(Renderer renderer,string collection, string image) { - - // Cached sprite if (cachedSprites.ContainsKey(collection) && cachedSprites[collection].ContainsKey(image)) return cachedSprites[collection][image]; diff --git a/OpenRa.Game/OpenRa.Game.csproj b/OpenRa.Game/OpenRa.Game.csproj index a287dcbac4..3b0747c4f5 100644 --- a/OpenRa.Game/OpenRa.Game.csproj +++ b/OpenRa.Game/OpenRa.Game.csproj @@ -77,6 +77,7 @@ + @@ -210,6 +211,7 @@ + diff --git a/OpenRa.Game/Shroud.cs b/OpenRa.Game/Shroud.cs index 91622065cd..b3a9e0adc2 100644 --- a/OpenRa.Game/Shroud.cs +++ b/OpenRa.Game/Shroud.cs @@ -137,6 +137,8 @@ namespace OpenRa internal void Draw(SpriteRenderer r) { + return; + if (dirty) { dirty = false; diff --git a/OpenRa.Game/Traits/Bridge.cs b/OpenRa.Game/Traits/Bridge.cs new file mode 100644 index 0000000000..e626e2c93d --- /dev/null +++ b/OpenRa.Game/Traits/Bridge.cs @@ -0,0 +1,43 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using OpenRa.Graphics; +using OpenRa.FileFormats; + +namespace OpenRa.Traits +{ + class BridgeInfo : ITraitInfo + { + public object Create(Actor self) { return new Bridge(); } + } + + class Bridge : IRender, ITick + { + Animation anim; + + public Bridge() {} + + public IEnumerable Render(Actor self) + { + if (anim != null) + return new[] { Util.Centered(self, anim.Image, self.CenterLocation) }; + else + return new Renderable[] { }; + } + + public void Tick(Actor self) + { + if (anim == null) + { + anim = new Animation("3tnk"); + anim.PlayRepeating("idle"); + } + } + + public void SetTiles(TileTemplate template, Dictionary replacedTiles) + { + /* todo: stash these, etc */ + } + } +} diff --git a/OpenRa.Game/World.cs b/OpenRa.Game/World.cs index d572b437ee..31c2e63444 100644 --- a/OpenRa.Game/World.cs +++ b/OpenRa.Game/World.cs @@ -44,6 +44,8 @@ namespace OpenRa CreateActor("World", new int2(int.MaxValue, int.MaxValue), null); + Bridges.MakeBridges(this); + WorldRenderer = new WorldRenderer(this, Game.renderer); Minimap = new Minimap(this, Game.renderer); } diff --git a/ra.yaml b/ra.yaml index fc8c476214..5c153858d1 100644 --- a/ra.yaml +++ b/ra.yaml @@ -1435,6 +1435,13 @@ DOMF: Image: DOME Fake: +BRIDGE: + Inherits: ^Building + Bridge: + BelowUnits: + -Selectable: + -Building: + T01: Inherits: ^Building Building: diff --git a/templates.ini b/templates.ini index e06254252f..b06455bb34 100644 --- a/templates.ini +++ b/templates.ini @@ -2491,6 +2491,8 @@ tiletype3=3 Name=BR1A width=4 height=3 +bridge=yes +hp=1 tiletype1=3 tiletype2=2 tiletype4=3 @@ -2505,6 +2507,8 @@ tiletype11=3 Name=BR1B width=4 height=3 +bridge=yes +hp=.5 tiletype1=3 tiletype2=6 tiletype4=3 @@ -2519,6 +2523,8 @@ tiletype11=3 Name=BR1C width=4 height=3 +bridge=yes +hp=0 tiletype1=3 tiletype2=3 tiletype4=3 @@ -2533,6 +2539,8 @@ tiletype11=3 Name=BR2A width=5 height=3 +bridge=yes +hp=1 tiletype1=3 tiletype2=2 tiletype5=3 @@ -2548,6 +2556,8 @@ tiletype13=3 Name=BR2B width=5 height=3 +bridge=yes +hp=.5 tiletype1=3 tiletype2=6 tiletype5=3 @@ -2563,6 +2573,8 @@ tiletype13=3 Name=BR2C width=5 height=3 +bridge=yes +hp=0 tiletype1=1 tiletype2=1 tiletype5=3 @@ -2578,6 +2590,8 @@ tiletype13=3 Name=BR3A width=4 height=2 +bridge=yes +hp=1 tiletype0=3 tiletype1=2 tiletype5=2 @@ -2588,6 +2602,8 @@ tiletype7=3 Name=BR3B width=4 height=2 +bridge=yes +hp=.5 tiletype0=3 tiletype1=2 tiletype5=2 @@ -2598,6 +2614,8 @@ tiletype7=3 Name=BR3C width=4 height=2 +bridge=yes +hp=0 tiletype0=3 tiletype1=3 tiletype5=3 @@ -2608,6 +2626,8 @@ tiletype7=3 Name=BR3D width=4 height=2 +bridge=yes +hp=0 tiletype0=5 tiletype1=3 tiletype5=5 @@ -2618,6 +2638,8 @@ tiletype7=5 Name=BR3E width=4 height=2 +bridge=yes +hp=0 tiletype0=1 tiletype1=1 tiletype5=3 @@ -2628,6 +2650,8 @@ tiletype7=1 Name=BR3F width=4 height=2 +bridge=yes +hp=0 tiletype0=1 tiletype1=1 tiletype5=1 diff --git a/units.ini b/units.ini index 9edf088fa8..9f9fbf2d23 100644 --- a/units.ini +++ b/units.ini @@ -253,6 +253,7 @@ DOMF ; pseudo-buildings MINP MINV +BRIDGE ; `Dimensions` is the size of a box that will include the whole building, excluding bib. @@ -533,6 +534,10 @@ Selectable=no Traits=Unit,RenderUnit,BelowUnits,InvisibleToOthers Selectable=no +[Bridge] +Traits=Bridge, BelowUnits +Selectable=no + [InfantryTypes] DOG E1