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); }
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); } } }
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; }
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; } } }
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); }
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)); }