diff --git a/OpenRA.FileFormats/TileReference.cs b/OpenRA.FileFormats/TileReference.cs index c4ca4d069e..e1688bd824 100644 --- a/OpenRA.FileFormats/TileReference.cs +++ b/OpenRA.FileFormats/TileReference.cs @@ -26,7 +26,6 @@ namespace OpenRA.FileFormats public byte image; public byte overlay; public byte smudge; - public byte density; /* used for ore/gems */ public override int GetHashCode() { return tile.GetHashCode() ^ image.GetHashCode(); } diff --git a/OpenRA.Game/Ore.cs b/OpenRA.Game/Ore.cs index 1b26d435d8..97d119e1ae 100644 --- a/OpenRA.Game/Ore.cs +++ b/OpenRA.Game/Ore.cs @@ -26,34 +26,13 @@ namespace OpenRA { public static class Ore { - public static void AddOre(this Map map, int i, int j) - { - if (map.ContainsOre(i, j) && map.MapTiles[i, j].density < 12) - map.MapTiles[i, j].density++; - else if (map.MapTiles[i, j].overlay == 0xff) - { - map.MapTiles[i, j].overlay = ChooseOre(); - map.MapTiles[i, j].density = 1; - } - } - public static void DestroyOre(this Map map, int i, int j) { - if (map.ContainsResource(new int2(i, j))) - { - map.MapTiles[i, j].density = 0; - map.MapTiles[i, j].overlay = 0xff; - } - } - - public static bool OreCanSpreadInto(this World world, int i, int j) - { - if (world.WorldActor.traits.Get().GetBuildingAt(new int2(i, j)) != null) - return false; - - return TerrainCosts.Cost(UnitMovementType.Wheel, - world.TileSet.GetWalkability(world.Map.MapTiles[i, j])) - < double.PositiveInfinity; + //if (map.ContainsResource(new int2(i, j))) + //{ + // map.MapTiles[i, j].density = 0; + // map.MapTiles[i, j].overlay = 0xff; + //} } public static void SpreadOre(this World world, Random r, float chance) @@ -72,7 +51,7 @@ namespace OpenRA if (!map.HasOverlay(i, j) && r.NextDouble() < chance && map.GetOreDensity(i, j) > 0 - && world.OreCanSpreadInto(i, j)) + && world.IsCellBuildable(new int2(i,j), UnitMovementType.Wheel)) newOverlay[i, j] = ChooseOre(); } @@ -82,10 +61,9 @@ namespace OpenRA map.MapTiles[i, j].overlay = newOverlay[i, j]; } - public static void GrowOre(this World world, Random r) + public static void GrowOre(this World world) { var map = world.Map; - var mini = map.XOffset; var maxi = map.XOffset + map.Width; var minj = map.YOffset; var maxj = map.YOffset + map.Height; @@ -95,10 +73,10 @@ namespace OpenRA for (int i = mini; i < maxi; i++) if (map.ContainsOre(i, j)) newDensity[i, j] = map.GetOreDensity(i, j); - for (int j = minj; j < maxj; j++) - for (int i = mini; i < maxi; i++) - if (map.MapTiles[i, j].density < newDensity[i, j]) - ++map.MapTiles[i, j].density; +// for (int j = minj; j < maxj; j++) +// for (int i = mini; i < maxi; i++) +// if (map.MapTiles[i, j].density < newDensity[i, j]) +// ++map.MapTiles[i, j].density; } static byte GetOreDensity(this Map map, int i, int j) @@ -112,17 +90,6 @@ namespace OpenRA return (byte)sum; } - static byte GetGemDensity(this Map map, int i, int j) - { - int sum = 0; - for (var u = -1; u < 2; u++) - for (var v = -1; v < 2; v++) - if (map.ContainsGem(i + u, j + v)) - ++sum; - sum = (sum+2) / 3; /* 3 gem units/tile is full. */ - return (byte)sum; - } - static bool HasOverlay(this Map map, int i, int j) { return map.MapTiles[i, j].overlay < overlayIsOre.Length; @@ -143,17 +110,6 @@ namespace OpenRA return map.ContainsGem(p.X, p.Y) || map.ContainsOre(p.X, p.Y); } - public static bool Harvest(this Map map, int2 p, out bool isGems) /* harvests one unit if possible */ - { - isGems = map.ContainsGem(p.X, p.Y); - if (map.MapTiles[p.X, p.Y].density == 0) return false; - - if (--map.MapTiles[p.X, p.Y].density == 0) - map.MapTiles[p.X, p.Y].overlay = 0xff; - - return true; - } - static byte ore = 5; static byte ChooseOre() { @@ -161,21 +117,6 @@ namespace OpenRA return ore; } - public static bool IsOverlaySolid(this Map map, int2 p) - { - var o = map.MapTiles[p.X, p.Y].overlay; - return o < overlayIsFence.Length && overlayIsFence[o]; - } - - public static bool[] overlayIsFence = - { - true, true, true, true, true, - false, false, false, false, - false, false, false, false, - false, false, false, false, false, false, false, - false, false, false, true, true, - }; - public static bool[] overlayIsOre = { false, false, false, false, false, diff --git a/OpenRA.Game/PathSearch.cs b/OpenRA.Game/PathSearch.cs index 24806e1d51..6297b2d7a6 100755 --- a/OpenRA.Game/PathSearch.cs +++ b/OpenRA.Game/PathSearch.cs @@ -84,9 +84,7 @@ namespace OpenRA if (!world.WorldActor.traits.Get().CanMoveHere(newHere) && world.WorldActor.traits.Get().GetBuildingAt(newHere) != ignoreBuilding) continue; - if (world.Map.IsOverlaySolid(newHere)) - continue; - + // Replicate real-ra behavior of not being able to enter a cell if there is a mixture of crushable and uncrushable units if (checkForBlocked && (world.WorldActor.traits.Get().GetUnitsAt(newHere).Any(a => !world.IsActorPathableToCrush(a, umt)))) continue; diff --git a/OpenRA.Game/Traits/Activities/Harvest.cs b/OpenRA.Game/Traits/Activities/Harvest.cs index 568be61320..6179c54e02 100644 --- a/OpenRA.Game/Traits/Activities/Harvest.cs +++ b/OpenRA.Game/Traits/Activities/Harvest.cs @@ -49,17 +49,16 @@ namespace OpenRA.Traits.Activities var harv = self.traits.Get(); var renderUnit = self.traits.Get(); /* better have one of these! */ - var isGem = false; - if (!self.World.Map.ContainsResource(self.Location) || - !self.World.Map.Harvest(self.Location, out isGem)) + var resource = self.World.WorldActor.traits.Get().Harvest(self.Location); + if (resource == null) return false; - + if (renderUnit.anim.CurrentSequence.Name != "harvest") { isHarvesting = true; renderUnit.PlayCustomAnimation(self, "harvest", () => isHarvesting = false); } - harv.AcceptResource(isGem); + harv.AcceptResource(resource); return true; } diff --git a/OpenRA.Game/Traits/Harvester.cs b/OpenRA.Game/Traits/Harvester.cs index e476624178..e62a7efa7e 100644 --- a/OpenRA.Game/Traits/Harvester.cs +++ b/OpenRA.Game/Traits/Harvester.cs @@ -47,9 +47,10 @@ namespace OpenRA.Traits public bool IsFull { get { return oreCarried + gemsCarried == self.Info.Traits.Get().BailCount; } } public bool IsEmpty { get { return oreCarried == 0 && gemsCarried == 0; } } - public void AcceptResource(bool isGem) + public void AcceptResource(ResourceTypeInfo type) { - if (isGem) gemsCarried++; + // FIXME: harvester probably needs to know *exactly* what it is carrying. + if (type.Name == "Gems") gemsCarried++; else oreCarried++; } diff --git a/OpenRA.Game/Traits/SeedsOre.cs b/OpenRA.Game/Traits/SeedsOre.cs index 378b110789..7006d3bc19 100644 --- a/OpenRA.Game/Traits/SeedsOre.cs +++ b/OpenRA.Game/Traits/SeedsOre.cs @@ -18,12 +18,16 @@ */ #endregion +using System.Linq; +using System; + namespace OpenRA.Traits { class SeedsOreInfo : ITraitInfo { public readonly float Chance = .05f; public readonly int Interval = 5; + public readonly string ResourceType = "Ore"; public object Create(Actor self) { return new SeedsOre(); } } @@ -37,12 +41,20 @@ namespace OpenRA.Traits if (--ticks <= 0) { var info = self.Info.Traits.Get(); + var resourceType = self.World.WorldActor.Info.Traits + .WithInterface() + .FirstOrDefault(t => t.Name == info.ResourceType); + + if (resourceType == null) + throw new InvalidOperationException("No such resource type `{0}`".F(info.ResourceType)); + + var resLayer = self.World.WorldActor.traits.Get(); for (var j = -1; j < 2; j++) for (var i = -1; i < 2; i++) if (self.World.SharedRandom.NextDouble() < info.Chance) - if (self.World.OreCanSpreadInto(self.Location.X + i, self.Location.Y + j)) - self.World.Map.AddOre(self.Location.X + i, self.Location.Y + j); + if (self.World.IsCellBuildable(self.Location + new int2(i, j), UnitMovementType.Wheel)) + resLayer.AddResource(resourceType, self.Location.X + i, self.Location.Y + j, 1); ticks = info.Interval; } diff --git a/OpenRA.Game/Traits/World/OreGrowth.cs b/OpenRA.Game/Traits/World/OreGrowth.cs index 71109f7e21..66889d51ba 100644 --- a/OpenRA.Game/Traits/World/OreGrowth.cs +++ b/OpenRA.Game/Traits/World/OreGrowth.cs @@ -46,7 +46,7 @@ namespace OpenRA.Traits info.Chance); if (info.Grows) - Ore.GrowOre(self.World, self.World.SharedRandom); + Ore.GrowOre(self.World); self.World.Minimap.InvalidateOre(); remainingTicks = (int)(info.Interval * 60 * 25); diff --git a/OpenRA.Game/Traits/World/ResourceLayer.cs b/OpenRA.Game/Traits/World/ResourceLayer.cs index eefbfa8a5a..328b62ce63 100644 --- a/OpenRA.Game/Traits/World/ResourceLayer.cs +++ b/OpenRA.Game/Traits/World/ResourceLayer.cs @@ -20,6 +20,7 @@ using System.Linq; using OpenRA.Graphics; +using System; namespace OpenRA.Traits { @@ -31,6 +32,7 @@ namespace OpenRA.Traits class ResourceLayer : IRenderOverlay, ILoadWorldHook { SpriteRenderer sr; + World w; public ResourceTypeInfo[] resourceTypes; public CellContents[,] content = new CellContents[128, 128]; @@ -62,6 +64,7 @@ namespace OpenRA.Traits public void WorldLoaded(World w) { + this.w = w; resourceTypes = w.WorldActor.Info.Traits.WithInterface().ToArray(); foreach (var rt in resourceTypes) rt.Sprites = rt.SpriteNames.Select(a => SpriteSheetBuilder.LoadAllSprites(a)).ToArray(); @@ -74,7 +77,7 @@ namespace OpenRA.Traits content[x,y].type = resourceTypes.FirstOrDefault( r => r.Overlays.Contains(w.Map.MapTiles[x, y].overlay)); if (content[x, y].type != null) - content[x, y].image = ChooseContent(w, content[x, y].type); + content[x, y].image = ChooseContent(content[x, y].type); } for (int y = map.YOffset; y < map.YOffset + map.Height; y++) @@ -84,7 +87,7 @@ namespace OpenRA.Traits content[x, y].image.Length) / 9; } - public Sprite[] ChooseContent(World w, ResourceTypeInfo info) + public Sprite[] ChooseContent(ResourceTypeInfo info) { return info.Sprites[w.SharedRandom.Next(info.Sprites.Length)]; } @@ -99,6 +102,33 @@ namespace OpenRA.Traits return sum; } + public void AddResource(ResourceTypeInfo info, int i, int j, int n) + { + if (content[i, j].type == null) + { + content[i, j].type = info; + content[i, j].image = ChooseContent(info); + content[i, j].density = -1; + } + + if (content[i, j].type != info) + return; + + content[i, j].density = Math.Min( + content[i, j].image.Length - 1, + content[i, j].density + n); + } + + public ResourceTypeInfo Harvest(int2 p) + { + var type = content[p.X,p.Y].type; + if (type == null) return null; + + if (--content[p.X, p.Y].density < 0) + content[p.X, p.Y].type = null; + return type; + } + public struct CellContents { public ResourceTypeInfo type; diff --git a/OpenRA.Game/Traits/World/ResourceType.cs b/OpenRA.Game/Traits/World/ResourceType.cs index dac76cbc83..6c98f0a8ea 100644 --- a/OpenRA.Game/Traits/World/ResourceType.cs +++ b/OpenRA.Game/Traits/World/ResourceType.cs @@ -22,7 +22,7 @@ using OpenRA.Graphics; using System.Collections.Generic; namespace OpenRA.Traits { - class ResourceTypeInfo : ITraitInfo + public class ResourceTypeInfo : ITraitInfo { public readonly int[] Overlays = { }; public readonly string[] SpriteNames = { };