public static bool IsRetaining(this Building_Storage bs) { if (RetainingLWM.RetainingForcedForAll) { return(true); } return(bs.GetComp <RetainingLWMComp>()?.IsRetaining ?? false); }
static void Postfix(Building_Storage __instance #if DEBUG , Thing newItem // might be null? #endif ) { #if DEBUG Log.Message("" + __instance + " lost thing " + newItem); #endif __instance.GetComp <CompRestrictedStorage>()?.CheckForIncorrectItems(); }
public static void Postfix(Building_Storage __instance, Map map) { CompDeepStorage cds; if ((cds = __instance.GetComp <CompDeepStorage>()) == null) { return; } foreach (var cell in __instance.AllSlotCells()) { var list = map.thingGrid.ThingsListAt(cell); var alreadyFoundItemOnTop = false; for (var i = list.Count - 1; i >= 0; i--) { var thing = list[i]; if (!thing.Spawned || !thing.def.EverStorable(false)) { continue; // don't make people walking past be invisible... } if (cds.cdsProps.overlayType != GuiOverlayType.Normal || !cds.showContents) // Remove gui overlay - this includes number of stackabe item, quality, etc { map.listerThings.ThingsInGroup(ThingRequestGroup.HasGUIOverlay).Remove(thing); } if (thing.def.drawerType != DrawerType.MapMeshOnly) { if (!alreadyFoundItemOnTop) { Utils.TopThingInDeepStorage.Add(thing); } if (!cds.showContents) { map.dynamicDrawManager.DeRegisterDrawable(thing); } } alreadyFoundItemOnTop = true; // it's true now, one way or another! if (!cds.showContents) { map.tooltipGiverList.Notify_ThingDespawned(thing); // should this go with guioverlays? } // Don't need to thing.DirtyMapMesh(map); because of course it's dirty on spawn setup ;p } // end cell // Now put the DSU at the top of the ThingsList here: list.Remove(__instance); list.Add(__instance); } }
// LWM rewrote most of this method to meet their implementation of CompDeepStorage private void DisplayHeaderInfo(ref float curY, float width, Building_Storage cabinet, int numCells, List <Thing> itemsList) { CompDeepStorage cds = cabinet.GetComp <CompDeepStorage>(); if (cds == null) { return; // what are we even doing here, mmm? } Rect rect = new Rect(0f, curY, width, 22f); if (itemsList.Count < 1) { Widgets.Label(rect, "NoItemsAreStoredHere".Translate()); curY += 22; return; } float itemsTotalMass = 0; // or Bulk for CE ;p for (int i = 0; i < itemsList.Count; i++) { itemsTotalMass += itemsList[i].GetStatValue(cds.stat, true) * (float)itemsList[i].stackCount; } if (cds.limitingTotalFactorForCell > 0f) { Widgets.Label(rect, "LWM.ContentHeaderOneOf".Translate(itemsList.Count.ToString(), cds.stat.ToString(), itemsTotalMass.ToString("0.##"), (cds.limitingTotalFactorForCell * numCells).ToString("0.##"))); } else { Widgets.Label(rect, "LWM.ContentHeaderOne".Translate(itemsList.Count.ToString(), cds.stat.ToString(), itemsTotalMass.ToString("0.##"))); } curY += 22f; }
static bool Prefix(Thing __instance) { if (Find.CameraDriver.CurrentZoom != CameraZoomRange.Closest) { return(false); } Building_Storage DSU = __instance as Building_Storage; if (DSU == null) { return(true); } CompDeepStorage cds = DSU.GetComp <CompDeepStorage>(); if (cds == null) { return(true); } if (cds.cdsProps.overlayType == LWM.DeepStorage.GuiOverlayType.Normal) { return(true); } if (cds.cdsProps.overlayType == GuiOverlayType.None) { return(false); } List <Thing> things; String s; if (cds.cdsProps.overlayType == GuiOverlayType.CountOfAllStacks) { // probably Armor Racks, Clothing Racks, Weapon Lockers etc... things = new List <Thing>(); foreach (IntVec3 c in DSU.AllSlotCellsList()) { things.AddRange(__instance.Map.thingGrid.ThingsListAtFast(c).FindAll(t => t.def.EverStorable(false))); } if (things.Count == 0) { if (cds.cdsProps.showContents) { return(false); // If it's empty, player will see! } s = "LWM_DS_Empty".Translate(); } else if (things.Count == 1) { s = 1.ToStringCached(); // Why not s="1";? You never know, someone may be playing in... } else if (AllSameType(things)) { s = "x" + things.Count.ToStringCached(); } else { s = "[ " + things.Count.ToStringCached() + " ]"; } GenMapUI.DrawThingLabel(GenMapUI.LabelDrawPosFor(__instance, 0f), s, GenMapUI.DefaultThingLabelColor); return(false); } if (cds.cdsProps.overlayType == GuiOverlayType.CountOfStacksPerCell) { // maybe Armor Racks, Clothing Racks? foreach (IntVec3 c in DSU.AllSlotCellsList()) { things = __instance.Map.thingGrid.ThingsListAtFast(c).FindAll(t => t.def.EverStorable(false)); if (things.Count == 0) { if (cds.cdsProps.showContents) { continue; // if it's empty, player will see! } s = "LWM_DS_Empty".Translate(); } else if (things.Count == 1) { s = 1.ToStringCached(); // ..a language that doesn't use arabic numerals? } else if (AllSameType(things)) { s = "x" + things.Count.ToStringCached(); } else { s = "[ " + things.Count.ToStringCached() + " ]"; } GenMapUI.DrawThingLabel(GenMapUI.LabelDrawPosFor(c), s, GenMapUI.DefaultThingLabelColor); } return(false); } if (cds.cdsProps.overlayType == GuiOverlayType.SumOfAllItems) { // probably food baskets, skips, etc... things = new List <Thing>(); foreach (IntVec3 c in DSU.slotGroup.CellsList) { things.AddRange(__instance.Map.thingGrid.ThingsListAtFast(c) .FindAll(t => t.def.EverStorable(false))); } if (things.Count == 0) { if (cds.cdsProps.showContents) { return(false); // if it's empty, player will see } s = "LWM_DS_Empty".Translate(); } else { int count = things[0].stackCount; bool allTheSame = true; for (int i = 1; i < things.Count; i++) { if (things[i].def != things[0].def) { allTheSame = false; } count += things[i].stackCount; } if (allTheSame) { s = count.ToStringCached(); } else { s = "[ " + count.ToStringCached() + " ]"; } } GenMapUI.DrawThingLabel(GenMapUI.LabelDrawPosFor(__instance, 0f), s, GenMapUI.DefaultThingLabelColor); return(false); } Log.Warning("LWM DeepStorage: could not find GuiOverlayType of " + cds.cdsProps.overlayType); return(true); }
protected override void FillTab() { buildingStorage = this.SelThing as Building_Storage; // don't attach this to other things, 'k? List <Thing> storedItems; //TODO: set fonts ize, etc. Text.Font = GameFont.Small; // 10f border: Rect frame = new Rect(10f, 10f, this.size.x - 10, this.size.y - 10); GUI.BeginGroup(frame); Text.Font = GameFont.Small; GUI.color = Color.white; /******* Title *******/ float curY = 0f; Widgets.ListSeparator(ref curY, frame.width, labelKey.Translate() #if DEBUG + " (" + buildingStorage.ToString() + ")" // extra info for debugging #endif ); curY += 5f; /****************** Header: Show count of contents, mass, etc: ****************/ //TODO: handle each cell separately? string header, headerTooltip; CompDeepStorage cds = buildingStorage.GetComp <CompDeepStorage>(); if (cds != null) { storedItems = cds.getContentsHeader(out header, out headerTooltip); } else { storedItems = CompDeepStorage.genericContentsHeader(buildingStorage, out header, out headerTooltip); } Rect tmpRect = new Rect(8f, curY, frame.width - 16, Text.CalcHeight(header, frame.width - 16)); Widgets.Label(tmpRect, header); // TODO: tooltip. Not that it's anything but null now curY += (tmpRect.height); //todo? /************* ScrollView ************/ /************* (contents) ************/ storedItems = storedItems.OrderBy((Thing x) => x.def.defName). ThenByDescending((Thing x) => { QualityCategory c; x.TryGetQuality(out c); return((int)c); }). ThenByDescending((Thing x) => (x.HitPoints / x.MaxHitPoints)).ToList(); // outRect is the is the rectangle that is visible on the screen: Rect outRect = new Rect(0f, 10f + curY, frame.width, frame.height - curY - GenUI.ListSpacing - TopPadding); // viewRect is inside the ScrollView, so it starts at y=0f Rect viewRect = new Rect(0f, 0f, frame.width - 16f, this.scrollViewHeight);//TODO: scrollbars are slightly too far to the right // 16f ensures plenty of room for scrollbars. // scrollViewHeight is set at the end of this call (via layout?); it is the proper // size the next time through, so it all works out. Widgets.BeginScrollView(outRect, ref this.scrollPosition, viewRect, true); curY = 0f; // now inside ScrollView if (storedItems.Count < 1) { Widgets.Label(viewRect, "NoItemsAreStoredHere".Translate()); curY += 22; } string stringUpper = searchString.ToUpperInvariant(); List <Thing> itemToDraw = storedItems .Where(t => t.LabelNoCount .ToUpperInvariant() .Contains(stringUpper)).ToList(); GetIndexRangeFromScrollPosition(outRect.height, this.scrollPosition.y, out int from, out int to, GenUI.ListSpacing); to = to > itemToDraw.Count ? itemToDraw.Count : to; curY = from * GenUI.ListSpacing; for (int i = from; i < to; i++) { this.DrawThingRow(ref curY, viewRect.width, itemToDraw[i]); } if (Event.current.type == EventType.Layout) { this.scrollViewHeight = storedItems.Count * GenUI.ListSpacing + 25f; //25f buffer -- ?? } Widgets.EndScrollView(); searchString = Widgets.TextField( new Rect(0, outRect.yMax, outRect.width - GenUI.ScrollBarWidth, GenUI.ListSpacing) , searchString); GUI.EndGroup(); //TODO: this should get stored at top and set here. GUI.color = Color.white; //TODO: this should get stored at top and set here. // it should get set to whatever draw-row uses at top Text.Anchor = TextAnchor.UpperLeft; }
static bool Prefix(Thing __instance) { if (Find.CameraDriver.CurrentZoom != CameraZoomRange.Closest) { return(true); // maybe someone changes this? Who knows. } Building_Storage DSU = __instance as Building_Storage; if (DSU == null) { return(true); } CompDeepStorage cds = DSU.GetComp <CompDeepStorage>(); if (cds == null) { return(true); } if (cds.cdsProps.overlayType == LWM.DeepStorage.GuiOverlayType.Normal) { return(true); } if (cds.cdsProps.overlayType == GuiOverlayType.None) { return(false); } List <Thing> things; String s; if (cds.cdsProps.overlayType == GuiOverlayType.CountOfAllStacks) { // maybe Armor Racks, Clothing Racks, def Weapon Lockers etc... things = new List <Thing>(); foreach (IntVec3 c in DSU.AllSlotCellsList()) { things.AddRange(__instance.Map.thingGrid.ThingsListAtFast(c).FindAll(t => t.def.EverStorable(false))); } if (things.Count == 0) { if (cds.cdsProps.showContents) { return(false); // If it's empty, player will see! } s = "LWM_DS_Empty".Translate(); } else if (things.Count == 1) { s = 1.ToStringCached(); // Why not s="1";? You never know, someone may be playing in... } else if (AllSameType(things)) { s = "x" + things.Count.ToStringCached(); } else { s = "[ " + things.Count.ToStringCached() + " ]"; } GenMapUI.DrawThingLabel(GenMapUI.LabelDrawPosFor(__instance, 0f), s, GenMapUI.DefaultThingLabelColor); return(false); } if (cds.cdsProps.overlayType == GuiOverlayType.CountOfStacksPerCell) { // maybe Armor Racks, Clothing Racks? foreach (IntVec3 c in DSU.AllSlotCellsList()) { things = __instance.Map.thingGrid.ThingsListAtFast(c).FindAll(t => t.def.EverStorable(false)); if (things.Count == 0) { if (cds.cdsProps.showContents) { continue; // if it's empty, player will see! } s = "LWM_DS_Empty".Translate(); } else if (things.Count == 1) { s = 1.ToStringCached(); // ..a language that doesn't use arabic numerals? } else if (AllSameType(things)) { s = "x" + things.Count.ToStringCached(); } else { s = "[ " + things.Count.ToStringCached() + " ]"; } var l2 = GenMapUI.LabelDrawPosFor(c); // l2.x+=cds.x; // l2.y+=cds.y; l2.y += 10f; GenMapUI.DrawThingLabel(l2, s, GenMapUI.DefaultThingLabelColor); } return(false); } if (cds.cdsProps.overlayType == GuiOverlayType.SumOfAllItems) { // probably food baskets, skips, etc... things = new List <Thing>(); foreach (IntVec3 c in DSU.slotGroup.CellsList) { things.AddRange(__instance.Map.thingGrid.ThingsListAtFast(c) .FindAll(t => t.def.EverStorable(false))); } if (things.Count == 0) { if (cds.cdsProps.showContents) { return(false); // if it's empty, player will see } s = "LWM_DS_Empty".Translate(); } else { int count = things[0].stackCount; bool allTheSame = true; for (int i = 1; i < things.Count; i++) { if (things[i].def != things[0].def) { allTheSame = false; } count += things[i].stackCount; } if (allTheSame) { s = count.ToStringCached(); } else { s = "[ " + count.ToStringCached() + " ]"; } } GenMapUI.DrawThingLabel(GenMapUI.LabelDrawPosFor(__instance, 0f), s, GenMapUI.DefaultThingLabelColor); return(false); } if (cds.cdsProps.overlayType == GuiOverlayType.SumOfItemsPerCell) { // Big Shelves bool anyItems = false; foreach (IntVec3 c in DSU.AllSlotCellsList()) { bool itemsWithStackSizeOne = false; things = __instance.Map.thingGrid.ThingsListAtFast(c).FindAll(t => t.def.EverStorable(false)); if (things.Count > 0) { anyItems = true; int count = 0; for (int i = 0; i < things.Count; i++) { // Break logic if there is anything with a stackLimit of 1 // show instead the count of stacks: if (itemsWithStackSizeOne || things[i].def.stackLimit == 1) { itemsWithStackSizeOne = true; if (things.Count == 1) { s = 1.ToStringCached(); // ..a language that doesn't use arabic numerals? } else if (AllSameType(things)) { s = "x" + things.Count.ToStringCached(); } else { s = "[ " + things.Count.ToStringCached() + " ]"; } var l = GenMapUI.LabelDrawPosFor(c); l.y += 10f; GenMapUI.DrawThingLabel(l, s, GenMapUI.DefaultThingLabelColor); goto WhyDoesCSharpNotHaveBreakTwo; } else { count += things[i].stackCount; } } // end list of things. if (AllSameType(things)) { s = count.ToStringCached(); } else { s = "[ " + count.ToStringCached() + " ]"; } var l2 = GenMapUI.LabelDrawPosFor(c); l2.y += 10f; GenMapUI.DrawThingLabel(l2, s, GenMapUI.DefaultThingLabelColor); } // if count > 0 WhyDoesCSharpNotHaveBreakTwo :; } // foreach cell if (!anyItems && !cds.cdsProps.showContents) // there are no items, but no way to see that. { s = "LWM_DS_Empty".Translate(); GenMapUI.DrawThingLabel(GenMapUI.LabelDrawPosFor(__instance, 0f), s, GenMapUI.DefaultThingLabelColor); } return(false); } Log.Warning("LWM DeepStorage: could not find GuiOverlayType of " + cds.cdsProps.overlayType); return(true); }
// LWM rewrote most of this method to meet their implementation of CompDeepStorage private void DisplayHeaderInfo(ref float curY, float width, Building_Storage building, int numCells, List <Thing> itemsList) { // Header information regardless of what the storage building is: Rect rect = new Rect(0f, curY, width, 22f); // TODO: Add hooks for other mods: // E.g., StockpileForDisaster has a nice little checkbox that shows whether // pawns can freely take from the unit, or whether restrictions are in effect CompDeepStorage cds = building.GetComp <CompDeepStorage>(); if (cds == null) { return; // what are we even doing here, mmm? In a vanilla shelf, probably! } bool flagUseStackInsteadOfItem = false; // "3/4 Items" vs "3/4 Stacks" float itemsTotalMass = 0; // or Bulk for CE ;p for (int i = 0; i < itemsList.Count; i++) { itemsTotalMass += itemsList[i].GetStatValue(cds.stat, true) * (float)itemsList[i].stackCount; if (itemsList[i].def.stackLimit > 1) { flagUseStackInsteadOfItem = true; } } if (cds.limitingTotalFactorForCell > 0f) { string tmpLabel = "LWM.ContentsHeaderItemsMass"; if (flagUseStackInsteadOfItem) { tmpLabel = "LWM.ContentsHeaderStacksMass"; } Widgets.Label(rect, tmpLabel.Translate(itemsList.Count, cds.maxNumberStacks * numCells, cds.stat.ToString().ToLower(), itemsTotalMass.ToString("0.##"), (cds.limitingTotalFactorForCell * numCells).ToString("0.##"))); } else { string tmpLabel = "LWM.ContentsHeaderItems"; if (flagUseStackInsteadOfItem) { tmpLabel = "LWM.ContentsHeaderStacks"; } Widgets.Label(rect, tmpLabel.Translate(itemsList.Count, cds.maxNumberStacks * numCells, cds.stat.ToString().ToLower(), itemsTotalMass.ToString("0.##"))); } curY += 22f; /* Limiting factor for Item: what's too damn big */ if (cds.limitingFactorForItem > 0f) { rect = new Rect(0f, curY, width, 22f); Widgets.Label(rect, "LWM.ContentsHeaderMaxSize".Translate( cds.stat.ToString().ToLower(), cds.limitingFactorForItem.ToString("0.##") )); curY += 22f; } /* Pawn reservations. I hope this cuts down on questions in the Steam thread */ List <Pawn> pwns = building.Map.mapPawns.SpawnedPawnsInFaction(Faction.OfPlayer); if (pwns.Count > 0) { listOfReservingPawns.Clear(); List <IntVec3> buildingCells = building.AllSlotCellsList(); for (int i = 0; i < buildingCells.Count; i++) { Pawn p = building.Map.reservationManager.FirstRespectedReserver(buildingCells[i], pwns[0]); if (p != null) { listOfReservingPawns.Add(p.ToString()); } } if (listOfReservingPawns.Count > 0) { rect = new Rect(0f, curY, width, 22f); if (listOfReservingPawns.Count == 1) { Widgets.Label(rect, "LWM.ContentsHeaderPawnUsing".Translate(listOfReservingPawns[0])); } else { Widgets.Label(rect, "LWM.ContentsHeaderPawnsUsing".Translate( String.Join(", ", listOfReservingPawns.ToArray()))); } curY += 22f; } } // end checking pawn reservations } // end Header for ITab