Pass resource type and count to IAcceptResources instead of the value.

This commit is contained in:
Paul Chote
2021-03-07 20:16:48 +00:00
committed by reaperrr
parent 3dbc6400a6
commit 1dc26a9b8e
8 changed files with 84 additions and 72 deletions

View File

@@ -56,12 +56,12 @@ namespace OpenRA.Mods.Cnc.Traits
base.Created(self); base.Created(self);
} }
void INotifyResourceAccepted.OnResourceAccepted(Actor self, Actor refinery, int amount) void INotifyResourceAccepted.OnResourceAccepted(Actor self, Actor refinery, ResourceTypeInfo resourceType, int count, int value)
{ {
if (IsTraitDisabled) if (IsTraitDisabled)
return; return;
var cash = OpenRA.Mods.Common.Util.ApplyPercentageModifiers(amount, modifier); var cash = Common.Util.ApplyPercentageModifiers(value, modifier);
playerResources.GiveCash(cash); playerResources.GiveCash(cash);
if (Info.ShowTicks && self.Info.HasTraitInfo<IOccupySpaceInfo>()) if (Info.ShowTicks && self.Info.HasTraitInfo<IOccupySpaceInfo>())

View File

@@ -58,7 +58,7 @@ namespace OpenRA.Mods.Common.Traits
readonly Actor self; readonly Actor self;
readonly RefineryInfo info; readonly RefineryInfo info;
PlayerResources playerResources; PlayerResources playerResources;
RefineryResourceMultiplier[] resourceMultipliers; IEnumerable<int> resourceValueModifiers;
int currentDisplayTick = 0; int currentDisplayTick = 0;
int currentDisplayValue = 0; int currentDisplayValue = 0;
@@ -86,7 +86,7 @@ namespace OpenRA.Mods.Common.Traits
void INotifyCreated.Created(Actor self) void INotifyCreated.Created(Actor self)
{ {
resourceMultipliers = self.TraitsImplementing<RefineryResourceMultiplier>().ToArray(); resourceValueModifiers = self.TraitsImplementing<IResourceValueModifier>().ToArray().Select(m => m.GetResourceValueModifier());
} }
public virtual Activity DockSequence(Actor harv, Actor self) public virtual Activity DockSequence(Actor harv, Actor self)
@@ -100,32 +100,39 @@ namespace OpenRA.Mods.Common.Traits
.Where(a => a.Trait.LinkedProc == self); .Where(a => a.Trait.LinkedProc == self);
} }
public bool CanGiveResource(int amount) { return !info.UseStorage || info.DiscardExcessResources || playerResources.CanGiveResources(amount); } int IAcceptResources.AcceptResources(ResourceTypeInfo resourceType, int count)
public void GiveResource(int amount)
{ {
amount = Util.ApplyPercentageModifiers(amount, resourceMultipliers.Select(m => m.GetModifier())); var value = Util.ApplyPercentageModifiers(count * resourceType.ValuePerUnit, resourceValueModifiers);
if (info.UseStorage) if (info.UseStorage)
{ {
if (info.DiscardExcessResources) var storageLimit = Math.Max(playerResources.ResourceCapacity - playerResources.Resources, 0);
amount = Math.Min(amount, playerResources.ResourceCapacity - playerResources.Resources); if (!info.DiscardExcessResources)
{
playerResources.GiveResources(amount); // Reduce amount if needed until it will fit the available storage
while (value > storageLimit)
value = Util.ApplyPercentageModifiers(--count * resourceType.ValuePerUnit, resourceValueModifiers);
} }
else else
amount = playerResources.ChangeCash(amount); value = Math.Min(value, playerResources.ResourceCapacity - playerResources.Resources);
playerResources.GiveResources(value);
}
else
value = playerResources.ChangeCash(value);
foreach (var notify in self.World.ActorsWithTrait<INotifyResourceAccepted>()) foreach (var notify in self.World.ActorsWithTrait<INotifyResourceAccepted>())
{ {
if (notify.Actor.Owner != self.Owner) if (notify.Actor.Owner != self.Owner)
continue; continue;
notify.Trait.OnResourceAccepted(notify.Actor, self, amount); notify.Trait.OnResourceAccepted(notify.Actor, self, resourceType, count, value);
} }
if (info.ShowTicks) if (info.ShowTicks)
currentDisplayValue += amount; currentDisplayValue += value;
return count;
} }
void CancelDock(Actor self) void CancelDock(Actor self)

View File

@@ -110,7 +110,6 @@ namespace OpenRA.Mods.Common.Traits
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;
HarvesterResourceMultiplier[] resourceMultipliers;
[Sync] [Sync]
public Actor LastLinkedProc = null; public Actor LastLinkedProc = null;
@@ -145,7 +144,6 @@ namespace OpenRA.Mods.Common.Traits
void INotifyCreated.Created(Actor self) void INotifyCreated.Created(Actor self)
{ {
resourceMultipliers = self.TraitsImplementing<HarvesterResourceMultiplier>().ToArray();
UpdateCondition(self); UpdateCondition(self);
// Note: This is queued in a FrameEndTask because otherwise the activity is dropped/overridden while moving out of a factory. // Note: This is queued in a FrameEndTask because otherwise the activity is dropped/overridden while moving out of a factory.
@@ -242,7 +240,7 @@ namespace OpenRA.Mods.Common.Traits
} }
// Returns true when unloading is complete // Returns true when unloading is complete
public bool TickUnload(Actor self, Actor proc) public virtual bool TickUnload(Actor self, Actor proc)
{ {
// Wait until the next bale is ready // Wait until the next bale is ready
if (--currentUnloadTicks > 0) if (--currentUnloadTicks > 0)
@@ -250,21 +248,23 @@ namespace OpenRA.Mods.Common.Traits
if (contents.Keys.Count > 0) if (contents.Keys.Count > 0)
{ {
var type = contents.First().Key; var acceptResources = proc.Trait<IAcceptResources>();
var iao = proc.Trait<IAcceptResources>(); foreach (var c in contents)
var count = Math.Min(contents[type], Info.BaleUnloadAmount); {
var value = Util.ApplyPercentageModifiers(type.ValuePerUnit * count, resourceMultipliers.Select(m => m.GetModifier())); var resourceType = c.Key;
var count = Math.Min(c.Value, Info.BaleUnloadAmount);
var accepted = acceptResources.AcceptResources(resourceType, count);
if (accepted == 0)
continue;
if (!iao.CanGiveResource(value)) contents[resourceType] -= accepted;
return false; if (contents[resourceType] <= 0)
contents.Remove(resourceType);
iao.GiveResource(value);
contents[type] -= count;
if (contents[type] == 0)
contents.Remove(type);
currentUnloadTicks = Info.BaleUnloadDelay; currentUnloadTicks = Info.BaleUnloadDelay;
UpdateCondition(self); UpdateCondition(self);
return false;
}
} }
return contents.Count == 0; return contents.Count == 0;

View File

@@ -1,33 +0,0 @@
#region Copyright & License Information
/*
* Copyright 2007-2020 The OpenRA Developers (see AUTHORS)
* This file is part of OpenRA, which is free software. It is made
* available to you under the terms of the GNU General Public License
* as published by the Free Software Foundation, either version 3 of
* the License, or (at your option) any later version. For more
* information, see COPYING.
*/
#endregion
using OpenRA.Traits;
namespace OpenRA.Mods.Common.Traits
{
[Desc("Modifies the bale values delivered to this refinery.")]
public class RefineryResourceMultiplierInfo : ConditionalTraitInfo
{
[FieldLoader.Require]
[Desc("Percentage modifier to apply.")]
public readonly int Modifier = 100;
public override object Create(ActorInitializer init) { return new RefineryResourceMultiplier(this); }
}
public class RefineryResourceMultiplier : ConditionalTrait<RefineryResourceMultiplierInfo>, Requires<RefineryInfo>
{
public RefineryResourceMultiplier(RefineryResourceMultiplierInfo info)
: base(info) { }
public int GetModifier() { return IsTraitDisabled ? 100 : Info.Modifier; }
}
}

View File

@@ -13,21 +13,21 @@ using OpenRA.Traits;
namespace OpenRA.Mods.Common.Traits namespace OpenRA.Mods.Common.Traits
{ {
[Desc("Modifies the bale values of this harvester.")] [Desc("Modifies the value of resources delivered to this actor.")]
public class HarvesterResourceMultiplierInfo : ConditionalTraitInfo public class ResourceValueMultiplierInfo : ConditionalTraitInfo
{ {
[FieldLoader.Require] [FieldLoader.Require]
[Desc("Percentage modifier to apply.")] [Desc("Percentage modifier to apply.")]
public readonly int Modifier = 100; public readonly int Modifier = 100;
public override object Create(ActorInitializer init) { return new HarvesterResourceMultiplier(this); } public override object Create(ActorInitializer init) { return new ResourceValueMultiplier(this); }
} }
public class HarvesterResourceMultiplier : ConditionalTrait<HarvesterResourceMultiplierInfo>, Requires<HarvesterInfo> public class ResourceValueMultiplier : ConditionalTrait<ResourceValueMultiplierInfo>, IResourceValueModifier
{ {
public HarvesterResourceMultiplier(HarvesterResourceMultiplierInfo info) public ResourceValueMultiplier(ResourceValueMultiplierInfo info)
: base(info) { } : base(info) { }
public int GetModifier() { return IsTraitDisabled ? 100 : Info.Modifier; } int IResourceValueModifier.GetResourceValueModifier() { return IsTraitDisabled ? 100 : Info.Modifier; }
} }
} }

View File

@@ -152,7 +152,7 @@ namespace OpenRA.Mods.Common.Traits
public interface INotifyDocking { void Docked(Actor self, Actor harvester); void Undocked(Actor self, Actor harvester); } public interface INotifyDocking { void Docked(Actor self, Actor harvester); void Undocked(Actor self, Actor harvester); }
[RequireExplicitImplementation] [RequireExplicitImplementation]
public interface INotifyResourceAccepted { void OnResourceAccepted(Actor self, Actor refinery, int amount); } public interface INotifyResourceAccepted { void OnResourceAccepted(Actor self, Actor refinery, ResourceTypeInfo resourceType, int count, int value); }
public interface INotifyParachute { void OnParachute(Actor self); void OnLanded(Actor self); } public interface INotifyParachute { void OnParachute(Actor self); void OnLanded(Actor self); }
[RequireExplicitImplementation] [RequireExplicitImplementation]
@@ -260,8 +260,7 @@ namespace OpenRA.Mods.Common.Traits
public interface IAcceptResources public interface IAcceptResources
{ {
void OnDock(Actor harv, DeliverResources dockOrder); void OnDock(Actor harv, DeliverResources dockOrder);
void GiveResource(int amount); int AcceptResources(ResourceTypeInfo resourceType, int count = 1);
bool CanGiveResource(int amount);
CVec DeliveryOffset { get; } CVec DeliveryOffset { get; }
bool AllowDocking { get; } bool AllowDocking { get; }
} }
@@ -380,6 +379,9 @@ namespace OpenRA.Mods.Common.Traits
[RequireExplicitImplementation] [RequireExplicitImplementation]
public interface IDetectCloakedModifier { int GetDetectCloakedModifier(); } public interface IDetectCloakedModifier { int GetDetectCloakedModifier(); }
[RequireExplicitImplementation]
public interface IResourceValueModifier { int GetResourceValueModifier(); }
[RequireExplicitImplementation] [RequireExplicitImplementation]
public interface ICustomMovementLayer public interface ICustomMovementLayer
{ {

View File

@@ -0,0 +1,35 @@
#region Copyright & License Information
/*
* Copyright 2007-2020 The OpenRA Developers (see AUTHORS)
* This file is part of OpenRA, which is free software. It is made
* available to you under the terms of the GNU General Public License
* as published by the Free Software Foundation, either version 3 of
* the License, or (at your option) any later version. For more
* information, see COPYING.
*/
#endregion
using System.Collections.Generic;
using System.Linq;
namespace OpenRA.Mods.Common.UpdateRules.Rules
{
public class ReplaceResourceValueModifiers : UpdateRule
{
public override string Name => "HarvesterResourceMultiplier and RefineryResourceMultiplier replaced with ResourceValueMultiplier.";
public override string Description => "The HarvesterResourceMultiplier trait has been removed, and the RefineryResourceMultiplier trait renamed to ResourceValueMultiplier.";
bool notified;
public override IEnumerable<string> UpdateActorNode(ModData modData, MiniYamlNode actorNode)
{
if (actorNode.RemoveNodes("HarvesterResourceModifier") > 0 && !notified)
{
notified = true;
yield return "The HarvesterResourceMultiplier trait is no longer supported and has been removed.";
}
actorNode.RenameChildrenMatching("RefineryResourceMultiplier", "ResourceValueMultiplier");
}
}
}

View File

@@ -90,6 +90,7 @@ namespace OpenRA.Mods.Common.UpdateRules
new RemoveRenderSpritesScale(), new RemoveRenderSpritesScale(),
new RemovePlaceBuildingPalette(), new RemovePlaceBuildingPalette(),
new ReplaceShadowPalette(), new ReplaceShadowPalette(),
new ReplaceResourceValueModifiers(),
}) })
}; };