Rework harvester resource claiming:
* Maintains lists of claims, and only restricts reservations for friendly units. * Removes OnNotifyResourceClaimLost; it's not clear whether that is still useful, and it prevents future necessary cleanups. * Moves other code without changing behaviour. This fixed stale claims from dead units and enemy claims from preventing otherwise valid harvest activities.
This commit is contained in:
@@ -78,10 +78,12 @@ namespace OpenRA.Mods.Common.Traits
|
||||
|
||||
public class Harvester : IIssueOrder, IResolveOrder, IPips,
|
||||
IExplodeModifier, IOrderVoice, ISpeedModifier, ISync, INotifyCreated,
|
||||
INotifyResourceClaimLost, INotifyIdle, INotifyBlockingMove, INotifyBuildComplete
|
||||
INotifyIdle, INotifyBlockingMove, INotifyBuildComplete
|
||||
{
|
||||
public readonly HarvesterInfo Info;
|
||||
readonly Mobile mobile;
|
||||
readonly ResourceLayer resLayer;
|
||||
readonly ResourceClaimLayer claimLayer;
|
||||
Dictionary<ResourceTypeInfo, int> contents = new Dictionary<ResourceTypeInfo, int>();
|
||||
bool idleSmart = true;
|
||||
int idleDuration;
|
||||
@@ -108,6 +110,9 @@ namespace OpenRA.Mods.Common.Traits
|
||||
{
|
||||
Info = info;
|
||||
mobile = self.Trait<Mobile>();
|
||||
resLayer = self.World.WorldActor.Trait<ResourceLayer>();
|
||||
claimLayer = self.World.WorldActor.Trait<ResourceClaimLayer>();
|
||||
|
||||
self.QueueActivity(new CallFunc(() => ChooseNewProc(self, null)));
|
||||
}
|
||||
|
||||
@@ -211,8 +216,10 @@ namespace OpenRA.Mods.Common.Traits
|
||||
|
||||
public void AcceptResource(ResourceType type)
|
||||
{
|
||||
if (!contents.ContainsKey(type.Info)) contents[type.Info] = 1;
|
||||
else contents[type.Info]++;
|
||||
if (!contents.ContainsKey(type.Info))
|
||||
contents[type.Info] = 1;
|
||||
else
|
||||
contents[type.Info]++;
|
||||
}
|
||||
|
||||
public void UnblockRefinery(Actor self)
|
||||
@@ -309,6 +316,20 @@ namespace OpenRA.Mods.Common.Traits
|
||||
return contents.Count == 0;
|
||||
}
|
||||
|
||||
public bool CanHarvestCell(Actor self, CPos cell)
|
||||
{
|
||||
// Resources only exist in the ground layer
|
||||
if (cell.Layer != 0)
|
||||
return false;
|
||||
|
||||
var resType = resLayer.GetResource(cell);
|
||||
if (resType == null)
|
||||
return false;
|
||||
|
||||
// Can the harvester collect this kind of resource?
|
||||
return Info.Resources.Contains(resType.Info.Type);
|
||||
}
|
||||
|
||||
public IEnumerable<IOrderTargeter> Orders
|
||||
{
|
||||
get
|
||||
@@ -355,20 +376,8 @@ namespace OpenRA.Mods.Common.Traits
|
||||
CPos? loc;
|
||||
if (order.TargetLocation != CPos.Zero)
|
||||
{
|
||||
loc = order.TargetLocation;
|
||||
|
||||
var territory = self.World.WorldActor.TraitOrDefault<ResourceClaimLayer>();
|
||||
if (territory != null)
|
||||
{
|
||||
// Find the nearest claimable cell to the order location (useful for group-select harvest):
|
||||
loc = mobile.NearestCell(loc.Value, p => mobile.CanEnterCell(p) && territory.ClaimResource(self, p), 1, 6);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Find the nearest cell to the order location (useful for group-select harvest):
|
||||
var taken = new HashSet<CPos>();
|
||||
loc = mobile.NearestCell(loc.Value, p => mobile.CanEnterCell(p) && taken.Add(p), 1, 6);
|
||||
}
|
||||
// Find the nearest claimable cell to the order location (useful for group-select harvest):
|
||||
loc = mobile.NearestCell(order.TargetLocation, p => mobile.CanEnterCell(p) && claimLayer.TryClaimCell(self, p), 1, 6);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -423,15 +432,6 @@ namespace OpenRA.Mods.Common.Traits
|
||||
}
|
||||
}
|
||||
|
||||
public void OnNotifyResourceClaimLost(Actor self, ResourceClaim claim, Actor claimer)
|
||||
{
|
||||
if (self == claimer) return;
|
||||
|
||||
// Our claim on a resource was stolen, find more unclaimed resources:
|
||||
self.CancelActivity();
|
||||
self.QueueActivity(new FindResources(self));
|
||||
}
|
||||
|
||||
PipType GetPipAt(int i)
|
||||
{
|
||||
var n = i * Info.Capacity / Info.PipCount;
|
||||
|
||||
Reference in New Issue
Block a user