private static Toil FinalizeMaintenance(Pawn targetPawn, Need_Maintenance need, Toil jumpToIfFailed) { Toil toil = new Toil(); toil.initAction = delegate { Pawn actor = toil.actor; float combatPowerCapped = targetPawn.kindDef.combatPower <= 10000 ? targetPawn.kindDef.combatPower : 300; float successChance = actor.GetStatValue(WTH_DefOf.WTH_HackingSuccessChance, true); if (Rand.Chance(successChance)) { actor.skills.Learn(SkillDefOf.Crafting, combatPowerCapped * 0.5f, false); actor.skills.Learn(SkillDefOf.Intellectual, combatPowerCapped * 0.5f, false); need.RestoreUsingParts(actor.carryTracker.CarriedThing.stackCount); Thing part = actor.CurJob.targetB.Thing; if (!part.Destroyed) { part.Destroy(DestroyMode.Vanish); } } else { actor.skills.Learn(SkillDefOf.Crafting, combatPowerCapped * 0.25f, false); actor.skills.Learn(SkillDefOf.Intellectual, combatPowerCapped * 0.25f, false); MoteMaker.ThrowText((actor.DrawPos + targetPawn.DrawPos) / 2f, actor.Map, "WTH_TextMote_MaintenanceFailed".Translate(new object[] { successChance.ToStringPercent() }), 8f); Thing part = actor.CurJob.targetB.Thing; if (!part.Destroyed) { part.Destroy(DestroyMode.Vanish); } actor.jobs.curDriver.JumpToToil(jumpToIfFailed); } }; return(toil); }
public static Toil PickupParts(TargetIndex ind, Need_Maintenance need) { Toil toil = new Toil(); toil.initAction = delegate { Pawn actor = toil.actor; Job curJob = actor.jobs.curJob; Thing thing = curJob.GetTarget(ind).Thing; int partsNeeded = need.PartsNeededToRestore(); if (actor.carryTracker.CarriedThing != null) { partsNeeded -= actor.carryTracker.CarriedThing.stackCount; } int partsFound = Mathf.Min(actor.Map.reservationManager.CanReserveStack(actor, thing, 10, null, false), partsNeeded); if (partsFound > 0) { actor.carryTracker.TryStartCarry(thing, partsFound, true); } curJob.count = partsNeeded - partsFound; if (thing.Spawned) { toil.actor.Map.reservationManager.Release(thing, actor, curJob); } curJob.SetTarget(ind, actor.carryTracker.CarriedThing); }; toil.defaultCompleteMode = ToilCompleteMode.Instant; return(toil); }
protected override IEnumerable <Toil> MakeNewToils() { this.FailOnAggroMentalState(TargetIndex.A); this.FailOnDespawnedNullOrForbidden(TargetIndex.A); this.FailOn(delegate { return(!Deliveree.OnBaseMechanoidPlatform()); }); Need_Maintenance need = Deliveree.needs.TryGetNeed <Need_Maintenance>() as Need_Maintenance; Toil reserveParts = null; reserveParts = ReserveParts(TargetIndex.B, need).FailOnDespawnedNullOrForbidden(TargetIndex.B); yield return(reserveParts); yield return(Toils_Goto.GotoThing(TargetIndex.B, PathEndMode.ClosestTouch).FailOnDespawnedNullOrForbidden(TargetIndex.B)); yield return(PickupParts(TargetIndex.B, need).FailOnDestroyedOrNull(TargetIndex.B)); yield return(Toils_Haul.CheckForGetOpportunityDuplicate(reserveParts, TargetIndex.B, TargetIndex.None, true, null)); PathEndMode interactionCell = (this.Deliveree != this.pawn) ? PathEndMode.InteractionCell : PathEndMode.OnCell; yield return(Toils_Goto.GotoThing(TargetIndex.A, interactionCell)); int duration = (int)(1f / this.pawn.GetStatValue(WTH_DefOf.WTH_HackingMaintenanceSpeed, true) * 600f); EffecterDef effect = DefDatabase <EffecterDef> .AllDefs.FirstOrDefault((EffecterDef ed) => ed.defName == "Repair"); yield return(Toils_General.Wait(duration, TargetIndex.None).FailOnCannotTouch(TargetIndex.A, interactionCell).WithProgressBarToilDelay(TargetIndex.A, false, -0.5f).WithEffect(effect, TargetIndex.A)); yield return(FinalizeMaintenance(this.Deliveree, need, reserveParts)); }
private static IEnumerable <Gizmo> AddHackedPawnGizmos(Pawn __instance, ExtendedDataStorage store) { ExtendedPawnData pawnData = store.GetExtendedDataFor(__instance); yield return(CreateGizmo_SearchAndDestroy(__instance, pawnData)); Need_Power powerNeed = __instance.needs.TryGetNeed <Need_Power>(); Need_Maintenance maintenanceNeed = __instance.needs.TryGetNeed <Need_Maintenance>(); if (powerNeed != null) { yield return(CreateGizmo_AutoRecharge(__instance, powerNeed)); } HediffSet hediffSet = __instance.health.hediffSet; if (!__instance.IsColonistPlayerControlled) { if (__instance.apparel != null) { foreach (Gizmo apparelGizmo in __instance.apparel.GetGizmos()) { yield return(apparelGizmo); } } } if (__instance.workSettings != null) { yield return(CreateGizmo_Work(__instance, pawnData)); if (powerNeed != null) { yield return(CreateGizmo_WorkThreshold(__instance, powerNeed)); } } if (maintenanceNeed != null) { yield return(CreateGizmo_MaintenanceThreshold(__instance, maintenanceNeed)); } if (hediffSet.HasHediff(WTH_DefOf.WTH_SelfDestruct)) { yield return(CreateGizmo_SelfDestruct(__instance, pawnData)); } if (hediffSet.HasHediff(WTH_DefOf.WTH_RepairModule)) { yield return(CreateGizmo_SelfRepair(__instance, pawnData)); } if (hediffSet.HasHediff(WTH_DefOf.WTH_RepairModule) && hediffSet.HasHediff(WTH_DefOf.WTH_RepairArm)) { yield return(CreateGizmo_Repair(__instance, pawnData)); } if (hediffSet.HasHediff(WTH_DefOf.WTH_BeltModule)) { yield return(CreateGizmo_EquipBelt(__instance, pawnData)); } if (hediffSet.HasHediff(WTH_DefOf.WTH_OverdriveModule)) { yield return(CreateGizmo_Overdrive(__instance, pawnData)); } }
private static void HackedPoorlyEvent(Pawn pawn) { Random rand = new Random(DateTime.Now.Millisecond); int rndInt = rand.Next(1, 1000); if (rndInt <= 4) //TODO: no magic number { Need_Maintenance need = pawn.needs.TryGetNeed <Need_Maintenance>(); need.CurLevel = 0; Find.LetterStack.ReceiveLetter("WTH_Letter_HackedPoorlyEvent_Label".Translate(), "WTH_Letter_HackedPoorlyEvent_Description".Translate(), LetterDefOf.ThreatBig, pawn); } }
private static Gizmo CreateGizmo_MaintenanceThreshold(Pawn __instance, Need_Maintenance maintenanceNeed) { string disabledReason = ""; bool disabled = false; Gizmo gizmo = new Command_SetMaintenanceThreshold { maintenanceNeed = maintenanceNeed, defaultLabel = "WTH_Gizmo_MaintenanceThreshold_Label".Translate(), defaultDesc = "WTH_Gizmo_MaintenanceThreshold_Description".Translate(), disabled = disabled, disabledReason = disabledReason, icon = ContentFinder <Texture2D> .Get(("UI/" + "MechMaintenanceThreshold"), true), }; return(gizmo); }
public static Toil ReserveParts(TargetIndex ind, Need_Maintenance need) { Toil toil = new Toil(); toil.initAction = delegate { Pawn actor = toil.actor; Job curJob = actor.jobs.curJob; Thing thing = curJob.GetTarget(ind).Thing; int num = actor.Map.reservationManager.CanReserveStack(actor, thing, 10, null, false); if (num <= 0 || !actor.Reserve(thing, curJob, 10, Mathf.Min(num, need.PartsNeededToRestore()), null, true)) { toil.actor.jobs.EndCurrentJob(JobCondition.Incompletable, true); } }; toil.defaultCompleteMode = ToilCompleteMode.Instant; toil.atomicWithPrevious = true; return(toil); }
private static void MaintainMechsIfNeeded(Caravan caravan, List <Thing> allParts, List <Pawn> allHackedMechs) { Thing partItem = allParts.First(); List <Pawn> allPawnsCapableOfMaintenance = caravan.AllThings.Where((Thing t) => t is Pawn pawn && !pawn.Dead && !pawn.Downed).Cast <Pawn>().ToList(); if (allPawnsCapableOfMaintenance.NullOrEmpty()) { return; } List <Pawn> allMechsNeedingMaintenance = allHackedMechs.Where((Pawn p) => p.needs.TryGetNeed <Need_Maintenance>() is Need_Maintenance needM && needM.CurLevelPercentage < 0.5f).ToList(); if (allMechsNeedingMaintenance.NullOrEmpty()) { return; } Pawn bestPawn = allPawnsCapableOfMaintenance.MaxBy((Pawn p) => p.skills.AverageOfRelevantSkillsFor(WTH_DefOf.WTH_Hack)); float successChance = bestPawn.GetStatValue(WTH_DefOf.WTH_HackingSuccessChance, true); if (successChance < 0.20f) { return; } Pawn chosenMech = allMechsNeedingMaintenance.RandomElement(); Need_Maintenance need = chosenMech.needs.TryGetNeed <Need_Maintenance>(); int partsAvailable = Math.Min(need.PartsNeededToRestore(), partItem.stackCount); float combatPowerCapped = chosenMech.kindDef.combatPower <= 10000 ? chosenMech.kindDef.combatPower : 300; if (Rand.Chance(successChance)) { bestPawn.skills.Learn(SkillDefOf.Crafting, combatPowerCapped * 0.5f, false); bestPawn.skills.Learn(SkillDefOf.Intellectual, combatPowerCapped * 0.5f, false); need.RestoreUsingParts(partsAvailable); } else { bestPawn.skills.Learn(SkillDefOf.Crafting, combatPowerCapped * 0.25f, false); bestPawn.skills.Learn(SkillDefOf.Intellectual, combatPowerCapped * 0.25f, false); } partItem.SplitOff(partsAvailable); }
private void HighMaintenanceDamage() { Need_Maintenance need = pawn.needs.TryGetNeed <Need_Maintenance>(); if (need == null) { return; } if (need.CurLevel > 5) { need.CurLevel = 5; } else { return; } if (pawn.Faction == Faction.OfPlayer) { Find.LetterStack.ReceiveLetter("WTH_Letter_HackedPoorlyEvent_Label".Translate(), "WTH_Letter_HighMaintenanceDamage_Description".Translate(new object[] { pawn.Name.ToStringShort }), LetterDefOf.ThreatBig, pawn); } }
private void MediumMaintenanceDamage() { Need_Maintenance need = pawn.needs.TryGetNeed <Need_Maintenance>(); if (need == null) { return; } if (need.CurLevel > 25) { need.CurLevel = 25; } else { return; } if (pawn.Faction == Faction.OfPlayer) { Find.LetterStack.ReceiveLetter("WTH_Letter_MediumMaintenanceDamage_Label".Translate(), "WTH_Letter_MediumMaintenanceDamage_Description".Translate(new object[] { pawn.Name.ToStringShort }), LetterDefOf.NegativeEvent, pawn); } }
protected virtual float GetThresHold(Need_Maintenance need) { return(need.MaxLevel * 0.5f); }
protected override float GetThresHold(Need_Maintenance need) { return(need.MaxLevel * need.PercentageThreshLowMaintenance); }