@@ -76,6 +76,7 @@ NEW:
|
||||
Fixed infantry sometimes using the wrong animation when standing.
|
||||
Fixed A* debug overlay.
|
||||
Fixed R8 offsets for sprites with embedded palettes.
|
||||
Implemented proper spice rendering.
|
||||
Engine:
|
||||
Replays are now saved in per-mod and per-version folders.
|
||||
Added password protection support for servers.
|
||||
@@ -129,6 +130,7 @@ NEW:
|
||||
Removed Utility --tmp-png, --r8, --fromd2 commands (use --png instead).
|
||||
Removed Asset Browser file extraction / conversion (use the Utility instead).
|
||||
Unified sprite loading allows any sprite type to be used anywhere: shp can now be used for terrain, and tmp for units.
|
||||
Harvestable resource definitions (ResourceTypes) have changed, and now specify their artwork using via sequences.
|
||||
|
||||
20130915:
|
||||
All mods:
|
||||
|
||||
@@ -77,7 +77,7 @@ namespace OpenRA.Editor
|
||||
|
||||
public static ResourceTemplate RenderResourceType(ResourceTypeInfo info, string[] exts, Palette p)
|
||||
{
|
||||
var image = info.SpriteNames[0];
|
||||
var image = info.EditorSprite;
|
||||
using (var s = FileSystem.OpenWithExts(image, exts))
|
||||
{
|
||||
// TODO: Do this properly
|
||||
|
||||
@@ -27,7 +27,7 @@ namespace OpenRA.Editor
|
||||
= new TileReference<byte, byte>
|
||||
{
|
||||
Type = (byte)resourceTemplate.Info.ResourceType,
|
||||
Index = (byte)random.Next(resourceTemplate.Info.SpriteNames.Length)
|
||||
Index = (byte)random.Next(resourceTemplate.Info.MaxDensity)
|
||||
};
|
||||
|
||||
var ch = new int2(surface.GetBrushLocation().X / Surface.ChunkSize,
|
||||
|
||||
@@ -11,31 +11,24 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using OpenRA.FileFormats;
|
||||
using OpenRA.Graphics;
|
||||
|
||||
namespace OpenRA.Traits
|
||||
{
|
||||
public class ResourceLayerInfo : TraitInfo<ResourceLayer> { }
|
||||
public class ResourceLayerInfo : TraitInfo<ResourceLayer>, Requires<ResourceTypeInfo> { }
|
||||
|
||||
public class ResourceLayer : IRenderOverlay, IWorldLoaded, ITickRender
|
||||
{
|
||||
World world;
|
||||
static readonly CellContents EmptyCell = new CellContents();
|
||||
|
||||
ResourceType[] resourceTypes;
|
||||
CellContents[,] content;
|
||||
CellContents[,] render;
|
||||
World world;
|
||||
protected CellContents[,] content;
|
||||
protected CellContents[,] render;
|
||||
List<CPos> dirty;
|
||||
bool hasSetupPalettes;
|
||||
|
||||
public void Render(WorldRenderer wr)
|
||||
{
|
||||
if (!hasSetupPalettes)
|
||||
{
|
||||
hasSetupPalettes = true;
|
||||
foreach (var rt in world.WorldActor.TraitsImplementing<ResourceType>())
|
||||
rt.info.PaletteRef = wr.Palette(rt.info.Palette);
|
||||
}
|
||||
|
||||
var clip = wr.Viewport.CellBounds;
|
||||
for (var x = clip.Left; x < clip.Right; x++)
|
||||
{
|
||||
@@ -46,13 +39,23 @@ namespace OpenRA.Traits
|
||||
continue;
|
||||
|
||||
var c = render[x, y];
|
||||
if (c.Image != null)
|
||||
new SpriteRenderable(c.Image[c.Density], pos.CenterPosition,
|
||||
WVec.Zero, -511, c.Type.info.PaletteRef, 1f, true).Render(wr);
|
||||
if (c.Sprite != null)
|
||||
new SpriteRenderable(c.Sprite, pos.CenterPosition,
|
||||
WVec.Zero, -511, c.Type.Palette, 1f, true).Render(wr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int GetAdjacentCellsWith(ResourceType t, int i, int j)
|
||||
{
|
||||
var sum = 0;
|
||||
for (var u = -1; u < 2; u++)
|
||||
for (var v = -1; v < 2; v++)
|
||||
if (content[i + u, j + v].Type == t)
|
||||
++sum;
|
||||
return sum;
|
||||
}
|
||||
|
||||
public void WorldLoaded(World w, WorldRenderer wr)
|
||||
{
|
||||
this.world = w;
|
||||
@@ -60,41 +63,66 @@ namespace OpenRA.Traits
|
||||
render = new CellContents[w.Map.MapSize.X, w.Map.MapSize.Y];
|
||||
dirty = new List<CPos>();
|
||||
|
||||
resourceTypes = w.WorldActor.TraitsImplementing<ResourceType>().ToArray();
|
||||
foreach (var rt in resourceTypes)
|
||||
rt.info.Sprites = rt.info.SpriteNames.Select(a => Game.modData.SpriteLoader.LoadAllSprites(a)).ToArray();
|
||||
var resources = w.WorldActor.TraitsImplementing<ResourceType>()
|
||||
.ToDictionary(r => r.Info.ResourceType, r => r);
|
||||
|
||||
var map = w.Map;
|
||||
|
||||
for (var x = map.Bounds.Left; x < map.Bounds.Right; x++)
|
||||
for (var y = map.Bounds.Top; y < map.Bounds.Bottom; y++)
|
||||
{
|
||||
var type = resourceTypes.FirstOrDefault(
|
||||
r => r.info.ResourceType == w.Map.MapResources.Value[x, y].Type);
|
||||
|
||||
if (type == null)
|
||||
continue;
|
||||
|
||||
if (!AllowResourceAt(type, new CPos(x, y)))
|
||||
continue;
|
||||
|
||||
render[x, y].Type = content[x, y].Type = type;
|
||||
render[x, y].Image = content[x, y].Image = ChooseContent(type);
|
||||
}
|
||||
|
||||
for (var x = map.Bounds.Left; x < map.Bounds.Right; x++)
|
||||
{
|
||||
for (var y = map.Bounds.Top; y < map.Bounds.Bottom; y++)
|
||||
{
|
||||
if (content[x, y].Type != null)
|
||||
var cell = new CPos(x, y);
|
||||
ResourceType t;
|
||||
if (!resources.TryGetValue(w.Map.MapResources.Value[x, y].Type, out t))
|
||||
continue;
|
||||
|
||||
if (!AllowResourceAt(t, cell))
|
||||
continue;
|
||||
|
||||
content[x, y] = CreateResourceCell(t, cell);
|
||||
}
|
||||
}
|
||||
|
||||
// Set initial density based on the number of neighboring resources
|
||||
for (var x = map.Bounds.Left; x < map.Bounds.Right; x++)
|
||||
{
|
||||
for (var y = map.Bounds.Top; y < map.Bounds.Bottom; y++)
|
||||
{
|
||||
var type = content[x, y].Type;
|
||||
if (type != null)
|
||||
{
|
||||
render[x, y].Density = content[x, y].Density = GetIdealDensity(x, y);
|
||||
w.Map.CustomTerrain[x, y] = content[x, y].Type.info.TerrainType;
|
||||
// Adjacent includes the current cell, so is always >= 1
|
||||
var adjacent = GetAdjacentCellsWith(type, x, y);
|
||||
var density = int2.Lerp(0, type.Info.MaxDensity, adjacent, 9);
|
||||
content[x, y].Density = density;
|
||||
|
||||
render[x, y] = content[x, y];
|
||||
UpdateRenderedSprite(new CPos(x, y));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual void UpdateRenderedSprite(CPos p)
|
||||
{
|
||||
var t = render[p.X, p.Y];
|
||||
if (t.Density > 0)
|
||||
{
|
||||
var sprites = t.Type.Variants[t.Variant];
|
||||
var frame = int2.Lerp(0, sprites.Length - 1, t.Density - 1, t.Type.Info.MaxDensity);
|
||||
t.Sprite = sprites[frame];
|
||||
}
|
||||
else
|
||||
t.Sprite = null;
|
||||
|
||||
render[p.X, p.Y] = t;
|
||||
}
|
||||
|
||||
protected virtual string ChooseRandomVariant(ResourceType t)
|
||||
{
|
||||
return t.Variants.Keys.Random(Game.CosmeticRandom);
|
||||
}
|
||||
|
||||
public void TickRender(WorldRenderer wr, Actor self)
|
||||
{
|
||||
var remove = new List<CPos>();
|
||||
@@ -103,6 +131,7 @@ namespace OpenRA.Traits
|
||||
if (!self.World.FogObscures(c))
|
||||
{
|
||||
render[c.X, c.Y] = content[c.X, c.Y];
|
||||
UpdateRenderedSprite(c);
|
||||
remove.Add(c);
|
||||
}
|
||||
}
|
||||
@@ -116,62 +145,45 @@ namespace OpenRA.Traits
|
||||
if (!world.Map.IsInMap(a.X, a.Y))
|
||||
return false;
|
||||
|
||||
if (!rt.info.AllowedTerrainTypes.Contains(world.GetTerrainInfo(a).Type))
|
||||
if (!rt.Info.AllowedTerrainTypes.Contains(world.GetTerrainInfo(a).Type))
|
||||
return false;
|
||||
|
||||
if (!rt.info.AllowUnderActors && world.ActorMap.AnyUnitsAt(a))
|
||||
if (!rt.Info.AllowUnderActors && world.ActorMap.AnyUnitsAt(a))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
Sprite[] ChooseContent(ResourceType t)
|
||||
CellContents CreateResourceCell(ResourceType t, CPos p)
|
||||
{
|
||||
return t.info.Sprites[world.SharedRandom.Next(t.info.Sprites.Length)];
|
||||
}
|
||||
|
||||
int GetAdjacentCellsWith(ResourceType t, int i, int j)
|
||||
{
|
||||
int sum = 0;
|
||||
for (var u = -1; u < 2; u++)
|
||||
for (var v = -1; v < 2; v++)
|
||||
if (content[i + u, j + v].Type == t)
|
||||
++sum;
|
||||
return sum;
|
||||
}
|
||||
|
||||
int GetIdealDensity(int x, int y)
|
||||
{
|
||||
return (GetAdjacentCellsWith(content[x, y].Type, x, y) *
|
||||
(content[x, y].Image.Length - 1)) / 9;
|
||||
}
|
||||
|
||||
public void AddResource(ResourceType t, int i, int j, int n)
|
||||
{
|
||||
if (content[i, j].Type == null)
|
||||
world.Map.CustomTerrain[p.X, p.Y] = t.Info.TerrainType;
|
||||
return new CellContents
|
||||
{
|
||||
content[i, j].Type = t;
|
||||
content[i, j].Image = ChooseContent(t);
|
||||
content[i, j].Density = -1;
|
||||
}
|
||||
Type = t,
|
||||
Variant = ChooseRandomVariant(t),
|
||||
Density = t.Info.MaxDensity,
|
||||
};
|
||||
}
|
||||
|
||||
if (content[i, j].Type != t)
|
||||
public void AddResource(ResourceType t, CPos p, int n)
|
||||
{
|
||||
var cell = content[p.X, p.Y];
|
||||
if (cell.Type == null)
|
||||
cell = CreateResourceCell(t, p);
|
||||
|
||||
if (cell.Type != t)
|
||||
return;
|
||||
|
||||
content[i, j].Density = Math.Min(
|
||||
content[i, j].Image.Length - 1,
|
||||
content[i, j].Density + n);
|
||||
cell.Density = Math.Min(cell.Type.Info.MaxDensity, cell.Density + n);
|
||||
content[p.X, p.Y] = cell;
|
||||
|
||||
world.Map.CustomTerrain[i, j] = t.info.TerrainType;
|
||||
|
||||
var cell = new CPos(i, j);
|
||||
if (!dirty.Contains(cell))
|
||||
dirty.Add(cell);
|
||||
if (!dirty.Contains(p))
|
||||
dirty.Add(p);
|
||||
}
|
||||
|
||||
public bool IsFull(int i, int j)
|
||||
{
|
||||
return content[i, j].Density == content[i, j].Image.Length - 1;
|
||||
return content[i, j].Density == content[i, j].Type.Info.MaxDensity;
|
||||
}
|
||||
|
||||
public ResourceType Harvest(CPos p)
|
||||
@@ -181,11 +193,7 @@ namespace OpenRA.Traits
|
||||
return null;
|
||||
|
||||
if (--content[p.X, p.Y].Density < 0)
|
||||
{
|
||||
content[p.X, p.Y].Type = null;
|
||||
content[p.X, p.Y].Image = null;
|
||||
world.Map.CustomTerrain[p.X, p.Y] = null;
|
||||
}
|
||||
content[p.X, p.Y] = EmptyCell;
|
||||
|
||||
if (!dirty.Contains(p))
|
||||
dirty.Add(p);
|
||||
@@ -199,10 +207,8 @@ namespace OpenRA.Traits
|
||||
if (content[p.X, p.Y].Type == null)
|
||||
return;
|
||||
|
||||
content[p.X, p.Y].Type = null;
|
||||
content[p.X, p.Y].Image = null;
|
||||
content[p.X, p.Y].Density = 0;
|
||||
world.Map.CustomTerrain[p.X, p.Y] = null;
|
||||
// Clear cell
|
||||
content[p.X, p.Y] = EmptyCell;
|
||||
|
||||
if (!dirty.Contains(p))
|
||||
dirty.Add(p);
|
||||
@@ -213,17 +219,18 @@ namespace OpenRA.Traits
|
||||
public int GetResourceDensity(CPos p) { return content[p.X, p.Y].Density; }
|
||||
public int GetMaxResourceDensity(CPos p)
|
||||
{
|
||||
if (content[p.X, p.Y].Image == null)
|
||||
if (content[p.X, p.Y].Type == null)
|
||||
return 0;
|
||||
|
||||
return content[p.X, p.Y].Image.Length - 1;
|
||||
return content[p.X, p.Y].Type.Info.MaxDensity;
|
||||
}
|
||||
|
||||
public struct CellContents
|
||||
{
|
||||
public ResourceType Type;
|
||||
public Sprite[] Image;
|
||||
public int Density;
|
||||
public string Variant;
|
||||
public Sprite Sprite;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,37 +8,54 @@
|
||||
*/
|
||||
#endregion
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using OpenRA.Graphics;
|
||||
|
||||
namespace OpenRA.Traits
|
||||
{
|
||||
public class ResourceTypeInfo : ITraitInfo
|
||||
{
|
||||
public readonly string[] SpriteNames = { };
|
||||
// Hack: The editor is getting really unmaintanable...
|
||||
public readonly string EditorSprite;
|
||||
public readonly string[] Variants = { };
|
||||
public readonly string Palette = "terrain";
|
||||
public readonly int ResourceType = 1;
|
||||
|
||||
public readonly int ValuePerUnit = 0;
|
||||
public readonly int MaxDensity = 10;
|
||||
public readonly string Name = null;
|
||||
public readonly string TerrainType = "Ore";
|
||||
|
||||
public readonly string[] AllowedTerrainTypes = { };
|
||||
public readonly bool AllowUnderActors = false;
|
||||
|
||||
public Sprite[][] Sprites;
|
||||
public PaletteReference PaletteRef;
|
||||
|
||||
public PipType PipColor = PipType.Yellow;
|
||||
|
||||
public object Create(ActorInitializer init) { return new ResourceType(this); }
|
||||
}
|
||||
|
||||
public class ResourceType
|
||||
public class ResourceType : IWorldLoaded
|
||||
{
|
||||
public ResourceTypeInfo info;
|
||||
public readonly ResourceTypeInfo Info;
|
||||
public PaletteReference Palette { get; private set; }
|
||||
public readonly Dictionary<string, Sprite[]> Variants;
|
||||
|
||||
public ResourceType(ResourceTypeInfo info)
|
||||
{
|
||||
this.info = info;
|
||||
this.Info = info;
|
||||
Variants = new Dictionary<string, Sprite[]>();
|
||||
foreach (var v in info.Variants)
|
||||
{
|
||||
var seq = SequenceProvider.GetSequence("resources", v);
|
||||
var sprites = Exts.MakeArray(seq.Length, x => seq.GetSprite(x));
|
||||
Variants.Add(v, sprites);
|
||||
}
|
||||
}
|
||||
|
||||
public void WorldLoaded(World w, WorldRenderer wr)
|
||||
{
|
||||
Palette = wr.Palette(Info.Palette);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,7 +35,7 @@ namespace OpenRA.Mods.Cnc
|
||||
var rl = self.World.WorldActor.Trait<ResourceLayer>();
|
||||
var r = rl.GetResource(self.Location);
|
||||
if (r == null) return;
|
||||
if (!info.Resources.Contains(r.info.Name)) return;
|
||||
if (!info.Resources.Contains(r.Info.Name)) return;
|
||||
|
||||
var weapon = Rules.Weapons[info.Weapon.ToLowerInvariant()];
|
||||
|
||||
|
||||
172
OpenRA.Mods.D2k/D2kResourceLayer.cs
Normal file
172
OpenRA.Mods.D2k/D2kResourceLayer.cs
Normal file
@@ -0,0 +1,172 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright 2007-2013 The OpenRA Developers (see AUTHORS)
|
||||
* This file is part of OpenRA, which is free software. It is made
|
||||
* available to you under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation. For more information,
|
||||
* see COPYING.
|
||||
*/
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using OpenRA.FileFormats;
|
||||
using OpenRA.Graphics;
|
||||
|
||||
namespace OpenRA.Traits
|
||||
{
|
||||
public class D2kResourceLayerInfo : TraitInfo<D2kResourceLayer> { }
|
||||
|
||||
public class D2kResourceLayer : ResourceLayer
|
||||
{
|
||||
[Flags] enum ClearSides : byte
|
||||
{
|
||||
None = 0x0,
|
||||
Left = 0x1,
|
||||
Top = 0x2,
|
||||
Right = 0x4,
|
||||
Bottom = 0x8,
|
||||
|
||||
TopLeft = 0x10,
|
||||
TopRight = 0x20,
|
||||
BottomLeft = 0x40,
|
||||
BottomRight = 0x80,
|
||||
|
||||
All = 0xFF
|
||||
};
|
||||
|
||||
static readonly Dictionary<string, int[]> variants = new Dictionary<string, int[]>()
|
||||
{
|
||||
{ "cleara", new[] { 0, 50 } },
|
||||
{ "clearb", new[] { 1, 51 } },
|
||||
{ "clearc", new[] { 43, 52 } },
|
||||
{ "cleard", new[] { 0, 53 } },
|
||||
};
|
||||
|
||||
static readonly Dictionary<ClearSides, int> spriteMap = new Dictionary<ClearSides, int>()
|
||||
{
|
||||
{ ClearSides.None, 0 },
|
||||
{ ClearSides.Left | ClearSides.Top | ClearSides.TopLeft | ClearSides.TopRight | ClearSides.BottomLeft | ClearSides.BottomRight, 2 },
|
||||
{ ClearSides.Top | ClearSides.Right | ClearSides.TopLeft | ClearSides.TopRight | ClearSides.BottomLeft | ClearSides.BottomRight, 3 },
|
||||
{ ClearSides.Left | ClearSides.Bottom | ClearSides.TopLeft | ClearSides.TopRight | ClearSides.BottomLeft | ClearSides.BottomRight, 4 },
|
||||
{ ClearSides.Right | ClearSides.Bottom | ClearSides.TopLeft | ClearSides.TopRight | ClearSides.BottomLeft | ClearSides.BottomRight, 5 },
|
||||
{ ClearSides.Left | ClearSides.TopLeft | ClearSides.TopRight | ClearSides.BottomLeft | ClearSides.BottomRight, 6 },
|
||||
{ ClearSides.Right | ClearSides.TopLeft | ClearSides.TopRight | ClearSides.BottomLeft | ClearSides.BottomRight, 7 },
|
||||
{ ClearSides.Top | ClearSides.TopLeft | ClearSides.TopRight | ClearSides.BottomLeft | ClearSides.BottomRight, 8 },
|
||||
{ ClearSides.Bottom | ClearSides.TopLeft | ClearSides.TopRight | ClearSides.BottomLeft | ClearSides.BottomRight, 9 },
|
||||
{ ClearSides.Left | ClearSides.Top | ClearSides.TopLeft | ClearSides.TopRight | ClearSides.BottomLeft, 10 },
|
||||
{ ClearSides.Top | ClearSides.Right | ClearSides.TopLeft | ClearSides.TopRight | ClearSides.BottomRight, 11 },
|
||||
{ ClearSides.Left | ClearSides.Bottom | ClearSides.TopLeft | ClearSides.BottomLeft | ClearSides.BottomRight, 12 },
|
||||
{ ClearSides.Right | ClearSides.Bottom | ClearSides.TopRight | ClearSides.BottomLeft | ClearSides.BottomRight, 13 },
|
||||
{ ClearSides.Left | ClearSides.Top | ClearSides.Right | ClearSides.TopLeft | ClearSides.TopRight | ClearSides.BottomLeft | ClearSides.BottomRight, 14 },
|
||||
{ ClearSides.Left | ClearSides.Right | ClearSides.Bottom | ClearSides.TopLeft | ClearSides.TopRight | ClearSides.BottomLeft | ClearSides.BottomRight, 15 },
|
||||
{ ClearSides.Left | ClearSides.Top | ClearSides.Bottom | ClearSides.TopLeft | ClearSides.TopRight | ClearSides.BottomLeft | ClearSides.BottomRight, 16 },
|
||||
{ ClearSides.Top | ClearSides.Right | ClearSides.Bottom | ClearSides.TopLeft | ClearSides.TopRight | ClearSides.BottomLeft | ClearSides.BottomRight, 17 },
|
||||
{ ClearSides.Top | ClearSides.TopLeft | ClearSides.TopRight, 18 },
|
||||
{ ClearSides.Right | ClearSides.TopRight | ClearSides.BottomRight, 19 },
|
||||
{ ClearSides.Left | ClearSides.TopLeft | ClearSides.BottomLeft, 20 },
|
||||
{ ClearSides.Bottom | ClearSides.BottomLeft | ClearSides.BottomRight, 21 },
|
||||
{ ClearSides.TopLeft, 22 },
|
||||
{ ClearSides.TopRight, 23 },
|
||||
{ ClearSides.BottomLeft, 24 },
|
||||
{ ClearSides.BottomRight, 25 },
|
||||
{ ClearSides.Left | ClearSides.TopLeft | ClearSides.BottomLeft | ClearSides.BottomRight, 26 },
|
||||
{ ClearSides.Right | ClearSides.TopRight | ClearSides.BottomLeft | ClearSides.BottomRight, 27 },
|
||||
{ ClearSides.Top | ClearSides.TopLeft | ClearSides.TopRight | ClearSides.BottomRight, 28 },
|
||||
{ ClearSides.Top | ClearSides.TopLeft | ClearSides.TopRight | ClearSides.BottomLeft, 29 },
|
||||
{ ClearSides.TopRight | ClearSides.BottomLeft | ClearSides.BottomRight, 30 },
|
||||
{ ClearSides.TopLeft | ClearSides.BottomLeft | ClearSides.BottomRight, 31 },
|
||||
{ ClearSides.TopLeft | ClearSides.TopRight | ClearSides.BottomRight, 32 },
|
||||
{ ClearSides.TopLeft | ClearSides.TopRight | ClearSides.BottomLeft, 33 },
|
||||
{ ClearSides.TopRight | ClearSides.BottomRight, 34 },
|
||||
{ ClearSides.TopLeft | ClearSides.TopRight, 35 },
|
||||
{ ClearSides.TopRight | ClearSides.BottomLeft, 36 },
|
||||
{ ClearSides.TopLeft | ClearSides.BottomLeft, 37 },
|
||||
{ ClearSides.BottomLeft | ClearSides.BottomRight, 38 },
|
||||
{ ClearSides.TopLeft | ClearSides.BottomRight, 39 },
|
||||
{ ClearSides.TopLeft | ClearSides.TopRight | ClearSides.BottomLeft | ClearSides.BottomRight, 40 },
|
||||
{ ClearSides.Left | ClearSides.Right | ClearSides.TopLeft | ClearSides.TopRight | ClearSides.BottomLeft | ClearSides.BottomRight, 41 },
|
||||
{ ClearSides.Top | ClearSides.Bottom | ClearSides.TopLeft | ClearSides.TopRight | ClearSides.BottomLeft | ClearSides.BottomRight, 42 },
|
||||
{ ClearSides.All, 44 },
|
||||
{ ClearSides.Left | ClearSides.TopLeft | ClearSides.TopRight | ClearSides.BottomLeft, 46 },
|
||||
{ ClearSides.Right | ClearSides.TopLeft | ClearSides.TopRight | ClearSides.BottomRight, 47 },
|
||||
{ ClearSides.Bottom | ClearSides.TopRight | ClearSides.BottomLeft | ClearSides.BottomRight, 48 },
|
||||
{ ClearSides.Bottom | ClearSides.TopLeft | ClearSides.BottomLeft | ClearSides.BottomRight, 49 },
|
||||
};
|
||||
|
||||
ClearSides FindClearSides(ResourceType t, CPos p)
|
||||
{
|
||||
var ret = ClearSides.None;
|
||||
if (render[p.X, p.Y - 1].Type != t)
|
||||
ret |= ClearSides.Top | ClearSides.TopLeft | ClearSides.TopRight;
|
||||
|
||||
if (render[p.X - 1, p.Y].Type != t)
|
||||
ret |= ClearSides.Left | ClearSides.TopLeft | ClearSides.BottomLeft;
|
||||
|
||||
if (render[p.X + 1, p.Y].Type != t)
|
||||
ret |= ClearSides.Right | ClearSides.TopRight | ClearSides.BottomRight;
|
||||
|
||||
if (render[p.X, p.Y + 1].Type != t)
|
||||
ret |= ClearSides.Bottom | ClearSides.BottomLeft | ClearSides.BottomRight;
|
||||
|
||||
if (render[p.X - 1, p.Y - 1].Type != t)
|
||||
ret |= ClearSides.TopLeft;
|
||||
|
||||
if (render[p.X + 1, p.Y - 1].Type != t)
|
||||
ret |= ClearSides.TopRight;
|
||||
|
||||
if (render[p.X - 1, p.Y + 1].Type != t)
|
||||
ret |= ClearSides.BottomLeft;
|
||||
|
||||
if (render[p.X + 1, p.Y + 1].Type != t)
|
||||
ret |= ClearSides.BottomRight;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void UpdateRenderedTileInner(CPos p)
|
||||
{
|
||||
var t = render[p.X, p.Y];
|
||||
if (t.Density > 0)
|
||||
{
|
||||
var clear = FindClearSides(t.Type, p);
|
||||
int index;
|
||||
|
||||
if (clear == ClearSides.None)
|
||||
{
|
||||
var sprites = variants[t.Variant];
|
||||
var frame = t.Density > t.Type.Info.MaxDensity / 2 ? 1 : 0;
|
||||
t.Sprite = t.Type.Variants.First().Value[sprites[frame]];
|
||||
}
|
||||
else if (spriteMap.TryGetValue(clear, out index))
|
||||
t.Sprite = t.Type.Variants.First().Value[index];
|
||||
else
|
||||
t.Sprite = null;
|
||||
}
|
||||
else
|
||||
t.Sprite = null;
|
||||
|
||||
render[p.X, p.Y] = t;
|
||||
}
|
||||
|
||||
protected override void UpdateRenderedSprite(CPos p)
|
||||
{
|
||||
// Need to update neighbouring tiles too
|
||||
UpdateRenderedTileInner(p);
|
||||
UpdateRenderedTileInner(p + new CVec(-1, -1));
|
||||
UpdateRenderedTileInner(p + new CVec(0, -1));
|
||||
UpdateRenderedTileInner(p + new CVec(1, -1));
|
||||
UpdateRenderedTileInner(p + new CVec(-1, 0));
|
||||
UpdateRenderedTileInner(p + new CVec(1, 0));
|
||||
UpdateRenderedTileInner(p + new CVec(-1, 1));
|
||||
UpdateRenderedTileInner(p + new CVec(0, 1));
|
||||
UpdateRenderedTileInner(p + new CVec(1, 1));
|
||||
}
|
||||
|
||||
protected override string ChooseRandomVariant(ResourceType t)
|
||||
{
|
||||
return variants.Keys.Random(Game.CosmeticRandom);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -79,6 +79,7 @@
|
||||
<Compile Include="Widgets\Logic\D2kInstallFromCDLogic.cs" />
|
||||
<Compile Include="Render\WithCrumbleOverlay.cs" />
|
||||
<Compile Include="PaletteFromR8.cs" />
|
||||
<Compile Include="D2kResourceLayer.cs" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
|
||||
<PropertyGroup>
|
||||
|
||||
@@ -73,7 +73,7 @@ namespace OpenRA.Mods.RA.Activities
|
||||
|
||||
if (resType == null) return 1;
|
||||
// Can the harvester collect this kind of resource?
|
||||
if (!harvInfo.Resources.Contains(resType.info.Name)) return 1;
|
||||
if (!harvInfo.Resources.Contains(resType.Info.Name)) return 1;
|
||||
|
||||
if (territory != null)
|
||||
{
|
||||
|
||||
@@ -143,8 +143,8 @@ namespace OpenRA.Mods.RA
|
||||
|
||||
public void AcceptResource(ResourceType type)
|
||||
{
|
||||
if (!contents.ContainsKey(type.info)) contents[type.info] = 1;
|
||||
else contents[type.info]++;
|
||||
if (!contents.ContainsKey(type.Info)) contents[type.Info] = 1;
|
||||
else contents[type.Info]++;
|
||||
}
|
||||
|
||||
public void UnblockRefinery(Actor self)
|
||||
@@ -357,7 +357,7 @@ namespace OpenRA.Mods.RA
|
||||
|
||||
if (resType == null) return 1;
|
||||
// Can the harvester collect this kind of resource?
|
||||
if (!harvInfo.Resources.Contains(resType.info.Name)) return 1;
|
||||
if (!harvInfo.Resources.Contains(resType.Info.Name)) return 1;
|
||||
|
||||
// Another harvester has claimed this resource:
|
||||
if (territory != null)
|
||||
@@ -436,7 +436,7 @@ namespace OpenRA.Mods.RA
|
||||
var res = self.World.WorldActor.Trait<ResourceLayer>().GetRenderedResource(location);
|
||||
var info = self.Info.Traits.Get<HarvesterInfo>();
|
||||
|
||||
if (res == null || !info.Resources.Contains(res.info.Name))
|
||||
if (res == null || !info.Resources.Contains(res.Info.Name))
|
||||
return false;
|
||||
|
||||
cursor = "harvest";
|
||||
|
||||
@@ -36,7 +36,7 @@ namespace OpenRA.Mods.RA
|
||||
var info = self.Info.Traits.Get<SeedsResourceInfo>();
|
||||
var resourceType = self.World.WorldActor
|
||||
.TraitsImplementing<ResourceType>()
|
||||
.FirstOrDefault(t => t.info.Name == info.ResourceType);
|
||||
.FirstOrDefault(t => t.Info.Name == info.ResourceType);
|
||||
|
||||
if (resourceType == null)
|
||||
throw new InvalidOperationException("No such resource type `{0}`".F(info.ResourceType));
|
||||
@@ -51,7 +51,7 @@ namespace OpenRA.Mods.RA
|
||||
if (cell != null && self.World.Map.IsInMap(cell.Value) &&
|
||||
(resLayer.GetResource(cell.Value) == resourceType
|
||||
|| (resLayer.GetResource(cell.Value) == null && resLayer.AllowResourceAt(resourceType, cell.Value))))
|
||||
resLayer.AddResource(resourceType, cell.Value.X, cell.Value.Y, 1);
|
||||
resLayer.AddResource(resourceType, cell.Value, 1);
|
||||
|
||||
ticks = info.Interval;
|
||||
}
|
||||
|
||||
@@ -292,7 +292,9 @@ World:
|
||||
ResourceType: 1
|
||||
Palette: staticterrain
|
||||
TerrainType: Tiberium
|
||||
SpriteNames: ti1,ti2,ti3,ti4,ti5,ti6,ti7,ti8,ti9,ti10,ti11,ti12
|
||||
EditorSprite: ti1
|
||||
Variants: ti1,ti2,ti3,ti4,ti5,ti6,ti7,ti8,ti9,ti10,ti11,ti12
|
||||
MaxDensity: 12
|
||||
ValuePerUnit: 35
|
||||
Name: Tiberium
|
||||
PipColor: Green
|
||||
@@ -302,7 +304,9 @@ World:
|
||||
ResourceType: 2
|
||||
Palette: staticterrain
|
||||
TerrainType: BlueTiberium
|
||||
SpriteNames: bti1,bti2,bti3,bti4,bti5,bti6,bti7,bti8,bti9,bti10,bti11,bti12
|
||||
EditorSprite: bti1
|
||||
Variants: bti1,bti2,bti3,bti4,bti5,bti6,bti7,bti8,bti9,bti10,bti11,bti12
|
||||
MaxDensity: 12
|
||||
ValuePerUnit: 75
|
||||
Name: BlueTiberium
|
||||
PipColor: Blue
|
||||
|
||||
@@ -310,4 +310,54 @@ moveflsh:
|
||||
idle:
|
||||
Start: 0
|
||||
Length: *
|
||||
Tick: 80
|
||||
Tick: 80
|
||||
|
||||
resources:
|
||||
ti1: ti1
|
||||
Length: *
|
||||
ti2: ti2
|
||||
Length: *
|
||||
ti3: ti3
|
||||
Length: *
|
||||
ti4: ti4
|
||||
Length: *
|
||||
ti5: ti5
|
||||
Length: *
|
||||
ti6: ti6
|
||||
Length: *
|
||||
ti7: ti7
|
||||
Length: *
|
||||
ti8: ti8
|
||||
Length: *
|
||||
ti9: ti9
|
||||
Length: *
|
||||
ti10: ti10
|
||||
Length: *
|
||||
ti11: ti11
|
||||
Length: *
|
||||
ti12: ti12
|
||||
Length: *
|
||||
bti1: bti1
|
||||
Length: *
|
||||
bti2: bti2
|
||||
Length: *
|
||||
bti3: bti3
|
||||
Length: *
|
||||
bti4: bti4
|
||||
Length: *
|
||||
bti5: bti5
|
||||
Length: *
|
||||
bti6: bti6
|
||||
Length: *
|
||||
bti7: bti7
|
||||
Length: *
|
||||
bti8: bti8
|
||||
Length: *
|
||||
bti9: bti9
|
||||
Length: *
|
||||
bti10: bti10
|
||||
Length: *
|
||||
bti11: bti11
|
||||
Length: *
|
||||
bti12: bti12
|
||||
Length: *
|
||||
Binary file not shown.
@@ -441,13 +441,15 @@ World:
|
||||
Race: ordos
|
||||
DomainIndex:
|
||||
PathfinderDebugOverlay:
|
||||
ResourceLayer:
|
||||
D2kResourceLayer:
|
||||
ResourceClaimLayer:
|
||||
ResourceType@Spice:
|
||||
ResourceType: 1
|
||||
Palette: d2k
|
||||
TerrainType: Spice
|
||||
SpriteNames: spice1
|
||||
EditorSprite: spice0
|
||||
Variants: spice
|
||||
MaxDensity: 20
|
||||
ValuePerUnit: 25
|
||||
Name: Spice
|
||||
PipColor: green
|
||||
|
||||
@@ -304,4 +304,10 @@ moveflsh:
|
||||
Start: 3621
|
||||
Length: 5
|
||||
Tick: 80
|
||||
BlendMode: Subtractive
|
||||
BlendMode: Subtractive
|
||||
|
||||
resources:
|
||||
spice: BLOXBASE
|
||||
Frames: 748, 749, 750, 751, 752, 753, 754, 755, 756, 757, 760, 761, 762, 763, 764, 765, 766, 767, 768, 769, 770, 771, 772, 773, 774, 775, 776, 777, 778, 779, 780, 781, 782, 783, 784, 785, 786, 787, 788, 789, 790, 791, 792, 793, 794, 795, 796, 797, 798, 799, 300, 301, 320, 321
|
||||
Length: 54
|
||||
Offset: -16,-16
|
||||
|
||||
@@ -632,7 +632,9 @@ World:
|
||||
ResourceType@ore:
|
||||
ResourceType: 1
|
||||
Palette: player
|
||||
SpriteNames: gold01,gold02,gold03,gold04
|
||||
EditorSprite: gold01
|
||||
Variants: gold01,gold02,gold03,gold04
|
||||
MaxDensity: 12
|
||||
ValuePerUnit: 25
|
||||
Name: Ore
|
||||
PipColor: Yellow
|
||||
@@ -642,7 +644,9 @@ World:
|
||||
ResourceType@gem:
|
||||
ResourceType: 2
|
||||
Palette: player
|
||||
SpriteNames: gem01,gem02,gem03,gem04
|
||||
EditorSprite: gem01
|
||||
Variants: gem01,gem02,gem03,gem04
|
||||
MaxDensity: 3
|
||||
ValuePerUnit: 50
|
||||
Name: Gems
|
||||
PipColor: Red
|
||||
|
||||
@@ -468,4 +468,22 @@ overlay:
|
||||
target-valid-temperat:
|
||||
Start: 0
|
||||
target-invalid:
|
||||
Start: 1
|
||||
Start: 1
|
||||
|
||||
resources:
|
||||
gold01: gold01
|
||||
Length: *
|
||||
gold02: gold02
|
||||
Length: *
|
||||
gold03: gold03
|
||||
Length: *
|
||||
gold04: gold04
|
||||
Length: *
|
||||
gem01: gem01
|
||||
Length: *
|
||||
gem02: gem02
|
||||
Length: *
|
||||
gem03: gem03
|
||||
Length: *
|
||||
gem04: gem04
|
||||
Length: *
|
||||
@@ -116,6 +116,17 @@ World:
|
||||
Race: nod
|
||||
ResourceLayer:
|
||||
ResourceClaimLayer:
|
||||
ResourceType@gem:
|
||||
ResourceType: 2
|
||||
Palette: player
|
||||
EditorSprite: shadow
|
||||
Variants: fake
|
||||
ValuePerUnit: 50
|
||||
Name: Gems
|
||||
PipColor: Red
|
||||
AllowedTerrainTypes: Clear,Road
|
||||
AllowUnderActors: false
|
||||
TerrainType: Gems
|
||||
PathfinderDebugOverlay:
|
||||
SpawnMapActors:
|
||||
CreateMPPlayers:
|
||||
|
||||
@@ -248,4 +248,9 @@ moveflsh:
|
||||
idle: ring
|
||||
Start: 0
|
||||
Length: *
|
||||
Tick: 30
|
||||
Tick: 30
|
||||
|
||||
# TODO: placeholder
|
||||
resources:
|
||||
fake: shadow
|
||||
Length: *
|
||||
Reference in New Issue
Block a user