public static void RemoveCommUnit(X2_AIRobot pawn) { // Do not remove, if one of the following work types: if (pawn.workSettings.GetPriority(WorkTypeDefOf.Doctor) > 0 || pawn.workSettings.GetPriority(WorkTypeDefOf.Handling) > 0 || pawn.workSettings.GetPriority(WorkTypeDefOf.Warden) > 0) { return; } PawnCapacityDef activity = PawnCapacityDefOf.Talking; if (pawn.health.capacities.CapableOf(activity)) { HediffSet hediffSet = pawn.health.hediffSet; IEnumerable <BodyPartRecord> notMissingParts = hediffSet.GetNotMissingParts(); BodyPartRecord bodyPart = notMissingParts.Where(p => p.def.defName == "AIRobot_CommUnit").FirstOrDefault(); if (bodyPart != null) { DamageInfo damageInfo = new DamageInfo(DamageDefOf.EMP, Mathf.RoundToInt(hediffSet.GetPartHealth(bodyPart)), 0f, -1f, null, bodyPart, null, DamageInfo.SourceCategory.ThingOrUnknown, null); //pawn.TakeDamage(damageInfo); Hediff_MissingPart hediff_MissingPart = (Hediff_MissingPart)HediffMaker.MakeHediff(HediffDefOf.MissingBodyPart, pawn, null); hediff_MissingPart.IsFresh = false; hediff_MissingPart.lastInjury = null; pawn.health.AddHediff(hediff_MissingPart, bodyPart, damageInfo); pawn.health.Notify_HediffChanged(hediff_MissingPart); pawn.apparel.Notify_LostBodyPart(); } } }
public static X2_Building_AIRobotRechargeStation TryFindRechargeStation(X2_AIRobot bot, Map map) { X2_Building_AIRobotRechargeStation foundBase; if (map == null && bot.rechargeStation != null) { map = bot.rechargeStation.Map; } if (map == null) { map = Find.VisibleMap; } if (map == null) { return(default(X2_Building_AIRobotRechargeStation)); } IEnumerable <X2_Building_AIRobotRechargeStation> allBases = map.listerBuildings.AllBuildingsColonistOfClass <X2_Building_AIRobotRechargeStation>(); if (allBases == null) { return(default(X2_Building_AIRobotRechargeStation)); } foundBase = allBases.Where(t => t.robot == bot).FirstOrDefault(); return(foundBase); }
private Toil DespawnIntoContainer(bool doDespawn) { Toil toil = new Toil(); toil.initAction = delegate { X2_AIRobot robot = toil.actor as X2_AIRobot; if (robot != null && robot.rechargeStation != null) { if (doDespawn) { // Despawn active --> robot into the container robot.rechargeStation.AddRobotToContainer(robot); } else { // Only recharge --> robot waits and let recharge robot.rechargeStation.isRechargeActive = true; } } }; toil.defaultCompleteMode = ToilCompleteMode.Instant; return(toil); }
public void AddRobotToContainer(X2_AIRobot bot) { if (bot.HasAttachment(ThingDefOf.Fire)) { bot.GetAttachment(ThingDefOf.Fire).Destroy(DestroyMode.Vanish); } isRechargeActive = false; bot.stances.CancelBusyStanceHard(); bot.jobs.StopAll(false); bot.pather.StopDead(); if (bot.Drafted) { bot.drafter.Drafted = false; } if (!container.Contains(bot)) { container.Add(bot); } List <Map> maps = Find.Maps; for (int i = 0; i < maps.Count; i++) { maps[i].designationManager.RemoveAllDesignationsOn(bot, false); } DespawnRobot(bot, false); }
private void Button_SpawnBot() { if (this.robot != null || robotIsDestroyed) { return; } if (spawnThingDef.NullOrEmpty()) { Log.Error("Robot Recharge Station: Wanted to spawn robot, but spawnThingDef is null or empty!"); return; } X2_AIRobot spawnedRobot = null; if (!IsRobotInContainer()) { spawnedRobot = X2_Building_AIRobotCreator.CreateRobot(spawnThingDef, this.Position, this.Map, Faction.OfPlayer); } else { spawnedRobot = container[0] as X2_AIRobot; container.Remove(spawnedRobot); spawnedRobot = GenSpawn.Spawn(spawnedRobot, this.Position, this.Map) as X2_AIRobot; } this.robot = spawnedRobot; this.robot.rechargeStation = this; this.robotSpawnedOnce = true; this.SpawnRobotAfterRecharge = true; }
public static void SetRobotName(X2_AIRobot robot, NameTriple name) { if (robot == null) { return; } robot.Name = name; }
// When the robot is idle, check if it is inside the room of the recharge station. If not, return there. public override ThinkResult TryIssueJobPackage(Pawn pawn, JobIssueParams jobParams) { X2_AIRobot robot = pawn as X2_AIRobot; if (robot.DestroyedOrNull()) { return(ThinkResult.NoJob); } if (!robot.Spawned) { return(ThinkResult.NoJob); } X2_Building_AIRobotRechargeStation rechargeStation = robot.rechargeStation; if (rechargeStation.DestroyedOrNull()) { return(ThinkResult.NoJob); } if (!rechargeStation.Spawned) { return(ThinkResult.NoJob); } Need_Rest needRest = pawn.needs.rest; if (needRest == null) { return(ThinkResult.NoJob); } float curLevel = needRest.CurLevel; Job jobIdle = new Job(DefDatabase <JobDef> .GetNamed("AIRobot_GoAndWait"), rechargeStation); jobIdle.locomotionUrgency = LocomotionUrgency.Amble; if (curLevel > 0.751f) { return(new ThinkResult(jobIdle, this, JobTag.Idle, false)); } //double distance = AIRobot_Helper.GetDistance(pawn.Position, (pawn as X2_AIRobot).rechargeStation.Position); // //if (distance > 5f) // return ThinkResult.NoJob; //Boolean isInDistance = AIRobot_Helper.IsInDistance(pawn.Position, (pawn as X2_AIRobot).rechargeStation.Position, 5); //if (isInDistance) // return ThinkResult.NoJob; Job job = new Job(DefDatabase <JobDef> .GetNamed("AIRobot_GoRecharge"), rechargeStation); job.locomotionUrgency = LocomotionUrgency.Amble; return(new ThinkResult(job, this, JobTag.SatisfyingNeeds, false)); }
// Self healing //private int timerRepairDamage = 0; private void TryHealDamagedBodyPartOfRobot(X2_AIRobot robot) { //timerRepairDamage--; //if (timerRepairDamage > 0) // return; //timerRepairDamage = 300; if (robot == null || !Verse.Gen.IsHashIntervalTick(robot, 300)) { return; } IEnumerable <Hediff_Injury> hediff_injuries = (from x in robot.health.hediffSet.GetHediffs <Hediff_Injury>() where x.CanHealFromTending() || x.CanHealNaturally() select x); // Apply Treated, but not healing! if (robot.health.HasHediffsNeedingTend(false)) { float quality = (Rand.Value); int batchPosition = 0; foreach (Hediff_Injury injury in from x in robot.health.hediffSet.GetInjuriesTendable() orderby x.Severity descending select x) { injury.Tended(quality, batchPosition); batchPosition++; if (batchPosition >= 1) { break; } } } // Apply healing if (hediff_injuries != null && hediff_injuries.Count() > 0) { Hediff_Injury hediff_Injury2 = hediff_injuries.RandomElement(); float tendQuality = hediff_Injury2.TryGetComp <HediffComp_TendDuration>().tendQuality; float num2 = GenMath.LerpDouble(0f, 1f, 0.5f, 1.5f, Mathf.Clamp01(tendQuality)); ////hediff_Injury2.Heal(22f * num2 * robot.HealthScale * 0.01f); -> At quality 0.5 --> 0.066 healed. //Log.Error("Calculation: " + (GenMath.LerpDouble(0f, 1f, 0.5f, 1.5f, Mathf.Clamp01(tendQuality)).ToString())); //Log.Error("Healing: " + (22f * num2 * robot.HealthScale * 0.1f).ToString()); //Log.Error("PRE:" + hediff_Injury2.Severity.ToString()); //hediff_Injury2.Heal(1f); hediff_Injury2.Heal(22f * num2 * robot.HealthScale * 0.1f * 0.5f); //Log.Error("POST:" + hediff_Injury2.Severity.ToString()); // Throw Healing Mote MoteMaker.ThrowMetaIcon(this.Position, this.Map, ThingDefOf.Mote_HealingCross); } }
public override void ExposeData() { try { try { base.ExposeData(); } catch (Exception ex) { Log.Warning("Warning: X2_Building_AIRobot_RechargeStation -- Unknown error while loading base->ExposeData:\n" + ex.Message + "\n" + ex.StackTrace); } Scribe_Values.Look <bool>(ref this.robotSpawnedOnce, "robotSpawned", false); Scribe_Values.Look <bool>(ref this.robotIsDestroyed, "robotDestroyed", false); Scribe_Values.Look <bool>(ref this.SpawnRobotAfterRecharge, "autospawn", true); Scribe_Values.Look <bool>(ref this.isRechargeActive, "isRechargeActive", false); Scribe_Values.Look <bool>(ref this.isRepairRequestActive, "isRepairRequestActive", false); try { if (Scribe.mode == LoadSaveMode.Saving && robot != null && robot.DestroyedOrNull()) { robot = null; } Scribe_References.Look <X2_AIRobot>(ref robot, "robot", false); // must be before Scribe_Collections -> Else errors! } catch (Exception ex) { Log.Warning("Warning: X2_Building_AIRobot_RechargeStation -- Error while loading 'robot':\n" + ex.Message + "\n" + ex.StackTrace); } try { Scribe_Collections.Look <X2_AIRobot>(ref this.container, "container", LookMode.Deep, null); // new object[0]); -> Throws errors! } catch (Exception ex) { Log.Warning("Warning: X2_Building_AIRobot_RechargeStation -- Error while loading 'container':\n" + ex.Message + "\n" + ex.StackTrace); } } catch (Exception ex) { Log.Error("X2_Building_AIRobot_RechargeStation -- Unknown error while loading:\n" + ex.Message + "\n" + ex.StackTrace); } if (Scribe.mode == LoadSaveMode.PostLoadInit) { updateGraphicForceNeeded = true; if (container == null) { ClearContainer(); } } }
public float GetHealthOfRobot(X2_AIRobot robot, float invalidValue = -1f) { float health = invalidValue; if (robot != null && robot.health != null && robot.health.summaryHealth != null) { health = robot.health.summaryHealth.SummaryHealthPercent; } return(health); }
// When the robot is idle, check if it is inside the room of the recharge station. If not, return there. public override ThinkResult TryIssueJobPackage(Pawn pawn, JobIssueParams jobParams) { X2_AIRobot robot = pawn as X2_AIRobot; if (robot.DestroyedOrNull()) { return(ThinkResult.NoJob); } if (!robot.Spawned) { return(ThinkResult.NoJob); } X2_Building_AIRobotRechargeStation rechargeStation = robot.rechargeStation; if (rechargeStation.DestroyedOrNull()) { return(ThinkResult.NoJob); } if (!rechargeStation.Spawned) { return(ThinkResult.NoJob); } Room roomRecharge = rechargeStation.Position.GetRoom(rechargeStation.Map); Room roomRobot = robot.Position.GetRoom(robot.Map); if (roomRecharge == roomRobot) { return(ThinkResult.NoJob); } // Find target pos, but max 10 cells away! Map mapRecharge = rechargeStation.Map; IntVec3 posRecharge = rechargeStation.Position; IntVec3 cell = roomRecharge.Cells.Where(c => c.Standable(mapRecharge) && !c.IsForbidden(pawn) && AIRobot_Helper.IsInDistance(c, posRecharge, 10) && pawn.CanReach(c, PathEndMode.OnCell, Danger.Some, false, TraverseMode.ByPawn) ) .FirstOrDefault(); if (cell == null || cell == IntVec3.Invalid) { return(ThinkResult.NoJob); } Job jobGoto = new Job(JobDefOf.Goto, cell); jobGoto.locomotionUrgency = LocomotionUrgency.Amble; return(new ThinkResult(jobGoto, this, JobTag.Misc, false)); }
private void Button_ResetDestroyedRobot(bool spawn = true) { if (robot != null && !robot.Destroyed) { robot.Destroy(DestroyMode.Vanish); } this.robot = null; robotIsDestroyed = false; if (spawn) { Button_SpawnBot(); } }
public static NameTriple GetRobotName(X2_AIRobot robot) { if (robot == null || robot.Name == null) { return(null); } NameTriple nameTriple = robot.Name as NameTriple; if (nameTriple != null) { return(new NameTriple(nameTriple.First, nameTriple.Nick, nameTriple.Last)); } return(null); }
private Toil DespawnIntoContainer() { Toil toil = new Toil(); toil.initAction = delegate { X2_AIRobot robot = toil.actor as X2_AIRobot; if (robot != null && robot.rechargeStation != null) { robot.rechargeStation.AddRobotToContainer(robot); } }; toil.defaultCompleteMode = ToilCompleteMode.Instant; return(toil); }
public static X2_AIRobot CreateRobot(string pawnDefName, IntVec3 position, Map map, Faction faction) { PawnKindDef kind = DefDatabase <PawnKindDef> .GetNamed(pawnDefName); PawnGenerationRequest request = new PawnGenerationRequest(kind, faction, PawnGenerationContext.NonPlayer, -1, true, true, false, false, false, false, 0f, false, false, false, false, false, false, false, false, 0, 0, null, 0, null, null, null, null, null, 0f, 0f, Gender.None); X2_AIRobot robot = (X2_AIRobot)PawnGenerator.GeneratePawn(request); robot.workSettings = new X2_AIRobot_Pawn_WorkSettings(robot); if (robot.inventory == null) { robot.inventory = new Pawn_InventoryTracker(robot); } if (true) // robot.RaceProps.ToolUser { if (robot.equipment == null) { robot.equipment = new Pawn_EquipmentTracker(robot); } if (robot.apparel == null) { robot.apparel = new Pawn_ApparelTracker(robot); } } robot.workSettings.EnableAndInitializeIfNotAlreadyInitialized(); //// Check/update faction //if (robot != null) //{ // if (faction != null && (robot.Faction == null || robot.Faction != faction)) // robot.SetFactionDirect(faction); // if (robot.Faction == null && Faction.OfPlayerSilentFail != null) // robot.SetFactionDirect(Faction.OfPlayerSilentFail); //} ////DEBUG //if (robot.workSettings == null) // Log.Error("Worksettings == null!"); //else // Log.Error("Worksettings == OK, EverWork:" + robot.workSettings.EverWork.ToString()); //AIRobot robot = RobotGenerator.GeneratePawn(pawnDefName, faction); IntVec3 spawnPos = position; // GenCellFinder.RandomStandableClosewalkCellNear(position, 1); return((X2_AIRobot)Spawn(robot, spawnPos, map)); }
public void DespawnRobot(X2_AIRobot bot, bool destroying = false) { if (bot != null && !bot.Destroyed) { if (destroying) { bot.Destroy(DestroyMode.Vanish); } else if (bot.Spawned) { bot.DeSpawn(); } } robot = null; }
private void TryUpdateAllowedArea(X2_AIRobot robot) { if (robot.DestroyedOrNull() || !robot.Spawned) { return; } if (ForbidUtility.InAllowedArea(this.Position, robot)) { return; } Messages.Message("AIRobot_MessageRechargeStationOutsideAreaRestriction".Translate(), robot, MessageTypeDefOf.RejectInput); //Remove area from robot robot.playerSettings.Notify_AreaRemoved(robot.playerSettings.AreaRestriction); }
public static X2_Building_AIRobotRechargeStation FindRechargeStationFor(X2_AIRobot sleeper, X2_AIRobot traveler, bool sleeperWillBePrisoner, bool checkSocialProperness, bool medicalBedNeeded = false) { Predicate <Thing> predicate = (Thing t) => { if (!traveler.CanReserveAndReach(t, PathEndMode.OnCell, Danger.Some, 1)) { return(false); } X2_Building_AIRobotRechargeStation foundRechargeStation = t as X2_Building_AIRobotRechargeStation; if (foundRechargeStation == null) { return(false); } if (foundRechargeStation.robot != null && foundRechargeStation.robot != sleeper) { return(false); } if (foundRechargeStation.IsForbidden(traveler)) { return(false); } if (foundRechargeStation.IsBurning()) { return(false); } return(true); }; if (sleeper.rechargeStation != null && predicate(sleeper.rechargeStation)) { X2_Building_AIRobotRechargeStation rStation = sleeper.rechargeStation; if (rStation != null) { return(rStation); } } return(null); }
private void Button_SpawnBot() { if (isRepairRequestActive) { return; } if (this.robot != null || robotIsDestroyed) { if (this.robot != null && this.robot.Spawned && AIRobot_Helper.IsInDistance(this.Position, robot.Position, 3)) { this.robot.jobs.ClearQueuedJobs(); this.robot.stances.CancelBusyStanceHard(); this.robot.jobs.StopAll(false); this.robot.pather.StopDead(); } return; } if (spawnThingDef.NullOrEmpty()) { Log.Error("Robot Recharge Station: Wanted to spawn robot, but spawnThingDef is null or empty!"); return; } X2_AIRobot spawnedRobot = null; if (!IsRobotInContainer()) { spawnedRobot = X2_Building_AIRobotCreator.CreateRobot(spawnThingDef, this.Position, this.Map, Faction.OfPlayer); } else { spawnedRobot = container[0] as X2_AIRobot; container.Remove(spawnedRobot); spawnedRobot = GenSpawn.Spawn(spawnedRobot, this.Position, this.Map) as X2_AIRobot; } this.robot = spawnedRobot; this.robot.rechargeStation = this; this.robotSpawnedOnce = true; this.SpawnRobotAfterRecharge = true; }
public override void DoCell(Rect rect, Pawn pawn, PawnTable table) { TipSignal tooltip = pawn.Label; // normal mode if (pawn != null && !pawn.Destroyed && pawn.Spawned) { if (Widgets.ButtonImage(rect, texNotRecharging)) { X2_AIRobot robot = pawn as X2_AIRobot; //if (robot != null && robot.rechargeStation != null) // robot.rechargeStation.Notify_CallBotForShutdown(); CameraJumper.TryJumpAndSelect(robot); } } // Is recharging else if (pawn != null && !pawn.Destroyed && !pawn.Spawned) { if (Widgets.ButtonImage(rect, texRecharging)) { X2_AIRobot robot = pawn as X2_AIRobot; //if (robot != null && robot.rechargeStation != null) // robot.rechargeStation.Notify_SpawnBot(); <-- ERROR: Creates a NEW robot wich causes ERRORS!!! if (robot != null && robot.rechargeStation != null) { if (Current.ProgramState == ProgramState.Playing && Event.current.button == 0) { Find.MainTabsRoot.EscapeCurrentTab(false); } CameraJumper.TryJumpAndSelect(robot.rechargeStation); } } tooltip.text = "AIRobot_RobotIsRecharging".Translate() + "\n" + pawn.Label; } if (Mouse.IsOver(rect)) { GUI.DrawTexture(rect, TexUI.HighlightTex); } TooltipHandler.TipRegion(rect, tooltip); }
private void TryThrowBatteryMote(X2_AIRobot robot) { if (robot == null) { return; } timerMoteThrow--; if (timerMoteThrow > 0) { return; } timerMoteThrow = 300; float batteryLevel = robot.needs.rest.CurLevel; if (batteryLevel > 0.99f) { return; } if (batteryLevel > 0.90f) { //MoteMaker.ThrowMetaIcon(this.Position, DefDatabase<ThingDef>.GetNamed("Mote_BatteryGreen")); MoteThrowHelper.ThrowBatteryGreen(this.Position.ToVector3(), Map, 0.8f); } else if (batteryLevel > 0.70f) { //MoteMaker.ThrowMetaIcon(this.Position, DefDatabase<ThingDef>.GetNamed("Mote_BatteryYellowYellow")); MoteThrowHelper.ThrowBatteryYellowYellow(this.Position.ToVector3(), Map, 0.8f); } else if (batteryLevel > 0.35f) { //MoteMaker.ThrowMetaIcon(this.Position, DefDatabase<ThingDef>.GetNamed("Mote_BatteryYellow")); MoteThrowHelper.ThrowBatteryYellow(this.Position.ToVector3(), Map, 0.8f); } else { //MoteMaker.ThrowMetaIcon(this.Position, DefDatabase<ThingDef>.GetNamed("Mote_BatteryRed")); MoteThrowHelper.ThrowBatteryRed(this.Position.ToVector3(), Map, 0.8f); } }
public override void DoCell(Rect rect, Pawn pawn, PawnTable table) { if (Widgets.ButtonImage(rect, texShutDown)) { X2_AIRobot robot = pawn as X2_AIRobot; if (robot != null && robot.rechargeStation != null) { robot.rechargeStation.Notify_CallBotForShutdown(); } } if (Mouse.IsOver(rect)) { GUI.DrawTexture(rect, TexUI.HighlightTex); } TipSignal tooltip = pawn.Label; tooltip.text = "AIRobot_ShutDownRobot".Translate() + "\n" + pawn.Label; TooltipHandler.TipRegion(rect, tooltip); }
protected override Job TryGiveJob(Pawn pawn) { X2_AIRobot aiRobot = pawn as X2_AIRobot; X2_Building_AIRobotRechargeStation rechargeStation = AIRobot_Helper.FindRechargeStationFor(aiRobot); if (rechargeStation == null) { return(null); } if (aiRobot.rechargeStation != rechargeStation) { return(null); } Job job = new Job(JobDefOf.Goto, rechargeStation); return(job); }
protected override Job TryGiveJob(Pawn pawn) { X2_AIRobot aiRobot = pawn as X2_AIRobot; X2_Building_AIRobotRechargeStation rechargeStation = AIRobot_Helper.FindRechargeStationFor(aiRobot); if (rechargeStation == null) { return(null); } if (aiRobot.rechargeStation != rechargeStation) { return(null); } Job job = new Job(DefDatabase <JobDef> .GetNamed("AIRobot_GoRecharge"), rechargeStation); return(job); }
public static X2_AIRobot CreateRobot(string pawnDefName, IntVec3 position, Map map, Faction faction) { PawnKindDef kind = DefDatabase <PawnKindDef> .GetNamed(pawnDefName); PawnGenerationRequest request = new PawnGenerationRequest(kind, faction, PawnGenerationContext.NonPlayer, -1, true, true, false, false, false, false, 0f, false, false, true, false, false, false, false, null, null, null, null, null, Gender.Male, null, null); X2_AIRobot robot = (X2_AIRobot)PawnGenerator.GeneratePawn(request); robot.workSettings = new X2_AIRobot_Pawn_WorkSettings(robot); ////DEBUG //if (robot.workSettings == null) // Log.Error("Worksettings == null!"); //else // Log.Error("Worksettings == OK, EverWork:" + robot.workSettings.EverWork.ToString()); //AIRobot robot = RobotGenerator.GeneratePawn(pawnDefName, faction); IntVec3 spawnPos = position; // GenCellFinder.RandomStandableClosewalkCellNear(position, 1); return((X2_AIRobot)Spawn(robot, spawnPos, map)); }
private void TryThrowBatteryMote(X2_AIRobot robot) { if (robot == null) { return; } timerMoteThrow--; if (timerMoteThrow > 0) { return; } timerMoteThrow = 300; float batteryLevel = robot.needs.rest.CurLevel; if (batteryLevel > 0.99f) { return; } if (batteryLevel > 0.90f) { MoteThrowHelper.ThrowBatteryGreen(this.Position.ToVector3(), Map, 0.8f); } else if (batteryLevel > 0.70f) { MoteThrowHelper.ThrowBatteryYellowYellow(this.Position.ToVector3(), Map, 0.8f); } else if (batteryLevel > 0.35f) { MoteThrowHelper.ThrowBatteryYellow(this.Position.ToVector3(), Map, 0.8f); } else { MoteThrowHelper.ThrowBatteryRed(this.Position.ToVector3(), Map, 0.8f); } }
public override IEnumerable <FloatMenuOption> GetFloatMenuOptions(Pawn selPawn) { foreach (FloatMenuOption fmo in base.GetFloatMenuOptions(selPawn)) { yield return(fmo); } X2_AIRobot bot = this.GetRobot; if (GetHealthOfRobot(bot) <= 0.99f) { Dictionary <ThingDef, int> resources = CalculateResourcesNeededForRepairingRobot(this, robotSpawnedOnce); if (resources.Count > 0) { FloatMenuOption fmoStationRobot = AIRobot_Helper.GetFloatMenuOption4RepairStationRobot(selPawn, this, resources); if (fmoStationRobot != null) { yield return(fmoStationRobot); } } } }
protected override bool Satisfied(Pawn pawn) { if (workType == null) { return(false); } X2_AIRobot robot = pawn as X2_AIRobot; if (robot == null) { return(false); } X2_ThingDef_AIRobot robotdef = robot.def as X2_ThingDef_AIRobot; if (robotdef == null) { return(false); } return(robot.CanDoWorkType(workType)); }
public override ThinkResult TryIssueJobPackage(Pawn pawn, JobIssueParams jobParams) { X2_AIRobot robot = pawn as X2_AIRobot; if (robot == null || !robot.Spawned || robot.Destroyed || robot.GetWorkGivers(false) == null) { return(ThinkResult.NoJob); } //Profiler.BeginSample("JobGiver_Work"); //if (emergency && pawn.mindState.priorityWork.IsPrioritized) //{ // List<WorkGiverDef> workGiversByPriority = pawn.mindState.priorityWork.WorkGiver.workType.workGiversByPriority; // for (int i = 0; i < workGiversByPriority.Count; i++) // { // WorkGiver worker = workGiversByPriority[i].Worker; // if (WorkGiversRelated(pawn.mindState.priorityWork.WorkGiver, worker.def)) // { // Job job = GiverTryGiveJobPrioritized(pawn, worker, pawn.mindState.priorityWork.Cell); // if (job != null) // { // job.playerForced = true; // return new ThinkResult(job, this, workGiversByPriority[i].tagToGive); // } // } // } // pawn.mindState.priorityWork.Clear(); //} List <WorkGiver> list = robot.GetWorkGivers(false); // Get Non-Emergency WorkGivers int num = -999; TargetInfo bestTargetOfLastPriority = TargetInfo.Invalid; WorkGiver_Scanner scannerWhoProvidedTarget = null; WorkGiver_Scanner scanner; IntVec3 pawnPosition; bool prioritized; bool allowUnreachable; Danger maxPathDanger; for (int j = 0; j < list.Count; j++) { WorkGiver workGiver = list[j]; if (workGiver.def.priorityInType != num && bestTargetOfLastPriority.IsValid) { break; } if (!PawnCanUseWorkGiver(pawn, workGiver)) { continue; } try { Job job2 = workGiver.NonScanJob(pawn); if (job2 != null) { return(new ThinkResult(job2, this, list[j].def.tagToGive)); } scanner = (workGiver as WorkGiver_Scanner); float closestDistSquared; float bestPriority; if (scanner != null) { if (scanner.def.scanThings) { Predicate <Thing> validator = (Thing t) => !t.IsForbidden(pawn) && scanner.HasJobOnThing(pawn, t); IEnumerable <Thing> enumerable = scanner.PotentialWorkThingsGlobal(pawn); Thing thing; try { if (scanner.Prioritized) { IEnumerable <Thing> enumerable2 = enumerable; if (enumerable2 == null) { enumerable2 = pawn.Map.listerThings.ThingsMatching(scanner.PotentialWorkThingRequest); } thing = ((!scanner.AllowUnreachable) ? GenClosest.ClosestThing_Global_Reachable(pawn.Position, pawn.Map, enumerable2, scanner.PathEndMode, TraverseParms.For(pawn, scanner.MaxPathDanger(pawn)), 9999f, validator, (Thing x) => scanner.GetPriority(pawn, x)) : GenClosest.ClosestThing_Global(pawn.Position, enumerable2, 99999f, 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); } thing = GenClosest.ClosestThing_Global(pawn.Position, enumerable3, 99999f, validator); } else { thing = GenClosest.ClosestThingReachable(pawn.Position, pawn.Map, scanner.PotentialWorkThingRequest, scanner.PathEndMode, TraverseParms.For(pawn, scanner.MaxPathDanger(pawn)), 9999f, validator, enumerable, 0, scanner.MaxRegionsToScanBeforeGlobalSearch, enumerable != null); } } catch (Exception ex) { Log.Error("Error in WorkGiver: " + ex.Message); thing = null; } if (thing != null) { bestTargetOfLastPriority = thing; scannerWhoProvidedTarget = scanner; } } if (scanner.def.scanCells) { pawnPosition = pawn.Position; closestDistSquared = 99999f; bestPriority = float.MinValue; prioritized = scanner.Prioritized; allowUnreachable = scanner.AllowUnreachable; maxPathDanger = scanner.MaxPathDanger(pawn); IEnumerable <IntVec3> enumerable4 = scanner.PotentialWorkCellsGlobal(pawn); IList <IntVec3> list2; if ((list2 = (enumerable4 as IList <IntVec3>)) != null) { for (int k = 0; k < list2.Count; k++) { ProcessCell(list2[k]); } } else { foreach (IntVec3 item in enumerable4) { ProcessCell(item); } } } } void ProcessCell(IntVec3 c) { bool flag = false; float num2 = (c - pawnPosition).LengthHorizontalSquared; float num3 = 0f; if (prioritized) { if (!c.IsForbidden(pawn) && scanner.HasJobOnCell(pawn, c)) { if (!allowUnreachable && !pawn.CanReach(c, scanner.PathEndMode, maxPathDanger)) { return; } num3 = scanner.GetPriority(pawn, c); if (num3 > bestPriority || (num3 == bestPriority && num2 < closestDistSquared)) { flag = true; } } } else if (num2 < closestDistSquared && !c.IsForbidden(pawn) && scanner.HasJobOnCell(pawn, c)) { if (!allowUnreachable && !pawn.CanReach(c, scanner.PathEndMode, maxPathDanger)) { return; } flag = true; } if (flag) { bestTargetOfLastPriority = new TargetInfo(c, pawn.Map); scannerWhoProvidedTarget = scanner; closestDistSquared = num2; bestPriority = num3; } } } catch (Exception ex) { Log.Error(pawn + " threw exception in WorkGiver " + workGiver.def.defName + ": " + ex.ToString()); } finally { } if (bestTargetOfLastPriority.IsValid) { Job job3 = (!bestTargetOfLastPriority.HasThing) ? scannerWhoProvidedTarget.JobOnCell(pawn, bestTargetOfLastPriority.Cell) : scannerWhoProvidedTarget.JobOnThing(pawn, bestTargetOfLastPriority.Thing); if (job3 != null) { job3.workGiverDef = scannerWhoProvidedTarget.def; return(new ThinkResult(job3, this, list[j].def.tagToGive)); } Log.ErrorOnce(scannerWhoProvidedTarget + " provided target " + bestTargetOfLastPriority + " 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); }
public override void Tick() { base.Tick(); //Handle graphic update UpdateGraphic(); // robot in container => recharge or release needed? if (robot == null) { if (notify_spawnRequested) { // Don't start all robots at the same time if (!this.IsHashIntervalTick(5)) { return; } notify_spawnRequested = false; Button_SpawnBot(); return; } if (IsRobotInContainer()) { X2_AIRobot containedRobot = container[0] as X2_AIRobot; if (containedRobot == null) { container.Remove(container[0]); return; } if (SpawnRobotAfterRecharge && containedRobot.needs.rest.CurLevel >= 0.99f) { Button_SpawnBot(); } else if (containedRobot.needs.rest.CurLevel < 1f) { containedRobot.needs.rest.CurLevel += (0.1f / GenDate.TicksPerHour) * rechargeEfficiency; if (containedRobot.needs.rest.CurLevel > 1f) { containedRobot.needs.rest.CurLevel = 1f; } TryThrowBatteryMote(containedRobot); } // Try to heal robot TryHealDamagedBodyPartOfRobot(containedRobot); return; } } notify_spawnRequested = false; if (robotIsDestroyed) { // What do we do, when the robot is destroyed? TryThrowNoRobotMote(this); // Last step: do nothing more! return; } if (robot == null && (!robotSpawnedOnce || !IsRobotInContainer())) { return; } // if the robot is dead... if (robotSpawnedOnce && !IsRobotInContainer() && (robot == null || robot.Destroyed || robot.Dead)) { if ((robot.Destroyed || robot.Dead) && robot.Corpse != null) { robot.Corpse.Destroy(DestroyMode.Vanish); } robotIsDestroyed = true; return; } if (isRechargeActive && robot != null && Gen.IsHashIntervalTick(robot, 30) && !AIRobot_Helper.IsInDistance(robot.Position, this.Position, 3)) { robot.jobs.ClearQueuedJobs(); isRechargeActive = false; } if (isRechargeActive) { if (robot.needs.rest.CurLevel < 1f) { robot.needs.rest.CurLevel += (0.1f / GenDate.TicksPerHour) * rechargeEfficiency * 2; if (robot.needs.rest.CurLevel > 1f) { robot.needs.rest.CurLevel = 1f; } TryThrowBatteryMote(robot); } else { robot.jobs.ClearQueuedJobs(); robot.jobs.EndCurrentJob(JobCondition.Succeeded, true); isRechargeActive = false; } return; } if (!Gen.IsHashIntervalTick(robot, 250)) { return; } TryUpdateAllowedArea(robot); if (calcDistanceRestCheck == -1) { calcDistanceRestCheck = AIRobot_Helper.GetSlopePoint(robot.GetStatValue(StatDefOf.MoveSpeed, true), 1f, 6f, 15f, 40f); // movementspeed slope: speed 1 -> 30 cells, speed 6 -> 50 cells } // If battery of robot is < 40% and distance > 25 cells => try to recall him // Also recall if battery is < 10% (emergency if ThinkTree isn't working) if ((robot.needs.rest.CurLevel < 0.40f && !AIRobot_Helper.IsInDistance(this.Position, robot.Position, calcDistanceRestCheck)) || robot.needs.rest.CurLevel < 0.10f) { Notify_CallBotForRecharge(); } }