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) { if (Info.SourceCap > 0) { var timedCount = timedTokens.Count(t => t.Source == source); if ((permanent != null ? permanent.Count + timedCount:timedCount) >= Info.SourceCap) { 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) { 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); expires = timedToken.Expires; this.duration = duration; } } else if (permanent == null) { permanentTokens.Add(source, new HashSet <int> { token }); } else { permanent.Add(token); } return(token); }