public virtual void SignalProximityAllies(List<Unit> CloseUnits, UnitGoal CurrentGoal) { foreach (Unit unit in CloseUnits) { if (!unit.Owner.IsEnemy) { if (Distance(Position, unit.Position) <= ViewRange)//this is also the range that they communicate at { if (unit.ProximitySignal == null) unit.ProximitySignal = new List<UnitGoal>(); unit.ProximitySignal.Add(CurrentGoal); } } } }
public virtual void Behavior(List<Unit> CloseUnits)//AI { Unit FocusedUnit = null; //this is after the check is done, where the unit will focus, can be enemy or ally if (ProximitySignal == null) ProximitySignal = new List<UnitGoal>(); //SELECT the enemy unit with lowest health, assuming its close enough foreach (Unit unit in CloseUnits) { if (!unit.Equals(this)) { if (unit.Owner.IsEnemy) { if (Distance(Position, unit.Position) <= ViewRange) { if (FocusedUnit == null) FocusedUnit = unit; if (unit.CurrentHealth <= FocusedUnit.CurrentHealth) { if (Distance(Position, unit.Position) >= Distance(Position, FocusedUnit.Position)) FocusedUnit = unit; } } } } } if (FocusedUnit == null) return; UnitGoal unitgoal; unitgoal = new UnitGoal(); unitgoal.Target = FocusedUnit; unitgoal.State = UnitState.AutoAttack; unitgoal.Position = FocusedUnit.Position; this.ProximitySignal.Add(unitgoal); SignalProximityAllies(CloseUnits,unitgoal); }
public void Evade(UnitGoal unitGoal) { Vector3 currentPos = (Vector3)Converters.WorldPositionToCartesianPosition(Position, worldSize.X); Vector3 targetPos = (Vector3)Converters.WorldPositionToCartesianPosition(unitGoal.Target.Position, worldSize.X); float x = currentPos.X - targetPos.X; float y = currentPos.Y - targetPos.Y; float z = currentPos.Z; Vector3 runVector = new Vector3(x, y, z); runVector.Normalize(); //destination x = currentPos.X + (runVector.X * 200); y = currentPos.Y + (runVector.Y * 200); z = currentPos.Z; Vector3 destPos = new Vector3(x, y, z); //unitGoal.Position = new Vector3(Position.X, Position.Y + 100, Position.Z); unitGoal.Position = Converters.CartesianPositionToWorldPosition(destPos, worldSize.X); Move(unitGoal); ////if (isSideStepping) ////{ //// sideStepCount++; //// //run in opposite direction //// float x = -1 * (unitGoal.Target.Position.X - Position.X)+sideStep.X; //// float y = -1 * (unitGoal.Target.Position.Y - Position.Y)+sideStep.Y; //// float z = -1 * (unitGoal.Target.Position.Z - Position.Z)+sideStep.Z; //// Vector3 runVector = new Vector3(x, y, z); //// unitGoal.Position = runVector; //// Move(unitGoal); //// if (sideStepCount == 50) //// isSideStepping = false; ////} ////else ////{ ////run in opposite direction //float x = 0; //float y = 0; //float z = 0; //if (unitGoal.Target.Position.X > Position.X) //{ // x = (unitGoal.Target.Position.X - Position.X); //} //else //{ // x = (Position.X - unitGoal.Target.Position.X); //} //if (unitGoal.Target.Position.Y > Position.Y) //{ // y = (unitGoal.Target.Position.Y - Position.Y); //} //else //{ // y = (Position.Y - unitGoal.Target.Position.Y); //} //if (unitGoal.Target.Position.Z > Position.Z) //{ // z = (unitGoal.Target.Position.Z - Position.Z); //} //else //{ // z = (Position.Z - unitGoal.Target.Position.Z); //} ////float x = (unitGoal.Target.Position.X - Position.X); ////float y = (unitGoal.Target.Position.Y - Position.Y); ////float z = (unitGoal.Target.Position.Z - Position.Z); //Vector3 runVector = new Vector3(x, y, z); ////10% chance of changing direction //Random random = new Random(); //if (random.NextDouble() > 0.9) //{ // isSideStepping = true; // sideStepCount = 0; // sideStep = new Vector3(random.Next(50), random.Next(50), random.Next(50)); // Console.WriteLine("step"); //} //unitGoal.Position = runVector; //Move(unitGoal); }
public void Chase(UnitGoal unitGoal) { unitGoal.Position = new Vector3(unitGoal.Target.Position.X, unitGoal.Target.Position.Y, unitGoal.Target.Position.Z); Move(unitGoal); }
public void crashAndTurn(UnitGoal unitGoal) { Vector3? curPos = Helpers.Converters.WorldPositionToCartesianPosition(Position, worldSize.X); Vector3? goalPos = Helpers.Converters.WorldPositionToCartesianPosition(unitGoal.Position, worldSize.X); if (Obstacles != null) { if (!IsColliding) { //calc distance between goal and position float XDistance = goalPos.Value.X - curPos.Value.X; float YDistance = goalPos.Value.Y - curPos.Value.Y; //calculate the required rotation by doing a two-variable arc-tan RotationY = (float)(Math.Atan2(YDistance, XDistance) / Math.PI) * 180; //if obstacle below model if (curPos.Value.Y > goalPos.Value.Y) RotationY = 360 + RotationY; //model forward is 0 degrees so subtract 90 RotationY -= 90; //move model towards goal by closing the gap 3 pixels per update float x = curPos.Value.X - (float)(Math.Cos(RotationY + 90)); float y = curPos.Value.Y - (float)(Math.Sin(RotationY + 90)); //Boids Vector2 boid = BoidRules(); x += boid.X; y += boid.Y; //move model to new position Position = (Vector3)Helpers.Converters.CartesianPositionToWorldPosition(new Vector3(x, y, curPos.Value.Z), worldSize.X); } else { bool noObstaclesAhead = false; //get move vector from rotation angle Vector2 angleVector = AngleToVector(RotationY); Vector3 moveDir = (Vector3)Converters.CartesianVectorToWorldVector(new Vector3(angleVector.X, angleVector.Y, 0)); //get goal vector Vector3? orig = Converters.CartesianPositionToWorldPosition(curPos, worldSize.X); Vector3? dest = Converters.CartesianPositionToWorldPosition(goalPos, worldSize.X); Vector3 goalDir = (Vector3)dest - (Vector3)orig; //position ray start at center of model Vector3 rayPos = (Vector3)orig; rayPos.Y += this.BoundingSphere.Radius; //create rays moveRay = new Ray(rayPos, (Vector3)moveDir); goalRay = new Ray(rayPos, (Vector3)goalDir); //get ray intersections try { float? intersectGoalRay = goalRay.Intersects(Obstacles[0].BoundingSphere); float? intersectMoveRay = moveRay.Intersects(Obstacles[0].BoundingSphere); if (intersectMoveRay == null) //no obstacles infront of model noObstaclesAhead = true; if (intersectGoalRay == null) //no obstacles between model and point IsColliding = false; } catch { } getBoundingSphere(); Obstacles[0].getBoundingSphere(); if (BoundingSphere.Intersects(Obstacles[0].BoundingSphere)) { IsColliding = false; } if (noObstaclesAhead) { //move model towards goal by closing the gap 3 pixels per update float x = curPos.Value.X - (float)(Math.Cos(RotationY + 90)); float y = curPos.Value.Y - (float)(Math.Sin(RotationY + 90)); //Boids Vector2 boid = BoidRules(); x += boid.X; y += boid.Y; Position = (Vector3)Helpers.Converters.CartesianPositionToWorldPosition(new Vector3(x, y, curPos.Value.Z), worldSize.X); } else { RotationY += 5; Console.WriteLine(RotationY); } } } else //no obstacles { showRays = true; //calc distance between goal and position float XDistance = goalPos.Value.X - curPos.Value.X; float YDistance = goalPos.Value.Y - curPos.Value.Y; //calculate the required rotation by doing a two-variable arc-tan RotationY = (float)(Math.Atan2(YDistance, XDistance) / Math.PI) * 180; //if obstacle below model if (curPos.Value.Y > goalPos.Value.Y) RotationY = 360 + RotationY; //model forward is 0 degrees so subtract 90 RotationY -= 90; //move model towards goal by closing the gap 3 pixels per update float x = curPos.Value.X - (float)(Math.Cos(RotationY + 90)); float y = curPos.Value.Y - (float)(Math.Sin(RotationY + 90)); //Boids Vector2 boid = BoidRules(); x += boid.X; y += boid.Y; //move model to new position Position = (Vector3)Helpers.Converters.CartesianPositionToWorldPosition(new Vector3(x, y, curPos.Value.Z), worldSize.X); } }
public void Move(UnitGoal unitGoal) { Vector3? curPos = Helpers.Converters.WorldPositionToCartesianPosition(Position, worldSize.X); Vector3? goalPos = Helpers.Converters.WorldPositionToCartesianPosition(unitGoal.Position, worldSize.X); float distance = Vector3.Distance(new Vector3(curPos.Value.X, curPos.Value.Y, curPos.Value.Z), new Vector3(goalPos.Value.X, goalPos.Value.Y, goalPos.Value.Z)); //check if reached goal if (distance > 15) { crashAndTurn(unitGoal); } else { //reached goal showRays = false; //remove it from everyone in swarm for (int x = 0; x < Swarm.Count; x++) { if (Swarm[x].UnitGoals.Count > 0) { Swarm[x].UnitGoals.RemoveAt(0); } } } }
public virtual void Attack(UnitGoal unitGoal) { if (Distance(Position, unitGoal.Target.Position) <= AttackRange) { if (isAttackCooldown) { //wait for attack cooldown attackCooldownLeft -= currentGameTime.ElapsedGameTime.TotalSeconds; if (attackCooldownLeft <= 0) { //cooldown over isAttackCooldown = false; } } else { //attack unitGoal.Target.CurrentHealth -= (int)AttackDamage; isAttackCooldown=true; attackCooldownLeft = AttackCooldown; } if (unitGoal.Target.CurrentHealth <= 0) { //target dead //remove from unit goals UnitGoals.Remove(unitGoal); } } else { unitGoal.Position = unitGoal.Target.Position; Move(unitGoal); } }