public override IEnumerable <FloatMenuOption> GetFloatMenuOptions(Pawn myPawn) { //// No base float menu options allowed! //foreach (FloatMenuOption fmo in base.GetFloatMenuOptionsFor(myPawn)) //{ // yield return fmo; //} // No self medication! if (myPawn == this) { yield break; } // Sedate AIPawn Action action_OrderSedateMai = delegate { myPawn.drafter.Drafted = false; Job jobNew = new Job(DefDatabase <JobDef> .GetNamed("AIPawn_Sedate"), this) { count = 1 }; myPawn.jobs.TryTakeOrderedJob(jobNew); }; yield return(new FloatMenuOption(txtFloatMenuSedateAIPawn.Translate(this.Label), action_OrderSedateMai)); // Sedate and Carry AIPawn to recharge station Building_AIPawnRechargeStation rechargeStation; rechargeStation = HelperAIPawn.FindMedicalRechargeStationFor(this); if (rechargeStation == null) { rechargeStation = HelperAIPawn.FindRechargeStationFor(this); } Action action_OrderSedateAndCarryMai = delegate { myPawn.drafter.Drafted = false; Job jobNew = new Job(DefDatabase <JobDef> .GetNamed("AIPawn_SedateAndRescue"), this, rechargeStation) { count = 1 }; myPawn.jobs.TryTakeOrderedJob(jobNew); }; if (rechargeStation != null) { yield return(new FloatMenuOption(txtFloatMenuSedateAndRescueAIPawn.Translate(this.Label), action_OrderSedateAndCarryMai)); } else { yield return(new FloatMenuOption(txtFloatMenuSedateAndRescueAIPawn.Translate(this.Label), null)); } yield break; }
protected override Job TryGiveJob(Pawn pawn) { if (Find.TickManager.TicksGame - pawn.mindState.lastDisturbanceTick < 400) { return(null); } AIPawn aiPawn = pawn as AIPawn; Building_AIPawnRechargeStation rechargeStation = HelperAIPawn.FindRechargeStationFor(aiPawn); if (rechargeStation == null) { return(null); } if (rechargeStation.owners != null && !rechargeStation.owners.Contains(aiPawn) && !rechargeStation.Medical) { aiPawn.ownership.ClaimBedIfNonMedical(rechargeStation); } if (aiPawn.ownership.OwnedBed == null || aiPawn.ownership.OwnedBed != rechargeStation) { return(null); } Job job = new Job(JobDefOf.LayDown, rechargeStation); return(job); }
private void TryGoRecharging() { // Drafting active, do nothing if (this.Drafted || !this.Spawned) { return; } // No recharge station, do nothing if (this.ownership.OwnedBed == null) { Building_AIPawnRechargeStation rs = HelperAIPawn.FindRechargeStationFor(this); if (rs == null) { return; } this.ownership.ClaimBedIfNonMedical(rs); //rs.TryAssignPawn(this); OLD if (this.ownership.OwnedBed == null) { return; } } Building_AIPawnRechargeStation rechargeStation = this.ownership.OwnedBed as Building_AIPawnRechargeStation; if (rechargeStation == null) { return; } if (rechargeStation.Position == this.Position) { return; } rechargeStation.Button_CallOwnerToRecharge(); }
// ================== Ticks ================== public override void Tick() { base.Tick(); // Do init work after spawning if (!init) { HelperAIPawn.ReApplyThingToListerThings(this.Position, this); Drawer.renderer.graphics.ResolveAllGraphics(); //Causes errors! UpdateGraphics(); initTicks--; if (initTicks <= 0) { // Replace invalid Mai with valid Mai if (!story.childhood.identifier.Contains(BackstoryHelper.BackstoryDefNameIdentifier)) { string savedDefName = def.defName; IntVec3 savedPosition = Position; Map savedMap = Map; Gender savedGender = this.gender; // Destroy me destroyMeWithoutExplosion = true; Destroy(DestroyMode.Vanish); // Create a new me AIPawn mai = Building_AIPawnCreator.CreateAIPawn(savedDefName, savedPosition, savedMap, savedGender); return; } BackstoryHelper.RemoveNewBackstoriesFromDatabase(); init = true; } return; } //// To circumvent the strange pathing error! //if ((this.CurJob == null || this.CurJob != curJobOld) && Map != null) //{ // HelperAIPawn.ReApplyThingToListerThings(this.Position, this); // curJobOld = this.CurJob; //} // To circumvent the destroy apparel error if (this.CurJob != null && this.CurJob.def.defName == "Wear" && this.CurJob.targetA.Cell == this.Position) { AIPawnGenerator.DestroyBaseShielding(this); } // Update drafted graphics if (draftedActiveOld != this.Drafted) { UpdateGraphics(); draftedActiveOld = this.Drafted; } // When AIPawn is in a Container, do nothing if (this.InContainerEnclosed) { return; } // When AIPawn is in a bed, fix rest value to prevent explosions in the hospital room if (Find.TickManager.TicksGame % fixRestWhenInBedCounter == 0) { Building_AIPawnRechargeStation rechargeStation; if (this.InBed() && !this.IsInAIRechargeStation(Map, out rechargeStation)) { needs.rest.CurLevel = fixRestWhenInBedFixedValue; } else { fixRestWhenInBedFixedValue = needs.rest.CurLevel; } } // Disable food reduction <-- Food is needed or some errors are thrown if (needs != null && needs.food != null && needs.food.CurLevel <= 0.95f) { needs.food.CurLevel = 1.0f; } //// Disable joy reduction //if (needs != null && needs.joy != null && needs.joy.CurLevel <= 0.95f) // needs.joy.CurLevel = 1.0f; //// Disable beauty reduction //if (needs != null && needs.beauty != null && needs.beauty.CurLevel <= 0.95f) // needs.beauty.CurLevel = 1.0f; //// Disable comfort reduction //if (needs != null && needs.comfort != null && needs.comfort.CurLevel <= 0.95f) // needs.comfort.CurLevel = 1.0f; //// Disable rest reduction when traveling in a caravan! //if (needs != null && needs.rest != null && needs.rest.CurLevel <= 0.95f && !Destroyed && !Downed && Map == null) // needs.rest.CurLevel += 0.01f / 60f; // If in bed, slowly increase rest (to circumvent bed problems) if (IsInBed(Map)) { needs.rest.CurLevel += 0.025f / 60f; } // Self healing ability (Nanobots) healDamagedPartsCounter -= 1; if (healDamagedPartsCounter <= 0) { DoHealDamagedBodyPart(enhancedAI); healDamagedPartsCounter = healDamagedPartsCounterStartValue; } refreshQuickCount += 1; if (refreshQuickCount >= refreshQuickMax) { refreshQuickCount = 0; } if (refreshQuickCount == 0) { // Add thought when health < x if (this.health.summaryHealth.SummaryHealthPercent < 0.75) { this.needs.mood.thoughts.memories.TryGainMemory(ThoughtDef.Named("AIShieldingError")); } // disable diseases DoDiseaseHandling(); if (Destroyed) { destroyMeWithoutExplosion = true; Destroy(DestroyMode.Vanish); return; } // Do explosion when downed, dead or incapable of moving if (Dead || (!isAnestheticIncap && !IsInBed(Map) && (Downed || health.capacities.GetLevel(PawnCapacityDefOf.Moving) < 0.1f))) { incapToExplosionCounter -= refreshQuickMax; if (incapToExplosionCounter <= 0) { Destroy(DestroyMode.KillFinalize); return; } } // Reset counter when health is rising -- Not working right now if ((Downed && this.health.summaryHealth.SummaryHealthPercent > incapHealthOld) || !Downed && (incapToExplosionCounter < incapToExplosionCounterStartValue)) { incapToExplosionCounter = incapToExplosionCounterStartValue; } incapHealthOld = this.health.summaryHealth.SummaryHealthPercent; //// Add thought when rested //if (rest.Rest.CurLevel >= 98.9f) // psychology.thoughts.memories.TryGainMemoryThought(ThoughtDef.Named("AIBatteriesRefilled")); // Change color when near exhausted float levelLowBatterie = 0.25f; float levelLowCriticalBatterie = 0.15f; if (needs.rest.CurLevel <= levelLowCriticalBatterie && !graphicHueActive) { // Switch to alternate graphic graphicHueActive = true; UpdateGraphics(); } else if (needs.rest.CurLevel > levelLowCriticalBatterie && graphicHueActive) { // Switch back to normal graphic graphicHueActive = false; UpdateGraphics(); } // Add thought when rest(batteries) < x if (needs.rest.CurLevel < levelLowCriticalBatterie) { needs.mood.thoughts.memories.TryGainMemory(ThoughtDef.Named("AILowCriticalBattery")); } // Add thought when rest(batteries) < x else if (needs.rest.CurLevel < levelLowBatterie) { needs.mood.thoughts.memories.TryGainMemory(ThoughtDef.Named("AILowBattery")); } // Explosion when exhausted if (needs.rest.CurLevel <= 0.011f) { if (!Downed) { HealthUtility.DamageUntilDowned(this, false); } } else if (needs.rest.CurLevel < 0.2f) { TryGoRecharging(); } // unclaim bed when fully rested // Activate? Don't Activate? //if (ownership != null && (rest.Rest.CurLevel >= 94.8f || rest.DoneResting)) // ownership.UnclaimBed(); } // Update base AI thought every x refreshBaseInfosCount += 1; if (refreshBaseInfosCount >= refreshBaseInfosMax || refreshBaseInfosCount < 0) { refreshBaseInfosCount = 0; this.mindState.canFleeIndividual = false; DoRelationHandling(); //Base thought is only available after save/load (why?) so it needs to be set this.needs.mood.thoughts.memories.TryGainMemory(ThoughtDef.Named("AIBaseThought")); // Rebuild Base Shielding if needed Building_AIPawnRechargeStation rs2; AIPawnGenerator.GiveBaseApparelWhileInBed(this, IsInAIRechargeStation(Map, out rs2)); } }
private static IEnumerable <Backstory> NewBackstories() { if (backstories == null) { Backstory backstory; backstories = new List <Backstory>(); string txtBaseDesc = "----------"; string txtTitle = "---"; string txtTitleShort = "AI"; BodyType bodyType = BodyType.Female; if (workTagCollection == null) { // Set a list with the possible disabled items workTagCollection = new List <WorkTags>(); workTagCollection.Add(WorkTags.Animals); //workTagCollection.Add(WorkTags.Artistic); //- In BasicWorkDisables workTagCollection.Add(WorkTags.Caring); workTagCollection.Add(WorkTags.Cleaning); workTagCollection.Add(WorkTags.Cooking); workTagCollection.Add(WorkTags.Crafting); workTagCollection.Add(WorkTags.Firefighting); workTagCollection.Add(WorkTags.Hauling); workTagCollection.Add(WorkTags.Intellectual); workTagCollection.Add(WorkTags.ManualDumb); workTagCollection.Add(WorkTags.ManualSkilled); workTagCollection.Add(WorkTags.Mining); workTagCollection.Add(WorkTags.PlantWork); workTagCollection.Add(WorkTags.Social); workTagCollection.Add(WorkTags.Violent); //workTagCollection.Add(); } // Get the base disables (The AI can never do these) WorkTags workDisables1 = GetBasicWorkDisables(); WorkTags workDisables2; // Create minimal backstory backstory = new Backstory(); backstory.baseDesc = txtBaseDesc; backstory.SetTitle(txtTitle); backstory.SetTitleShort(txtTitleShort); backstory.bodyTypeGlobal = bodyType; backstory.bodyTypeFemale = BodyType.Female; backstory.bodyTypeMale = BodyType.Male; backstory.workDisables = workDisables1; backstory.identifier = GetBackstoryUniqueKey(backstory.workDisables); backstories.Add(backstory); //string log = workDisables1.ToString().Replace(", ", "_"); //Logging // add other backstories if (allCombos == null) { allCombos = HelperAIPawn.GetAllCombos <WorkTags>(workTagCollection); } foreach (List <WorkTags> activeCombo in allCombos) { workDisables2 = GetBasicWorkDisables(); foreach (WorkTags entry in activeCombo) { workDisables2 = workDisables2 | entry; } backstory = new Backstory(); backstory.baseDesc = txtBaseDesc; backstory.SetTitle(txtTitle); backstory.SetTitleShort(txtTitleShort); backstory.bodyTypeGlobal = bodyType; backstory.bodyTypeFemale = BodyType.Female; backstory.bodyTypeMale = BodyType.Male; backstory.workDisables = workDisables2; backstory.identifier = GetBackstoryUniqueKey(backstory.workDisables); backstories.Add(backstory); //log = log + Environment.NewLine + backstory.defName; // workDisables2.ToString().Replace(", ", "_"); //Logging } } //Log.Error(log); //Logging return(backstories.AsEnumerable <Backstory>()); }