Replace ResourceType with strings in interfaces/public methods.

This commit is contained in:
Paul Chote
2021-01-25 22:21:48 +00:00
committed by reaperrr
parent dcd8eccee4
commit 80e92849da
21 changed files with 226 additions and 186 deletions

View File

@@ -56,7 +56,7 @@ namespace OpenRA.Mods.Cnc.Traits
base.Created(self);
}
void INotifyResourceAccepted.OnResourceAccepted(Actor self, Actor refinery, ResourceTypeInfo resourceType, int count, int value)
void INotifyResourceAccepted.OnResourceAccepted(Actor self, Actor refinery, string resourceType, int count, int value)
{
if (IsTraitDisabled)
return;

View File

@@ -67,7 +67,7 @@ namespace OpenRA.Mods.Cnc.Traits
var location = self.Location + direction;
var resource = resourceLayer.GetResource(location);
if (resource.Type == null || resource.Type.Info.Type != info.Type)
if (resource.Type == null || resource.Type != info.Type)
continue;
if (resource.Density < info.Density)

View File

@@ -78,7 +78,7 @@ namespace OpenRA.Mods.Common.Widgets
if (underCursor != null)
editorWidget.SetTooltip(underCursor.Tooltip);
else if (resourceUnderCursor != null)
editorWidget.SetTooltip(resourceUnderCursor.Info.Type);
editorWidget.SetTooltip(resourceUnderCursor);
else
editorWidget.SetTooltip(null);
@@ -150,12 +150,12 @@ namespace OpenRA.Mods.Common.Widgets
ResourceLayerContents resourceContents;
public RemoveResourceAction(IResourceLayer resourceLayer, CPos cell, ResourceType type)
public RemoveResourceAction(IResourceLayer resourceLayer, CPos cell, string resourceType)
{
this.resourceLayer = resourceLayer;
this.cell = cell;
Text = "Removed {0}".F(type.Info.TerrainType);
Text = "Removed {0}".F(resourceType);
}
public void Execute()

View File

@@ -17,7 +17,7 @@ namespace OpenRA.Mods.Common.Widgets
{
public sealed class EditorResourceBrush : IEditorBrush
{
public readonly ResourceType ResourceType;
public readonly string ResourceType;
readonly WorldRenderer worldRenderer;
readonly World world;
@@ -30,18 +30,18 @@ namespace OpenRA.Mods.Common.Widgets
AddResourcesEditorAction action;
bool resourceAdded;
public EditorResourceBrush(EditorViewportControllerWidget editorWidget, ResourceType resource, WorldRenderer wr)
public EditorResourceBrush(EditorViewportControllerWidget editorWidget, string resourceType, WorldRenderer wr)
{
this.editorWidget = editorWidget;
ResourceType = resource;
ResourceType = resourceType;
worldRenderer = wr;
world = wr.World;
editorActionManager = world.WorldActor.Trait<EditorActionManager>();
editorCursor = world.WorldActor.Trait<EditorCursorLayer>();
resourceLayer = world.WorldActor.Trait<IResourceLayer>();
action = new AddResourcesEditorAction(world.Map, resourceLayer, resource);
action = new AddResourcesEditorAction(world.Map, resourceType, resourceLayer);
cursorToken = editorCursor.SetResource(wr, resource);
cursorToken = editorCursor.SetResource(wr, resourceType);
}
public bool HandleMouseInput(MouseInput mi)
@@ -74,7 +74,7 @@ namespace OpenRA.Mods.Common.Widgets
else if (resourceAdded && mi.Button == MouseButton.Left && mi.Event == MouseInputEvent.Up)
{
editorActionManager.Add(action);
action = new AddResourcesEditorAction(world.Map, resourceLayer, ResourceType);
action = new AddResourcesEditorAction(world.Map, ResourceType, resourceLayer);
resourceAdded = false;
}
@@ -93,9 +93,9 @@ namespace OpenRA.Mods.Common.Widgets
{
public readonly CPos Cell;
public readonly ResourceLayerContents OldResourceTile;
public readonly ResourceType NewResourceType;
public readonly string NewResourceType;
public CellResource(CPos cell, ResourceLayerContents oldResourceTile, ResourceType newResourceType)
public CellResource(CPos cell, ResourceLayerContents oldResourceTile, string newResourceType)
{
Cell = cell;
OldResourceTile = oldResourceTile;
@@ -109,14 +109,14 @@ namespace OpenRA.Mods.Common.Widgets
readonly Map map;
readonly IResourceLayer resourceLayer;
readonly ResourceType resourceType;
readonly string resourceType;
readonly List<CellResource> cellResources = new List<CellResource>();
public AddResourcesEditorAction(Map map, IResourceLayer resourceLayer, ResourceType resourceType)
public AddResourcesEditorAction(Map map, string resourceType, IResourceLayer resourceLayer)
{
this.map = map;
this.resourceLayer = resourceLayer;
this.resourceType = resourceType;
this.resourceLayer = resourceLayer;
}
public void Execute()
@@ -128,7 +128,7 @@ namespace OpenRA.Mods.Common.Widgets
foreach (var resourceCell in cellResources)
{
resourceLayer.ClearResources(resourceCell.Cell);
resourceLayer.AddResource(resourceCell.NewResourceType, resourceCell.Cell, resourceCell.NewResourceType.Info.MaxDensity);
resourceLayer.AddResource(resourceCell.NewResourceType, resourceCell.Cell, resourceLayer.GetMaxDensity(resourceCell.NewResourceType));
}
}
@@ -145,11 +145,11 @@ namespace OpenRA.Mods.Common.Widgets
public void Add(CellResource resourceCell)
{
resourceLayer.ClearResources(resourceCell.Cell);
resourceLayer.AddResource(resourceCell.NewResourceType, resourceCell.Cell, resourceCell.NewResourceType.Info.MaxDensity);
resourceLayer.AddResource(resourceCell.NewResourceType, resourceCell.Cell, resourceLayer.GetMaxDensity(resourceCell.NewResourceType));
cellResources.Add(resourceCell);
var cellText = cellResources.Count != 1 ? "cells" : "cell";
Text = "Added {0} {1} of {2}".F(cellResources.Count, cellText, resourceType.Info.TerrainType);
Text = "Added {0} {1} of {2}".F(cellResources.Count, cellText, resourceType);
}
}
}

View File

@@ -57,6 +57,7 @@ namespace OpenRA.Mods.Common.Traits
{
readonly Actor self;
readonly RefineryInfo info;
readonly Dictionary<string, int> resourceValues;
PlayerResources playerResources;
IEnumerable<int> resourceValueModifiers;
@@ -82,6 +83,8 @@ namespace OpenRA.Mods.Common.Traits
this.info = info;
playerResources = self.Owner.PlayerActor.Trait<PlayerResources>();
currentDisplayTick = info.TickRate;
resourceValues = self.World.WorldActor.TraitsImplementing<ResourceType>()
.ToDictionary(r => r.Info.Type, r => r.Info.ValuePerUnit);
}
void INotifyCreated.Created(Actor self)
@@ -100,9 +103,12 @@ namespace OpenRA.Mods.Common.Traits
.Where(a => a.Trait.LinkedProc == self);
}
int IAcceptResources.AcceptResources(ResourceTypeInfo resourceType, int count)
int IAcceptResources.AcceptResources(string resourceType, int count)
{
var value = Util.ApplyPercentageModifiers(count * resourceType.ValuePerUnit, resourceValueModifiers);
if (!resourceValues.TryGetValue(resourceType, out var resourceValue))
return 0;
var value = Util.ApplyPercentageModifiers(count * resourceValue, resourceValueModifiers);
if (info.UseStorage)
{
@@ -111,7 +117,7 @@ namespace OpenRA.Mods.Common.Traits
{
// Reduce amount if needed until it will fit the available storage
while (value > storageLimit)
value = Util.ApplyPercentageModifiers(--count * resourceType.ValuePerUnit, resourceValueModifiers);
value = Util.ApplyPercentageModifiers(--count * resourceValue, resourceValueModifiers);
}
else
value = Math.Min(value, playerResources.ResourceCapacity - playerResources.Resources);

View File

@@ -48,7 +48,7 @@ namespace OpenRA.Mods.Common.Traits
t.MovementCancelled(self);
}
void INotifyHarvesterAction.Harvested(Actor self, ResourceType resource) { }
void INotifyHarvesterAction.Harvested(Actor self, string resourceType) { }
void INotifyHarvesterAction.Docked() { }
void INotifyHarvesterAction.Undocked() { }
}

View File

@@ -214,7 +214,7 @@ namespace OpenRA.Mods.Common.Traits
void INotifyHarvesterAction.MovementCancelled(Actor self) { }
void INotifyHarvesterAction.Harvested(Actor self, ResourceType resource) { }
void INotifyHarvesterAction.Harvested(Actor self, string resourceType) { }
void INotifyHarvesterAction.Docked()
{

View File

@@ -103,12 +103,12 @@ namespace OpenRA.Mods.Common.Traits
ISpeedModifier, ISync, INotifyCreated
{
public readonly HarvesterInfo Info;
public readonly IReadOnlyDictionary<ResourceTypeInfo, int> Contents;
public readonly IReadOnlyDictionary<string, int> Contents;
readonly Mobile mobile;
readonly IResourceLayer resourceLayer;
readonly ResourceClaimLayer claimLayer;
readonly Dictionary<ResourceTypeInfo, int> contents = new Dictionary<ResourceTypeInfo, int>();
readonly Dictionary<string, int> contents = new Dictionary<string, int>();
int conditionToken = Actor.InvalidConditionToken;
[Sync]
@@ -121,13 +121,13 @@ namespace OpenRA.Mods.Common.Traits
int currentUnloadTicks;
[Sync]
public int ContentValue
public int ContentHash
{
get
{
var value = 0;
foreach (var c in contents)
value += c.Key.ValuePerUnit * c.Value;
value += c.Value << c.Key.Length;
return value;
}
}
@@ -135,8 +135,7 @@ namespace OpenRA.Mods.Common.Traits
public Harvester(Actor self, HarvesterInfo info)
{
Info = info;
Contents = new ReadOnlyDictionary<ResourceTypeInfo, int>(contents);
Contents = new ReadOnlyDictionary<string, int>(contents);
mobile = self.Trait<Mobile>();
resourceLayer = self.World.WorldActor.Trait<IResourceLayer>();
claimLayer = self.World.WorldActor.Trait<ResourceClaimLayer>();
@@ -229,12 +228,12 @@ namespace OpenRA.Mods.Common.Traits
conditionToken = self.RevokeCondition(conditionToken);
}
public void AcceptResource(Actor self, ResourceType type)
public void AcceptResource(Actor self, string resourceType)
{
if (!contents.ContainsKey(type.Info))
contents[type.Info] = 1;
if (!contents.ContainsKey(resourceType))
contents[resourceType] = 1;
else
contents[type.Info]++;
contents[resourceType]++;
UpdateCondition(self);
}
@@ -281,7 +280,7 @@ namespace OpenRA.Mods.Common.Traits
return false;
// Can the harvester collect this kind of resource?
return Info.Resources.Contains(resourceType.Info.Type);
return Info.Resources.Contains(resourceType);
}
IEnumerable<IOrderTargeter> IIssueOrder.Orders
@@ -388,7 +387,7 @@ namespace OpenRA.Mods.Common.Traits
var info = self.Info.TraitInfo<HarvesterInfo>();
var res = self.World.WorldActor.TraitsImplementing<IResourceRenderer>()
.Select(r => r.GetRenderedResourceType(location))
.FirstOrDefault(r => r != null && info.Resources.Contains(r.Info.Type));
.FirstOrDefault(r => r != null && info.Resources.Contains(r));
if (res == null)
return false;

View File

@@ -37,7 +37,7 @@ namespace OpenRA.Mods.Common.Traits.Render
wsb = init.Self.TraitsImplementing<WithSpriteBody>().Single(w => w.Info.Name == Info.Body);
}
void INotifyHarvesterAction.Harvested(Actor self, ResourceType resource)
void INotifyHarvesterAction.Harvested(Actor self, string resourceType)
{
var sequence = wsb.NormalizeSequence(self, Info.HarvestSequence);
if (wsb.DefaultAnimation.HasSequence(sequence) && wsb.DefaultAnimation.CurrentSequence.Name != sequence)

View File

@@ -51,7 +51,7 @@ namespace OpenRA.Mods.Common.Traits.Render
p => ZOffsetFromCenter(self, p, 0)), info.Palette);
}
void INotifyHarvesterAction.Harvested(Actor self, ResourceType resource)
void INotifyHarvesterAction.Harvested(Actor self, string resourceType)
{
if (visible)
return;

View File

@@ -65,7 +65,7 @@ namespace OpenRA.Mods.Common.Traits.Render
{
if (n < rt.Value)
{
if (!Info.ResourceSequences.TryGetValue(rt.Key.Type, out var sequence))
if (!Info.ResourceSequences.TryGetValue(rt.Key, out var sequence))
sequence = Info.FullSequence;
return sequence;

View File

@@ -28,21 +28,12 @@ namespace OpenRA.Mods.Common.Traits
class SeedsResource : ConditionalTrait<SeedsResourceInfo>, ITick, ISeedableResource
{
readonly SeedsResourceInfo info;
readonly ResourceType resourceType;
readonly IResourceLayer resourceLayer;
public SeedsResource(Actor self, SeedsResourceInfo info)
: base(info)
{
this.info = info;
resourceType = self.World.WorldActor.TraitsImplementing<ResourceType>()
.FirstOrDefault(t => t.Info.Type == info.ResourceType);
if (resourceType == null)
throw new InvalidOperationException("No such resource type `{0}`".F(info.ResourceType));
resourceLayer = self.World.WorldActor.Trait<IResourceLayer>();
}
@@ -64,11 +55,11 @@ namespace OpenRA.Mods.Common.Traits
{
var cell = Util.RandomWalk(self.Location, self.World.SharedRandom)
.Take(info.MaxRange)
.SkipWhile(p => resourceLayer.GetResource(p).Type == resourceType && !resourceLayer.CanAddResource(resourceType, p))
.SkipWhile(p => resourceLayer.GetResource(p).Type == info.ResourceType && !resourceLayer.CanAddResource(info.ResourceType, p))
.Cast<CPos?>().FirstOrDefault();
if (cell != null && resourceLayer.CanAddResource(resourceType, cell.Value))
resourceLayer.AddResource(resourceType, cell.Value);
if (cell != null && resourceLayer.CanAddResource(info.ResourceType, cell.Value))
resourceLayer.AddResource(info.ResourceType, cell.Value);
}
}
}

View File

@@ -44,7 +44,7 @@ namespace OpenRA.Mods.Common.Traits
bool actorSharesCell;
public TerrainTemplateInfo TerrainTemplate { get; private set; }
public ResourceType Resource { get; private set; }
public string ResourceType { get; private set; }
CPos terrainOrResourceCell;
bool terrainOrResourceDirty;
readonly List<IRenderable> terrainOrResourcePreview = new List<IRenderable>();
@@ -82,7 +82,7 @@ namespace OpenRA.Mods.Common.Traits
if (Type == EditorCursorType.TerrainTemplate)
terrainOrResourcePreview.AddRange(terrainRenderer.RenderPreview(wr, TerrainTemplate, pos));
else
terrainOrResourcePreview.AddRange(resourceRenderers.SelectMany(r => r.RenderPreview(wr, Resource, pos)));
terrainOrResourcePreview.AddRange(resourceRenderers.SelectMany(r => r.RenderPreview(wr, ResourceType, pos)));
}
}
else if (Type == EditorCursorType.Actor)
@@ -181,7 +181,7 @@ namespace OpenRA.Mods.Common.Traits
Type = EditorCursorType.Actor;
Actor = new EditorActorPreview(wr, null, reference, owner);
TerrainTemplate = null;
Resource = null;
ResourceType = null;
return ++CurrentToken;
}
@@ -193,18 +193,18 @@ namespace OpenRA.Mods.Common.Traits
Type = EditorCursorType.TerrainTemplate;
TerrainTemplate = template;
Actor = null;
Resource = null;
ResourceType = null;
terrainOrResourceDirty = true;
return ++CurrentToken;
}
public int SetResource(WorldRenderer wr, ResourceType resource)
public int SetResource(WorldRenderer wr, string resourceType)
{
terrainOrResourceCell = wr.Viewport.ViewToWorld(wr.Viewport.WorldToViewPx(Viewport.LastMousePos));
Type = EditorCursorType.Resource;
Resource = resource;
ResourceType = resourceType;
Actor = null;
TerrainTemplate = null;
terrainOrResourceDirty = true;
@@ -220,7 +220,7 @@ namespace OpenRA.Mods.Common.Traits
Type = EditorCursorType.None;
Actor = null;
TerrainTemplate = null;
Resource = null;
ResourceType = null;
}
}
}

View File

@@ -26,19 +26,28 @@ namespace OpenRA.Mods.Common.Traits
public class EditorResourceLayer : IResourceLayer, IWorldLoaded, INotifyActorDisposing
{
protected readonly Map Map;
protected readonly Dictionary<int, ResourceType> Resources;
protected readonly Dictionary<string, ResourceTypeInfo> ResourceInfo;
protected readonly Dictionary<int, string> Resources;
protected readonly CellLayer<ResourceLayerContents> Tiles;
public int NetWorth { get; protected set; }
bool disposed;
public event Action<CPos, ResourceType> CellChanged;
public event Action<CPos, string> CellChanged;
ResourceLayerContents IResourceLayer.GetResource(CPos cell) { return Tiles.Contains(cell) ? Tiles[cell] : default; }
bool IResourceLayer.CanAddResource(ResourceType resourceType, CPos cell, int amount) { return CanAddResource(resourceType, cell, amount); }
int IResourceLayer.AddResource(ResourceType resourceType, CPos cell, int amount) { return AddResource(resourceType, cell, amount); }
int IResourceLayer.RemoveResource(ResourceType resourceType, CPos cell, int amount) { return RemoveResource(resourceType, cell, amount); }
int IResourceLayer.GetMaxDensity(string resourceType)
{
if (!ResourceInfo.TryGetValue(resourceType, out var resourceInfo))
return 0;
return resourceInfo.MaxDensity;
}
bool IResourceLayer.CanAddResource(string resourceType, CPos cell, int amount) { return CanAddResource(resourceType, cell, amount); }
int IResourceLayer.AddResource(string resourceType, CPos cell, int amount) { return AddResource(resourceType, cell, amount); }
int IResourceLayer.RemoveResource(string resourceType, CPos cell, int amount) { return RemoveResource(resourceType, cell, amount); }
void IResourceLayer.ClearResources(CPos cell) { ClearResources(cell); }
bool IResourceLayer.IsVisible(CPos cell) { return Map.Contains(cell); }
bool IResourceLayer.IsEmpty => false;
@@ -50,8 +59,10 @@ namespace OpenRA.Mods.Common.Traits
Map = self.World.Map;
Tiles = new CellLayer<ResourceLayerContents>(Map);
Resources = self.TraitsImplementing<ResourceType>()
.ToDictionary(r => r.Info.ResourceType, r => r);
ResourceInfo = self.TraitsImplementing<ResourceType>()
.ToDictionary(r => r.Info.Type, r => r.Info);
Resources = ResourceInfo.Values
.ToDictionary(r => r.ResourceType, r => r.Type);
Map.Resources.CellEntryChanged += UpdateCell;
}
@@ -76,10 +87,10 @@ namespace OpenRA.Mods.Common.Traits
var newTile = ResourceLayerContents.Empty;
var newTerrain = byte.MaxValue;
if (Resources.TryGetValue(tile.Type, out var type))
if (Resources.TryGetValue(tile.Type, out var resourceType) && ResourceInfo.TryGetValue(resourceType, out var resourceInfo))
{
newTile = new ResourceLayerContents(type, CalculateCellDensity(type, cell));
newTerrain = Map.Rules.TerrainInfo.GetTerrainIndex(type.Info.TerrainType);
newTile = new ResourceLayerContents(resourceType, CalculateCellDensity(resourceType, cell));
newTerrain = Map.Rules.TerrainInfo.GetTerrainIndex(resourceInfo.TerrainType);
}
// Nothing has changed
@@ -89,7 +100,7 @@ namespace OpenRA.Mods.Common.Traits
UpdateNetWorth(t.Type, t.Density, newTile.Type, newTile.Density);
Tiles[uv] = newTile;
Map.CustomTerrain[uv] = newTerrain;
CellChanged?.Invoke(cell, type);
CellChanged?.Invoke(cell, newTile.Type);
// Neighbouring cell density depends on this cell
foreach (var d in CVec.Directions)
@@ -106,24 +117,24 @@ namespace OpenRA.Mods.Common.Traits
UpdateNetWorth(neighbouringTile.Type, neighbouringTile.Density, neighbouringTile.Type, density);
Tiles[neighbouringCell] = new ResourceLayerContents(neighbouringTile.Type, density);
CellChanged?.Invoke(neighbouringCell, type);
CellChanged?.Invoke(neighbouringCell, neighbouringTile.Type);
}
}
void UpdateNetWorth(ResourceType oldType, int oldDensity, ResourceType newType, int newDensity)
void UpdateNetWorth(string oldResourceType, int oldDensity, string newResourceType, int newDensity)
{
// Density + 1 as workaround for fixing ResourceLayer.Harvest as it would be very disruptive to balancing
if (oldType != null && oldDensity > 0)
NetWorth -= (oldDensity + 1) * oldType.Info.ValuePerUnit;
if (oldResourceType != null && oldDensity > 0 && ResourceInfo.TryGetValue(oldResourceType, out var oldResourceInfo))
NetWorth -= (oldDensity + 1) * oldResourceInfo.ValuePerUnit;
if (newType != null && newDensity > 0)
NetWorth += (newDensity + 1) * newType.Info.ValuePerUnit;
if (newResourceType != null && newDensity > 0 && ResourceInfo.TryGetValue(newResourceType, out var newResourceInfo))
NetWorth += (newDensity + 1) * newResourceInfo.ValuePerUnit;
}
public int CalculateCellDensity(ResourceType type, CPos c)
public int CalculateCellDensity(string resourceType, CPos c)
{
var resources = Map.Resources;
if (type == null || resources[c].Type != type.Info.ResourceType)
if (resourceType == null || !ResourceInfo.TryGetValue(resourceType, out var resourceInfo) || resources[c].Type != resourceInfo.ResourceType)
return 0;
// Set density based on the number of neighboring resources
@@ -133,73 +144,85 @@ namespace OpenRA.Mods.Common.Traits
for (var v = -1; v < 2; v++)
{
var cell = c + new CVec(u, v);
if (resources.Contains(cell) && resources[cell].Type == type.Info.ResourceType)
if (resources.Contains(cell) && resources[cell].Type == resourceInfo.ResourceType)
adjacent++;
}
}
return Math.Max(int2.Lerp(0, type.Info.MaxDensity, adjacent, 9), 1);
return Math.Max(int2.Lerp(0, resourceInfo.MaxDensity, adjacent, 9), 1);
}
bool AllowResourceAt(ResourceType rt, CPos cell)
bool AllowResourceAt(string resourceType, CPos cell)
{
var mapResources = Map.Resources;
if (!mapResources.Contains(cell))
return false;
if (!ResourceInfo.TryGetValue(resourceType, out var resourceInfo))
return false;
// Ignore custom terrain types when spawning resources in the editor
var terrainInfo = Map.Rules.TerrainInfo;
var terrainType = terrainInfo.TerrainTypes[terrainInfo.GetTerrainInfo(Map.Tiles[cell]).TerrainType].Type;
if (!rt.Info.AllowedTerrainTypes.Contains(terrainType))
if (!resourceInfo.AllowedTerrainTypes.Contains(terrainType))
return false;
// TODO: Check against actors in the EditorActorLayer
return rt.Info.AllowOnRamps || Map.Ramp[cell] == 0;
return resourceInfo.AllowOnRamps || Map.Ramp[cell] == 0;
}
bool CanAddResource(ResourceType resourceType, CPos cell, int amount = 1)
bool CanAddResource(string resourceType, CPos cell, int amount = 1)
{
var resources = Map.Resources;
if (!resources.Contains(cell))
return false;
if (!ResourceInfo.TryGetValue(resourceType, out var resourceInfo))
return false;
// The editor allows the user to replace one resource type with another, so treat mismatching resource type as an empty cell
var content = resources[cell];
if (content.Type != resourceType.Info.ResourceType)
return amount <= resourceType.Info.MaxDensity && AllowResourceAt(resourceType, cell);
if (content.Type != resourceInfo.ResourceType)
return amount <= resourceInfo.MaxDensity && AllowResourceAt(resourceType, cell);
var oldDensity = content.Type == resourceType.Info.ResourceType ? content.Index : 0;
return oldDensity + amount <= resourceType.Info.MaxDensity;
var oldDensity = content.Type == resourceInfo.ResourceType ? content.Index : 0;
return oldDensity + amount <= resourceInfo.MaxDensity;
}
int AddResource(ResourceType resourceType, CPos cell, int amount = 1)
int AddResource(string resourceType, CPos cell, int amount = 1)
{
var resources = Map.Resources;
if (!resources.Contains(cell))
return 0;
if (!ResourceInfo.TryGetValue(resourceType, out var resourceInfo))
return 0;
// The editor allows the user to replace one resource type with another, so treat mismatching resource type as an empty cell
var content = resources[cell];
var oldDensity = content.Type == resourceType.Info.ResourceType ? content.Index : 0;
var density = (byte)Math.Min(resourceType.Info.MaxDensity, oldDensity + amount);
Map.Resources[cell] = new ResourceTile((byte)resourceType.Info.ResourceType, density);
var oldDensity = content.Type == resourceInfo.ResourceType ? content.Index : 0;
var density = (byte)Math.Min(resourceInfo.MaxDensity, oldDensity + amount);
Map.Resources[cell] = new ResourceTile((byte)resourceInfo.ResourceType, density);
return density - oldDensity;
}
int RemoveResource(ResourceType resourceType, CPos cell, int amount = 1)
int RemoveResource(string resourceType, CPos cell, int amount = 1)
{
var resources = Map.Resources;
if (!resources.Contains(cell))
return 0;
if (!ResourceInfo.TryGetValue(resourceType, out var resourceInfo))
return 0;
var content = resources[cell];
if (content.Type == 0 || content.Type != resourceType.Info.ResourceType)
if (content.Type == 0 || content.Type != resourceInfo.ResourceType)
return 0;
var oldDensity = content.Index;
var density = (byte)Math.Max(0, oldDensity - amount);
resources[cell] = density > 0 ? new ResourceTile((byte)resourceType.Info.ResourceType, density) : default;
resources[cell] = density > 0 ? new ResourceTile((byte)resourceInfo.ResourceType, density) : default;
return oldDensity - density;
}

View File

@@ -10,6 +10,7 @@
#endregion
using System;
using System.Collections.Generic;
using System.Linq;
using OpenRA.Graphics;
using OpenRA.Traits;
@@ -19,10 +20,10 @@ namespace OpenRA.Mods.Common.Traits
public struct ResourceLayerContents
{
public static readonly ResourceLayerContents Empty = default;
public readonly ResourceType Type;
public readonly string Type;
public readonly int Density;
public ResourceLayerContents(ResourceType type, int density)
public ResourceLayerContents(string type, int density)
{
Type = type;
Density = density;
@@ -39,29 +40,31 @@ namespace OpenRA.Mods.Common.Traits
{
readonly World world;
readonly BuildingInfluence buildingInfluence;
protected readonly Dictionary<string, ResourceTypeInfo> ResourceInfo;
protected readonly CellLayer<ResourceLayerContents> Content;
int resCells;
public event Action<CPos, ResourceType> CellChanged;
public event Action<CPos, string> CellChanged;
public ResourceLayer(Actor self)
{
world = self.World;
buildingInfluence = self.Trait<BuildingInfluence>();
ResourceInfo = self.TraitsImplementing<ResourceType>()
.ToDictionary(r => r.Info.Type, r => r.Info);
Content = new CellLayer<ResourceLayerContents>(world.Map);
}
int GetAdjacentCellsWith(ResourceType t, CPos cell)
int GetAdjacentCellsWith(string resourceType, CPos cell)
{
var sum = 0;
var directions = CVec.Directions;
for (var i = 0; i < directions.Length; i++)
{
var c = cell + directions[i];
if (Content.Contains(c) && Content[c].Type == t)
if (Content.Contains(c) && Content[c].Type == resourceType)
++sum;
}
@@ -71,78 +74,93 @@ namespace OpenRA.Mods.Common.Traits
public void WorldLoaded(World w, WorldRenderer wr)
{
var resources = w.WorldActor.TraitsImplementing<ResourceType>()
.ToDictionary(r => r.Info.ResourceType, r => r);
.ToDictionary(r => r.Info.ResourceType, r => r.Info.Type);
foreach (var cell in w.Map.AllCells)
{
if (!resources.TryGetValue(w.Map.Resources[cell].Type, out var t))
if (!resources.TryGetValue(w.Map.Resources[cell].Type, out var resourceType))
continue;
if (!AllowResourceAt(t, cell))
if (!AllowResourceAt(resourceType, cell))
continue;
Content[cell] = CreateResourceCell(t, cell);
Content[cell] = CreateResourceCell(resourceType, cell);
}
foreach (var cell in w.Map.AllCells)
{
var type = Content[cell].Type;
if (type != null)
var resourceType = Content[cell].Type;
if (resourceType != null && ResourceInfo.TryGetValue(resourceType, out var resourceInfo))
{
// Set initial density based on the number of neighboring resources
// Adjacent includes the current cell, so is always >= 1
var adjacent = GetAdjacentCellsWith(type, cell);
var density = int2.Lerp(0, type.Info.MaxDensity, adjacent, 9);
var adjacent = GetAdjacentCellsWith(resourceType, cell);
var density = int2.Lerp(0, resourceInfo.MaxDensity, adjacent, 9);
Content[cell] = new ResourceLayerContents(Content[cell].Type, Math.Max(density, 1));
}
}
}
public bool AllowResourceAt(ResourceType rt, CPos cell)
public bool AllowResourceAt(string resourceType, CPos cell)
{
if (!ResourceInfo.TryGetValue(resourceType, out var resourceInfo))
return false;
if (!world.Map.Contains(cell))
return false;
if (!rt.Info.AllowedTerrainTypes.Contains(world.Map.GetTerrainInfo(cell).Type))
if (!resourceInfo.AllowedTerrainTypes.Contains(world.Map.GetTerrainInfo(cell).Type))
return false;
if (!rt.Info.AllowUnderActors && world.ActorMap.AnyActorsAt(cell))
if (!resourceInfo.AllowUnderActors && world.ActorMap.AnyActorsAt(cell))
return false;
if (!rt.Info.AllowUnderBuildings && buildingInfluence.GetBuildingAt(cell) != null)
if (!resourceInfo.AllowUnderBuildings && buildingInfluence.GetBuildingAt(cell) != null)
return false;
return rt.Info.AllowOnRamps || world.Map.Ramp[cell] == 0;
return resourceInfo.AllowOnRamps || world.Map.Ramp[cell] == 0;
}
ResourceLayerContents CreateResourceCell(ResourceType t, CPos cell)
ResourceLayerContents CreateResourceCell(string resourceType, CPos cell)
{
world.Map.CustomTerrain[cell] = world.Map.Rules.TerrainInfo.GetTerrainIndex(t.Info.TerrainType);
if (!ResourceInfo.TryGetValue(resourceType, out var resourceInfo))
{
world.Map.CustomTerrain[cell] = byte.MaxValue;
return ResourceLayerContents.Empty;
}
world.Map.CustomTerrain[cell] = world.Map.Rules.TerrainInfo.GetTerrainIndex(resourceInfo.TerrainType);
++resCells;
return new ResourceLayerContents(t, 0);
return new ResourceLayerContents(resourceType, 0);
}
bool CanAddResource(ResourceType resourceType, CPos cell, int amount = 1)
bool CanAddResource(string resourceType, CPos cell, int amount = 1)
{
if (!world.Map.Contains(cell))
return false;
if (!ResourceInfo.TryGetValue(resourceType, out var resourceInfo))
return false;
var content = Content[cell];
if (content.Type == null)
return amount <= resourceType.Info.MaxDensity && AllowResourceAt(resourceType, cell);
return amount <= resourceInfo.MaxDensity && AllowResourceAt(resourceType, cell);
if (content.Type != resourceType)
return false;
return content.Density + amount <= resourceType.Info.MaxDensity;
return content.Density + amount <= resourceInfo.MaxDensity;
}
int AddResource(ResourceType resourceType, CPos cell, int amount = 1)
int AddResource(string resourceType, CPos cell, int amount = 1)
{
if (!Content.Contains(cell))
return 0;
if (!ResourceInfo.TryGetValue(resourceType, out var resourceInfo))
return 0;
var content = Content[cell];
if (content.Type == null)
content = CreateResourceCell(resourceType, cell);
@@ -151,7 +169,7 @@ namespace OpenRA.Mods.Common.Traits
return 0;
var oldDensity = content.Density;
var density = Math.Min(content.Type.Info.MaxDensity, oldDensity + amount);
var density = Math.Min(resourceInfo.MaxDensity, oldDensity + amount);
Content[cell] = new ResourceLayerContents(content.Type, density);
CellChanged?.Invoke(cell, content.Type);
@@ -159,7 +177,7 @@ namespace OpenRA.Mods.Common.Traits
return density - oldDensity;
}
int RemoveResource(ResourceType resourceType, CPos cell, int amount = 1)
int RemoveResource(string resourceType, CPos cell, int amount = 1)
{
if (!Content.Contains(cell))
return 0;
@@ -206,9 +224,17 @@ namespace OpenRA.Mods.Common.Traits
}
ResourceLayerContents IResourceLayer.GetResource(CPos cell) { return Content.Contains(cell) ? Content[cell] : default; }
bool IResourceLayer.CanAddResource(ResourceType resourceType, CPos cell, int amount) { return CanAddResource(resourceType, cell, amount); }
int IResourceLayer.AddResource(ResourceType resourceType, CPos cell, int amount) { return AddResource(resourceType, cell, amount); }
int IResourceLayer.RemoveResource(ResourceType resourceType, CPos cell, int amount) { return RemoveResource(resourceType, cell, amount); }
int IResourceLayer.GetMaxDensity(string resourceType)
{
if (!ResourceInfo.TryGetValue(resourceType, out var resourceInfo))
return 0;
return resourceInfo.MaxDensity;
}
bool IResourceLayer.CanAddResource(string resourceType, CPos cell, int amount) { return CanAddResource(resourceType, cell, amount); }
int IResourceLayer.AddResource(string resourceType, CPos cell, int amount) { return AddResource(resourceType, cell, amount); }
int IResourceLayer.RemoveResource(string resourceType, CPos cell, int amount) { return RemoveResource(resourceType, cell, amount); }
void IResourceLayer.ClearResources(CPos cell) { ClearResources(cell); }
bool IResourceLayer.IsVisible(CPos cell) { return !world.FogObscures(cell); }
bool IResourceLayer.IsEmpty => resCells < 1;

View File

@@ -33,7 +33,7 @@ namespace OpenRA.Mods.Common.Traits
protected readonly IResourceLayer ResourceLayer;
protected readonly CellLayer<RendererCellContents> RenderContent;
protected readonly ResourceRendererInfo Info;
protected readonly World World;
protected readonly Dictionary<string, ResourceType> ResourceInfo;
readonly HashSet<CPos> dirty = new HashSet<CPos>();
readonly Queue<CPos> cleanDirty = new Queue<CPos>();
@@ -43,36 +43,34 @@ namespace OpenRA.Mods.Common.Traits
public ResourceRenderer(Actor self, ResourceRendererInfo info)
{
Info = info;
World = self.World;
ResourceLayer = self.Trait<IResourceLayer>();
ResourceLayer.CellChanged += AddDirtyCell;
ResourceInfo = self.TraitsImplementing<ResourceType>()
.ToDictionary(r => r.Info.Type, r => r);
RenderContent = new CellLayer<RendererCellContents>(self.World.Map);
}
void AddDirtyCell(CPos cell, ResourceType resType)
void AddDirtyCell(CPos cell, string resourceType)
{
if (resType == null || Info.RenderTypes.Contains(resType.Info.Type))
if (resourceType == null || Info.RenderTypes.Contains(resourceType))
dirty.Add(cell);
}
void IWorldLoaded.WorldLoaded(World w, WorldRenderer wr)
{
var resources = w.WorldActor.TraitsImplementing<ResourceType>()
.ToDictionary(r => r.Info.ResourceType, r => r);
foreach (var r in resources)
foreach (var resourceType in ResourceInfo.Values)
{
if (spriteLayer == null)
{
var first = r.Value.Variants.First().Value.GetSprite(0);
var first = resourceType.Variants.First().Value.GetSprite(0);
var emptySprite = new Sprite(first.Sheet, Rectangle.Empty, TextureChannel.Alpha);
spriteLayer = new TerrainSpriteLayer(w, wr, emptySprite, first.BlendMode, wr.World.Type != WorldType.Editor);
}
if (shadowLayer == null)
{
var firstWithShadow = r.Value.Variants.Values.FirstOrDefault(v => v.ShadowStart > 0);
var firstWithShadow = resourceType.Variants.Values.FirstOrDefault(v => v.ShadowStart > 0);
if (firstWithShadow != null)
{
var first = firstWithShadow.GetShadow(0, WAngle.Zero);
@@ -82,7 +80,7 @@ namespace OpenRA.Mods.Common.Traits
}
// All resources must share a blend mode
var sprites = r.Value.Variants.Values.SelectMany(v => Exts.MakeArray(v.Length, x => v.GetSprite(x)));
var sprites = resourceType.Variants.Values.SelectMany(v => Exts.MakeArray(v.Length, x => v.GetSprite(x)));
if (sprites.Any(s => s.BlendMode != spriteLayer.BlendMode))
throw new InvalidDataException("Resource sprites specify different blend modes. "
+ "Try using different ResourceRenderer traits for resource types that use different blend modes.");
@@ -93,10 +91,13 @@ namespace OpenRA.Mods.Common.Traits
foreach (var cell in w.Map.AllCells)
{
var type = ResourceLayer.GetResource(cell).Type;
if (type != null && Info.RenderTypes.Contains(type.Info.Type))
if (type != null && Info.RenderTypes.Contains(type))
{
var resourceContent = ResourceLayer.GetResource(cell);
var rendererCellContents = new RendererCellContents(ChooseRandomVariant(resourceContent.Type), resourceContent.Type, resourceContent.Density);
if (!ResourceInfo.TryGetValue(resourceContent.Type, out var resourceType))
continue;
var rendererCellContents = new RendererCellContents(ChooseRandomVariant(resourceType), resourceType, resourceContent.Density);
RenderContent[cell] = rendererCellContents;
UpdateRenderedSprite(cell, rendererCellContents);
}
@@ -135,11 +136,12 @@ namespace OpenRA.Mods.Common.Traits
if (resourceContent.Density > 0)
{
var cellContents = RenderContent[cell];
var resourceData = ResourceInfo[resourceContent.Type];
var variant = cellContents.Variant;
if (cellContents.Variant == null || cellContents.Type != resourceContent.Type)
variant = ChooseRandomVariant(resourceContent.Type);
if (cellContents.Variant == null || cellContents.Type.Info.Type != resourceContent.Type)
variant = ChooseRandomVariant(resourceData);
var rendererCellContents = new RendererCellContents(variant, resourceContent.Type, resourceContent.Density);
var rendererCellContents = new RendererCellContents(variant, resourceData, resourceContent.Density);
RenderContent[cell] = rendererCellContents;
UpdateRenderedSprite(cell, rendererCellContents);
@@ -199,22 +201,25 @@ namespace OpenRA.Mods.Common.Traits
return t.Variants.Keys.Random(Game.CosmeticRandom);
}
protected virtual ResourceType GetRenderedResourceType(CPos cell) { return RenderContent[cell].Type; }
protected virtual string GetRenderedResourceType(CPos cell) { return RenderContent[cell].Type.Info.Type; }
protected virtual string GetRenderedResourceTooltip(CPos cell) { return RenderContent[cell].Type?.Info.Name; }
IEnumerable<ResourceType> IResourceRenderer.ResourceTypes => World.WorldActor.TraitsImplementing<ResourceType>();
IEnumerable<string> IResourceRenderer.ResourceTypes => ResourceInfo.Keys;
ResourceType IResourceRenderer.GetRenderedResourceType(CPos cell) { return GetRenderedResourceType(cell); }
string IResourceRenderer.GetRenderedResourceType(CPos cell) { return GetRenderedResourceType(cell); }
string IResourceRenderer.GetRenderedResourceTooltip(CPos cell) { return GetRenderedResourceTooltip(cell); }
IEnumerable<IRenderable> IResourceRenderer.RenderUIPreview(WorldRenderer wr, ResourceType resourceType, int2 origin, float scale)
IEnumerable<IRenderable> IResourceRenderer.RenderUIPreview(WorldRenderer wr, string resourceType, int2 origin, float scale)
{
var sequence = resourceType.Variants.First().Value;
if (!ResourceInfo.TryGetValue(resourceType, out var resourceInfo))
yield break;
var sequence = resourceInfo.Variants.First().Value;
var sprite = sequence.GetSprite(sequence.Length - 1);
var shadow = sequence.GetShadow(sequence.Length - 1, WAngle.Zero);
var palette = resourceType.Palette;
var palette = resourceInfo.Palette;
if (shadow != null)
yield return new UISpriteRenderable(shadow, WPos.Zero, origin, 0, palette, scale);
@@ -222,13 +227,16 @@ namespace OpenRA.Mods.Common.Traits
yield return new UISpriteRenderable(sprite, WPos.Zero, origin, 0, palette, scale);
}
IEnumerable<IRenderable> IResourceRenderer.RenderPreview(WorldRenderer wr, ResourceType resourceType, WPos origin)
IEnumerable<IRenderable> IResourceRenderer.RenderPreview(WorldRenderer wr, string resourceType, WPos origin)
{
var sequence = resourceType.Variants.First().Value;
if (!ResourceInfo.TryGetValue(resourceType, out var resourceInfo))
yield break;
var sequence = resourceInfo.Variants.First().Value;
var sprite = sequence.GetSprite(sequence.Length - 1);
var shadow = sequence.GetShadow(sequence.Length - 1, WAngle.Zero);
var alpha = sequence.GetAlpha(sequence.Length - 1);
var palette = resourceType.Palette;
var palette = resourceInfo.Palette;
var tintModifiers = sequence.IgnoreWorldTint ? TintModifiers.IgnoreWorldTint : TintModifiers.None;
if (shadow != null)
@@ -243,7 +251,7 @@ namespace OpenRA.Mods.Common.Traits
public readonly ResourceType Type;
public readonly int Density;
public static readonly RendererCellContents Empty = default(RendererCellContents);
public static readonly RendererCellContents Empty = default;
public RendererCellContents(string variant, ResourceType type, int density)
{

View File

@@ -152,7 +152,7 @@ namespace OpenRA.Mods.Common.Traits
public interface INotifyDocking { void Docked(Actor self, Actor harvester); void Undocked(Actor self, Actor harvester); }
[RequireExplicitImplementation]
public interface INotifyResourceAccepted { void OnResourceAccepted(Actor self, Actor refinery, ResourceTypeInfo resourceType, int count, int value); }
public interface INotifyResourceAccepted { void OnResourceAccepted(Actor self, Actor refinery, string resourceType, int count, int value); }
public interface INotifyParachute { void OnParachute(Actor self); void OnLanded(Actor self); }
[RequireExplicitImplementation]
@@ -188,7 +188,7 @@ namespace OpenRA.Mods.Common.Traits
void MovingToResources(Actor self, CPos targetCell);
void MovingToRefinery(Actor self, Actor refineryActor);
void MovementCancelled(Actor self);
void Harvested(Actor self, ResourceType resource);
void Harvested(Actor self, string resourceType);
void Docked();
void Undocked();
}
@@ -260,7 +260,7 @@ namespace OpenRA.Mods.Common.Traits
public interface IAcceptResources
{
void OnDock(Actor harv, DeliverResources dockOrder);
int AcceptResources(ResourceTypeInfo resourceType, int count = 1);
int AcceptResources(string resourceType, int count = 1);
CVec DeliveryOffset { get; }
bool AllowDocking { get; }
}
@@ -668,11 +668,12 @@ namespace OpenRA.Mods.Common.Traits
[RequireExplicitImplementation]
public interface IResourceLayer
{
event Action<CPos, ResourceType> CellChanged;
event Action<CPos, string> CellChanged;
ResourceLayerContents GetResource(CPos cell);
bool CanAddResource(ResourceType resourceType, CPos cell, int amount = 1);
int AddResource(ResourceType resourceType, CPos cell, int amount = 1);
int RemoveResource(ResourceType resourceType, CPos cell, int amount = 1);
int GetMaxDensity(string resourceType);
bool CanAddResource(string resourceType, CPos cell, int amount = 1);
int AddResource(string resourceType, CPos cell, int amount = 1);
int RemoveResource(string resourceType, CPos cell, int amount = 1);
void ClearResources(CPos cell);
bool IsVisible(CPos cell);
@@ -682,10 +683,10 @@ namespace OpenRA.Mods.Common.Traits
[RequireExplicitImplementation]
public interface IResourceRenderer
{
IEnumerable<ResourceType> ResourceTypes { get; }
ResourceType GetRenderedResourceType(CPos cell);
IEnumerable<string> ResourceTypes { get; }
string GetRenderedResourceType(CPos cell);
string GetRenderedResourceTooltip(CPos cell);
IEnumerable<IRenderable> RenderUIPreview(WorldRenderer wr, ResourceType resourceType, int2 origin, float scale);
IEnumerable<IRenderable> RenderPreview(WorldRenderer wr, ResourceType resourceType, WPos origin);
IEnumerable<IRenderable> RenderUIPreview(WorldRenderer wr, string resourceType, int2 origin, float scale);
IEnumerable<IRenderable> RenderPreview(WorldRenderer wr, string resourceType, WPos origin);
}
}

View File

@@ -16,7 +16,7 @@ using OpenRA.Traits;
namespace OpenRA.Mods.Common.Warheads
{
public class CreateResourceWarhead : Warhead, IRulesetLoaded<WeaponInfo>
public class CreateResourceWarhead : Warhead
{
[Desc("Size of the area. The resources are seeded within this area.", "Provide 2 values for a ring effect (outer/inner).")]
public readonly int[] Size = { 0, 0 };
@@ -25,16 +25,6 @@ namespace OpenRA.Mods.Common.Warheads
[FieldLoader.Require]
public readonly string AddsResourceType = null;
void IRulesetLoaded<WeaponInfo>.RulesetLoaded(Ruleset rules, WeaponInfo info)
{
var world = rules.Actors["world"];
var resourceType = world.TraitInfos<ResourceTypeInfo>()
.FirstOrDefault(t => t.Type == AddsResourceType);
if (resourceType == null)
throw new YamlException("CreateResourceWarhead defines an invalid resource type '{0}'".F(AddsResourceType));
}
// TODO: Allow maximum resource splatter to be defined. (Per tile, and in total).
public override void DoImpact(in Target target, WarheadArgs args)
{
@@ -53,17 +43,15 @@ namespace OpenRA.Mods.Common.Warheads
var minRange = (Size.Length > 1 && Size[1] > 0) ? Size[1] : 0;
var allCells = world.Map.FindTilesInAnnulus(targetTile, minRange, Size[0]);
var resourceType = world.WorldActor.TraitsImplementing<ResourceType>()
.First(t => t.Info.Type == AddsResourceType);
var resourceLayer = world.WorldActor.Trait<IResourceLayer>();
var maxDensity = resourceLayer.GetMaxDensity(AddsResourceType);
foreach (var cell in allCells)
{
if (!resourceLayer.CanAddResource(resourceType, cell))
if (!resourceLayer.CanAddResource(AddsResourceType, cell))
continue;
var splash = world.SharedRandom.Next(1, resourceType.Info.MaxDensity - resourceLayer.GetResource(cell).Density);
resourceLayer.AddResource(resourceType, cell, splash);
var splash = world.SharedRandom.Next(1, maxDensity - resourceLayer.GetResource(cell).Density);
resourceLayer.AddResource(AddsResourceType, cell, splash);
}
}
}

View File

@@ -49,7 +49,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
foreach (var resourceType in resourceRenderer.ResourceTypes)
{
var newResourcePreviewTemplate = ScrollItemWidget.Setup(layerPreviewTemplate,
() => editorCursor.Type == EditorCursorType.Resource && editorCursor.Resource == resourceType,
() => editorCursor.Type == EditorCursorType.Resource && editorCursor.ResourceType == resourceType,
() => editor.SetBrush(new EditorResourceBrush(editor, resourceType, worldRenderer)));
newResourcePreviewTemplate.Bounds.X = 0;
@@ -63,7 +63,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
newResourcePreviewTemplate.Bounds.Width = tileSize.Width + (layerPreview.Bounds.X * 2);
newResourcePreviewTemplate.Bounds.Height = tileSize.Height + (layerPreview.Bounds.Y * 2);
newResourcePreviewTemplate.IsVisible = () => true;
newResourcePreviewTemplate.GetTooltipText = () => resourceType.Info.Type;
newResourcePreviewTemplate.GetTooltipText = () => resourceType;
layerTemplateList.AddChild(newResourcePreviewTemplate);
}

View File

@@ -28,10 +28,10 @@ namespace OpenRA.Mods.Common.Widgets
readonly IResourceRenderer[] resourceRenderers;
readonly Size tileSize;
ResourceType resourceType;
string resourceType;
IResourceRenderer resourceRenderer;
public ResourceType ResourceType
public string ResourceType
{
get => resourceType;

View File

@@ -61,7 +61,6 @@ namespace OpenRA.Mods.D2k.Traits
public class SpiceBloom : ITick, INotifyKilled
{
readonly SpiceBloomInfo info;
readonly ResourceType resourceType;
readonly IResourceLayer resourceLayer;
readonly Animation body;
readonly Animation spurt;
@@ -76,7 +75,6 @@ namespace OpenRA.Mods.D2k.Traits
this.info = info;
resourceLayer = self.World.WorldActor.Trait<IResourceLayer>();
resourceType = self.World.WorldActor.TraitsImplementing<ResourceType>().First(t => t.Info.Type == info.ResourceType);
var rs = self.Trait<RenderSprites>();
body = new Animation(self.World, rs.GetImage(self));
@@ -127,7 +125,7 @@ namespace OpenRA.Mods.D2k.Traits
for (var i = 0; i < pieces; i++)
{
var cell = cells
.SkipWhile(p => resourceLayer.GetResource(p).Type == resourceType && !resourceLayer.CanAddResource(resourceType, p))
.SkipWhile(p => resourceLayer.GetResource(p).Type == info.ResourceType && !resourceLayer.CanAddResource(info.ResourceType, p))
.Cast<CPos?>()
.RandomOrDefault(self.World.SharedRandom);