// public method for adding pathfinding requests public void AddPathFindRequest(MoveCommand command, bool queued, bool recalculatingCurrentPath, bool avoidUnits) { int distancePriority; if (!queued) { distancePriority = (int)Vector2.DistanceSquared(command.Unit.CenterPoint, command.Destination); if (!recalculatingCurrentPath) addHighPriorityPathFindRequest(command, distancePriority, avoidUnits); else addLowPriorityPathFindRequest(command, command.Unit.CurrentPathNode, distancePriority, queued, avoidUnits); } else { Vector2 beginLocation = command.Unit.FinalMoveDestination; distancePriority = (int)Vector2.DistanceSquared(beginLocation, command.Destination); addLowPriorityPathFindRequest(command, Tools.PathNodeAt(beginLocation), distancePriority, queued, avoidUnits); } }
public void GiveCommand(MoveCommand command) { if (Busy) { if (Commands.Count > 1) { //for (int i = 1; i < Commands.Count - 1; i++) // Player.Players[Team].UnitCommands.Remove(Commands[i]); Commands.RemoveRange(1, Commands.Count - 1); } return; } IgnoringCollision = (command is HarvestCommand || command is ReturnCargoCommand); // use previous path with new destination tacked on until new path is calculated // (LoL style) int commandPriority = -1; if (Commands.Count > 0 && !command.Calculated) { MoveCommand lastMoveCommand = Commands[0] as MoveCommand; if (lastMoveCommand != null) { if (lastMoveCommand.Destination == command.Destination) return; command.WayPoints = lastMoveCommand.WayPoints; command.WayPoints.Add(command.Destination); Rts.pathFinder.Tools.SmoothPathEnd(command.WayPoints, this); commandPriority = ((int)Vector2.DistanceSquared(lastMoveCommand.Destination, command.Destination) + (int)Vector2.DistanceSquared(centerPoint, command.Destination)) / 2; } } deactivateAllCommands(); clearCommands(); Commands.Add(command); lastWayPoint = centerPoint; lastMoveDestination = command.Destination; timeSinceLastRecalculatePath = 0; //command.WayPoints = PathFinder.FindPath(CurrentPathNode, command.Destination, false); if (command is ReturnCargoCommand || command is HarvestCommand) commandPriority = int.MaxValue / 2 + (int)Vector2.DistanceSquared(centerPoint, command.Destination); else if (commandPriority == -1) commandPriority = (int)Vector2.DistanceSquared(centerPoint, command.Destination); //AttackCommand attackCommand = command as AttackCommand; //if (attackCommand != null) //PathFinder.AddHighPriorityPathFindRequest(this, command, CurrentPathNode, commandPriority, false); //else //if (Team == Player.Me.Team) //PathFinder.AddHighPriorityPathFindRequest(command, commandPriority, false); // look for target if attack move command if (command is AttackMoveCommand) { RtsObject target = FindNearestTarget(); if (target != null) { Commands[0] = new AttackCommand(this, target, true, false); Commands.Insert(1, command); return; } timeSinceLastLookForTarget = lookForTargetDelay; } }
/*void Move(Vector2 target, GameTime gameTime) { clearPushStatus(); float moveX = Util.ScaleWithGameTime(speed.X, gameTime); float moveY = Util.ScaleWithGameTime(speed.Y, gameTime); Vector2 difference = target - centerPoint; if (Math.Abs(difference.X) < moveX && Math.Abs(difference.Y) < moveY) { this.CenterPoint = target; nextWayPoint(); return; } float angle = (float)Math.Atan2((double)(target.Y - CenterPoint.Y), (double)(target.X - CenterPoint.X)); moveX *= (float)Math.Cos(angle); moveY *= (float)Math.Sin(angle); lastMove.X = moveX; lastMove.Y = moveY; PrecisePosition += lastMove; checkForWallHit(); //foreach (Unit unit in Units) foreach (Unit unit in PotentialCollisions) { if (unit != this && Intersects(unit)) { if (isMoving) { if (unit.isIdle && unit.lastWayPoint == target) { nextWayPoint(); //Stop(); } else if (Contains(MoveTarget))// || unit.Contains(moveTarget)) { nextWayPoint(); //Stop(); } } angle = (float)Math.Atan2(unit.centerPoint.Y - centerPoint.Y, unit.centerPoint.X - centerPoint.X); float distance = Radius + unit.Radius; float force = distance - Vector2.Distance(unit.centerPoint, centerPoint); if (unit.isFollowing && unit.followTarget == this) { unit.Push(this, angle, force); } else if (isFollowing && unit == followTarget) { //Push(angle + (float)Math.PI, force); PushSimple(angle + (float)Math.PI, force); } else { isPushing = true; unit.Push(this, angle, force * .1f); PushSimple(angle + (float)Math.PI, force * .9f); //Push(angle + (float)Math.PI, force * .5f); //unit.Push(angle, force); } } } //if (instanceFrameCount % 6 == 0) // checkIfCurrentPathNodeChanged(); checkIfCloserToNextWayPointThanCurrentWayPoint(); //if (instanceFrameCount % 120 == 0) // checkIfCloserToGoalThanCurrentWayPoint(); turnTowards(target, 100 / radius, gameTime); }*/ void Move(MoveCommand command, GameTime gameTime) { checkForSmoothPath(command, gameTime); clearPushStatus(); clearHitWallStatus(); Vector2 wayPoint = command.WayPoints[0]; //float moveX = Util.ScaleWithGameTime(speed.X, gameTime); //float moveY = Util.ScaleWithGameTime(speed.Y, gameTime); Speed = MathHelper.Min(Speed + Util.ScaleWithGameTime(acceleration, gameTime), MaxSpeed); float actualSpeed = Util.ScaleWithGameTime(Speed, gameTime); //float moveX = Util.ScaleWithGameTime(Speed, gameTime); //float moveY = moveX; if (command.WayPoints.Count > 1) { if (Contains(wayPoint)) { lastWayPoint = wayPoint; command.NextWayPoint(this, Rts.pathFinder); return; } } else { //Vector2 difference = wayPoint - centerPoint; float distance = Vector2.Distance(wayPoint, centerPoint); if (distance < actualSpeed) { this.CenterPoint = wayPoint; HasMoved = true; lastWayPoint = wayPoint; //command.NextWayPoint(this, PathFinder); //if (command.WayPoints.Count == 0) NextCommand(); return; } } //float angle = (float)Math.Atan2(wayPoint.Y - CenterPoint.Y, wayPoint.X - CenterPoint.X); //moveX *= (float)Math.Cos(angle); //moveY *= (float)Math.Sin(angle); //lastMove.X = moveX; //lastMove.Y = moveY; lastMove = new Vector2(wayPoint.X - CenterPoint.X, wayPoint.Y - CenterPoint.Y); //lastMove.Normalize(); //lastMove *= actualSpeed; lastMove *= (actualSpeed / lastMove.Length()); PrecisePosition += lastMove; HasMoved = true; if (checkForWallHit(command) && Vector2.Distance(centerPoint, command.Destination) < Radius) { NextCommand(); return; } if (checkForPush(command)) return; if (!turnTowards(wayPoint, 120 / Radius, gameTime)) { Speed = MathHelper.Max(Speed - Util.ScaleWithGameTime(acceleration, gameTime), 0); } }
protected bool checkForWallHit(MoveCommand command) { if (hitWall >= 2) return false; bool hit = false; List<PathNode> pathNodesHit = new List<PathNode>(); foreach (PathNode pathNode in PathNodeBufferSquare) //foreach (PathNode pathNode in OccupiedPathNodes) { MapTile tile = pathNode.Tile; //if (!tile.Walkable && Intersects(tile)) if ((!tile.Walkable || pathNode.Blocked) && tile.IntersectsUnit(this)) { //if (harvestCommand != null) //{ pathNodesHit.Add(pathNode); //return (pathNode.Blocker == ((HarvestCommand)command).TargetResource); //} if (command != null && timeSinceLastRecalculatePath >= recalculatePathDelay && command.Calculated) { timeSinceLastRecalculatePath = 0; Rts.pathFinder.AddPathFindRequest(command, false, true, false); } float angle = (float)Math.Atan2(centerPoint.Y - tile.CenterPoint.Y, centerPoint.X - tile.CenterPoint.X); float distance = Radius + tile.CollisionRadius; float force = distance - Vector2.Distance(tile.CenterPoint, centerPoint); hitWall++; hit = true; //isBlocked = true; PushSimple(angle, force); //Push(null, angle, force); } /*MapTile tile = pathNode.Tile; //if (!tile.Walkable && Intersects(tile)) if (!tile.Walkable) { hitWall++; if (centerPoint.X < tile.CenterPoint.X) { CenterPointX = tile.Rectangle.X - Radius; checkForWallHit(); } else if (centerPoint.X >= tile.CenterPoint.X) { CenterPointX = tile.Rectangle.X + tile.Rectangle.Width + Radius; checkForWallHit(); } else if (centerPoint.Y < tile.CenterPoint.Y) { CenterPointY = tile.Rectangle.Y - Radius; checkForWallHit(); } else if (centerPoint.Y >= tile.CenterPoint.Y) { CenterPointY = tile.Rectangle.Y + tile.Rectangle.Height + Radius; checkForWallHit(); } }*/ } HarvestCommand harvestCommand = command as HarvestCommand; if (harvestCommand != null) { foreach (PathNode pathNode in pathNodesHit) { if (pathNode.Blocker == harvestCommand.TargetResource) return true; } //return (pathNodeHit != null && pathNodeHit.Blocker is Resource); return false; } ReturnCargoCommand returnCargoCommand = command as ReturnCargoCommand; if (returnCargoCommand != null) { foreach (PathNode pathNode in pathNodesHit) { if (pathNode.Blocker == returnCargoCommand.TargetStructure) return true; } return false; } return hit; }
protected void checkForSmoothPath(MoveCommand command, GameTime gameTime) { timeSinceLastSmoothPath += (int)(gameTime.ElapsedGameTime.TotalMilliseconds * Rts.GameSpeed); if (timeSinceLastSmoothPath >= smoothPathDelay) { timeSinceLastSmoothPath = 0; Rts.pathFinder.Tools.SmoothImmediatePath(command.WayPoints, this, centerPoint, false); } }
public void GiveCommand(MoveCommand command) { // use previous path with new destination tacked on until new path is calculated // (LoL style) int commandPriority = -1; if (Commands.Count > 0) { MoveCommand lastMoveCommand = Commands[0] as MoveCommand; if (lastMoveCommand != null) { if (lastMoveCommand.Destination == command.Destination) return; command.WayPoints = lastMoveCommand.WayPoints; command.WayPoints.Add(command.Destination); PathFinder.SmoothPathEnd(command.WayPoints, this); commandPriority = ((int)Vector2.Distance(lastMoveCommand.Destination, command.Destination) + (int)Vector2.Distance(centerPoint, command.Destination)) / 2; } } deactivateAllCommands(); Commands.Clear(); Commands.Add(command); lastWayPoint = centerPoint; lastMoveDestination = command.Destination; timeSinceLastRecalculatePath = 0; //command.WayPoints = PathFinder.FindPath(CurrentPathNode, command.Destination, false); if (commandPriority == -1) commandPriority = (int)Vector2.DistanceSquared(centerPoint, command.Destination); PathFinder.AddHighPriorityPathFindRequest(this, command, CurrentPathNode, commandPriority, false); }
// without attack target void addHighPriorityPathFindRequest(MoveCommand command, int priority, bool avoidUnits) { command.Calculated = false; //highPriorityRequestsToAdd.Enqueue(new PathFindRequest(command, command.Unit.CurrentPathNode, priority, avoidUnits)); highPriorityRequestsToAdd.Enqueue(new PathFindRequest(command, command.Unit.CurrentPathNode, priority, false, avoidUnits)); }
// for move command. returns true if command ended protected bool checkForPush(MoveCommand command) { //lock (PotentialCollisions) { foreach (Unit unit in PotentialCollisions) { if (!unit.IgnoringCollision && Intersects(unit)) { if (timeSinceLastRecalculatePath >= recalculatePathDelay && command.Calculated) { timeSinceLastRecalculatePath = 0; Rts.pathFinder.AddPathFindRequest(command, false, true, false); } float angle = (float)Math.Atan2(unit.centerPoint.Y - centerPoint.Y, unit.centerPoint.X - centerPoint.X); float distance = Radius + unit.Radius; float force = distance - Vector2.Distance(unit.centerPoint, centerPoint); if (unit.Team != Team) { PushSimple(angle + (float)Math.PI, force); } else if (unit.IsIdle && (unit.lastMoveDestination == command.Destination || unit.Contains(command.Destination))) { PushSimple(angle + (float)Math.PI, force); lastWayPoint = command.WayPoints[0]; if (!(command is BuildStructureCommand)) { command.NextWayPoint(this, Rts.pathFinder); if (command.WayPoints.Count == 0) { NextCommand(); return true; } } } else if (unit.lastMoveDestination == command.Destination && unit.Contains(command.Destination)) { PushSimple(angle + (float)Math.PI, force); lastWayPoint = command.WayPoints[0]; if (!(command is BuildStructureCommand)) { command.NextWayPoint(this, Rts.pathFinder); if (command.WayPoints.Count == 0) { NextCommand(); return true; } } command.NextWayPoint(this, Rts.pathFinder); if (command.WayPoints.Count == 0 && !(command is BuildStructureCommand)) { NextCommand(); return true; } } else if (Contains(command.Destination)) { PushSimple(angle + (float)Math.PI, force); lastWayPoint = command.WayPoints[0]; if (!(command is BuildStructureCommand)) { command.NextWayPoint(this, Rts.pathFinder); if (command.WayPoints.Count == 0) { NextCommand(); return true; } } } //if (unit.isFollowing && unit.followTarget == this) //{ // unit.Push(this, angle, force); //} //else if (isFollowing && unit == followTarget) //{ // PushSimple(angle + (float)Math.PI, force); //} // else { //pushCount++; float sizeRatio = this.Diameter / unit.Diameter; //float pushForce = force * (.05f * sizeRatio); float pushForce; if (unit.IsMoving) pushForce = force * (.05f * sizeRatio); else pushForce = force * (.3f * sizeRatio); unit.Push(this, angle, pushForce); PushSimple(angle + (float)Math.PI, force - pushForce); //PushSimple(angle + (float)Math.PI, force * .90f); //unit.Push(this, angle, force * .1f); //PushSimple(angle + (float)Math.PI, force * .9f); } } } } /*foreach (PathNode pathNode in OccupiedPathNodes) { foreach (Unit unit in pathNode.UnitsContained) { if (unit != this && Intersects(unit)) { if (timeSinceLastRecalculatePath >= recalculatePathDelay && command.Calculated) { timeSinceLastRecalculatePath = 0; PathFinder.AddLowPriorityPathFindRequest(this, command, CurrentPathNode, (int)Vector2.DistanceSquared(centerPoint, command.Destination), false); } float angle = (float)Math.Atan2(unit.centerPoint.Y - centerPoint.Y, unit.centerPoint.X - centerPoint.X); float distance = Radius + unit.Radius; float force = distance - Vector2.Distance(unit.centerPoint, centerPoint); if (unit.IsIdle && (unit.lastMoveDestination == command.Destination || unit.Contains(command.Destination))) { PushSimple(angle + (float)Math.PI, force); lastWayPoint = command.WayPoints[0]; command.NextWayPoint(this, PathFinder); if (command.WayPoints.Count == 0) { nextCommand(); return true; } } else if (unit.lastMoveDestination == command.Destination && unit.Contains(command.Destination)) { PushSimple(angle + (float)Math.PI, force); lastWayPoint = command.WayPoints[0]; command.NextWayPoint(this, PathFinder); if (command.WayPoints.Count == 0) { nextCommand(); return true; } } else if (Contains(command.Destination)) { PushSimple(angle + (float)Math.PI, force); lastWayPoint = command.WayPoints[0]; command.NextWayPoint(this, PathFinder); if (command.WayPoints.Count == 0) { nextCommand(); return true; } } //if (unit.isFollowing && unit.followTarget == this) //{ // unit.Push(this, angle, force); //} //else if (isFollowing && unit == followTarget) //{ // PushSimple(angle + (float)Math.PI, force); //} // else { //pushCount++; float sizeRatio = this.Diameter / unit.Diameter; float pushForce = force * (.1f * sizeRatio); unit.Push(this, angle, pushForce); PushSimple(angle + (float)Math.PI, force - pushForce); //unit.Push(this, angle, force * .1f); //PushSimple(angle + (float)Math.PI, force * .9f); } } } }*/ return false; }
void completeBuildQueueItem(BuildQueueItem item) { BuildUnitButtonType buttonType = item.Type as BuildUnitButtonType; if (buttonType != null) { Unit unit; if (buttonType.UnitType == UnitType.MeleeNublet) unit = new MeleeNublet(new Vector2(), Team, item.ID); else if (buttonType.UnitType == UnitType.RangedNublet) unit = new RangedNublet(new Vector2(), Team, item.ID); else unit = new WorkerNublet(new Vector2(), Team, item.ID); float angle = 0; Vector2 spawnLocation; if (rallyPoints.Count > 0) { angle = (float)Math.Atan2(rallyPoints[0].Point.Y - CenterPoint.Y, rallyPoints[0].Point.X - CenterPoint.X); angle = Util.ConvertToPositiveRadians(angle); /*if (angle < MathHelper.TwoPi / 4) spawnLocation = new Vector2(Rectangle.X + Rectangle.Width - map.TileSize, Rectangle.Y + Rectangle.Height - map.TileSize / 2); else if (angle < MathHelper.TwoPi / 2) spawnLocation = new Vector2(Rectangle.X + map.TileSize, Rectangle.Y + Rectangle.Height - map.TileSize / 2); else if (angle < MathHelper.TwoPi * .75f) spawnLocation = new Vector2(Rectangle.X + map.TileSize, Rectangle.Y + map.TileSize / 2); else spawnLocation = new Vector2(Rectangle.X + Rectangle.Width - map.TileSize, Rectangle.Y + map.TileSize / 2);*/ PathNode closestPathNode = null; float closest = float.MaxValue; foreach (PathNode pathNode in exitPathNodes) { float distance = Vector2.Distance(pathNode.Tile.CenterPoint, RallyPoints[0].Point); if (distance < closest) { closestPathNode = pathNode; closest = distance; } } if (closestPathNode != null) spawnLocation = closestPathNode.Tile.CenterPoint; else if (exitPathNodes.Count > 0) spawnLocation = exitPathNodes[0].Tile.CenterPoint; else spawnLocation = new Vector2(Rectangle.X + Rts.map.TileSize, Rectangle.Y + Rectangle.Height - Rts.map.TileSize / 2); } else { spawnLocation = new Vector2(Rectangle.X + Rts.map.TileSize, Rectangle.Y + Rectangle.Height - Rts.map.TileSize / 2); } unit.CenterPoint = new Vector2(spawnLocation.X, spawnLocation.Y); unit.Rotation = angle; unit.InitializeCurrentPathNode(); if (rallyPoints.Count == 0) { unit.CheckForWallHit(); unit.CheckForPush(); } else { MoveCommand command = null; if (rallyPoints[0].Resource != null && unit is WorkerNublet) command = new HarvestCommand(unit, rallyPoints[0].Resource); else command = new MoveCommand(unit, RallyPoints[0].Point); if (command != null) { unit.GiveCommand(command); Rts.pathFinder.AddPathFindRequest(command, false, false, false); } for (int i = 1; i < RallyPoints.Count; i++) { if (rallyPoints[i].Resource != null && unit is WorkerNublet) unit.QueueCommand(new HarvestCommand(unit, rallyPoints[i].Resource)); else unit.QueueCommand(new MoveCommand(unit, RallyPoints[i].Point)); } unit.CheckForWallHit(); } } }
/*// with attack target * public void AddHighPriorityPathFindRequest(Unit unit, RtsObject attackTarget, MoveCommand command, PathNode startNode, int priority, bool avoidUnits) * { * command.Calculated = false; * highPriorityRequestsToAdd.Enqueue(new PathFindRequest(unit, attackTarget, command, startNode, priority, avoidUnits)); * }*/ // without attack target void addLowPriorityPathFindRequest(MoveCommand command, PathNode startNode, int priority, bool queued, bool avoidUnits) { command.Calculated = false; lowPriorityRequestsToAdd.Enqueue(new PathFindRequest(command, startNode, priority, queued, avoidUnits)); }
// for move command. returns true if command ended bool checkForPush(MoveCommand command) { lock (PotentialCollisions) { foreach (Unit unit in PotentialCollisions) { if (Intersects(unit)) { if (timeSinceLastRecalculatePath >= recalculatePathDelay && command.Calculated) { timeSinceLastRecalculatePath = 0; PathFinder.AddLowPriorityPathFindRequest(this, command, CurrentPathNode, (int)Vector2.DistanceSquared(centerPoint, command.Destination), false); } float angle = (float)Math.Atan2(unit.centerPoint.Y - centerPoint.Y, unit.centerPoint.X - centerPoint.X); float distance = Radius + unit.Radius; float force = distance - Vector2.Distance(unit.centerPoint, centerPoint); if (unit.IsIdle && (unit.lastMoveDestination == command.Destination || unit.Contains(command.Destination))) { PushSimple(angle + (float)Math.PI, force); lastWayPoint = command.WayPoints[0]; command.NextWayPoint(this, PathFinder); if (command.WayPoints.Count == 0) { nextCommand(); return(true); } } else if (unit.lastMoveDestination == command.Destination && unit.Contains(command.Destination)) { PushSimple(angle + (float)Math.PI, force); lastWayPoint = command.WayPoints[0]; command.NextWayPoint(this, PathFinder); if (command.WayPoints.Count == 0) { nextCommand(); return(true); } } else if (Contains(command.Destination)) { PushSimple(angle + (float)Math.PI, force); lastWayPoint = command.WayPoints[0]; command.NextWayPoint(this, PathFinder); if (command.WayPoints.Count == 0) { nextCommand(); return(true); } } /*if (unit.isFollowing && unit.followTarget == this) * { * unit.Push(this, angle, force); * } * else if (isFollowing && unit == followTarget) * { * PushSimple(angle + (float)Math.PI, force); * } * else*/ { //pushCount++; float sizeRatio = this.Diameter / unit.Diameter; float pushForce = force * (.1f * sizeRatio); unit.Push(this, angle, pushForce); PushSimple(angle + (float)Math.PI, force - pushForce); //unit.Push(this, angle, force * .1f); //PushSimple(angle + (float)Math.PI, force * .9f); } } } } return(false); }
public void Update(GameTime gameTime) { int elapsedMilliseconds = (int)gameTime.ElapsedGameTime.TotalMilliseconds; timeSinceLastRecalculatePath += elapsedMilliseconds; timeSinceLastAttack += elapsedMilliseconds; updateCurrentPathNode(); if (Commands.Count == 0) { return; } UnitCommand command = Commands[0]; if (command is AttackCommand) { AttackCommand attackCommand = (AttackCommand)command; if (attackCommand.Target.IsDead) { nextCommand(); } else { Attack(attackCommand, gameTime); performAttackIfStarted(attackCommand); } } else if (command is MoveCommand) { MoveCommand moveCommand = (MoveCommand)command; /*if (timeSinceLastRecalculatePath >= recalculatePathDelay && moveCommand.Calculated) * { * timeSinceLastRecalculatePath = 0; * PathFinder.AddLowPriorityPathFindRequest(this, moveCommand, CurrentPathNode, (int)Vector2.Distance(centerPoint, moveCommand.Destination), false); * }*/ //if (instanceFrameCount % reCalculatePathFrameDelay == 1) // PathFinder.SmoothPath(moveCommand.WayPoints, this); Move(moveCommand, gameTime); } // update attack command destinations for (int i = 0; i < Commands.Count; i++) { AttackCommand c = Commands[i] as AttackCommand; if (c != null) { if (c.Target.IsDead) { Commands.Remove(c); i--; } else { c.Destination = c.Target.CenterPoint; } } } // update queued command starting points for (int i = 1; i < Commands.Count; i++) { MoveCommand c = Commands[i] as MoveCommand; MoveCommand previous = Commands[i - 1] as MoveCommand; if (c != null && previous != null) { c.WayPoints[0] = previous.Destination; } } // recalculate queued paths /*if (command is MoveCommand && instanceFrameCount % (reCalculatePathFrameDelay) == 0) * { * MoveCommand moveCommand = (MoveCommand)command; * for (int i = 1; i < Commands.Count; i++) * { * MoveCommand c = Commands[i] as MoveCommand; * MoveCommand previousCommand = Commands[i - 1] as MoveCommand; * if (c != null && previousCommand != null) * { * int y = (int)MathHelper.Clamp(previousCommand.Destination.Y / Map.TileSize, 0, Map.Height - 1); * int x = (int)MathHelper.Clamp(previousCommand.Destination.X / Map.TileSize, 0, Map.Width - 1); * * PathNode node = PathFinder.PathNodes[y, x]; * if (!node.Tile.Walkable) * node = PathFinder.FindNearestPathNode(y, x); * * c.WayPoints = PathFinder.FindPath(node, c.Destination, false); * } * } * }*/ }
void giveMoveCommand(Vector2 mousePosition) { // create move command shrinker thing Shrinker moveCommandThing; if (Unit.PathFinder.IsPointWalkable(mousePosition)) moveCommandThing = new Shrinker(mousePosition - new Vector2(moveCommandShrinkerSize / 2f, moveCommandShrinkerSize / 2f), moveCommandShrinkerSize, 10); else moveCommandThing = new Shrinker(map.FindNearestWalkableTile(mousePosition) - new Vector2(moveCommandShrinkerSize / 2f, moveCommandShrinkerSize / 2f), moveCommandShrinkerSize, 10); moveCommandThing.Texture = moveCommandTexture; // create magic box Rectangle magicBox = SelectedUnits[0]; foreach (Unit unit in SelectedUnits) magicBox = Rectangle.Union(magicBox, unit.Rectangle); // box is too big or clicked inside magic box if (magicBox.Width > magicBoxMaxSize || magicBox.Height > magicBoxMaxSize || magicBox.Contains((int)mousePosition.X, (int)mousePosition.Y)) { //bool isPointWalkable = Unit.PathFinder.IsPointWalkable(mousePosition); // assign move targets to mouse position foreach (Unit unit in SelectedUnits) { // if mouse position is not in a walkable tile, find nearest walkable tile Vector2 destinationPoint; //if (isPointWalkable) if (Unit.PathFinder.IsPointWalkable(mousePosition, unit)) destinationPoint = mousePosition; else destinationPoint = map.FindNearestWalkableTile(mousePosition); // not holding shift if (keyboardState.IsKeyUp(Keys.LeftShift)) { //float distanceToDestination = Vector2.Distance(unit.CurrentPathNode.Tile.CenterPoint, destinationPoint); //if (distanceToDestination <= unit.Diameter) //unit.GiveCommand(new MoveCommand(destinationPoint, 1)); //else MoveCommand command = new MoveCommand(destinationPoint, 1); unit.GiveCommand(command); } // holding shift else { //float distanceBetweenCurrentAndNewMoveTarget = Vector2.Distance(unit.FinalMoveDestination, destinationPoint); //if (distanceBetweenCurrentAndNewMoveTarget <= unit.Diameter) // unit.QueueCommand(new MoveCommand(destinationPoint, 1)); //else MoveCommand command = new MoveCommand(destinationPoint, 1); unit.QueueCommand(command); //Unit.PathFinder.AddPathFindRequest(unit, command, unit.CurrentPathNode); } } } // clicked outside magic box else { // make destination box and keep in screen Rectangle destBox = magicBox; destBox.X = (int)mousePosition.X - destBox.Width / 2; destBox.Y = (int)mousePosition.Y - destBox.Height / 2; // calculate angle from magic box to destination box float angle = (float)Math.Atan2(destBox.Center.Y - magicBox.Center.Y, destBox.Center.X - magicBox.Center.X); float angleX = (float)Math.Cos(angle); float angleY = (float)Math.Sin(angle); float distance = Vector2.Distance(new Vector2(magicBox.Center.X, magicBox.Center.Y), new Vector2(destBox.Center.X, destBox.Center.Y)); // assign move targets based on angle foreach (Unit unit in SelectedUnits) { // if mouse position is not in a walkable tile, find nearest walkable tile Vector2 destinationPoint = unit.CenterPoint + new Vector2(distance * angleX, distance * angleY); if (!Unit.PathFinder.IsPointWalkable(destinationPoint, unit)) destinationPoint = map.FindNearestWalkableTile(destinationPoint); // not holding shift if (keyboardState.IsKeyUp(Keys.LeftShift)) { //float distanceToDestination = Vector2.Distance(unit.CurrentPathNode.Tile.CenterPoint, destinationPoint); //if (distanceToDestination <= unit.Diameter) // unit.GiveCommand(new MoveCommand(destinationPoint, 1)); //else MoveCommand command = new MoveCommand(destinationPoint, 1); unit.GiveCommand(command); //Unit.PathFinder.AddPathFindRequest(unit, command, unit.CurrentPathNode, 0, false); } // holding shift else { //float distanceBetweenCurrentAndNewMoveTarget = Vector2.Distance(unit.FinalMoveDestination, destinationPoint); //if (distanceBetweenCurrentAndNewMoveTarget <= unit.Diameter) // unit.QueueCommand(new MoveCommand(destinationPoint, 1)); //else unit.QueueCommand(new MoveCommand(destinationPoint, 1)); } } } }
/*// with attack target public void AddHighPriorityPathFindRequest(Unit unit, RtsObject attackTarget, MoveCommand command, PathNode startNode, int priority, bool avoidUnits) { command.Calculated = false; highPriorityRequestsToAdd.Enqueue(new PathFindRequest(unit, attackTarget, command, startNode, priority, avoidUnits)); }*/ // without attack target void addLowPriorityPathFindRequest(MoveCommand command, PathNode startNode, int priority, bool queued, bool avoidUnits) { command.Calculated = false; lowPriorityRequestsToAdd.Enqueue(new PathFindRequest(command, startNode, priority, queued, avoidUnits)); }
public void InsertCommand(MoveCommand command) { lastWayPoint = centerPoint; lastMoveDestination = command.Destination; timeSinceLastRecalculatePath = 0; IgnoringCollision = (command is HarvestCommand || command is ReturnCargoCommand); /*int commandPriority; if (command is ReturnCargoCommand || command is HarvestCommand) commandPriority = int.MaxValue / 2 + (int)Vector2.DistanceSquared(centerPoint, command.Destination); else commandPriority = (int)Vector2.DistanceSquared(centerPoint, command.Destination);*/ //if (Team == Player.Me.Team) Rts.pathFinder.AddPathFindRequest(command, false, false, false); Commands.Insert(0, command); }
// for move command. returns true if command ended bool checkForPush(MoveCommand command) { lock (PotentialCollisions) { foreach (Unit unit in PotentialCollisions) { if (Intersects(unit)) { if (timeSinceLastRecalculatePath >= recalculatePathDelay && command.Calculated) { timeSinceLastRecalculatePath = 0; PathFinder.AddLowPriorityPathFindRequest(this, command, CurrentPathNode, (int)Vector2.DistanceSquared(centerPoint, command.Destination), false); } float angle = (float)Math.Atan2(unit.centerPoint.Y - centerPoint.Y, unit.centerPoint.X - centerPoint.X); float distance = Radius + unit.Radius; float force = distance - Vector2.Distance(unit.centerPoint, centerPoint); if (unit.IsIdle && (unit.lastMoveDestination == command.Destination || unit.Contains(command.Destination))) { PushSimple(angle + (float)Math.PI, force); lastWayPoint = command.WayPoints[0]; command.NextWayPoint(this, PathFinder); if (command.WayPoints.Count == 0) { nextCommand(); return true; } } else if (unit.lastMoveDestination == command.Destination && unit.Contains(command.Destination)) { PushSimple(angle + (float)Math.PI, force); lastWayPoint = command.WayPoints[0]; command.NextWayPoint(this, PathFinder); if (command.WayPoints.Count == 0) { nextCommand(); return true; } } else if (Contains(command.Destination)) { PushSimple(angle + (float)Math.PI, force); lastWayPoint = command.WayPoints[0]; command.NextWayPoint(this, PathFinder); if (command.WayPoints.Count == 0) { nextCommand(); return true; } } /*if (unit.isFollowing && unit.followTarget == this) { unit.Push(this, angle, force); } else if (isFollowing && unit == followTarget) { PushSimple(angle + (float)Math.PI, force); } else*/ { //pushCount++; float sizeRatio = this.Diameter / unit.Diameter; float pushForce = force * (.1f * sizeRatio); unit.Push(this, angle, pushForce); PushSimple(angle + (float)Math.PI, force - pushForce); //unit.Push(this, angle, force * .1f); //PushSimple(angle + (float)Math.PI, force * .9f); } } } } return false; }
public void QueueCommand(MoveCommand command) { if (Commands.Count == 0) GiveCommand(command); else { //MoveCommand previousMoveCommand = Commands[Commands.Count - 1] as MoveCommand; //if (previousMoveCommand != null) // command.WayPoints.Insert(0, previousMoveCommand.Destination); Commands.Add(command); } }
void Move(MoveCommand command, GameTime gameTime) { timeSinceLastSmoothPath += (int)gameTime.ElapsedGameTime.TotalMilliseconds; if (timeSinceLastSmoothPath >= smoothPathDelay) { timeSinceLastSmoothPath = 0; PathFinder.SmoothImmediatePath(command.WayPoints, this); } clearPushStatus(); clearHitWallStatus(); Vector2 wayPoint = command.WayPoints[0]; float moveX = Util.ScaleWithGameTime(speed.X, gameTime); float moveY = Util.ScaleWithGameTime(speed.Y, gameTime); if (command.WayPoints.Count > 1) { if (Contains(wayPoint)) { lastWayPoint = wayPoint; command.NextWayPoint(this, PathFinder); return; } } else { Vector2 difference = wayPoint - centerPoint; if (Math.Abs(difference.X) < moveX && Math.Abs(difference.Y) < moveY) { this.CenterPoint = wayPoint; lastWayPoint = wayPoint; //command.NextWayPoint(this, PathFinder); //if (command.WayPoints.Count == 0) nextCommand(); return; } } float angle = (float)Math.Atan2(wayPoint.Y - CenterPoint.Y, wayPoint.X - CenterPoint.X); moveX *= (float)Math.Cos(angle); moveY *= (float)Math.Sin(angle); lastMove.X = moveX; lastMove.Y = moveY; PrecisePosition += lastMove; checkForWallHit(); if (checkForPush(command)) return; turnTowards(wayPoint, 120 / Radius, gameTime); }
void processUnitMoveCommandBatch(NetIncomingMessage msg) { float scheduledTime = msg.ReadFloat(); short team = msg.ReadInt16(); bool queued = msg.ReadBoolean(); short numberOfCommands = msg.ReadInt16(); for (int i = 0; i < numberOfCommands; i++) { short unitID = msg.ReadInt16(); Unit unit = Player.Players[team].UnitArray[unitID]; Vector2 destination = new Vector2(msg.ReadFloat(), msg.ReadFloat()); if (unit != null) { MoveCommand moveCommand = new MoveCommand(unit, destination); Player.Players[team].ScheduledActions.Add(new ScheduledUnitCommand(scheduledTime, moveCommand, queued)); //Rts.pathFinder.AddHighPriorityPathFindRequest(moveCommand, (int)Vector2.DistanceSquared(moveCommand.Unit.CenterPoint, moveCommand.Destination), false); } else { int wut = 0; } } }
public void AddLowPriorityPathFindRequest(Unit unit, MoveCommand command, PathNode startNode, int priority, bool avoidUnits) { command.Calculated = false; lowPriorityRequestsToAdd.Enqueue(new PathFindRequest(unit, command, startNode, priority, avoidUnits)); }