public override void Tick() { base.Tick(); if (DronesLeft > 0 && !lockdown && this.IsHashIntervalTick(60) && GetComp <CompPowerTrader>()?.PowerOn != false) { Job job = TryGiveJob(); if (job != null) { job.playerForced = true; job.expiryInterval = -1; Pawn_Drone drone = MakeDrone(); GenSpawn.Spawn(drone, Position, Map); drone.jobs.StartJob(job); } } //To enhance performence we could add "this.IsHashIntervalTick(60)" if (spawnedDrones.Count > 0 && GetComp <CompPowerTrader>()?.PowerOn == false) { for (int i = spawnedDrones.Count - 1; i >= 0; i--) { spawnedDrones[i].jobs.StartJob(new Job(PRFDefOf.PRFDrone_ReturnToStation, this), JobCondition.InterruptForced); } } //TODO Check if we should increase the IsHashIntervalTick to enhace performence (will reduce responsivness) if (this.IsHashIntervalTick(60) && GetComp <CompPowerTrader>().powerOutputInt != LastPowerOutput) { //Update the Range Update_droneAllowedArea_forDrones(); //Update the last know Val LastPowerOutput = GetComp <CompPowerTrader>().powerOutputInt; //TODO add cell calc cashed_GetCoverageCells = StationRangecells.ToList(); } }
public virtual Pawn_Drone MakeDrone() { Pawn_Drone drone = (Pawn_Drone)PawnGenerator.GeneratePawn(PRFDefOf.PRFDroneKind, Faction); drone.station = this; spawnedDrones.Add(drone); return(drone); }
//It appers as if TickLong & TickRare are not getting called here public void Notify_DroneMayBeLost(Pawn_Drone drone) { if (spawnedDrones.Contains(drone)) { spawnedDrones.Remove(drone); Notify_DroneLost(); } }
public override void SpawnSetup(Map map, bool respawningAfterLoad) { base.SpawnSetup(map, respawningAfterLoad); this.mapManager = map.GetComponent <MapTickManager>(); refuelableComp = GetComp <CompRefuelable>(); compPowerTrader = GetComp <CompPowerTrader>(); extension = def.GetModExtension <DefModExtension_DroneStation>(); compPowerWorkSetting = GetComp <CompPowerWorkSetting>(); StationRangecells_old = StationRangecells; //Setup Allowd Area //Enssuring that Update_droneAllowedArea_forDrones() is run resolves #224 (May need to add a diffrent check) if (droneAllowedArea == null) { //Log.Message("droneAllowedArea was null"); Update_droneAllowedArea_forDrones(droneAllowedArea); } //Load the SleepTimes from XML cachedSleepTimeList = extension.Sleeptimes.Split(','); cashed_GetCoverageCells = StationRangecells.ToList(); //Check for missing WorkTypeDef foreach (WorkTypeDef def in extension.workTypes.Except(WorkSettings.Keys).ToList()) { WorkSettings.Add(def, true); } //Remove stuff thats nolonger valid (can only happen after updates) foreach (WorkTypeDef def in WorkSettings.Keys.Except(extension.workTypes).ToList()) { WorkSettings.Remove(def); } //need to take action to init droneSkillsRecord if (droneSkillsRecord.Count == 0) { Pawn_Drone drone = MakeDrone(); GenSpawn.Spawn(drone, Position, Map); drone.Destroy(); GetComp <CompRefuelable>()?.Refuel(1); } //Init the Designator default Label update_droneAreaSelectorLable(droneAllowedArea); //Need this type of call to set the Powerconsumption on load //A normal call will not work var rangePowerSupplyMachine = this.RangePowerSupplyMachine; if (rangePowerSupplyMachine != null) { this.MapManager.NextAction(rangePowerSupplyMachine.RefreshPowerStatus); this.MapManager.AfterAction(5, rangePowerSupplyMachine.RefreshPowerStatus); } }
public override void Tick() { base.Tick(); if (DronesLeft > 0 && !lockdown && this.IsHashIntervalTick(60) && GetComp <CompPowerTrader>()?.PowerOn != false) { Job job = TryGiveJob(); if (job != null) { job.playerForced = true; job.expiryInterval = -1; Pawn_Drone drone = MakeDrone(); GenSpawn.Spawn(drone, Position, Map); drone.jobs.StartJob(job); } } }
public override void Tick() { //Base Tick base.Tick(); //Return if not Spawnd if (!this.Spawned) { return; } //Should not draw much performence... //To enhance performence we could add "this.IsHashIntervalTick(60)" if (spawnedDrones.Count > 0 && compPowerTrader?.PowerOn == false) { for (int i = spawnedDrones.Count - 1; i >= 0; i--) { spawnedDrones[i].jobs.StartJob(new Job(PRFDefOf.PRFDrone_ReturnToStation, this), JobCondition.InterruptForced); } //return as there is nothing to do if its off.... return; } //Update the Allowed Area Range on Power Change if (this.IsHashIntervalTick(60)) { //Update the Range Update_droneAllowedArea_forDrones(droneAllowedArea); //TODO add cell calc cashed_GetCoverageCells = StationRangecells.ToList(); } //Search for Job if (this.IsHashIntervalTick(60 + additionJobSearchTickDelay) && DronesLeft > 0 && !lockdown && compPowerTrader?.PowerOn != false) { //The issue appears to be 100% with TryGiveJob Job job = TryGiveJob(); if (job != null) { additionJobSearchTickDelay = 0; //Reset to 0 - found a job -> may find more job.playerForced = true; job.expiryInterval = -1; //MakeDrone takes about 1ms Pawn_Drone drone = MakeDrone(); GenSpawn.Spawn(drone, Position, Map); drone.jobs.StartJob(job); } else { //Experimental Delay //Add delay (limit to 300) i am well aware that this can be higher that 300 with the current code if (additionJobSearchTickDelay < 300) { //Exponential delay additionJobSearchTickDelay = (additionJobSearchTickDelay + 1) * 2; } } } }
// Method from RimWorld.JobGiver_Work.TryIssueJobPackage(Pawn pawn, JobIssueParams jobParams) // I modified the line if (!workGiver.ShouldSkip(pawn)) #pragma warning disable public ThinkResult TryIssueJobPackageDrone(Pawn pawn, bool emergency) { List <WorkGiver> list = emergency ? pawn.workSettings.WorkGiversInOrderEmergency : pawn.workSettings.WorkGiversInOrderNormal; int num = -999; TargetInfo targetInfo = TargetInfo.Invalid; WorkGiver_Scanner workGiver_Scanner = null; for (int j = 0; j < list.Count; j++) { WorkGiver workGiver = list[j]; if (workGiver.def.priorityInType != num && targetInfo.IsValid) { break; } if (!workGiver.ShouldSkip(pawn)) { try { Job job2 = workGiver.NonScanJob(pawn); if (job2 != null) { return(new ThinkResult(job2, null, new JobTag?(list[j].def.tagToGive), false)); } WorkGiver_Scanner scanner = workGiver as WorkGiver_Scanner; if (scanner != null) { if (scanner.def.scanThings) { Predicate <Thing> predicate = (Thing t) => !t.IsForbidden(pawn) && scanner.HasJobOnThing(pawn, t, false); IEnumerable <Thing> enumerable = scanner.PotentialWorkThingsGlobal(pawn); Thing thing; if (scanner.Prioritized) { IEnumerable <Thing> enumerable2 = enumerable; if (enumerable2 == null) { enumerable2 = pawn.Map.listerThings.ThingsMatching(scanner.PotentialWorkThingRequest); } if (scanner.AllowUnreachable) { IntVec3 position = pawn.Position; IEnumerable <Thing> searchSet = enumerable2; Predicate <Thing> validator = predicate; thing = GenClosest.ClosestThing_Global(position, searchSet, 99999f, validator, (Thing x) => scanner.GetPriority(pawn, x)); } else { IntVec3 position = pawn.Position; Map map = pawn.Map; IEnumerable <Thing> searchSet = enumerable2; PathEndMode pathEndMode = scanner.PathEndMode; TraverseParms traverseParams = TraverseParms.For(pawn, scanner.MaxPathDanger(pawn), TraverseMode.ByPawn, false); Predicate <Thing> validator = predicate; thing = GenClosest.ClosestThing_Global_Reachable(position, map, searchSet, pathEndMode, traverseParams, 9999f, validator, (Thing x) => scanner.GetPriority(pawn, x)); } } else if (scanner.AllowUnreachable) { IEnumerable <Thing> enumerable3 = enumerable; if (enumerable3 == null) { enumerable3 = pawn.Map.listerThings.ThingsMatching(scanner.PotentialWorkThingRequest); } IntVec3 position = pawn.Position; IEnumerable <Thing> searchSet = enumerable3; Predicate <Thing> validator = predicate; thing = GenClosest.ClosestThing_Global(position, searchSet, 99999f, validator, null); } else { IntVec3 position = pawn.Position; Map map = pawn.Map; ThingRequest potentialWorkThingRequest = scanner.PotentialWorkThingRequest; PathEndMode pathEndMode = scanner.PathEndMode; TraverseParms traverseParams = TraverseParms.For(pawn, scanner.MaxPathDanger(pawn), TraverseMode.ByPawn, false); Predicate <Thing> validator = predicate; bool forceGlobalSearch = enumerable != null; thing = GenClosest.ClosestThingReachable(position, map, potentialWorkThingRequest, pathEndMode, traverseParams, 9999f, validator, enumerable, 0, scanner.MaxRegionsToScanBeforeGlobalSearch, forceGlobalSearch, RegionType.Set_Passable, false); if (scanner is WorkGiver_ConstructDeliverResourcesToBlueprints) { //Preforme further checks too see if this is a reinstall attempt of its own station if (thing is Blueprint_Install) { Blueprint_Install bpthing = (Blueprint_Install)thing; Pawn_Drone pd = (Pawn_Drone)pawn; if (bpthing.MiniToInstallOrBuildingToReinstall == pd.station) { //This is a reinstall attempt - Prevent by setting thing to null thing = null; } } } } if (thing != null) { targetInfo = thing; workGiver_Scanner = scanner; } } if (scanner.def.scanCells) { IntVec3 position2 = pawn.Position; float num2 = 99999f; float num3 = float.MinValue; bool prioritized = scanner.Prioritized; bool allowUnreachable = scanner.AllowUnreachable; Danger maxDanger = scanner.MaxPathDanger(pawn); foreach (IntVec3 intVec in scanner.PotentialWorkCellsGlobal(pawn)) { bool flag = false; float num4 = (float)(intVec - position2).LengthHorizontalSquared; float num5 = 0f; if (prioritized) { if (scanner.HasJobOnCell(pawn, intVec)) { if (!allowUnreachable && !pawn.CanReach(intVec, scanner.PathEndMode, maxDanger, false, false, TraverseMode.ByPawn)) { continue; } num5 = scanner.GetPriority(pawn, intVec); if (num5 > num3 || (num5 == num3 && num4 < num2)) { flag = true; } } } else if (num4 < num2 && scanner.HasJobOnCell(pawn, intVec)) { if (!allowUnreachable && !pawn.CanReach(intVec, scanner.PathEndMode, maxDanger, false, false, TraverseMode.ByPawn)) { continue; } flag = true; } if (flag) { targetInfo = new TargetInfo(intVec, pawn.Map, false); workGiver_Scanner = scanner; num2 = num4; num3 = num5; } } } } } catch (Exception ex) { Log.Error(string.Concat(new object[] { pawn, " threw exception in WorkGiver ", workGiver.def.defName, ": ", ex.ToString() })); } finally { } if (targetInfo.IsValid) { Job job3; if (targetInfo.HasThing) { job3 = workGiver_Scanner.JobOnThing(pawn, targetInfo.Thing, false); } else { job3 = workGiver_Scanner.JobOnCell(pawn, targetInfo.Cell); } if (job3 != null) { return(new ThinkResult(job3, null, new JobTag?(list[j].def.tagToGive), false)); } Log.ErrorOnce(string.Concat(new object[] { workGiver_Scanner, " provided target ", targetInfo, " but yielded no actual job for pawn ", pawn, ". The CanGiveJob and JobOnX methods may not be synchronized." }), 6112651); } num = workGiver.def.priorityInType; } } return(ThinkResult.NoJob); }