Files
OpenRA/OpenRA.Mods.Common/Upgrades/UpgradableTrait.cs
atlimit8 bbd54cb32f Added IDisabledTrait & rewrote upgrade code using a level-based approach.
Upgradeable traits are notified whenever an upgrade of their declared types are granted or revoked.  The traits maintain their own internal level counter, which is then used to enable or disable the trait functionality.  A trait can register for multiple upgrade types which then all affect the internal level counter.

	IDisabledTrait for identifying (and filtering) disabled traits
	UpgradableTrait provides an abstract base for traits to support upgrade levels
	Added IDisabledTrait support to GlobalButtonOrderGenerator

	Includes rework by pchote with alterations.
2014-11-26 05:45:26 -06:00

87 lines
3.2 KiB
C#

#region Copyright & License Information
/*
* Copyright 2007-2014 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. For more information,
* see COPYING.
*/
#endregion
using System.Collections.Generic;
using System.Linq;
using OpenRA.Traits;
namespace OpenRA.Mods.Common
{
/// <summary>Use as base class for *Info to subclass of UpgradableTrait. (See UpgradableTrait.)</summary>
public abstract class UpgradableTraitInfo
{
[Desc("The upgrade types which can enable or disable this trait.")]
public readonly string[] UpgradeTypes = { };
[Desc("The minimum upgrade level at which this trait is enabled.", "Defaults to 0 (enabled by default).")]
public readonly int UpgradeMinEnabledLevel = 0;
[Desc("The maximum upgrade level at which the trait is enabled.",
"Defaults to UpgradeMaxAcceptedLevel (enabled for all levels greater than UpgradeMinEnabledLevel).",
"Set this to a value smaller than UpgradeMaxAcceptedLevel to disable the trait at higher levels.",
"Use UpgradeMaxAcceptedLevel: 2 (1 more) to be able to extend upgrade time.")]
public readonly int UpgradeMaxEnabledLevel = int.MaxValue;
[Desc("The maximum upgrade level that this trait will accept.")]
public readonly int UpgradeMaxAcceptedLevel = 1;
}
/// <summary>
/// Abstract base for enabling and disabling trait using upgrades.
/// Requires basing *Info on UpgradableTraitInfo and using base(info) constructor.
/// Note that EnabledByUpgrade is not called at creation even if this starts as enabled.
/// </summary>,
public abstract class UpgradableTrait<InfoType> : IUpgradable, IDisabledTrait, ISync where InfoType : UpgradableTraitInfo
{
public readonly InfoType Info;
public IEnumerable<string> UpgradeTypes { get { return Info.UpgradeTypes; } }
[Sync] public bool IsTraitDisabled { get; private set; }
public UpgradableTrait(InfoType info)
{
Info = info;
IsTraitDisabled = info.UpgradeTypes != null && info.UpgradeTypes.Length > 0 && info.UpgradeMinEnabledLevel > 0;
}
public bool AcceptsUpgradeLevel(Actor self, string type, int level)
{
return level > 0 && level <= Info.UpgradeMaxAcceptedLevel;
}
public void UpgradeLevelChanged(Actor self, string type, int oldLevel, int newLevel)
{
if (!Info.UpgradeTypes.Contains(type))
return;
// Restrict the levels to the allowed range
oldLevel = oldLevel.Clamp(0, Info.UpgradeMaxAcceptedLevel);
newLevel = newLevel.Clamp(0, Info.UpgradeMaxAcceptedLevel);
if (oldLevel == newLevel)
return;
var wasDisabled = IsTraitDisabled;
IsTraitDisabled = newLevel < Info.UpgradeMinEnabledLevel || newLevel > Info.UpgradeMaxEnabledLevel;
UpgradeLevelChanged(self, oldLevel, newLevel);
if (IsTraitDisabled != wasDisabled)
{
if (wasDisabled)
UpgradeEnabled(self);
else
UpgradeDisabled(self);
}
}
// Subclasses can add upgrade support by querying IsTraitDisabled and/or overriding these methods.
protected virtual void UpgradeLevelChanged(Actor self, int oldLevel, int newLevel) { }
protected virtual void UpgradeEnabled(Actor self) { }
protected virtual void UpgradeDisabled(Actor self) { }
}
}