Ejemplo n.º 1
0
        void ITick.Tick(Actor self)
        {
            if (conditionManager == null)
            {
                return;
            }

            var isMovingVertically = Info.ConsiderVerticalMovement ? movement.IsMovingVertically : false;
            var isMoving           = !IsTraitDisabled && !self.IsDead && (movement.IsMoving || isMovingVertically);

            if (isMoving && conditionToken == ConditionManager.InvalidConditionToken)
            {
                conditionToken = conditionManager.GrantCondition(self, Info.Condition);
            }
            else if (!isMoving && conditionToken != ConditionManager.InvalidConditionToken)
            {
                conditionToken = conditionManager.RevokeCondition(self, conditionToken);
            }
        }
Ejemplo n.º 2
0
        void ApplyStanceCondition(Actor self)
        {
            if (conditionManager == null)
            {
                return;
            }

            if (conditionToken != ConditionManager.InvalidConditionToken)
            {
                conditionToken = conditionManager.RevokeCondition(self, conditionToken);
            }

            string condition;

            if (Info.ConditionByStance.TryGetValue(stance, out condition))
            {
                conditionToken = conditionManager.GrantCondition(self, condition);
            }
        }
Ejemplo n.º 3
0
        void UpdateCondition(Actor self)
        {
            if (conditionManager == null || string.IsNullOrEmpty(Info.RepairCondition))
            {
                return;
            }

            var currentRepairers = Repairers.Count;

            while (Repairers.Count > repairTokens.Count)
            {
                repairTokens.Push(conditionManager.GrantCondition(self, Info.RepairCondition));
            }

            while (Repairers.Count < repairTokens.Count && repairTokens.Count > 0)
            {
                conditionManager.RevokeCondition(self, repairTokens.Pop());
            }
        }
Ejemplo n.º 4
0
        void ITick.Tick(Actor self)
        {
            // Stop charging when we lose our target
            charging &= self.CurrentActivity is SetTarget;

            var delta = charging ? info.ChargeRate : -info.DischargeRate;

            ChargeLevel = (ChargeLevel + delta).Clamp(0, info.ChargeLevel);

            if (ChargeLevel > 0 && conditionManager != null && !string.IsNullOrEmpty(info.ChargingCondition) &&
                chargingToken == ConditionManager.InvalidConditionToken)
            {
                chargingToken = conditionManager.GrantCondition(self, info.ChargingCondition);
            }

            if (ChargeLevel == 0 && conditionManager != null && chargingToken != ConditionManager.InvalidConditionToken)
            {
                chargingToken = conditionManager.RevokeCondition(self, chargingToken);
            }
        }
Ejemplo n.º 5
0
        void Kill(Actor self)
        {
            if (self.IsDead)
            {
                return;
            }

            if (conditionManager != null && !string.IsNullOrEmpty(Info.GrantsCondition))
            {
                conditionManager.GrantCondition(self, Info.GrantsCondition);
            }

            if (Info.RemoveInstead || !self.Info.HasTraitInfo <IHealthInfo>())
            {
                self.Dispose();
            }
            else
            {
                self.Kill(self, Info.DamageTypes);
            }
        }
        void SetCondition(Actor self, bool granted)
        {
            if (conditionManager == null)
            {
                return;
            }

            if (granted && conditionToken == ConditionManager.InvalidConditionToken)
            {
                conditionToken = conditionManager.GrantCondition(self, Info.Condition);

                if (Info.EnabledSound != null)
                {
                    Game.Sound.PlayNotification(self.World.Map.Rules, self.Owner, "Sounds", Info.EnabledSound, self.Owner.Faction.InternalName);
                }

                if (Info.EnabledSpeech != null)
                {
                    Game.Sound.PlayNotification(self.World.Map.Rules, self.Owner, "Speech", Info.EnabledSpeech, self.Owner.Faction.InternalName);
                }
            }
            else if (!granted && conditionToken != ConditionManager.InvalidConditionToken)
            {
                conditionToken = conditionManager.RevokeCondition(self, conditionToken);

                if (Info.DisabledSound != null)
                {
                    Game.Sound.PlayNotification(self.World.Map.Rules, self.Owner, "Sounds", Info.DisabledSound, self.Owner.Faction.InternalName);
                }

                if (Info.DisabledSpeech != null)
                {
                    Game.Sound.PlayNotification(self.World.Map.Rules, self.Owner, "Speech", Info.DisabledSpeech, self.Owner.Faction.InternalName);
                }
            }
        }
Ejemplo n.º 7
0
        public void SetPrimaryProducer(Actor self, bool isPrimary)
        {
            IsPrimary = isPrimary;

            if (isPrimary)
            {
                // Cancel existing primaries
                // TODO: THIS IS SHIT
                var queues = Info.ProductionQueues.Length == 0 ? self.TraitsImplementing <Production>()
                             .Where(t => !t.IsTraitDisabled).SelectMany(pi => pi.Info.Produces) : Info.ProductionQueues;
                foreach (var q in queues)
                {
                    foreach (var b in self.World
                             .ActorsWithTrait <PrimaryBuilding>()
                             .Where(a =>
                                    a.Actor != self &&
                                    a.Actor.Owner == self.Owner &&
                                    a.Trait.IsPrimary &&
                                    a.Actor.TraitsImplementing <Production>().Where(p => !p.IsTraitDisabled).Any(pi => pi.Info.Produces.Contains(q))))
                    {
                        b.Trait.SetPrimaryProducer(b.Actor, false);
                    }
                }

                if (conditionManager != null && primaryToken == ConditionManager.InvalidConditionToken && !string.IsNullOrEmpty(Info.PrimaryCondition))
                {
                    primaryToken = conditionManager.GrantCondition(self, Info.PrimaryCondition);
                }

                Game.Sound.PlayNotification(self.World.Map.Rules, self.Owner, "Speech", Info.SelectionNotification, self.Owner.Faction.InternalName);
            }
            else if (primaryToken != ConditionManager.InvalidConditionToken)
            {
                primaryToken = conditionManager.RevokeCondition(self, primaryToken);
            }
        }
Ejemplo n.º 8
0
        void ITick.Tick(Actor self)
        {
            if (conditionManager == null)
            {
                return;
            }

            var currentTerrain = self.World.Map.GetTerrainInfo(self.Location).Type;
            var wantsGranted   = info.TerrainTypes.Contains(currentTerrain);

            if (currentTerrain != previousTerrain)
            {
                if (wantsGranted && conditionToken == ConditionManager.InvalidConditionToken)
                {
                    conditionToken = conditionManager.GrantCondition(self, info.Condition);
                }
                else if (!wantsGranted && conditionToken != ConditionManager.InvalidConditionToken)
                {
                    conditionToken = conditionManager.RevokeCondition(self, conditionToken);
                }
            }

            previousTerrain = currentTerrain;
        }
Ejemplo n.º 9
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);
        }
        /// <summary>
        /// Called by CaptureActor when the activity is ready to enter and capture the target.
        /// This method grants the capturing conditions on the captor and target and returns
        /// true if the captor is able to start entering or false if it needs to wait.
        /// </summary>
        public bool StartCapture(Actor self, Actor target, CaptureManager targetManager, out Captures captures)
        {
            captures = null;

            // Prevent a capture being restarted after it has been canceled during disposal
            if (self.WillDispose)
            {
                return(false);
            }

            if (target != currentTarget)
            {
                if (currentTarget != null)
                {
                    CancelCapture(self, currentTarget, currentTargetManager);
                }

                targetManager.currentCaptors.Add(self);
                currentTarget        = target;
                currentTargetManager = targetManager;
                currentTargetDelay   = 0;
            }
            else
            {
                currentTargetDelay += 1;
            }

            if (conditionManager != null && !string.IsNullOrEmpty(info.CapturingCondition) &&
                capturingToken == ConditionManager.InvalidConditionToken)
            {
                capturingToken = conditionManager.GrantCondition(self, info.CapturingCondition);
            }

            if (targetManager.conditionManager != null && !string.IsNullOrEmpty(targetManager.info.BeingCapturedCondition) &&
                targetManager.beingCapturedToken == ConditionManager.InvalidConditionToken)
            {
                targetManager.beingCapturedToken = targetManager.conditionManager.GrantCondition(target, targetManager.info.BeingCapturedCondition);
            }

            captures = enabledCaptures
                       .OrderBy(c => c.Info.CaptureDelay)
                       .FirstOrDefault(c => targetManager.CanBeTargetedBy(target, self, c));

            if (captures == null)
            {
                return(false);
            }

            if (progressWatchers.Any() || targetManager.progressWatchers.Any())
            {
                currentTargetTotal = captures.Info.CaptureDelay;
                if (move != null && captures.Info.ConsumedByCapture)
                {
                    var pos = target.GetTargetablePositions().PositionClosestTo(self.CenterPosition);
                    currentTargetTotal += move.EstimatedMoveDuration(self, self.CenterPosition, pos);
                }

                foreach (var w in progressWatchers)
                {
                    w.Update(self, self, target, currentTargetDelay, currentTargetTotal);
                }

                foreach (var w in targetManager.progressWatchers)
                {
                    w.Update(target, self, target, currentTargetDelay, currentTargetTotal);
                }
            }

            enteringCurrentTarget = currentTargetDelay >= captures.Info.CaptureDelay;
            return(enteringCurrentTarget);
        }
Ejemplo n.º 11
0
        public int GrantCondition(Actor self, object source, int duration = 0)
        {
            if (conditionManager == null || source == null || !CanGrantCondition(self, source))
            {
                return(ConditionManager.InvalidConditionToken);
            }

            var token     = conditionManager.GrantCondition(self, Info.Condition, duration);
            var permanent = permanentTokens.GetOrAdd(source);

            if (duration > 0)
            {
                var timed = timedTokens.GetOrAdd(source);

                // Remove expired tokens
                timed.RemoveWhere(t => t.Expires < self.World.WorldTick);

                // Check level caps
                if (Info.SourceCap > 0)
                {
                    if (permanent.Count + timed.Count >= Info.SourceCap)
                    {
                        var expire = timed.MinByOrDefault(t => t.Expires);
                        if (expire != null)
                        {
                            timed.Remove(expire);
                            if (conditionManager.TokenValid(self, expire.Token))
                            {
                                conditionManager.RevokeCondition(self, expire.Token);
                            }
                        }
                    }
                }

                if (Info.TotalCap > 0)
                {
                    var totalCount = permanentTokens.Values.SelectMany(t => t).Count() + timedTokens.Values.SelectMany(t => t).Count();
                    if (totalCount >= Info.TotalCap)
                    {
                        // Prefer tokens from the same source
                        var expire = timedTokens.SelectMany(t => t.Value.Select(tt => new Tuple <object, TimedToken>(t.Key, tt)))
                                     .MinByOrDefault(t => t.Item2.Expires);
                        if (expire != null)
                        {
                            if (conditionManager.TokenValid(self, expire.Item2.Token))
                            {
                                conditionManager.RevokeCondition(self, expire.Item2.Token);
                            }

                            timedTokens[expire.Item1].Remove(expire.Item2);
                        }
                    }
                }

                timed.Add(new TimedToken {
                    Expires = self.World.WorldTick + duration, Token = token
                });
            }
            else
            {
                permanent.Add(token);
            }

            return(token);
        }