Example #1
0
        /// <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);
        }
Example #2
0
        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);
                        }
                    }
                });
            }
        }
Example #3
0
        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);
            }
        }
Example #4
0
        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>());
        }