protected virtual Activity InnerTick(Actor self, AttackBase attack) { if (IsCanceled) return NextActivity; var type = Target.Type; if (!Target.IsValidFor(self) || type == TargetType.FrozenActor) return NextActivity; // Drop the target if it moves under the shroud / fog. // HACK: This would otherwise break targeting frozen actors // The problem is that Shroud.IsTargetable returns false (as it should) for // frozen actors, but we do want to explicitly target the underlying actor here. if (type == TargetType.Actor && !Target.Actor.HasTrait<FrozenUnderFog>() && !self.Owner.Shroud.IsTargetable(Target.Actor)) return NextActivity; // Try to move within range if (move != null && (!Target.IsInRange(self.CenterPosition, maxRange) || Target.IsInRange(self.CenterPosition, minRange))) return Util.SequenceActivities(move.MoveWithinRange(Target, minRange, maxRange), this); var desiredFacing = Util.GetFacing(Target.CenterPosition - self.CenterPosition, 0); if (facing.Facing != desiredFacing) return Util.SequenceActivities(new Turn(desiredFacing), this); attack.DoAttack(self, Target); return this; }
IActivity InnerTick( Actor self, AttackBase attack ) { if (IsCanceled) return NextActivity; var facing = self.Trait<IFacing>(); if (!Target.IsValid) return NextActivity; var targetCell = Util.CellContaining(Target.CenterLocation); if ((targetCell - self.Location).LengthSquared >= Range * Range) return Util.SequenceActivities( new Move( Target, Range ), this ); var desiredFacing = Util.GetFacing((targetCell - self.Location).ToFloat2(), 0); var renderUnit = self.TraitOrDefault<RenderUnit>(); var numDirs = (renderUnit != null) ? renderUnit.anim.CurrentSequence.Facings : 8; if (Util.QuantizeFacing(facing.Facing, numDirs) != Util.QuantizeFacing(desiredFacing, numDirs)) { return Util.SequenceActivities( new Turn( desiredFacing ), this ); } attack.target = Target; attack.DoAttack(self); return this; }
IActivity InnerTick( Actor self, AttackBase attack ) { if (IsCanceled) return NextActivity; var facing = self.Trait<IFacing>(); if (!Target.IsValid) return NextActivity; if (!Combat.IsInRange(self.CenterLocation, Range, Target)) return (AllowMovement) ? Util.SequenceActivities(self.Trait<Mobile>().MoveWithinRange(Target, Range), this) : NextActivity; var desiredFacing = Util.GetFacing(Target.CenterLocation - self.CenterLocation, 0); if (facing.Facing != desiredFacing) return Util.SequenceActivities( new Turn( desiredFacing ), this ); attack.DoAttack(self, Target); return this; }
protected virtual Activity InnerTick( Actor self, AttackBase attack ) { if (IsCanceled) return NextActivity; var facing = self.Trait<IFacing>(); if (!Target.IsValid) return NextActivity; if (targetable != null && !targetable.TargetableBy(Target.Actor, self)) return NextActivity; if (!Combat.IsInRange(self.CenterLocation, Range, Target)) { if (--nextPathTime > 0) return this; nextPathTime = self.World.SharedRandom.Next(delayBetweenPathingAttempts - delaySpread, delayBetweenPathingAttempts + delaySpread); return (AllowMovement) ? Util.SequenceActivities(self.Trait<Mobile>().MoveWithinRange(Target, Range), this) : NextActivity; } var desiredFacing = Util.GetFacing(Target.CenterLocation - self.CenterLocation, 0); if (facing.Facing != desiredFacing) return Util.SequenceActivities( new Turn( desiredFacing ), this ); attack.DoAttack(self, Target); return this; }
protected virtual Activity InnerTick(Actor self, AttackBase attack) { if (IsCanceled) return NextActivity; var type = Target.Type; if (!Target.IsValidFor(self) || type == TargetType.FrozenActor) return NextActivity; // TODO: This is horrible, and probably wrong. Work out what it is trying to solve, then redo it properly. if (type == TargetType.Actor && !self.Owner.HasFogVisibility() && Target.Actor.HasTrait<Mobile>() && !self.Owner.Shroud.IsTargetable(Target.Actor)) return NextActivity; if (!Target.IsInRange(self.CenterPosition, Range)) { if (--nextPathTime > 0) return this; nextPathTime = self.World.SharedRandom.Next(delayBetweenPathingAttempts - delaySpread, delayBetweenPathingAttempts + delaySpread); return (AllowMovement) ? Util.SequenceActivities(self.Trait<IMove>().MoveWithinRange(Target, Range), this) : NextActivity; } var desiredFacing = Util.GetFacing(Target.CenterPosition - self.CenterPosition, 0); var facing = self.Trait<IFacing>(); if (facing.Facing != desiredFacing) return Util.SequenceActivities(new Turn(desiredFacing), this); attack.DoAttack(self, Target); return this; }
protected virtual Activity InnerTick(Actor self, AttackBase attack) { if (IsCanceled) return NextActivity; var type = Target.Type; if (!Target.IsValidFor(self) || type == TargetType.FrozenActor) return NextActivity; if (attack.Info.AttackRequiresEnteringCell && !positionable.CanEnterCell(Target.Actor.Location, null, false)) return NextActivity; // Drop the target if it moves under the shroud / fog. // HACK: This would otherwise break targeting frozen actors // The problem is that Shroud.IsTargetable returns false (as it should) for // frozen actors, but we do want to explicitly target the underlying actor here. if (!attack.Info.IgnoresVisibility && type == TargetType.Actor && !Target.Actor.Info.HasTraitInfo<FrozenUnderFogInfo>() && !self.Owner.CanTargetActor(Target.Actor)) return NextActivity; // Drop the target once none of the weapons are effective against it var armaments = attack.ChooseArmamentsForTarget(Target, forceAttack); if (!armaments.Any()) return NextActivity; // Update ranges minRange = armaments.Max(a => a.Weapon.MinRange); maxRange = armaments.Min(a => a.MaxRange()); // Try to move within range if (move != null && (!Target.IsInRange(self.CenterPosition, maxRange) || Target.IsInRange(self.CenterPosition, minRange))) return Util.SequenceActivities(move.MoveWithinRange(Target, minRange, maxRange), this); var desiredFacing = Util.GetFacing(Target.CenterPosition - self.CenterPosition, 0); if (facing.Facing != desiredFacing) return Util.SequenceActivities(new Turn(self, desiredFacing), this); attack.DoAttack(self, Target, armaments); return this; }