Replace ResourceType with strings in interfaces/public methods.
This commit is contained in:
@@ -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()
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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() { }
|
||||
}
|
||||
|
||||
@@ -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()
|
||||
{
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user