public List <CPos> FindUnitPath(CPos source, CPos target, Actor self, Actor ignoreActor) { var li = self.Info.TraitInfo <MobileInfo>().LocomotorInfo; 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, li)) { return(EmptyPath); } var distance = source - target; if (source.Layer == target.Layer && 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); return(pb); }
protected override void TraitEnabled(Actor self) { pathfinder = world.WorldActor.Trait <IPathFinder>(); domainIndex = world.WorldActor.Trait <DomainIndex>(); resLayer = world.WorldActor.TraitOrDefault <ResourceLayer>(); claimLayer = world.WorldActor.TraitOrDefault <ResourceClaimLayer>(); scanForIdleHarvestersTicks = Info.ScanForIdleHarvestersInterval; }
public ProductionFromMapEdge(ActorInitializer init, ProductionInfo info) : base(init, info) { domainIndex = init.Self.World.WorldActor.Trait <DomainIndex>(); if (init.Contains <ProductionSpawnLocationInit>()) { spawnLocation = init.Get <ProductionSpawnLocationInit, CPos>(); } }
protected override void TraitEnabled(Actor self) { requestUnitProduction = player.PlayerActor.TraitsImplementing <IBotRequestUnitProduction>().ToArray(); pathfinder = world.WorldActor.Trait <IPathFinder>(); domainIndex = world.WorldActor.Trait <DomainIndex>(); resLayer = world.WorldActor.TraitOrDefault <ResourceLayer>(); claimLayer = world.WorldActor.TraitOrDefault <ResourceClaimLayer>(); scanForIdleHarvestersTicks = Info.ScanForIdleHarvestersInterval; }
protected override void TraitEnabled(Actor self) { pathfinder = world.WorldActor.Trait <IPathFinder>(); domainIndex = world.WorldActor.Trait <DomainIndex>(); resourceLayer = world.WorldActor.TraitOrDefault <IResourceLayer>(); claimLayer = world.WorldActor.TraitOrDefault <ResourceClaimLayer>(); // Avoid all AIs scanning for idle harvesters on the same tick, randomize their initial scan delay. scanForIdleHarvestersTicks = world.LocalRandom.Next(Info.ScanForIdleHarvestersInterval, Info.ScanForIdleHarvestersInterval * 2); }
public ProductionFromMapEdge(ActorInitializer init, ProductionInfo info) : base(init, info) { domainIndex = init.Self.World.WorldActor.Trait <DomainIndex>(); var spawnLocationInit = init.GetOrDefault <ProductionSpawnLocationInit>(info); if (spawnLocationInit != null) { spawnLocation = spawnLocationInit.Value; } }
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)) { 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); }
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); }
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 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)); }