private bool CheckForExcessItems(Pawn pawn)
        {
            //if (pawn.CurJob != null && pawn.CurJob.def == JobDefOf.Tame) return false;
            CompInventory inventory = pawn.TryGetComp <CompInventory>();
            Loadout       loadout   = pawn.GetLoadout();

            if (inventory == null || inventory.container == null || loadout == null || loadout.Slots.NullOrEmpty())
            {
                return(false);
            }
            if (inventory.container.Count > loadout.SlotCount + 1)
            {
                return(true);
            }
            // Check to see if there is at least one loadout slot specifying currently equipped weapon
            ThingWithComps equipment = ((pawn.equipment == null) ? null : pawn.equipment.Primary) ?? null;

            if (equipment != null && !loadout.Slots.Any(slot => slot.Def == equipment.def && slot.Count >= 1))
            {
                return(true);
            }

            // Go through each item in the inventory and see if its part of our loadout
            bool allowDropRaw = Find.TickManager.TicksGame > pawn.mindState.lastInventoryRawFoodUseTick + ticksBeforeDropRaw;

            foreach (Thing thing in inventory.container)
            {
                if (allowDropRaw || !thing.def.IsNutritionGivingIngestible || thing.def.ingestible.preferability > FoodPreferability.RawBad)
                {
                    LoadoutSlot slot = loadout.Slots.FirstOrDefault(x => x.Def == thing.def);
                    if (slot == null)
                    {
                        return(true);
                    }
                    else
                    {
                        int numContained = inventory.container.NumContained(thing.def);

                        // Add currently equipped gun
                        if (pawn.equipment != null && pawn.equipment.Primary != null)
                        {
                            if (pawn.equipment.Primary.def == slot.Def)
                            {
                                numContained++;
                            }
                        }
                        if (slot.Count < numContained)
                        {
                            return(true);
                        }
                    }
                }
            }
            return(false);
        }
Example #2
0
        public void AddSlot(LoadoutSlot slot)
        {
            LoadoutSlot found = _slots.FirstOrDefault(s => s.Def == slot.Def);

            if (found != null)
            {
                found.Count++;
            }
            else
            {
                _slots.Add(slot);
            }
        }
        private void DrawCountField(Rect canvas, LoadoutSlot slot)
        {
            if (slot == null)
            {
                return;
            }
            string count = GUI.TextField(canvas, slot.Count.ToString());

            TooltipHandler.TipRegion(canvas, "CR.CountFieldTip".Translate(slot.Count));
            int countInt;

            if (int.TryParse(count, out countInt))
            {
                slot.Count = countInt;
            }
        }
        private void DrawSlotSelection(Rect canvas)
        {
            GUI.DrawTexture(canvas, _darkBackground);

            if (_source.NullOrEmpty())
            {
                return;
            }

            Rect viewRect = new Rect(canvas);

            viewRect.width -= 16f;
            viewRect.height = _source.Count * _rowHeight;

            Widgets.BeginScrollView(canvas, ref _availableScrollPosition, viewRect.AtZero());
            for (int i = 0; i < _source.Count; i++)
            {
                Rect row       = new Rect(0f, i * _rowHeight, canvas.width, _rowHeight);
                Rect labelRect = new Rect(row);
                TooltipHandler.TipRegion(row, _source[i].GetWeightAndBulkTip());

                labelRect.xMin += _margin;
                if (i % 2 == 0)
                {
                    GUI.DrawTexture(row, _darkBackground);
                }

                Text.Anchor = TextAnchor.MiddleLeft;
                Widgets.Label(labelRect, _source[i].LabelCap);
                Text.Anchor = TextAnchor.UpperLeft;

                Widgets.DrawHighlightIfMouseover(row);
                if (Widgets.ButtonInvisible(row))
                {
                    var slot = new LoadoutSlot(_source[i], 1);
                    CurrentLoadout.AddSlot(slot);
                }
            }
            Widgets.EndScrollView();
        }
Example #5
0
        private int MoveTo(int fromIndex, int toIndex)
        {
            if (fromIndex < 0 || fromIndex >= _slots.Count || toIndex < 0 || toIndex >= _slots.Count)
            {
                throw new Exception("Attempted to move i " + fromIndex + " to " + toIndex + ", bounds are [0," + (_slots.Count - 1) + "].");
            }

            // fetch the filter we're moving
            LoadoutSlot temp = _slots[fromIndex];

            // remove from old location
            _slots.RemoveAt(fromIndex);

            // this may have changed the toIndex
            if (fromIndex + 1 < toIndex)
            {
                toIndex--;
            }

            // insert at new location
            _slots.Insert(toIndex, temp);
            return(toIndex);
        }
        private void DrawSlot(Rect row, LoadoutSlot slot, bool slotDraggable = true)
        {
            // set up rects
            // dragging handle (square) | label (fill) | count (50px) | delete (iconSize)
            Rect draggingHandle = new Rect(row);

            draggingHandle.width = row.height;

            Rect labelRect = new Rect(row);

            if (slotDraggable)
            {
                labelRect.xMin = draggingHandle.xMax;
            }
            labelRect.xMax = row.xMax - _countFieldSize.x - _iconSize - 2 * _margin;

            Rect countRect = new Rect(
                row.xMax - _countFieldSize.x - _iconSize - 2 * _margin,
                row.yMin + (row.height - _countFieldSize.y) / 2f,
                _countFieldSize.x,
                _countFieldSize.y);

            Rect ammoRect = new Rect(
                countRect.xMin - _iconSize - _margin,
                row.yMin + (row.height - _iconSize) / 2f,
                _iconSize, _iconSize);

            Rect deleteRect = new Rect(countRect.xMax + _margin, row.yMin + (row.height - _iconSize) / 2f, _iconSize, _iconSize);

            // dragging on dragHandle
            if (slotDraggable)
            {
                TooltipHandler.TipRegion(draggingHandle, "CR.DragToReorder".Translate());
                GUI.DrawTexture(draggingHandle, _iconMove);

                if (Mouse.IsOver(draggingHandle) && Input.GetMouseButtonDown(0))
                {
                    Dragging = slot;
                }
            }

            // interactions (main row rect)
            if (!Mouse.IsOver(deleteRect))
            {
                Widgets.DrawHighlightIfMouseover(row);
                TooltipHandler.TipRegion(row, slot.Def.GetWeightAndBulkTip(slot.Count));
            }

            // label
            Text.Anchor = TextAnchor.MiddleLeft;
            Widgets.Label(labelRect, slot.Def.LabelCap);
            Text.Anchor = TextAnchor.UpperLeft;

            // easy ammo adder, ranged weapons only
            if (slot.Def.IsRangedWeapon)
            {
                // make sure there's an ammoset defined
                AmmoSetDef ammoSet = ((slot.Def.GetCompProperties <CompProperties_AmmoUser>() == null) ? null : slot.Def.GetCompProperties <CompProperties_AmmoUser>().ammoSet);

                bool?temp = !((((ammoSet == null) ? null : ammoSet.ammoTypes)).NullOrEmpty());

                if (temp ?? false)
                {
                    if (Widgets.ButtonImage(ammoRect, _iconAmmoAdd))
                    {
                        List <FloatMenuOption> options = new List <FloatMenuOption>();

                        foreach (var ammo in ((ammoSet == null) ? null : ammoSet.ammoTypes))
                        {
                            options.Add(new FloatMenuOption(ammo.LabelCap, delegate
                            {
                                CurrentLoadout.AddSlot(new LoadoutSlot(ammo));
                            }));
                        }

                        Find.WindowStack.Add(new FloatMenu(options, "CR.AddAmmoFor".Translate(slot.Def.LabelCap)));
                    }
                }
            }

            // count
            DrawCountField(countRect, slot);

            // delete
            if (Mouse.IsOver(deleteRect))
            {
                GUI.DrawTexture(row, TexUI.HighlightTex);
            }
            if (Widgets.ButtonImage(deleteRect, _iconClear))
            {
                CurrentLoadout.RemoveSlot(slot);
            }
            TooltipHandler.TipRegion(deleteRect, "CR.DeleteFilter".Translate());
        }
Example #7
0
 public void AddSlot(LoadoutSlot slot)
 {
     _slots.Add(slot);
 }
Example #8
0
 public void RemoveSlot(LoadoutSlot slot)
 {
     _slots.Remove(slot);
 }
Example #9
0
        public void MoveSlot(LoadoutSlot slot, int toIndex)
        {
            int fromIndex = _slots.IndexOf(slot);

            MoveTo(fromIndex, toIndex);
        }
Example #10
0
        private LoadoutSlot GetPrioritySlot(Pawn pawn, out ItemPriority priority, out Thing closestThing, out int count)
        {
            priority = ItemPriority.None;
            LoadoutSlot slot = null;

            closestThing = null;
            count        = 0;

            CompInventory inventory = pawn.TryGetComp <CompInventory>();

            if (inventory != null && inventory.container != null)
            {
                Loadout loadout = pawn.GetLoadout();
                if (loadout != null && !loadout.Slots.NullOrEmpty())
                {
                    foreach (LoadoutSlot curSlot in loadout.Slots)
                    {
                        ItemPriority curPriority = ItemPriority.None;
                        Thing        curThing    = null;
                        int          numCarried  = inventory.container.TotalStackCountOfDef(curSlot.Def);

                        // Add currently equipped gun
                        if (pawn.equipment != null && pawn.equipment.Primary != null)
                        {
                            if (pawn.equipment.Primary.def == curSlot.Def)
                            {
                                numCarried++;
                            }
                        }
                        if (numCarried < curSlot.Count)
                        {
                            curThing = GenClosest.ClosestThingReachable(
                                pawn.Position,
                                pawn.Map,
                                ThingRequest.ForDef(curSlot.Def),
                                PathEndMode.ClosestTouch,
                                TraverseParms.For(pawn, Danger.None, TraverseMode.ByPawn),
                                proximitySearchRadius,
                                x => !x.IsForbidden(pawn) && pawn.CanReserve(x));
                            if (curThing != null)
                            {
                                curPriority = ItemPriority.Proximity;
                            }
                            else
                            {
                                curThing = GenClosest.ClosestThingReachable(
                                    pawn.Position,
                                    pawn.Map,
                                    ThingRequest.ForDef(curSlot.Def),
                                    PathEndMode.ClosestTouch,
                                    TraverseParms.For(pawn, Danger.None, TraverseMode.ByPawn),
                                    maximumSearchRadius,
                                    x => !x.IsForbidden(pawn) && pawn.CanReserve(x));
                                if (curThing != null)
                                {
                                    if (!curSlot.Def.IsNutritionGivingIngestible && numCarried / curSlot.Count <= 0.5f)
                                    {
                                        curPriority = ItemPriority.LowStock;
                                    }
                                    else
                                    {
                                        curPriority = ItemPriority.Low;
                                    }
                                }
                            }
                        }
                        if (curPriority > priority && curThing != null && inventory.CanFitInInventory(curThing, out count))
                        {
                            priority     = curPriority;
                            slot         = curSlot;
                            closestThing = curThing;
                        }
                        if (priority >= ItemPriority.LowStock)
                        {
                            break;
                        }
                    }
                }
            }

            return(slot);
        }
Example #11
0
        protected override Job TryGiveJob(Pawn pawn)
        {
            // Get inventory
            CompInventory inventory = pawn.TryGetComp <CompInventory>();

            if (inventory == null)
            {
                return(null);
            }

            Loadout loadout = pawn.GetLoadout();

            if (loadout != null)
            {
                // Find and drop excess items
                foreach (LoadoutSlot slot in loadout.Slots)
                {
                    int numContained = inventory.container.TotalStackCountOfDef(slot.Def);

                    // Add currently equipped gun
                    if (pawn.equipment != null && pawn.equipment.Primary != null)
                    {
                        if (pawn.equipment.Primary.def == slot.Def)
                        {
                            numContained++;
                        }
                    }
                    // Drop excess items
                    if (numContained > slot.Count)
                    {
                        Thing thing = inventory.container.FirstOrDefault(x => x.def == slot.Def);
                        if (thing != null)
                        {
                            Thing droppedThing;
                            if (inventory.container.TryDrop(thing, pawn.Position, pawn.Map, ThingPlaceMode.Near, numContained - slot.Count, out droppedThing))
                            {
                                if (droppedThing != null)
                                {
                                    return(HaulAIUtility.HaulToStorageJob(pawn, droppedThing));
                                }
                                Log.Error(pawn + " tried dropping " + thing + " from loadout but resulting thing is null");
                            }
                        }
                    }
                }

                // Try drop currently equipped weapon
                if (pawn.equipment != null && pawn.equipment.Primary != null && !loadout.Slots.Any(slot => slot.Def == pawn.equipment.Primary.def && slot.Count >= 1))
                {
                    ThingWithComps droppedEq;
                    if (pawn.equipment.TryDropEquipment(pawn.equipment.Primary, out droppedEq, pawn.Position, false))
                    {
                        return(HaulAIUtility.HaulToStorageJob(pawn, droppedEq));
                    }
                }

                // Find excess items in inventory that are not part of our loadout
                bool  allowDropRaw  = Find.TickManager.TicksGame > pawn.mindState?.lastInventoryRawFoodUseTick + ticksBeforeDropRaw;
                Thing thingToRemove = inventory.container.FirstOrDefault(t =>
                                                                         (allowDropRaw || !t.def.IsNutritionGivingIngestible || t.def.ingestible.preferability > FoodPreferability.RawTasty) &&
                                                                         !loadout.Slots.Any(s => s.Def == t.def));
                if (thingToRemove != null)
                {
                    Thing droppedThing;
                    if (inventory.container.TryDrop(thingToRemove, pawn.Position, pawn.Map, ThingPlaceMode.Near, thingToRemove.stackCount, out droppedThing))
                    {
                        return(HaulAIUtility.HaulToStorageJob(pawn, droppedThing));
                    }
                    Log.Error(pawn + " tried dropping " + thingToRemove + " from inventory but resulting thing is null");
                }

                // Find missing items
                ItemPriority priority;
                Thing        closestThing;
                int          count;
                LoadoutSlot  prioritySlot = GetPrioritySlot(pawn, out priority, out closestThing, out count);
                if (closestThing != null)
                {
                    // Equip gun if unarmed or current gun is not in loadout
                    if (closestThing.TryGetComp <CompEquippable>() != null &&
                        (pawn.health != null && pawn.health.capacities.CapableOf(PawnCapacityDefOf.Manipulation)) &&
                        (pawn.equipment == null || pawn.equipment.Primary == null || !loadout.Slots.Any(s => s.Def == pawn.equipment.Primary.def)))
                    {
                        return(new Job(JobDefOf.Equip, closestThing));
                    }
                    // Take items into inventory if needed
                    int numContained = inventory.container.TotalStackCountOfDef(prioritySlot.Def);
                    return(new Job(JobDefOf.TakeInventory, closestThing)
                    {
                        count = Mathf.Min(closestThing.stackCount, prioritySlot.Count - numContained, count)
                    });
                }
            }
            return(null);
        }