예제 #1
0
        public Missile(Game game, StaticObject target, StaticObject parent)
            : base(game, parent)
        {
            this.target = target;

            Vector3 velocity = this.shipData.speed * Matrix.CreateFromQuaternion(this.rotation).Forward;

            BBN_Game.Controller.GameController.particleController.MissileFiredExplosions(parent.Position, velocity, parent);
        }
예제 #2
0
 public int getEliminationPriority(StaticObject target)
 {
     if (target is playerObject)
         return PRIORITY_FOR_ELIMINATING_PLAYER;
     else if (target is Turret)
         return PRIORITY_FOR_ELIMINATING_TURRET;
     else if (target is Destroyer)
         return PRIORITY_FOR_ELIMINATING_DESTROYER;
     else if (target is Fighter)
         return PRIORITY_FOR_ELIMINATING_FIGHTER;
     else if (target is Base)
         return PRIORITY_FOR_ELIMINATING_BASE;
     else return 0;
 }
예제 #3
0
        protected float lifeSpan; // how long the bullet lasts

        #endregion Fields

        #region Constructors

        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="game">Game class</param>
        /// <param name="parent">The parent of the bullet</param>
        public Projectile(Game game, StaticObject parent)
            : base(game, Objects.Team.neutral, parent.Position + Vector3.Transform(new Vector3(0, -parent.getGreatestLength / 2, parent.getGreatestLength / 2), Matrix.CreateFromQuaternion(parent.rotation)))
        {
            this.Health = 10;
            numHudLines = 3;
            typeOfLine = PrimitiveType.LineStrip;

            Vector3 foreward = parent.Position + Vector3.Transform(new Vector3(0, 0, 10), Matrix.CreateFromQuaternion(parent.rotation));
            Vector3 PYR = MathEuler.AngleTo(foreward, parent.Position);

            rotation = Quaternion.CreateFromYawPitchRoll(PYR.Y, PYR.X, PYR.Z);

            this.shipData.speed = parent.ShipMovementInfo.speed;

            this.parent = parent;
        }
예제 #4
0
 /// <summary>
 /// Constructor
 /// </summary>
 /// <param name="game">Game class</param>
 /// <param name="parent">The parent of the bullet</param>
 /// <param name="target">The target for the object</param>
 public Bullet(Game game, StaticObject target, StaticObject parent)
     : base(game, parent)
 {
     this.target = target;
 }
예제 #5
0
        /// <summary>
        /// Checks if a particular dodge is valid
        /// </summary>
        private bool isDodgeValid(DynamicObject callingAI,float dodgeAngle,int dodgeAngleMultiplierYaw,int dodgeAngleMultiplierPitch,PathInformation pathInfo, StaticObject closestObstruction,float dodgeDistance, ref Vector3 dodgeWp)
        {
            bool bFlag = false;
            //Define a conal area around the current path to choose another path from
            Quaternion qRot = Quaternion.CreateFromYawPitchRoll(dodgeAngle * dodgeAngleMultiplierYaw, dodgeAngle * dodgeAngleMultiplierPitch, 0);
            Vector3 choiceVector = Vector3.Normalize(
                Vector3.Transform(pathInfo.currentWaypoint.Position - callingAI.Position,
                    Matrix.CreateFromQuaternion(qRot)));
            dodgeWp = callingAI.Position + choiceVector * dodgeDistance;
            if ((dodgeWp - closestObstruction.Position).Length() > dodgeDistance)
            {
                foreach (GridObjectInterface o in spatialGrid.checkNeighbouringBlocks(dodgeWp))
                {
                    if (o != callingAI)
                    {

                        if (o is StaticObject)
                        {
                            if ((o.Position - dodgeWp).Length() > (o.getBoundingSphere().Radius + callingAI.getBoundingSphere().Radius * (DODGE_DISTANCE_MULTIPLIER)))
                                bFlag = true;
                        }
                        if (o is DynamicObject)
                        {
                            if (isObjectRegistered(o as DynamicObject))
                            {
                                Node otherObjectsWaypoint = objectPaths[o as DynamicObject].currentWaypoint;
                                if (otherObjectsWaypoint != null)
                                {
                                    if ((otherObjectsWaypoint.Position - dodgeWp).Length() < (o.getBoundingSphere().Radius + callingAI.getBoundingSphere().Radius * (DODGE_DISTANCE_MULTIPLIER)))
                                        bFlag = false;
                                }
                            }
                        }
                        if (!spatialGrid.isInGrid(new Node(dodgeWp,-1)))
                            bFlag = false;
                    }
                }
            }
            return bFlag;
        }
예제 #6
0
        /// <summary>
        /// Method to set the path of an ai unit in order to dodge an object
        /// </summary>
        /// <param name="callingAI">ai to perform dodge</param>
        /// <param name="closestObstruction">closest obstruction</param>
        private void dodgeObject(DynamicObject callingAI, StaticObject closestObstruction)
        {
            if (!this.isObjectRegistered(callingAI)) return;
            PathInformation pathInfo = objectPaths[callingAI];
            if (pathInfo.currentWaypoint == null) return;
            if (!dodgeInactiveCountDown.Keys.Contains(callingAI))
                dodgeInactiveCountDown.Add(callingAI, RETAIN_DODGE_PATH_TICKS);
            else
                return;
            Vector3 dodgeWp = new Vector3();
            bool bFlag = false;

            // Set the new path:
            float dodgeDistance = (callingAI.getBoundingSphere().Radius + closestObstruction.getBoundingSphere().Radius) * DODGE_DISTANCE_MULTIPLIER;
            float distanceToObject = (callingAI.Position - closestObstruction.Position).Length();
            float distanceToCurrentWp = (callingAI.Position - pathInfo.currentWaypoint.Position).Length();
            float dodgeAngle = (float)Math.Abs(Math.Atan2(distanceToObject, dodgeDistance));
            for (int i = (int)Math.Ceiling(dodgeAngle); i * dodgeAngle < Math.PI; ++i)
            {
                for (int j = (int)Math.Ceiling(dodgeAngle); j * dodgeAngle < Math.PI; ++j)
                {
                    if (isDodgeValid(callingAI, dodgeAngle, i, j, pathInfo, closestObstruction, dodgeDistance, ref dodgeWp))
                    {
                        bFlag = true;
                        break;
                    }
                    if (isDodgeValid(callingAI, -dodgeAngle, i, j, pathInfo, closestObstruction, dodgeDistance, ref dodgeWp))
                    {
                        bFlag = true;
                        break;
                    }
                }
                if (bFlag)
                    break;
            }
            List<Node> path = pathInfo.remainingPath;
            if (path.Count > 0)
                path.Remove(path.Last());
            path.Add(new Node(dodgeWp, -1));
            pathInfo.remainingPath = path;
        }
예제 #7
0
        /// <summary>
        /// Performs a dogfight move against the opponent
        /// </summary>
        /// <param name="ti">Team on which the ai is registered</param>
        /// <param name="ai">Character to perform move</param>
        /// <param name="target">Opponent of the ai</param>
        public void doDogfightMove(TeamInformation ti, DynamicObject ai, StaticObject target)
        {
            if (!this.isObjectRegistered(ai)) return;
            float radiusToGoBehindTarget = (target.getBoundingSphere().Radius + ai.getBoundingSphere().Radius) * RADIUS_MULTIPLIER_TO_GO_BEHIND_TARGET;
            Vector3 wpPosition = target.Position + Vector3.Normalize(Matrix.CreateFromQuaternion(target.rotation).Forward) * radiusToGoBehindTarget;
            Vector3 wpDPosition = target.Position + Vector3.Normalize(Matrix.CreateFromQuaternion(target.rotation).Up) * radiusToGoBehindTarget / RADIUS_FACTOR_TO_GO_ABOVE_TARGET;
            if (Vector3.Dot(Vector3.Normalize(wpPosition - target.Position), Vector3.Normalize(ai.Position - target.Position)) < DOT_ANGLE_TO_STOP_DOGFIGHT_MOVE ||
                (ai.Position - target.Position).Length() > CHASE_WHEN_FURTHER)
            {
                PathInformation fighterPath = objectPaths[ai];
                List<Node> waypointList = fighterPath.remainingPath;

                //we clear the waypoint list and add new waypoints:
                if (waypointList.Count > 0)
                {
                    bool shouldAddTopWaypt = (Vector3.Dot(Vector3.Normalize(Matrix.CreateFromQuaternion(target.rotation).Forward), Vector3.Normalize(target.Position - ai.Position)) > 0);
                    if ((wpPosition - waypointList.ElementAt(0).Position).Length() > TARGET_WP_BUFFER || shouldAddTopWaypt)
                    {
                        waypointList.Clear();
                        if (shouldAddTopWaypt)
                            waypointList.Insert(0, new Node(wpDPosition, -1));
                        waypointList.Insert(0, new Node(wpPosition, -1));
                    }
                }
                else
                {
                    if (Vector3.Dot(Vector3.Normalize(Matrix.CreateFromQuaternion(target.rotation).Forward), Vector3.Normalize(target.Position - ai.Position)) > 0)
                        waypointList.Insert(0, new Node(wpDPosition, -1));
                    waypointList.Insert(0, new Node(wpPosition, -1));
                }
                fighterPath.remainingPath = waypointList;
            }
            else //stop navigation (we are behind the target so we can start shooting it)
                getPath(ai).Clear();
        }
예제 #8
0
        /// <summary>
        /// override for the update method to call on the camera update methods.
        /// </summary>
        /// <param name="gt">Game time variable</param>
        public override void Update(GameTime gt)
        {
            // todo add the if statement on the enum for cockpit View
            if (cameraType.Equals(CurrentCam.Chase))
                chaseCamera.update(gt, Position, Matrix.CreateFromQuaternion(rotation));
            else
                fpCamera.update(gt, Position, Matrix.CreateFromQuaternion(rotation), this.getGreatestLength);

            if (target != null)
            {
                if (target is Turret)
                {
                    if (((Turret)target).Repairing)
                        target = null;
                }
                else
                {
                    if (target.getHealth <= 0)
                        target = null;
                }
            }

            if (target == null)
            {
                getNewTarget();
            }

            base.Update(gt);
        }
예제 #9
0
        /// <summary>
        /// This tries to get 
        /// </summary>
        public void getNewTarget()
        {
            List<Grid.GridObjectInterface> list = Controller.GameController.getTargets(this);

            if (list.Count > 0)
            {
                for (int i = 0; i < list.Count; ++i)
                {
                    if (list.ElementAt(i) is StaticObject)
                    {
                        StaticObject obj = (StaticObject)list.ElementAt(i);

                        if (obj.Team != Team.neutral)
                        {
                            if (obj.Team != this.Team)
                            {
                                if (!previousList.Contains(obj))
                                {
                                    previousList.Add(obj);
                                    target = obj;
                                    return;
                                }
                            }
                        }
                    }

                }
                previousList.Clear();
            }
        }
예제 #10
0
        public void registerHitOnBaseOrTurretOrFighters(StaticObject victim, StaticObject shooter)
        {
            TeamInformation tiV = getTeam(victim);
            TeamInformation tiS = getTeam(shooter);
            if (tiV == null || tiS == null) return;

            if (tiV != tiS)
                if (!isTargetMarkedForElimination(shooter, tiV))
                    if (!isTargetAlreadyBattledByFighters(tiV, shooter))
                    {
                        if (shooter is playerObject)
                        {
                            if (victim is Fighter || victim is Base)
                                tiV.scrambleQueue.Add(new KeyValuePair<int, StaticObject>(PRIORITY_FOR_ELIMINATING_PLAYER, shooter));
                            else if (victim is Turret)
                            {
                                float distanceFromTurretToHomeBase = (victim.Position - tiV.teamBase.Position).Length();
                                if (distanceFromTurretToHomeBase <= DISTANCE_WHEN_TURRET_IS_CLOSE_TO_BASE)
                                    tiV.scrambleQueue.Add(new KeyValuePair<int, StaticObject>(PRIORITY_FOR_ELIMINATING_PLAYER, shooter));
                            }
                        }
                        else if (shooter is Destroyer)
                        {
                            if (victim is Fighter || victim is Base)
                                tiV.scrambleQueue.Add(new KeyValuePair<int, StaticObject>(PRIORITY_FOR_ELIMINATING_DESTROYER, shooter));
                            else if (victim is Turret)
                            {
                                float distanceFromTurretToHomeBase = (victim.Position - tiV.teamBase.Position).Length();
                                if (distanceFromTurretToHomeBase <= DISTANCE_WHEN_TURRET_IS_CLOSE_TO_BASE)
                                    tiV.scrambleQueue.Add(new KeyValuePair<int, StaticObject>(PRIORITY_FOR_ELIMINATING_DESTROYER, shooter));
                            }
                        }
                    }
        }
예제 #11
0
 private int topupAssignedFightersToBattle(TeamInformation ti, StaticObject enemy)
 {
     Dictionary<StaticObject, int> numEngagedFightersPerEnemy = countFightersEngagedOnEnemy(ti);
             int numToScramble = 0;
             if (enemy is playerObject)
                 numToScramble = FIGHTERS_TO_SCRAMBLE_FOR_PLAYER;
             else if (enemy is Destroyer)
                 numToScramble = FIGHTERS_TO_SCRAMBLE_FOR_DESTROYER;
             //if the enemy is already being faught then just top up the fighters when they die off
             if (numEngagedFightersPerEnemy.Keys.Contains(enemy))
                 numToScramble -= numEngagedFightersPerEnemy[enemy];
             //now get the healthiest fighters and scramble them:
             if (numToScramble > 0)
             {
                 PowerDataStructures.PriorityQueue<float, Fighter> healthiestInactiveFighters = getHealthiestFighters(ti, FighterState.FS_IDLE);
                 int numIdleAvailable = healthiestInactiveFighters.Count;
                 //when we have enough fighters available just scramble them
                 if (numIdleAvailable >= numToScramble)
                 {
                     for (int i = 0; i < numToScramble; ++i)
                         ti.fighterBattleList.Add(healthiestInactiveFighters.DequeueValue(), enemy);
                     return numIdleAvailable;
                 }
                 //when we have too few fighters reassign them to more important targets
                 else
                 {
                     //add what we do have:
                     for (int i = 0; i < numIdleAvailable; ++i)
                         ti.fighterBattleList.Add(healthiestInactiveFighters.DequeueValue(), enemy);
                     //now find more fighters and reassign:
                     PowerDataStructures.PriorityQueue<float, Fighter> healthiestActiveFighters = getHealthiestFighters(ti, FighterState.FS_ENGAGED);
                     int numReassigned = 0;
                     foreach (KeyValuePair<float,Fighter> fighter in healthiestActiveFighters)
                         if (getEliminationPriority(ti.fighterBattleList[fighter.Value]) < getEliminationPriority(enemy))
                         {
                             ti.fighterBattleList.Remove(fighter.Value);
                             ti.fighterBattleList.Add(fighter.Value, enemy);
                             if (numIdleAvailable+(++numReassigned) == numToScramble)
                                 break;
                         }
                     return numReassigned+numIdleAvailable;
                 }
             }
             else return 0;
 }
예제 #12
0
 private bool isTargetMarkedForElimination(StaticObject target, TeamInformation ti)
 {
     foreach (System.Collections.Generic.KeyValuePair<int, BBN_Game.Objects.StaticObject> pair in ti.scrambleQueue)
         if (pair.Value == target)
             return true;
     return false;
 }
예제 #13
0
 private bool isTargetAlreadyBattledByFighters(TeamInformation ti, StaticObject target)
 {
     return ti.fighterBattleList.Values.Contains(target);
 }
예제 #14
0
 private TeamInformation getTeam(StaticObject ai)
 {
     foreach (TeamInformation ti in infoOnTeams)
         if (ai.Team == ti.teamId)
             return ti;
     return null;
 }
예제 #15
0
 /// <summary>
 /// Constructor
 /// </summary>
 /// <param name="game">Game class</param>
 /// <param name="parent">The parent of the bullet</param>
 /// <param name="target">The target for the object</param>
 public Bullet(Game game, StaticObject target, StaticObject parent)
     : base(game, parent)
 {
     this.target = target;
 }