private void Button_CallAllBotsForShutdown() { List <X2_Building_AIRobotRechargeStation> buildings = Map.listerThings.AllThings.OfType <X2_Building_AIRobotRechargeStation>().ToList(); for (int i = buildings.Count; i > 0; i--) { X2_Building_AIRobotRechargeStation building = buildings[i - 1]; building.Notify_CallBotForShutdown(); } }
private void Button_SpawnAllAvailableBots() { List <X2_Building_AIRobotRechargeStation> buildings = Map.listerThings.AllThings.OfType <X2_Building_AIRobotRechargeStation>().ToList(); for (int i = buildings.Count; i > 0; i--) { X2_Building_AIRobotRechargeStation building = buildings[i - 1]; building.Notify_SpawnBot(); } }
public static Job TryCreateJob(Pawn pawn, Thing t, bool forced = false) { if (!CanPawnWorkThisJob(pawn, t, forced)) { return(null); } X2_Building_AIRobotRechargeStation t1 = (t as X2_Building_AIRobotRechargeStation); return(AIRobot_Helper.GetStationRepairJob(pawn, t1, t1.isRepairRequestCosts)); }
// 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)); }
public override void Destroy(DestroyMode mode = DestroyMode.Vanish) { IntVec3 oldPos = this.Position != IntVec3.Invalid ? this.Position : this.PositionHeld; Map oldMap = this.Map != null ? this.Map : this.MapHeld; X2_Building_AIRobotRechargeStation oldRechargeStation = this.rechargeStation; ThingDef wDef = null; if (this != null && this.def2 != null && this.def2.destroyedDef != null) { wDef = this.def2.destroyedDef; } try { base.Destroy(DestroyMode.Vanish); } catch (Exception ex) { Log.Warning(ex.Message + "\n" + ex.StackTrace); } // --- !!! NEW Approach !!! --- TrySpawnResources(oldMap, oldPos); try { IEnumerable <Thing> corpses = oldMap.listerThings.AllThings.Where <Thing>(t => t.Spawned && t == this.Corpse); foreach (Thing corpse in corpses) { corpse.Destroy(DestroyMode.Vanish); } } catch (Exception ex) { Log.Warning("Couldn't destroy corpses.\n" + ex.StackTrace); } // --- !!! OLD Approach !!! --- //// spawn destroyed object here //if (mode != DestroyMode.Vanish && wDef != null) //{ // X2_AIRobot_disabled thing = (X2_AIRobot_disabled)GenSpawn.Spawn(wDef, oldPos, oldMap); // thing.stackCount = 1; // thing.rechargestation = oldRechargeStation; // thing.SetFactionDirect(this.Faction); // // set the disabled robot in the recharge station // oldRechargeStation.disabledRobot = thing; //} }
public static void StartStationRepairJob(Pawn pawn, X2_Building_AIRobotRechargeStation station, Dictionary <ThingDef, int> resources) { Job job = GetStationRepairJob(pawn, station, resources); if (job == null) { return; } pawn.jobs.StopAll(); pawn.jobs.StartJob(job); }
public override void Tick() { // Prevent ticks, if you aren't living anymore! if (this.DestroyedOrNull()) { //Log.Error("I'm destroyed but ticking.."); return; } if (Spawned && (Dead || Downed || needs.rest.CurLevel <= 0.02f)) { this.Destroy(DestroyMode.KillFinalize); return; } base.Tick(); // needed? if (needs.food != null && needs.food.CurLevel < 1.0f) { needs.food.CurLevel = 1f; } // Learning disabled? if (def2 == null || !def2.allowLearning) { foreach (SkillRecord skill in skills.skills) { if (skill.xpSinceLastLevel > 1) { skill.xpSinceLastLevel = 1; skill.xpSinceMidnight = 1; } } } if (this.Spawned) { if (rechargeStation == null) { rechargeStation = TryFindRechargeStation(this, Map); } // Remove unwanted HeDiffs if (!Gen.IsHashIntervalTick(this, 500)) { RemoveUnwantedHediffs(this); } } }
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); }
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); }
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); }
public override void DoCell(Rect rect, Pawn pawn, PawnTable table) { if (Widgets.ButtonImage(rect, texShutDown)) { List <X2_Building_AIRobotRechargeStation> buildings = pawn.Map.listerThings.AllThings.OfType <X2_Building_AIRobotRechargeStation>().ToList(); for (int i = buildings.Count; i > 0; i--) { X2_Building_AIRobotRechargeStation building = buildings[i - 1]; building.Notify_CallBotForShutdown(); } } if (Mouse.IsOver(rect)) { GUI.DrawTexture(rect, TexUI.HighlightTex); } TipSignal tooltip = pawn.Label; tooltip.text = "AIRobot_ShutDownAllRobots".Translate(); TooltipHandler.TipRegion(rect, tooltip); }
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 override void Destroy(DestroyMode mode = DestroyMode.Vanish) { IntVec3 oldPos = this.Position != IntVec3.Invalid ? this.Position : this.PositionHeld; Map oldMap = this.Map != null ? this.Map : this.MapHeld; X2_Building_AIRobotRechargeStation oldRechargeStation = this.rechargeStation; ThingDef wDef = null; if (this != null && this.def2 != null && this.def2.destroyedDef != null) { wDef = this.def2.destroyedDef; } base.Destroy(DestroyMode.Vanish); // spawn destroyed object here if (mode != DestroyMode.Vanish && wDef != null) { X2_AIRobot_disabled thing = (X2_AIRobot_disabled)GenSpawn.Spawn(wDef, oldPos, oldMap); thing.stackCount = 1; thing.rechargestation = oldRechargeStation; } }
private void TryThrowNoRobotMote(X2_Building_AIRobotRechargeStation station) { if (station == null) { return; } timerNoRobotMoteThrow--; if (timerNoRobotMoteThrow > 0) { return; } timerNoRobotMoteThrow = 800; if (!station.robotIsDestroyed) { return; } MoteThrowHelper.ThrowNoRobotSign(this.Position.ToVector3(), Map, 0.8f); }
public override void Tick() { base.Tick(); // needed? if (needs.food != null && needs.food.CurLevel < 1.0f) { needs.food.CurLevel = 1f; } // Learning disabled? if (def2 == null || !def2.allowLearning) { foreach (SkillRecord skill in skills.skills) { if (skill.xpSinceLastLevel > 1) { skill.xpSinceLastLevel = 1; skill.xpSinceMidnight = 1; } } } if (Spawned && (Dead || Downed || needs.rest.CurLevel <= 0.02f)) { this.Destroy(DestroyMode.KillFinalize); return; } if (this.Spawned) { if (rechargeStation == null) { rechargeStation = TryFindRechargeStation(this, Map); } } }
public Dictionary <ThingDef, int> CalculateResourcesNeededForRepairingRobot(X2_Building_AIRobotRechargeStation station, bool wasSpawned) { Dictionary <ThingDef, int> resources = new Dictionary <ThingDef, int>(); try { float health = 0f; health = GetHealthOfRobot(station.GetRobot, 0f); if (health < 0.99f) { float missing = 1f - health; List <ThingDefCountClass> costs = null; //1st Try: get robotRepairCost if (station != null && station.def2 != null) { costs = station.def2.robotRepairCosts; } //2nd Try: Get costList * 0.6 if (costs == null || costs.Count == 0) { List <ThingDefCountClass> costsCL = station.def2.costList; costs = new List <ThingDefCountClass>(); foreach (ThingDefCountClass c in costsCL) { ThingDefCountClass _c = new ThingDefCountClass(c.thingDef, (int)(c.count * 0.6f)); costs.Add(c); } } //Log.Error("robotRepairCosts:" + ( costs == null ? "null" : costs.Count.ToString() )); // 3rd Try: If still nothing is set, create a basic cost list with defined values if (costs == null || costs.Count == 0) { costs = new List <ThingDefCountClass>(); ThingDefCountClass tDefCC; tDefCC = new ThingDefCountClass(ThingDefOf.Steel, 45); costs.Add(tDefCC); tDefCC = new ThingDefCountClass(ThingDefOf.ComponentIndustrial, 3); costs.Add(tDefCC); //tDefCC = new ThingDefCountClass(ThingDefOf.Gold, 5); //costs.Add(tDefCC); } foreach (ThingDefCountClass cost in costs) { int count = (int)Math.Floor(cost.count * missing); if (count <= 1) //if (count <= 0) { continue; } resources.Add(cost.thingDef, count); } } } catch (Exception ex) { Log.Error(ex.Message + "\n" + ex.StackTrace); } return(resources); }
protected override IEnumerable <Toil> MakeNewToils() { //Workbench giver destroyed (only in bill using phase! Not in carry phase) this.AddEndCondition(() => { var targ = GetActor().jobs.curJob.GetTarget(StationIndex).Thing; if (targ == null || (targ is Building && !targ.Spawned)) { return(JobCondition.Incompletable); } return(JobCondition.Ongoing); }); this.FailOnBurningImmobile(StationIndex); //Rechargestation is burning this.FailOn(() => { X2_Building_AIRobotRechargeStation workbench = job.GetTarget(StationIndex).Thing as X2_Building_AIRobotRechargeStation; //conditions only apply during the billgiver-use phase if (workbench == null) { return(true); } return(false); }); //Go to the recharge station, this is yielded later, but needed here! Toil gotoStation = Toils_Goto.GotoThing(StationIndex, PathEndMode.Touch); //Jump over ingredient gathering if there are no ingredients needed yield return(Toils_Jump.JumpIf(gotoStation, () => this.job.GetTargetQueue(IngredientIndex).NullOrEmpty())); { //Get to ingredient and pick it up //Note that these fail cases must be on these toils, otherwise the recipe work fails if you stacked // your targetB into another object on the bill giver square. Toil extract = Toils_JobTransforms.ExtractNextTargetFromQueue(IngredientIndex); yield return(extract); //Note that these fail cases must be on these toils, otherwise the recipe work fails if you stacked // your targetB into another object on the bill giver square. var getToHaulTarget2 = Toils_Goto.GotoThing(IngredientIndex, PathEndMode.Touch) .FailOnDespawnedNullOrForbidden(IngredientIndex) .FailOnSomeonePhysicallyInteracting(IngredientIndex); yield return(getToHaulTarget2); //Carry ingredient to the workbench yield return(Toils_Haul.StartCarryThing(IngredientIndex, true)); //Jump to pick up more in this run if we're collecting from multiple stacks at once yield return(JumpToAlsoCollectTargetInQueue(getToHaulTarget2, IngredientIndex)); //Carry ingredient to the workbench yield return(Toils_Goto.GotoThing(StationIndex, PathEndMode.Touch) .FailOnDestroyedOrNull(IngredientIndex)); //Place ingredient on the appropriate cell Toil findPlaceTarget2 = Toils_JobTransforms.SetTargetToIngredientPlaceCell(StationIndex, IngredientIndex, IngredientPlaceCellIndex); yield return(findPlaceTarget2); yield return(Toils_Haul.PlaceHauledThingInCell(IngredientPlaceCellIndex, findPlaceTarget2, false, false)); // save the ingredient, so that it can be deleted later on! Toil saveIngredient = new Toil(); saveIngredient.initAction = delegate { this.ingredients.Add(GetActor().jobs.curJob.GetTarget(IngredientIndex).Thing); }; saveIngredient.defaultCompleteMode = ToilCompleteMode.Instant; yield return(saveIngredient); //Jump back if another ingredient is queued, or you didn't finish carrying your current ingredient target yield return(Toils_Jump.JumpIfHaveTargetInQueue(IngredientIndex, extract)); extract = null; getToHaulTarget2 = null; findPlaceTarget2 = null; } //yield return GetDebugToil("goto station", true); //Go to the recharge station yield return(gotoStation); //Do the repair work yield return(DoRepairWork(500, "Interact_ConstructMetal") .FailOnDespawnedNullOrForbiddenPlacedThings() .FailOnCannotTouch(StationIndex, PathEndMode.Touch)); yield break; }
public override void Tick() { // If idle at station, don't loose charge if (this.needs != null && this.needs.rest != null) { if (this.CurJob != null && this.CurJob.def != null && (this.CurJob.def.defName == "AIRobot_GoAndWait" || this.CurJob.def == JobDefOf.Wait) && IsInDistanceToStation(1.5f)) { if (this.needs.rest.CurLevel <= oldRestLevel - 0.01f) { this.needs.rest.CurLevel = oldRestLevel; } isSleepModeActive = true; } else { oldRestLevel = this.needs.rest.CurLevel; isSleepModeActive = false; } } // Prevent ticks, if you aren't living anymore! if (this.DestroyedOrNull()) { //Log.Error("I'm destroyed but ticking.."); return; } // Downed only destroyes, if health is < 5% if (Spawned && (Dead || (Downed && health.summaryHealth.SummaryHealthPercent < 0.05f) || needs.rest.CurLevel <= 0.01f)) { this.Destroy(DestroyMode.KillFinalize); return; } base.Tick(); // needed? if (needs.food != null && needs.food.CurLevel < 1.0f) { needs.food.CurLevel = 1f; } // Learning disabled --> reset skills every x ticks if (def2 == null || !def2.allowLearning) { if (this.IsHashIntervalTick(4800)) { SetSkills(true); } } if (this.Spawned) { if (rechargeStation == null) { rechargeStation = TryFindRechargeStation(this, Map); } // Remove unwanted HeDiffs if (Gen.IsHashIntervalTick(this, 500)) { RemoveUnwantedHediffs(this); } } }
public static FloatMenuOption GetFloatMenuOption4RepairStationRobot(Pawn selPawn, X2_Building_AIRobotRechargeStation station, Dictionary <ThingDef, int> resources) { if (station.robot != null && !station.robotIsDestroyed) { return(new FloatMenuOption("AIRobot_CannotRepairRobotIsActive".Translate().CapitalizeFirst(), null)); } if (!selPawn.CanReach(station, PathEndMode.InteractionCell, Danger.Deadly)) { return(new FloatMenuOption("CannotUseNoPath".Translate().CapitalizeFirst(), null)); } if (selPawn.skills.GetSkill(SkillDefOf.Crafting).Level < AIRobot_Helper.jobRepairRobotSkillMin) { return(new FloatMenuOption("SkillTooLowForConstruction".Translate("WorkTagCrafting".Translate()).CapitalizeFirst() + ": " + "MinSkill".Translate() + " " + AIRobot_Helper.jobRepairRobotSkillMin.ToString(), null)); } List <string> missingResources = GetStationRepairJobMissingThingStrings(resources, selPawn); if (missingResources == null || missingResources.Count == 0) { return(new FloatMenuOption("AIRobot_RepairRobot".Translate().CapitalizeFirst(), delegate { StartStationRepairJob(selPawn, station, resources); })); } else { string missingResourcesFull = ""; foreach (string str in missingResources) { missingResourcesFull += "\n" + str; } //Log.Error(missingResourcesFull); return(new FloatMenuOption("AIRobot_RepairRobot".Translate().CapitalizeFirst() + ": " + "NotEnoughStoredLower".Translate() + missingResourcesFull, null)); } }