/// <summary> /// Reduces Health of the Enemy, makes him rotate to the Player and registers his Position /// </summary> /// <param name="Damage">Damage that the Enemy takes</param> /// <param name="Direction">Direction of the impacted Projectile</param> public void ReduceHealth(uint Damage, Vector2f Direction) { iHealth -= (int)Damage; vRegisteredPlayerPosition = MainMap.GetVirtualCharacterPosition(); RotateEnemy(ref fAngle, Direction + MainMap.GetStartCharacterPosition() + new Vector2f(25, 25)); sEntity.Rotation = fAngle; }
/// <summary> /// Alerts other Enemys in a determined Radius if Player is detected /// </summary> protected void Alert() { List <Enemy> lEnemy = MainMap.GetEnemies(); for (int x = 0; x < lEnemy.Count; x++) { if (lEnemy[x].uID == uID || Utilities.DistanceBetweenVectors(lEnemy[x].GetVirtualPosition(), vEntityPosition) > iDistanceDetection / 2 || lEnemy[x].vRegisteredPlayerPosition != new Vector2f()) { continue; } lEnemy[x].vRegisteredPlayerPosition = MainMap.GetVirtualCharacterPosition(); } }
// DECLARING METHODS: DETECTION /// <summary> /// Updates Detect Logic of the Archer. /// If it detects the Player, the Archer shoots Projectiles. /// If it is hit or has detected the Player previously it moves to the registered Position. /// </summary> protected void DetectLogic() { if (DetectPlayer()) { vRegisteredPlayerPosition = MainMap.GetVirtualCharacterPosition() + new Vector2f(25, 25); RotateEnemy(ref fAngle, MainMap.GetStartCharacterPosition() + new Vector2f(25, 25)); sEntity.Rotation = fAngle; cSuspecting.Restart(); Closed = new List <Node>(); Path = new List <Node>(); Move(); Alert(); if (tShooting.AsMilliseconds() >= 1200) { Shoot(); cShooting.Restart(); } if (bSuspecting) { bSuspecting = false; } } else if (Utilities.MakePositive(vRegisteredPlayerPosition.X) > 0) { if (!bSuspecting) { cSuspecting.Restart(); bSuspecting = true; PathFinder(vEntityPosition, vRegisteredPlayerPosition); } tSuspecting = cSuspecting.ElapsedTime; if (tSuspecting.AsMilliseconds() <= 100000) { PathfinderLogic(); } else { vRegisteredPlayerPosition = new Vector2f(); } } }
// DECLARING METHODS: PLAYER-DETECTION RELATED /// <summary> /// Returns true if the Player is in the Radius and Angle of Sight of the Enemy and isn't hidden behind a Tile with Collision /// </summary> protected bool DetectPlayer() { DisposingInvisibleListLeft = false; DisposingInvisibleListMiddle = false; DisposingInvisibleListRight = false; // UPDATING vEnemyDirection vEnemyDirection = sEntity.Position + new Vector2f(0, 25); // Creating distance to Origin vEnemyDirection = Utilities.VectorRotation(fAngle / 57, vEnemyDirection, sEntity.Position); // Rotating to PlayerPosition // UPDATING vEnemyAngleOrigin vEnemyAngleOrigin = (vEnemyDirection - sEntity.Position) * 0.80f + sEntity.Position; // Calculating based on EnemyDirection1 // UPDATING vEnemyBottomRightPosition and vEnemyBottomLeftPosition vEnemyBottomRightPosition = Utilities.VectorRotation(fAngle / fNumberToCorrect, sEntity.Position + new Vector2f(25, 25), sEntity.Position); // Rotating to PlayerPosition vEnemyBottomLeftPosition = Utilities.VectorRotation(fAngle / fNumberToCorrect, sEntity.Position + new Vector2f(-25, 25), sEntity.Position); // Rotating to PlayerPosition // CALCULATING AngleEnemy fAngleEnemy = Utilities.AngleBetweenVectors180(vEnemyDirection - vEnemyAngleOrigin, new Vector2f(925, 525) - vEnemyAngleOrigin); if (fAngleEnemy.Equals(0 / Zero)) { fAngleEnemy = 0; } // CALCULATING MaxPermittedAngle fMaxPermittedAngle = Utilities.AngleBetweenVectors180(vEnemyDirection - vEnemyAngleOrigin, vEnemyBottomRightPosition - vEnemyAngleOrigin); tDetecting = cDetecting.ElapsedTime; if (fAngleEnemy == 0) { fAngleEnemy = 0.0001f; } if (Utilities.MakePositive(Utilities.DistanceBetweenVectors(MainMap.GetVirtualCharacterPosition(), vEntityPosition)) < iDistanceDetection && fAngleEnemy < fMaxPermittedAngle) { fAnglecopy = fAngle; RotateEnemy(ref fAnglecopy, MainMap.GetStartCharacterPosition() + new Vector2f(25, 25)); ShootInvisible(MainMap.GetTileMapPosition(), fAnglecopy); if (DisposeInvisibleProjectile(lInvisibleProjectileLeft)) { DisposingInvisibleListLeft = true; } //if (DisposeInvisibleProjectile(lInvisibleProjectileMiddle)) // DisposingInvisibleListMiddle = true; if (DisposeInvisibleProjectile(lInvisibleProjectileRight)) { DisposingInvisibleListRight = true; } if (DisposingInvisibleListLeft || DisposingInvisibleListMiddle || DisposingInvisibleListRight) { cDetecting.Restart(); tDetecting = cDetecting.ElapsedTime; bAlert = true; return(true); } if (tDetecting.AsMilliseconds() <= 500) { return(true); } } bAlert = false; return(false); }
// DECLARING METHODS: MOVEMENT /// <summary> /// Moves Archer Randomly, but always to a Position within the DetectionRadius and respecting Collision with Tiles. The Archer doesn't psush the Player around. /// </summary> protected override void Move() { bCollisionUp = false; bCollisionDown = false; bCollisionRight = false; bCollisionLeft = false; bool nearright = false; bool nearleft = false; bool nearup = false; bool neardown = false; bool bRepeat = false; int iRepeating = 0; Vector2f vCharacterPositionEnemyOrigin = MainMap.GetStartCharacterPosition() + new Vector2f(25, 25) - sEntity.Position; CollisionDetection(ref vEntityPosition, ref bCollisionUp, ref bCollisionDown, ref bCollisionRight, ref bCollisionLeft, tEntity.Size.X, tEntity.Size.Y); EnemyEnemyCollision(ref vEntityPosition, ref bCollisionUp, ref bCollisionDown, ref bCollisionRight, ref bCollisionLeft); tMoving = cMoving.ElapsedTime; if (tMoving.AsMilliseconds() > 500) { iRandomNumber = rRandom.Next(0, 4); cMoving.Restart(); } // Enemy does not Push the Player around if (Utilities.MakePositive(MainMap.GetStartCharacterPosition().X + 25 - vEnemyDirection.X + fSpeed) < 50 && Utilities.MakePositive(MainMap.GetStartCharacterPosition().Y + 25 - vEnemyDirection.Y) < 50) { bCollisionLeft = true; } if (Utilities.MakePositive(MainMap.GetStartCharacterPosition().X + 25 - vEnemyDirection.X - fSpeed) < 50 && Utilities.MakePositive(MainMap.GetStartCharacterPosition().Y + 25 - vEnemyDirection.Y) < 50) { bCollisionRight = true; } if (Utilities.MakePositive(MainMap.GetStartCharacterPosition().X + 25 - vEnemyDirection.X) < 50 && Utilities.MakePositive(MainMap.GetStartCharacterPosition().Y + 25 - vEnemyDirection.Y + fSpeed) < 50) { bCollisionUp = true; } if (Utilities.MakePositive(MainMap.GetStartCharacterPosition().X + 25 - vEnemyDirection.X) < 50 && Utilities.MakePositive(MainMap.GetStartCharacterPosition().Y + 25 - vEnemyDirection.Y - fSpeed) < 50) { bCollisionDown = true; } float CharacterPosEnemyOriginX = MainMap.GetVirtualCharacterPosition().X - vEntityPosition.X; float CharacterPosEnemyOriginY = MainMap.GetVirtualCharacterPosition().Y - vEntityPosition.Y; // Enemy does not accidently hide behind Tiles with Collision if (CharacterPosEnemyOriginX > 0 && DisposingInvisibleListLeft && !DisposingInvisibleListRight || CharacterPosEnemyOriginX < 0 && !DisposingInvisibleListLeft && DisposingInvisibleListRight) { bCollisionDown = true; } else if (CharacterPosEnemyOriginX > 0 && !DisposingInvisibleListLeft && DisposingInvisibleListRight || CharacterPosEnemyOriginX < 0 && DisposingInvisibleListLeft && !DisposingInvisibleListRight) { bCollisionUp = true; } if (CharacterPosEnemyOriginY > 0 && DisposingInvisibleListLeft && !DisposingInvisibleListRight || CharacterPosEnemyOriginY < 0 && !DisposingInvisibleListLeft && DisposingInvisibleListRight) { bCollisionLeft = true; } else if (CharacterPosEnemyOriginY > 0 && !DisposingInvisibleListLeft && DisposingInvisibleListRight || CharacterPosEnemyOriginY < 0 && DisposingInvisibleListLeft && !DisposingInvisibleListRight) { bCollisionRight = true; } // Enemy does not go outside a specific range of the Player if (vCharacterPositionEnemyOrigin.X > (-iDistanceDetection / 2) || vCharacterPositionEnemyOrigin.X < (iDistanceDetection / 2)) { if (vCharacterPositionEnemyOrigin.Y < (iDistanceDetection / 2)) { nearup = true; } if (vCharacterPositionEnemyOrigin.Y > (-iDistanceDetection / 2)) { neardown = true; } } if (vCharacterPositionEnemyOrigin.Y < (iDistanceDetection / 2) || vCharacterPositionEnemyOrigin.Y > (-iDistanceDetection / 2)) { if (vCharacterPositionEnemyOrigin.X > (-iDistanceDetection / 2)) { nearright = true; } if (vCharacterPositionEnemyOrigin.X < (iDistanceDetection / 2)) { nearleft = true; } } do { if (bRepeat) { bRepeat = false; iRandomNumber = rRandom.Next(0, 4); iRepeating++; } switch (iRandomNumber) { case (0): if (nearup && !bCollisionUp) { MoveUp(); } else { bRepeat = true; } break; case (1): if (neardown && !bCollisionDown) { MoveDown(); } else { bRepeat = true; } break; case (2): if (nearright && !bCollisionRight) { MoveRight(); } else { bRepeat = true; } break; case (3): if (nearleft && !bCollisionLeft) { MoveLeft(); } else { bRepeat = true; } break; } }while (bRepeat && iRepeating <= 2); }