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); }
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(); }
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()); }
public void AddSlot(LoadoutSlot slot) { _slots.Add(slot); }
public void RemoveSlot(LoadoutSlot slot) { _slots.Remove(slot); }
public void MoveSlot(LoadoutSlot slot, int toIndex) { int fromIndex = _slots.IndexOf(slot); MoveTo(fromIndex, toIndex); }
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); }
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); }