Exemplo n.º 1
0
        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);
        }
Exemplo n.º 2
0
        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);
        }