From dcd8eccee472f7512939ba91f11c95defbb091e6 Mon Sep 17 00:00:00 2001 From: Paul Chote Date: Sun, 7 Mar 2021 17:31:26 +0000 Subject: [PATCH] Replace ResourceLayer references with IResourceLayer in traits/warheads. --- .../Traits/TransformsNearResources.cs | 11 +++-- .../Activities/HarvestResource.cs | 12 +++--- .../EditorBrushes/EditorResourceBrush.cs | 4 +- .../Orders/PlaceBuildingOrderGenerator.cs | 6 +-- .../Traits/BotModules/HarvesterBotModule.cs | 6 +-- .../Traits/Buildings/BuildingUtils.cs | 4 +- OpenRA.Mods.Common/Traits/Harvester.cs | 10 ++--- OpenRA.Mods.Common/Traits/SeedsResource.cs | 11 +++-- .../Traits/World/EditorResourceLayer.cs | 3 +- .../Traits/World/ResourceLayer.cs | 43 ++++--------------- OpenRA.Mods.Common/TraitsInterfaces.cs | 16 +++++++ .../Warheads/CreateResourceWarhead.cs | 8 ++-- .../Warheads/DestroyResourceWarhead.cs | 4 +- OpenRA.Mods.D2k/Traits/SpiceBloom.cs | 14 +++--- 14 files changed, 72 insertions(+), 80 deletions(-) diff --git a/OpenRA.Mods.Cnc/Traits/TransformsNearResources.cs b/OpenRA.Mods.Cnc/Traits/TransformsNearResources.cs index 078e7cd08f..3ff95aa8c6 100644 --- a/OpenRA.Mods.Cnc/Traits/TransformsNearResources.cs +++ b/OpenRA.Mods.Cnc/Traits/TransformsNearResources.cs @@ -46,12 +46,12 @@ namespace OpenRA.Mods.Cnc.Traits public class TransformsNearResources : ITick { readonly TransformsNearResourcesInfo info; - readonly ResourceLayer resourceLayer; + readonly IResourceLayer resourceLayer; int delay; public TransformsNearResources(Actor self, TransformsNearResourcesInfo info) { - resourceLayer = self.World.WorldActor.Trait(); + resourceLayer = self.World.WorldActor.Trait(); delay = Common.Util.RandomDelay(self.World, info.Delay); this.info = info; } @@ -66,12 +66,11 @@ namespace OpenRA.Mods.Cnc.Traits { var location = self.Location + direction; - var resource = resourceLayer.GetResourceType(location); - if (resource == null || resource.Info.Type != info.Type) + var resource = resourceLayer.GetResource(location); + if (resource.Type == null || resource.Type.Info.Type != info.Type) continue; - var density = resourceLayer.GetResourceDensity(location); - if (density < info.Density) + if (resource.Density < info.Density) continue; if (++adjacent < info.Adjacency) diff --git a/OpenRA.Mods.Common/Activities/HarvestResource.cs b/OpenRA.Mods.Common/Activities/HarvestResource.cs index 57b274ea72..08863059b6 100644 --- a/OpenRA.Mods.Common/Activities/HarvestResource.cs +++ b/OpenRA.Mods.Common/Activities/HarvestResource.cs @@ -24,7 +24,7 @@ namespace OpenRA.Mods.Common.Activities readonly HarvesterInfo harvInfo; readonly IFacing facing; readonly ResourceClaimLayer claimLayer; - readonly ResourceLayer resLayer; + readonly IResourceLayer resourceLayer; readonly BodyOrientation body; readonly IMove move; readonly CPos targetCell; @@ -38,7 +38,7 @@ namespace OpenRA.Mods.Common.Activities body = self.Trait(); move = self.Trait(); claimLayer = self.World.WorldActor.Trait(); - resLayer = self.World.WorldActor.Trait(); + resourceLayer = self.World.WorldActor.Trait(); this.targetCell = targetCell; notifyHarvesterActions = self.TraitsImplementing().ToArray(); } @@ -81,14 +81,14 @@ namespace OpenRA.Mods.Common.Activities } } - var resourceType = resLayer.GetResourceType(self.Location); - if (resourceType == null || resLayer.RemoveResource(resourceType, self.Location) != 1) + var resource = resourceLayer.GetResource(self.Location); + if (resource.Type == null || resourceLayer.RemoveResource(resource.Type, self.Location) != 1) return true; - harv.AcceptResource(self, resourceType); + harv.AcceptResource(self, resource.Type); foreach (var t in notifyHarvesterActions) - t.Harvested(self, resourceType); + t.Harvested(self, resource.Type); QueueChild(new Wait(harvInfo.BaleLoadDelay)); return false; diff --git a/OpenRA.Mods.Common/EditorBrushes/EditorResourceBrush.cs b/OpenRA.Mods.Common/EditorBrushes/EditorResourceBrush.cs index b83766cb44..a3a394ff5f 100644 --- a/OpenRA.Mods.Common/EditorBrushes/EditorResourceBrush.cs +++ b/OpenRA.Mods.Common/EditorBrushes/EditorResourceBrush.cs @@ -33,7 +33,7 @@ namespace OpenRA.Mods.Common.Widgets public EditorResourceBrush(EditorViewportControllerWidget editorWidget, ResourceType resource, WorldRenderer wr) { this.editorWidget = editorWidget; - ResourceType = resource.Info; + ResourceType = resource; worldRenderer = wr; world = wr.World; editorActionManager = world.WorldActor.Trait(); @@ -41,7 +41,7 @@ namespace OpenRA.Mods.Common.Widgets resourceLayer = world.WorldActor.Trait(); action = new AddResourcesEditorAction(world.Map, resourceLayer, resource); - cursorToken = editorCursor.SetResource(wr, resource.Info); + cursorToken = editorCursor.SetResource(wr, resource); } public bool HandleMouseInput(MouseInput mi) diff --git a/OpenRA.Mods.Common/Orders/PlaceBuildingOrderGenerator.cs b/OpenRA.Mods.Common/Orders/PlaceBuildingOrderGenerator.cs index fa7c31d1b5..a55b7a3d6c 100644 --- a/OpenRA.Mods.Common/Orders/PlaceBuildingOrderGenerator.cs +++ b/OpenRA.Mods.Common/Orders/PlaceBuildingOrderGenerator.cs @@ -87,7 +87,7 @@ namespace OpenRA.Mods.Common.Orders readonly World world; readonly ProductionQueue queue; readonly PlaceBuildingInfo placeBuildingInfo; - readonly ResourceLayer resourceLayer; + readonly IResourceLayer resourceLayer; readonly Viewport viewport; readonly VariantWrapper[] variants; int variant; @@ -97,7 +97,7 @@ namespace OpenRA.Mods.Common.Orders this.queue = queue; world = queue.Actor.World; placeBuildingInfo = queue.Actor.Owner.PlayerActor.Info.TraitInfo(); - resourceLayer = world.WorldActor.TraitOrDefault(); + resourceLayer = world.WorldActor.TraitOrDefault(); viewport = worldRenderer.Viewport; // 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); 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(); diff --git a/OpenRA.Mods.Common/Traits/BotModules/HarvesterBotModule.cs b/OpenRA.Mods.Common/Traits/BotModules/HarvesterBotModule.cs index d3ee76deb8..a37ddd921a 100644 --- a/OpenRA.Mods.Common/Traits/BotModules/HarvesterBotModule.cs +++ b/OpenRA.Mods.Common/Traits/BotModules/HarvesterBotModule.cs @@ -63,7 +63,7 @@ namespace OpenRA.Mods.Common.Traits IPathFinder pathfinder; DomainIndex domainIndex; - ResourceLayer resLayer; + IResourceLayer resourceLayer; ResourceClaimLayer claimLayer; IBotRequestUnitProduction[] requestUnitProduction; int scanForIdleHarvestersTicks; @@ -85,7 +85,7 @@ namespace OpenRA.Mods.Common.Traits { pathfinder = world.WorldActor.Trait(); domainIndex = world.WorldActor.Trait(); - resLayer = world.WorldActor.TraitOrDefault(); + resourceLayer = world.WorldActor.TraitOrDefault(); claimLayer = world.WorldActor.TraitOrDefault(); // 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) { - if (resLayer == null || resLayer.IsResourceLayerEmpty) + if (resourceLayer == null || resourceLayer.IsEmpty) return; if (--scanForIdleHarvestersTicks > 0) diff --git a/OpenRA.Mods.Common/Traits/Buildings/BuildingUtils.cs b/OpenRA.Mods.Common/Traits/Buildings/BuildingUtils.cs index 183a848f80..e4a0631cee 100644 --- a/OpenRA.Mods.Common/Traits/Buildings/BuildingUtils.cs +++ b/OpenRA.Mods.Common/Traits/Buildings/BuildingUtils.cs @@ -87,9 +87,9 @@ namespace OpenRA.Mods.Common.Traits if (bi.AllowInvalidPlacement) return true; - var res = world.WorldActor.TraitOrDefault(); + var resourceLayer = world.WorldActor.TraitOrDefault(); 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)); } diff --git a/OpenRA.Mods.Common/Traits/Harvester.cs b/OpenRA.Mods.Common/Traits/Harvester.cs index 885d0bb69f..508c550458 100644 --- a/OpenRA.Mods.Common/Traits/Harvester.cs +++ b/OpenRA.Mods.Common/Traits/Harvester.cs @@ -106,7 +106,7 @@ namespace OpenRA.Mods.Common.Traits public readonly IReadOnlyDictionary Contents; readonly Mobile mobile; - readonly ResourceLayer resLayer; + readonly IResourceLayer resourceLayer; readonly ResourceClaimLayer claimLayer; readonly Dictionary contents = new Dictionary(); int conditionToken = Actor.InvalidConditionToken; @@ -138,7 +138,7 @@ namespace OpenRA.Mods.Common.Traits Contents = new ReadOnlyDictionary(contents); mobile = self.Trait(); - resLayer = self.World.WorldActor.Trait(); + resourceLayer = self.World.WorldActor.Trait(); claimLayer = self.World.WorldActor.Trait(); } @@ -276,12 +276,12 @@ namespace OpenRA.Mods.Common.Traits if (cell.Layer != 0) return false; - var resType = resLayer.GetResourceType(cell); - if (resType == null) + var resourceType = resourceLayer.GetResource(cell).Type; + if (resourceType == null) return false; // Can the harvester collect this kind of resource? - return Info.Resources.Contains(resType.Info.Type); + return Info.Resources.Contains(resourceType.Info.Type); } IEnumerable IIssueOrder.Orders diff --git a/OpenRA.Mods.Common/Traits/SeedsResource.cs b/OpenRA.Mods.Common/Traits/SeedsResource.cs index e7bb894501..42bbd786b4 100644 --- a/OpenRA.Mods.Common/Traits/SeedsResource.cs +++ b/OpenRA.Mods.Common/Traits/SeedsResource.cs @@ -30,7 +30,7 @@ namespace OpenRA.Mods.Common.Traits readonly SeedsResourceInfo info; readonly ResourceType resourceType; - readonly ResourceLayer resLayer; + readonly IResourceLayer resourceLayer; public SeedsResource(Actor self, SeedsResourceInfo info) : base(info) @@ -43,7 +43,7 @@ namespace OpenRA.Mods.Common.Traits if (resourceType == null) throw new InvalidOperationException("No such resource type `{0}`".F(info.ResourceType)); - resLayer = self.World.WorldActor.Trait(); + resourceLayer = self.World.WorldActor.Trait(); } int ticks; @@ -64,12 +64,11 @@ namespace OpenRA.Mods.Common.Traits { var cell = Util.RandomWalk(self.Location, self.World.SharedRandom) .Take(info.MaxRange) - .SkipWhile(p => !self.World.Map.Contains(p) || - (resLayer.GetResourceType(p) == resourceType && resLayer.IsFull(p))) + .SkipWhile(p => resourceLayer.GetResource(p).Type == resourceType && !resourceLayer.CanAddResource(resourceType, p)) .Cast().FirstOrDefault(); - if (cell != null && resLayer.CanAddResource(resourceType, cell.Value)) - resLayer.AddResource(resourceType, cell.Value); + if (cell != null && resourceLayer.CanAddResource(resourceType, cell.Value)) + resourceLayer.AddResource(resourceType, cell.Value); } } } diff --git a/OpenRA.Mods.Common/Traits/World/EditorResourceLayer.cs b/OpenRA.Mods.Common/Traits/World/EditorResourceLayer.cs index ee47d882c8..4c3dc3732c 100644 --- a/OpenRA.Mods.Common/Traits/World/EditorResourceLayer.cs +++ b/OpenRA.Mods.Common/Traits/World/EditorResourceLayer.cs @@ -35,12 +35,13 @@ namespace OpenRA.Mods.Common.Traits public event Action 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); } 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); } void IResourceLayer.ClearResources(CPos cell) { ClearResources(cell); } bool IResourceLayer.IsVisible(CPos cell) { return Map.Contains(cell); } + bool IResourceLayer.IsEmpty => false; public EditorResourceLayer(Actor self) { diff --git a/OpenRA.Mods.Common/Traits/World/ResourceLayer.cs b/OpenRA.Mods.Common/Traits/World/ResourceLayer.cs index ee093a71b6..0e8c2a6b93 100644 --- a/OpenRA.Mods.Common/Traits/World/ResourceLayer.cs +++ b/OpenRA.Mods.Common/Traits/World/ResourceLayer.cs @@ -29,22 +29,7 @@ namespace OpenRA.Mods.Common.Traits } } - public interface IResourceLayerInfo : ITraitInfoInterface { } - - [RequireExplicitImplementation] - public interface IResourceLayer - { - event Action 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.")] + [Desc("Attach this to the world actor.")] public class ResourceLayerInfo : TraitInfo, IResourceLayerInfo, Requires, Requires { public override object Create(ActorInitializer init) { return new ResourceLayer(init.Self); } @@ -57,8 +42,6 @@ namespace OpenRA.Mods.Common.Traits protected readonly CellLayer Content; - public bool IsResourceLayerEmpty => resCells < 1; - int resCells; public event Action CellChanged; @@ -103,7 +86,7 @@ namespace OpenRA.Mods.Common.Traits foreach (var cell in w.Map.AllCells) { - var type = GetResourceType(cell); + var type = Content[cell].Type; if (type != null) { // Set initial density based on the number of neighboring resources @@ -140,7 +123,7 @@ namespace OpenRA.Mods.Common.Traits 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)) return false; @@ -155,7 +138,7 @@ namespace OpenRA.Mods.Common.Traits 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)) return 0; @@ -176,7 +159,7 @@ namespace OpenRA.Mods.Common.Traits 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)) return 0; @@ -205,7 +188,7 @@ namespace OpenRA.Mods.Common.Traits return oldDensity - density; } - public void ClearResources(CPos cell) + void ClearResources(CPos cell) { if (!Content.Contains(cell)) return; @@ -222,22 +205,12 @@ namespace OpenRA.Mods.Common.Traits CellChanged?.Invoke(cell, null); } - public bool IsFull(CPos cell) - { - 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]; } - + 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); } void IResourceLayer.ClearResources(CPos cell) { ClearResources(cell); } bool IResourceLayer.IsVisible(CPos cell) { return !world.FogObscures(cell); } + bool IResourceLayer.IsEmpty => resCells < 1; } } diff --git a/OpenRA.Mods.Common/TraitsInterfaces.cs b/OpenRA.Mods.Common/TraitsInterfaces.cs index baf92b6d99..2f509ad984 100644 --- a/OpenRA.Mods.Common/TraitsInterfaces.cs +++ b/OpenRA.Mods.Common/TraitsInterfaces.cs @@ -663,6 +663,22 @@ namespace OpenRA.Mods.Common.Traits IEnumerable RenderPreview(WorldRenderer wr, TerrainTemplateInfo template, WPos origin); } + public interface IResourceLayerInfo : ITraitInfoInterface { } + + [RequireExplicitImplementation] + public interface IResourceLayer + { + event Action 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] public interface IResourceRenderer { diff --git a/OpenRA.Mods.Common/Warheads/CreateResourceWarhead.cs b/OpenRA.Mods.Common/Warheads/CreateResourceWarhead.cs index c067f2a654..44b33aa4e5 100644 --- a/OpenRA.Mods.Common/Warheads/CreateResourceWarhead.cs +++ b/OpenRA.Mods.Common/Warheads/CreateResourceWarhead.cs @@ -56,14 +56,14 @@ namespace OpenRA.Mods.Common.Warheads var resourceType = world.WorldActor.TraitsImplementing() .First(t => t.Info.Type == AddsResourceType); - var resLayer = world.WorldActor.Trait(); + var resourceLayer = world.WorldActor.Trait(); foreach (var cell in allCells) { - if (!resLayer.CanAddResource(resourceType, cell)) + if (!resourceLayer.CanAddResource(resourceType, cell)) continue; - var splash = world.SharedRandom.Next(1, resourceType.Info.MaxDensity - resLayer.GetResourceDensity(cell)); - resLayer.AddResource(resourceType, cell, splash); + var splash = world.SharedRandom.Next(1, resourceType.Info.MaxDensity - resourceLayer.GetResource(cell).Density); + resourceLayer.AddResource(resourceType, cell, splash); } } } diff --git a/OpenRA.Mods.Common/Warheads/DestroyResourceWarhead.cs b/OpenRA.Mods.Common/Warheads/DestroyResourceWarhead.cs index bf60f30a64..054da05c12 100644 --- a/OpenRA.Mods.Common/Warheads/DestroyResourceWarhead.cs +++ b/OpenRA.Mods.Common/Warheads/DestroyResourceWarhead.cs @@ -34,14 +34,14 @@ namespace OpenRA.Mods.Common.Warheads return; var targetTile = world.Map.CellContaining(pos); - var resLayer = world.WorldActor.Trait(); + var resourceLayer = world.WorldActor.Trait(); var minRange = (Size.Length > 1 && Size[1] > 0) ? Size[1] : 0; var allCells = world.Map.FindTilesInAnnulus(targetTile, minRange, Size[0]); // Destroy all resources in the selected tiles foreach (var cell in allCells) - resLayer.ClearResources(cell); + resourceLayer.ClearResources(cell); } } } diff --git a/OpenRA.Mods.D2k/Traits/SpiceBloom.cs b/OpenRA.Mods.D2k/Traits/SpiceBloom.cs index 49950df666..eaec5da59c 100644 --- a/OpenRA.Mods.D2k/Traits/SpiceBloom.cs +++ b/OpenRA.Mods.D2k/Traits/SpiceBloom.cs @@ -61,8 +61,8 @@ namespace OpenRA.Mods.D2k.Traits public class SpiceBloom : ITick, INotifyKilled { readonly SpiceBloomInfo info; - readonly ResourceType resType; - readonly ResourceLayer resLayer; + readonly ResourceType resourceType; + readonly IResourceLayer resourceLayer; readonly Animation body; readonly Animation spurt; readonly int growTicks; @@ -75,8 +75,8 @@ namespace OpenRA.Mods.D2k.Traits { this.info = info; - resLayer = self.World.WorldActor.Trait(); - resType = self.World.WorldActor.TraitsImplementing().First(t => t.Info.Type == info.ResourceType); + resourceLayer = self.World.WorldActor.Trait(); + resourceType = self.World.WorldActor.TraitsImplementing().First(t => t.Info.Type == info.ResourceType); var rs = self.Trait(); body = new Animation(self.World, rs.GetImage(self)); @@ -126,7 +126,11 @@ namespace OpenRA.Mods.D2k.Traits for (var i = 0; i < pieces; i++) { - var cell = cells.SkipWhile(p => resLayer.GetResourceType(p) == resType && resLayer.IsFull(p)).Cast().RandomOrDefault(self.World.SharedRandom); + var cell = cells + .SkipWhile(p => resourceLayer.GetResource(p).Type == resourceType && !resourceLayer.CanAddResource(resourceType, p)) + .Cast() + .RandomOrDefault(self.World.SharedRandom); + if (cell == null) cell = cells.Random(self.World.SharedRandom);