/// <summary> /// Checks the collisions of each Entity which deals damage on impact. If it has collided with something containing a Health Component, /// an Attack is registered with the Damage System. /// </summary> public override void Process() { /// <summary> /// The System where Attacks are registered. /// </summary> DamageSystem damageSystem = World.GetSystem <DamageSystem>(); for (int i = Entities.Count - 1; i >= 0; i--) { CDamage damage; CCollision collision; CDamagesOnImpact dmgOnImp; collision = World.GetComponent <CCollision>(Entities[i]); /// <summary> /// Apply damage to the first Entity the Entity has collided with that still exists in /// the World and also has a Health Component. If none are found, the Arrow remains live. /// </summary> for (int j = 0; j < collision.Count; j++) { if (World.HasEntity(collision[j])) { if (World.EntityHasComponent(collision[j], typeof(CHealth))) { damage = World.GetComponent <CDamage>(Entities[i]); damageSystem.RegisterAttack(collision[j], damage.Damage); } } } /// <summary> /// If the Entity is set to die after impact, remove it from the World. /// </summary> dmgOnImp = World.GetComponent <CDamagesOnImpact>(Entities[i]); if (dmgOnImp.DiesAfterImpact) { World.RemoveEntity(Entities[i]); } } }
/// <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); } } } }