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); } }
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); } }
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()); } }
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); } }
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); } } }
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); } }
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; }
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); }
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); }