Files
OpenRA/OpenRa.Game/Ore.cs

188 lines
5.1 KiB
C#

using System;
using OpenRa.FileFormats;
using OpenRa.Traits;
namespace OpenRa
{
public static class Ore
{
public static void AddOre(this Map map, int i, int j)
{
if (Rules.General.OreSpreads)
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<BuildingInfluence>().GetBuildingAt(new int2(i, j)) != null)
return false;
return TerrainCosts.Cost(UnitMovementType.Wheel,
world.TileSet.GetWalkability(world.Map.MapTiles[i, j]))
< double.PositiveInfinity;
}
public static void GrowOre(this World world, Random r)
{
var map = world.Map;
var mini = map.XOffset; var maxi = map.XOffset + map.Width;
var minj = map.YOffset; var maxj = map.YOffset + map.Height;
var chance = Rules.General.OreChance;
/* phase 1: grow into neighboring regions */
if (Rules.General.OreSpreads)
{
var newOverlay = new byte[128, 128];
for (int j = minj; j < maxj; j++)
for (int i = mini; i < maxi; i++)
{
newOverlay[i, j] = 0xff;
if (!map.HasOverlay(i, j)
&& r.NextDouble() < chance
&& map.GetOreDensity(i, j) > 0
&& world.OreCanSpreadInto(i,j))
newOverlay[i, j] = ChooseOre();
}
for (int j = minj; j < maxj; j++)
for (int i = mini; i < maxi; i++)
if (newOverlay[i, j] != 0xff)
map.MapTiles[i, j].overlay = newOverlay[i, j];
}
/* phase 2: increase density of existing areas */
if (Rules.General.OreGrows)
{
var newDensity = new byte[128, 128];
for (int j = minj; j < maxj; j++)
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;
}
}
public static void InitOreDensity( this Map map )
{
for (int j = 0; j < 128; j++)
for (int i = 0; i < 128; i++)
{
if (map.ContainsOre(i, j)) map.MapTiles[i, j].density = map.GetOreDensity(i, j);
if (map.ContainsGem(i, j)) map.MapTiles[i, j].density = map.GetGemDensity(i, j);
}
}
static byte GetOreDensity(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.ContainsOre(i + u, j + v))
++sum;
sum = (sum * 4 + 2) / 3;
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;
}
static bool ContainsOre(this Map map, int i, int j)
{
return map.HasOverlay(i, j) && overlayIsOre[map.MapTiles[i, j].overlay];
}
static bool ContainsGem(this Map map, int i, int j)
{
return map.HasOverlay(i, j) && overlayIsGems[map.MapTiles[i, j].overlay];
}
public static bool ContainsResource(this Map map, int2 p)
{
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()
{
if (++ore > 8) ore = 5;
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,
true, true, true, true,
false, false, false, false,
false, false, false, false, false, false, false,
false, false, false, false, false,
};
public static bool[] overlayIsGems =
{
false, false, false, false, false,
false, false, false, false,
true, true, true, true,
false, false, false, false, false, false, false,
false, false, false, false, false,
};
}
}