Use IResourceLayer for editor resources.

This commit is contained in:
Paul Chote
2021-01-19 21:32:37 +00:00
committed by reaperrr
parent 0b93556c06
commit 5adcbe4c78
3 changed files with 56 additions and 72 deletions

View File

@@ -31,8 +31,8 @@ namespace OpenRA.Mods.Common.Widgets
readonly World world; readonly World world;
readonly EditorViewportControllerWidget editorWidget; readonly EditorViewportControllerWidget editorWidget;
readonly EditorActorLayer editorLayer; readonly EditorActorLayer editorLayer;
readonly Dictionary<int, ResourceType> resources;
readonly EditorActionManager editorActionManager; readonly EditorActionManager editorActionManager;
readonly IResourceLayer resourceLayer;
public EditorActorPreview SelectedActor; public EditorActorPreview SelectedActor;
int2 worldPixel; int2 worldPixel;
@@ -44,10 +44,8 @@ namespace OpenRA.Mods.Common.Widgets
world = wr.World; world = wr.World;
editorLayer = world.WorldActor.Trait<EditorActorLayer>(); editorLayer = world.WorldActor.Trait<EditorActorLayer>();
resources = world.WorldActor.TraitsImplementing<ResourceType>()
.ToDictionary(r => r.Info.ResourceType, r => r);
editorActionManager = world.WorldActor.Trait<EditorActionManager>(); editorActionManager = world.WorldActor.Trait<EditorActionManager>();
resourceLayer = world.WorldActor.Trait<IResourceLayer>();
} }
long CalculateActorSelectionPriority(EditorActorPreview actor) long CalculateActorSelectionPriority(EditorActorPreview actor)
@@ -75,13 +73,12 @@ namespace OpenRA.Mods.Common.Widgets
var cell = worldRenderer.Viewport.ViewToWorld(mi.Location); var cell = worldRenderer.Viewport.ViewToWorld(mi.Location);
var underCursor = editorLayer.PreviewsAt(worldPixel).MinByOrDefault(CalculateActorSelectionPriority); var underCursor = editorLayer.PreviewsAt(worldPixel).MinByOrDefault(CalculateActorSelectionPriority);
var resourceUnderCursor = resourceLayer.GetResource(cell).Type;
var mapResources = world.Map.Resources;
ResourceType type = null;
if (underCursor != null) if (underCursor != null)
editorWidget.SetTooltip(underCursor.Tooltip); editorWidget.SetTooltip(underCursor.Tooltip);
else if (mapResources.Contains(cell) && resources.TryGetValue(mapResources[cell].Type, out type)) else if (resourceUnderCursor != null)
editorWidget.SetTooltip(type.Info.Type); editorWidget.SetTooltip(resourceUnderCursor.Info.Type);
else else
editorWidget.SetTooltip(null); editorWidget.SetTooltip(null);
@@ -102,8 +99,8 @@ namespace OpenRA.Mods.Common.Widgets
if (underCursor != null && underCursor != SelectedActor) if (underCursor != null && underCursor != SelectedActor)
editorActionManager.Add(new RemoveActorAction(editorLayer, underCursor)); editorActionManager.Add(new RemoveActorAction(editorLayer, underCursor));
if (type != null && mapResources.Contains(cell) && mapResources[cell].Type != 0) if (resourceUnderCursor != null)
editorActionManager.Add(new RemoveResourceAction(mapResources, cell, type)); editorActionManager.Add(new RemoveResourceAction(resourceLayer, cell, resourceUnderCursor));
} }
return true; return true;
@@ -148,14 +145,14 @@ namespace OpenRA.Mods.Common.Widgets
{ {
public string Text { get; private set; } public string Text { get; private set; }
readonly CellLayer<ResourceTile> mapResources; readonly IResourceLayer resourceLayer;
readonly CPos cell; readonly CPos cell;
ResourceTile resourceTile; ResourceLayerContents resourceContents;
public RemoveResourceAction(CellLayer<ResourceTile> mapResources, CPos cell, ResourceType type) public RemoveResourceAction(IResourceLayer resourceLayer, CPos cell, ResourceType type)
{ {
this.mapResources = mapResources; this.resourceLayer = resourceLayer;
this.cell = cell; this.cell = cell;
Text = "Removed {0}".F(type.Info.TerrainType); Text = "Removed {0}".F(type.Info.TerrainType);
@@ -168,13 +165,14 @@ namespace OpenRA.Mods.Common.Widgets
public void Do() public void Do()
{ {
resourceTile = mapResources[cell]; resourceContents = resourceLayer.GetResource(cell);
mapResources[cell] = default(ResourceTile); resourceLayer.ClearResources(cell);
} }
public void Undo() public void Undo()
{ {
mapResources[cell] = resourceTile; resourceLayer.ClearResources(cell);
resourceLayer.AddResource(resourceContents.Type, cell, resourceContents.Density);
} }
} }
} }

View File

@@ -17,13 +17,14 @@ namespace OpenRA.Mods.Common.Widgets
{ {
public sealed class EditorResourceBrush : IEditorBrush public sealed class EditorResourceBrush : IEditorBrush
{ {
public readonly ResourceTypeInfo ResourceType; public readonly ResourceType ResourceType;
readonly WorldRenderer worldRenderer; readonly WorldRenderer worldRenderer;
readonly World world; readonly World world;
readonly EditorViewportControllerWidget editorWidget; readonly EditorViewportControllerWidget editorWidget;
readonly EditorActionManager editorActionManager; readonly EditorActionManager editorActionManager;
readonly EditorCursorLayer editorCursor; readonly EditorCursorLayer editorCursor;
readonly IResourceLayer resourceLayer;
readonly int cursorToken; readonly int cursorToken;
AddResourcesEditorAction action; AddResourcesEditorAction action;
@@ -37,9 +38,10 @@ namespace OpenRA.Mods.Common.Widgets
world = wr.World; world = wr.World;
editorActionManager = world.WorldActor.Trait<EditorActionManager>(); editorActionManager = world.WorldActor.Trait<EditorActionManager>();
editorCursor = world.WorldActor.Trait<EditorCursorLayer>(); editorCursor = world.WorldActor.Trait<EditorCursorLayer>();
action = new AddResourcesEditorAction(world.Map, ResourceType); resourceLayer = world.WorldActor.Trait<IResourceLayer>();
action = new AddResourcesEditorAction(world.Map, resourceLayer, resource);
cursorToken = editorCursor.SetResource(wr, resource); cursorToken = editorCursor.SetResource(wr, resource.Info);
} }
public bool HandleMouseInput(MouseInput mi) public bool HandleMouseInput(MouseInput mi)
@@ -64,42 +66,21 @@ namespace OpenRA.Mods.Common.Widgets
var cell = worldRenderer.Viewport.ViewToWorld(mi.Location); var cell = worldRenderer.Viewport.ViewToWorld(mi.Location);
if (mi.Button == MouseButton.Left && mi.Event != MouseInputEvent.Up && AllowResourceAt(cell)) if (mi.Button == MouseButton.Left && mi.Event != MouseInputEvent.Up && resourceLayer.CanAddResource(ResourceType, cell))
{ {
var type = (byte)ResourceType.ResourceType; action.Add(new CellResource(cell, resourceLayer.GetResource(cell), ResourceType));
var index = (byte)ResourceType.MaxDensity;
action.Add(new CellResource(cell, world.Map.Resources[cell], new ResourceTile(type, index)));
resourceAdded = true; resourceAdded = true;
} }
else if (resourceAdded && mi.Button == MouseButton.Left && mi.Event == MouseInputEvent.Up) else if (resourceAdded && mi.Button == MouseButton.Left && mi.Event == MouseInputEvent.Up)
{ {
editorActionManager.Add(action); editorActionManager.Add(action);
action = new AddResourcesEditorAction(world.Map, ResourceType); action = new AddResourcesEditorAction(world.Map, resourceLayer, ResourceType);
resourceAdded = false; resourceAdded = false;
} }
return true; return true;
} }
public bool AllowResourceAt(CPos cell)
{
var mapResources = world.Map.Resources;
if (!mapResources.Contains(cell))
return false;
var tile = world.Map.Tiles[cell];
var tileInfo = world.Map.Rules.TerrainInfo.GetTerrainInfo(tile);
var terrainType = world.Map.Rules.TerrainInfo.TerrainTypes[tileInfo.TerrainType];
if (mapResources[cell].Type == ResourceType.ResourceType)
return false;
if (!ResourceType.AllowedTerrainTypes.Contains(terrainType.Type))
return false;
return ResourceType.AllowOnRamps || tileInfo.RampType == 0;
}
public void Tick() { } public void Tick() { }
public void Dispose() public void Dispose()
@@ -111,14 +92,14 @@ namespace OpenRA.Mods.Common.Widgets
readonly struct CellResource readonly struct CellResource
{ {
public readonly CPos Cell; public readonly CPos Cell;
public readonly ResourceTile ResourceTile; public readonly ResourceLayerContents OldResourceTile;
public readonly ResourceTile NewResourceTile; public readonly ResourceType NewResourceType;
public CellResource(CPos cell, ResourceTile resourceTile, ResourceTile newResourceTile) public CellResource(CPos cell, ResourceLayerContents oldResourceTile, ResourceType newResourceType)
{ {
Cell = cell; Cell = cell;
ResourceTile = resourceTile; OldResourceTile = oldResourceTile;
NewResourceTile = newResourceTile; NewResourceType = newResourceType;
} }
} }
@@ -127,12 +108,14 @@ namespace OpenRA.Mods.Common.Widgets
public string Text { get; private set; } public string Text { get; private set; }
readonly Map map; readonly Map map;
readonly ResourceTypeInfo resourceType; readonly IResourceLayer resourceLayer;
readonly ResourceType resourceType;
readonly List<CellResource> cellResources = new List<CellResource>(); readonly List<CellResource> cellResources = new List<CellResource>();
public AddResourcesEditorAction(Map map, ResourceTypeInfo resourceType) public AddResourcesEditorAction(Map map, IResourceLayer resourceLayer, ResourceType resourceType)
{ {
this.map = map; this.map = map;
this.resourceLayer = resourceLayer;
this.resourceType = resourceType; this.resourceType = resourceType;
} }
@@ -143,27 +126,30 @@ namespace OpenRA.Mods.Common.Widgets
public void Do() public void Do()
{ {
foreach (var resourceCell in cellResources) foreach (var resourceCell in cellResources)
SetTile(resourceCell.Cell, resourceCell.NewResourceTile); {
} resourceLayer.ClearResources(resourceCell.Cell);
resourceLayer.AddResource(resourceCell.NewResourceType, resourceCell.Cell, resourceCell.NewResourceType.Info.MaxDensity);
void SetTile(CPos cell, ResourceTile tile) }
{
map.Resources[cell] = tile;
} }
public void Undo() public void Undo()
{ {
foreach (var resourceCell in cellResources) foreach (var resourceCell in cellResources)
SetTile(resourceCell.Cell, resourceCell.ResourceTile); {
resourceLayer.ClearResources(resourceCell.Cell);
if (resourceCell.OldResourceTile.Type != null)
resourceLayer.AddResource(resourceCell.OldResourceTile.Type, resourceCell.Cell, resourceCell.OldResourceTile.Density);
}
} }
public void Add(CellResource cellResource) public void Add(CellResource resourceCell)
{ {
SetTile(cellResource.Cell, cellResource.NewResourceTile); resourceLayer.ClearResources(resourceCell.Cell);
cellResources.Add(cellResource); resourceLayer.AddResource(resourceCell.NewResourceType, resourceCell.Cell, resourceCell.NewResourceType.Info.MaxDensity);
cellResources.Add(resourceCell);
var cellText = cellResources.Count != 1 ? "cells" : "cell"; var cellText = cellResources.Count != 1 ? "cells" : "cell";
Text = "Added {0} {1} of {2}".F(cellResources.Count, cellText, resourceType.TerrainType); Text = "Added {0} {1} of {2}".F(cellResources.Count, cellText, resourceType.Info.TerrainType);
} }
} }
} }

View File

@@ -146,7 +146,10 @@ namespace OpenRA.Mods.Common.Traits
if (!mapResources.Contains(cell)) if (!mapResources.Contains(cell))
return false; return false;
if (!rt.Info.AllowedTerrainTypes.Contains(Map.GetTerrainInfo(cell).Type)) // 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))
return false; return false;
// TODO: Check against actors in the EditorActorLayer // TODO: Check against actors in the EditorActorLayer
@@ -159,14 +162,13 @@ namespace OpenRA.Mods.Common.Traits
if (!resources.Contains(cell)) if (!resources.Contains(cell))
return false; 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]; var content = resources[cell];
if (content.Type == 0) if (content.Type != resourceType.Info.ResourceType)
return amount <= resourceType.Info.MaxDensity && AllowResourceAt(resourceType, cell); return amount <= resourceType.Info.MaxDensity && AllowResourceAt(resourceType, cell);
if (content.Type != resourceType.Info.ResourceType) var oldDensity = content.Type == resourceType.Info.ResourceType ? content.Index : 0;
return false; return oldDensity + amount <= resourceType.Info.MaxDensity;
return content.Index + amount <= resourceType.Info.MaxDensity;
} }
int AddResource(ResourceType resourceType, CPos cell, int amount = 1) int AddResource(ResourceType resourceType, CPos cell, int amount = 1)
@@ -175,11 +177,9 @@ namespace OpenRA.Mods.Common.Traits
if (!resources.Contains(cell)) if (!resources.Contains(cell))
return 0; 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 content = resources[cell];
if (content.Type != 0 && content.Type != resourceType.Info.ResourceType) var oldDensity = content.Type == resourceType.Info.ResourceType ? content.Index : 0;
return 0;
var oldDensity = content.Index;
var density = (byte)Math.Min(resourceType.Info.MaxDensity, oldDensity + amount); var density = (byte)Math.Min(resourceType.Info.MaxDensity, oldDensity + amount);
Map.Resources[cell] = new ResourceTile((byte)resourceType.Info.ResourceType, density); Map.Resources[cell] = new ResourceTile((byte)resourceType.Info.ResourceType, density);