/// <summary>
        /// Evaluates the state of each Explosion Man. Two key events occur with Explosion Men:
        ///     -When the Spawn Animation finishes, the explosion is created.
        ///     -When the Explosion Animation finishes, the Entity is removed.
        /// This System checks the state and animation of each Explosion Man.
        /// </summary>
        public override void Process()
        {
            CExplosionMan explosion;
            CAnimation    anim;
            CPosition     pos;

            for (int i = Entities.Count - 1; i >= 0; i--)
            {
                anim = World.GetComponent <CAnimation>(Entities[i]);

                /// <summary>
                /// If one of the two key events are happening.
                /// </summary>
                if (SwinGame.AnimationEnded(anim.Anim))
                {
                    explosion = World.GetComponent <CExplosionMan>(Entities[i]);

                    /// <summary>
                    /// If not ready to explode, the Spawn animation has just finished.
                    /// Therefore, create the explosion.
                    /// </summary>
                    if (!explosion.ReadyToExplode)
                    {
                        explosion.ReadyToExplode = true;
                        pos = World.GetComponent <CPosition>(Entities[i]);

                        /// <summary>
                        /// Update size details as the Entity is now an Explosion.
                        /// </summary>
                        pos.Width  = EntityFactory.EXPLOSION_SIZE;
                        pos.Height = EntityFactory.EXPLOSION_SIZE;

                        /// <summary>
                        /// Adjust position details so explosion is in centre of the cell.
                        /// </summary>
                        CollisionCheckSystem collisions = World.GetSystem <CollisionCheckSystem>();
                        Point2D cellPos = collisions.CentreOfCell(explosion.TargetCell);
                        pos.X = cellPos.X - (pos.Width / 2);
                        pos.Y = cellPos.Y - (pos.Height / 2);

                        /// <summary>
                        /// Create explosion animation.
                        /// </summary>
                        anim.Img = SwinGame.BitmapNamed("Explosion");
                        SwinGame.AssignAnimation(anim.Anim, "Explode", anim.AnimScript);

                        /// <summary>
                        /// Add new components to the Entity.
                        /// </summary>
                        World.AddComponent(Entities[i], new CDamagesOnImpact(false));
                        World.AddComponent(Entities[i], new CDamage(EntityFactory.EXPLOSION_DAMAGE));
                        World.AddComponent(Entities[i], new CCollidable());
                    }
                    else //If ready to explode, the Explode animation has just finished. Therefore, remove the Entity.
                    {
                        World.RemoveEntity(Entities[i]);
                    }
                }
            }
        }
        /// <summary>
        /// Checks the Game Time against the last time the AI attacked. If the time difference is greater
        /// than the attack cooldown of the AI, then the AI is ready to attack and their Attack animation begins.
        /// </summary>
        /// <param name="entID">Ent identifier.</param>
        protected void CheckCooldown(ulong entID)
        {
            CAI AI = World.GetComponent <CAI>(entID);

            AI.AttackIsReady = World.GameTime - AI.LastAttackTime >= AI.Cooldown;

            if (AI.AttackIsReady)
            {
                /// <summary>
                /// Begin the Attack animation for the AI
                /// </summary>
                CAnimation anim = World.GetComponent <CAnimation>(entID);
                SwinGame.AssignAnimation(anim.Anim, "Attack", anim.AnimScript);
            }
        }
        public override void Process()
        {
            CAI        AI;
            CPosition  pos;
            CAnimation anim;

            /// <summary>
            /// For each Enemy AI Entity.
            /// </summary>
            for (int i = 0; i < Entities.Count; i++)
            {
                AI  = World.GetComponent <CAI>(Entities[i]);
                pos = World.GetComponent <CPosition>(Entities[i]);

                if (!AI.IsInRange)
                {
                    CheckRange(Entities[i], AI, pos);

                    /// If the AI is now in range, stop moving and begin attacking.
                    if (AI.IsInRange)
                    {
                        World.RemoveComponent <CVelocity>(Entities[i]);
                    }
                }
                else if (!AI.AttackIsReady)
                {
                    CheckCooldown(Entities[i]);
                }
                else
                {
                    anim = World.GetComponent <CAnimation>(Entities[i]);

                    /// <summary>
                    /// Attack will be carried out when the Attack animation has ended.
                    /// </summary>
                    if (SwinGame.AnimationEnded(anim.Anim))
                    {
                        Attack <CEnemyTeam>(Entities[i]);

                        ///If the Entity has attacked, stand still during the cooldown period.
                        SwinGame.AssignAnimation(anim.Anim, "Still", anim.AnimScript);
                    }
                }
            }
        }
Esempio n. 4
0
        /// <summary>
        /// Represents the decision making process for Player AI. AI operates with the following procedure:
        /// - If I don't have a target, get a target.
        /// - If I have a target, check if I'm in range to attack.
        /// - If I'm in range to attack, check if I can attack.
        /// - If I'm in range to attack, attack.
        /// </summary>
        public override void Process()
        {
            CAI        playerAI;
            CPosition  playerPos;
            CAnimation playerAnim;

            /// <summary>
            /// Populates the dictionary of Enemy positions only once per frame.
            /// Each AI uses these positions to evaluate their targets.
            /// </summary>
            GetEnemyPositions();

            /// <summary>
            /// For each Player Entity.
            /// </summary>
            for (int i = 0; i < Entities.Count; i++)
            {
                playerAI  = World.GetComponent <CAI>(Entities[i]);
                playerPos = World.GetComponent <CPosition>(Entities[i]);

                /// <summary>
                /// If target died, get a new target and stand still.
                /// </summary>
                if (!World.HasEntity(playerAI.TargetID))
                {
                    playerAI.HasTarget = false;

                    //playerAnim = World.GetComponent<CAnimation>(Entities[i]);
                    //SwinGame.AssignAnimation(playerAnim.Anim, "Still", playerAnim.AnimScript);
                }

                if (!playerAI.HasTarget)
                {
                    GetClosestTarget(playerAI, playerPos);
                }
                else if (!playerAI.IsInRange)
                {
                    CheckRange(Entities[i], playerAI, playerPos);
                }
                else if (!playerAI.AttackIsReady)
                {
                    CheckCooldown(Entities[i]);
                }
                else
                {
                    /// <summary>
                    /// If ready to attack, start the attack animation. The attack will be carried out
                    /// when the attack animation has finished.
                    /// </summary>
                    playerAnim = World.GetComponent <CAnimation>(Entities[i]);

                    if (SwinGame.AnimationEnded(playerAnim.Anim)) //Attack at end of Attack animation
                    {
                        Attack <CPlayerTeam>(Entities[i]);

                        //If the Entity has attacked, stand still during the cooldown period.
                        SwinGame.AssignAnimation(playerAnim.Anim, "Still", playerAnim.AnimScript);
                    }
                }
            }
        }