Exemple #1
0
        public void Existing_path() {
            g.Insert(new Edge{v = 0, w = 1});
            g.Insert(new Edge{v = 1, w = 2});
            g.Insert(new Edge{v = 2, w = 3});

            var path = new PathSearch(g, 0, 3);
            Assert.That(path.Exists, Is.True);
        }
Exemple #2
0
		public static PathSearch Search(World world, MobileInfo mi, Actor self, bool checkForBlocked)
		{
			var search = new PathSearch(world, mi, self)
			{
				CheckForBlocked = checkForBlocked
			};

			return search;
		}
Exemple #3
0
		public static PathSearch FromPoint(World world, MobileInfo mi, Actor self, CPos from, CPos target, bool checkForBlocked)
		{
			var search = new PathSearch(world, mi, self)
			{
				Heuristic = DefaultEstimator(target),
				CheckForBlocked = checkForBlocked
			};

			search.AddInitialCell(from);
			return search;
		}
Exemple #4
0
		public static PathSearch FromPoints(World world, MobileInfo mi, Actor self, IEnumerable<CPos> froms, CPos target, bool checkForBlocked)
		{
			var search = new PathSearch(world, mi, self)
			{
				Heuristic = DefaultEstimator(target),
				CheckForBlocked = checkForBlocked
			};

			foreach (var sl in froms)
				search.AddInitialCell(sl);

			return search;
		}
Exemple #5
0
        public void Path_with_circles() {
            g.Insert(new Edge{v = 0, w = 1});
            g.Insert(new Edge{v = 1, w = 2});
            g.Insert(new Edge{v = 2, w = 3});
            
            g.Insert(new Edge{v = 1, w = 0});
            g.Insert(new Edge{v = 2, w = 0});
            g.Insert(new Edge{v = 3, w = 0});

            // g.ShowGraph();

            var path = new PathSearch(g, 0, 3);
            Assert.That(path.Exists, Is.True);
        }
    void Start()
    {
        selectedTileIndex = 0;

        TGMap tempMap = (TGMap)FindObjectOfType(typeof(TGMap));

        tileSizeX = tempMap.size_x;

        myPathSearch   = GetComponent <PathSearch>();
        pathSolution   = new List <TDTile>();
        pathMarkerList = new List <GameObject>();

        Component selectedTile = transform.FindChild("SelectedTile");

        selectedTile.GetComponent <Renderer>().enabled = false;

        showMarker    = false;
        moveCharacter = false;
    }
Exemple #7
0
        Actor ClosestProc(Actor self, Actor ignore)
        {
            // Find all refineries and their occupancy count:
            var refs = (
                from r in self.World.ActorsWithTrait <IAcceptOre>()
                where r.Actor != ignore && r.Actor.Owner == self.Owner
                let linkedHarvs = self.World.ActorsWithTrait <Harvester>().Where(a => a.Trait.LinkedProc == r.Actor).Count()
                                  select new { Location = r.Actor.Location + r.Trait.DeliverOffset, Actor = r.Actor, Occupancy = linkedHarvs }
                ).ToDictionary(r => r.Location);

            // Start a search from each refinery's delivery location:
            var mi   = self.Info.Traits.Get <MobileInfo>();
            var path = self.World.WorldActor.Trait <PathFinder>().FindPath(
                PathSearch.FromPoints(self.World, mi, self, refs.Values.Select(r => r.Location), self.Location, false)
                .WithCustomCost((loc) =>
            {
                if (!refs.ContainsKey(loc))
                {
                    return(0);
                }

                int occupancy = refs[loc].Occupancy;
                // 4 harvesters clogs up the refinery's delivery location:
                if (occupancy >= 3)
                {
                    return(int.MaxValue);
                }

                // Prefer refineries with less occupancy (multiplier is to offset distance cost):
                return(occupancy * 12);
            })
                );

            // Reverse the found-path to find the refinery location instead of our location:
            path.Reverse();

            if (path.Count != 0)
            {
                return(refs[path[0]].Actor);
            }

            return(null);
        }
Exemple #8
0
    private void HandleMove()
    {
        if (!Input.GetMouseButtonDown(0))
        {
            return;
        }

        var cameraRay = Camera.main.ScreenPointToRay(Input.mousePosition);

        if (Physics.Raycast(cameraRay, out RaycastHit hitInfo, 100, LayerMask.GetMask("Floor")))
        {
            var search = new PathSearch(transform.position, hitInfo.point, MapObj.Air | MapObj.Enemy);
            var path   = search.Solve();
            if (path != null && path.Count > 1)
            {
                StartCoroutine(SmoothMove(path));
            }
        }
    }
Exemple #9
0
        public Actor ClosestProc(Actor self, Actor ignore)
        {
            // Find all refineries and their occupancy count:
            var refineries = self.World.ActorsWithTrait <IAcceptResources>()
                             .Where(r => r.Actor != ignore && r.Actor.Owner == self.Owner && IsAcceptableProcType(r.Actor))
                             .Select(r => new
            {
                Location  = r.Actor.Location + r.Trait.DeliveryOffset,
                Actor     = r.Actor,
                Occupancy = self.World.ActorsHavingTrait <Harvester>(h => h.LinkedProc == r.Actor).Count()
            }).ToLookup(r => r.Location);

            // Start a search from each refinery's delivery location:
            List <CPos> path;

            using (var search = PathSearch.FromPoints(self.World, mobile.Locomotor, self, refineries.Select(r => r.Key), self.Location, BlockedByActor.None)
                                .WithCustomCost(location =>
            {
                if (!refineries.Contains(location))
                {
                    return(0);
                }

                var occupancy = refineries[location].First().Occupancy;

                // Too many harvesters clogs up the refinery's delivery location:
                if (occupancy >= Info.MaxUnloadQueue)
                {
                    return(PathGraph.CostForInvalidCell);
                }

                // Prefer refineries with less occupancy (multiplier is to offset distance cost):
                return(occupancy * Info.UnloadQueueCostModifier);
            }))
                path = mobile.Pathfinder.FindPath(search);

            if (path.Count != 0)
            {
                return(refineries[path.Last()].First().Actor);
            }

            return(null);
        }
Exemple #10
0
        public List <CPos> FindUnitPath(CPos source, CPos target, Actor self, Actor ignoreActor, BlockedByActor check)
        {
            // PERF: Because we can be sure that OccupiesSpace is Mobile here, we can save some performance by avoiding querying for the trait.
            var locomotor = ((Mobile)self.OccupiesSpace).Locomotor;

            if (!cached)
            {
                domainIndex = world.WorldActor.TraitOrDefault <DomainIndex>();
                cached      = true;
            }

            // If a water-land transition is required, bail early
            if (domainIndex != null && !domainIndex.IsPassable(source, target, locomotor.Info))
            {
                return(EmptyPath);
            }

            var distance      = source - target;
            var canMoveFreely = locomotor.CanMoveFreelyInto(self, target, check, null);

            if (distance.LengthSquared < 3 && !canMoveFreely)
            {
                return new List <CPos> {
                }
            }
            ;

            if (source.Layer == target.Layer && distance.LengthSquared < 3 && canMoveFreely)
            {
                return new List <CPos> {
                           target
                }
            }
            ;

            List <CPos> pb;

            using (var fromSrc = PathSearch.FromPoint(world, locomotor, self, target, source, check).WithIgnoredActor(ignoreActor))
                using (var fromDest = PathSearch.FromPoint(world, locomotor, self, source, target, check).WithIgnoredActor(ignoreActor).Reverse())
                    pb = FindBidiPath(fromSrc, fromDest);

            return(pb);
        }
Exemple #11
0
        public List <CPos> FindUnitPath(CPos source, CPos target, Actor self, Actor ignoreActor, BlockedByActor check)
        {
            var mobile    = self.Trait <Mobile>();
            var locomotor = mobile.Locomotor;

            if (!cached)
            {
                domainIndex = world.WorldActor.TraitOrDefault <DomainIndex>();
                cached      = true;
            }

            // If a water-land transition is required, bail early
            if (domainIndex != null && !domainIndex.IsPassable(source, target, locomotor.Info))
            {
                return(EmptyPath);
            }

            var distance      = source - target;
            var canMoveFreely = locomotor.CanMoveFreelyInto(self, target, check, null);

            if (distance.LengthSquared < 3 && !canMoveFreely)
            {
                return new List <CPos> {
                }
            }
            ;

            if (source.Layer == target.Layer && distance.LengthSquared < 3 && canMoveFreely)
            {
                return new List <CPos> {
                           target
                }
            }
            ;

            List <CPos> pb;

            using (var fromSrc = PathSearch.FromPoint(world, locomotor, self, target, source, check).WithIgnoredActor(ignoreActor))
                using (var fromDest = PathSearch.FromPoint(world, locomotor, self, source, target, check).WithIgnoredActor(ignoreActor).Reverse())
                    pb = FindBidiPath(fromSrc, fromDest);

            return(pb);
        }
Exemple #12
0
        // Scriptable move order
        // Ignores lane bias and nearby units
        public Move(Actor self, CPos destination, Color?targetLineColor = null)
        {
            // PERF: Because we can be sure that OccupiesSpace is Mobile here, we can save some performance by avoiding querying for the trait.
            mobile = (Mobile)self.OccupiesSpace;

            getPath = check =>
            {
                List <CPos> path;
                using (var search =
                           PathSearch.FromPoint(self.World, mobile.Locomotor, self, mobile.ToCell, destination, check)
                           .WithoutLaneBias())
                    path = mobile.Pathfinder.FindPath(search);
                return(path);
            };

            this.destination     = destination;
            this.targetLineColor = targetLineColor;
            nearEnough           = WDist.Zero;
        }
Exemple #13
0
        public List <CPos> FindUnitPathToRange(CPos source, SubCell srcSub, WPos target, WDist range, Actor self, BlockedByActor check)
        {
            if (!cached)
            {
                domainIndex = world.WorldActor.TraitOrDefault <DomainIndex>();

                cached = true;
            }

            // PERF: Because we can be sure that OccupiesSpace is Mobile here, we can save some performance by avoiding querying for the trait.
            var mobile    = (Mobile)self.OccupiesSpace;
            var locomotor = mobile.Locomotor;

            var targetCell = world.Map.CellContaining(target);

            // Correct for SubCell offset
            target -= world.Map.Grid.OffsetOfSubCell(srcSub);

            var rangeLengthSquared = range.LengthSquared;
            var map = world.Map;

            // Select only the tiles that are within range from the requested SubCell
            // This assumes that the SubCell does not change during the path traversal
            var tilesInRange = map.FindTilesInCircle(targetCell, range.Length / 1024 + 1)
                               .Where(t => (map.CenterOfCell(t) - target).LengthSquared <= rangeLengthSquared &&
                                      mobile.Info.CanEnterCell(world, self, t));

            // See if there is any cell within range that does not involve a cross-domain request
            // Really, we only need to check the circle perimeter, but it's not clear that would be a performance win
            if (domainIndex != null)
            {
                tilesInRange = new List <CPos>(tilesInRange.Where(t => domainIndex.IsPassable(source, t, locomotor)));
                if (!tilesInRange.Any())
                {
                    return(EmptyPath);
                }
            }

            using (var fromSrc = PathSearch.FromPoints(world, locomotor, self, tilesInRange, source, check))
                using (var fromDest = PathSearch.FromPoint(world, locomotor, self, source, targetCell, check).Reverse())
                    return(FindBidiPath(fromSrc, fromDest));
        }
        public Actor ClosestDestination(Actor self)
        {
            var refineries = self.World.ActorsWithTrait <AcceptsDeliveredResources>()
                             .Where(r => r.Actor.Owner == self.Owner);

            List <CPos> path;

            using (var search = PathSearch.FromPoints(self.World, mobile.Locomotor, self, refineries.Select(r => r.Actor.Location), self.Location, BlockedByActor.None)
                                .WithCustomCost(loc => self.World.FindActorsInCircle(self.World.Map.CenterOfCell(loc), Info.EnemyAvoidanceRadius)
                                                .Where(u => !u.IsDead && self.Owner.Stances[u.Owner] == Stance.Enemy)
                                                .Sum(u => Math.Max(WDist.Zero.Length, Info.EnemyAvoidanceRadius.Length - (self.World.Map.CenterOfCell(loc) - u.CenterPosition).Length))))
                path = self.World.WorldActor.Trait <IPathFinder>().FindPath(search);

            if (path.Count != 0)
            {
                return(refineries.First(r => r.Actor.Location == path.Last()).Actor);
            }

            return(null);
        }
        public Actor ClosestDestination(Actor self)
        {
            var actors = string.IsNullOrEmpty(ResourceType)
                         ? self.World.ActorsHavingTrait <ResourceCollector>().Where(r => r.Owner == self.Owner)
                         : self.World.ActorsHavingTrait <AcceptsDeliveredResources>().Where(r => r.Owner == self.Owner);

            List <CPos> path;

            using (var search = PathSearch.FromPoints(self.World, mobile.Locomotor, self, actors.Select(a => a.Location), self.Location, BlockedByActor.None)
                                .WithCustomCost(loc => self.World.FindActorsInCircle(self.World.Map.CenterOfCell(loc), Info.EnemyAvoidanceRadius)
                                                .Where(u => !u.IsDead && self.Owner.RelationshipWith(u.Owner) == PlayerRelationship.Enemy)
                                                .Sum(u => Math.Max(WDist.Zero.Length, Info.EnemyAvoidanceRadius.Length - (self.World.Map.CenterOfCell(loc) - u.CenterPosition).Length))))
                path = self.World.WorldActor.Trait <IPathFinder>().FindPath(search);

            if (path.Count != 0)
            {
                return(actors.First(r => r.Location == path.Last()));
            }

            return(null);
        }
Exemple #16
0
        CPos FindNextResource(Actor harvester)
        {
            var harvInfo   = harvester.Info.TraitInfo <HarvesterInfo>();
            var mobileInfo = harvester.Info.TraitInfo <MobileInfo>();
            var passable   = (uint)mobileInfo.GetMovementClass(World.Map.Rules.TileSet);

            var path = pathfinder.FindPath(
                PathSearch.Search(World, mobileInfo, harvester, true,
                                  loc => domainIndex.IsPassable(harvester.Location, loc, passable) && harvester.CanHarvestAt(loc, resLayer, harvInfo, territory))
                .WithCustomCost(loc => World.FindActorsInCircle(World.Map.CenterOfCell(loc), Info.HarvesterEnemyAvoidanceRadius)
                                .Where(u => !u.IsDead && harvester.Owner.Stances[u.Owner] == Stance.Enemy)
                                .Sum(u => Math.Max(WDist.Zero.Length, Info.HarvesterEnemyAvoidanceRadius.Length - (World.Map.CenterOfCell(loc) - u.CenterPosition).Length)))
                .FromPoint(harvester.Location));

            if (path.Count == 0)
            {
                return(CPos.Zero);
            }

            return(path[0]);
        }
Exemple #17
0
        Target FindNextResource(Actor actor, HarvesterTraitWrapper harv)
        {
            Func <CPos, bool> isValidResource = cell =>
                                                domainIndex.IsPassable(actor.Location, cell, harv.Locomotor) &&
                                                harv.Harvester.CanHarvestCell(actor, cell) &&
                                                claimLayer.CanClaimCell(actor, cell);

            var path = pathfinder.FindPath(
                PathSearch.Search(world, harv.Locomotor, actor, BlockedByActor.Stationary, isValidResource)
                .WithCustomCost(loc => world.FindActorsInCircle(world.Map.CenterOfCell(loc), Info.HarvesterEnemyAvoidanceRadius)
                                .Where(u => !u.IsDead && actor.Owner.RelationshipWith(u.Owner) == PlayerRelationship.Enemy)
                                .Sum(u => Math.Max(WDist.Zero.Length, Info.HarvesterEnemyAvoidanceRadius.Length - (world.Map.CenterOfCell(loc) - u.CenterPosition).Length)))
                .FromPoint(actor.Location));

            if (path.Count == 0)
            {
                return(Target.Invalid);
            }

            return(Target.FromCell(world, path[0]));
        }
Exemple #18
0
        CPos FindNextResource(Actor actor, Harvester harv)
        {
            var mobileInfo = actor.Info.TraitInfo <MobileInfo>();
            var passable   = (uint)mobileInfo.GetMovementClass(World.Map.Rules.TileSet);

            Func <CPos, bool> isValidResource = cell =>
                                                domainIndex.IsPassable(actor.Location, cell, mobileInfo, passable) &&
                                                harv.CanHarvestCell(actor, cell) &&
                                                claimLayer.CanClaimCell(actor, cell);
            var path = pathfinder.FindPath(
                PathSearch.Search(World, mobileInfo, actor, true, isValidResource)
                .WithCustomCost(loc => World.FindActorsInCircle(World.Map.CenterOfCell(loc), Info.HarvesterEnemyAvoidanceRadius)
                                .Where(u => !u.IsDead && actor.Owner.Stances[u.Owner] == Stance.Enemy)
                                .Sum(u => Math.Max(WDist.Zero.Length, Info.HarvesterEnemyAvoidanceRadius.Length - (World.Map.CenterOfCell(loc) - u.CenterPosition).Length))).FromPoint(actor.Location));

            if (path.Count == 0)
            {
                return(CPos.Zero);
            }
            return(path[0]);
        }
Exemple #19
0
        public List <CPos> FindUnitPathToRange(CPos source, SubCell srcSub, WPos target, WDist range, Actor self)
        {
            if (!cached)
            {
                domainIndex = world.WorldActor.TraitOrDefault <DomainIndex>();

                cached = true;
            }

            var mobile     = self.Trait <Mobile>();
            var mi         = mobile.Info;
            var li         = mi.LocomotorInfo;
            var targetCell = world.Map.CellContaining(target);

            // Correct for SubCell offset
            target -= world.Map.Grid.OffsetOfSubCell(srcSub);

            // Select only the tiles that are within range from the requested SubCell
            // This assumes that the SubCell does not change during the path traversal
            var tilesInRange = world.Map.FindTilesInCircle(targetCell, range.Length / 1024 + 1)
                               .Where(t => (world.Map.CenterOfCell(t) - target).LengthSquared <= range.LengthSquared &&
                                      mi.CanEnterCell(self.World, self, t));

            // See if there is any cell within range that does not involve a cross-domain request
            // Really, we only need to check the circle perimeter, but it's not clear that would be a performance win
            if (domainIndex != null)
            {
                tilesInRange = new List <CPos>(tilesInRange.Where(t => domainIndex.IsPassable(source, t, li)));
                if (!tilesInRange.Any())
                {
                    return(EmptyPath);
                }
            }

            var locomotor = mobile.Locomotor;

            using (var fromSrc = PathSearch.FromPoints(world, locomotor, self, tilesInRange, source, true))
                using (var fromDest = PathSearch.FromPoint(world, locomotor, self, source, targetCell, true).Reverse())
                    return(FindBidiPath(fromSrc, fromDest));
        }
Exemple #20
0
        public Actor ClosestProc(Actor self, Actor ignore)
        {
            // Find all refineries and their occupancy count:
            var refs = (
                from r in self.World.ActorsWithTrait <IAcceptResources>()
                where r.Actor != ignore && r.Actor.Owner == self.Owner && IsAcceptableProcType(r.Actor)
                let linkedHarvs = self.World.ActorsWithTrait <Harvester>().Count(a => a.Trait.LinkedProc == r.Actor)
                                  select new { Location = r.Actor.Location + r.Trait.DeliveryOffset, Actor = r.Actor, Occupancy = linkedHarvs }).ToDictionary(r => r.Location);

            // Start a search from each refinery's delivery location:
            var mi   = self.Info.Traits.Get <MobileInfo>();
            var path = self.World.WorldActor.Trait <IPathFinder>().FindPath(
                PathSearch.FromPoints(self.World, mi, self, refs.Values.Select(r => r.Location), self.Location, false)
                .WithCustomCost(loc =>
            {
                if (!refs.ContainsKey(loc))
                {
                    return(0);
                }

                var occupancy = refs[loc].Occupancy;

                // 4 harvesters clogs up the refinery's delivery location:
                if (occupancy >= 3)
                {
                    return(Constants.InvalidNode);
                }

                // Prefer refineries with less occupancy (multiplier is to offset distance cost):
                return(occupancy * 12);
            }));

            if (path.Count != 0)
            {
                return(refs[path.Last()].Actor);
            }

            return(null);
        }
Exemple #21
0
        public List<CPos> FindUnitPath(CPos source, CPos target, Actor self, Actor ignoreActor)
        {
            var li = self.Info.TraitInfo<MobileInfo>().LocomotorInfo;

            // If a water-land transition is required, bail early
            var domainIndex = world.WorldActor.TraitOrDefault<DomainIndex>();
            if (domainIndex != null && !domainIndex.IsPassable(source, target, li))
                return EmptyPath;

            var distance = source - target;
            if (distance.LengthSquared < 3 && li.CanMoveFreelyInto(world, self, target, null, CellConditions.All))
                return new List<CPos> { target };

            List<CPos> pb;
            using (var fromSrc = PathSearch.FromPoint(world, li, self, target, source, true).WithIgnoredActor(ignoreActor))
            using (var fromDest = PathSearch.FromPoint(world, li, self, source, target, true).WithIgnoredActor(ignoreActor).Reverse())
                pb = FindBidiPath(fromSrc, fromDest);

            CheckSanePath2(pb, source, target);

            return pb;
        }
Exemple #22
0
        /// <summary>
        /// Finds the closest harvestable pos between the current position of the harvester
        /// and the last order location
        /// </summary>
        CPos?ClosestHarvestablePos(Actor self)
        {
            if (harv.CanHarvestCell(self, self.Location) && claimLayer.CanClaimCell(self, self.Location))
            {
                return(self.Location);
            }

            // Determine where to search from and how far to search:
            var searchFromLoc       = GetSearchFromLocation(self);
            var searchRadius        = harv.LastOrderLocation.HasValue ? harvInfo.SearchFromOrderRadius : harvInfo.SearchFromProcRadius;
            var searchRadiusSquared = searchRadius * searchRadius;

            // Find any harvestable resources:
            var         passable = (uint)mobileInfo.GetMovementClass(self.World.Map.Rules.TileSet);
            List <CPos> path;

            using (var search = PathSearch.Search(self.World, mobileInfo, self, true, loc =>
                                                  domainIndex.IsPassable(self.Location, loc, mobileInfo, passable) && harv.CanHarvestCell(self, loc) && claimLayer.CanClaimCell(self, loc))
                                .WithCustomCost(loc =>
            {
                if ((avoidCell.HasValue && loc == avoidCell.Value) ||
                    (loc - self.Location).LengthSquared > searchRadiusSquared)
                {
                    return(int.MaxValue);
                }

                return(0);
            })
                                .FromPoint(self.Location)
                                .FromPoint(searchFromLoc))
                path = pathFinder.FindPath(search);

            if (path.Count > 0)
            {
                return(path[0]);
            }

            return(null);
        }
Exemple #23
0
        public void mapCompute()
        {
            //声源离散
            Layer      sourceLayer = getSource();
            PathSearch pathbean    = new PathSearch();
            //接收点离散
            Queue <Geometry> receiveList = PolygonPartition.staticPartition(m_gridSize, m_computationalGrid, m_receiveHeight);


            //障碍物优化
            DataSource barrierSource = Ogr.Open(m_barrierPath, 0);
            Layer      barrierLayer  = barrierSource.GetLayerByIndex(0);

            Geometry receivePoint  = null;
            Geometry sourcePoint   = null;
            Feature  sourceFeature = null;

            Geometry[]     pathList       = null;
            List <float[]> sourceLineList = new List <float[]>();

            //路径计算,循环接收点
            while (receiveList.Count > 0)
            {
                //声源点和接收点
                receivePoint = receiveList.Dequeue();
                sourceLayer.SetSpatialFilter(receivePoint.Buffer(m_range, 30));
                //循环声源点
                while ((sourceFeature = sourceLayer.GetNextFeature()) != null)
                {
                    sourcePoint = sourceFeature.GetGeometryRef();
                    //获取路径
                    pathList = pathbean.getPath(barrierLayer, sourcePoint, receivePoint, m_range);
                }
            }


            //衰减计算
        }
Exemple #24
0
        Actor ClosestProc(Actor self, Actor ignore)
        {
            var refs = self.World.ActorsWithTrait <IAcceptOre>()
                       .Where(x => x.Actor != ignore && x.Actor.Owner == self.Owner)
                       .ToList();
            var mi   = self.Info.Traits.Get <MobileInfo>();
            var path = self.World.WorldActor.Trait <PathFinder>().FindPath(
                PathSearch.FromPoints(self.World, mi, self.Owner,
                                      refs.Select(r => r.Actor.Location + r.Trait.DeliverOffset),
                                      self.Location, false));

            path.Reverse();

            if (path.Count != 0)
            {
                return(refs.Where(x => x.Actor.Location + x.Trait.DeliverOffset == path[0])
                       .Select(a => a.Actor).FirstOrDefault());
            }
            else
            {
                return(null);
            }
        }
Exemple #25
0
        List <CPos> CalculatePathToTarget(Actor self)
        {
            var targetCells = CandidateMovementCells(self);
            var searchCells = new List <CPos>();
            var loc         = self.Location;

            foreach (var cell in targetCells)
            {
                if (domainIndex.IsPassable(loc, cell, Mobile.Info, movementClass) && Mobile.CanEnterCell(cell))
                {
                    searchCells.Add(cell);
                }
            }

            if (!searchCells.Any())
            {
                return(NoPath);
            }

            using (var fromSrc = PathSearch.FromPoints(self.World, Mobile.Info, self, searchCells, loc, true))
                using (var fromDest = PathSearch.FromPoint(self.World, Mobile.Info, self, loc, targetPosition, true).Reverse())
                    return(pathFinder.FindBidiPath(fromSrc, fromDest));
        }
        Target FindNextResource(Actor actor, HarvesterTraitWrapper harv)
        {
            Func <CPos, bool> isValidResource = cell =>
                                                harv.Harvester.CanHarvestCell(actor, cell) &&
                                                claimLayer.CanClaimCell(actor, cell);

            List <CPos> path;

            using (var search =
                       PathSearch.ToTargetCellByPredicate(
                           world, harv.Locomotor, actor, new[] { actor.Location }, isValidResource, BlockedByActor.Stationary,
                           loc => world.FindActorsInCircle(world.Map.CenterOfCell(loc), Info.HarvesterEnemyAvoidanceRadius)
                           .Where(u => !u.IsDead && actor.Owner.RelationshipWith(u.Owner) == PlayerRelationship.Enemy)
                           .Sum(u => Math.Max(WDist.Zero.Length, Info.HarvesterEnemyAvoidanceRadius.Length - (world.Map.CenterOfCell(loc) - u.CenterPosition).Length))))
                path = pathfinder.FindPath(search);

            if (path.Count == 0)
            {
                return(Target.Invalid);
            }

            return(Target.FromCell(world, path[0]));
        }
Exemple #27
0
        Target SafePath(Actor capturer, Actor target)
        {
            var locomotor = capturer.Trait <Mobile>().Locomotor;

            if (!domainIndex.IsPassable(capturer.Location, target.Location, locomotor))
            {
                return(Target.Invalid);
            }

            var path = pathfinder.FindPath(
                PathSearch.FromPoint(world, locomotor, capturer, capturer.Location, target.Location, BlockedByActor.None)
                .WithCustomCost(loc => world.FindActorsInCircle(world.Map.CenterOfCell(loc), Info.EnemyAvoidanceRadius)
                                .Where(u => !u.IsDead && capturer.Owner.RelationshipWith(u.Owner) == PlayerRelationship.Enemy && capturer.IsTargetableBy(u))
                                .Sum(u => Math.Max(WDist.Zero.Length, Info.EnemyAvoidanceRadius.Length - (world.Map.CenterOfCell(loc) - u.CenterPosition).Length)))
                .FromPoint(capturer.Location));

            if (path.Count == 0)
            {
                return(Target.Invalid);
            }

            return(Target.FromActor(target));
        }
Exemple #28
0
        /// <summary>
        /// Finds the closest harvestable pos between the current position of the harvester
        /// and the last order location
        /// </summary>
        CPos?ClosestHarvestablePos(Actor self)
        {
            if (IsHarvestable(self, self.Location))
            {
                return(self.Location);
            }

            // Determine where to search from and how far to search:
            var searchFromLoc       = harv.LastOrderLocation ?? (harv.LastLinkedProc ?? harv.LinkedProc ?? self).Location;
            var searchRadius        = harv.LastOrderLocation.HasValue ? harvInfo.SearchFromOrderRadius : harvInfo.SearchFromProcRadius;
            var searchRadiusSquared = searchRadius * searchRadius;

            var search = PathSearch.Search(self.World, mobileInfo, self, true,
                                           loc => IsHarvestable(self, loc))
                         .WithCustomCost(loc =>
            {
                if ((avoidCell.HasValue && loc == avoidCell.Value) ||
                    (loc - self.Location).LengthSquared > searchRadiusSquared)
                {
                    return(int.MaxValue);
                }

                return(0);
            })
                         .FromPoint(self.Location)
                         .FromPoint(searchFromLoc);

            // Find any harvestable resources:
            var path = pathFinder.FindPath(search);

            if (path.Count > 0)
            {
                return(path[0]);
            }

            return(null);
        }
Exemple #29
0
        Target PathToNextcube(Actor collector, Actor cube)
        {
            var locomotor = collector.Trait <Mobile>().Locomotor;

            if (!domainIndex.IsPassable(collector.Location, cube.Location, locomotor))
            {
                return(Target.Invalid);
            }

            var path = pathfinder.FindPath(
                PathSearch.FromPoint(world, locomotor, collector, collector.Location, cube.Location, BlockedByActor.Stationary)
                .WithCustomCost(loc => world.FindActorsInCircle(world.Map.CenterOfCell(loc), Info.EnemyAvoidanceRadius)
                                .Where(u => !u.IsDead && collector.Owner.RelationshipWith(u.Owner) == PlayerRelationship.Enemy)
                                .Sum(u => Math.Max(WDist.Zero.Length, Info.EnemyAvoidanceRadius.Length - (world.Map.CenterOfCell(loc) - u.CenterPosition).Length)))
                .FromPoint(collector.Location));

            if (path.Count == 0)
            {
                return(Target.Invalid);
            }

            // Don't use the actor to avoid invalid targets when the cube disappears midway.
            return(Target.FromCell(world, cube.Location));
        }
        Target FindNextResource(Actor actor, MinerTraitWrapper miner)
        {
            var towerInfo    = AIUtils.GetInfoByCommonName(Info.DeployedActorTypes, player);
            var buildingInfo = towerInfo.TraitInfo <BuildingInfo>();
            Func <CPos, bool> isValidResource = cell =>
                                                domainIndex.IsPassable(actor.Location, cell, miner.Locomotor.Info) &&
                                                Info.DeployableTerrainTypes.Contains(world.Map.GetTerrainInfo(cell).Type) &&
                                                miner.Locomotor.CanStayInCell(cell) &&
                                                world.CanPlaceBuilding(cell + miner.Transforms.Info.Offset, towerInfo, buildingInfo, actor);

            var path = pathfinder.FindPath(
                PathSearch.Search(world, miner.Locomotor, actor, BlockedByActor.Stationary, isValidResource)
                .WithCustomCost(loc => world.FindActorsInCircle(world.Map.CenterOfCell(loc), Info.EnemyAvoidanceRadius)
                                .Where(u => !u.IsDead && actor.Owner.Stances[u.Owner] == Stance.Enemy)
                                .Sum(u => Math.Max(WDist.Zero.Length, Info.EnemyAvoidanceRadius.Length - (world.Map.CenterOfCell(loc) - u.CenterPosition).Length)))
                .FromPoint(actor.Location));

            if (path.Count == 0)
            {
                return(Target.Invalid);
            }

            return(Target.FromCell(world, path[0]));
        }
Exemple #31
0
        CPos?ClosestGroundCell()
        {
            var above = new CPos(TopLeft.X, TopLeft.Y);

            if (CanEnterCell(above))
            {
                return(above);
            }

            var         pathFinder = self.World.WorldActor.Trait <IPathFinder>();
            List <CPos> path;

            using (var search = PathSearch.Search(self.World, Info, self, true,
                                                  loc => loc.Layer == 0 && CanEnterCell(loc))
                                .FromPoint(self.Location))
                path = pathFinder.FindPath(search);

            if (path.Count > 0)
            {
                return(path[0]);
            }

            return(null);
        }
Exemple #32
0
        public async Task <List <Path> > GetPathsByProperty(PathSearch locationSearch)
        {
            Path path = new Path();

            PropertyInfo info = path
                                .GetType()
                                .GetProperty(locationSearch.searchByProperty.ToString());
            PropertyInfo info1 = locationSearch
                                 .GetType()
                                 .GetProperty(locationSearch.searchByProperty.ToString());

            List <Path> pathsInPropery = await _dbcontext.Paths.ToListAsync();

            if (pathsInPropery == null)
            {
                //  Log.Warning("Couldn't find any paths");
                throw new Exception("NotFound:Couldn't find any paths");
            }
            List <Path> newPathsInPropery = new List <Path>();

            for (int i = 0; i < pathsInPropery.Count(); i++)
            {
                if (string.Compare(info.GetValue(pathsInPropery[i]).ToString(), info1.GetValue(locationSearch).ToString()) == 0)
                {
                    newPathsInPropery.Add(pathsInPropery[i]);
                }
            }


            if (newPathsInPropery == null)
            {
                //  Log.Warning("Couldn't find any paths in property {@pathSearchByCity}", locationSearch.searchByProperty);
                throw new Exception($"NotFound:Couldn't find any paths for property {locationSearch.searchByProperty}");
            }
            return(newPathsInPropery);
        }
Exemple #33
0
        public List <CPos> FindUnitPath(CPos source, CPos target, Actor self)
        {
            var mi = self.Info.Traits.Get <MobileInfo>();

            // If a water-land transition is required, bail early
            var domainIndex = world.WorldActor.TraitOrDefault <DomainIndex>();

            if (domainIndex != null)
            {
                var passable = mi.GetMovementClass(world.TileSet);
                if (!domainIndex.IsPassable(source, target, (uint)passable))
                {
                    return(EmptyPath);
                }
            }

            var pb = FindBidiPath(
                PathSearch.FromPoint(world, mi, self, target, source, true),
                PathSearch.FromPoint(world, mi, self, source, target, true).Reverse());

            CheckSanePath2(pb, source, target);

            return(pb);
        }
Exemple #34
0
        /// <summary>
        /// Finds the closest harvestable pos between the current position of the harvester
        /// and the last order location
        /// </summary>
        CPos?ClosestHarvestablePos(Actor self)
        {
            // Harvesters should respect an explicit harvest order instead of harvesting the current cell.
            if (orderLocation == null)
            {
                if (harv.CanHarvestCell(self, self.Location) && claimLayer.CanClaimCell(self, self.Location))
                {
                    return(self.Location);
                }
            }
            else
            {
                if (harv.CanHarvestCell(self, orderLocation.Value) && claimLayer.CanClaimCell(self, orderLocation.Value))
                {
                    return(orderLocation);
                }

                orderLocation = null;
            }

            // Determine where to search from and how far to search:
            var procLoc       = GetSearchFromProcLocation(self);
            var searchFromLoc = lastHarvestedCell ?? procLoc ?? self.Location;
            var searchRadius  = lastHarvestedCell.HasValue ? harvInfo.SearchFromHarvesterRadius : harvInfo.SearchFromProcRadius;

            var searchRadiusSquared = searchRadius * searchRadius;

            var map     = self.World.Map;
            var procPos = procLoc.HasValue ? (WPos?)map.CenterOfCell(procLoc.Value) : null;
            var harvPos = self.CenterPosition;

            // Find any harvestable resources:
            List <CPos> path;

            using (var search = PathSearch.Search(self.World, mobile.Locomotor, self, BlockedByActor.Stationary, loc =>
                                                  domainIndex.IsPassable(self.Location, loc, mobile.Locomotor) && harv.CanHarvestCell(self, loc) && claimLayer.CanClaimCell(self, loc))
                                .WithCustomCost(loc =>
            {
                if ((loc - searchFromLoc).LengthSquared > searchRadiusSquared)
                {
                    return(PathGraph.PathCostForInvalidPath);
                }

                // Add a cost modifier to harvestable cells to prefer resources that are closer to the refinery.
                // This reduces the tendency for harvesters to move in straight lines
                if (procPos.HasValue && harvInfo.ResourceRefineryDirectionPenalty > 0 && harv.CanHarvestCell(self, loc))
                {
                    var pos = map.CenterOfCell(loc);

                    // Calculate harv-cell-refinery angle (cosine rule)
                    var b = pos - procPos.Value;

                    if (b != WVec.Zero)
                    {
                        var c = pos - harvPos;
                        if (c != WVec.Zero)
                        {
                            var a = harvPos - procPos.Value;
                            var cosA = (int)(512 * (b.LengthSquared + c.LengthSquared - a.LengthSquared) / b.Length / c.Length);

                            // Cost modifier varies between 0 and ResourceRefineryDirectionPenalty
                            return(Math.Abs(harvInfo.ResourceRefineryDirectionPenalty / 2) + harvInfo.ResourceRefineryDirectionPenalty * cosA / 2048);
                        }
                    }
                }

                return(0);
            })
                                .FromPoint(searchFromLoc)
                                .FromPoint(self.Location))
                path = mobile.Pathfinder.FindPath(search);

            if (path.Count > 0)
            {
                return(path[0]);
            }

            return(null);
        }
Exemple #35
0
        void FindMoreResource(Actor self)
        {
            var res = self.World.WorldActor.traits.Get<ResourceLayer>();
            var harv = self.Info.Traits.Get<HarvesterInfo>();

            self.QueueActivity(new Move(
                () =>
                {
                    var search = new PathSearch(self.World)
                    {
                        heuristic = loc => (res.GetResource(loc) != null
                            && harv.Resources.Contains( res.GetResource(loc).Name )) ? 0 : 1,
                        umt = UnitMovementType.Wheel,
                        checkForBlocked = true
                    };
                    search.AddInitialCell(self.World, self.Location);
                    return self.World.PathFinder.FindPath(search);
                }));
            self.QueueActivity(new Harvest());
        }
Exemple #36
0
        public override Activity Tick(Actor self)
        {
            if (IsCanceled || NextActivity != null)
            {
                return(NextActivity);
            }

            var harv = self.Trait <Harvester>();

            if (harv.IsFull)
            {
                return(Util.SequenceActivities(new DeliverResources(), NextActivity));
            }

            var harvInfo   = self.Info.Traits.Get <HarvesterInfo>();
            var mobile     = self.Trait <Mobile>();
            var mobileInfo = self.Info.Traits.Get <MobileInfo>();
            var resLayer   = self.World.WorldActor.Trait <ResourceLayer>();
            var territory  = self.World.WorldActor.TraitOrDefault <ResourceClaimLayer>();

            // Determine where to search from and how far to search:
            var searchFromLoc       = harv.LastOrderLocation ?? (harv.LastLinkedProc ?? harv.LinkedProc ?? self).Location;
            int searchRadius        = harv.LastOrderLocation.HasValue ? harvInfo.SearchFromOrderRadius : harvInfo.SearchFromProcRadius;
            int searchRadiusSquared = searchRadius * searchRadius;

            // Find harvestable resources nearby:
            // Avoid enemy territory:
            // TODO: calculate weapons ranges of units and factor those in instead of hard-coding 8.
            var path = self.World.WorldActor.Trait <PathFinder>().FindPath(
                PathSearch.Search(self.World, mobileInfo, self, true)
                .WithCustomCost(loc => self.World.FindActorsInCircle(loc.CenterPosition, WRange.FromCells(8))
                                .Where(u => !u.Destroyed && self.Owner.Stances[u.Owner] == Stance.Enemy)
                                .Sum(u => Math.Max(0, 64 - (loc - u.Location).LengthSquared)))
                .WithHeuristic(loc =>
            {
                // Avoid this cell:
                if (avoidCell.HasValue && loc == avoidCell.Value)
                {
                    return(1);
                }

                // Don't harvest out of range:
                int distSquared = (loc - searchFromLoc).LengthSquared;
                if (distSquared > searchRadiusSquared)
                {
                    return(int.MaxValue);
                }

                // Get the resource at this location:
                var resType = resLayer.GetResource(loc);

                if (resType == null)
                {
                    return(1);
                }
                // Can the harvester collect this kind of resource?
                if (!harvInfo.Resources.Contains(resType.Info.Name))
                {
                    return(1);
                }

                if (territory != null)
                {
                    // Another harvester has claimed this resource:
                    ResourceClaim claim;
                    if (territory.IsClaimedByAnyoneElse(self, loc, out claim))
                    {
                        return(1);
                    }
                }

                return(0);
            })
                .FromPoint(self.Location)
                );

            if (path.Count == 0)
            {
                if (!harv.IsEmpty)
                {
                    return(new DeliverResources());
                }
                else
                {
                    // Get out of the way if we are:
                    harv.UnblockRefinery(self);
                    int randFrames = 125 + self.World.SharedRandom.Next(-35, 35);
                    if (NextActivity != null)
                    {
                        return(Util.SequenceActivities(NextActivity, new Wait(randFrames), new FindResources()));
                    }
                    else
                    {
                        return(Util.SequenceActivities(new Wait(randFrames), new FindResources()));
                    }
                }
            }

            // Attempt to claim a resource as ours:
            if (territory != null)
            {
                if (!territory.ClaimResource(self, path[0]))
                {
                    return(Util.SequenceActivities(new Wait(25), new FindResources()));
                }
            }

            // If not given a direct order, assume ordered to the first resource location we find:
            if (harv.LastOrderLocation == null)
            {
                harv.LastOrderLocation = path[0];
            }

            self.SetTargetLine(Target.FromCell(path[0]), Color.Red, false);
            return(Util.SequenceActivities(mobile.MoveTo(path[0], 1), new HarvestResource(), new FindResources()));
        }
Exemple #37
0
 public void Path_to_self() {
     var path = new PathSearch(g, 42, 42);
     Assert.That(path.Exists, Is.True);
 }
Exemple #38
0
 public void Empty_graph() {
     var path = new PathSearch(g, 0, 1);
     Assert.That(path.Exists, Is.False);
 }