Example #1
0
        public static bool CanHarvestAt(this Actor self, CPos pos, ResourceLayer resLayer, HarvesterInfo harvInfo,
                                        ResourceClaimLayer territory)
        {
            var resType = resLayer.GetResource(pos);

            if (resType == null)
            {
                return(false);
            }

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

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

            return(true);
        }
Example #2
0
        public void Leech(Actor self)
        {
            CPos cell  = CPos.Zero;
            var  cells = self.World.Map.FindTilesInCircle(self.World.Map.CellContaining(self.CenterPosition), 6, true)
                         .Where(c =>
            {
                if (!self.World.Map.Contains(c))
                {
                    return(false);
                }
                if (resLayer.GetResource(c) != null)
                {
                    return(false);
                }
                return(true);
            });

            if (cells != null && cells.Any())
            {
                cell = self.ClosestCell(cells);
            }

            if (cell != CPos.Zero && resLayer.GetResourceDensity(cell) > 0)
            {
                var ammount = resLayer.GetResource(cell).Info.ValuePerUnit;

                if ((self.Owner.PlayerActor.Trait <PlayerResources>().Resources + ammount) <= self.Owner.PlayerActor.Trait <PlayerResources>().ResourceCapacity)
                {
                    var playerResources = self.Owner.PlayerActor.Trait <PlayerResources>();
                    playerResources.GiveResources(ammount);

                    if (ammount > 0 && self.IsInWorld && !self.IsDead)
                    {
                        if (self.Owner.IsAlliedWith(self.World.RenderPlayer))
                        {
                            self.World.AddFrameEndTask(w => w.Add(new FloatingText(self.CenterPosition,
                                                                                   self.Owner.Color.RGB, FloatingText.FormatCashTick(ammount), 30)));
                        }
                    }
                    resLayer.Harvest(cell);
                }
            }
        }
Example #3
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.GetResource(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 = 0,
                    CurrentMuzzleFacing = () => 0,

                    DamageModifiers = self.TraitsImplementing <IFirepowerModifier>()
                                      .Select(a => a.GetFirepowerModifier()).ToArray(),

                    InaccuracyModifiers = self.TraitsImplementing <IInaccuracyModifier>()
                                          .Select(a => a.GetInaccuracyModifier()).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.Random(self.World.SharedRandom), self.CenterPosition);
                        }
                    }
                });
            }
        }
        public bool CanHarvestCell(Actor self, CPos cell)
        {
            // Resources only exist in the ground layer
            if (cell.Layer != 0)
            {
                return(false);
            }

            var resType = resLayer.GetResource(cell).Type;

            if (resType == null)
            {
                return(false);
            }

            // Can the harvester collect this kind of resource?
            return(info.Resources.Contains(resType.Info.Type));
        }
        public void Tick(Actor self)
        {
            if (IsTraitDisabled || --poisonTicks > 0)
            {
                return;
            }

            // Prevents harming infantry in cargo.
            if (!self.IsInWorld)
            {
                return;
            }

            var r = rl.GetResource(self.Location);

            if (r == null || !Info.Resources.Contains(r.Info.Name))
            {
                return;
            }

            Info.WeaponInfo.Impact(Target.FromActor(self), self.World.WorldActor, Enumerable.Empty <int>());
            poisonTicks = Info.WeaponInfo.ReloadDelay;
        }
Example #6
0
        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.First, actorInfo, buildingInfo);
                        var lineCloseEnough = buildingInfo.IsCloseEnoughToBase(world, world.LocalPlayer, actorInfo, t.First);
                        footprint.Add(t.First, 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.GetResource(t) == null)));
                }
            }

            return(preview != null?preview.Render(wr, topLeft, footprint) : Enumerable.Empty <IRenderable>());
        }
        void ITick.Tick(Actor self)
        {
            if (IsTraitDisabled)
            {
                return;
            }

            if (tickler-- <= 0)
            {
                var cells = self.World.Map.FindTilesInCircle(self.Location, info.CollectRange, true)
                            .Where(c =>
                {
                    if (resLayer.GetResource(c) == null)
                    {
                        return(false);
                    }
                    if (info.ResourcesNames.Contains(resLayer.GetResource(c).Info.Name))
                    {
                        return(true);
                    }
                    return(false);
                });

                var zapRandom = CPos.Zero;

                if (cells != null && cells.Any() && cells.Count() > 1)
                {
                    zapRandom = cells.MinByOrDefault(c => (self.Location - c).LengthSquared);
                }
                else if (cells != null && cells.Any() && cells.Count() == 1)
                {
                    zapRandom = cells.First();
                }

                if (zapRandom != CPos.Zero)
                {
                    var ammount         = resLayer.GetResource(zapRandom).Info.ValuePerUnit;
                    var playerResources = self.Owner.PlayerActor.Trait <PlayerResources>();

                    playerResources.GiveResources(ammount);

                    if (ammount > 0 && self.IsInWorld && !self.IsDead)
                    {
                        var floattest = ammount.ToString();

                        floattest = "+ " + floattest + " Essence";

                        if (self.Owner.IsAlliedWith(self.World.RenderPlayer))
                        {
                            self.World.AddFrameEndTask(w => w.Add(new FloatingText(self.CenterPosition,
                                                                                   self.Owner.Color.RGB, floattest, 30)));
                        }
                    }

                    resLayer.Harvest(zapRandom);
                    if (resLayer.GetResourceDensity(zapRandom) <= 0)
                    {
                        resLayer.Destroy(zapRandom);
                    }

                    var weapon = Info.WeaponInfo;
                    if (weapon == null)
                    {
                        return;
                    }

                    if (weapon.Report != null && weapon.Report.Any())
                    {
                        Game.Sound.Play(SoundType.World, weapon.Report.Random(self.World.SharedRandom), self.CenterPosition);
                    }

                    weapon.Impact(Target.FromPos(self.World.Map.CenterOfCell(zapRandom)), self, Enumerable.Empty <int>());

                    tickler = info.CollectInterval;
                }
            }
        }
Example #8
0
        public int Leech(Actor self)
        {
            var validRes = new HashSet <string>();

            foreach (var restype in resourceTypesPreres)
            {
                var hash = new List <string>();
                hash.Add(restype.Value);

                if (restype.Value == "NONE")
                {
                    validRes.Add(restype.Key);
                }
                else if (self.Owner.PlayerActor.TraitOrDefault <TechTree>().HasPrerequisites(hash))
                {
                    validRes.Add(restype.Key);
                }
            }

            CPos cell  = CPos.Zero;
            var  cells = self.World.Map.FindTilesInCircle(self.World.Map.CellContaining(self.CenterPosition), 6, true)
                         .Where(c =>
            {
                if (!self.World.Map.Contains(c))
                {
                    return(false);
                }
                if (resLayer.GetResource(c) == null)
                {
                    return(false);
                }
                if (resLayer.GetResourceDensity(c) == 0)
                {
                    return(false);
                }
                if (validRes.Contains(resLayer.GetResource(c).Info.Type))
                {
                    return(true);
                }

                return(false);
            });

            if (cells != null && cells.Any())
            {
                cell = self.ClosestCell(cells);
            }

            if (cell != CPos.Zero && resLayer.GetResourceDensity(cell) > 0)
            {
                var type    = resLayer.GetResource(cell);
                var ammount = type.Info.ValuePerUnit + ReturnExtraTime(type);

                if ((self.Owner.PlayerActor.Trait <PlayerResources>().Resources + ammount) <= self.Owner.PlayerActor.Trait <PlayerResources>().ResourceCapacity)
                {
                    var playerResources = self.Owner.PlayerActor.Trait <PlayerResources>();
                    playerResources.GiveResources(ammount);

                    if (ammount > 0 && self.IsInWorld && !self.IsDead)
                    {
                        var floattest = ammount.ToString();

                        floattest = "+ " + floattest + " Essence";

                        if (self.Owner.IsAlliedWith(self.World.RenderPlayer))
                        {
                            self.World.AddFrameEndTask(w => w.Add(new FloatingText(self.CenterPosition,
                                                                                   self.Owner.Color.RGB, floattest, 30)));
                        }
                    }

                    resLayer.Harvest(cell);
                    if (resLayer.GetResourceDensity(cell) <= 0)
                    {
                        resLayer.Destroy(cell);
                    }

                    return(ammount);
                }
            }

            return(0);
        }
Example #9
0
        public override Activity Tick(Actor self)
        {
            if (IsCanceled || NextActivity != null)
            {
                return(NextActivity);
            }

            var deliver = new DeliverResources(self);

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

            // 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;

            // Find harvestable resources nearby:
            var path = pathFinder.FindPath(
                PathSearch.Search(self.World, mobileInfo, self, true)
                .WithHeuristic(loc =>
            {
                // Avoid this cell:
                if (avoidCell.HasValue && loc == avoidCell.Value)
                {
                    return(EstimateDistance(loc, searchFromLoc) + Constants.CellCost);
                }

                // Don't harvest out of range:
                var distSquared = (loc - searchFromLoc).LengthSquared;
                if (distSquared > searchRadiusSquared)
                {
                    return(EstimateDistance(loc, searchFromLoc) + Constants.CellCost * 2);
                }

                // Get the resource at this location:
                var resType = resLayer.GetResource(loc);
                if (resType == null)
                {
                    return(EstimateDistance(loc, searchFromLoc) + Constants.CellCost);
                }

                // Can the harvester collect this kind of resource?
                if (!harvInfo.Resources.Contains(resType.Info.Name))
                {
                    return(EstimateDistance(loc, searchFromLoc) + Constants.CellCost);
                }

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

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

            var next = this;

            if (path.Count == 0)
            {
                if (!harv.IsEmpty)
                {
                    return(deliver);
                }
                else
                {
                    // Get out of the way if we are:
                    harv.UnblockRefinery(self);
                    var randFrames = self.World.SharedRandom.Next(90, 160);
                    if (NextActivity != null)
                    {
                        return(Util.SequenceActivities(NextActivity, new Wait(randFrames), next));
                    }
                    else
                    {
                        return(Util.SequenceActivities(new Wait(randFrames), next));
                    }
                }
            }

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

            // 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(self.World, path[0]), Color.Red, false);

            var notify = self.TraitsImplementing <INotifyHarvesterAction>();

            foreach (var n in notify)
            {
                n.MovingToResources(self, path[0], next);
            }

            return(Util.SequenceActivities(mobile.MoveTo(path[0], 1), new HarvestResource(self), next));
        }