コード例 #1
0
        /// <summary>
        /// Builds a list of targets which would be hit by a line attack performed by a siege cannon.
        /// </summary>
        /// <param name="instigator">The player firing the cannon.</param>
        /// <returns>The farthest target from the siege weapon which would be struck by the attack, for use as the target of the ability.</returns>
        public Unit BuildTargetList(Unit instigator)
        {
            CurrentTargetList.Clear();

            Unit initialTarget = _weapon.CbtInterface.GetTarget(TargetTypes.TARGETTYPES_TARGET_ENEMY);

            Unit bestTarget = initialTarget;
            int  bestDist   = _weapon.GetDistanceToObject(initialTarget);

            CurrentTargetList.Add(initialTarget);

            Vector3 unitDir = new Vector3(initialTarget.WorldPosition.X - _weapon.WorldPosition.X,
                                          initialTarget.WorldPosition.Y - _weapon.WorldPosition.Y,
                                          initialTarget.WorldPosition.Z - _weapon.WorldPosition.Z);

            unitDir.Normalize();

            Vector3 toTarget   = new Vector3();
            Vector3 projection = new Vector3();

            foreach (Object obj in _weapon.ObjectsInRange)
            {
                Unit unit = obj as Unit;

                if (unit == null || unit == initialTarget || unit.Realm == instigator.Realm || !_weapon.IsObjectInFront(unit, 45) || !CombatInterface.CanAttack(instigator, unit))
                {
                    continue;
                }

                // Determine whether this unit is within 5ft on either side of the cannon's attack.

                // Unit vector in direction of cannon's view
                projection.X = unitDir.X;
                projection.Y = unitDir.Y;
                projection.Z = unitDir.Z;

                toTarget.X = unit.WorldPosition.X - _weapon.WorldPosition.X;
                toTarget.Y = unit.WorldPosition.Y - _weapon.WorldPosition.Y;
                toTarget.Z = unit.WorldPosition.Z - _weapon.WorldPosition.Z;

                // Vector projection ((a dot ^b) ^b)
                projection.Multiply(Vector3.DotProduct3D(toTarget, unitDir));

                // Vector rejection (a - (a dot ^b) ^b)
                toTarget.X -= projection.X;
                toTarget.Y -= projection.Y;
                toTarget.Z -= projection.Z;

                if (toTarget.MagnitudeSquare < 60 * 60 && _weapon.LOSHit(unit)) // 5ft either side
                {
                    CurrentTargetList.Add(unit);

                    // Select the target furthest away as the target of the ability, for the projectile effect to look best
                    if (!_weapon.IsWithinRadiusFeet(unit, bestDist))
                    {
                        bestTarget = unit;
                        bestDist   = _weapon.GetDistanceToObject(bestTarget);
                    }
                }
            }

            return(bestTarget);
        }