public static void DrawFilters(Dialog_BillConfig __instance, Rect inRect) { var billRaw = (Bill_Production)BillGetter.GetValue(__instance); if (billRaw == null) { return; } Main.Instance.IsRootBillFilterBeingDrawn = false; var extendedBillDataStorage = Main.Instance.GetExtendedBillDataStorage(); extendedBillDataStorage.MirrorBillToLinkedBills(billRaw); var extendedBillData = extendedBillDataStorage.GetExtendedDataFor(billRaw); if (extendedBillData == null) { return; } // Bill navigation buttons DrawWorkTableNavigation(__instance, billRaw, inRect); // Linked bill handling if (extendedBillDataStorage.IsLinkedBill(billRaw)) { var unlinkRect = new Rect(inRect.xMin + 28f, inRect.yMin + 50f, 24f, 24f); if (Widgets.ButtonImage(unlinkRect, Resources.BreakLink)) { extendedBillDataStorage.RemoveBillFromLinkSets(billRaw); } TooltipHandler.TipRegion(unlinkRect, "IW.BreakLinkToOtherBillsTip".Translate()); } // Bill renaming { var renameRect = new Rect(inRect.xMax - 75f, inRect.yMin + 4f, 24f, 24f); if (Widgets.ButtonImage(renameRect, Resources.Rename)) { Find.WindowStack.Add(new Dialog_RenameBill(extendedBillData, billRaw.LabelCap)); } TooltipHandler.TipRegion(renameRect, "IW.RenameBillTip".Translate()); } const float columnWidth = 180f; const float middleColumn = columnWidth + 34f; // Allowed worker filter var potentialWorkers = GetAllowedWorkersWithSkillLevel(billRaw); if (potentialWorkers != null) { var anyoneText = "IW.NoColRestrictionLabel".Translate(); var workerButtonRect = new Rect(middleColumn + 3f, inRect.yMin + 18f, columnWidth, 30f); var currentWorkerLabel = extendedBillData.Worker != null ? "IW.RestrictToLabel".Translate() + " " + extendedBillData.Worker.NameStringShort.CapitalizeFirst() : anyoneText; if (Widgets.ButtonText(workerButtonRect, currentWorkerLabel)) { var potentialWorkerList = new List <FloatMenuOption> { new FloatMenuOption( anyoneText, delegate { extendedBillData.Worker = null; }) }; foreach (var allowedWorkerAndTheirSkill in potentialWorkers) { var allowedWorker = allowedWorkerAndTheirSkill.First; var skillRecord = allowedWorkerAndTheirSkill.Second; var skillPrefix = ""; if (skillRecord != null) { var level = skillRecord.Level; string passion; switch (skillRecord.passion) { case Passion.Minor: passion = "+"; break; case Passion.Major: passion = "++"; break; default: passion = ""; break; } skillPrefix = $"[{level}{passion}] "; } var nameWithSkill = $"{skillPrefix}" + "IW.RestrictToLabel".Translate() + " " + $"{allowedWorker}"; var workerMenuItem = new FloatMenuOption(nameWithSkill, delegate { extendedBillData.Worker = allowedWorker; }); potentialWorkerList.Add(workerMenuItem); } Find.WindowStack.Add(new FloatMenu(potentialWorkerList)); } TooltipHandler.TipRegion(workerButtonRect, "IW.RestrictJobToSpecificColonistTip".Translate()); } // Custom take to stockpile, overlay dummy button { var storeRect = new Rect(middleColumn + 3f, inRect.yMin + 114f, columnWidth, 30f); var label = extendedBillData.UsesTakeToStockpile() ? extendedBillData.CurrentTakeToStockpileLabel() : ("BillStoreMode_" + billRaw.storeMode).Translate(); Widgets.ButtonText(storeRect, label); TooltipHandler.TipRegion(storeRect, "IW.CrafterWillToSpecificStockpileTip".Translate()); } // Filter copy/paste buttons if (billRaw.ingredientFilter != null) { const float filterButtonWidth = 96f; const float filterButtonHeight = 24f; var oldFont = Text.Font; Text.Font = GameFont.Tiny; var copyPasteHandler = Main.Instance.BillCopyPasteHandler; var copyButtonRect = new Rect(inRect.xMax - filterButtonWidth * 2 + 4f, inRect.yMax - 35f, filterButtonWidth, filterButtonHeight); var parentFilter = billRaw.recipe?.fixedIngredientFilter; if (Widgets.ButtonText(copyButtonRect, "IW.CopyFilterButton".Translate())) { copyPasteHandler.CopyFilter(billRaw.ingredientFilter, parentFilter); } TooltipHandler.TipRegion(copyButtonRect, "IW.CopyFilterTip".Translate()); if (copyPasteHandler.IsMatchingFilterCopied(parentFilter)) { var pasteButtonRect = new Rect(copyButtonRect); pasteButtonRect.xMin += filterButtonWidth + 4f; pasteButtonRect.xMax += filterButtonWidth + 4f; if (Widgets.ButtonText(pasteButtonRect, "IW.PasteFilterButton".Translate())) { copyPasteHandler.PasteCopiedFilterInto(billRaw.ingredientFilter); } } Text.Font = oldFont; } if (!ExtendedBillDataStorage.CanOutputBeFiltered(billRaw)) { return; } if (billRaw.repeatMode != BillRepeatModeDefOf.TargetCount) { return; } { var keyboardRect = new Rect(middleColumn + 90f, inRect.yMin + 208f, 24f, 24f); void TargetCountSetter(int i) { billRaw.targetCount = i; if (billRaw.unpauseWhenYouHave >= billRaw.targetCount) { billRaw.unpauseWhenYouHave = billRaw.targetCount - 1; } } if (Widgets.ButtonImage(keyboardRect, Resources.Rename)) { Find.WindowStack.Add(new Dialog_NumericEntry( billRaw.targetCount, i => i > 0, TargetCountSetter)); } TooltipHandler.TipRegion(keyboardRect, "IW.RenameTip".Translate()); } const float buttonHeight = 26f; const float smallButtonHeight = 24f; var y = inRect.height - 248f + Text.LineHeight; // "Unpause when" level adjustment buttons if (billRaw.pauseWhenSatisfied) { var buttonWidth = 42f; var minusOneRect = new Rect(middleColumn, inRect.height - 70, buttonWidth, smallButtonHeight); if (Widgets.ButtonText(minusOneRect, "-1")) { if (billRaw.unpauseWhenYouHave > 0) { billRaw.unpauseWhenYouHave--; } } var plusOneRect = new Rect(minusOneRect); plusOneRect.xMin += buttonWidth + 2f; plusOneRect.xMax += buttonWidth + 2f; if (Widgets.ButtonText(plusOneRect, "+1")) { if (billRaw.unpauseWhenYouHave < billRaw.targetCount - 1) { billRaw.unpauseWhenYouHave++; } } var keyboardRect = new Rect(plusOneRect.xMax + 2f, plusOneRect.yMin, 24f, 24f); if (Widgets.ButtonImage(keyboardRect, Resources.Rename)) { Find.WindowStack.Add(new Dialog_NumericEntry( billRaw.unpauseWhenYouHave, i => i < billRaw.targetCount, i => billRaw.unpauseWhenYouHave = i)); } TooltipHandler.TipRegion(keyboardRect, "IW.RenameTip".Translate()); } // Restrict counting to specific stockpile { y += 33; var subRect = new Rect(0f, y, columnWidth, buttonHeight); var anyStockpileText = "IW.CountOnStockpilesText".Translate(); var currentCountingStockpileLabel = extendedBillData.UsesCountingStockpile() ? "Count in " + extendedBillData.GetCountingStockpile().label : anyStockpileText; var map = Find.VisibleMap; var allStockpiles = map.zoneManager.AllZones.OfType <Zone_Stockpile>().ToList(); if (Widgets.ButtonText(subRect, currentCountingStockpileLabel)) { var potentialStockpileList = new List <FloatMenuOption> { new FloatMenuOption( anyStockpileText, delegate { extendedBillData.RemoveCountingStockpile(); }) }; foreach (var stockpile in allStockpiles) { var stockpileName = "IW.CountInText".Translate() + " " + stockpile.label; var menuOption = new FloatMenuOption( stockpileName, delegate { extendedBillData.SetCountingStockpile(stockpile); }); potentialStockpileList.Add(menuOption); } Find.WindowStack.Add(new FloatMenu(potentialStockpileList)); } TooltipHandler.TipRegion(subRect, "IW.WillCountTowardsTargetTip".Translate()); } var thingDef = billRaw.recipe.products.First().thingDef; if (!thingDef.CountAsResource) { // Counted items filter y += 33; var countedLabelRect = new Rect(0f, y, columnWidth, buttonHeight); Widgets.Label(countedLabelRect, "IW.CountedItemsFilter".Translate()); y += Text.LineHeight; var filter = extendedBillData.OutputFilter; if (filter.allowedHitPointsConfigurable) { var allowedHitPointsPercents = filter.AllowedHitPointsPercents; var rect1 = new Rect(0f, y, columnWidth, buttonHeight); Widgets.FloatRange(rect1, 10, ref allowedHitPointsPercents, 0f, 1f, "HitPoints", ToStringStyle.PercentZero); TooltipHandler.TipRegion(rect1, "IW.HitPointsTip".Translate()); filter.AllowedHitPointsPercents = allowedHitPointsPercents; } if (filter.allowedQualitiesConfigurable) { y += 33; var rect2 = new Rect(0f, y, columnWidth, buttonHeight); var allowedQualityLevels = filter.AllowedQualityLevels; Widgets.QualityRange(rect2, 11, ref allowedQualityLevels); TooltipHandler.TipRegion(rect2, "IW.QualityTip".Translate()); filter.AllowedQualityLevels = allowedQualityLevels; } } // Use input ingredients for counted items filter if (billRaw.ingredientFilter != null && thingDef.MadeFromStuff) { y += 33; var subRect = new Rect(0f, y, columnWidth, buttonHeight); Widgets.CheckboxLabeled(subRect, "IW.MatchInputIngredientsText".Translate(), ref extendedBillData.UseInputFilter); TooltipHandler.TipRegion(subRect, "IW.IngredientsTip".Translate()); } // Deadmans clothing count filter if (thingDef.IsApparel) { var nonDeadmansApparelFilter = new SpecialThingFilterWorker_NonDeadmansApparel(); if (!nonDeadmansApparelFilter.CanEverMatch(thingDef)) { // Thing can't be worn. return; } y += 26; var rect3 = new Rect(0f, y, columnWidth, buttonHeight); Widgets.CheckboxLabeled(rect3, "IW.CountCorpseClothesLabel".Translate(), ref extendedBillData.AllowDeadmansApparel); TooltipHandler.TipRegion(rect3, "IW.CountCorpseClothesDesc".Translate()); y += 26; var rect4 = new Rect(0f, y, columnWidth, buttonHeight); Widgets.CheckboxLabeled(rect4, "IW.CountEquippedClothesLabel".Translate(), ref extendedBillData.CountWornApparel); TooltipHandler.TipRegion(rect4, "IW.CountEquippedClothesDesc".Translate()); } }
static bool Prefix(ref Bill_Production bill, ref int __result) { if (!ExtendedBillDataStorage.CanOutputBeFiltered(bill)) { return(true); } var extendedBillData = Main.Instance.GetExtendedBillDataStorage().GetExtendedDataFor(bill); if (extendedBillData == null) { return(true); } var productThingDef = bill.recipe.products.First().thingDef; var isThingAResource = productThingDef.CountAsResource; if (isThingAResource && !extendedBillData.UsesCountingStockpile()) { return(true); } var statFilterWrapper = new StatFilterWrapper(extendedBillData); if (!statFilterWrapper.IsAnyFilteringNeeded(productThingDef)) { return(true); } SpecialThingFilterWorker_NonDeadmansApparel nonDeadmansApparelFilter = null; if (!extendedBillData.AllowDeadmansApparel && productThingDef.IsApparel) { // We want to filter out corpse worn apparel nonDeadmansApparelFilter = new SpecialThingFilterWorker_NonDeadmansApparel(); if (!nonDeadmansApparelFilter.CanEverMatch(productThingDef)) { // Not apparel, don't bother checking nonDeadmansApparelFilter = null; } } __result = 0; if (productThingDef.Minifiable) { var minifiedThings = bill.Map.listerThings.ThingsInGroup(ThingRequestGroup.MinifiedThing); foreach (var thing in minifiedThings) { var minifiedThing = (MinifiedThing)thing; var innerThing = minifiedThing.InnerThing; if (innerThing.def == productThingDef && statFilterWrapper.DoesThingOnMapMatchFilter(bill.ingredientFilter, innerThing) && statFilterWrapper.DoesThingOnMapMatchFilter(bill.ingredientFilter, minifiedThing)) { __result++; } } return(false); } var thingList = bill.Map.listerThings.ThingsOfDef(productThingDef).ToList(); foreach (var thing in thingList) { if (!statFilterWrapper.DoesThingOnMapMatchFilter(bill.ingredientFilter, thing)) { continue; } if (nonDeadmansApparelFilter != null && !nonDeadmansApparelFilter.Matches(thing)) { continue; } __result += thing.stackCount; } if (!statFilterWrapper.ShouldCheckWornClothes(productThingDef)) { return(false); } foreach (var colonist in Find.VisibleMap.mapPawns.FreeColonists) { foreach (var apparel in colonist.apparel.WornApparel) { if (apparel.def != productThingDef) { continue; } if (statFilterWrapper.DoesThingMatchFilter(bill.ingredientFilter, apparel)) { __result++; } } } return(false); }