コード例 #1
0
ファイル: PathFinder.cs プロジェクト: nubington/rts
        // 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);
            }
        }
コード例 #2
0
ファイル: Unit.cs プロジェクト: nubington/rts
        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;
            }
        }
コード例 #3
0
ファイル: Unit.cs プロジェクト: nubington/rts
        /*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);
            }
        }
コード例 #4
0
ファイル: Unit.cs プロジェクト: nubington/rts
        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;
        }
コード例 #5
0
ファイル: Unit.cs プロジェクト: nubington/rts
 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);
     }
 }
コード例 #6
0
ファイル: Unit.cs プロジェクト: nubington/rts
        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);
        }
コード例 #7
0
ファイル: PathFinder.cs プロジェクト: nubington/rts
        // 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));
        }
コード例 #8
0
ファイル: Unit.cs プロジェクト: nubington/rts
        // 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;
        }
コード例 #9
0
ファイル: Structure.cs プロジェクト: nubington/rts
        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();
                }
            }
        }
コード例 #10
0
        /*// 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));
        }
コード例 #11
0
        // 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);
        }
コード例 #12
0
        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);
             *      }
             *  }
             * }*/
        }
コード例 #13
0
ファイル: Rts.cs プロジェクト: nubington/rts
        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));
                    }
                }
            }
        }
コード例 #14
0
ファイル: PathFinder.cs プロジェクト: nubington/rts
 /*// 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));
 }
コード例 #15
0
ファイル: Unit.cs プロジェクト: nubington/rts
        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);
        }
コード例 #16
0
ファイル: Unit.cs プロジェクト: nubington/rts
        // 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;
        }
コード例 #17
0
ファイル: Unit.cs プロジェクト: nubington/rts
 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);
     }
 }
コード例 #18
0
ファイル: Unit.cs プロジェクト: nubington/rts
        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);
        }
コード例 #19
0
ファイル: Rts Networking.cs プロジェクト: nubington/rts
        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;
                }
            }
        }
コード例 #20
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));
 }