public TreeNode_UIOption_ReservedItem(Building_Shelf shelf, ThingDef reservedThing, IntVec3 cell, bool forcedOpen = false) : base(reservedThing.LabelCap, "AS.ReservedItem.ToolTip".Translate(cell.ToString()), forcedOpen, () => true) { this.shelf = shelf; this.reservedThing = reservedThing; this.cell = cell; }
public void CreateListingFor(Building_Shelf shelf) { SetupListing(shelf); if (!shelf.filterChangedSignalManager.receivers.Contains(this)) { shelf.filterChangedSignalManager.RegisterReceiver(this); shelf.itemsHeldChangedSignalManager.RegisterReceiver(this); } }
public static void Prefix(StorageSettings __instance, ref StoragePriority value) { Building_Shelf shelf = __instance.owner as Building_Shelf; if (value != __instance.Priority) { shelf?.Notify_PriorityChanging(value); } }
public override bool HasJobOnThing(Pawn pawn, Thing t, bool forced = false) { Building_Shelf shelf = t as Building_Shelf; if (shelf == null || !shelf.HasEmptyCell()) { return(false); } if (!shelf.slotGroup.EmptyCells().Any(cell => pawn.CanReserveAndReach(new LocalTargetInfo(cell), PathEndMode.Touch, pawn.NormalMaxDanger(), 1, -1, null, false))) { return(false); } LocalTargetInfo target = t; if (!pawn.CanReserve(target, 1, -1, null, false)) { JobFailReason.Is("ShelfReserved".Translate()); return(false); } foreach (SlotGroup sg in pawn.Map?.haulDestinationManager.AllGroupsListInPriorityOrder ?? Enumerable.Empty <SlotGroup>()) { if (sg.Settings.Priority > shelf.settings.Priority || ((sg.Settings.Priority == shelf.settings.Priority) && (sg.parent is Building_Shelf)) || sg.parent == shelf) { continue; } else { foreach (Thing thing in sg.HeldThings) { if ((thing.stackCount >= thing.def.stackLimit || forced) && shelf.settings.filter.Allows(thing) && StockingUtility.PawnCanAutomaticallyHaul(pawn, thing, forced, shelf.InForbiddenMode)) { return(true); } } } } if (!JobFailReason.HaveReason) { JobFailReason.Is("FillEmptyStock_NoItemsFound_JobFailReason".Translate()); } if (JobFailReason.Reason == "ForbiddenLower".Translate()) { JobFailReason.Is("FillEmptyStock_AllItemsFoundAreForbidden_JobFailReason".Translate()); } return(false); }
public override Job JobOnThing(Pawn pawn, Thing t, bool forced = false) { Thing stockSource = null; IntVec3 destCell = IntVec3.Invalid; Building_Shelf s = t as Building_Shelf; if (s.CanOverlayThing(out stockSource, out destCell)) { return(new Job(StockingJobDefOf.OverlayThing, t, stockSource, destCell)); } return(null); }
public static void Copy(Building_Shelf shelf) { StorageSettingsClipboard.Copy(shelf.settings); StockingSettingsClipboard.copiedShelf = shelf; StockingSettingsClipboard.copied = true; //As both this and StorageSettingsClipboard are static without constructors // I have a timing issue setting up callbacks. I will do so during the first copy if (!setupCallback) { SetupCallback(); } }
public void CopyStockSettingsFrom(Building_Shelf other) { settings.CopyFrom(other.settings); InRackMode = other.InRackMode; InForbiddenMode = other.InForbiddenMode; InPriorityCyclingMode = other.InPriorityCyclingMode; PawnShouldOrganizeAfterFilling = other.PawnShouldOrganizeAfterFilling; FillEmptyStockPriority = other.FillEmptyStockPriority; OrganizeStockPriority = other.OrganizeStockPriority; overlayLimit = other.overlayLimit; stackLimits = new Dictionary <ThingDef, int>(other.stackLimits); RecalcOverlays(); }
private static Gizmo PasteGizmoFor(Building_Shelf shelf) { return(new Command_Action() { icon = ContentFinder <Texture2D> .Get("UI/Commands/PasteSettings", true), defaultLabel = "CommandPasteStockingSettingsLabel".Translate(), defaultDesc = "CommandPasteStockingSettingsDesc".Translate(), action = delegate { SoundDefOf.Tick_High.PlayOneShotOnCamera(null); StockingSettingsClipboard.PasteInto(shelf); }, hotKey = KeyBindingDefOf.Misc5 }); }
public void Notify_SignalReceived(Signal signal) { Building_Shelf shelf = signal.args[0] as Building_Shelf; if (shelf != displayingFor) //Cannot remove OnClose, will do so when erroneous signal sent { shelf.filterChangedSignalManager.DeregisterReceiver(this); shelf.itemsHeldChangedSignalManager.DeregisterReceiver(this); } else { SetupListing(shelf); } }
public override bool HasJobOnThing(Pawn pawn, Thing t, bool forced = false) { Building_Shelf shelf = t as Building_Shelf; LocalTargetInfo target = t; if (!pawn.CanReserveAndReach(target, PathEndMode.Touch, pawn.NormalMaxDanger(), 1, -1, null, false)) { return(false); } return((shelf != null) && shelf.InRackMode && shelf.CanOverlayThing(out Thing source, out IntVec3 dest) && pawn.CanReserve(source, 1, -1, null, false)); }
public override string GetExplanationUnfinalized(StatRequest req, ToStringNumberSense numberSense) { StringBuilder stringBuilder = new StringBuilder(); Building_Shelf shelf = req.Thing as Building_Shelf; stringBuilder.AppendLine("StatWorker.OverlayLimit.Desc.ModSettings".Translate(AS_Mod.settings.maxOverlayLimit)); if (shelf.MaxOverlayLimit < AS_Mod.settings.maxOverlayLimit && shelf.HeaviestAllowedThing != null) { stringBuilder.AppendLine("StatWorker.OverlayLimit.Desc.MassContraint" .Translate(shelf.HeaviestAllowedThing.LabelCap , shelf.HeaviestAllowedThing.GetStatValueAbstract(StatDefOf.Mass) , shelf.GetStatValue(StockingStatDefOf.MaxStockWeight))); } return(stringBuilder.ToString()); }
public override IEnumerable <Thing> PotentialWorkThingsGlobal(Pawn pawn) { List <SlotGroup> slotGroups = pawn.Map?.haulDestinationManager?.AllGroupsListForReading; if (slotGroups == null) { yield break; } for (int i = 0; i < slotGroups.Count; i++) { Building_Shelf shelf = slotGroups[i].parent as Building_Shelf; if (shelf != null) { yield return(shelf); } } }
public override bool HasJobOnThing(Pawn pawn, Thing t, bool forced = false) { Building_Shelf shelf = t as Building_Shelf; LocalTargetInfo target = t; if (!pawn.CanReserveAndReach(target, PathEndMode.Touch, pawn.NormalMaxDanger(), 1, -1, null, false)) { return(false); } return((shelf != null) && shelf.CanCombineThings(out Thing source, out Thing dest) && (pawn.CanReserve(source, 1, -1, null, false) || (shelf.InForbiddenMode && source.IsForbidden(Faction.OfPlayer))) && (pawn.CanReserve(dest, 1, -1, null, false) || (shelf.InForbiddenMode && dest.IsForbidden(Faction.OfPlayer)))); }
public override void OnOpen() { Building_Shelf shelf = this.SelObject as Building_Shelf; if (shelf == null) { return; } if (shelf != this.displayingFor) { CreateListingFor(shelf); } else { RebuildReservationOptions(); } }
//If someone selects another Shelf while Tab is open, OnOpen won't be called inbetween protected override void FillTab() { Building_Shelf shelf = this.SelObject as Building_Shelf; if (shelf == null) { return; } if (shelf != this.displayingFor) { CreateListingFor(shelf); } Rect rect = new Rect(0, 30, ITab_Stock.WinSize.x, ITab_Stock.WinSize.y - 30).ContractedBy(CellSpacing); listing.Begin(rect); listing.DrawUIOptions(); listing.End(); }
public override string GetExplanationUnfinalized(StatRequest req, ToStringNumberSense numberSense) { StringBuilder stringBuilder = new StringBuilder(); Building_Shelf shelf = req.Thing as Building_Shelf; stringBuilder.AppendLine("StatWorker.OverstackLimit.Desc.ModSettings".Translate(AS_Mod.settings.maxOverstackRatio)); if (AS_Mod.settings.overlaysReduceStacklimit) { if (AS_Mod.settings.overlaysReduceStacklimitPartially) { stringBuilder.AppendLine("StatWorker.OverstackLimit.Desc.OverlayReduction.Partial" .Translate(shelf.OverlayLimit * 2f / 3f + 1f / 3f)); } else { stringBuilder.AppendLine("StatWorker.OverstackLimit.Desc.OverlayReduction".Translate(shelf.OverlayLimit)); } } return(stringBuilder.ToString()); }
public static void PasteInto(Building_Shelf shelf) { shelf.CopyStockSettingsFrom(StockingSettingsClipboard.copiedShelf); }
private void SetupListing(Building_Shelf shelf) { TreeNode_UIOption advancedStockingRootNode = new TreeNode_UIOption("AdvancedStocking.Label".Translate()); (new TreeNode_UIOption_Checkbox("InRackMode.Label".Translate(), () => shelf.InRackMode, b => shelf.InRackMode = b, "InRackMode.ToolTip".Translate())) .AddAsChildTo(advancedStockingRootNode); (new TreeNode_UIOption_Checkbox("InPriorityCyclingMode_label".Translate(), () => shelf.InPriorityCyclingMode, b => shelf.InPriorityCyclingMode = b, "InPriorityCyclingMode_tooltip".Translate(), false)) .AddAsChildTo(advancedStockingRootNode); // advancedStockingRootNode.children.Add (new TreeNode_UIOptionCheckbox ("InSingleThingMode_label".Translate(), // () => shelf.InSingleThingMode, b => shelf.InSingleThingMode = b, "Testing", false, () => shelf.InStockingMode)); (new TreeNode_UIOption_Checkbox("InForbiddenMode_label".Translate(), () => shelf.InForbiddenMode, b => shelf.InForbiddenMode = b, "InForbiddenMode_tooltip".Translate(), false)) .AddAsChildTo(advancedStockingRootNode); (new TreeNode_UIOption_Checkbox("AutoOrganizeAfterFilling_label".Translate(), () => shelf.PawnShouldOrganizeAfterFilling, b => shelf.PawnShouldOrganizeAfterFilling = b, "AutoOrganizeAfterFilling_tooltip".Translate(), false)) .AddAsChildTo(advancedStockingRootNode); TreeNode_UIOption prioritiesSubtree = new TreeNode_UIOption("StockJobPriorities_label".Translate(), "StockJobPriorities_tooltip".Translate()); prioritiesSubtree.AddAsChildTo(advancedStockingRootNode); (new TreeNode_UIOption_EnumMenuButton <StockingPriority>("Fill_Empty_Stock_Priority".Translate(), () => Enum.GetName(typeof(StockingPriority), shelf.FillEmptyStockPriority).Translate(), p => shelf.FillEmptyStockPriority = p, null, ITab_Stock.PriorityButtonWidth, "Fill_Empty_Stock_Priority_Tooltip".Translate(), false)) .AddAsChildTo(prioritiesSubtree); (new TreeNode_UIOption_EnumMenuButton <StockingPriority>("Organize_Stock_Priority".Translate(), () => Enum.GetName(typeof(StockingPriority), shelf.OrganizeStockPriority).Translate(), p => shelf.OrganizeStockPriority = p, null, ITab_Stock.PriorityButtonWidth, "Organize_Stock_Priority_Tooltip".Translate(), false)) .AddAsChildTo(prioritiesSubtree); TreeNode_UIOption stockingLimitsRootNode = new TreeNode_UIOption("StockingLimits.Label".Translate()); if (shelf.MaxOverlayLimit > 1) { (new TreeNode_UIOption_Slider("OverlayLimit.Label".Translate(shelf.CurrentOverlaysUsed, shelf.MaxOverlayLimit) , valGetter: () => (float)shelf.OverlayLimit , valSetter: val => shelf.OverlayLimit = (int)val , minGetter: () => shelf.CurrentOverlaysUsed , maxGetter: () => shelf.MaxOverlayLimit , roundTo: 1f , toolTip: "OverlayLimit.ToolTip".Translate())) .AddAsChildTo(stockingLimitsRootNode); } IEnumerable <ThingDef> thingDefsToDisplay = null; if (shelf.settings.filter.AllowedDefCount <= Building_Shelf.MAX_UNHELD_STACKLIMITS_TO_DISPLAY) { thingDefsToDisplay = shelf.settings.filter.AllowedThingDefs; } else { thingDefsToDisplay = shelf.slotGroup.HeldThings.Select(thing => thing.def).Distinct(); } foreach (var thingDef in thingDefsToDisplay) { (new TreeNode_UIOption_Slider(() => "StackLimit.Label".Translate(thingDef.LabelCap, shelf.GetMaxStackLimit(thingDef)) , valGetter: () => (float)shelf.GetStackLimit(thingDef) , valSetter: value => shelf.SetStackLimit(thingDef, (int)value) , minGetter: () => 0f , maxGetter: () => shelf.GetMaxStackLimit(thingDef) , roundTo: 1f , toolTip: "StackLimit.ToolTip".Translate())) .AddAsChildTo(stockingLimitsRootNode); } if (stockingLimitsRootNode.children.NullOrEmpty()) { stockingLimitsRootNode.label = "StockingLimits.Label.NoChildren".Translate(); } Action <TreeNode, TreeNode> configureNodeOpenings = null; FieldInfo openBitsField = typeof(Verse.TreeNode).GetField("openBits", BindingFlags.Instance | BindingFlags.NonPublic); configureNodeOpenings = delegate(TreeNode oldNode, TreeNode newNode) { openBitsField.SetValue(newNode, openBitsField.GetValue(oldNode)); IEnumerator <TreeNode> oldNodeEnum = oldNode.children?.GetEnumerator() ?? Enumerable.Empty <TreeNode>().GetEnumerator(); IEnumerator <TreeNode> newNodeEnum = newNode.children?.GetEnumerator() ?? Enumerable.Empty <TreeNode>().GetEnumerator(); while (oldNodeEnum.MoveNext() && newNodeEnum.MoveNext()) { configureNodeOpenings(oldNodeEnum.Current, newNodeEnum.Current); } }; var newListing = new Listing_TreeUIOption(new List <TreeNode_UIOption>() { stockingLimitsRootNode , advancedStockingRootNode }); int maxOptionIndex = Math.Min(this.listing?.RootOptions.Count ?? 0, newListing.RootOptions.Count); for (int i = 0; i < maxOptionIndex; i++) { configureNodeOpenings(this.listing.RootOptions[i], newListing.RootOptions[i]); } this.displayingFor = shelf; this.listing = newListing; RebuildReservationOptions(); //Perform after nodeOpening configuration as reservations will change }
public override Job JobOnThing(Pawn pawn, Thing t, bool forced = false) { Building_Shelf shelf = t as Building_Shelf; List <Thing> potentials = new List <Thing> (); if (shelf == null) { return(null); } foreach (SlotGroup sg in pawn.Map?.haulDestinationManager.AllGroupsListInPriorityOrder ?? Enumerable.Empty <SlotGroup>()) { if (sg.Settings.Priority > shelf.settings.Priority || ((sg.Settings.Priority == shelf.settings.Priority) && (sg.parent is Building_Shelf))) { continue; } else { foreach (Thing thing in sg.HeldThings) { if ((thing.stackCount >= thing.def.stackLimit || forced) && shelf.settings.filter.Allows(thing) && StockingUtility.PawnCanAutomaticallyHaul(pawn, thing, forced, shelf.InForbiddenMode)) { potentials.Add(thing); } } } } int minDist = 200000000; float maxPartialFullStackFound = 0f; Thing chosenThing = null; foreach (Thing thing in potentials) //I KNOW THIS IS TERRIBLE, BUT I LOVE IT ANYWAYS { int dist = (thing.Position - pawn.Position).LengthHorizontalSquared + (thing.Position - shelf.Position).LengthHorizontalSquared; if (forced) { float part = (float)thing.stackCount / (float)thing.def.stackLimit; if (part < maxPartialFullStackFound) { continue; } if (part > maxPartialFullStackFound) { maxPartialFullStackFound = part; chosenThing = thing; minDist = dist; continue; } } if (dist < minDist) { minDist = dist; chosenThing = thing; } } if (chosenThing == null) { return(null); } IntVec3 destEmptyCell = shelf.slotGroup.EmptyCells().FirstOrDefault(cell => pawn.CanReserveAndReach(new LocalTargetInfo(cell), PathEndMode.Touch, pawn.NormalMaxDanger(), 1, -1, null, false)); if (destEmptyCell == default(IntVec3)) { return(null); } Job job = new Job(StockingJobDefOf.FillEmptyStock, chosenThing, destEmptyCell, shelf); job.haulOpportunisticDuplicates = true; job.haulMode = HaulMode.ToCellStorage; job.count = chosenThing.stackCount; return(job); }