public static bool Prefix(Pawn pawn, Thing thing, WorkGiver_HaulToInventory __instance, bool forced, ref bool __result)
        {
            #region PickUpAndHaul code
            //bulky gear (power armor + minigun) so don't bother.
            if (MassUtility.GearMass(pawn) / MassUtility.Capacity(pawn) >= 0.8f)
            {
                return(false);
            }

            if (!WorkGiver_HaulToInventory.GoodThingToHaul(thing, pawn) || !HaulAIUtility.PawnCanAutomaticallyHaulFast(pawn, thing, forced))
            {
                return(false);
            }

            StoragePriority currentPriority = StoreUtility.CurrentStoragePriorityOf(thing);
            bool            foundCell       = StoreUtility.TryFindBestBetterStoreCellFor(thing, pawn, pawn.Map, currentPriority, pawn.Faction, out IntVec3 storeCell, true);
            #endregion

            if (!foundCell)
            {
                __result = false;
            }
            else
            {
                SlotGroup slotGroup = pawn.Map.haulDestinationManager.SlotGroupAt(storeCell);
                __result = !(slotGroup != null && Limits.HasLimit(slotGroup.Settings) && Limits.GetLimit(slotGroup.Settings) >= slotGroup.TotalPrecalculatedItemsStack());
            }

            return(false);
        }
        static void Postfix(ref Pawn p, ref float __result)
        {
            ExtendedDataStorage store = GiddyUpCore.Base.Instance.GetExtendedDataStorage();

            if (store == null)//this check is needed because some mods call this function on world load
            {
                return;
            }

            ExtendedPawnData pawnData = store.GetExtendedDataFor(p);

            if (pawnData == null || pawnData.caravanRider == null)
            {
                return;
            }
            else
            {
                //new solution A - more forgiving
                //float riderTotalMass = pawnData.caravanRider.GetStatValue(StatDefOf.Mass);
                //float riderGearInvMass = MassUtility.GearAndInventoryMass(pawnData.caravanRider);
                //float riderBodyMass = riderTotalMass - riderGearInvMass;
                //__result -= riderBodyMass;
                //__result = Math.Max(__result, 0f);

                //new solution B - more restrictive
                float riderTotalMass   = pawnData.caravanRider.GetStatValue(StatDefOf.Mass);
                float riderGearInvMass = MassUtility.GearAndInventoryMass(pawnData.caravanRider);
                float riderBodyMass    = riderTotalMass - riderGearInvMass;
                float riderCapacity    = MassUtility.Capacity(pawnData.caravanRider);
                float riderGrossMass   = riderBodyMass + riderCapacity;
                __result -= riderGrossMass;
                __result  = Math.Max(__result, 0f);
            }
        }
        public static bool CheckCanCarryGift(List <Tradeable> tradeables, ITrader trader)
        {
            Pawn pawn = trader as Pawn;

            if (pawn == null)
            {
                return(true);
            }
            float num  = 0f;
            float num2 = 0f;
            Lord  lord = pawn.GetLord();

            if (lord != null)
            {
                for (int i = 0; i < lord.ownedPawns.Count; i++)
                {
                    Pawn pawn2 = lord.ownedPawns[i];
                    TraderCaravanRole traderCaravanRole = pawn2.GetTraderCaravanRole();
                    if ((pawn2.RaceProps.Humanlike && traderCaravanRole != TraderCaravanRole.Guard) || traderCaravanRole == TraderCaravanRole.Carrier)
                    {
                        num  += MassUtility.Capacity(pawn2);
                        num2 += MassUtility.GearAndInventoryMass(pawn2);
                    }
                }
            }
            else
            {
                num  = MassUtility.Capacity(pawn);
                num2 = MassUtility.GearAndInventoryMass(pawn);
            }
            float num3 = 0f;

            for (int j = 0; j < tradeables.Count; j++)
            {
                if (tradeables[j].ActionToDo == TradeAction.PlayerSells)
                {
                    int num4 = Mathf.Min(tradeables[j].CountToTransferToDestination, tradeables[j].CountHeldBy(Transactor.Colony));
                    if (num4 > 0)
                    {
                        num3 += tradeables[j].AnyThing.GetStatValue(StatDefOf.Mass) * (float)num4;
                    }
                }
            }
            if (num2 + num3 <= num)
            {
                return(true);
            }
            float num5 = num - num2;

            if (num5 <= 0f)
            {
                Messages.Message("MessageCantGiveGiftBecauseCantCarryEncumbered".Translate(), MessageTypeDefOf.RejectInput, historical: false);
            }
            else
            {
                Messages.Message("MessageCantGiveGiftBecauseCantCarry".Translate(num3.ToStringMass(), num5.ToStringMass()), MessageTypeDefOf.RejectInput, historical: false);
            }
            return(false);
        }
Example #4
0
        public static bool DrawThingRow(object tab, ref float y, ref float width, Thing thing, bool inventory)
        {
            if (!Settings.gui_manual_unload)
            {
                return(true);
            }

            Pawn  SelPawn    = (Pawn)ITab_Pawn_Gear_Utility.LSelPawnForGear.GetValue(tab);
            bool  CanControl = (bool)ITab_Pawn_Gear_Utility.LCanControl.GetValue(tab);
            Color hColor     = new Color(1f, 0.8f, 0.8f, 1f);
            //Log.Message($"CanControl={CanControl}, pc={SelPawn.IsColonistPlayerControlled}, spawned={SelPawn.Spawned}, pcHome={SelPawn.Map.IsPlayerHome}, bcoded={IsBiocodedOrLinked(SelPawn, thing, inventory)}, locked={IsLocked(SelPawn, thing)}");

            Rect rect = new Rect(0f, y, width, 28f);

            if ((thing is ThingWithComps) &&
                CanControl &&
                (inventory || SelPawn.IsColonistPlayerControlled || SelPawn.Spawned && !SelPawn.Map.IsPlayerHome) &&
                !IsBiocodedOrLinked(SelPawn, thing, inventory) &&
                !IsLocked(SelPawn, thing))
            {
                Rect rect2          = new Rect(rect.width - 24f, y, 24f, 24f);
                CompUnloadChecker c = CompUnloadChecker.GetChecker(thing, false, true);
                if (c.ShouldUnload)
                {
                    TooltipHandler.TipRegion(rect2, "UnloadThingCancel".Translate());

                    var cl = GUI.color;
                    if (Widgets.ButtonImage(rect2, ContentFinder <Texture2D> .Get("UI/Icons/Unload_Thing_Cancel"), hColor))
                    {
                        SoundDefOf.Tick_High.PlayOneShotOnCamera(null);
                        c.ShouldUnload = false;

                        if (MassUtility.Capacity(SelPawn, null) < MassUtility.GearAndInventoryMass(SelPawn) &&
                            thing.stackCount * thing.GetStatValue(StatDefOf.Mass, true) > 0 &&
                            !thing.def.destroyOnDrop)
                        {
                            ITab_Pawn_Gear_Utility.LInterfaceDrop.Invoke(tab, new object[] { thing });
                        }
                    }
                    GUI.color = cl;
                }
                else
                {
                    TooltipHandler.TipRegion(rect2, "UnloadThing".Translate());
                    var cl = GUI.color;
                    if (Widgets.ButtonImage(rect2, ContentFinder <Texture2D> .Get("UI/Icons/Unload_Thing"), Color.white))
                    {
                        SoundDefOf.Tick_High.PlayOneShotOnCamera(null);
                        c.ShouldUnload = true;
                    }
                }
                width -= 24f;
            }
            return(true);
        }
        public static bool Prefix(ITab_Pawn_Gear __instance, ref float y, ref float width, Thing thing, bool inventory)
        {
            if (!Settings.gui_manual_unload)
            {
                return(true);
            }

            bool CanControl     = Traverse.Create(__instance).Property("CanControl").GetValue <bool>();
            Pawn SelPawnForGear = Traverse.Create(__instance).Property("SelPawnForGear").GetValue <Pawn>();
            Rect rect           = new Rect(0f, y, width, 28f);

            if (CanControl &&
                (SelPawnForGear.IsColonistPlayerControlled || SelPawnForGear.Spawned && !SelPawnForGear.Map.IsPlayerHome) &&
                (thing is ThingWithComps) &&
                !IsBiocodedOrLinked(SelPawnForGear, thing, inventory) &&
                !IsLocked(SelPawnForGear, thing))
            {
                Rect rect2          = new Rect(rect.width - 24f, y, 24f, 24f);
                CompUnloadChecker c = CompUnloadChecker.GetChecker(thing, false, true);
                if (c.ShouldUnload)
                {
                    TooltipHandler.TipRegion(rect2, "UnloadThingCancel".Translate());

                    //weird shenanigans with colors
                    var cl = GUI.color;
                    if (Widgets.ButtonImage(rect2, ContentFinder <Texture2D> .Get("UI/Icons/Unload_Thing_Cancel"), hColor))
                    {
                        SoundDefOf.Tick_High.PlayOneShotOnCamera(null);
                        c.ShouldUnload = false;

                        if (MassUtility.Capacity(SelPawnForGear, null) < MassUtility.GearAndInventoryMass(SelPawnForGear) &&
                            thing.stackCount * thing.GetStatValue(StatDefOf.Mass, true) > 0 &&
                            !thing.def.destroyOnDrop)
                        {
                            Thing t;
                            SelPawnForGear.inventory.innerContainer.TryDrop(thing, SelPawnForGear.Position, SelPawnForGear.Map, ThingPlaceMode.Near, out t, null, null);
                        }
                    }
                    GUI.color = cl;
                }
                else
                {
                    TooltipHandler.TipRegion(rect2, "UnloadThing".Translate());
                    if (Widgets.ButtonImage(rect2, ContentFinder <Texture2D> .Get("UI/Icons/Unload_Thing")))
                    {
                        SoundDefOf.Tick_High.PlayOneShotOnCamera(null);
                        c.ShouldUnload = true;
                    }
                }
                width -= 24f;
            }
            return(true);
        }
Example #6
0
        //pick up stuff until you can't anymore,
        //while you're up and about, pick up something and haul it
        //before you go out, empty your pockets

        public override Job JobOnThing(Pawn pawn, Thing thing, bool forced = false)
        {
            CompHauledToInventory takenToInventory = pawn.TryGetComp <CompHauledToInventory>();

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

            if (thing is Corpse)
            {
                return(null);
            }

            if (!HaulAIUtility.PawnCanAutomaticallyHaulFast(pawn, thing, forced))
            {
                return(null);
            }

            if (thing.IsForbidden(pawn) || StoreUtility.IsInValidBestStorage(thing))
            {
                return(null);
            }

            //bulky gear (power armor + minigun) so don't bother.
            if (MassUtility.GearMass(pawn) / MassUtility.Capacity(pawn) >= 0.8f)
            {
                return(null);
            }

            StoragePriority currentPriority = HaulAIUtility.StoragePriorityAtFor(thing.Position, thing);

            if (StoreUtility.TryFindBestBetterStoreCellFor(thing, pawn, pawn.Map, currentPriority, pawn.Faction, out IntVec3 storeCell, true))
            {
                //since we've gone through all the effort of getting the loc, might as well use it.
                //Don't multi-haul food to hoppers.
                if (thing.def.IsNutritionGivingIngestible)
                {
                    if (thing.def.ingestible.preferability == FoodPreferability.RawBad || thing.def.ingestible.preferability == FoodPreferability.RawTasty)
                    {
                        List <Thing> thingList = storeCell.GetThingList(thing.Map);
                        for (int i = 0; i < thingList.Count; i++)
                        {
                            Thing thingAtCell = thingList[i];
                            if (thingAtCell.def == ThingDefOf.Hopper)
                            {
                                return(HaulAIUtility.HaulToStorageJob(pawn, thing));
                            }
                        }
                    }
                }
            }
Example #7
0
        private void TryDrawMassInfo(ref float curY, float width)
        {
            if (this.SelPawnForCargo.GetComp <CompShips>().beached)
            {
                return;
            }
            Rect  rect = new Rect(0f, curY, width, 22f);
            float num  = MassUtility.GearAndInventoryMass(this.SelPawnForCargo);
            float num2 = MassUtility.Capacity(this.SelPawnForCargo, null);

            Widgets.Label(rect, "MassCarried".Translate(num.ToString("0.##"), num2.ToString("0.##")));
            curY += 22f;
        }
        private void TryDrawMassInfo(ref float curY, float width)
        {
            if (this.SelPawnForGear.Dead || !this.ShouldShowInventory(this.SelPawnForGear))
            {
                return;
            }
            Rect  rect = new Rect(0f, curY, width, 22f);
            float num  = MassUtility.GearAndInventoryMass(this.SelPawnForGear);
            float num2 = MassUtility.Capacity(this.SelPawnForGear, null);

            Widgets.Label(rect, "MassCarried".Translate(num.ToString("0.##"), num2.ToString("0.##")));
            curY += 22f;
        }
Example #9
0
        public static void TryDrawMassInfo(Pawn pawn, ref float curY, float width)
        {
            if (pawn.Dead || !ShouldShowInventory(pawn))
            {
                return;
            }
            Rect  rect = new Rect(0f, curY, width, 22f);
            float num  = MassUtility.GearAndInventoryMass(pawn);
            float num2 = MassUtility.Capacity(pawn, null);

            Widgets.Label(rect, "MassCarried".Translate(num.ToString("0.##"), num2.ToString("0.##")));
            curY += 22f;
        }
        //pick up stuff until you can't anymore,
        //while you're up and about, pick up something and haul it
        //before you go out, empty your pockets

        public override Job JobOnThing(Pawn pawn, Thing thing, bool forced = false)
        {
            //bulky gear (power armor + minigun) so don't bother.
            if (MassUtility.GearMass(pawn) / MassUtility.Capacity(pawn) >= 0.8f)
            {
                return(null);
            }

            DesignationDef haulUrgentlyDesignation = DefDatabase <DesignationDef> .GetNamed("HaulUrgentlyDesignation", false);

            // Misc. Robots compatibility
            // See https://github.com/catgirlfighter/RimWorld_CommonSense/blob/master/Source/CommonSense11/CommonSense/OpportunisticTasks.cs#L129-L140
            if (pawn.TryGetComp <CompHauledToInventory>() == null)
            {
                return(null);
            }

            //This WorkGiver gets hijacked by AllowTool and expects us to urgently haul corpses.
            if (ModCompatibilityCheck.AllowToolIsActive && thing is Corpse &&
                pawn.Map.designationManager.DesignationOn(thing)?.def == haulUrgentlyDesignation && HaulAIUtility.PawnCanAutomaticallyHaulFast(pawn, thing, forced))
            {
                return(HaulAIUtility.HaulToStorageJob(pawn, thing));
            }

            if (!GoodThingToHaul(thing, pawn) || !HaulAIUtility.PawnCanAutomaticallyHaulFast(pawn, thing, forced))
            {
                return(null);
            }

            StoragePriority currentPriority = StoreUtility.CurrentStoragePriorityOf(thing);

            if (StoreUtility.TryFindBestBetterStoreCellFor(thing, pawn, pawn.Map, currentPriority, pawn.Faction, out IntVec3 storeCell, true))
            {
                //since we've gone through all the effort of getting the loc, might as well use it.
                //Don't multi-haul food to hoppers.
                if (thing.def.IsNutritionGivingIngestible)
                {
                    if (thing.def.ingestible.preferability == FoodPreferability.RawBad || thing.def.ingestible.preferability == FoodPreferability.RawTasty)
                    {
                        List <Thing> thingList = storeCell.GetThingList(thing.Map);

                        foreach (Thing t in thingList)
                        {
                            if (t.def == ThingDefOf.Hopper)
                            {
                                return(HaulAIUtility.HaulToStorageJob(pawn, thing));
                            }
                        }
                    }
                }
            }
        private void TryDrawMassInfo1(Rect rect)
        {
            if (this.SelPawnForGear.Dead || !this.ShouldShowInventory(this.SelPawnForGear))
            {
                return;
            }
            Rect rect1 = new Rect(rect.x, rect.y, 24f, 24f);

            GUI.DrawTexture(rect1, ContentFinder <Texture2D> .Get("UI/Icons/Sandy_MassCarried_Icon", true));
            TooltipHandler.TipRegion(rect1, "SandyMassCarried".Translate());
            float num   = MassUtility.GearAndInventoryMass(this.SelPawnForGear);
            float num2  = MassUtility.Capacity(this.SelPawnForGear, null);
            Rect  rect2 = new Rect(rect.x + 30f, rect.y + 2f, 104f, 24f);

            Widgets.Label(rect2, "SandyMassValue".Translate(num.ToString("0.##"), num2.ToString("0.##")));
        }
        public override bool HasJobOnThing(Pawn pawn, Thing thing, bool forced = false)
        {
            //bulky gear (power armor + minigun) so don't bother.
            if (MassUtility.GearMass(pawn) / MassUtility.Capacity(pawn) >= 0.8f)
            {
                return(false);
            }

            if (!GoodThingToHaul(thing, pawn) || !HaulAIUtility.PawnCanAutomaticallyHaulFast(pawn, thing, forced))
            {
                return(false);
            }

            StoragePriority currentPriority = StoreUtility.CurrentStoragePriorityOf(thing);

            return(StoreUtility.TryFindBestBetterStoreCellFor(thing, pawn, pawn.Map, currentPriority, pawn.Faction, out IntVec3 _));
        }
        private void DrawMassInfo(Vector2 topLeft)
        {
            if (SelPawnForGear.Dead || !ShouldShowInventory(SelPawnForGear))
            {
                return;
            }
            Rect iconRect = new Rect(topLeft.x, topLeft.y, SmallIconSize, SmallIconSize);

            GUI.DrawTexture(iconRect, ContentFinder <Texture2D> .Get("UI/Icons/Sandy_MassCarried_Icon", true));
            TooltipHandler.TipRegion(iconRect, "SandyMassCarried".Translate());

            float mass     = MassUtility.GearAndInventoryMass(SelPawnForGear);
            float capacity = MassUtility.Capacity(SelPawnForGear, null);
            Rect  textRect = new Rect(topLeft.x + SmallIconSize + MediumMargin, topLeft.y + SmallIconMargin, statBoxWidth - SmallIconSize, SmallIconSize);

            Widgets.Label(textRect, "SandyMassValue".Translate(mass.ToString("0.##"), capacity.ToString("0.##")));
        }
Example #14
0
        //pick up stuff until you can't anymore,
        //while you're up and about, pick up something and haul it
        //before you go out, empty your pockets

        public override Job JobOnThing(Pawn pawn, Thing thing, bool forced = false)
        {
            //bulky gear (power armor + minigun) so don't bother.
            if (MassUtility.GearMass(pawn) / MassUtility.Capacity(pawn) >= 0.8f)
            {
                return(null);
            }

            DesignationDef HaulUrgentlyDesignation = DefDatabase <DesignationDef> .GetNamed("HaulUrgentlyDesignation", false);

            //This WorkGiver gets hijacked by AllowTool and expects us to urgently haul corpses.
            if (ModCompatibilityCheck.AllowToolIsActive && thing is Corpse && pawn.Map.designationManager.DesignationOn(thing)?.def == HaulUrgentlyDesignation && HaulAIUtility.PawnCanAutomaticallyHaulFast(pawn, thing, forced))
            {
                return(HaulAIUtility.HaulToStorageJob(pawn, thing));
            }

            if (!GoodThingToHaul(thing, pawn) || !HaulAIUtility.PawnCanAutomaticallyHaulFast(pawn, thing, forced))
            {
                return(null);
            }

            StoragePriority currentPriority = StoreUtility.CurrentStoragePriorityOf(thing);

            if (StoreUtility.TryFindBestBetterStoreCellFor(thing, pawn, pawn.Map, currentPriority, pawn.Faction, out IntVec3 storeCell, true))
            {
                //since we've gone through all the effort of getting the loc, might as well use it.
                //Don't multi-haul food to hoppers.
                if (thing.def.IsNutritionGivingIngestible)
                {
                    if (thing.def.ingestible.preferability == FoodPreferability.RawBad || thing.def.ingestible.preferability == FoodPreferability.RawTasty)
                    {
                        List <Thing> thingList = storeCell.GetThingList(thing.Map);
                        for (int i = 0; i < thingList.Count; i++)
                        {
                            if (thingList[i].def == ThingDefOf.Hopper)
                            {
                                return(HaulAIUtility.HaulToStorageJob(pawn, thing));
                            }
                        }
                    }
                }
            }
Example #15
0
 /// <summary>
 /// Carry capacity with Vehicles when using MassCalculator
 /// </summary>
 /// <param name="thingCounts"></param>
 /// <param name="__result"></param>
 /// <param name="explanation"></param>
 public static bool CapacityWithVehicle(List <ThingCount> thingCounts, ref float __result, StringBuilder explanation = null)
 {
     if (thingCounts.NotNullAndAny(x => x.Thing is VehiclePawn))
     {
         float num = 0f;
         foreach (ThingCount tc in thingCounts)
         {
             if (tc.Count > 0)
             {
                 if (tc.Thing is VehiclePawn)
                 {
                     num += MassUtility.Capacity(tc.Thing as Pawn, explanation) * (float)tc.Count;
                 }
             }
         }
         __result = Mathf.Max(num, 0f);
         return(false);
     }
     return(true);
 }
Example #16
0
        private void TryDrawMassInfo(ref float curY, float width)
        {
            if (SelPawnForCargo.beached)
            {
                return;
            }
            Rect  rect       = new Rect(0f, curY, width, StandardLineHeight);
            float cannonsNum = 0f;

            if (SelPawnForCargo.TryGetComp <CompCannons>() != null)
            {
                foreach (VehicleTurret cannon in SelPawnForCargo.CompCannons.Cannons)
                {
                    cannonsNum += cannon.loadedAmmo is null ? 0f : cannon.loadedAmmo.BaseMass * cannon.shellCount;
                }
            }
            float num  = MassUtility.GearAndInventoryMass(SelPawnForCargo) + cannonsNum;
            float num2 = MassUtility.Capacity(SelPawnForCargo, null);

            Widgets.Label(rect, "MassCarried".Translate(num.ToString("0.##"), num2.ToString("0.##")));
            curY += StandardLineHeight;
        }
Example #17
0
        public void DrawStatistics(Rect rect)
        {
            var viewRect = new Rect(rect.x, rect.y, rect.width - 16f, statsHeight);

            //Widgets.DrawBoxSolid(rect, Color.green);

            var height = 0f;

            Widgets.BeginScrollView(rect, ref statsScroll, viewRect);

            ModGUIUtility.ListSeperator(ref viewRect, "LoadoutStatistics");

            viewRect.AdjVertBy(GenUI.GapTiny);

            var loadoutItems = selectedUnit.loadout.AllItems.ToList();

            ModGUIUtility.BarWithOverlay(
                viewRect.PopTopPartPixels(ModGUIUtility.SPACED_HEIGHT),
                Utility.HypotheticalEncumberancePercent(pawn, loadoutItems),
                Utility.HypotheticalUnboundedEncumberancePercent(pawn, loadoutItems) > 1f ? Textures.ValvetTex as Texture2D : Textures.RWPrimaryTex as Texture2D,
                "Weight".Translate(),
                Utility.HypotheticalGearAndInventoryMass(pawn, loadoutItems).ToString("0.#") + "/" + MassUtility.Capacity(pawn).ToStringMass(),
                "WeightOverCapacity".Translate());

            height += GenUI.GapTiny + ModGUIUtility.SPACED_HEIGHT;

            // var statBonuses = new Dictionary<StatDef, List<Item>>();
            // var wornApparel = selectedUnit.loadout.HypotheticalWornApparel(pawn.RaceProps.body).ToList();
            // var heldItems = loadoutItems.Where(item => !item.Def.IsApparel).ToList();
            //
            // foreach (var potentialStatBoost in wornApparel.Union(heldItems))
            // {
            //     if (!potentialStatBoost.Def?.equippedStatOffsets?.Any() ?? true) continue;
            //
            //     foreach (var mod in potentialStatBoost.Def.equippedStatOffsets.Select(m => m.stat)) {
            //         if (!statBonuses.TryGetValue(mod, out var list)) {
            //             statBonuses.Add(mod, new List<Item> { potentialStatBoost });
            //             continue;
            //         }
            //         list.Add(potentialStatBoost);
            //     }
            // }
            //
            // var apparelBonuses = new List<StatDef> {
            //     StatDefOf.SharpDamageMultiplier, StatDefOf.ArmorRating_Blunt, StatDefOf.ArmorRating_Heat,
            //     StatDefOf.Insulation_Cold, StatDefOf.Insulation_Heat
            // };
            //
            // foreach (var stat in apparelBonuses) {
            //     statBonuses.Add(stat, wornApparel);
            // }
            //
            // foreach (var statBonus in statBonuses) {
            //     TryDrawSpoofStatCalculations(ref viewRect, statBonus.Key, statBonus.Value);
            //     height += GUIUtility.SPACED_HEIGHT;
            // }

            Widgets.EndScrollView();

            statsHeight = height;
        }
        //[HarmonyPostfix]
        public static void TicksPerMove(bool diagonal, Pawn __instance, ref int __result)
        {
            if (_carrymodifier == 0f)
            {
                return;
            }
            if (!MassUtility.CanEverCarryAnything(__instance))
            {
                __result = Mathf.Clamp(Mathf.RoundToInt(__result / _modifier), 1, 450);
                return;
            }
            var c           = (float)__result;
            var pawnMass    = __instance.GetStatValue(StatDefOf.Mass);
            var ignoredMass = pawnMass * (__instance.RaceProps.packAnimal ? 0.5f : 0.2f);

            if (Compatibility_GiddyUp.GetMount(__instance) is Pawn mount)
            {
                __result = diagonal ? mount.TicksPerMoveDiagonal : mount.TicksPerMoveCardinal;
                return;
            }

            // add our own modifiers
            var mass = ignoredMass - MassUtility.GearAndInventoryMass(__instance);

            if (Compatibility_GiddyUp.GetRider(__instance) is Pawn rider)
            {
                mass += MassUtility.GearAndInventoryMass(rider);

                mass += rider.GetStatValue(StatDefOf.Mass, true);
                var riderCarriedThing = rider.carryTracker.CarriedThing;
                if (riderCarriedThing != null)
                {
                    mass += riderCarriedThing.stackCount * riderCarriedThing.GetStatValue(StatDefOf.Mass);
                    if (riderCarriedThing is Pawn p)
                    {
                        mass += MassUtility.GearAndInventoryMass(p);

                        // undo carry pawn modifier
                        c /= 1.666f;
                    }
                }
            }


            var capacity = MassUtility.Capacity(__instance, null);

            var pawnCarriedThing = __instance.carryTracker.CarriedThing;

            if (pawnCarriedThing != null)
            {
                mass += pawnCarriedThing.stackCount * pawnCarriedThing.GetStatValue(StatDefOf.Mass);
                if (pawnCarriedThing is Pawn p)
                {
                    mass += MassUtility.GearAndInventoryMass(p);

                    // undo carry pawn modifier
                    c /= 1.666f;
                }
            }

            var encumbrance = Mathf.Clamp(mass / capacity, 0f, 1f);

            var modifier = 1 + (encumbrance * _carrymodifier);

            c *= modifier;

            __result = Mathf.Clamp(Mathf.RoundToInt(c / _modifier), 1, 450);
        }
Example #19
0
 public static float HypotheticalUnboundedEncumberancePercent(Pawn p, List <Item> items)
 {
     return(HypotheticalGearAndInventoryMass(p, items) / MassUtility.Capacity(p));
 }
Example #20
0
        private void DrawMass(Rect rect, TransferableOneWay trad, float availableMass)
        {
            if (!trad.HasAnyThing)
            {
                return;
            }
            Thing anyThing = trad.AnyThing;
            Pawn  pawn     = anyThing as Pawn;

            if (pawn != null && !includePawnsMassInMassUsage && !MassUtility.CanEverCarryAnything(pawn))
            {
                return;
            }
            Widgets.DrawHighlightIfMouseover(rect);
            if (pawn == null || includePawnsMassInMassUsage)
            {
                float mass = GetMass(anyThing);
                if (Mouse.IsOver(rect))
                {
                    if (pawn != null)
                    {
                        float gearMass = 0f;
                        float invMass  = 0f;
                        gearMass = MassUtility.GearMass(pawn);
                        if (!InventoryCalculatorsUtility.ShouldIgnoreInventoryOf(pawn, ignorePawnInventoryMass))
                        {
                            invMass = MassUtility.InventoryMass(pawn);
                        }
                        TooltipHandler.TipRegion(rect, () => GetPawnMassTip(trad, 0f, mass - gearMass - invMass, gearMass, invMass), trad.GetHashCode() * 59);
                    }
                    else
                    {
                        TooltipHandler.TipRegion(rect, "ItemWeightTip".Translate());
                    }
                }
                if (mass > availableMass)
                {
                    GUI.color = ColoredText.RedReadable;
                }
                else
                {
                    GUI.color = TransferableOneWayWidget.ItemMassColor;
                }
                Widgets.Label(rect, mass.ToStringMass());
            }
            else
            {
                float cap      = MassUtility.Capacity(pawn, null);
                float gearMass = MassUtility.GearMass(pawn);
                float invMass  = InventoryCalculatorsUtility.ShouldIgnoreInventoryOf(pawn, ignorePawnInventoryMass) ? 0f : MassUtility.InventoryMass(pawn);
                float num      = cap - gearMass - invMass;
                if (num > 0f)
                {
                    GUI.color = Color.green;
                }
                else if (num < 0f)
                {
                    GUI.color = ColoredText.RedReadable;
                }
                else
                {
                    GUI.color = Color.gray;
                }
                Widgets.Label(rect, num.ToStringMassOffset());
                if (Mouse.IsOver(rect))
                {
                    TooltipHandler.TipRegion(rect, () => GetPawnMassTip(trad, cap, 0f, gearMass, invMass), trad.GetHashCode() * 59);
                }
            }
            GUI.color = Color.white;
        }
Example #21
0
        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);
        }
        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);
        }
Example #23
0
        public static bool DrawThingRow(Pawn SelPawn, bool CanControl, ref float y, ref float width, Thing thing, bool inventory)
        {
            Color hColor = new Color(1f, 0.8f, 0.8f, 1f);

            bool IsBiocodedOrLinked(Pawn pawn, Thing athing, bool ainventory)
            {
                if (pawn.IsQuestLodger())
                {
                    if (ainventory)
                    {
                        return(true);
                    }
                    else
                    {
                        CompBiocodable compBiocodable = athing.TryGetComp <CompBiocodable>();
                        if (compBiocodable != null && compBiocodable.Biocoded)
                        {
                            return(true);
                        }
                        else
                        {
                            CompBladelinkWeapon compBladelinkWeapon = athing.TryGetComp <CompBladelinkWeapon>();
                            return(compBladelinkWeapon != null && compBladelinkWeapon.bondedPawn == pawn);
                        }
                    }
                }
                else
                {
                    return(false);
                }
            }

            bool IsLocked(Pawn pawn, Thing athing)
            {
                Apparel apparel;

                return((apparel = (athing as Apparel)) != null && pawn.apparel != null && pawn.apparel.IsLocked(apparel));
            }

            if (!Settings.gui_manual_unload)
            {
                return(true);
            }

            Rect rect = new Rect(0f, y, width, 28f);

            if (CanControl &&
                (SelPawn.IsColonistPlayerControlled || SelPawn.Spawned && !SelPawn.Map.IsPlayerHome) &&
                (thing is ThingWithComps) &&
                !IsBiocodedOrLinked(SelPawn, thing, inventory) &&
                !IsLocked(SelPawn, thing))
            {
                Rect rect2          = new Rect(rect.width - 24f, y, 24f, 24f);
                CompUnloadChecker c = CompUnloadChecker.GetChecker(thing, false, true);
                if (c.ShouldUnload)
                {
                    TooltipHandler.TipRegion(rect2, "UnloadThingCancel".Translate());

                    //weird shenanigans with colors
                    var cl = GUI.color;
                    if (Widgets.ButtonImage(rect2, ContentFinder <Texture2D> .Get("UI/Icons/Unload_Thing_Cancel"), hColor))
                    {
                        SoundDefOf.Tick_High.PlayOneShotOnCamera(null);
                        c.ShouldUnload = false;

                        if (MassUtility.Capacity(SelPawn, null) < MassUtility.GearAndInventoryMass(SelPawn) &&
                            thing.stackCount * thing.GetStatValue(StatDefOf.Mass, true) > 0 &&
                            !thing.def.destroyOnDrop)
                        {
                            Thing t;
                            SelPawn.inventory.innerContainer.TryDrop(thing, SelPawn.Position, SelPawn.Map, ThingPlaceMode.Near, out t, null, null);
                        }
                    }
                    GUI.color = cl;
                }
                else
                {
                    TooltipHandler.TipRegion(rect2, "UnloadThing".Translate());
                    if (Widgets.ButtonImage(rect2, ContentFinder <Texture2D> .Get("UI/Icons/Unload_Thing")))
                    {
                        SoundDefOf.Tick_High.PlayOneShotOnCamera(null);
                        c.ShouldUnload = true;
                    }
                }
                width -= 24f;
            }
            return(true);
        }
Example #24
0
            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);
            }