private void TrySwitchToWeapon(ThingWithComps newEq, Pawn pawn) { if (newEq == null || pawn.equipment == null || !pawn.inventory.innerContainer.Contains(newEq)) { return; } if (newEq.def.stackLimit > 1 && newEq.stackCount > 1) { newEq = (ThingWithComps)newEq.SplitOff(1); } if (pawn.equipment.Primary != null) { if (MassUtility.FreeSpace(pawn) > 0) { pawn.equipment.TryTransferEquipmentToContainer(pawn.equipment.Primary, pawn.inventory.innerContainer); } else { pawn.equipment.MakeRoomFor(newEq); } } pawn.equipment.GetDirectlyHeldThings().TryAddOrTransfer(newEq); if (newEq.def.soundInteract != null) { newEq.def.soundInteract.PlayOneShot(new TargetInfo(pawn.Position, pawn.MapHeld, false)); } }
/// <summary> /// Get vehicle with the most free space that is able to hold cargo /// </summary> /// <param name="pawn"></param> public static Pawn UsableVehicleWithTheMostFreeSpace(Pawn pawn) { Pawn carrierPawn = null; float num = 0f; foreach (Pawn p in UsableCandidatesForCargo(pawn)) { if (p is VehiclePawn && p != pawn && pawn.CanReach(p, PathEndMode.Touch, Danger.Deadly, false)) { float num2 = MassUtility.FreeSpace(p); if (carrierPawn is null || num2 > num) { carrierPawn = p; num = num2; } } } return(carrierPawn); }
public static float FreeSpaceIfCarried(this Pawn carrier, Thing thing) { return(Mathf.Max(0f, MassUtility.FreeSpace(carrier) - thing.Mass())); }
internal static bool canCarrySidearm(ThingDef sidearm, Pawn pawn, out string errString) { float maxCapacity = MassUtility.Capacity(pawn); float freeCapacity = MassUtility.FreeSpace(pawn); float sidearmWeight = sidearm.GetStatValueAbstract(StatDefOf.Mass); //ThingStuffPair sidearmAsThingStuffPair = new ThingStuffPair(sidearm.def, sidearm.Stuff); if (sidearmWeight >= freeCapacity) { errString = "SidearmPickupFail_NoFreeSpace".Translate(); return(false); } if (!SimpleSidearms.SeparateModes) { switch (SimpleSidearms.LimitModeSingle.Value) { case LimitModeSingleSidearm.None: break; case LimitModeSingleSidearm.AbsoluteWeight: if (sidearmWeight >= SimpleSidearms.LimitModeSingle_Absolute.Value) { errString = "SidearmPickupFail_TooHeavyForSidearm".Translate(); return(false); } break; case LimitModeSingleSidearm.RelativeWeight: if (sidearmWeight >= SimpleSidearms.LimitModeSingle_Relative.Value * maxCapacity) { errString = "SidearmPickupFail_TooHeavyForSidearm".Translate(); return(false); } break; case LimitModeSingleSidearm.Selection: if (!SimpleSidearms.LimitModeSingle_Selection.Value.InnerList.Contains <string>(sidearm.defName)) { errString = "SidearmPickupFail_NotASidearm".Translate(); return(false); } break; } switch (SimpleSidearms.LimitModeAmount.Value) { case LimitModeAmountOfSidearms.MaximumCarryWeightOnly: break; case LimitModeAmountOfSidearms.AbsoluteWeight: if (sidearmWeight >= (SimpleSidearms.LimitModeAmount_Absolute.Value - weightForType(pawn, WeaponSearchType.Both))) { errString = "SidearmPickupFail_SidearmsTooHeavyInTotal".Translate(); return(false); } break; case LimitModeAmountOfSidearms.RelativeWeight: if (sidearmWeight >= ((SimpleSidearms.LimitModeAmount_Relative.Value * maxCapacity) - weightForType(pawn, WeaponSearchType.Both))) { errString = "SidearmPickupFail_SidearmsTooHeavyInTotal".Translate(); return(false); } break; case LimitModeAmountOfSidearms.Slots: if (SimpleSidearms.LimitModeAmount_Slots.Value <= countForType(pawn, WeaponSearchType.Both)) { errString = "SidearmPickupFail_AllSlotsFull".Translate(); return(false); } break; } } else { switch (SimpleSidearms.LimitModeAmountTotal.Value) { case LimitModeAmountOfSidearms.MaximumCarryWeightOnly: break; case LimitModeAmountOfSidearms.AbsoluteWeight: if (sidearmWeight >= (SimpleSidearms.LimitModeAmountTotal_Absolute.Value - weightForType(pawn, WeaponSearchType.Both))) { errString = "SidearmPickupFail_SidearmsTooHeavyInTotal".Translate(); return(false); } break; case LimitModeAmountOfSidearms.RelativeWeight: if (sidearmWeight >= ((SimpleSidearms.LimitModeAmountTotal_Relative.Value * maxCapacity) - weightForType(pawn, WeaponSearchType.Both))) { errString = "SidearmPickupFail_SidearmsTooHeavyInTotal".Translate(); return(false); } break; case LimitModeAmountOfSidearms.Slots: if (SimpleSidearms.LimitModeAmountTotal_Slots.Value <= countForType(pawn, WeaponSearchType.Both)) { errString = "SidearmPickupFail_AllSlotsFull".Translate(); return(false); } break; } if (!sidearm.IsRangedWeapon) { switch (SimpleSidearms.LimitModeSingleMelee.Value) { case LimitModeSingleSidearm.None: break; case LimitModeSingleSidearm.AbsoluteWeight: if (sidearmWeight >= SimpleSidearms.LimitModeSingleMelee_Absolute.Value) { errString = "SidearmPickupFail_TooHeavyForSidearmMelee".Translate(); return(false); } break; case LimitModeSingleSidearm.RelativeWeight: if (sidearmWeight >= SimpleSidearms.LimitModeSingleMelee_Relative.Value * maxCapacity) { errString = "SidearmPickupFail_TooHeavyForSidearmMelee".Translate(); return(false); } break; case LimitModeSingleSidearm.Selection: if (!SimpleSidearms.LimitModeSingleMelee_Selection.Value.InnerList.Contains <string>(sidearm.defName)) { errString = "SidearmPickupFail_NotASidearmMelee".Translate(); return(false); } break; } switch (SimpleSidearms.LimitModeAmountMelee.Value) { case LimitModeAmountOfSidearms.MaximumCarryWeightOnly: break; case LimitModeAmountOfSidearms.AbsoluteWeight: if (sidearmWeight >= (SimpleSidearms.LimitModeAmountMelee_Absolute.Value - weightForType(pawn, WeaponSearchType.Melee))) { errString = "SidearmPickupFail_SidearmsTooHeavyMelee".Translate(); return(false); } break; case LimitModeAmountOfSidearms.RelativeWeight: if (sidearmWeight >= ((SimpleSidearms.LimitModeAmountMelee_Relative.Value * maxCapacity) - weightForType(pawn, WeaponSearchType.Melee))) { errString = "SidearmPickupFail_SidearmsTooHeavyMelee".Translate(); return(false); } break; case LimitModeAmountOfSidearms.Slots: if (SimpleSidearms.LimitModeAmountMelee_Slots.Value <= countForType(pawn, WeaponSearchType.Melee)) { errString = "SidearmPickupFail_MeleeSlotsFull".Translate(); return(false); } break; } } else { switch (SimpleSidearms.LimitModeSingleRanged.Value) { case LimitModeSingleSidearm.None: break; case LimitModeSingleSidearm.AbsoluteWeight: if (sidearmWeight >= SimpleSidearms.LimitModeSingleRanged_Absolute.Value) { errString = "SidearmPickupFail_TooHeavyForSidearmRanged".Translate(); return(false); } break; case LimitModeSingleSidearm.RelativeWeight: if (sidearmWeight >= SimpleSidearms.LimitModeSingleRanged_Relative.Value * maxCapacity) { errString = "SidearmPickupFail_TooHeavyForSidearmRanged".Translate(); return(false); } break; case LimitModeSingleSidearm.Selection: if (!SimpleSidearms.LimitModeSingleRanged_Selection.Value.InnerList.Contains <string>(sidearm.defName)) { errString = "SidearmPickupFail_NotASidearmRanged".Translate(); return(false); } break; } switch (SimpleSidearms.LimitModeAmountRanged.Value) { case LimitModeAmountOfSidearms.MaximumCarryWeightOnly: break; case LimitModeAmountOfSidearms.AbsoluteWeight: if (sidearmWeight >= (SimpleSidearms.LimitModeAmountRanged_Absolute.Value - weightForType(pawn, WeaponSearchType.Ranged))) { errString = "SidearmPickupFail_SidearmsTooHeavyRanged".Translate(); return(false); } break; case LimitModeAmountOfSidearms.RelativeWeight: if (sidearmWeight >= ((SimpleSidearms.LimitModeAmountRanged_Relative.Value * maxCapacity) - weightForType(pawn, WeaponSearchType.Ranged))) { errString = "SidearmPickupFail_SidearmsTooHeavyRanged".Translate(); return(false); } break; case LimitModeAmountOfSidearms.Slots: if (SimpleSidearms.LimitModeAmountRanged_Slots.Value <= countForType(pawn, WeaponSearchType.Ranged)) { errString = "SidearmPickupFail_RangedSlotsFull".Translate(); return(false); } break; } } } errString = "SidearmPickupPass".Translate(); return(true); }
private static bool Prefix(PawnGroupMakerParms parms, PawnGroupMaker groupMaker, Pawn trader, List <Thing> wares, List <Pawn> outPawns) { Func <Thing, float> massTotaler = t => t.stackCount * t.GetStatValue(StatDefOf.Mass, true); List <Thing> list = wares.Where(t => !(t is Pawn)).ToList(); list.SortByDescending(massTotaler); float ttlMassThings = list.Sum(massTotaler); float ttlCapacity = 0f; float ttlBodySize = 0f; int numCarriers = 0; IEnumerable <PawnGenOption> carrierKinds = groupMaker.carriers.Where(p => { if (parms.tile != -1) { return(Find.WorldGrid[parms.tile].biome.IsPackAnimalAllowed(p.kind.race)); } return(true); }); PawnKindDef kind = carrierKinds.RandomElementByWeight(x => x.selectionWeight).kind; // No slow or small juveniles Predicate <Pawn> validator = (p => p.ageTracker.CurLifeStage.bodySizeFactor >= 1 && p.GetStatValue(StatDefOf.MoveSpeed, true) >= p.kindDef.race.GetStatValueAbstract(StatDefOf.MoveSpeed) ); // 50/50 chance of uniform carriers (like vanilla) or mixed carriers bool mixedCarriers = Rand.RangeInclusive(0, 1) == 1; // Generate all of the carrier pawns (empty). Either we spawn as many pawns as we need to cover // 120% of the weight of the items, or enough pawns before it seems "unreasonable" based on body // size. for (; ttlCapacity < ttlMassThings * 1.2 && ttlBodySize < 20; numCarriers++) { PawnGenerationRequest request = new PawnGenerationRequest( kind: kind, faction: parms.faction, tile: parms.tile, inhabitant: parms.inhabitants, validatorPreGear: validator ); Pawn pawn = PawnGenerator.GeneratePawn(request); outPawns.Add(pawn); ttlCapacity += MassUtility.Capacity(pawn); // Still can't have 100 chickenmuffalos. That might slow down some PCs. ttlBodySize += Mathf.Max(pawn.BodySize, 0.5f); if (mixedCarriers) { kind = carrierKinds.RandomElementByWeight(x => x.selectionWeight).kind; } } // Add items (in descending order of weight) to randomly chosen pack animals. This isn't the most // efficient routine, as we're trying to be a bit random. If I was trying to be efficient, I would // use something like SortByDescending(p.Capacity) against the existing thing list. foreach (Thing thing in list) { List <Pawn> validPawns = outPawns.FindAll(p => !MassUtility.WillBeOverEncumberedAfterPickingUp(p, thing, thing.stackCount)); if (validPawns.Count() != 0) { validPawns.RandomElement().inventory.innerContainer.TryAdd(thing, true); } else if (thing.stackCount > 1) { // No carrier can handle the full stack; split it up int countLeft = thing.stackCount; int c = 0; // safety counter (while loops can be dangerous) while (countLeft > 0) { validPawns = outPawns.FindAll(p => MassUtility.CountToPickUpUntilOverEncumbered(p, thing) >= 1); if (validPawns.Count() != 0 && c < thing.stackCount) { Pawn pawn = validPawns.RandomElement(); int countToAdd = Mathf.Min(MassUtility.CountToPickUpUntilOverEncumbered(pawn, thing), countLeft); countLeft -= pawn.inventory.innerContainer.TryAdd(thing, countToAdd, true); } else { // Either no carrier can handle a single item, or we're just in some bad while loop breakout. In // any case, force it in, evenly split among all carriers. int splitCount = Mathf.FloorToInt(countLeft / outPawns.Count()); if (splitCount > 0) { outPawns.ForEach(p => p.inventory.innerContainer.TryAdd(thing, splitCount, true)); countLeft -= splitCount * outPawns.Count(); } // Give the remainer to the ones with space (one at a time) while (countLeft > 0) { validPawns = new List <Pawn>(outPawns); validPawns.SortByDescending(p => MassUtility.FreeSpace(p)); validPawns.First().inventory.innerContainer.TryAdd(thing, 1, true); countLeft--; } break; } c++; } } else { // No way to split it; force it in validPawns = new List <Pawn>(outPawns); validPawns.SortByDescending(p => MassUtility.FreeSpace(p)); validPawns.First().inventory.innerContainer.TryAdd(thing, true); } } // Always skip the original method return(false); }
public static bool canCarrySidearmType(ThingDefStuffDefPair sidearm, Pawn pawn, out string errString) { float maxCapacity = MassUtility.Capacity(pawn); float freeCapacity = MassUtility.FreeSpace(pawn); float sidearmWeight = sidearm.thing.GetStatValueAbstract(StatDefOf.Mass, sidearm.stuff); if (((pawn.CombinedDisabledWorkTags & WorkTags.Violent) != 0) && (!sidearm.isTool())) { errString = "SidearmPickupFail_NotAToolForPacifist".Translate(pawn.LabelShort); return(false); } //this is duplicated in the switches later but Id rather not risk accidentaly deleting a case that might come up if (!isValidSidearm(sidearm, out errString)) { return(false); } if (sidearmWeight >= freeCapacity) { errString = "SidearmPickupFail_NoFreeSpace".Translate(); return(false); } if (!SimpleSidearms.SeparateModes) { switch (SimpleSidearms.LimitModeSingle.Value) { case LimitModeSingleSidearm.None: break; case LimitModeSingleSidearm.AbsoluteWeight: if (sidearmWeight >= SimpleSidearms.LimitModeSingle_Absolute.Value) { errString = "SidearmPickupFail_TooHeavyForSidearm".Translate(); return(false); } break; case LimitModeSingleSidearm.RelativeWeight: if (sidearmWeight >= SimpleSidearms.LimitModeSingle_Relative.Value * maxCapacity) { errString = "SidearmPickupFail_TooHeavyForSidearm".Translate(); return(false); } break; case LimitModeSingleSidearm.Selection: if (!SimpleSidearms.LimitModeSingle_Selection.Value.InnerList.Contains <ThingDef>(sidearm.thing)) { errString = "SidearmPickupFail_NotASidearm".Translate(); return(false); } break; } switch (SimpleSidearms.LimitModeAmount.Value) { case LimitModeAmountOfSidearms.MaximumCarryWeightOnly: break; case LimitModeAmountOfSidearms.AbsoluteWeight: if (sidearmWeight >= (SimpleSidearms.LimitModeAmount_Absolute.Value - weightForLimitType(pawn, WeaponSearchType.Both))) { errString = "SidearmPickupFail_SidearmsTooHeavyInTotal".Translate(); return(false); } break; case LimitModeAmountOfSidearms.RelativeWeight: if (sidearmWeight >= ((SimpleSidearms.LimitModeAmount_Relative.Value * maxCapacity) - weightForLimitType(pawn, WeaponSearchType.Both))) { errString = "SidearmPickupFail_SidearmsTooHeavyInTotal".Translate(); return(false); } break; case LimitModeAmountOfSidearms.Slots: if (SimpleSidearms.LimitModeAmount_Slots.Value <= countForLimitType(pawn, WeaponSearchType.Both)) { errString = "SidearmPickupFail_AllSlotsFull".Translate(); return(false); } break; } } else { switch (SimpleSidearms.LimitModeAmountTotal.Value) { case LimitModeAmountOfSidearms.MaximumCarryWeightOnly: break; case LimitModeAmountOfSidearms.AbsoluteWeight: if (sidearmWeight >= (SimpleSidearms.LimitModeAmountTotal_Absolute.Value - weightForLimitType(pawn, WeaponSearchType.Both))) { errString = "SidearmPickupFail_SidearmsTooHeavyInTotal".Translate(); return(false); } break; case LimitModeAmountOfSidearms.RelativeWeight: if (sidearmWeight >= ((SimpleSidearms.LimitModeAmountTotal_Relative.Value * maxCapacity) - weightForLimitType(pawn, WeaponSearchType.Both))) { errString = "SidearmPickupFail_SidearmsTooHeavyInTotal".Translate(); return(false); } break; case LimitModeAmountOfSidearms.Slots: if (SimpleSidearms.LimitModeAmountTotal_Slots.Value <= countForLimitType(pawn, WeaponSearchType.Both)) { errString = "SidearmPickupFail_AllSlotsFull".Translate(); return(false); } break; } if (sidearm.thing.IsMeleeWeapon) { switch (SimpleSidearms.LimitModeSingleMelee.Value) { case LimitModeSingleSidearm.None: break; case LimitModeSingleSidearm.AbsoluteWeight: if (sidearmWeight >= SimpleSidearms.LimitModeSingleMelee_Absolute.Value) { errString = "SidearmPickupFail_TooHeavyForSidearmMelee".Translate(); return(false); } break; case LimitModeSingleSidearm.RelativeWeight: if (sidearmWeight >= SimpleSidearms.LimitModeSingleMelee_Relative.Value * maxCapacity) { errString = "SidearmPickupFail_TooHeavyForSidearmMelee".Translate(); return(false); } break; case LimitModeSingleSidearm.Selection: if (!SimpleSidearms.LimitModeSingleMelee_Selection.Value.InnerList.Contains <ThingDef>(sidearm.thing)) { errString = "SidearmPickupFail_NotASidearmMelee".Translate(); return(false); } break; } switch (SimpleSidearms.LimitModeAmountMelee.Value) { case LimitModeAmountOfSidearms.MaximumCarryWeightOnly: break; case LimitModeAmountOfSidearms.AbsoluteWeight: if (sidearmWeight >= (SimpleSidearms.LimitModeAmountMelee_Absolute.Value - weightForLimitType(pawn, WeaponSearchType.Melee))) { errString = "SidearmPickupFail_SidearmsTooHeavyMelee".Translate(); return(false); } break; case LimitModeAmountOfSidearms.RelativeWeight: if (sidearmWeight >= ((SimpleSidearms.LimitModeAmountMelee_Relative.Value * maxCapacity) - weightForLimitType(pawn, WeaponSearchType.Melee))) { errString = "SidearmPickupFail_SidearmsTooHeavyMelee".Translate(); return(false); } break; case LimitModeAmountOfSidearms.Slots: if (SimpleSidearms.LimitModeAmountMelee_Slots.Value <= countForLimitType(pawn, WeaponSearchType.Melee)) { errString = "SidearmPickupFail_MeleeSlotsFull".Translate(); return(false); } break; } } else if (sidearm.thing.IsRangedWeapon) { switch (SimpleSidearms.LimitModeSingleRanged.Value) { case LimitModeSingleSidearm.None: break; case LimitModeSingleSidearm.AbsoluteWeight: if (sidearmWeight >= SimpleSidearms.LimitModeSingleRanged_Absolute.Value) { errString = "SidearmPickupFail_TooHeavyForSidearmRanged".Translate(); return(false); } break; case LimitModeSingleSidearm.RelativeWeight: if (sidearmWeight >= SimpleSidearms.LimitModeSingleRanged_Relative.Value * maxCapacity) { errString = "SidearmPickupFail_TooHeavyForSidearmRanged".Translate(); return(false); } break; case LimitModeSingleSidearm.Selection: if (!SimpleSidearms.LimitModeSingleRanged_Selection.Value.InnerList.Contains <ThingDef>(sidearm.thing)) { errString = "SidearmPickupFail_NotASidearmRanged".Translate(); return(false); } break; } switch (SimpleSidearms.LimitModeAmountRanged.Value) { case LimitModeAmountOfSidearms.MaximumCarryWeightOnly: break; case LimitModeAmountOfSidearms.AbsoluteWeight: if (sidearmWeight >= (SimpleSidearms.LimitModeAmountRanged_Absolute.Value - weightForLimitType(pawn, WeaponSearchType.Ranged))) { errString = "SidearmPickupFail_SidearmsTooHeavyRanged".Translate(); return(false); } break; case LimitModeAmountOfSidearms.RelativeWeight: if (sidearmWeight >= ((SimpleSidearms.LimitModeAmountRanged_Relative.Value * maxCapacity) - weightForLimitType(pawn, WeaponSearchType.Ranged))) { errString = "SidearmPickupFail_SidearmsTooHeavyRanged".Translate(); return(false); } break; case LimitModeAmountOfSidearms.Slots: if (SimpleSidearms.LimitModeAmountRanged_Slots.Value <= countForLimitType(pawn, WeaponSearchType.Ranged)) { errString = "SidearmPickupFail_RangedSlotsFull".Translate(); return(false); } break; } } } errString = "SidearmPickupPass".Translate(); return(true); }
private IEnumerable <Pawn> GenerateCarriers(PawnGroupMakerParms parms, PawnGroupMaker groupMaker, List <Thing> wares) { var carrierList = new List <Pawn>(); var carrierKind = (from x in groupMaker.carriers where parms.tile == -1 || Find.WorldGrid[parms.tile].biome.IsPackAnimalAllowed(x.kind.race) select x).RandomElementByWeight(o => o.selectionWeight).kind; var waresSansPawns = new List <Thing>(); var numCarriers = 1; if (!wares.NullOrEmpty()) { var baseCapacity = carrierKind.RaceProps.baseBodySize * 34f; // Leaving some space for silvah, original calculation is 35f var totalWeight = 0f; for (int j = wares.Count - 1; j > -1; j--) { var thing = wares[j]; if (thing is Pawn) { continue; } var mass = thing.Mass(); if (thing.stackCount == 1 && mass > baseCapacity) { if (Prefs.DevMode) { Log.Warning("[Carnivale] " + thing + " is too big for any carrier and will be removed from wares. mass=" + mass + ", " + carrierKind.label + " capacity=" + baseCapacity ); } wares.RemoveAt(j); continue; } if (thing.def.stackLimit > 1) { while (thing.stackCount >= 2 && mass > baseCapacity) { thing.stackCount /= 2; mass = thing.Mass(); if (Prefs.DevMode) { Log.Message("\t[Carnivale] " + thing.LabelShort + " was to heavy for any carrier. Reducing its stack count to " + thing.stackCount + " and trying again."); } } if (mass > baseCapacity) { if (Prefs.DevMode) { Log.Warning("[Carnivale] " + thing.LabelShort + " is too heavy for any carrier and will be removed from wares. mass=" + mass + ", stackCount=" + thing.stackCount + ", carrierKind=" + carrierKind.label + ", capacity=" + baseCapacity ); } wares.RemoveAt(j); continue; } } totalWeight += mass; waresSansPawns.Add(thing); } numCarriers = Mathf.CeilToInt(totalWeight / baseCapacity); } else { var silver = ThingMaker.MakeThing(ThingDefOf.Silver); silver.stackCount = 100; waresSansPawns.Add(silver); } int i = 0; for (int j = 0; j < numCarriers; j++) { // Generate carrier PawnGenerationRequest request = new PawnGenerationRequest( carrierKind, parms.faction, PawnGenerationContext.NonPlayer, parms.tile, false, false, false, false, true, false, 1f, false, true, true, parms.inhabitants, false, null, null, null, null, null, null ); var carrier = PawnGenerator.GeneratePawn(request); if (i < waresSansPawns.Count) { // Add initial few items to carrier if (carrier.inventory.innerContainer.TryAdd(waresSansPawns[i], true)) { i++; } } carrierList.Add(carrier); yield return(carrier); } // Finally, fill up all the carriers' inventories while (i < waresSansPawns.Count) { var thing = waresSansPawns[i]; var mass = thing.Mass(); var carrier = carrierList.MaxBy(c => MassUtility.FreeSpace(c)); if (thing.stackCount > 1 && !carrier.HasSpaceFor(thing)) { while (thing.stackCount >= 2 && mass > MassUtility.FreeSpace(carrier)) { thing.stackCount /= 2; mass = thing.Mass(); if (Prefs.DevMode) { Log.Message("\t[Carnivale] " + thing.LabelShort + " was to heavy for any carrier. Reducing its stack count to " + thing.stackCount + " and trying again."); } } } if (carrier.inventory.innerContainer.TryAdd(thing)) { i++; } else { if (Prefs.DevMode) { Log.Warning("[Carnivale] " + thing.LabelShort + " is too heavy for any carrier and will be removed from wares. mass=" + mass + ", stackCount=" + thing.stackCount + ", carrierKind=" + carrierKind.label + ", freeSpace=" + MassUtility.FreeSpace(carrier) ); } wares.RemoveAt(i); } } if (i == waresSansPawns.Count) { yield break; } var remainingMass = waresSansPawns.Sum(w => w.Mass()); var remainingFreeSpace = carrierList.Sum(c => MassUtility.FreeSpace(c)); if (Prefs.DevMode) { Log.Warning("[Carnivale] Could not fit all wares in carriers. remainingMass=" + remainingMass + ", remainingFreeSpace=" + remainingFreeSpace); } while (i < waresSansPawns.Count) { var thing = waresSansPawns[i]; // Remove things that could not fit for whatever reason if (Prefs.DevMode) { Log.Warning("\t[Carnivale] removing " + thing); } wares.Remove(waresSansPawns[i]); i++; } }