Exemple #1
0
        /// <summary>
        /// Update this AI instance.
        /// </summary>
        /// <param name="wo">WorldObject controlled by this AI instance
        /// </param>
        /// <param name="lev">Currently active level</param>
        public override void Update(WorldObject wo, Level lev)
        {
            // If the player is dead then do not update and stop motion
            if (lev.Player.Dead)
            {
                wo.Stand();
                return;
            }

            // Turn to face the player
            if (wo.WorldX - lev.Player.WorldX < 0)
            {
                wo.FlipX();
            }
            else
            {
                wo.UnflipX();
            }

            // Update the timers
            CurFireTime += GameMain.SecondsPerFrame;
            CurDuckTime += GameMain.SecondsPerFrame;

            // If attacking then let it finish
            if (wo.State == WorldObject.AnimationState.Attack)
            {
                return;
            }

            // Distance to any incoming shots
            float shotDistX = 0.0F;
            float shotDistY = 0.0F;

            if (!CheckDuck(wo, lev, ref shotDistX, ref shotDistY))
            {
                // If not ducking a shot then check if an attack
                // should occur
                if (wo.State != WorldObject.AnimationState.Duck &&
                    Math.Abs(wo.WorldX - lev.Player.WorldX) <= MaxX &&
                    CurFireTime >= CurFireRate)
                {
                    CurFireTime = 0;
                    CurFireRate = (FireRateMin + GameMain.Random() *
                                   (FireRateMax - FireRateMin));
                    wo.Attack();
                }
                else if (wo.State != WorldObject.AnimationState.Duck)
                {
                    wo.Stand();
                }
            }
        }
Exemple #2
0
        /// <summary>
        /// Initialize this instance of the fly by AI.
        /// </summary>
        /// <param name="wo">WorldObject owning this AI</param>
        /// <param name="lev">Current level</param>
        public override void Init(WorldObject wo, Level lev)
        {
            // Determine random circling and attacking altitudes
            circleY = MaxY * .6F + .8F * MaxY * GameMain.Random();
            attackY = MinY * .8F + .4F * MinY * GameMain.Random();

            // Make sure the object is stopped
            wo.VelocityY = 0.0F;
            wo.VelocityX = 0.0F;

            // Make sure that the circling altitude is at least as high as
            // the attacking altitude.
            if (circleY < attackY)
            {
                circleY = attackY;
            }

            // Start at the circling altitude
            wo.WorldY = circleY;

            // Start with the walking animation
            wo.Walk();
        }
Exemple #3
0
 /// <summary>
 /// Initialize this instance of AI.
 /// </summary>
 /// <param name="wo">WorldObject controlled by this AI instance
 /// </param>
 /// <param name="lev">Currently active level</param>
 public override void Init(WorldObject wo, Level lev)
 {
     CurFireRate = (FireRateMin + GameMain.Random() *
                    (FireRateMax - FireRateMin));
 }
Exemple #4
0
 /// <summary>
 /// Determine if the world object should duck, assuming there is a
 /// need to.
 /// </summary>
 /// <param name="lev">Current level</param>
 /// <param name="wo">WorldObject to check</param>
 /// <returns>true if the object should duck, false otherwise</returns>
 protected bool ShouldDuck(Level lev, WorldObject wo)
 {
     return((CurDuckTime >= DuckRate &&
             GameMain.Random() < DuckChance) ||
            Math.Abs(wo.WorldX - lev.Player.WorldX) > MaxX);
 }
Exemple #5
0
        /// <summary>
        /// Update the player.
        /// </summary>
        /// <param name="gi">Input instance</param>
        /// <param name="lev">Current level</param>
        /// <returns>Always false</returns>
        public override bool Update(Input gi, Level lev)
        {
            // Assume there is no misfire this frame
            misfireValue = false;

            // If a shot is charging then update the time
            if (shotStarted)
            {
                shotTime += GameMain.SecondsPerFrame;
            }

            // If the player is not dead then update it
            if ((State & AnimationState.Dead) == 0)
            {
                // clear out the current direction but leave the animation
                // state
                State = prevState & AnimationState.AnimationMask;

                // If attacking then update the shot state
                if ((State & AnimationState.Attack) != 0)
                {
                    // If the shot is not already fired and the current
                    // animation cell is the one where the player shoots
                    // then launch a shot
                    if (!GetShotInfo()[0].Fired &&
                        Animation.CurCell == GetShotInfo()[0].ShootCell)
                    {
                        // Determine the direction of the shot
                        WorldDir dir = WorldDir.Left;
                        if ((DrawOptions & DrawOptions.BlitMirrorLeftRight)
                            == 0)
                        {
                            dir = WorldDir.Right;
                        }

                        // Velocity multipliers
                        float shotVelXMultiplier;
                        float shotVelYMultiplier;

                        // Determine the chance of a misfire based on the shot
                        // bar charge (min to max)
                        float misfireChance =
                            shotMisfireMax - CurrentShotBarPercent *
                            (shotMisfireMax - shotMisfireMin);

                        if (GameMain.Random() < misfireChance)
                        {
                            // A misfire occurred so set the flag and
                            // update the velocity multipliers accordingly
                            misfireValue       = true;
                            shotVelXMultiplier = shotMisfireVelocityXMin +
                                                 GameMain.Random() *
                                                 (shotVelocityXMax - shotVelocityXMin);
                            shotVelYMultiplier = shotMisfireVelocityYMin +
                                                 GameMain.Random() *
                                                 (shotVelocityYMax - shotVelocityYMin);
                        }
                        else
                        {
                            // No misfire, so the velocities are set
                            // relative to the bar charge percentage
                            shotVelXMultiplier = shotVelocityXMin +
                                                 CurrentShotBarPercent *
                                                 (shotVelocityXMax - shotVelocityXMin);
                            shotVelYMultiplier = shotVelocityYMax -
                                                 CurrentShotBarPercent *
                                                 (shotVelocityYMax - shotVelocityYMin);
                        }

                        // Fire a shot and reset the charge time
                        shotTime = 0.0F;
                        FireShot(lev, GetShotInfo()[0], dir,
                                 shotVelXMultiplier, shotVelYMultiplier);
                    }
                    else if (Animation.Done)
                    {
                        // If the shot animation is done then reset shot info
                        GetShotInfo()[0].Fired = false;
                        State    = AnimationState.Walk;
                        curCycle = WalkCycle;
                    }
                }
                else if (gi.KeyPressed((int)Keys.Down))
                {
                    // If pressing down then attempt to crawl.
                    State    = AnimationState.Duck;
                    curCycle = DuckCycle;
                }
                else if (gi.KeyPressed((int)Keys.Up))
                {
                    // If pressing up then stand up
                    State    = AnimationState.Walk;
                    curCycle = WalkCycle;
                }
                else if (!shotStarted && gi.KeyDown(
                             (int)gi.HardwareKeys[buttonMapValue[
                                                      (int)Buttons.FireShot]]))
                {
                    // If the fire button is pressed then start charging
                    // the bar
                    shotStarted = true;
                    shotTime    = 0.0F;
                }
                else if (shotStarted && gi.KeyReleased(
                             (int)gi.HardwareKeys[buttonMapValue[
                                                      (int)Buttons.FireShot]]))
                {
                    // If the fire button is released then start the shot
                    // animation
                    curCycle = AttackCycle;
                    State   |= AnimationState.Attack;
                    Animation.SetCycle(WalkCycle.StartCell,
                                       WalkCycle.EndCell, WalkCycle.AnimationRate);
                    Animation.StartOneShot(AttackCycle.StartCell,
                                           AttackCycle.EndCell, AttackCycle.AnimationRate);
                    shotStarted = false;
                }

                Debug.Assert(curCycle != null,
                             "Player.Update: Invalid animation sequence");

                Debug.Assert((State & AnimationState.AnimationMask) != 0,
                             "Player.Update: Invalid animation state determined");

                // Attempt to walk in the direction the user is pressing
                if (gi.KeyDown((int)Keys.Left))
                {
                    WalkLeft(lev);
                }
                else if (gi.KeyDown((int)Keys.Right))
                {
                    WalkRight(lev);
                }
                else
                {
                    Stop(lev);
                }

                Debug.Assert((State & AnimationState.DirectionMask) != 0 &&
                             (State & AnimationState.AnimationMask) != 0,
                             "Player.Update: Invalid movement state determined");
            }

            // Update the animation
            Animation.Update(GameMain.SecondsPerFrame);

            // Set the previous state
            prevState = State;

            // The player always returns false
            return(false);
        }
Exemple #6
0
        /// <summary>
        /// Update this AI instance.
        /// </summary>
        /// <param name="wo">WorldObject controlled by this AI instance
        /// </param>
        /// <param name="lev">Currently active level</param>
        public override void Update(WorldObject wo, Level lev)
        {
            // If the player is dead then do not update and stop motion
            if (lev.Player.Dead)
            {
                wo.Stand();
                wo.VelocityX = 0.0F;
                wo.VelocityY = 0.0F;
                return;
            }

            // Update the timers
            CurFireTime += GameMain.SecondsPerFrame;
            CurDuckTime += GameMain.SecondsPerFrame;

            // If attacking then let it finish
            if (wo.State == WorldObject.AnimationState.Attack)
            {
                return;
            }

            // Distance to any incoming shots
            float shotDistX = 0.0F;
            float shotDistY = 0.0F;

            // Cache some parameters
            Player p            = lev.Player;
            float  deltaPlayerX = p.WorldX - wo.WorldX;
            float  deltaPlayerY = p.WorldY - wo.WorldY;

            // Check if the world object should evade a shot
            if (!CheckDuck(wo, lev, ref shotDistX, ref shotDistY))
            {
                if (wo.State != WorldObject.AnimationState.Duck &&
                    Math.Abs(deltaPlayerX) <= MaxX &&
                    CurFireTime >= CurFireRate)
                {
                    // If the player is within range, the world object is not
                    // ducking, and it is time to fire then shoot at the
                    // player
                    CurFireTime = 0;
                    CurFireRate = (FireRateMin + GameMain.Random() *
                                   (FireRateMax - FireRateMin));
                    wo.Attack();
                    wo.VelocityX = 0.0F;
                }
                else if (wo.State != WorldObject.AnimationState.Duck)
                {
                    // Walk toward the player if not overlapping
                    // Overlapping can only occur when collisions are off
                    if (deltaPlayerX > 5.0F)
                    {
                        wo.Walk();
                        wo.VelocityX = VelocityX;
                        wo.FlipX();
                    }
                    else if (deltaPlayerX < -5.0F)
                    {
                        wo.Walk();
                        wo.VelocityX = -VelocityX;
                        wo.UnflipX();
                    }
                    else
                    {
                        wo.Stand();
                        wo.VelocityX = 0.0F;
                    }
                }
            }
            else
            {
                // Stop all movement if ducking
                wo.VelocityX = 0.0F;
            }
        }