示例#1
0
            public bool CanTarget(Actor self, Target target, List <Actor> othersAtTarget, TargetModifiers modifiers, ref string cursor)
            {
                if (rejectMove || !target.IsValidFor(self))
                {
                    return(false);
                }

                var location = self.World.Map.CellContaining(target.CenterPosition);

                IsQueued = modifiers.HasModifier(TargetModifiers.ForceQueue);
                cursor   = "move";

                if (self.Owner.Shroud.IsExplored(location))
                {
                    cursor = self.World.Map.GetTerrainInfo(location).CustomCursor ?? cursor;
                }

                if (!self.World.Map.Contains(location) || (self.Owner.Shroud.IsExplored(location) &&
                                                           unitType.MovementCostForCell(self.World, location) == int.MaxValue))
                {
                    cursor = "move-blocked";
                }

                return(true);
            }
示例#2
0
            public bool CanTargetLocation(Actor self, int2 location, List <Actor> actorsAtLocation, bool forceAttack, bool forceQueued, ref string cursor)
            {
                IsQueued = forceQueued;
                cursor   = "move";
                if (!self.World.Map.IsInMap(location) || (self.World.LocalPlayer.Shroud.IsExplored(location) &&
                                                          unitType.MovementCostForCell(self.World, location) == int.MaxValue))
                {
                    cursor = "move-blocked";
                }

                return(true);
            }
示例#3
0
            public bool CanTargetLocation(Actor self, CPos location, List <Actor> actorsAtLocation, bool forceAttack, bool forceQueued, ref string cursor)
            {
                IsQueued = forceQueued;
                cursor   = "move";

                if (self.Owner.Shroud.IsExplored(location))
                {
                    cursor = self.World.GetTerrainInfo(location).CustomCursor ?? cursor;
                }

                if (!self.World.Map.IsInMap(location) || (self.Owner.Shroud.IsExplored(location) &&
                                                          unitType.MovementCostForCell(self.World, location) == int.MaxValue))
                {
                    cursor = "move-blocked";
                }

                return(true);
            }
示例#4
0
        public CPos Expand(World world)
        {
            var p = Queue.Pop();

            while (CellInfo[p.Location].Seen)
            {
                if (Queue.Empty)
                {
                    return(p.Location);
                }

                p = Queue.Pop();
            }

            var pCell = CellInfo[p.Location];

            pCell.Seen           = true;
            CellInfo[p.Location] = pCell;

            var thisCost = mobileInfo.MovementCostForCell(world, p.Location);

            if (thisCost == int.MaxValue)
            {
                return(p.Location);
            }

            if (customCost != null)
            {
                var c = customCost(p.Location);
                if (c == int.MaxValue)
                {
                    return(p.Location);
                }
            }

            // This current cell is ok; check all immediate directions:
            Considered.Add(p.Location);

            for (var i = 0; i < nextDirections.Length; ++i)
            {
                var d = nextDirections[i].First;
                nextDirections[i].Second = int.MaxValue;

                var newHere = p.Location + d;

                // Is this direction flat-out unusable or already seen?
                if (!world.Map.Contains(newHere))
                {
                    continue;
                }

                if (CellInfo[newHere].Seen)
                {
                    continue;
                }

                // Now we may seriously consider this direction using heuristics:
                var costHere = mobileInfo.MovementCostForCell(world, newHere);

                if (costHere == int.MaxValue)
                {
                    continue;
                }

                if (!mobileInfo.CanEnterCell(world, self, newHere, IgnoreBuilding, CheckForBlocked ? CellConditions.TransientActors : CellConditions.None))
                {
                    continue;
                }

                if (customBlock != null && customBlock(newHere))
                {
                    continue;
                }

                var est = Heuristic(newHere);
                if (est == int.MaxValue)
                {
                    continue;
                }

                var cellCost = costHere;
                if (d.X * d.Y != 0)
                {
                    cellCost = (cellCost * 34) / 24;
                }

                var userCost = 0;
                if (customCost != null)
                {
                    userCost  = customCost(newHere);
                    cellCost += userCost;
                }

                // directional bonuses for smoother flow!
                if (laneBias != 0)
                {
                    var ux = newHere.X + (InReverse ? 1 : 0) & 1;
                    var uy = newHere.Y + (InReverse ? 1 : 0) & 1;

                    if (ux == 0 && d.Y < 0)
                    {
                        cellCost += laneBias;
                    }
                    else if (ux == 1 && d.Y > 0)
                    {
                        cellCost += laneBias;
                    }

                    if (uy == 0 && d.X < 0)
                    {
                        cellCost += laneBias;
                    }
                    else if (uy == 1 && d.X > 0)
                    {
                        cellCost += laneBias;
                    }
                }

                var newCost = CellInfo[p.Location].MinCost + cellCost;

                // Cost is even higher; next direction:
                if (newCost > CellInfo[newHere].MinCost)
                {
                    continue;
                }

                var hereCell = CellInfo[newHere];
                hereCell.Path     = p.Location;
                hereCell.MinCost  = newCost;
                CellInfo[newHere] = hereCell;

                nextDirections[i].Second = newCost + est;
                Queue.Add(new PathDistance(newCost + est, newHere));

                if (newCost > MaxCost)
                {
                    MaxCost = newCost;
                }

                Considered.Add(newHere);
            }

            // Sort to prefer the cheaper direction:
            // Array.Sort(nextDirections, (a, b) => a.Second.CompareTo(b.Second));
            return(p.Location);
        }
示例#5
0
        public CPos Expand(World world)
        {
            var p = queue.Pop();

            while (cellInfo[p.Location.X, p.Location.Y].Seen)
            {
                if (queue.Empty)
                {
                    return(p.Location);
                }
                else
                {
                    p = queue.Pop();
                }
            }

            cellInfo[p.Location.X, p.Location.Y].Seen = true;

            var thisCost = mobileInfo.MovementCostForCell(world, p.Location);

            if (thisCost == int.MaxValue)
            {
                return(p.Location);
            }

            if (customCost != null)
            {
                int c = customCost(p.Location);
                if (c == int.MaxValue)
                {
                    return(p.Location);
                }
            }

            // This current cell is ok; check all immediate directions:
            considered.Add(p.Location);

            for (int i = 0; i < nextDirections.Length; ++i)
            {
                CVec d = nextDirections[i].First;
                nextDirections[i].Second = int.MaxValue;

                CPos newHere = p.Location + d;

                // Is this direction flat-out unusable or already seen?
                if (!world.Map.IsInMap(newHere.X, newHere.Y))
                {
                    continue;
                }
                if (cellInfo[newHere.X, newHere.Y].Seen)
                {
                    continue;
                }

                // Now we may seriously consider this direction using heuristics:
                var costHere = mobileInfo.MovementCostForCell(world, newHere);

                if (costHere == int.MaxValue)
                {
                    continue;
                }

                if (!mobileInfo.CanEnterCell(world, self, newHere, ignoreBuilding, checkForBlocked, false))
                {
                    continue;
                }

                if (customBlock != null && customBlock(newHere))
                {
                    continue;
                }

                var est = heuristic(newHere);
                if (est == int.MaxValue)
                {
                    continue;
                }

                int cellCost = costHere;
                if (d.X * d.Y != 0)
                {
                    cellCost = (cellCost * 34) / 24;
                }

                int userCost = 0;
                if (customCost != null)
                {
                    userCost  = customCost(newHere);
                    cellCost += userCost;
                }

                // directional bonuses for smoother flow!
                if (LaneBias != 0)
                {
                    var ux = (newHere.X + (inReverse ? 1 : 0) & 1);
                    var uy = (newHere.Y + (inReverse ? 1 : 0) & 1);

                    if (ux == 0 && d.Y < 0)
                    {
                        cellCost += LaneBias;
                    }
                    else if (ux == 1 && d.Y > 0)
                    {
                        cellCost += LaneBias;
                    }
                    if (uy == 0 && d.X < 0)
                    {
                        cellCost += LaneBias;
                    }
                    else if (uy == 1 && d.X > 0)
                    {
                        cellCost += LaneBias;
                    }
                }

                int newCost = cellInfo[p.Location.X, p.Location.Y].MinCost + cellCost;

                // Cost is even higher; next direction:
                if (newCost > cellInfo[newHere.X, newHere.Y].MinCost)
                {
                    continue;
                }

                cellInfo[newHere.X, newHere.Y].Path    = p.Location;
                cellInfo[newHere.X, newHere.Y].MinCost = newCost;

                nextDirections[i].Second = newCost + est;
                queue.Add(new PathDistance(newCost + est, newHere));

                if (newCost > maxCost)
                {
                    maxCost = newCost;
                }
                considered.Add(newHere);
            }

            // Sort to prefer the cheaper direction:
            //Array.Sort(nextDirections, (a, b) => a.Second.CompareTo(b.Second));

            return(p.Location);
        }
示例#6
0
        public CPos Expand(World world)
        {
            var p = queue.Pop();

            while (cellInfo[p.Location.X, p.Location.Y].Seen)
            {
                if (queue.Empty)
                {
                    return(p.Location);
                }
                else
                {
                    p = queue.Pop();
                }
            }

            cellInfo[p.Location.X, p.Location.Y].Seen = true;

            var thisCost = mobileInfo.MovementCostForCell(world, p.Location);

            if (thisCost == int.MaxValue)
            {
                return(p.Location);
            }

            if (customCost != null)
            {
                int c = customCost(p.Location);
                if (c == int.MaxValue)
                {
                    return(p.Location);
                }
            }

            foreach (CVec d in directions)
            {
                CPos newHere = p.Location + d;

                if (!world.Map.IsInMap(newHere.X, newHere.Y))
                {
                    continue;
                }
                if (cellInfo[newHere.X, newHere.Y].Seen)
                {
                    continue;
                }

                var costHere = mobileInfo.MovementCostForCell(world, newHere);

                if (costHere == int.MaxValue)
                {
                    continue;
                }

                if (!mobileInfo.CanEnterCell(world, self, newHere, ignoreBuilding, checkForBlocked, false))
                {
                    continue;
                }

                if (customBlock != null && customBlock(newHere))
                {
                    continue;
                }

                var est = heuristic(newHere);
                if (est == int.MaxValue)
                {
                    continue;
                }

                int cellCost = costHere;
                if (d.X * d.Y != 0)
                {
                    cellCost = (cellCost * 34) / 24;
                }

                if (customCost != null)
                {
                    cellCost += customCost(newHere);
                }

                // directional bonuses for smoother flow!
                if (LaneBias != 0)
                {
                    var ux = (newHere.X + (inReverse ? 1 : 0) & 1);
                    var uy = (newHere.Y + (inReverse ? 1 : 0) & 1);

                    if (ux == 0 && d.Y < 0)
                    {
                        cellCost += LaneBias;
                    }
                    else if (ux == 1 && d.Y > 0)
                    {
                        cellCost += LaneBias;
                    }
                    if (uy == 0 && d.X < 0)
                    {
                        cellCost += LaneBias;
                    }
                    else if (uy == 1 && d.X > 0)
                    {
                        cellCost += LaneBias;
                    }
                }

                int newCost = cellInfo[p.Location.X, p.Location.Y].MinCost + cellCost;

                if (newCost >= cellInfo[newHere.X, newHere.Y].MinCost)
                {
                    continue;
                }

                cellInfo[newHere.X, newHere.Y].Path    = p.Location;
                cellInfo[newHere.X, newHere.Y].MinCost = newCost;

                queue.Add(new PathDistance(newCost + est, newHere));
            }
            return(p.Location);
        }