예제 #1
0
        public static bool GetDeepStorageOnCell(IntVec3 cell, Map map, out CompDeepStorage compDeepStorage) {
            if (HasDeepStorageComp(map?.haulDestinationManager?.SlotGroupAt(cell), out compDeepStorage))
            {
                return true;
            }

            compDeepStorage = null;
            return false;
        }
예제 #2
0
        public static HashSet<Thing> TopThingInDeepStorage = new HashSet<Thing>(); // for display

        public static bool HasDeepStorageComp(SlotGroup slotGroup, out CompDeepStorage compDeepStorage) {
            if (slotGroup?.parent is ThingWithComps thingWithComps
                && (compDeepStorage = thingWithComps.TryGetComp<CompDeepStorage>()) != null)
            {
                return true;
            }

            compDeepStorage = null;
            return false;
        }
예제 #3
0
        } // end Transpiler

        // TODO: move this logic to DeepStorage.cs
        public static Thing NullOrLastThingAt(Map map, IntVec3 c, ThingDef def)
        {
            CompDeepStorage cds       = (c.GetSlotGroup(map).parent as ThingWithComps).GetComp <CompDeepStorage>();
            var             l         = map.thingGrid.ThingsListAtFast(c); // we know it's a slotgroup, so it's valid :p
            var             freeSlots = cds.maxNumberStacks;

            Utils.Err(HaulToCellStorageJob, "  testing for def " + def + " at " + c + "; " + freeSlots + " slots.");
            Thing lastThing = null;

            for (int i = 0; i < l.Count; i++)
            {
                if (!l[i].def.EverStorable(false))
                {
                    continue;
                }
                freeSlots--;
                Utils.Mess(HaulToCellStorageJob, "  Checking item " + l[i] + "; now have " + freeSlots + " left.");
                if (!(l[i].def == def))
                {
                    continue;                     // possible problem if defs are same but cannot stack?
                }
                if (lastThing == null)
                {
                    lastThing = l[i];
                }
                else
                {
                    if (l[i].stackCount <= lastThing.stackCount)
                    {
                        lastThing = l[i];
                    }
                }
            }
            if (freeSlots > 0)
            {
                Utils.Err(HaulToCellStorageJob, "  Final count of free slots: " + freeSlots);
                return(null);
            }
            Utils.Warn(HaulToCellStorageJob, "  Final item count: " + ((lastThing == null)?
                                                                       "NULL":lastThing.stackCount.ToString()));
            return(lastThing); // if this is also null, we have a problem :p
        }
        // 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;
        }
예제 #5
0
        protected static bool Prefix(IntVec3 c, Map map, Thing thing, ref bool __result)
        {
            Utils.Err(NoStorageBlockerseIn, "Looking for blockers for " + thing + " at " + c);
            // Check if storage location is in an uber-storage building:
            SlotGroup       slotGroup = c.GetSlotGroup(map);
            CompDeepStorage cds       = null;

            if (slotGroup == null || !(slotGroup?.parent is ThingWithComps) ||
                (cds = (slotGroup.parent as ThingWithComps).TryGetComp <CompDeepStorage>()) == null)
            {
                //                Log.Warning("  ...letting vanilla handle it.");
                return(true); // normal spot, NoStorageBlockersIn() will handle it
            }
            //TODO: Make this IHoldMultipleThings
//            __result = false; // NoStorageBlockersIn returns false if there's a blocker
            // Default to having a blocker unless EVERYTHING is okay
            //  (We return false from this Patch function to skip original method)
            __result = cds.StackableAt(thing, c, map);
            Utils.Warn(NoStorageBlockerseIn, "Final result for " + thing + " at " + c + ": " + __result);
            return(false);

#if false
            // If there is a maximum size of items that will fit in the unit, quit:
            if (cds.limitingFactorForItem > 0f)
            {
                if (thing.GetStatValue(cds.stat) > cds.limitingFactorForItem)
                {
                    Utils.Warn(NoStorageBlockerseIn, "Thing has " + cds.stat + " of " +
                               thing.GetStatValue(StatDefOf.Mass) + " but max allowed is " +
                               cds.limitingFactorForItem);
                    return(false);
                }
            }
            // We will usually care how many stacks can fit here:
            var maxStacks = cds.maxNumberStacks;
            // If maxTotalMass is set, we will keep track of how much "room" we have as well:
            float totalAmountHereSoFar = 0f;
            if (cds.limitingTotalFactorForCell > 0f)
            {
                totalAmountHereSoFar = thing.GetStatValue(cds.stat);
            }

            var          objInStack = 0;
            List <Thing> list       = map.thingGrid.ThingsListAt(c);
            for (int i = 0; i < list.Count; i++)   //loop thru cell's contents
            {
                Thing thing2 = list[i];
                Utils.Warn(NoStorageBlockerseIn, "  ...checking: does " + thing2 + " block?");
                if (thing2.def.EverStorable(false))   // an "item" as it were
                {
                    if (cds.limitingTotalFactorForCell > 0f)
                    {
                        totalAmountHereSoFar += (thing2.GetStatValue(cds.stat) * thing2.stackCount);
                        Utils.Warn(NoStorageBlockerseIn, "  added 'mass' " + thing2.GetStatValue(cds.stat) +
                                   " to running total " + totalAmountHereSoFar + " / " + cds.limitingTotalFactorForCell
                                   + "(" + (objInStack + 1) + " v " + cds.minNumberStacks + ")");
                        if (totalAmountHereSoFar > cds.limitingTotalFactorForCell &&
                            objInStack + 1 >= cds.minNumberStacks)   // Must accept minimum (haven't incremented objInStack yet)
                                                                     // but if reached minimum and over capacity, cannot store here
                        {
                            Utils.Warn(NoStorageBlockerseIn, "  BLOCKS: Over mass limit ("
                                       + cds.limitingTotalFactorForCell + ")");
                            return(false);
                        }
                    }
                    if (!thing2.CanStackWith(thing))
                    {
                        objInStack++;
                    }
                    else if (thing2.stackCount >= thing.def.stackLimit)
                    {
                        objInStack++;
                    }
                    else // it can stack and there's room in the stack for more...
                    {    // go ahead and get out of here with the good news!
                        __result = true;
                        Utils.Warn(NoStorageBlockerseIn, thing.ToString() + " at " + c.ToString() + ": " + __result);
                        return(false);
                    }
                    if (objInStack >= maxStacks)
                    {
                        return(false);
                    }
                    continue;
                }
                if (thing2.def.entityDefToBuild != null && thing2.def.entityDefToBuild.passability != Traversability.Standable)
                {
                    Utils.Warn(NoStorageBlockerseIn, thing.ToString() + " at " + c.ToString() + ": " + __result);
                    return(false);
                }
                if (thing2.def.surfaceType == SurfaceType.None && thing2.def.passability != Traversability.Standable)
                {
                    Utils.Warn(NoStorageBlockerseIn, thing.ToString() + " at " + c.ToString() + ": " + __result);
                    return(false);
                }
            }
            //You know what I can't get running in Linux?  Monodevelop's debugger.
            //Log.Warning("No storage blockers for "+thing.ToString()+" in "+slotGroup.ToString());
            __result = true; // no blockers after all!
            Utils.Warn(NoStorageBlockerseIn, thing.ToString() + " at " + c.ToString() + ": " + __result);
            return(false);
#endif
        }
예제 #6
0
        static bool OverCapacity(Map map, Thing thing, ref StoragePriority storagePriority)
        {
            if (!thing.Spawned)
            {
                return(false);
            }
            if (storagePriority == StoragePriority.Unstored)
            {
                return(false);
            }
            CompDeepStorage cds = (thing.Position.GetSlotGroup(map)?.parent as ThingWithComps)?.GetComp <CompDeepStorage>();
            List <Thing>    l;

            // What if it's a slotGroup put down after someone moved/destroyed a DSU?
            //   Because we CAN still end up with more than one thing on the ground.
            if (cds == null)
            {
                l = map.thingGrid.ThingsListAt(thing.Position);
                for (int i = 0; i < l.Count; i++)
                {
                    if (l[i].def.EverStorable(false))
                    {
                        if (thing == l[i])
                        {
                            return(false);
                        }
                        Utils.Warn(ShouldRemoveFromStorage,
                                   "LWM.DeepStorage: " + thing.stackCount + thing +
                                   " is not in a DSU and there is already a thing at " + thing.Position);
                        storagePriority = StoragePriority.Unstored;
                        return(true);
                    }
                }
            }

            if (cds.limitingFactorForItem > 0f)
            {
                if (thing.GetStatValue(cds.stat) > cds.limitingFactorForItem)
                {
                    Utils.Warn(ShouldRemoveFromStorage,
                               "LWM.DeepStorage: " + thing.stackCount + thing + " is too heavy for DSU at " + thing.Position);
                    storagePriority = StoragePriority.Unstored;
                    return(true);
                }
            }
            float totalWeightStoredHere = 0f;  //mass, or bulk, etc.
            var   stacksStoredHere      = 0;

            l = map.thingGrid.ThingsListAt(thing.Position);
            for (int i = 0; i < l.Count; i++)
            {
                Thing thingInStorage = l[i];
                // TODO: Decide how to handle weight: if thing is stackable, do I want to take some out, if it goes over?
                if (thing == thingInStorage)
                {
                    return(false);                          // it's here, and not over capacity yet!
                }
                if (thingInStorage.def.EverStorable(false)) // an "item" we care about
                {
                    stacksStoredHere++;
                    if (cds.limitingTotalFactorForCell > 0f)
                    {
                        totalWeightStoredHere += thingInStorage.GetStatValue(cds.stat) * thingInStorage.stackCount;
                        if (totalWeightStoredHere > cds.limitingTotalFactorForCell &&
                            stacksStoredHere >= cds.minNumberStacks)
                        {
                            Utils.Warn(ShouldRemoveFromStorage,
                                       "LWM.DeepStorage: " + thing.stackCount + thing + " is over weight capacity at " + thing.Position);
                            storagePriority = StoragePriority.Unstored;
                            return(true);  // this takes us to capacity, and we haven't hit thing
                        }
                    }
                    if (stacksStoredHere >= cds.maxNumberStacks)   // breaks if minNumberStacks > maxNumberStacks. I'm okay with this
                    {
                        Utils.Warn(ShouldRemoveFromStorage,
                                   "LWM.DeepStorage: " + thing.stackCount + thing + " is over capacity at " + thing.Position);
                        storagePriority = StoragePriority.Unstored;
                        return(true);  // this takes us to capacity, and we haven't hit thing
                    }
                } // if storable
            } // end list
            return(false);
        }
예제 #7
0
 public Dialog_RenameDSU(CompDeepStorage cds)
 {
     this.cds = cds;
     curName  = cds.parent.Label;
 }
예제 #8
0
        static bool OverCapacity(Map map, Thing thing, ref StoragePriority storagePriority)
        {
            Utils.Warn(ShouldRemoveFromStorage, "LWM.DeepStorage: Over Capacity Called."
                       + (map == null ? "  Map is NULL (this is bad)." : ("  Map: " + map))
                       + (thing == null? "  Thing is NULL (this is bad).":("  Thing: " + thing.stackCount + thing)));
            if (!thing.Spawned)
            {
                return(false);
            }
            if (storagePriority == StoragePriority.Unstored)
            {
                return(false);
            }
            CompDeepStorage cds = (thing.Position.GetSlotGroup(map)?.parent as ThingWithComps)?.GetComp <CompDeepStorage>();
            List <Thing>    l;

            // What if it's a slotGroup put down after someone moved/destroyed a DSU?
            //   Because we CAN still end up with more than one thing on the ground.
            //   (Also, TODO: Other mods can possibly cause this.  ...Hmmm...)
            if (cds == null)
            {
                l = map.thingGrid.ThingsListAt(thing.Position);
                for (int i = 0; i < l.Count; i++)
                {
                    Utils.Mess(ShouldRemoveFromStorage, "LWM.DeepStorage: Not in DSU: looking at item "
                               + ((l[i] != null)?l[i].ToString():"NULL ITEM"));
                    if (l[i].def.EverStorable(false))
                    {
                        if (thing == l[i]) // first thing is okay.
                        {
                            return(false);
                        }
                        Utils.Warn(ShouldRemoveFromStorage,
                                   "LWM.DeepStorage: " + thing.stackCount + thing +
                                   " is not in a DSU and there is already a thing at " + thing.Position);
                        storagePriority = StoragePriority.Unstored;
                        return(true); // anything else is over capactiy!
                    }
                }
                return(false); // Should be difficult to get here?  But apparently RoM - Arachnophobia does.
            }
            // TODO: This should really all be in CompDeepStorage:

            if (cds.limitingFactorForItem > 0f)
            {
                if (thing.GetStatValue(cds.stat) > cds.limitingFactorForItem)
                {
                    Utils.Warn(ShouldRemoveFromStorage,
                               "LWM.DeepStorage: " + thing.stackCount + thing + " is too heavy for DSU at " + thing.Position);
                    storagePriority = StoragePriority.Unstored;
                    return(true);
                }
            }
            float totalWeightStoredHere = 0f;  //mass, or bulk, etc.
            var   stacksStoredHere      = 0;

            Utils.Mess(ShouldRemoveFromStorage, "  Checking ThingListAt now...");
            l = map.thingGrid.ThingsListAt(thing.Position);
            for (int i = 0; i < l.Count; i++)
            {
                Thing thingInStorage = l[i];
                // TODO: Decide how to handle weight: if thing is stackable, do I want to take some out, if it goes over?
                if (thing == thingInStorage)
                {
                    return(false);                          // it's here, and not over capacity yet!
                }
                if (thingInStorage.def.EverStorable(false)) // an "item" we care about
                {
                    Utils.Mess(ShouldRemoveFromStorage, "    Checking Item " + thingInStorage.stackCount + thingInStorage);
                    stacksStoredHere++;
                    if (cds.limitingTotalFactorForCell > 0f)
                    {
                        totalWeightStoredHere += thingInStorage.GetStatValue(cds.stat) * thingInStorage.stackCount;
                        Utils.Mess(ShouldRemoveFromStorage, "      total mass so far: " + totalWeightStoredHere + " / " +
                                   cds.limitingTotalFactorForCell);
                        if (totalWeightStoredHere > cds.limitingTotalFactorForCell &&
                            stacksStoredHere >= cds.minNumberStacks)
                        {
                            Utils.Warn(ShouldRemoveFromStorage,
                                       "LWM.DeepStorage: " + thing.stackCount + thing + " is over weight capacity at " + thing.Position);
                            storagePriority = StoragePriority.Unstored;
                            return(true);  // this takes us to capacity, and we haven't hit thing
                        }
                    }
                    if (stacksStoredHere >= cds.maxNumberStacks)   // breaks if minNumberStacks > maxNumberStacks. I'm okay with this
                    {
                        Utils.Warn(ShouldRemoveFromStorage,
                                   "LWM.DeepStorage: " + thing.stackCount + thing + " is over capacity at " + thing.Position);
                        storagePriority = StoragePriority.Unstored;
                        return(true);  // this takes us to capacity, and we haven't hit thing
                    }
                } // if storable
            } // end list
            return(false);
        }
예제 #9
0
        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);
        }
        public static void Postfix(Selector __instance)
        {
            if (__instance.NumSelected != 1)
            {
                return;
            }
            Thing t = __instance.SingleSelectedThing;

            if (t == null)
            {
                return;
            }
            if (!(t is ThingWithComps))
            {
                return;
            }
            CompDeepStorage cds = t.TryGetComp <CompDeepStorage>();

            if (cds == null)
            {
                return;
            }
            // Off to a good start; it's a DSU
            // Check to see if a tab is already open.
            var  pane = (MainTabWindow_Inspect)MainButtonDefOf.Inspect.TabWindow;
            Type alreadyOpenTabType = pane.OpenTabType;

            if (alreadyOpenTabType != null)
            {
                var listOfTabs = t.GetInspectTabs();
                foreach (var x in listOfTabs)
                {
                    if (x.GetType() == alreadyOpenTabType) // Misses any subclassing?
                    {
                        return;                            // standard Selector behavior should kick in.
                    }
                }
            }
            // If not, open ours!
            // TODO: ...make this happen for shelves, heck, any storage buildings?
            ITab tab = null;

            /* If there are no items stored, default intead to settings (preferably with note about being empty?) */
            // If we find a stored item, open Contents tab:
            // TODO: Make storage settings tab show label if it's empty
            if (t.Spawned && t is IStoreSettingsParent && t is ISlotGroupParent)
            {
                foreach (IntVec3 c in ((ISlotGroupParent)t).GetSlotGroup().CellsList)
                {
                    List <Thing> l = t.Map.thingGrid.ThingsListAt(c);
                    foreach (Thing tmp in l)
                    {
                        if (tmp.def.EverStorable(false))
                        {
                            goto EndLoop;
                            // Seriously?  C# doesn't have "break 2;"?
                        }
                    }
                }
                tab = t.GetInspectTabs().OfType <ITab_Storage>().First();
            }
EndLoop:
            if (tab == null)
            {
                tab = t.GetInspectTabs().OfType <ITab_DeepStorage_Inventory>().First();
            }
            if (tab == null)
            {
                Log.Error("LWM Deep Storage object " + t + " does not have an inventory tab?");  return;
            }
            tab.OnOpen();
            if (tab is ITab_DeepStorage_Inventory)
            {
                pane.OpenTabType = typeof(ITab_DeepStorage_Inventory);
            }
            else
            {
                pane.OpenTabType = typeof(ITab_Storage);
            }
        }
        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;
        }
예제 #12
0
        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);
        }
예제 #13
0
        protected override void FillTab()
        {
            var          storageBuilding = 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:
            var frame = new Rect(10f, 10f, size.x - 10, size.y - 10);

            GUI.BeginGroup(frame);
            Text.Font = GameFont.Small;
            GUI.color = Color.white;

            /*******  Title *******/
            var curY = 0f;

            Widgets.ListSeparator(ref curY, frame.width, labelKey.Translate()
#if DEBUG
                                  + "    (" + storageBuilding.ToString() + ")"                        // extra info for debugging
#endif
                                  );
            curY += 5f;
            /****************** Header: Show count of contents, mass, etc: ****************/
            //TODO: handle each cell separately?
            string header, headerTooltip;
            var    cds = storageBuilding.GetComp <CompDeepStorage>();
            if (cds != null)
            {
                storedItems = cds.getContentsHeader(out header, out headerTooltip);
            }
            else
            {
                storedItems = CompDeepStorage.genericContentsHeader(storageBuilding, out header, out headerTooltip);
            }
            var 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(x => x.def.defName).ThenByDescending(x =>
            {
                QualityCategory c;
                x.TryGetQuality(out c);
                return((int)c);
            }).ThenByDescending(x => x.HitPoints / x.MaxHitPoints).ToList();
            // outRect is the is the rectangle that is visible on the screen:
            var outRect = new Rect(0f, 10f + curY, frame.width, frame.height - curY);
            // viewRect is inside the ScrollView, so it starts at y=0f
            var viewRect = new Rect(0f, 0f, frame.width - 16f, 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 scrollPosition, viewRect);

            curY = 0f; // now inside ScrollView
            if (storedItems.Count < 1)
            {
                Widgets.Label(viewRect, "NoItemsAreStoredHere".Translate());
                curY += 22;
            }

            for (var i = 0; i < storedItems.Count; i++)
            {
                DrawThingRow(ref curY, viewRect.width, storedItems[i]);
            }

            if (Event.current.type == EventType.Layout)
            {
                scrollViewHeight = curY + 25f;                                         //25f buffer   -- ??
            }
            Widgets.EndScrollView();
            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;
        }
        // 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