private void StartRepairJob(Pawn pawn) { List <Thing> foundIngredients; List <int> foundIngredientsCount; List <Thing> foundIngredients2; List <int> foundIngredients2Count; if (!AIRobot_Helper.GetAllNeededIngredients(pawn, DefDatabase <ThingDef> .GetNamed(ingredientDefName), this.ingredientNeedCount, out foundIngredients, out foundIngredientsCount) || foundIngredients == null || foundIngredients.Count == 0) { return; } if (!AIRobot_Helper.GetAllNeededIngredients(pawn, DefDatabase <ThingDef> .GetNamed(ingredient2DefName), this.ingredient2NeedCount, out foundIngredients2, out foundIngredients2Count) || foundIngredients == null || foundIngredients.Count == 0) { return; } //Log.Error("foundIngredients="+foundIngredients.Count.ToString() + " " + "foundIngredientsCount="+foundIngredientsCount.Count.ToString()); List <LocalTargetInfo> ingredientsLTI = new List <LocalTargetInfo>(); foreach (Thing t in foundIngredients) { ingredientsLTI.Add(t); } foreach (Thing t in foundIngredients2) { ingredientsLTI.Add(t); } X2_JobDriver_RepairDamagedRobot repairRobot = new X2_JobDriver_RepairDamagedRobot(); Job job = new Job(DefDatabase <JobDef> .GetNamed(this.jobDefName_repair), this.rechargestation, foundIngredients[0], this); job.targetQueueB = ingredientsLTI; job.countQueue = foundIngredientsCount; pawn.jobs.StopAll(); pawn.jobs.StartJob(job); Log.Error("Pawn.CurJob:" + pawn.CurJob.def.defName); //Log.Error("Job: "+ job.def.defName + " Ingredients: "+ foundIngredientsCount[0].ToString()); }
public override string GetInspectString() { if (DebugSettings.godMode) { string workString = base.GetInspectString(); if (Position != null && Position != IntVec3.Invalid && rechargeStation != null && rechargeStation.Position != null && rechargeStation.Position != IntVec3.Invalid) { if (!workString.NullOrEmpty()) { workString += "\n"; } workString += "Distance to base: " + AIRobot_Helper.GetDistance(Position, rechargeStation.Position).ToString("0") + " cells"; workString += " -- Remaining charge: " + needs.rest.CurLevel.ToStringPercent(); } return(workString); } return(base.GetInspectString()); }
private static Boolean AreAllNeededResourcesAvailable(Dictionary <ThingDef, int> resources, Pawn pawn) { List <string> missingResources = new List <string>(); foreach (ThingDef ingredientDef in resources.Keys) { int availableResources; AIRobot_Helper.FindAvailableNearbyResources(ingredientDef, pawn, out availableResources); if (availableResources < resources[ingredientDef]) { missingResources.Add("(" + availableResources.ToString() + " / " + resources[ingredientDef].ToString() + " " + ingredientDef.LabelCap + ")"); } } if (missingResources.Count == 0) { return(true); } return(false); }
public static Job GetStationRepairJob(Pawn pawn, X2_Building_AIRobotRechargeStation station, Dictionary <ThingDef, int> resources) { string jobDefName = "AIRobot_RepairStationRobot"; List <Thing> foundIngredients = new List <Thing>(); List <int> foundIngredientsCount = new List <int>(); List <Thing> workIngredients = new List <Thing>(); List <int> workIngredientCount = new List <int>(); if (resources != null) { foreach (ThingDef ingredientDef in resources.Keys) { if (!AIRobot_Helper.GetAllNeededIngredients(pawn, ingredientDef, resources[ingredientDef], out workIngredients, out workIngredientCount) || workIngredients == null || workIngredients.Count == 0) { return(null); } foundIngredients.AddRange(workIngredients); foundIngredientsCount.AddRange(workIngredientCount); } } //X2_JobDriver_RepairStationRobot repairRobot = new X2_JobDriver_RepairStationRobot(); Job job = new Job(DefDatabase <JobDef> .GetNamed(jobDefName), station, null, station.Position); job.count = 1; job.targetQueueB = new List <LocalTargetInfo>(); //new List<LocalTargetInfo>(foundIngredients.Count); job.countQueue = new List <int>(foundIngredients.Count); for (int i = 0; i < foundIngredients.Count; i++) { job.targetQueueB.Add(foundIngredients[i]); job.countQueue.Add(foundIngredientsCount[i]); } job.haulMode = HaulMode.ToCellNonStorage; return(job); }
public static List <string> GetStationRepairJobMissingThingStrings(Dictionary <ThingDef, int> resources, Pawn pawn) { List <string> missingResources = new List <string>(); if (resources == null) { return(missingResources); } foreach (ThingDef ingredientDef in resources.Keys) { int availableResources; AIRobot_Helper.FindAvailableNearbyResources(ingredientDef, pawn, out availableResources); if (availableResources < resources[ingredientDef]) { missingResources.Add("(" + availableResources.ToString() + " / " + resources[ingredientDef].ToString() + " " + GetThingDefLabel(ingredientDef) + ")"); //return new FloatMenuOption("AIRobot_RepairRobot".Translate().CapitalizeFirst() + ": " + "NotEnoughStoredLower".Translate() + " (" + availableResources.ToString() + " / " + resources[ingredientDef].ToString() + " " + ingredientDef.LabelCap + ")", null); } } return(missingResources); }
private static Boolean AreAllNeededResourcesAvailable(Dictionary <ThingDef, int> resources, Pawn pawn) { List <string> missingResources = new List <string>(); foreach (ThingDef ingredientDef in resources.Keys) { int availableResources; AIRobot_Helper.FindAvailableNearbyResources(ingredientDef, pawn, out availableResources); if (availableResources < resources[ingredientDef]) { missingResources.Add("(" + availableResources.ToString() + " / " + resources[ingredientDef].ToString() + " " + ingredientDef.LabelCap + ")"); //return new FloatMenuOption("AIRobot_RepairRobot".Translate().CapitalizeFirst() + ": " + "NotEnoughStoredLower".Translate() + " (" + availableResources.ToString() + " / " + resources[ingredientDef].ToString() + " " + ingredientDef.LabelCap + ")", null); } } if (missingResources.Count == 0) { return(true); } return(false); }
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); } } } }
public override string GetInspectString() { string workString = base.GetInspectString(); if (DebugSettings.godMode) { if (Position != null && Position != IntVec3.Invalid && rechargeStation != null && rechargeStation.Position != null && rechargeStation.Position != IntVec3.Invalid) { if (!workString.NullOrEmpty()) { workString += "\n"; } workString += "Distance to base: " + AIRobot_Helper.GetDistance(Position, rechargeStation.Position).ToString("0") + " cells"; workString += " -- "; workString += "AIRobot_Battery".Translate() + " " + needs.rest.CurLevel.ToStringPercent(); } } else { if (!workString.NullOrEmpty()) { workString += "\n"; } workString += "AIRobot_Battery".Translate() + " " + needs.rest.CurLevel.ToStringPercent(); } if (isSleepModeActive) { if (!workString.NullOrEmpty()) { workString += "\n"; } workString += "AIRobot_SleepMode".Translate(); } return(workString.TrimEndNewlines()); }
//private static Designator_Deconstruct designatorDeconstruct = new Designator_Deconstruct(); /// <summary> /// This creates new selection buttons with a new graphic /// </summary> /// <returns></returns> public override IEnumerable <Gizmo> GetGizmos() { int groupBaseKey = 31367676; foreach (Gizmo gizmo in base.GetGizmos()) { yield return(gizmo); } if (robot == null && !robotIsDestroyed) { // Key-Binding N - Start robot Command_Action act2; act2 = new Command_Action(); act2.defaultLabel = lbSpawnOwner.Translate(); act2.defaultDesc = txtSpawnOwner.Translate(); act2.icon = UI_ButtonStart; act2.hotKey = KeyBindingDefOf.Misc4; act2.activateSound = SoundDef.Named("Click"); act2.action = Button_SpawnBot; if (!Map.IsPlayerHome || Map.IsTempIncidentMap) { act2.disabled = true; act2.disabledReason = txtDisabledBecauseNotHomeMap.Translate(); } else { act2.disabled = (powerComp != null && !powerComp.PowerOn) || isRepairRequestActive; if (!isRepairRequestActive) { act2.disabledReason = txtNoPower.Translate(); } else { act2.disabledReason = txtRapairRequested.Translate(); } } act2.groupKey = groupBaseKey + 1; yield return(act2); } if ((robot != null || robotSpawnedOnce) && !robotIsDestroyed) { // Key-Binding M - Deactivate robot Command_Action act1; act1 = new Command_Action(); //act1.disabled = owner == null; //act1.disabledReason = txtNoOwner.Translate(); act1.defaultLabel = lbSendOwnerToRecharge.Translate(); act1.defaultDesc = txtSendOwnerToRecharge.Translate(); act1.icon = UI_ButtonForceRecharge; act1.hotKey = KeyBindingDefOf.Misc7; act1.activateSound = SoundDef.Named("Click"); act1.action = Notify_CallBotForShutdown; act1.disabled = (powerComp != null && !powerComp.PowerOn) || isRepairRequestActive; if (!isRepairRequestActive) { act1.disabledReason = txtNoPower.Translate(); } else { act1.disabledReason = txtRapairRequested.Translate(); } act1.groupKey = groupBaseKey + 2; yield return(act1); } { // Key-Binding K - Deactivate ALL robots Command_Action act3; act3 = new Command_Action(); act3.defaultLabel = lbRecallAllRobots.Translate(); act3.defaultDesc = txtRecallAllRobots.Translate(); act3.icon = UI_ButtonForceRechargeAll; act3.hotKey = KeyBindingDefOf.Misc8; act3.activateSound = SoundDef.Named("Click"); act3.action = Button_CallAllBotsForShutdown; act3.disabled = powerComp != null && !powerComp.PowerOn; act3.disabledReason = txtNoPower.Translate(); act3.groupKey = groupBaseKey + 3; yield return(act3); } { // Key-Binding L - Activate ALL robots Command_Action act4; act4 = new Command_Action(); act4.defaultLabel = lbActivateAllRobots.Translate(); act4.defaultDesc = txtActivateAllRobots.Translate(); act4.icon = UI_ButtonForceActivateAll; act4.hotKey = KeyBindingDefOf.Misc10; act4.activateSound = SoundDef.Named("Click"); act4.action = Button_SpawnAllAvailableBots; act4.disabled = powerComp != null && !powerComp.PowerOn; act4.disabledReason = txtNoPower.Translate(); act4.groupKey = groupBaseKey + 4; yield return(act4); } float health = GetHealthOfRobot(GetRobot, -1f); if (health != -1f && health < 0.90f || GetRobot == null && robotSpawnedOnce) { Dictionary <ThingDef, int> resources = CalculateResourcesNeededForRepairingRobot(this, robotSpawnedOnce); string hintText = txtRepairRobot.Translate(); bool first = true; foreach (ThingDef thingDef in resources.Keys) { int count = resources[thingDef]; if (!first) { hintText = hintText + ", "; } else { hintText = hintText + "\n"; } hintText = hintText + count.ToString() + "x " + AIRobot_Helper.GetThingDefLabel(thingDef); first = false; } hintText += "\n"; hintText += AIRobot_Helper.GetPossiblePawnsForRobotRepair(Map); // Key-Binding O - Request repair of damaged robot Command_Action act6; act6 = new Command_Action(); act6.defaultLabel = lbRepairRobot.Translate(); act6.defaultDesc = hintText; if (!isRepairRequestActive) { act6.icon = UI_ButtonRepair_NotActive; } else { act6.icon = UI_ButtonRepair_Active; } act6.hotKey = KeyBindingDefOf.Misc9; act6.activateSound = SoundDef.Named("Click"); act6.action = Button_RequestRepair4Robot; act6.disabled = this.robot != null && !this.robotIsDestroyed; // Disable when the robot is up and running act6.disabledReason = txtRobotNotDeactivated.Translate(); act6.groupKey = groupBaseKey + 6; yield return(act6); } { // Key-Binding O - Find robot Command_Action act5; act5 = new Command_Action(); act5.defaultLabel = lbFindRobot.Translate(); act5.defaultDesc = txtFindRobot.Translate(); act5.icon = UI_ButtonSearch; act5.hotKey = KeyBindingDefOf.Misc11; act5.activateSound = SoundDef.Named("Click"); act5.action = Button_FindRobot; act5.disabled = powerComp != null && !powerComp.PowerOn; act5.disabledReason = txtNoPower.Translate(); act5.groupKey = groupBaseKey + 5; yield return(act5); } if (DebugSettings.godMode) { // Key-Binding - (DEBUG) Reset robot Command_Action act9; act9 = new Command_Action(); act9.defaultLabel = "(DEBUG) Reset destroyed robot"; act9.defaultDesc = ""; act9.icon = BaseContent.BadTex; act9.hotKey = null; act9.activateSound = SoundDef.Named("Click"); act9.action = Button_ResetDestroyedRobot; act9.disabled = false; act9.disabledReason = ""; act9.groupKey = groupBaseKey + 9; yield return(act9); // Key-Binding - (DEBUG) Repair damaged robot Command_Action act10; act10 = new Command_Action(); act10.defaultLabel = "(DEBUG) Repair damaged robot"; act10.defaultDesc = ""; act10.icon = BaseContent.BadTex; act10.hotKey = null; act10.activateSound = SoundDef.Named("Click"); act10.action = Button_RepairDamagedRobot; act10.disabled = false; act10.disabledReason = ""; act10.groupKey = groupBaseKey + 10; yield return(act10); } }
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(); } }
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(); } //// Check/update faction //if (robot != null) //{ // if (this.Faction != null && (robot.Faction == null || robot.Faction != this.Faction)) // robot.SetFactionDirect(this.Faction); // if (robot.Faction == null && Faction.OfPlayerSilentFail != null) // robot.SetFactionDirect(Faction.OfPlayerSilentFail); //} return; } if (spawnThingDef.NullOrEmpty()) { Log.Error("Robot Recharge Station: Wanted to spawn robot, but spawnThingDef is null or empty!"); return; } X2_AIRobot spawnedRobot; 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; // Check/update faction if (robot != null) { if (this.Faction != null && (robot.Faction == null || robot.Faction != this.Faction)) { robot.SetFactionDirect(this.Faction); } if (robot.Faction == null && Faction.OfPlayerSilentFail != null) { robot.SetFactionDirect(Faction.OfPlayerSilentFail); } } }
private void Button_RepairDamagedRobot() { NameTriple name = null; string first = null, nick = null, last = null; Area area = null; X2_AIRobot bot = this.robot; if (bot == null && this.container.FirstOrDefault() != null) { bot = this.container.FirstOrDefault(); } if (bot != null) { name = AIRobot_Helper.GetRobotName(bot); } if (bot != null && bot.playerSettings != null) { area = bot.playerSettings.AreaRestriction; } if (name != null) { first = name.First; nick = name.Nick; last = name.Last; name = null; } if (bot != null && !bot.Destroyed && bot.Spawned) { bot.Destroy(DestroyMode.Vanish); } this.container.Clear(); this.robot = null; this.robotIsDestroyed = false; this.isRepairRequestActive = false; Button_SpawnBot(); this.disabledRobot = null; if (first != null && nick != null && last != null) { name = new NameTriple(first, nick, last); } // Robot should again be filled (with the new robot) if (this.robot != null) { if (name != null) { AIRobot_Helper.SetRobotName(this.robot, name); } if (area != null) { this.robot.playerSettings.AreaRestriction = area; } } }
public override float GetPriority(Pawn pawn) { if (pawn == null || pawn.needs == null) { return(0f); } Need_Rest needRest = pawn.needs.rest; if (needRest == null) { return(0f); } float curLevel = needRest.CurLevel; TimeAssignmentDef timeAssignmentDef = (pawn.timetable != null ? pawn.timetable.CurrentAssignment : TimeAssignmentDefOf.Anything); if (timeAssignmentDef == TimeAssignmentDefOf.Anything || timeAssignmentDef == TimeAssignmentDefOf.Work) { if ((pawn as X2_AIRobot) == null || (pawn as X2_AIRobot).rechargeStation == null || (pawn as X2_AIRobot).rechargeStation.Position == null) { return(0f); } double distance = AIRobot_Helper.GetDistance(pawn.Position, (pawn as X2_AIRobot).rechargeStation.Position); // Own implementation: When level < 45% && dist > 25 bool isOutsideMaxDistance = distance > 25f; if (curLevel < 0.40f && pawn as X2_AIRobot != null && isOutsideMaxDistance) { return(8f); } //// Own implementation: When level < 70% && idle //bool isInsideCloseCallRange = distance < 15f && distance > 0f; //if (curLevel < 0.70f && pawn as X2_AIRobot != null && isInsideCloseCallRange && // (pawn.CurJobDef == null || pawn.CurJobDef == JobDefOf.Wait_Wander || pawn.CurJobDef == JobDefOf.GotoWander || pawn.CurJobDef == JobDefOf.Wait)) // return 8f; if (curLevel < 0.25f) { return(8f); } return(0f); } if (timeAssignmentDef == TimeAssignmentDefOf.Joy) { if (curLevel < 0.3f) { return(8f); } return(0f); } if (timeAssignmentDef == TimeAssignmentDefOf.Sleep) { if (curLevel < 0.75f) { return(8f); } return(0f); } return(0f); }
public override void Tick() { base.Tick(); //Handle graphic update UpdateGraphic(); // robot in container => recharge or release needed? if (robot == null && 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; } if (robotIsDestroyed) { // TODO: What do we do, when the robot is destroyed? // 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 (!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 } //Log.Error("Max allowed distance: " + calcDistanceRestCheck.ToString("0.##") + " / MoveSpeed: " + robot.GetStatValue(StatDefOf.MoveSpeed, true).ToString()); // 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) { Button_CallBotForShutdown(); SpawnRobotAfterRecharge = true; } }