protected virtual void DoAttack(Actor self, AttackFrontal attack, IEnumerable <Armament> armaments) { if (!attack.IsTraitPaused) { foreach (var a in armaments) { a.CheckFire(self, facing, target); } } }
protected override void DoAttack(Actor self, AttackFrontal attack, IEnumerable <Armament> armaments) { attack.DoAttack(self, target); }
protected virtual AttackStatus TickAttack(Actor self, AttackFrontal attack) { if (!target.IsValidFor(self)) { return(AttackStatus.UnableToAttack); } if (attack.Info.AttackRequiresEnteringCell && !positionable.CanEnterCell(target.Actor.Location, null, false)) { return(AttackStatus.UnableToAttack); } if (!attack.Info.TargetFrozenActors && !forceAttack && target.Type == TargetType.FrozenActor) { // Try to move within range, drop the target otherwise if (move == null) { return(AttackStatus.UnableToAttack); } var rs = revealsShroud .Where(Exts.IsTraitEnabled) .MaxByOrDefault(s => s.Range); // Default to 2 cells if there are no active traits var sightRange = rs != null ? rs.Range : WDist.FromCells(2); attackStatus |= AttackStatus.NeedsToMove; QueueChild(self, move.MoveWithinRange(target, sightRange, target.CenterPosition, Color.Red), true); return(AttackStatus.NeedsToMove); } // Drop the target once none of the weapons are effective against it var armaments = attack.ChooseArmamentsForTarget(target, forceAttack).ToList(); if (armaments.Count == 0) { return(AttackStatus.UnableToAttack); } // Update ranges minRange = armaments.Max(a => a.Weapon.MinRange); maxRange = armaments.Min(a => a.MaxRange()); var pos = self.CenterPosition; var mobile = move as Mobile; if (!target.IsInRange(pos, maxRange) || (minRange.Length != 0 && target.IsInRange(pos, minRange)) || (mobile != null && !mobile.CanInteractWithGroundLayer(self))) { // Try to move within range, drop the target otherwise if (move == null) { return(AttackStatus.UnableToAttack); } attackStatus |= AttackStatus.NeedsToMove; var checkTarget = useLastVisibleTarget ? lastVisibleTarget : target; QueueChild(self, move.MoveWithinRange(target, minRange, maxRange, checkTarget.CenterPosition, Color.Red), true); return(AttackStatus.NeedsToMove); } if (!attack.TargetInFiringArc(self, target, attack.Info.FacingTolerance)) { var desiredFacing = (attack.GetTargetPosition(pos, target) - pos).Yaw.Facing; attackStatus |= AttackStatus.NeedsToTurn; QueueChild(self, new Turn(self, desiredFacing), true); return(AttackStatus.NeedsToTurn); } attackStatus |= AttackStatus.Attacking; DoAttack(self, attack, armaments); return(AttackStatus.Attacking); }