public int GrantCondition(Actor self, object source, int duration = 0) { if (!CanGrantCondition(self, source)) { return(ConditionManager.InvalidConditionToken); } var token = conditionManager.GrantCondition(self, Info.Condition); HashSet <int> permanent; permanentTokens.TryGetValue(source, out permanent); if (duration > 0) { // Check level caps if (Info.SourceCap > 0) { var timedCount = timedTokens.Count(t => t.Source == source); if ((permanent != null ? permanent.Count + timedCount : timedCount) >= Info.SourceCap) { // Get timed token from the same source with closest expiration. var expireIndex = timedTokens.FindIndex(t => t.Source == source); if (expireIndex >= 0) { var expireToken = timedTokens[expireIndex].Token; timedTokens.RemoveAt(expireIndex); if (conditionManager.TokenValid(self, expireToken)) { conditionManager.RevokeCondition(self, expireToken); } } } } if (Info.TotalCap > 0) { var totalCount = permanentTokens.Values.Sum(t => t.Count) + timedTokens.Count; if (totalCount >= Info.TotalCap) { // Prefer tokens from the same source if (timedTokens.Count > 0) { var expire = timedTokens[0].Token; if (conditionManager.TokenValid(self, expire)) { conditionManager.RevokeCondition(self, expire); } timedTokens.RemoveAt(0); } } } var timedToken = new TimedToken(token, self, source, duration); var index = timedTokens.FindIndex(t => t.Expires >= timedToken.Expires); if (index >= 0) { timedTokens.Insert(index, timedToken); } else { timedTokens.Add(timedToken); // Track the duration and expiration for the longest remaining timer. expires = timedToken.Expires; this.duration = duration; } } else if (permanent == null) { permanentTokens.Add(source, new HashSet <int> { token }); } else { permanent.Add(token); } return(token); }
public int GrantCondition(Actor self, object source, int duration = 0, int remaining = 0) { if (!CanGrantCondition(self, source)) { return(Actor.InvalidConditionToken); } var token = self.GrantCondition(Info.Condition); permanentTokens.TryGetValue(source, out var permanent); // Callers can override the amount of time remaining by passing a value // between 1 and the duration if (remaining <= 0 || remaining > duration) { remaining = duration; } if (duration > 0) { // Check level caps if (Info.SourceCap > 0) { var timedCount = timedTokens.Count(t => t.Source == source); if ((permanent?.Count ?? 0) + timedCount >= Info.SourceCap) { // Get timed token from the same source with closest expiration. var expireIndex = timedTokens.FindIndex(t => t.Source == source); if (expireIndex >= 0) { var expireToken = timedTokens[expireIndex].Token; timedTokens.RemoveAt(expireIndex); if (self.TokenValid(expireToken)) { self.RevokeCondition(expireToken); } } } } if (Info.TotalCap > 0) { var totalCount = permanentTokens.Values.Sum(t => t.Count) + timedTokens.Count; if (totalCount >= Info.TotalCap) { // Prefer tokens from the same source if (timedTokens.Count > 0) { var expire = timedTokens[0].Token; if (self.TokenValid(expire)) { self.RevokeCondition(expire); } timedTokens.RemoveAt(0); } } } var timedToken = new TimedToken(token, self, source, remaining); var index = timedTokens.FindIndex(t => t.Expires >= timedToken.Expires); if (index >= 0) { timedTokens.Insert(index, timedToken); } else { timedTokens.Add(timedToken); // Track the duration and expiration for the longest remaining timer. expires = timedToken.Expires; this.duration = duration; } } else if (permanent == null) { permanentTokens.Add(source, new HashSet <int> { token }); } else { permanent.Add(token); } return(token); }