Replace ResourceLayer references with IResourceLayer in traits/warheads.

This commit is contained in:
Paul Chote
2021-03-07 17:31:26 +00:00
committed by reaperrr
parent 5adcbe4c78
commit dcd8eccee4
14 changed files with 72 additions and 80 deletions

View File

@@ -46,12 +46,12 @@ namespace OpenRA.Mods.Cnc.Traits
public class TransformsNearResources : ITick public class TransformsNearResources : ITick
{ {
readonly TransformsNearResourcesInfo info; readonly TransformsNearResourcesInfo info;
readonly ResourceLayer resourceLayer; readonly IResourceLayer resourceLayer;
int delay; int delay;
public TransformsNearResources(Actor self, TransformsNearResourcesInfo info) public TransformsNearResources(Actor self, TransformsNearResourcesInfo info)
{ {
resourceLayer = self.World.WorldActor.Trait<ResourceLayer>(); resourceLayer = self.World.WorldActor.Trait<IResourceLayer>();
delay = Common.Util.RandomDelay(self.World, info.Delay); delay = Common.Util.RandomDelay(self.World, info.Delay);
this.info = info; this.info = info;
} }
@@ -66,12 +66,11 @@ namespace OpenRA.Mods.Cnc.Traits
{ {
var location = self.Location + direction; var location = self.Location + direction;
var resource = resourceLayer.GetResourceType(location); var resource = resourceLayer.GetResource(location);
if (resource == null || resource.Info.Type != info.Type) if (resource.Type == null || resource.Type.Info.Type != info.Type)
continue; continue;
var density = resourceLayer.GetResourceDensity(location); if (resource.Density < info.Density)
if (density < info.Density)
continue; continue;
if (++adjacent < info.Adjacency) if (++adjacent < info.Adjacency)

View File

@@ -24,7 +24,7 @@ namespace OpenRA.Mods.Common.Activities
readonly HarvesterInfo harvInfo; readonly HarvesterInfo harvInfo;
readonly IFacing facing; readonly IFacing facing;
readonly ResourceClaimLayer claimLayer; readonly ResourceClaimLayer claimLayer;
readonly ResourceLayer resLayer; readonly IResourceLayer resourceLayer;
readonly BodyOrientation body; readonly BodyOrientation body;
readonly IMove move; readonly IMove move;
readonly CPos targetCell; readonly CPos targetCell;
@@ -38,7 +38,7 @@ namespace OpenRA.Mods.Common.Activities
body = self.Trait<BodyOrientation>(); body = self.Trait<BodyOrientation>();
move = self.Trait<IMove>(); move = self.Trait<IMove>();
claimLayer = self.World.WorldActor.Trait<ResourceClaimLayer>(); claimLayer = self.World.WorldActor.Trait<ResourceClaimLayer>();
resLayer = self.World.WorldActor.Trait<ResourceLayer>(); resourceLayer = self.World.WorldActor.Trait<IResourceLayer>();
this.targetCell = targetCell; this.targetCell = targetCell;
notifyHarvesterActions = self.TraitsImplementing<INotifyHarvesterAction>().ToArray(); notifyHarvesterActions = self.TraitsImplementing<INotifyHarvesterAction>().ToArray();
} }
@@ -81,14 +81,14 @@ namespace OpenRA.Mods.Common.Activities
} }
} }
var resourceType = resLayer.GetResourceType(self.Location); var resource = resourceLayer.GetResource(self.Location);
if (resourceType == null || resLayer.RemoveResource(resourceType, self.Location) != 1) if (resource.Type == null || resourceLayer.RemoveResource(resource.Type, self.Location) != 1)
return true; return true;
harv.AcceptResource(self, resourceType); harv.AcceptResource(self, resource.Type);
foreach (var t in notifyHarvesterActions) foreach (var t in notifyHarvesterActions)
t.Harvested(self, resourceType); t.Harvested(self, resource.Type);
QueueChild(new Wait(harvInfo.BaleLoadDelay)); QueueChild(new Wait(harvInfo.BaleLoadDelay));
return false; return false;

View File

@@ -33,7 +33,7 @@ namespace OpenRA.Mods.Common.Widgets
public EditorResourceBrush(EditorViewportControllerWidget editorWidget, ResourceType resource, WorldRenderer wr) public EditorResourceBrush(EditorViewportControllerWidget editorWidget, ResourceType resource, WorldRenderer wr)
{ {
this.editorWidget = editorWidget; this.editorWidget = editorWidget;
ResourceType = resource.Info; ResourceType = resource;
worldRenderer = wr; worldRenderer = wr;
world = wr.World; world = wr.World;
editorActionManager = world.WorldActor.Trait<EditorActionManager>(); editorActionManager = world.WorldActor.Trait<EditorActionManager>();
@@ -41,7 +41,7 @@ namespace OpenRA.Mods.Common.Widgets
resourceLayer = world.WorldActor.Trait<IResourceLayer>(); resourceLayer = world.WorldActor.Trait<IResourceLayer>();
action = new AddResourcesEditorAction(world.Map, resourceLayer, resource); action = new AddResourcesEditorAction(world.Map, resourceLayer, resource);
cursorToken = editorCursor.SetResource(wr, resource.Info); cursorToken = editorCursor.SetResource(wr, resource);
} }
public bool HandleMouseInput(MouseInput mi) public bool HandleMouseInput(MouseInput mi)

View File

@@ -87,7 +87,7 @@ namespace OpenRA.Mods.Common.Orders
readonly World world; readonly World world;
readonly ProductionQueue queue; readonly ProductionQueue queue;
readonly PlaceBuildingInfo placeBuildingInfo; readonly PlaceBuildingInfo placeBuildingInfo;
readonly ResourceLayer resourceLayer; readonly IResourceLayer resourceLayer;
readonly Viewport viewport; readonly Viewport viewport;
readonly VariantWrapper[] variants; readonly VariantWrapper[] variants;
int variant; int variant;
@@ -97,7 +97,7 @@ namespace OpenRA.Mods.Common.Orders
this.queue = queue; this.queue = queue;
world = queue.Actor.World; world = queue.Actor.World;
placeBuildingInfo = queue.Actor.Owner.PlayerActor.Info.TraitInfo<PlaceBuildingInfo>(); placeBuildingInfo = queue.Actor.Owner.PlayerActor.Info.TraitInfo<PlaceBuildingInfo>();
resourceLayer = world.WorldActor.TraitOrDefault<ResourceLayer>(); resourceLayer = world.WorldActor.TraitOrDefault<IResourceLayer>();
viewport = worldRenderer.Viewport; viewport = worldRenderer.Viewport;
// Clear selection if using Left-Click Orders // Clear selection if using Left-Click Orders
@@ -279,7 +279,7 @@ namespace OpenRA.Mods.Common.Orders
{ {
var isCloseEnough = buildingInfo.IsCloseEnoughToBase(world, world.LocalPlayer, actorInfo, topLeft); var isCloseEnough = buildingInfo.IsCloseEnoughToBase(world, world.LocalPlayer, actorInfo, topLeft);
foreach (var t in buildingInfo.Tiles(topLeft)) foreach (var t in buildingInfo.Tiles(topLeft))
footprint.Add(t, MakeCellType(isCloseEnough && world.IsCellBuildable(t, actorInfo, buildingInfo) && (resourceLayer == null || resourceLayer.GetResourceType(t) == null))); footprint.Add(t, MakeCellType(isCloseEnough && world.IsCellBuildable(t, actorInfo, buildingInfo) && (resourceLayer == null || resourceLayer.GetResource(t).Type == null)));
} }
return preview?.Render(wr, topLeft, footprint) ?? Enumerable.Empty<IRenderable>(); return preview?.Render(wr, topLeft, footprint) ?? Enumerable.Empty<IRenderable>();

View File

@@ -63,7 +63,7 @@ namespace OpenRA.Mods.Common.Traits
IPathFinder pathfinder; IPathFinder pathfinder;
DomainIndex domainIndex; DomainIndex domainIndex;
ResourceLayer resLayer; IResourceLayer resourceLayer;
ResourceClaimLayer claimLayer; ResourceClaimLayer claimLayer;
IBotRequestUnitProduction[] requestUnitProduction; IBotRequestUnitProduction[] requestUnitProduction;
int scanForIdleHarvestersTicks; int scanForIdleHarvestersTicks;
@@ -85,7 +85,7 @@ namespace OpenRA.Mods.Common.Traits
{ {
pathfinder = world.WorldActor.Trait<IPathFinder>(); pathfinder = world.WorldActor.Trait<IPathFinder>();
domainIndex = world.WorldActor.Trait<DomainIndex>(); domainIndex = world.WorldActor.Trait<DomainIndex>();
resLayer = world.WorldActor.TraitOrDefault<ResourceLayer>(); resourceLayer = world.WorldActor.TraitOrDefault<IResourceLayer>();
claimLayer = world.WorldActor.TraitOrDefault<ResourceClaimLayer>(); claimLayer = world.WorldActor.TraitOrDefault<ResourceClaimLayer>();
// Avoid all AIs scanning for idle harvesters on the same tick, randomize their initial scan delay. // Avoid all AIs scanning for idle harvesters on the same tick, randomize their initial scan delay.
@@ -94,7 +94,7 @@ namespace OpenRA.Mods.Common.Traits
void IBotTick.BotTick(IBot bot) void IBotTick.BotTick(IBot bot)
{ {
if (resLayer == null || resLayer.IsResourceLayerEmpty) if (resourceLayer == null || resourceLayer.IsEmpty)
return; return;
if (--scanForIdleHarvestersTicks > 0) if (--scanForIdleHarvestersTicks > 0)

View File

@@ -87,9 +87,9 @@ namespace OpenRA.Mods.Common.Traits
if (bi.AllowInvalidPlacement) if (bi.AllowInvalidPlacement)
return true; return true;
var res = world.WorldActor.TraitOrDefault<ResourceLayer>(); var resourceLayer = world.WorldActor.TraitOrDefault<IResourceLayer>();
return bi.Tiles(cell).All(t => world.Map.Contains(t) && return bi.Tiles(cell).All(t => world.Map.Contains(t) &&
(bi.AllowPlacementOnResources || res == null || res.GetResourceType(t) == null) && (bi.AllowPlacementOnResources || resourceLayer == null || resourceLayer.GetResource(t).Type == null) &&
world.IsCellBuildable(t, ai, bi, toIgnore)); world.IsCellBuildable(t, ai, bi, toIgnore));
} }

View File

@@ -106,7 +106,7 @@ namespace OpenRA.Mods.Common.Traits
public readonly IReadOnlyDictionary<ResourceTypeInfo, int> Contents; public readonly IReadOnlyDictionary<ResourceTypeInfo, int> Contents;
readonly Mobile mobile; readonly Mobile mobile;
readonly ResourceLayer resLayer; readonly IResourceLayer resourceLayer;
readonly ResourceClaimLayer claimLayer; readonly ResourceClaimLayer claimLayer;
readonly Dictionary<ResourceTypeInfo, int> contents = new Dictionary<ResourceTypeInfo, int>(); readonly Dictionary<ResourceTypeInfo, int> contents = new Dictionary<ResourceTypeInfo, int>();
int conditionToken = Actor.InvalidConditionToken; int conditionToken = Actor.InvalidConditionToken;
@@ -138,7 +138,7 @@ namespace OpenRA.Mods.Common.Traits
Contents = new ReadOnlyDictionary<ResourceTypeInfo, int>(contents); Contents = new ReadOnlyDictionary<ResourceTypeInfo, int>(contents);
mobile = self.Trait<Mobile>(); mobile = self.Trait<Mobile>();
resLayer = self.World.WorldActor.Trait<ResourceLayer>(); resourceLayer = self.World.WorldActor.Trait<IResourceLayer>();
claimLayer = self.World.WorldActor.Trait<ResourceClaimLayer>(); claimLayer = self.World.WorldActor.Trait<ResourceClaimLayer>();
} }
@@ -276,12 +276,12 @@ namespace OpenRA.Mods.Common.Traits
if (cell.Layer != 0) if (cell.Layer != 0)
return false; return false;
var resType = resLayer.GetResourceType(cell); var resourceType = resourceLayer.GetResource(cell).Type;
if (resType == null) if (resourceType == null)
return false; return false;
// Can the harvester collect this kind of resource? // Can the harvester collect this kind of resource?
return Info.Resources.Contains(resType.Info.Type); return Info.Resources.Contains(resourceType.Info.Type);
} }
IEnumerable<IOrderTargeter> IIssueOrder.Orders IEnumerable<IOrderTargeter> IIssueOrder.Orders

View File

@@ -30,7 +30,7 @@ namespace OpenRA.Mods.Common.Traits
readonly SeedsResourceInfo info; readonly SeedsResourceInfo info;
readonly ResourceType resourceType; readonly ResourceType resourceType;
readonly ResourceLayer resLayer; readonly IResourceLayer resourceLayer;
public SeedsResource(Actor self, SeedsResourceInfo info) public SeedsResource(Actor self, SeedsResourceInfo info)
: base(info) : base(info)
@@ -43,7 +43,7 @@ namespace OpenRA.Mods.Common.Traits
if (resourceType == null) if (resourceType == null)
throw new InvalidOperationException("No such resource type `{0}`".F(info.ResourceType)); throw new InvalidOperationException("No such resource type `{0}`".F(info.ResourceType));
resLayer = self.World.WorldActor.Trait<ResourceLayer>(); resourceLayer = self.World.WorldActor.Trait<IResourceLayer>();
} }
int ticks; int ticks;
@@ -64,12 +64,11 @@ namespace OpenRA.Mods.Common.Traits
{ {
var cell = Util.RandomWalk(self.Location, self.World.SharedRandom) var cell = Util.RandomWalk(self.Location, self.World.SharedRandom)
.Take(info.MaxRange) .Take(info.MaxRange)
.SkipWhile(p => !self.World.Map.Contains(p) || .SkipWhile(p => resourceLayer.GetResource(p).Type == resourceType && !resourceLayer.CanAddResource(resourceType, p))
(resLayer.GetResourceType(p) == resourceType && resLayer.IsFull(p)))
.Cast<CPos?>().FirstOrDefault(); .Cast<CPos?>().FirstOrDefault();
if (cell != null && resLayer.CanAddResource(resourceType, cell.Value)) if (cell != null && resourceLayer.CanAddResource(resourceType, cell.Value))
resLayer.AddResource(resourceType, cell.Value); resourceLayer.AddResource(resourceType, cell.Value);
} }
} }
} }

View File

@@ -35,12 +35,13 @@ namespace OpenRA.Mods.Common.Traits
public event Action<CPos, ResourceType> CellChanged; public event Action<CPos, ResourceType> CellChanged;
ResourceLayerContents IResourceLayer.GetResource(CPos cell) { return Tiles[cell]; } 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); } 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.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.RemoveResource(ResourceType resourceType, CPos cell, int amount) { return RemoveResource(resourceType, cell, amount); }
void IResourceLayer.ClearResources(CPos cell) { ClearResources(cell); } void IResourceLayer.ClearResources(CPos cell) { ClearResources(cell); }
bool IResourceLayer.IsVisible(CPos cell) { return Map.Contains(cell); } bool IResourceLayer.IsVisible(CPos cell) { return Map.Contains(cell); }
bool IResourceLayer.IsEmpty => false;
public EditorResourceLayer(Actor self) public EditorResourceLayer(Actor self)
{ {

View File

@@ -29,22 +29,7 @@ namespace OpenRA.Mods.Common.Traits
} }
} }
public interface IResourceLayerInfo : ITraitInfoInterface { } [Desc("Attach this to the world actor.")]
[RequireExplicitImplementation]
public interface IResourceLayer
{
event Action<CPos, ResourceType> 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);
void ClearResources(CPos cell);
bool IsVisible(CPos cell);
}
[Desc("Attach this to the world actor.", "Order of the layers defines the Z sorting.")]
public class ResourceLayerInfo : TraitInfo, IResourceLayerInfo, Requires<ResourceTypeInfo>, Requires<BuildingInfluenceInfo> public class ResourceLayerInfo : TraitInfo, IResourceLayerInfo, Requires<ResourceTypeInfo>, Requires<BuildingInfluenceInfo>
{ {
public override object Create(ActorInitializer init) { return new ResourceLayer(init.Self); } public override object Create(ActorInitializer init) { return new ResourceLayer(init.Self); }
@@ -57,8 +42,6 @@ namespace OpenRA.Mods.Common.Traits
protected readonly CellLayer<ResourceLayerContents> Content; protected readonly CellLayer<ResourceLayerContents> Content;
public bool IsResourceLayerEmpty => resCells < 1;
int resCells; int resCells;
public event Action<CPos, ResourceType> CellChanged; public event Action<CPos, ResourceType> CellChanged;
@@ -103,7 +86,7 @@ namespace OpenRA.Mods.Common.Traits
foreach (var cell in w.Map.AllCells) foreach (var cell in w.Map.AllCells)
{ {
var type = GetResourceType(cell); var type = Content[cell].Type;
if (type != null) if (type != null)
{ {
// Set initial density based on the number of neighboring resources // Set initial density based on the number of neighboring resources
@@ -140,7 +123,7 @@ namespace OpenRA.Mods.Common.Traits
return new ResourceLayerContents(t, 0); return new ResourceLayerContents(t, 0);
} }
public bool CanAddResource(ResourceType resourceType, CPos cell, int amount = 1) bool CanAddResource(ResourceType resourceType, CPos cell, int amount = 1)
{ {
if (!world.Map.Contains(cell)) if (!world.Map.Contains(cell))
return false; return false;
@@ -155,7 +138,7 @@ namespace OpenRA.Mods.Common.Traits
return content.Density + amount <= resourceType.Info.MaxDensity; return content.Density + amount <= resourceType.Info.MaxDensity;
} }
public int AddResource(ResourceType resourceType, CPos cell, int amount = 1) int AddResource(ResourceType resourceType, CPos cell, int amount = 1)
{ {
if (!Content.Contains(cell)) if (!Content.Contains(cell))
return 0; return 0;
@@ -176,7 +159,7 @@ namespace OpenRA.Mods.Common.Traits
return density - oldDensity; return density - oldDensity;
} }
public int RemoveResource(ResourceType resourceType, CPos cell, int amount = 1) int RemoveResource(ResourceType resourceType, CPos cell, int amount = 1)
{ {
if (!Content.Contains(cell)) if (!Content.Contains(cell))
return 0; return 0;
@@ -205,7 +188,7 @@ namespace OpenRA.Mods.Common.Traits
return oldDensity - density; return oldDensity - density;
} }
public void ClearResources(CPos cell) void ClearResources(CPos cell)
{ {
if (!Content.Contains(cell)) if (!Content.Contains(cell))
return; return;
@@ -222,22 +205,12 @@ namespace OpenRA.Mods.Common.Traits
CellChanged?.Invoke(cell, null); CellChanged?.Invoke(cell, null);
} }
public bool IsFull(CPos cell) ResourceLayerContents IResourceLayer.GetResource(CPos cell) { return Content.Contains(cell) ? Content[cell] : default; }
{
var cellContents = Content[cell];
return cellContents.Density == cellContents.Type.Info.MaxDensity;
}
public ResourceType GetResourceType(CPos cell) { return Content[cell].Type; }
public int GetResourceDensity(CPos cell) { return Content[cell].Density; }
ResourceLayerContents IResourceLayer.GetResource(CPos cell) { return Content[cell]; }
bool IResourceLayer.CanAddResource(ResourceType resourceType, CPos cell, int amount) { return CanAddResource(resourceType, cell, amount); } 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.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.RemoveResource(ResourceType resourceType, CPos cell, int amount) { return RemoveResource(resourceType, cell, amount); }
void IResourceLayer.ClearResources(CPos cell) { ClearResources(cell); } void IResourceLayer.ClearResources(CPos cell) { ClearResources(cell); }
bool IResourceLayer.IsVisible(CPos cell) { return !world.FogObscures(cell); } bool IResourceLayer.IsVisible(CPos cell) { return !world.FogObscures(cell); }
bool IResourceLayer.IsEmpty => resCells < 1;
} }
} }

View File

@@ -663,6 +663,22 @@ namespace OpenRA.Mods.Common.Traits
IEnumerable<IRenderable> RenderPreview(WorldRenderer wr, TerrainTemplateInfo template, WPos origin); IEnumerable<IRenderable> RenderPreview(WorldRenderer wr, TerrainTemplateInfo template, WPos origin);
} }
public interface IResourceLayerInfo : ITraitInfoInterface { }
[RequireExplicitImplementation]
public interface IResourceLayer
{
event Action<CPos, ResourceType> 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);
void ClearResources(CPos cell);
bool IsVisible(CPos cell);
bool IsEmpty { get; }
}
[RequireExplicitImplementation] [RequireExplicitImplementation]
public interface IResourceRenderer public interface IResourceRenderer
{ {

View File

@@ -56,14 +56,14 @@ namespace OpenRA.Mods.Common.Warheads
var resourceType = world.WorldActor.TraitsImplementing<ResourceType>() var resourceType = world.WorldActor.TraitsImplementing<ResourceType>()
.First(t => t.Info.Type == AddsResourceType); .First(t => t.Info.Type == AddsResourceType);
var resLayer = world.WorldActor.Trait<ResourceLayer>(); var resourceLayer = world.WorldActor.Trait<IResourceLayer>();
foreach (var cell in allCells) foreach (var cell in allCells)
{ {
if (!resLayer.CanAddResource(resourceType, cell)) if (!resourceLayer.CanAddResource(resourceType, cell))
continue; continue;
var splash = world.SharedRandom.Next(1, resourceType.Info.MaxDensity - resLayer.GetResourceDensity(cell)); var splash = world.SharedRandom.Next(1, resourceType.Info.MaxDensity - resourceLayer.GetResource(cell).Density);
resLayer.AddResource(resourceType, cell, splash); resourceLayer.AddResource(resourceType, cell, splash);
} }
} }
} }

View File

@@ -34,14 +34,14 @@ namespace OpenRA.Mods.Common.Warheads
return; return;
var targetTile = world.Map.CellContaining(pos); var targetTile = world.Map.CellContaining(pos);
var resLayer = world.WorldActor.Trait<ResourceLayer>(); var resourceLayer = world.WorldActor.Trait<IResourceLayer>();
var minRange = (Size.Length > 1 && Size[1] > 0) ? Size[1] : 0; var minRange = (Size.Length > 1 && Size[1] > 0) ? Size[1] : 0;
var allCells = world.Map.FindTilesInAnnulus(targetTile, minRange, Size[0]); var allCells = world.Map.FindTilesInAnnulus(targetTile, minRange, Size[0]);
// Destroy all resources in the selected tiles // Destroy all resources in the selected tiles
foreach (var cell in allCells) foreach (var cell in allCells)
resLayer.ClearResources(cell); resourceLayer.ClearResources(cell);
} }
} }
} }

View File

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