ExternalCondition: List<struct TimedToken> timedTokens
This commit is contained in:
@@ -34,10 +34,10 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
|
|
||||||
public class ExternalCondition : ITick
|
public class ExternalCondition : ITick
|
||||||
{
|
{
|
||||||
class TimedToken
|
struct TimedToken
|
||||||
{
|
{
|
||||||
public readonly int Token;
|
|
||||||
public readonly int Expires;
|
public readonly int Expires;
|
||||||
|
public readonly int Token;
|
||||||
public readonly object Source;
|
public readonly object Source;
|
||||||
|
|
||||||
public TimedToken(int token, Actor self, object source, int duration)
|
public TimedToken(int token, Actor self, object source, int duration)
|
||||||
@@ -51,7 +51,9 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
public readonly ExternalConditionInfo Info;
|
public readonly ExternalConditionInfo Info;
|
||||||
readonly ConditionManager conditionManager;
|
readonly ConditionManager conditionManager;
|
||||||
readonly Dictionary<object, HashSet<int>> permanentTokens = new Dictionary<object, HashSet<int>>();
|
readonly Dictionary<object, HashSet<int>> permanentTokens = new Dictionary<object, HashSet<int>>();
|
||||||
readonly List<KeyValuePair<int, TimedToken>> timedTokensByExpiration = new List<KeyValuePair<int, TimedToken>>();
|
|
||||||
|
// Tokens are sorted on insert/remove by ascending expiry time
|
||||||
|
readonly List<TimedToken> timedTokens = new List<TimedToken>();
|
||||||
|
|
||||||
public ExternalCondition(Actor self, ExternalConditionInfo info)
|
public ExternalCondition(Actor self, ExternalConditionInfo info)
|
||||||
{
|
{
|
||||||
@@ -79,20 +81,6 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Remove(TimedToken timedToken)
|
|
||||||
{
|
|
||||||
timedTokensByExpiration.RemoveAt(timedTokensByExpiration.FindIndex(p => p.Value == timedToken));
|
|
||||||
}
|
|
||||||
|
|
||||||
void Add(TimedToken timedToken)
|
|
||||||
{
|
|
||||||
var index = timedTokensByExpiration.FindIndex(p => p.Key >= timedToken.Expires);
|
|
||||||
if (index >= 0)
|
|
||||||
timedTokensByExpiration.Insert(index, new KeyValuePair<int, TimedToken>(timedToken.Expires, timedToken));
|
|
||||||
else
|
|
||||||
timedTokensByExpiration.Add(new KeyValuePair<int, TimedToken>(timedToken.Expires, timedToken));
|
|
||||||
}
|
|
||||||
|
|
||||||
public int GrantCondition(Actor self, object source, int duration = 0)
|
public int GrantCondition(Actor self, object source, int duration = 0)
|
||||||
{
|
{
|
||||||
if (!CanGrantCondition(self, source))
|
if (!CanGrantCondition(self, source))
|
||||||
@@ -107,41 +95,44 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
// Check level caps
|
// Check level caps
|
||||||
if (Info.SourceCap > 0)
|
if (Info.SourceCap > 0)
|
||||||
{
|
{
|
||||||
var timedCount = timedTokensByExpiration.Count(p => p.Value.Source == source);
|
var timedCount = timedTokens.Count(t => t.Source == source);
|
||||||
if ((permanent != null ? permanent.Count + timedCount : timedCount) >= Info.SourceCap)
|
if ((permanent != null ? permanent.Count + timedCount : timedCount) >= Info.SourceCap)
|
||||||
{
|
{
|
||||||
// Get timed token from the same source with closest expiration.
|
// Get timed token from the same source with closest expiration.
|
||||||
var expireIndex = timedTokensByExpiration.FindIndex(t => t.Value.Source == source);
|
var expireIndex = timedTokens.FindIndex(t => t.Source == source);
|
||||||
if (expireIndex >= 0)
|
if (expireIndex >= 0)
|
||||||
{
|
{
|
||||||
var expire = timedTokensByExpiration[expireIndex].Value;
|
var expireToken = timedTokens[expireIndex].Token;
|
||||||
Remove(expire);
|
timedTokens.RemoveAt(expireIndex);
|
||||||
|
if (conditionManager.TokenValid(self, expireToken))
|
||||||
if (conditionManager.TokenValid(self, expire.Token))
|
conditionManager.RevokeCondition(self, expireToken);
|
||||||
conditionManager.RevokeCondition(self, expire.Token);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Info.TotalCap > 0)
|
if (Info.TotalCap > 0)
|
||||||
{
|
{
|
||||||
var totalCount = permanentTokens.Values.Sum(t => t.Count) + timedTokensByExpiration.Count;
|
var totalCount = permanentTokens.Values.Sum(t => t.Count) + timedTokens.Count;
|
||||||
if (totalCount >= Info.TotalCap)
|
if (totalCount >= Info.TotalCap)
|
||||||
{
|
{
|
||||||
// Prefer tokens from the same source
|
// Prefer tokens from the same source
|
||||||
var expire = timedTokensByExpiration.FirstOrDefault().Value;
|
if (timedTokens.Count > 0)
|
||||||
if (expire != null)
|
|
||||||
{
|
{
|
||||||
if (conditionManager.TokenValid(self, expire.Token))
|
var expire = timedTokens[0].Token;
|
||||||
conditionManager.RevokeCondition(self, expire.Token);
|
if (conditionManager.TokenValid(self, expire))
|
||||||
|
conditionManager.RevokeCondition(self, expire);
|
||||||
|
|
||||||
Remove(expire);
|
timedTokens.RemoveAt(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var timedToken = new TimedToken(token, self, source, duration);
|
var timedToken = new TimedToken(token, self, source, duration);
|
||||||
Add(timedToken);
|
var index = timedTokens.FindIndex(t => t.Expires >= timedToken.Expires);
|
||||||
|
if (index >= 0)
|
||||||
|
timedTokens.Insert(index, timedToken);
|
||||||
|
else
|
||||||
|
timedTokens.Add(timedToken);
|
||||||
}
|
}
|
||||||
else if (permanent == null)
|
else if (permanent == null)
|
||||||
permanentTokens.Add(source, new HashSet<int> { token });
|
permanentTokens.Add(source, new HashSet<int> { token });
|
||||||
@@ -166,9 +157,9 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var index = timedTokensByExpiration.FindIndex(p => p.Value.Token == token);
|
var index = timedTokens.FindIndex(p => p.Token == token);
|
||||||
if (index >= 0 && timedTokensByExpiration[index].Value.Source == source)
|
if (index >= 0 && timedTokens[index].Source == source)
|
||||||
timedTokensByExpiration.RemoveAt(index);
|
timedTokens.RemoveAt(index);
|
||||||
else
|
else
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -184,11 +175,11 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
// Remove expired tokens
|
// Remove expired tokens
|
||||||
var worldTick = self.World.WorldTick;
|
var worldTick = self.World.WorldTick;
|
||||||
var count = 0;
|
var count = 0;
|
||||||
while (count < timedTokensByExpiration.Count && timedTokensByExpiration[count].Key < worldTick)
|
while (count < timedTokens.Count && timedTokens[count].Expires < worldTick)
|
||||||
count++;
|
count++;
|
||||||
|
|
||||||
if (count > 0)
|
if (count > 0)
|
||||||
timedTokensByExpiration.RemoveRange(0, count);
|
timedTokens.RemoveRange(0, count);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user