/// <summary> /// Finds the closest harvestable pos between the current position of the harvester /// and the last order location /// </summary> CPos?ClosestHarvestablePos(Actor self) { var mobile = self.Trait <Mobile>(); // Determine where to search from and how far to search: Func <CPos, bool> canHarvest = pos => { var resType = resourceLayer.GetResourceType(pos); if (resType != null && string.Compare(resType.Info.Name, Info.TargetResourceType, StringComparison.OrdinalIgnoreCase) == 0) { return(true); } return(false); }; // 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) && canHarvest(loc) && claimLayer.CanClaimCell(self, loc)) .FromPoint(self.Location)) path = pathFinder.FindPath(search); if (path.Count > 0) { return(path[0]); } return(null); }
void SeedResources(Actor self) { var pieces = self.World.SharedRandom.Next(info.Pieces[0], info.Pieces[1]) * ticks / growTicks; if (pieces < info.Pieces[0]) { pieces = info.Pieces[0]; } var cells = self.World.Map.FindTilesInAnnulus(self.Location, 1, info.Range); for (var i = 0; i < pieces; i++) { var cell = cells.SkipWhile(p => resLayer.GetResourceType(p) == resType && resLayer.IsFull(p)).Cast <CPos?>().RandomOrDefault(self.World.SharedRandom); if (cell == null) { cell = cells.Random(self.World.SharedRandom); } var args = new ProjectileArgs { Weapon = self.World.Map.Rules.Weapons[info.Weapon.ToLowerInvariant()], Facing = WAngle.Zero, CurrentMuzzleFacing = () => WAngle.Zero, DamageModifiers = self.TraitsImplementing <IFirepowerModifier>() .Select(a => a.GetFirepowerModifier()).ToArray(), InaccuracyModifiers = self.TraitsImplementing <IInaccuracyModifier>() .Select(a => a.GetInaccuracyModifier()).ToArray(), RangeModifiers = self.TraitsImplementing <IRangeModifier>() .Select(a => a.GetRangeModifier()).ToArray(), Source = self.CenterPosition, CurrentSource = () => self.CenterPosition, SourceActor = self, PassiveTarget = self.World.Map.CenterOfCell(cell.Value) }; self.World.AddFrameEndTask(_ => { if (args.Weapon.Projectile != null) { var projectile = args.Weapon.Projectile.Create(args); if (projectile != null) { self.World.Add(projectile); } if (args.Weapon.Report != null && args.Weapon.Report.Any()) { Game.Sound.Play(SoundType.World, args.Weapon.Report, self.World, self.CenterPosition); } } }); } }
public void Seed(Actor self) { var cell = Util.RandomWalk(self.Location, self.World.SharedRandom) .Take(Info.MaxRange) .SkipWhile(p => !self.World.Map.Contains(p) || (resLayer.GetResourceType(p) == resourceType && resLayer.IsFull(p))) .Cast <CPos?>().FirstOrDefault(); if (cell != null && resLayer.CanSpawnResourceAt(resourceType, cell.Value)) { resLayer.AddResource(resourceType, cell.Value, 1); } }
void ITick.Tick(Actor self) { if (delay < 0) { return; } var adjacent = 0; foreach (var direction in CVec.Directions) { var location = self.Location + direction; var resource = resourceLayer.GetResourceType(location); if (resource == null || resource.Info.Type != info.Type) { continue; } var density = resourceLayer.GetResourceDensity(location); if (density < info.Density) { continue; } if (++adjacent < info.Adjacency) { continue; } delay--; break; } if (delay < 0) { Transform(self); } }
IEnumerable <IRenderable> IOrderGenerator.RenderAboveShroud(WorldRenderer wr, World world) { var topLeft = TopLeft; var footprint = new Dictionary <CPos, PlaceBuildingCellType>(); var activeVariant = variants[variant]; var actorInfo = activeVariant.ActorInfo; var buildingInfo = activeVariant.BuildingInfo; var plugInfo = activeVariant.PlugInfo; var lineBuildInfo = activeVariant.LineBuildInfo; var preview = activeVariant.Preview; var owner = queue.Actor.Owner; if (plugInfo != null) { if (buildingInfo.Dimensions.X != 1 || buildingInfo.Dimensions.Y != 1) { throw new InvalidOperationException("Plug requires a 1x1 sized Building"); } footprint.Add(topLeft, MakeCellType(AcceptsPlug(topLeft, plugInfo))); } else if (lineBuildInfo != null && owner.Shroud.IsExplored(topLeft)) { // Linebuild for walls. if (buildingInfo.Dimensions.X != 1 || buildingInfo.Dimensions.Y != 1) { throw new InvalidOperationException("LineBuild requires a 1x1 sized Building"); } if (!Game.GetModifierKeys().HasModifier(Modifiers.Shift)) { foreach (var t in BuildingUtils.GetLineBuildCells(world, topLeft, actorInfo, buildingInfo, owner)) { var lineBuildable = world.IsCellBuildable(t.Cell, actorInfo, buildingInfo); var lineCloseEnough = buildingInfo.IsCloseEnoughToBase(world, world.LocalPlayer, actorInfo, t.Cell); footprint.Add(t.Cell, MakeCellType(lineBuildable && lineCloseEnough, true)); } } var buildable = world.IsCellBuildable(topLeft, actorInfo, buildingInfo); var closeEnough = buildingInfo.IsCloseEnoughToBase(world, world.LocalPlayer, actorInfo, topLeft); footprint[topLeft] = MakeCellType(buildable && closeEnough); } else { var isCloseEnough = buildingInfo.IsCloseEnoughToBase(world, world.LocalPlayer, actorInfo, topLeft); foreach (var t in buildingInfo.Tiles(topLeft)) { footprint.Add(t, MakeCellType(isCloseEnough && world.IsCellBuildable(t, actorInfo, buildingInfo) && (resourceLayer == null || resourceLayer.GetResourceType(t) == null))); } } return(preview != null?preview.Render(wr, topLeft, footprint) : Enumerable.Empty <IRenderable>()); }