public PawnCapacityDef GetNextAsCapacity(Action <string> errorCallback) { PawnCapacityDef capacityDef = GetNextAsCapacity(); if (capacityDef == null) { errorCallback.Invoke(_lastArgument); } return(capacityDef); }
public static bool Affects(this Bill_Medical bill, PawnCapacityDef capacity) { if (bill?.recipe == null) { return(false); } return(bill.recipe.AddsHediffThatAffects(capacity, -1) || bill.recipe.AdministersDrugThatAffects(capacity, -1) || (bill.recipe.addsHediff.IsAddedPart() && bill.Part.Affects(capacity))); }
public static bool Prefix(ref string __result, PawnCapacityDef __instance, Pawn pawn) { if (pawn.RaceProps.FleshType == DefDatabase <FleshTypeDef> .GetNamed("Android")) { if (__instance.GetModExtension <AndroidCapacityLabel>() != null) { __result = __instance.GetModExtension <AndroidCapacityLabel>().androidNewLabel; return(false); } } return(true); }
public static T FailOnIncapable <T>(this T f, PawnCapacityDef pawnCapacity) where T : IJobEndable { f.AddEndCondition(delegate { if (!f.GetActor().health.capacities.CapableOf(pawnCapacity)) { return(JobCondition.Incompletable); } return(JobCondition.Ongoing); }); return(f); }
public static void DoHediffTooltip( Rect rect, Pawn p, PawnCapacityDef capDef ) { StringBuilder tooltip = new StringBuilder( ); bool tip = false; try { // get parts that matter for this capDef List<string> activityGroups = p.RaceProps.body.GetActivityGroups( capDef ); List<BodyPartRecord> relevantParts = new List<BodyPartRecord>( ); foreach ( string t in activityGroups ) { relevantParts.AddRange( p.RaceProps.body.GetParts( capDef, t ) ); } relevantParts = relevantParts.Distinct().ToList(); // the following is an incredible hacky way to show all diffs, but not child nodes of missing body parts // if you care about good code, look away. // remove missing parts relevantParts.RemoveAll( bp => p.health.hediffSet.GetHediffs<Hediff_MissingPart>( ).Select( h => h.Part ).Contains( bp ) ); // add common ancestors back in relevantParts.AddRange( p.health.hediffSet.GetMissingPartsCommonAncestors( ).Select( h => h.Part ) ); // hediffs with a direct effect listed (CapMods), or affecting a relevant part. IEnumerable<Hediff> hediffs = p.health.hediffSet.GetHediffs<Hediff>( ).Where( h => h.Visible && ( ( h.CapMods != null && h.CapMods.Count > 0 && h.CapMods.Any( cm => cm.capacity == capDef ) ) || relevantParts.Contains( h.Part ) ) ); foreach ( Hediff diff in hediffs ) { tip = true; tooltip.AppendLine( ( diff.Part == null ? "Whole body" : diff.Part.def.LabelCap ) + ": " + diff.LabelCap ); } } catch ( Exception ) { Log.Message( "Error getting tooltip for medical info." ); } if ( !tip ) { tooltip.AppendLine( "OK" ); } TooltipHandler.TipRegion( rect, tooltip.ToString( ) ); }
public static void Postfix(ref string __result, PawnCapacityDef __instance, Pawn pawn) { if (!PeacekeeperUtility.IsPeacekeeper(pawn)) { return; } if (__instance == PawnCapacityDefOf.BloodFiltration) { __result = "RSCoolantFiltration".Translate(); } if (__instance == PawnCapacityDefOf.BloodPumping) { __result = "RSCoolantCirculation".Translate(); } }
private void DoCapacity(Rect rect, Pawn pawn, PawnCapacityDef capacity) { var efficiencyLabel = HealthCardUtility.GetEfficiencyLabel(pawn, capacity); var pawnCapacityTip = HealthCardUtility.GetPawnCapacityTip(pawn, capacity); if (Mouse.IsOver(rect)) { Widgets.DrawHighlight(rect); } GUI.color = efficiencyLabel.Second; Text.Anchor = TextAnchor.MiddleCenter; Widgets.Label(rect, efficiencyLabel.First); GUI.color = Color.white; Text.Anchor = TextAnchor.UpperLeft; TooltipHandler.TipRegion(rect, pawnCapacityTip); }
static void Postfix(ref float __result, HediffSet diffSet, PawnCapacityDef capacity, List <PawnCapacityUtility.CapacityImpactor> impactors, bool forTradePrice) { var pawn = diffSet.pawn; var aspectTracker = pawn.GetAspectTracker(); if (aspectTracker != null && __result > 0) { float offset = 0; float postFix = 1; float setMax = float.PositiveInfinity; foreach (Aspect aspect in aspectTracker.Aspects) { if (!aspect.HasCapMods) { continue; } foreach (PawnCapacityModifier capMod in aspect.CapMods) { if (capMod.capacity != capacity) { continue; } offset += capMod.offset; postFix *= capMod.postFactor; if (capMod.SetMaxDefined && (capMod.setMax < setMax)) { setMax = capMod.setMax; } } impactors?.Add(new AspectCapacityImpactor(aspect)); } offset += GetTotalCapacityOffset(diffSet, capacity); //need to start with the uncapped offset value offset = Mathf.Min(offset * postFix, setMax); GenMath.RoundedHundredth(Mathf.Max(offset, capacity.minValue)); __result = Mathf.Min(__result, offset); //take the min of the aspect modified value and the capped value from Rimworld's calculation } }
public static string Postfix(string __result, Pawn pawn, PawnCapacityDef capacity) { // So this might look a bit like dark magic, but what's happening is that the impactors list is populated // in CalculateCapacityLevel. Why isn't it an out parameter? Because it's optional. var impactors = new List <PawnCapacityUtility.CapacityImpactor>(); PawnCapacityUtility.CalculateCapacityLevel(pawn.health.hediffSet, capacity, impactors); var sb = new StringBuilder(); foreach (var impactor in impactors.FindAll(impact => impact is CapacityImpactorPsychic)) { sb.AppendLine($" {impactor.Readable(pawn)}"); } __result += sb; return(__result); }
public static void DoHediffTooltip(Rect rect, Pawn p, string effLabel, PawnCapacityDef capDef) { var tooltip = new StringBuilder( ); tooltip.AppendLine(effLabel); try { // get parts that matter for this capDef var activityGroups = p.RaceProps.body.GetActivityGroups(capDef); var relevantParts = new List <BodyPartRecord>( ); foreach (var t in activityGroups) { relevantParts.AddRange(p.RaceProps.body.GetParts(capDef, t)); } relevantParts = relevantParts.Distinct().ToList(); // the following is an incredible hacky way to show all diffs, but not child nodes of missing body parts // if you care about good code, look away. // remove missing parts relevantParts.RemoveAll( bp => p.health.hediffSet.GetHediffs <Hediff_MissingPart>( ).Select(h => h.Part).Contains(bp)); // add common ancestors back in relevantParts.AddRange(p.health.hediffSet.GetMissingPartsCommonAncestors( ).Select(h => h.Part)); // hediffs with a direct effect listed (CapMods), or affecting a relevant part. var hediffs = p.health.hediffSet.GetHediffs <Hediff>( ).Where(h => h.Visible && ((h.CapMods != null && h.CapMods.Count > 0 && h.CapMods.Any( cm => cm.capacity == capDef)) || relevantParts.Contains(h.Part))); foreach (var diff in hediffs) { tooltip.AppendLine((diff.Part == null ? "Whole body" : diff.Part.def.LabelCap) + ": " + diff.LabelCap); } } catch (Exception) { Log.Message("Error getting tooltip for medical info."); } TooltipHandler.TipRegion(rect, tooltip.ToString( )); }
public static string GetPawnCapacityTip(Pawn pawn, PawnCapacityDef capacity) { List <PawnCapacityUtility.CapacityImpactor> list = new List <PawnCapacityUtility.CapacityImpactor>(); float eff = PawnCapacityUtility.CalculateCapacityLevel(pawn.health.hediffSet, capacity, list); PawnCapacityUtility.CapacityImpactorCapacity capacityImpactorCapacity; list.RemoveAll((PawnCapacityUtility.CapacityImpactor x) => (capacityImpactorCapacity = x as PawnCapacityUtility.CapacityImpactorCapacity) != null && !capacityImpactorCapacity.capacity.CanShowOnPawn(pawn)); StringBuilder stringBuilder = new StringBuilder(); stringBuilder.AppendLine(capacity.GetLabelFor(pawn).CapitalizeFirst() + ": " + GetEfficiencyEstimateLabel(eff)); if (list.Count > 0) { stringBuilder.AppendLine(); stringBuilder.AppendLine("AffectedBy".Translate()); for (int i = 0; i < list.Count; i++) { if (list[i] is PawnCapacityUtility.CapacityImpactorHediff) { stringBuilder.AppendLine($" {list[i].Readable(pawn)}"); } } for (int j = 0; j < list.Count; j++) { if (list[j] is PawnCapacityUtility.CapacityImpactorBodyPartHealth) { stringBuilder.AppendLine($" {list[j].Readable(pawn)}"); } } for (int k = 0; k < list.Count; k++) { if (list[k] is PawnCapacityUtility.CapacityImpactorCapacity) { stringBuilder.AppendLine($" {list[k].Readable(pawn)}"); } } for (int l = 0; l < list.Count; l++) { if (list[l] is PawnCapacityUtility.CapacityImpactorPain) { stringBuilder.AppendLine($" {list[l].Readable(pawn)}"); } } } return(stringBuilder.ToString()); }
// RimWorld.HealthCardUtility public static void Vamp_GetPawnCapacityTip(Pawn pawn, PawnCapacityDef capacity, ref string __result) { if (pawn.IsVampire() && ( capacity == PawnCapacityDefOf.Breathing || capacity == PawnCapacityDefOf.BloodPumping || capacity == PawnCapacityDefOf.BloodFiltration || capacity == PawnCapacityDefOf.Eating || capacity == PawnCapacityDefOf.Metabolism)) { StringBuilder s = new StringBuilder(); s.AppendLine(capacity.LabelCap + ": 0%"); s.AppendLine(); s.AppendLine("AffectedBy".Translate()); s.AppendLine(" " + "ROMV_HI_Vampirism".Translate()); s.AppendLine(" " + "ROMV_HI_UnusedCapacities".Translate().AdjustedFor(pawn)); __result = s.ToString(); } }
public static float Postfix(float __result, HediffSet diffSet, PawnCapacityDef capacity, ref List <PawnCapacityUtility.CapacityImpactor> impactors) { if (capacity.zeroIfCannotBeAwake && !diffSet.pawn.health.capacities.CanBeAwake) { return(__result); } var max = 999f; var originalMult = 1f; foreach (var hediff in diffSet.hediffs) { var capMod = hediff.CapMods?.Find(mod => mod.capacity == capacity); if (capMod == null) { continue; } originalMult *= capMod.postFactor; if (capMod.setMax < max) { max = capMod.setMax; } } var offset = diffSet.pawn.PsiTracker().GetTotalOffsetOfCapacity(capacity); var mult = diffSet.pawn.PsiTracker().GetTotalFactorOfCapacity(capacity); if (impactors != null) { var abilities = diffSet.pawn.PsiTracker().GetAllAbilitiesImpactingCapacity(capacity); impactors.AddRange(abilities.Select(ab => new CapacityImpactorPsychic { ability = ab })); } var newResult = __result * mult + offset * originalMult * mult; __result = Mathf.Min(newResult, max); return(GenMath.RoundedHundredth(Mathf.Max(__result, capacity.minValue))); }
public static string GetPawnCapacityTip(Pawn pawn, PawnCapacityDef capacity) { List <PawnCapacityUtility.CapacityImpactor> list = new List <PawnCapacityUtility.CapacityImpactor>(); float num = PawnCapacityUtility.CalculateCapacityLevel(pawn.health.hediffSet, capacity, list); StringBuilder stringBuilder = new StringBuilder(); stringBuilder.AppendLine(capacity.LabelCap + ": " + ((float)(num * 100.0)).ToString("F0") + "%"); if (list.Count > 0) { stringBuilder.AppendLine(); stringBuilder.AppendLine("AffectedBy".Translate()); for (int i = 0; i < list.Count; i++) { if (list[i] is PawnCapacityUtility.CapacityImpactorHediff) { stringBuilder.AppendLine(string.Format(" {0}", list[i].Readable(pawn))); } } for (int j = 0; j < list.Count; j++) { if (list[j] is PawnCapacityUtility.CapacityImpactorBodyPartHealth) { stringBuilder.AppendLine(string.Format(" {0}", list[j].Readable(pawn))); } } for (int k = 0; k < list.Count; k++) { if (list[k] is PawnCapacityUtility.CapacityImpactorCapacity) { stringBuilder.AppendLine(string.Format(" {0}", list[k].Readable(pawn))); } } for (int l = 0; l < list.Count; l++) { if (list[l] is PawnCapacityUtility.CapacityImpactorPain) { stringBuilder.AppendLine(string.Format(" {0}", list[l].Readable(pawn))); } } } return(stringBuilder.ToString()); }
private bool IsIncapableOfWholeWorkType(Pawn p, WorkTypeDef work) { for (int i = 0; i < work.workGiversByPriority.Count; i++) { bool flag = true; for (int j = 0; j < work.workGiversByPriority[i].requiredCapacities.Count; j++) { PawnCapacityDef capacity = work.workGiversByPriority[i].requiredCapacities[j]; if (!p.health.capacities.CapableOf(capacity)) { flag = false; break; } } if (flag) { return(false); } } return(true); }
public static bool Patch_ShouldBeDeadFromRequiredCapacity(PawnCapacityDef __result, Pawn ___pawn) { Pawn pawn = ___pawn; if (pawn.health.hediffSet.HasHediff(LifeSupportDefOf.QE_LifeSupport) && pawn.ValidLifeSupportNearby()) { //Check if consciousness is there. If it is then its okay. PawnCapacityDef pawnCapacityDef = PawnCapacityDefOf.Consciousness; bool flag = (!pawn.RaceProps.IsFlesh) ? pawnCapacityDef.lethalMechanoids : pawnCapacityDef.lethalFlesh; if (flag && pawn.health.capacities.CapableOf(pawnCapacityDef)) { __result = pawnCapacityDef; return(false); } __result = null; return(false); } return(true); }
public override void Tick() { if (!added) { Log.Message("Added"); lookup.Add(pawn.GetHashCode(), this); InfluenceGainFromLeader = DefDatabase <StatDef> .GetNamed("InfluenceGainFromLeader"); InfluenceGainFromFriends = DefDatabase <StatDef> .GetNamed("InfluenceGainFromFriends"); CritThink = DefDatabase <PawnCapacityDef> .GetNamed("CriticalThinking"); added = true; } cnt++; if (!isLeader) { delta = pawn.GetStatValue(InfluenceGainFromLeader) + pawn.GetStatValue(InfluenceGainFromFriends) - CurStageIndex * 0.2f * pawn.health.capacities.GetLevel(CritThink); Severity += delta / GenDate.TicksPerDay; } }
public void ExposeData() { Scribe_Values.Look <ObjectType>(ref oType, "oType"); Scribe_Values.Look <float>(ref minWidthDesired, "minWidthDesired"); Scribe_Values.Look <string>(ref this.label, "label"); switch (oType) { case ObjectType.Stat: StatDef tempObjectS = (StatDef)displayObject; Scribe_Defs.Look(ref tempObjectS, "displayObject"); displayObject = tempObjectS; break; case ObjectType.Skill: SkillDef tempObjectK = (SkillDef)displayObject; Scribe_Defs.Look(ref tempObjectK, "displayObject"); displayObject = tempObjectK; break; case ObjectType.Need: NeedDef tempObjectN = (NeedDef)displayObject; Scribe_Defs.Look(ref tempObjectN, "displayObject"); displayObject = tempObjectN; break; case ObjectType.Capacity: PawnCapacityDef tempObjectCap = (PawnCapacityDef)displayObject; Scribe_Defs.Look(ref tempObjectCap, "displayObject"); displayObject = tempObjectCap; break; case ObjectType.Record: RecordDef tempObjectRecord = (RecordDef)displayObject; Scribe_Defs.Look(ref tempObjectRecord, "displayObject"); displayObject = tempObjectRecord; break; } }
public override void RunCommand(IRCMessage message) { Viewer viewer = Viewers.GetViewer(message.User); Pawn pawn = GetPawnIfAllowed(message); if (pawn == null) { return; } string[] healthArgs = message.Message.Split(' ').Skip(1).ToArray(); for (int i = 0; i < healthArgs.Length; ++i) { healthArgs[i] = healthArgs[i].ToLower(); } string output; if (healthArgs.Length > 0) { PawnCapacityDef capacityDef = DefDatabase <PawnCapacityDef> .AllDefs .FirstOrDefault(def => healthArgs.All(arg => def.defName.ToLower().Contains(arg.ToLower()) || def.label.ToLower().Contains(arg.ToLower()))); if (capacityDef != null) { output = MyPawnHealthCapacity(viewer, pawn, capacityDef); } else { output = $"@{viewer.username} Could not find a pawn capacity for \"{healthArgs.Aggregate((s1, s2) => s1 + " " + s2)}\""; } } else { output = MyPawnHealthSummary(viewer, pawn); } SendWrappedOutputText(output, message); }
public static Pair <string, Color> GetEfficiencyLabel(Pawn pawn, PawnCapacityDef activity) { float level = pawn.health.capacities.GetLevel(activity); string empty = string.Empty; Color white = Color.white; if (level <= 0.0) { empty = "None".Translate(); white = HealthUtility.DarkRedColor; } else if (level < 0.40000000596046448) { empty = "VeryPoor".Translate(); white = HealthCardUtility.VeryPoorColor; } else if (level < 0.699999988079071) { empty = "Poor".Translate(); white = HealthCardUtility.PoorColor; } else if (level < 1.0 && !Mathf.Approximately(level, 1f)) { empty = "Weakened".Translate(); white = HealthCardUtility.WeakenedColor; } else if (Mathf.Approximately(level, 1f)) { empty = "GoodCondition".Translate(); white = HealthUtility.GoodConditionColor; } else { empty = "Enhanced".Translate(); white = HealthCardUtility.EnhancedColor; } return(new Pair <string, Color>(empty, white)); }
public static Pair <string, Color> GetEfficiencyLabel(Pawn pawn, PawnCapacityDef activity) { float level = pawn.health.capacities.GetLevel(activity); string first = string.Empty; Color second = Color.white; if (level <= 0f) { first = "None".Translate(); second = HealthUtility.DarkRedColor; } else if (level < 0.4f) { first = "VeryPoor".Translate(); second = HealthCardUtility.VeryPoorColor; } else if (level < 0.7f) { first = "Poor".Translate(); second = HealthCardUtility.PoorColor; } else if (level < 1f && !Mathf.Approximately(level, 1f)) { first = "Weakened".Translate(); second = HealthCardUtility.WeakenedColor; } else if (Mathf.Approximately(level, 1f)) { first = "GoodCondition".Translate(); second = HealthUtility.GoodConditionColor; } else { first = "Enhanced".Translate(); second = HealthCardUtility.EnhancedColor; } return(new Pair <string, Color>(first, second)); }
private static string HealthCapacityReport([NotNull] Pawn pawn, [NotNull] PawnCapacityDef capacity) { if (!PawnCapacityUtility.BodyCanEverDoCapacity(pawn.RaceProps.body, capacity)) { return("TKUtils.PawnHealth.IncapableOfCapacity".LocalizeKeyed(capacity.GetLabelFor(pawn))); } var impactors = new List <PawnCapacityUtility.CapacityImpactor>(); var segments = new List <string> { ResponseHelper.JoinPair( RichTextHelper.StripTags(capacity.LabelCap), PawnCapacityUtility.CalculateCapacityLevel(pawn.health.hediffSet, capacity, impactors).ToStringPercent() ), impactors.Any() ? ResponseHelper.JoinPair("TKUtils.PawnHealth.AffectedBy".Localize(), GetImpactorsForPawn(pawn, impactors).SectionJoin()) : "NoHealthConditions".Localize().CapitalizeFirst() }; return(segments.GroupedJoin()); }
public override void RunCommand([NotNull] ITwitchMessage twitchMessage) { if (!PurchaseHelper.TryGetPawn(twitchMessage.Username, out Pawn pawn)) { twitchMessage.Reply("TKUtils.NoPawn".Localize().WithHeader("TabHealth".Localize())); return; } string segment = CommandFilter.Parse(twitchMessage.Message).Skip(1).FirstOrFallback(""); if (segment.NullOrEmpty()) { twitchMessage.Reply(HealthReport(pawn !).WithHeader("TabHealth".Localize())); return; } PawnCapacityDef capacity = DefDatabase <PawnCapacityDef> .AllDefs.FirstOrDefault( d => d.defName.EqualsIgnoreCase(segment) || d.LabelCap.RawText.ToToolkit().EqualsIgnoreCase(segment.ToToolkit()) ); twitchMessage.Reply((capacity == null ? HealthReport(pawn !) : HealthCapacityReport(pawn !, capacity)).WithHeader("TabHealth".Localize())); }
public virtual float GetFactorOfCapacity(PawnCapacityDef cap) { return(1f); }
public override float GetFactorOfCapacity(PawnCapacityDef cap) { return(Def.CapMods.Find(capMod => capMod.capacity == cap)?.postFactor ?? 1); }
public override float GetOffsetOfCapacity(PawnCapacityDef cap) { return(Def.CapMods.Find(capMod => capMod.capacity == cap)?.offset ?? 0); }
public override void DoWindowContents( Rect rect ) { base.DoWindowContents( rect ); if ( IsDirty ) { BuildPawnList( ); } var position = new Rect( 0f, 0f, rect.width, 80f ); GUI.BeginGroup( position ); var x = 0f; Text.Font = GameFont.Small; // prisoner / colonist / Animal toggle var sourceButton = new Rect( 0f, 0f, 200f, 35f ); if ( Widgets.ButtonText( sourceButton, Source.ToString().Translate( ) ) ) { List<FloatMenuOption> options = new List<FloatMenuOption>(); if (Source != SourceOptions.Colonists) options.Add( new FloatMenuOption( "Colonists".Translate(), delegate { Source = SourceOptions.Colonists; IsDirty = true; })); if (Source != SourceOptions.Prisoners) options.Add( new FloatMenuOption( "Prisoners".Translate(), delegate { Source = SourceOptions.Prisoners; IsDirty = true; })); if (Source != SourceOptions.Animals) options.Add( new FloatMenuOption( "Animals".Translate(), delegate { Source = SourceOptions.Animals; IsDirty = true; })); Find.WindowStack.Add(new FloatMenu(options)); } // name var nameLabel = new Rect( x, 50f, 175f, 30f ); Text.Anchor = TextAnchor.LowerCenter; Widgets.Label( nameLabel, "FluffyMedical.Name".Translate( ) ); if ( Widgets.ButtonInvisible( nameLabel ) ) { if ( OrderBy == Order.Name ) { Asc = !Asc; } else { OrderBy = Order.Name; Asc = true; } IsDirty = true; } TooltipHandler.TipRegion( nameLabel, "FluffyMedical.ClickToSortBy".Translate( "FluffyMedical.Name".Translate( ) ) ); Widgets.DrawHighlightIfMouseover( nameLabel ); x += 175f; // care var careLabel = new Rect( x, 50f, 100f, 30f ); Widgets.Label( careLabel, "FluffyMedical.Care".Translate( ) ); if ( Widgets.ButtonInvisible( careLabel ) ) { if ( Event.current.shift ) { Utility_Medical.MedicalCareSetterAll( pawns ); } else { if ( OrderBy == Order.Care ) { Asc = !Asc; } else { OrderBy = Order.Care; Asc = true; } IsDirty = true; } } TooltipHandler.TipRegion( careLabel, "FluffyMedical.ClickToSortBy".Translate( "FluffyMedical.Care".Translate( ) ) + "\n" + "FluffyMedical.ShiftClickTo".Translate( "FluffyMedical.SetCare".Translate( ) ) ); Widgets.DrawHighlightIfMouseover( careLabel ); x += 100f; // bloodloss var bloodLabel = new Rect( x, 50f, 50f, 30f ); var bloodIcon = new Rect( x + 17f, 60f, 16f, 16f ); GUI.DrawTexture( bloodIcon, Utility_Medical.BloodTextureWhite ); if ( Widgets.ButtonInvisible( bloodLabel ) ) { if ( OrderBy == Order.BleedRate ) { Asc = !Asc; } else { OrderBy = Order.BleedRate; Asc = true; } IsDirty = true; } TooltipHandler.TipRegion( bloodLabel, "FluffyMedical.ClickToSortBy".Translate( "BleedingRate".Translate( ) ) ); Widgets.DrawHighlightIfMouseover( bloodLabel ); x += 50f; // Operations var opLabel = new Rect( x, 50f, 50f, 30f ); var opIcon = new Rect( x + 17f, 60f, 16f, 16f ); GUI.DrawTexture( opIcon, Utility_Medical.OpTexture ); if ( Widgets.ButtonInvisible( opLabel ) ) { if ( OrderBy == Order.Operations ) { Asc = !Asc; } else { OrderBy = Order.Operations; Asc = true; } IsDirty = true; } TooltipHandler.TipRegion( opLabel, "FluffyMedical.ClickToSortBy".Translate( "FluffyMedical.CurrentOperations".Translate( ) ) ); Widgets.DrawHighlightIfMouseover( opLabel ); x += 50f; var offset = true; // extra 15f offset for... what? makes labels roughly align. var colWidth = ( rect.width - x - 15f ) / CapDefs.Count; for ( var i = 0; i < CapDefs.Count; i++ ) { var defLabel = new Rect( x + colWidth * i - colWidth / 2, 10f + ( offset ? 10f : 40f ), colWidth * 2, 30f ); Widgets.DrawLine( new Vector2( x + colWidth * ( i + 1 ) - colWidth / 2, 40f + ( offset ? 5f : 35f ) ), new Vector2( x + colWidth * ( i + 1 ) - colWidth / 2, 80f ), Color.gray, 1 ); Widgets.Label( defLabel, CapDefs[i].LabelCap ); if ( Widgets.ButtonInvisible( defLabel ) ) { if ( OrderBy == Order.Efficiency && OrderByCapDef == CapDefs[i] ) { Asc = !Asc; } else { OrderBy = Order.Efficiency; OrderByCapDef = CapDefs[i]; Asc = true; } IsDirty = true; } TooltipHandler.TipRegion( defLabel, "FluffyMedical.ClickToSortBy".Translate( CapDefs[i].LabelCap ) ); Widgets.DrawHighlightIfMouseover( defLabel ); offset = !offset; } GUI.EndGroup( ); var content = new Rect( 0f, position.yMax, rect.width, rect.height - position.yMax ); GUI.BeginGroup( content ); DrawRows( new Rect( 0f, 0f, content.width, content.height ) ); GUI.EndGroup( ); }
public static bool Affects(this BodyPartRecord part, PawnCapacityDef capacity) { return(CapacityTags[capacity].Any(tag => part.ThisOrAnyChildHasTag(tag))); }
public static bool AddsHediffThatAffects(this RecipeDef r, PawnCapacityDef capacity, float current, bool negative = false) { return(r.addsHediff.IsHediffThatAffects(capacity, current, negative)); }
public static List <FloatMenuOption> AddedPartOptionsThatAffect(this RecipeDef r, PawnCapacityDef capacity, Pawn pawn, bool negative = false) { var options = new List <FloatMenuOption>(); if (!r?.addsHediff?.IsAddedPart() ?? true) { return(options); } if (!NotMissingVitalIngredient(pawn, r)) { return(options); } var after = r.addsHediff.addedPartProps.partEfficiency; var parts = r.Worker.GetPartsToApplyOn(pawn, r) .Where(p => p.Affects(capacity) && !pawn.health.hediffSet.AncestorHasDirectlyAddedParts(p)); foreach (var part in parts) { var current = PawnCapacityUtility.CalculatePartEfficiency(pawn.health.hediffSet, part); if (after < current == negative) { options.Add(GenerateSurgeryOption(pawn, pawn, r, r.PotentiallyMissingIngredients(null, pawn.Map), part)); } } return(options); }
private static void Postfix(Vector3 clickPos, Pawn pawn, List <FloatMenuOption> opts, bool drafted, FloatMenuOption[] ___equivalenceGroupTempStorage) { if (pawn.thinker.TryGetMainTreeThinkNode <JobGiver_Work>() != null) { IntVec3 clickCell = IntVec3.FromVector3(clickPos); TargetingParameters targetingParameters = new TargetingParameters(); targetingParameters.canTargetPawns = true; targetingParameters.canTargetBuildings = true; targetingParameters.canTargetItems = true; targetingParameters.mapObjectTargetsMustBeAutoAttackable = false; var ZTracker = ZUtils.ZTracker; foreach (Thing item in GenUI.ThingsUnderMouse(clickPos, 1f, targetingParameters)) { bool flag = false; foreach (WorkTypeDef item2 in DefDatabase <WorkTypeDef> .AllDefsListForReading) { for (int i = 0; i < item2.workGiversByPriority.Count; i++) { WorkGiverDef workGiver2 = item2.workGiversByPriority[i]; if (!drafted || workGiver2.canBeDoneWhileDrafted) { WorkGiver_Scanner workGiver_Scanner = workGiver2.Worker as WorkGiver_Scanner; if (workGiver_Scanner != null && workGiver_Scanner.def.directOrderable) { JobFailReason.Clear(); if ((workGiver_Scanner.PotentialWorkThingRequest.Accepts(item) || (workGiver_Scanner.PotentialWorkThingsGlobal(pawn) != null && workGiver_Scanner.PotentialWorkThingsGlobal(pawn).Contains(item))) && !workGiver_Scanner.ShouldSkip(pawn, forced: true)) { string text = null; Action action = null; PawnCapacityDef pawnCapacityDef = workGiver_Scanner.MissingRequiredCapacity(pawn); if (pawnCapacityDef != null) { text = "CannotMissingHealthActivities".Translate(pawnCapacityDef.label); } else { Map oldMap = pawn.Map; Job job = null; Map dest = null; foreach (var otherMap in ZTracker.GetAllMapsInClosestOrder(oldMap)) { if (workGiver_Scanner is WorkGiver_Refuel scanner1) { job = JobPatches.TryIssueJobPackagePatch.JobOnThing( scanner1, pawn, item, true); } else if (workGiver_Scanner.def.defName == "HaulGeneral" || workGiver_Scanner.def.defName == "HaulCorpses") { job = JobPatches.TryIssueJobPackagePatch.JobOnThing(pawn, item, ref dest); } else if (workGiver_Scanner is WorkGiver_DoBill scanner2) { job = JobPatches.TryIssueJobPackagePatch.JobOnThing( scanner2, pawn, item); } else if (workGiver_Scanner is WorkGiver_ConstructDeliverResourcesToBlueprints scanner3) { job = JobPatches.TryIssueJobPackagePatch.JobOnThing( scanner3, pawn, item); } else if (workGiver_Scanner is WorkGiver_ConstructDeliverResourcesToFrames scanner4) { job = JobPatches.TryIssueJobPackagePatch.JobOnThing( scanner4, pawn, item); } else { job = workGiver_Scanner.HasJobOnThing(pawn, item, forced: true) ? workGiver_Scanner.JobOnThing(pawn, item, forced: true) : null; } if (job != null) { break; } } if (job == null) { if (JobFailReason.HaveReason) { text = (JobFailReason.CustomJobString.NullOrEmpty() ? ((string)"CannotGenericWork".Translate(workGiver_Scanner.def.verb, item.LabelShort, item)) : ((string)"CannotGenericWorkCustom".Translate(JobFailReason.CustomJobString))); text = text + ": " + JobFailReason.Reason.CapitalizeFirst(); } else { if (!item.IsForbidden(pawn)) { continue; } text = (item.Position.InAllowedArea(pawn) ? ((string)"CannotPrioritizeForbidden".Translate(item.Label, item)) : ((string)("CannotPrioritizeForbiddenOutsideAllowedArea".Translate() + ": " + pawn.playerSettings.EffectiveAreaRestriction.Label))); } } else { WorkTypeDef workType = workGiver_Scanner.def.workType; if (pawn.WorkTagIsDisabled(workGiver_Scanner.def.workTags)) { text = "CannotPrioritizeWorkGiverDisabled".Translate(workGiver_Scanner.def.label); } else if (pawn.jobs.curJob != null && pawn.jobs.curJob.JobIsSameAs(job)) { text = "CannotGenericAlreadyAm".Translate(workGiver_Scanner.PostProcessedGerund(job), item.LabelShort, item); } else if (pawn.workSettings.GetPriority(workType) == 0) { text = (pawn.WorkTypeIsDisabled(workType) ? ((string)"CannotPrioritizeWorkTypeDisabled".Translate(workType.gerundLabel)) : ((!"CannotPrioritizeNotAssignedToWorkType".CanTranslate()) ? ((string)"CannotPrioritizeWorkTypeDisabled".Translate(workType.pawnLabel)) : ((string)"CannotPrioritizeNotAssignedToWorkType".Translate(workType.gerundLabel)))); } else if (job.def == JobDefOf.Research && item is Building_ResearchBench) { text = "CannotPrioritizeResearch".Translate(); } else if (item.IsForbidden(pawn)) { text = (item.Position.InAllowedArea(pawn) ? ((string)"CannotPrioritizeForbidden".Translate(item.Label, item)) : ((string)("CannotPrioritizeForbiddenOutsideAllowedArea".Translate() + ": " + pawn.playerSettings.EffectiveAreaRestriction.Label))); } else if (!pawn.CanReach(item, workGiver_Scanner.PathEndMode, Danger.Deadly)) { text = (item.Label + ": " + "NoPath".Translate().CapitalizeFirst()).CapitalizeFirst(); } else { text = "PrioritizeGeneric".Translate(workGiver_Scanner.PostProcessedGerund(job), item.Label); Job localJob2 = job; WorkGiver_Scanner localScanner2 = workGiver_Scanner; job.workGiverDef = workGiver_Scanner.def; action = delegate { if (!ZTracker.jobTracker.ContainsKey(pawn)) { ZTracker.jobTracker[pawn] = new JobTracker(); } if (dest != null) { ZTracker.BuildJobListFor(pawn, dest, job); } else { ZTracker.BuildJobListFor(pawn, oldMap, job); } pawn.jobs.EndCurrentJob(JobCondition.InterruptForced); if (workGiver2.forceMote != null) { MoteMaker.MakeStaticMote(clickCell, pawn.Map, workGiver2.forceMote); } }; } } } if (DebugViewSettings.showFloatMenuWorkGivers) { text += $" (from {workGiver2.defName})"; } FloatMenuOption menuOption = FloatMenuUtility.DecoratePrioritizedTask(new FloatMenuOption(text, action), pawn, item); if (drafted && workGiver2.autoTakeablePriorityDrafted != -1) { menuOption.autoTakeable = true; menuOption.autoTakeablePriority = workGiver2.autoTakeablePriorityDrafted; } if (!opts.Any((FloatMenuOption op) => op.Label == menuOption.Label)) { if (workGiver2.equivalenceGroup != null) { if (___equivalenceGroupTempStorage[workGiver2.equivalenceGroup.index] == null || (___equivalenceGroupTempStorage[workGiver2.equivalenceGroup.index].Disabled && !menuOption.Disabled)) { ___equivalenceGroupTempStorage[workGiver2.equivalenceGroup.index] = menuOption; flag = true; } } else { opts.Add(menuOption); } } } } } } } if (flag) { for (int j = 0; j < ___equivalenceGroupTempStorage.Length; j++) { if (___equivalenceGroupTempStorage[j] != null) { opts.Add(___equivalenceGroupTempStorage[j]); ___equivalenceGroupTempStorage[j] = null; } } } } foreach (WorkTypeDef item3 in DefDatabase <WorkTypeDef> .AllDefsListForReading) { for (int k = 0; k < item3.workGiversByPriority.Count; k++) { WorkGiverDef workGiver = item3.workGiversByPriority[k]; if (!drafted || workGiver.canBeDoneWhileDrafted) { WorkGiver_Scanner workGiver_Scanner2 = workGiver.Worker as WorkGiver_Scanner; if (workGiver_Scanner2 != null && workGiver_Scanner2.def.directOrderable) { JobFailReason.Clear(); if (workGiver_Scanner2.PotentialWorkCellsGlobal(pawn).Contains(clickCell) && !workGiver_Scanner2.ShouldSkip(pawn, forced: true)) { Action action2 = null; string label = null; PawnCapacityDef pawnCapacityDef2 = workGiver_Scanner2.MissingRequiredCapacity(pawn); if (pawnCapacityDef2 != null) { label = "CannotMissingHealthActivities".Translate(pawnCapacityDef2.label); } else { Job job2 = workGiver_Scanner2.HasJobOnCell(pawn, clickCell, forced: true) ? workGiver_Scanner2.JobOnCell(pawn, clickCell, forced: true) : null; if (job2 == null) { if (JobFailReason.HaveReason) { if (!JobFailReason.CustomJobString.NullOrEmpty()) { label = "CannotGenericWorkCustom".Translate(JobFailReason.CustomJobString); } else { label = "CannotGenericWork".Translate(workGiver_Scanner2.def.verb, "AreaLower".Translate()); } label = label + ": " + JobFailReason.Reason.CapitalizeFirst(); } else { if (!clickCell.IsForbidden(pawn)) { continue; } if (!clickCell.InAllowedArea(pawn)) { label = "CannotPrioritizeForbiddenOutsideAllowedArea".Translate() + ": " + pawn.playerSettings.EffectiveAreaRestriction.Label; } else { label = "CannotPrioritizeCellForbidden".Translate(); } } } else { WorkTypeDef workType2 = workGiver_Scanner2.def.workType; if (pawn.jobs.curJob != null && pawn.jobs.curJob.JobIsSameAs(job2)) { label = "CannotGenericAlreadyAmCustom".Translate(workGiver_Scanner2.PostProcessedGerund(job2)); } else if (pawn.workSettings.GetPriority(workType2) == 0) { if (pawn.WorkTypeIsDisabled(workType2)) { label = "CannotPrioritizeWorkTypeDisabled".Translate(workType2.gerundLabel); } else if ("CannotPrioritizeNotAssignedToWorkType".CanTranslate()) { label = "CannotPrioritizeNotAssignedToWorkType".Translate(workType2.gerundLabel); } else { label = "CannotPrioritizeWorkTypeDisabled".Translate(workType2.pawnLabel); } } else if (clickCell.IsForbidden(pawn)) { if (!clickCell.InAllowedArea(pawn)) { label = "CannotPrioritizeForbiddenOutsideAllowedArea".Translate() + ": " + pawn.playerSettings.EffectiveAreaRestriction.Label; } else { label = "CannotPrioritizeCellForbidden".Translate(); } } else if (!pawn.CanReach(clickCell, PathEndMode.Touch, Danger.Deadly)) { label = "AreaLower".Translate().CapitalizeFirst() + ": " + "NoPath".Translate().CapitalizeFirst(); } else { label = "PrioritizeGeneric".Translate(workGiver_Scanner2.PostProcessedGerund(job2), "AreaLower".Translate()); Job localJob = job2; WorkGiver_Scanner localScanner = workGiver_Scanner2; job2.workGiverDef = workGiver_Scanner2.def; action2 = delegate { if (pawn.jobs.TryTakeOrderedJobPrioritizedWork(localJob, localScanner, clickCell) && workGiver.forceMote != null) { MoteMaker.MakeStaticMote(clickCell, pawn.Map, workGiver.forceMote); } }; } } } if (!opts.Any((FloatMenuOption op) => op.Label == label.TrimEnd())) { FloatMenuOption floatMenuOption = FloatMenuUtility.DecoratePrioritizedTask(new FloatMenuOption(label, action2), pawn, clickCell); if (drafted && workGiver.autoTakeablePriorityDrafted != -1) { floatMenuOption.autoTakeable = true; floatMenuOption.autoTakeablePriority = workGiver.autoTakeablePriorityDrafted; } opts.Add(floatMenuOption); } } } } } } } }
public virtual float GetOffsetOfCapacity(PawnCapacityDef cap) { return(0f); }