Exemple #1
0
        public override void DoWindowContents(Rect windowRect)
        {
            MapComponent_AutoEquip mapComponent  = MapComponent_AutoEquip.Get;
            PawnCalcForApparel     pawnAutoEquip = new PawnCalcForApparel(mapComponent.GetCache(this.pawn));
            List <Apparel>         allApparels   = new List <Apparel>(Find.ListerThings.ThingsInGroup(ThingRequestGroup.Apparel).OfType <Apparel>());

            foreach (Pawn pawn in Find.ListerPawns.FreeColonists)
            {
                foreach (Apparel pawnApparel in pawn.apparel.WornApparel)
                {
                    if (pawn.outfits.forcedHandler.AllowedToAutomaticallyDrop(pawnApparel))
                    {
                        allApparels.Add(pawnApparel);
                    }
                }
            }

            allApparels = allApparels.Where(i => !ApparelUtility.CanWearTogether(this.apparel.def, i.def)).ToList();

            Rect groupRect = windowRect.ContractedBy(10f);

            groupRect.height -= 100;
            GUI.BeginGroup(groupRect);

            float apparelScoreWidth   = 100f;
            float apparelGainWidth    = 100f;
            float apparelLabelWidth   = (groupRect.width - apparelScoreWidth - apparelGainWidth) / 3 - 8f - 8f;
            float apparelEquipedWidth = apparelLabelWidth;
            float apparelOwnerWidth   = apparelLabelWidth;

            Rect itemRect = new Rect(groupRect.xMin + 4f, groupRect.yMin, groupRect.width - 8f, 28f);

            this.DrawLine(ref itemRect,
                          null, "Apparel", apparelLabelWidth,
                          null, "Equiped", apparelEquipedWidth,
                          null, "Target", apparelOwnerWidth,
                          "Score", apparelScoreWidth,
                          "Gain", apparelGainWidth);

            groupRect.yMin += itemRect.height;
            Widgets.DrawLineHorizontal(groupRect.xMin, groupRect.yMin, groupRect.width);
            groupRect.yMin   += 4f;
            groupRect.height -= 4f;
            groupRect.height -= Text.LineHeight * 1.2f * 3f;

            Rect viewRect = new Rect(groupRect.xMin, groupRect.yMin, groupRect.width - 16f, allApparels.Count() * 28f + 16f);

            if (viewRect.height < groupRect.height)
            {
                groupRect.height = viewRect.height;
            }

            Rect listRect = viewRect.ContractedBy(4f);

            Widgets.BeginScrollView(groupRect, ref scrollPosition, viewRect);

            allApparels = allApparels.OrderByDescending(i => { float g; if (pawnAutoEquip.CalculateApparelScoreGain(i, out g))
                                                               {
                                                                   return(g);
                                                               }
                                                               return(-1000f); }).ToList();

            foreach (Apparel currentAppel in allApparels)
            {
                itemRect = new Rect(listRect.xMin, listRect.yMin, listRect.width, 28f);
                if (Mouse.IsOver(itemRect))
                {
                    GUI.color = ITab_Pawn_AutoEquip.HighlightColor;
                    GUI.DrawTexture(itemRect, TexUI.HighlightTex);
                    GUI.color = Color.white;
                }

                Pawn equiped = null;
                Pawn target  = null;

                foreach (Pawn pawn in Find.ListerPawns.FreeColonists)
                {
                    foreach (Apparel a in pawn.apparel.WornApparel)
                    {
                        if (a == currentAppel)
                        {
                            equiped = pawn;
                            break;
                        }
                    }

                    foreach (Apparel a in mapComponent.GetCache(pawn).targetApparel)
                    {
                        if (a == currentAppel)
                        {
                            target = pawn;
                            break;
                        }
                    }

                    if ((equiped != null) &&
                        (target != null))
                    {
                        break;
                    }
                }

                float gain;
                if (pawnAutoEquip.CalculateApparelScoreGain(currentAppel, out gain))
                {
                    this.DrawLine(ref itemRect,
                                  currentAppel, currentAppel.LabelCap, apparelLabelWidth,
                                  equiped, equiped == null ? null : equiped.LabelCap, apparelEquipedWidth,
                                  target, target == null ? null : target.LabelCap, apparelOwnerWidth,
                                  pawnAutoEquip.CalculateApparelScoreRaw(currentAppel).ToString("N5"), apparelScoreWidth,
                                  gain.ToString("N5"), apparelGainWidth);
                }
                else
                {
                    this.DrawLine(ref itemRect,
                                  currentAppel, currentAppel.LabelCap, apparelLabelWidth,
                                  equiped, equiped == null ? null : equiped.LabelCap, apparelEquipedWidth,
                                  target, target == null ? null : target.LabelCap, apparelOwnerWidth,
                                  pawnAutoEquip.CalculateApparelScoreRaw(currentAppel).ToString("N5"), apparelScoreWidth,
                                  "No Allow", apparelGainWidth);
                }

                listRect.yMin = itemRect.yMax;
            }

            Widgets.EndScrollView();

            Widgets.DrawLineHorizontal(groupRect.xMin, groupRect.yMax, groupRect.width);

            GUI.color   = Color.white;
            Text.Anchor = TextAnchor.UpperLeft;
            GUI.EndGroup();
        }
		public static void Postfix(Vector3 clickPos, Pawn pawn, List<FloatMenuOption> opts)
		{
			IntVec3 c = IntVec3.FromVector3(clickPos);
			if (pawn.equipment != null) {
				//First equipment already handled by patched Method, so skip
				var equipmentList = c.GetThingList(pawn.Map).Where(t => t.TryGetComp<CompEquippable>() != null).OfType<ThingWithComps>().Skip(1);

				//Log.Message(string.Format("Adding {0:d} equipment orders", equipmentList.Count()));

				foreach (ThingWithComps equipment in equipmentList) {
					string labelShort = equipment.LabelShort;
					FloatMenuOption item3;
					if (equipment.def.IsWeapon && pawn.story.WorkTagIsDisabled(WorkTags.Violent)) {
						item3 = new FloatMenuOption("CannotEquip".Translate(new object[] {
							labelShort
						}) + " (" + "IsIncapableOfViolenceLower".Translate(new object[] {
							pawn.LabelShort
						}) + ")", null, MenuOptionPriority.Default, null, null, 0f, null, null);
					}
					else if (!pawn.CanReach(equipment, PathEndMode.ClosestTouch, Danger.Deadly, false, TraverseMode.ByPawn)) {
						item3 = new FloatMenuOption("CannotEquip".Translate(new object[] {
							labelShort
						}) + " (" + "NoPath".Translate() + ")", null, MenuOptionPriority.Default, null, null, 0f, null, null);
					}
					else if (!pawn.health.capacities.CapableOf(PawnCapacityDefOf.Manipulation)) {
						item3 = new FloatMenuOption("CannotEquip".Translate(new object[] {
							labelShort
						}) + " (" + "Incapable".Translate() + ")", null, MenuOptionPriority.Default, null, null, 0f, null, null);
					}
					else {
						string text3 = "Equip".Translate(new object[] {
							labelShort
						});
						if (equipment.def.IsRangedWeapon && pawn.story != null && pawn.story.traits.HasTrait(TraitDefOf.Brawler)) {
							text3 = text3 + " " + "EquipWarningBrawler".Translate();
						}
						item3 = FloatMenuUtility.DecoratePrioritizedTask(new FloatMenuOption(text3, delegate {
							equipment.SetForbidden(false, true);
							pawn.jobs.TryTakeOrderedJob(new Job(JobDefOf.Equip, equipment), JobTag.Misc);
							MoteMaker.MakeStaticMote(equipment.DrawPos, equipment.Map, ThingDefOf.Mote_FeedbackEquip, 1f);
							PlayerKnowledgeDatabase.KnowledgeDemonstrated(ConceptDefOf.EquippingWeapons, KnowledgeAmount.Total);
						}, MenuOptionPriority.High, null, null, 0f, null, null), pawn, equipment, "ReservedBy");
					}
					opts.Add(item3);
				}
			}
			if (pawn.apparel != null) {
				//First apparel already handled by patched method, so skip
				var apparelList = c.GetThingList(pawn.Map).OfType<Apparel>().Skip(1);

				//Log.Message(string.Format("Adding {0:d} apparel orders", apparelList.Count()));

				foreach (Apparel apparel in apparelList) {
					FloatMenuOption item4;
					if (!pawn.CanReach(apparel, PathEndMode.ClosestTouch, Danger.Deadly, false, TraverseMode.ByPawn)) {
						item4 = new FloatMenuOption("CannotWear".Translate(new object[] {
							apparel.Label
						}) + " (" + "NoPath".Translate() + ")", null, MenuOptionPriority.Default, null, null, 0f, null, null);
					}
					else if (!ApparelUtility.HasPartsToWear(pawn, apparel.def)) {
						item4 = new FloatMenuOption("CannotWear".Translate(new object[] {
							apparel.Label
						}) + " (" + "CannotWearBecauseOfMissingBodyParts".Translate() + ")", null, MenuOptionPriority.Default, null, null, 0f, null, null);
					}
					else {
						item4 = FloatMenuUtility.DecoratePrioritizedTask(new FloatMenuOption("ForceWear".Translate(new object[] {
							apparel.LabelShort
						}), delegate {
							apparel.SetForbidden(false, true);
							Job job = new Job(JobDefOf.Wear, apparel);
							pawn.jobs.TryTakeOrderedJob(job, JobTag.Misc);
						}, MenuOptionPriority.High, null, null, 0f, null, null), pawn, apparel, "ReservedBy");
					}
					opts.Add(item4);
				}
			}
            AddReservationActionsIfOnlySingleItem(c, pawn.MapHeld, opts);
		}
Exemple #3
0
        internal static void AddHumanlikeOrders(Vector3 clickPos, Pawn pawn, List <FloatMenuOption> opts)
        {
            IntVec3 c2  = IntVec3.FromVector3(clickPos);
            int     num = 0;

            if (pawn.story != null)
            {
                num = pawn.story.traits.DegreeOfTrait(TraitDefOf.DrugDesire);
            }
            foreach (Thing current in c2.GetThingList())
            {
                Thing t = current;
                if (t.def.ingestible != null && pawn.RaceProps.CanEverEat(t) && t.IngestibleNow)
                {
                    FloatMenuOption item;
                    if (t.def.ingestible.isPleasureDrug && num < 0)
                    {
                        item = new FloatMenuOption("ConsumeThing".Translate(new object[]
                        {
                            t.LabelShort
                        }) + " (" + "Teetotaler".Translate() + ")", null, MenuOptionPriority.Medium, null, null, 0f, null);
                    }
                    else if (!pawn.CanReach(t, PathEndMode.OnCell, Danger.Deadly, false, TraverseMode.ByPawn))
                    {
                        item = new FloatMenuOption("ConsumeThing".Translate(new object[]
                        {
                            t.LabelShort
                        }) + " (" + "NoPath".Translate() + ")", null, MenuOptionPriority.Medium, null, null, 0f, null);
                    }
                    else if (!pawn.CanReserve(t, 1))
                    {
                        item = new FloatMenuOption("ConsumeThing".Translate(new object[]
                        {
                            t.LabelShort
                        }) + " (" + "ReservedBy".Translate(new object[]
                        {
                            Find.Reservations.FirstReserverOf(t, pawn.Faction, true).LabelShort
                        }) + ")", null, MenuOptionPriority.Medium, null, null, 0f, null);
                    }
                    else
                    {
                        item = new FloatMenuOption("ConsumeThing".Translate(new object[]
                        {
                            t.LabelShort
                        }), delegate
                        {
                            t.SetForbidden(false, true);
                            Job job           = new Job(JobDefOf.Ingest, t);
                            job.maxNumToCarry = FoodUtility.WillEatStackCountOf(pawn, t.def);
                            pawn.drafter.TakeOrderedJob(job);
                        }, MenuOptionPriority.Medium, null, null, 0f, null);
                    }
                    opts.Add(item);
                }
            }
            if (pawn.health.capacities.CapableOf(PawnCapacityDefOf.Manipulation))
            {
                foreach (TargetInfo current2 in GenUI.TargetsAt(clickPos, TargetingParameters.ForRescue(pawn), true))
                {
                    Pawn victim = (Pawn)current2.Thing;
                    if (!victim.InBed() && pawn.CanReserveAndReach(victim, PathEndMode.OnCell, Danger.Deadly, 1) && !victim.IsPrisonerOfColony)
                    {
                        if ((victim.Faction == Faction.OfPlayer && victim.MentalStateDef == null) || (victim.Faction != Faction.OfPlayer && victim.MentalStateDef == null && !victim.IsPrisonerOfColony && (victim.Faction == null || !victim.Faction.HostileTo(Faction.OfPlayer))))
                        {
                            Pawn victim2 = victim;
                            opts.Add(new FloatMenuOption("Rescue".Translate(new object[]
                            {
                                victim.LabelCap
                            }), delegate
                            {
                                Building_Bed building_Bed = RestUtility.FindBedFor(victim, pawn, false, false, false);
                                if (building_Bed == null)
                                {
                                    string str2;
                                    if (victim.RaceProps.Animal)
                                    {
                                        str2 = "NoAnimalBed".Translate();
                                    }
                                    else
                                    {
                                        str2 = "NoNonPrisonerBed".Translate();
                                    }
                                    Messages.Message("CannotRescue".Translate() + ": " + str2, victim, MessageSound.RejectInput);
                                    return;
                                }
                                Job job           = new Job(JobDefOf.Rescue, victim, building_Bed);
                                job.maxNumToCarry = 1;
                                job.playerForced  = true;
                                pawn.drafter.TakeOrderedJob(job);
                                ConceptDatabase.KnowledgeDemonstrated(ConceptDefOf.Rescuing, KnowledgeAmount.Total);
                            }, MenuOptionPriority.Medium, null, victim2, 0f, null));
                        }
                        if (victim.MentalStateDef != null || (victim.RaceProps.Humanlike && victim.Faction != Faction.OfPlayer))
                        {
                            Pawn victim2 = victim;
                            opts.Add(new FloatMenuOption("Capture".Translate(new object[]
                            {
                                victim.LabelCap
                            }), delegate
                            {
                                Building_Bed building_Bed = RestUtility.FindBedFor(victim, pawn, true, false, false);
                                if (building_Bed == null)
                                {
                                    Messages.Message("CannotCapture".Translate() + ": " + "NoPrisonerBed".Translate(), victim, MessageSound.RejectInput);
                                    return;
                                }
                                Job job           = new Job(JobDefOf.Capture, victim, building_Bed);
                                job.maxNumToCarry = 1;
                                job.playerForced  = true;
                                pawn.drafter.TakeOrderedJob(job);
                                ConceptDatabase.KnowledgeDemonstrated(ConceptDefOf.Capturing, KnowledgeAmount.Total);
                            }, MenuOptionPriority.Medium, null, victim2, 0f, null));
                        }
                    }
                }
                foreach (TargetInfo current3 in GenUI.TargetsAt(clickPos, TargetingParameters.ForRescue(pawn), true))
                {
                    TargetInfo targetInfo = current3;
                    Pawn       victim     = (Pawn)targetInfo.Thing;
                    if (victim.Downed && pawn.CanReserveAndReach(victim, PathEndMode.OnCell, Danger.Deadly, 1) && Building_CryptosleepCasket.FindCryptosleepCasketFor(victim, pawn) != null)
                    {
                        string label = "CarryToCryptosleepCasket".Translate(new object[]
                        {
                            targetInfo.Thing.LabelCap
                        });
                        JobDef jDef   = JobDefOf.CarryToCryptosleepCasket;
                        Action action = delegate
                        {
                            Building_CryptosleepCasket building_CryptosleepCasket = Building_CryptosleepCasket.FindCryptosleepCasketFor(victim, pawn);
                            if (building_CryptosleepCasket == null)
                            {
                                Messages.Message("CannotCarryToCryptosleepCasket".Translate() + ": " + "NoCryptosleepCasket".Translate(), victim, MessageSound.RejectInput);
                                return;
                            }
                            Job job = new Job(jDef, victim, building_CryptosleepCasket);
                            job.maxNumToCarry = 1;
                            job.playerForced  = true;
                            pawn.drafter.TakeOrderedJob(job);
                        };
                        Pawn victim2 = victim;
                        opts.Add(new FloatMenuOption(label, action, MenuOptionPriority.Medium, null, victim2, 0f, null));
                    }
                }
            }
            foreach (TargetInfo current4 in GenUI.TargetsAt(clickPos, TargetingParameters.ForStrip(pawn), true))
            {
                TargetInfo      stripTarg = current4;
                FloatMenuOption item2;
                if (!pawn.CanReach(stripTarg, PathEndMode.ClosestTouch, Danger.Deadly, false, TraverseMode.ByPawn))
                {
                    item2 = new FloatMenuOption("CannotStrip".Translate(new object[]
                    {
                        stripTarg.Thing.LabelCap
                    }) + " (" + "NoPath".Translate() + ")", null, MenuOptionPriority.Medium, null, null, 0f, null);
                }
                else if (!pawn.CanReserveAndReach(stripTarg, PathEndMode.ClosestTouch, Danger.Deadly, 1))
                {
                    item2 = new FloatMenuOption("CannotStrip".Translate(new object[]
                    {
                        stripTarg.Thing.LabelCap
                    }) + " (" + "ReservedBy".Translate(new object[]
                    {
                        Find.Reservations.FirstReserverOf(stripTarg, pawn.Faction, true).LabelShort
                    }) + ")", null, MenuOptionPriority.Medium, null, null, 0f, null);
                }
                else
                {
                    item2 = new FloatMenuOption("Strip".Translate(new object[]
                    {
                        stripTarg.Thing.LabelCap
                    }), delegate
                    {
                        stripTarg.Thing.SetForbidden(false, false);
                        Job job          = new Job(JobDefOf.Strip, stripTarg);
                        job.playerForced = true;
                        pawn.drafter.TakeOrderedJob(job);
                    }, MenuOptionPriority.Medium, null, null, 0f, null);
                }
                opts.Add(item2);
            }


            CompInventory compInventory = pawn.TryGetComp <CompInventory>();      // Need compInventory here for equip and wear options

            if (pawn.equipment != null)
            {
                ThingWithComps equipment = null;
                List <Thing>   thingList = c2.GetThingList();
                for (int i = 0; i < thingList.Count; i++)
                {
                    if (thingList[i].TryGetComp <CompEquippable>() != null)
                    {
                        equipment = (ThingWithComps)thingList[i];
                        break;
                    }
                }
                if (equipment != null)
                {
                    string          label2 = equipment.Label;
                    FloatMenuOption item3;
                    if (!pawn.CanReach(equipment, PathEndMode.ClosestTouch, Danger.Deadly, false, TraverseMode.ByPawn))
                    {
                        item3 = new FloatMenuOption("CannotEquip".Translate(new object[]
                        {
                            label2
                        }) + " (" + "NoPath".Translate() + ")", null, MenuOptionPriority.Medium, null, null, 0f, null);
                    }
                    else if (!pawn.CanReserve(equipment, 1))
                    {
                        item3 = new FloatMenuOption("CannotEquip".Translate(new object[]
                        {
                            label2
                        }) + " (" + "ReservedBy".Translate(new object[]
                        {
                            Find.Reservations.FirstReserverOf(equipment, pawn.Faction, true).LabelShort
                        }) + ")", null, MenuOptionPriority.Medium, null, null, 0f, null);
                    }
                    else if (!pawn.health.capacities.CapableOf(PawnCapacityDefOf.Manipulation))
                    {
                        item3 = new FloatMenuOption("CannotEquip".Translate(new object[]
                        {
                            label2
                        }) + " (" + "Incapable".Translate() + ")", null, MenuOptionPriority.Medium, null, null, 0f, null);
                    }
                    else
                    {
                        string text = "Equip".Translate(new object[]
                        {
                            label2
                        });
                        if (equipment.def.IsRangedWeapon && pawn.story != null && pawn.story.traits.HasTrait(TraitDefOf.Brawler))
                        {
                            text = text + " " + "EquipWarningBrawler".Translate();
                        }
                        item3 = new FloatMenuOption(text, delegate
                        {
                            equipment.SetForbidden(false, true);
                            Job job          = new Job(JobDefOf.Equip, equipment);
                            job.playerForced = true;
                            pawn.drafter.TakeOrderedJob(job);
                            MoteThrower.ThrowStatic(equipment.DrawPos, ThingDefOf.Mote_FeedbackEquip, 1f);
                            ConceptDatabase.KnowledgeDemonstrated(ConceptDefOf.EquippingWeapons, KnowledgeAmount.Total);
                        }, MenuOptionPriority.Medium, null, null, 0f, null);
                    }
                    opts.Add(item3);
                }
            }
            if (pawn.apparel != null)
            {
                Apparel apparel = Find.ThingGrid.ThingAt <Apparel>(c2);
                if (apparel != null)
                {
                    FloatMenuOption item4;
                    if (!pawn.CanReach(apparel, PathEndMode.ClosestTouch, Danger.Deadly, false, TraverseMode.ByPawn))
                    {
                        item4 = new FloatMenuOption("CannotWear".Translate(new object[]
                        {
                            apparel.Label
                        }) + " (" + "NoPath".Translate() + ")", null, MenuOptionPriority.Medium, null, null, 0f, null);
                    }
                    else if (!pawn.CanReserve(apparel, 1))
                    {
                        Pawn pawn2 = Find.Reservations.FirstReserverOf(apparel, pawn.Faction, true);
                        item4 = new FloatMenuOption("CannotWear".Translate(new object[]
                        {
                            apparel.Label
                        }) + " (" + "ReservedBy".Translate(new object[]
                        {
                            pawn2.LabelShort
                        }) + ")", null, MenuOptionPriority.Medium, null, null, 0f, null);
                    }
                    else if (!ApparelUtility.HasPartsToWear(pawn, apparel.def))
                    {
                        item4 = new FloatMenuOption("CannotWear".Translate(new object[]
                        {
                            apparel.Label
                        }) + " (" + "CannotWearBecauseOfMissingBodyParts".Translate() + ")", null, MenuOptionPriority.Medium, null, null, 0f, null);
                    }
                    else
                    {
                        // Added check for inventory capacity
                        int count;
                        if (compInventory != null && !compInventory.CanFitInInventory(apparel, out count, false, true))
                        {
                            item4 = new FloatMenuOption("CannotWear".Translate(new object[] { apparel.Label }) + " (" + "CR_InventoryFull".Translate() + ")", null);
                        }
                        else
                        {
                            item4 = new FloatMenuOption("ForceWear".Translate(new object[] { apparel.LabelShort }),
                                                        new Action(delegate
                            {
                                apparel.SetForbidden(false, true);
                                Job job          = new Job(JobDefOf.Wear, apparel);
                                job.playerForced = true;
                                pawn.drafter.TakeOrderedJob(job);
                            }),
                                                        MenuOptionPriority.Medium, null, null);
                        }
                    }
                    opts.Add(item4);
                }
            }


            // *** NEW: Pick up option ***
            if (compInventory != null)
            {
                List <Thing> thingList = c2.GetThingList();
                if (!thingList.NullOrEmpty <Thing>())
                {
                    Thing item = thingList.FirstOrDefault(thing => thing.def.alwaysHaulable && !(thing is Corpse));
                    if (item != null)
                    {
                        FloatMenuOption pickUpOption;
                        int             count = 0;
                        if (!pawn.CanReach(item, PathEndMode.Touch, Danger.Deadly))
                        {
                            pickUpOption = new FloatMenuOption("CR_CannotPickUp".Translate() + " " + item.LabelShort + " (" + "NoPath".Translate() + ")", null);
                        }
                        else if (!pawn.CanReserve(item))
                        {
                            pickUpOption = new FloatMenuOption("CR_CannotPickUp".Translate() + " " + item.LabelShort + " (" + "ReservedBy".Translate(new object[] { Find.Reservations.FirstReserverOf(item, pawn.Faction) }), null);
                        }
                        else if (!compInventory.CanFitInInventory(item, out count))
                        {
                            pickUpOption = new FloatMenuOption("CR_CannotPickUp".Translate() + " " + item.LabelShort + " (" + "CR_InventoryFull".Translate() + ")", null);
                        }
                        else
                        {
                            pickUpOption = new FloatMenuOption("CR_PickUp".Translate() + " " + item.LabelShort,
                                                               new Action(delegate
                            {
                                item.SetForbidden(false);
                                Job job = new Job(JobDefOf.TakeInventory, item)
                                {
                                    maxNumToCarry = 1
                                };
                                job.playerForced = true;
                                pawn.drafter.TakeOrderedJob(job);
                            }));
                        }
                        opts.Add(pickUpOption);
                        if (count > 1 && item.stackCount > 1)
                        {
                            int             numToCarry        = Math.Min(count, item.stackCount);
                            FloatMenuOption pickUpStackOption = new FloatMenuOption("CR_PickUp".Translate() + " " + item.LabelShort + " x" + numToCarry.ToString(),
                                                                                    new Action(delegate
                            {
                                item.SetForbidden(false);
                                Job job = new Job(JobDefOf.TakeInventory, item)
                                {
                                    maxNumToCarry = numToCarry
                                };
                                job.playerForced = true;
                                pawn.drafter.TakeOrderedJob(job);
                            }));
                            opts.Add(pickUpStackOption);

                            FloatMenuOption pickUpHalfStackOption = new FloatMenuOption("CE_PickUpHalf" + " " + item.LabelShort + " x" + (numToCarry / 2).ToString(),
                                                                                        new Action(delegate
                            {
                                item.SetForbidden(false);
                                Job job = new Job(JobDefOf.TakeInventory, item)
                                {
                                    maxNumToCarry = numToCarry / 2
                                };
                                job.playerForced = true;
                                pawn.drafter.TakeOrderedJob(job);
                            }));
                            opts.Add(pickUpHalfStackOption);
                        }
                    }
                }
            }

            if (pawn.equipment != null && pawn.equipment.Primary != null)
            {
                Thing thing = Find.ThingGrid.ThingAt(c2, ThingDefOf.EquipmentRack);
                if (thing != null)
                {
                    if (!pawn.CanReach(thing, PathEndMode.ClosestTouch, Danger.Deadly, false, TraverseMode.ByPawn))
                    {
                        opts.Add(new FloatMenuOption("CannotDeposit".Translate(new object[]
                        {
                            pawn.equipment.Primary.LabelCap,
                            thing.def.label
                        }) + " (" + "NoPath".Translate() + ")", null, MenuOptionPriority.Medium, null, null, 0f, null));
                    }
                    else
                    {
                        foreach (IntVec3 c in GenAdj.CellsOccupiedBy(thing))
                        {
                            if (c.GetStorable() == null && pawn.CanReserveAndReach(c, PathEndMode.ClosestTouch, Danger.Deadly, 1))
                            {
                                Action action2 = delegate
                                {
                                    ThingWithComps t;
                                    if (pawn.equipment.TryDropEquipment(pawn.equipment.Primary, out t, pawn.Position, true))
                                    {
                                        t.SetForbidden(false, true);
                                        Job job = new Job(JobDefOf.HaulToCell, t, c);
                                        job.haulMode      = HaulMode.ToCellStorage;
                                        job.maxNumToCarry = 1;
                                        job.playerForced  = true;
                                        pawn.drafter.TakeOrderedJob(job);
                                    }
                                };
                                opts.Add(new FloatMenuOption("Deposit".Translate(new object[]
                                {
                                    pawn.equipment.Primary.LabelCap,
                                    thing.def.label
                                }), action2, MenuOptionPriority.Medium, null, null, 0f, null));
                                break;
                            }
                        }
                    }
                }
                if (pawn.equipment != null && GenUI.TargetsAt(clickPos, TargetingParameters.ForSelf(pawn), true).Any <TargetInfo>())
                {
                    Action action3 = delegate
                    {
                        ThingWithComps thingWithComps;
                        pawn.equipment.TryDropEquipment(pawn.equipment.Primary, out thingWithComps, pawn.Position, true);
                        pawn.drafter.TakeOrderedJob(new Job(JobDefOf.Wait, 20, false));
                    };
                    opts.Add(new FloatMenuOption("Drop".Translate(new object[]
                    {
                        pawn.equipment.Primary.Label
                    }), action3, MenuOptionPriority.Medium, null, null, 0f, null));
                }
            }
            foreach (TargetInfo current5 in GenUI.TargetsAt(clickPos, TargetingParameters.ForTrade(), true))
            {
                TargetInfo dest = current5;
                if (!pawn.CanReach(dest, PathEndMode.OnCell, Danger.Deadly, false, TraverseMode.ByPawn))
                {
                    opts.Add(new FloatMenuOption("CannotTrade".Translate() + " (" + "NoPath".Translate() + ")", null, MenuOptionPriority.Medium, null, null, 0f, null));
                }
                else if (!pawn.CanReserve(dest.Thing, 1))
                {
                    opts.Add(new FloatMenuOption("CannotTrade".Translate() + " (" + "Reserved".Translate() + ")", null, MenuOptionPriority.Medium, null, null, 0f, null));
                }
                else
                {
                    Pawn   pTarg   = (Pawn)dest.Thing;
                    Action action4 = delegate
                    {
                        Job job = new Job(JobDefOf.TradeWithPawn, pTarg);
                        job.playerForced = true;
                        pawn.drafter.TakeOrderedJob(job);
                        ConceptDatabase.KnowledgeDemonstrated(ConceptDefOf.InteractingWithTraders, KnowledgeAmount.Total);
                    };
                    string str = string.Empty;
                    if (pTarg.Faction != null)
                    {
                        str = " (" + pTarg.Faction.Name + ")";
                    }
                    Thing thing2 = dest.Thing;
                    opts.Add(new FloatMenuOption("TradeWith".Translate(new object[]
                    {
                        pTarg.LabelShort
                    }) + str, action4, MenuOptionPriority.Medium, null, thing2, 0f, null));
                }
            }
            foreach (Thing current6 in Find.ThingGrid.ThingsAt(c2))
            {
                foreach (FloatMenuOption current7 in current6.GetFloatMenuOptions(pawn))
                {
                    opts.Add(current7);
                }
            }
        }
        protected override IEnumerable <Toil> MakeNewToils()
        {
            foreach (var toil in base.MakeNewToils())
            {
                yield return(toil);
            }
            yield return(new Toil()
            {
                initAction = delegate
                {
                    var armorRack = TargetThingA as ArmorRack;
                    var storedRackApparel = new List <Apparel>(armorRack.GetStoredApparel());
                    var storedRackWeapon = armorRack.GetStoredWeapon();
                    var storedPawnWeapon = pawn.equipment.Primary;
                    armorRack.InnerContainer.Clear();

                    foreach (Apparel rackApparel in storedRackApparel)
                    {
                        if (!ApparelUtility.HasPartsToWear(pawn, rackApparel.def))
                        {
                            Thing lastRemovedThing = null;
                            GenPlace.TryPlaceThing(rackApparel, armorRack.Position, armorRack.Map, ThingPlaceMode.Near, out lastRemovedThing);
                            continue;
                        }
                        if (!pawn.apparel.CanWearWithoutDroppingAnything(rackApparel.def))
                        {
                            var storedPawnApparel = new List <Apparel>(pawn.apparel.WornApparel);
                            foreach (var pawnApparel in storedPawnApparel)
                            {
                                if (!ApparelUtility.CanWearTogether(rackApparel.def, pawnApparel.def, armorRack.PawnKindDef.RaceProps.body))
                                {
                                    pawn.apparel.Remove(pawnApparel);
                                    armorRack.InnerContainer.TryAdd(pawnApparel);
                                }
                            }
                        }
                        pawn.apparel.Wear(rackApparel);
                        if (EquipSetForced())
                        {
                            pawn.outfits.forcedHandler.SetForced(rackApparel, true);
                        }
                    }

                    int hasRackWeapon = storedRackWeapon == null ? 0x00 : 0x01;
                    int hasPawnWeapon = storedPawnWeapon == null ? 0x00 : 0x10;
                    switch (hasRackWeapon | hasPawnWeapon)
                    {
                    case 0x11:
                        {
                            pawn.equipment.Remove(storedPawnWeapon);
                            armorRack.InnerContainer.TryAdd(storedPawnWeapon);
                            pawn.equipment.MakeRoomFor((ThingWithComps)storedRackWeapon);
                            pawn.equipment.AddEquipment((ThingWithComps)storedRackWeapon);
                            break;
                        }

                    case 0x01:
                        pawn.equipment.MakeRoomFor((ThingWithComps)storedRackWeapon);
                        pawn.equipment.AddEquipment((ThingWithComps)storedRackWeapon);
                        break;

                    case 0x10:
                        {
                            break;
                        }
                    }
                    ForbidUtility.SetForbidden(TargetThingA, true);
                    var useComp = pawn.GetComp <ArmorRackUseCommandComp>();
                    if (useComp != null)
                    {
                        useComp.CurArmorRackJobDef = ArmorRacksJobDefOf.ArmorRacks_JobTransferToRack;
                    }
                }
            });
        }
Exemple #5
0
        private Apparel FindGarmentCoveringPart(Pawn pawn, BodyPartGroupDef bodyPartGroupDef)
        {
            Room room = pawn.GetRoom();
            Predicate <Thing> validator = (Thing t) => pawn.CanReserve(t, 1) &&
                                          pawn.CanReach(t, PathEndMode.Touch, Danger.Deadly, true) &&
                                          (t.Position.DistanceToSquared(pawn.Position) < 12f || room == RoomQuery.RoomAtFast(t.Position, t.Map));
            List <Thing> aList = (
                from t in pawn.Map.listerThings.ThingsInGroup(ThingRequestGroup.Apparel)
                orderby t.MarketValue - t.Position.DistanceToSquared(pawn.Position) * 2f descending
                where validator(t)
                select t
                ).ToList();

            foreach (Thing current in aList)
            {
                Apparel ap = current as Apparel;
                if (ap != null && ap.def.apparel.bodyPartGroups.Contains(bodyPartGroupDef) && pawn.CanReserve(ap, 1) && ApparelUtility.HasPartsToWear(pawn, ap.def))
                {
                    return(ap);
                }
            }
            return(null);
        }
Exemple #6
0
        // Decompiled code is painful to read... Continue at your own risk
        public static List <FloatMenuOption> ChoicesForThing(Thing thing, Pawn pawn)
        {
            List <FloatMenuOption> opts = new List <FloatMenuOption>();
            Thing t = thing;


            // Copied from FloatMenuMakerMap.AddHumanlikeOrders
            if (t.def.ingestible != null && pawn.RaceProps.CanEverEat(t) && t.IngestibleNow)
            {
                string text;
                if (t.def.ingestible.ingestCommandString.NullOrEmpty())
                {
                    text = "ConsumeThing".Translate(t.LabelShort, t);
                }
                else
                {
                    text = string.Format(t.def.ingestible.ingestCommandString, t.LabelShort);
                }
                if (!t.IsSociallyProper(pawn))
                {
                    text = text + " (" + "ReservedForPrisoners".Translate() + ")";
                }
                FloatMenuOption item7;
                if (t.def.IsNonMedicalDrug && pawn.IsTeetotaler())
                {
                    item7 = new FloatMenuOption(text + " (" + TraitDefOf.DrugDesire.DataAtDegree(-1).label + ")", null, MenuOptionPriority.Default, null, null, 0f, null, null);
                }
                else if (!pawn.CanReach(t, PathEndMode.OnCell, Danger.Deadly, false, TraverseMode.ByPawn))
                {
                    item7 = new FloatMenuOption(text + " (" + "NoPath".Translate() + ")", null, MenuOptionPriority.Default, null, null, 0f, null, null);
                }
                else
                {
                    MenuOptionPriority priority2 = (!(t is Corpse)) ? MenuOptionPriority.Default : MenuOptionPriority.Low;
                    item7 = FloatMenuUtility.DecoratePrioritizedTask(new FloatMenuOption(text, delegate()
                    {
                        t.SetForbidden(false, true);
                        Job job   = new Job(JobDefOf.Ingest, t);
                        job.count = FoodUtility.WillIngestStackCountOf(pawn, t.def, t.GetStatValue(StatDefOf.Nutrition, true));
                        pawn.jobs.TryTakeOrderedJob(job, JobTag.Misc);
                    }, priority2, null, null, 0f, null, null), pawn, t, "ReservedBy");
                }
                opts.Add(item7);
            }


            // Add equipment commands
            // Copied from FloatMenuMakerMap.AddHumanlikeOrders
            if (thing is ThingWithComps equipment && equipment.GetComp <CompEquippable>() != null)
            {
                string          labelShort = equipment.LabelShort;
                FloatMenuOption item4;
                if (equipment.def.IsWeapon && pawn.WorkTagIsDisabled(WorkTags.Violent))
                {
                    item4 = new FloatMenuOption("CannotEquip".Translate(labelShort) + " (" + "IsIncapableOfViolenceLower".Translate(pawn.LabelShort, pawn) + ")", null, MenuOptionPriority.Default, null, null, 0f, null, null);
                }
                else if (!pawn.CanReach(equipment, PathEndMode.ClosestTouch, Danger.Deadly, false, TraverseMode.ByPawn))
                {
                    item4 = new FloatMenuOption("CannotEquip".Translate(labelShort) + " (" + "NoPath".Translate() + ")", null, MenuOptionPriority.Default, null, null, 0f, null, null);
                }
                else if (!pawn.health.capacities.CapableOf(PawnCapacityDefOf.Manipulation))
                {
                    item4 = new FloatMenuOption("CannotEquip".Translate(labelShort) + " (" + "Incapable".Translate() + ")", null, MenuOptionPriority.Default, null, null, 0f, null, null);
                }
                else
                {
                    string text5 = "Equip".Translate(labelShort);
                    if (equipment.def.IsRangedWeapon && pawn.story != null && pawn.story.traits.HasTrait(TraitDefOf.Brawler))
                    {
                        text5 = text5 + " " + "EquipWarningBrawler".Translate();
                    }
                    item4 = FloatMenuUtility.DecoratePrioritizedTask(new FloatMenuOption(text5, delegate()
                    {
                        equipment.SetForbidden(false, true);
                        pawn.jobs.TryTakeOrderedJob(new Job(JobDefOf.Equip, equipment), JobTag.Misc);
                        MoteMaker.MakeStaticMote(equipment.DrawPos, equipment.Map, ThingDefOf.Mote_FeedbackEquip, 1f);
                        PlayerKnowledgeDatabase.KnowledgeDemonstrated(ConceptDefOf.EquippingWeapons, KnowledgeAmount.Total);
                    }, MenuOptionPriority.High, null, null, 0f, null, null), pawn, equipment, "ReservedBy");
                }
                opts.Add(item4);
            }

            // Add clothing commands
            Apparel apparel = thing as Apparel;

            if (apparel != null)
            {
                FloatMenuOption item5;
                if (!pawn.CanReach(apparel, PathEndMode.ClosestTouch, Danger.Deadly, false, TraverseMode.ByPawn))
                {
                    item5 = new FloatMenuOption("CannotWear".Translate(apparel.Label, apparel) + " (" + "NoPath".Translate() + ")", null, MenuOptionPriority.Default, null, null, 0f, null, null);
                }
                else if (!ApparelUtility.HasPartsToWear(pawn, apparel.def))
                {
                    item5 = new FloatMenuOption("CannotWear".Translate(apparel.Label, apparel) + " (" + "CannotWearBecauseOfMissingBodyParts".Translate() + ")", null, MenuOptionPriority.Default, null, null, 0f, null, null);
                }
                else
                {
                    item5 = FloatMenuUtility.DecoratePrioritizedTask(new FloatMenuOption("ForceWear".Translate(apparel.LabelShort, apparel), delegate()
                    {
                        apparel.SetForbidden(false, true);
                        Job job = new Job(JobDefOf.Wear, apparel);
                        pawn.jobs.TryTakeOrderedJob(job, JobTag.Misc);
                    }, MenuOptionPriority.High, null, null, 0f, null, null), pawn, apparel, "ReservedBy");
                }
                opts.Add(item5);
            }

            // Add caravan commands

            if (pawn.IsFormingCaravan())
            {
                if (thing != null && thing.def.EverHaulable)
                {
                    Pawn   packTarget = GiveToPackAnimalUtility.UsablePackAnimalWithTheMostFreeSpace(pawn) ?? pawn;
                    JobDef jobDef     = (packTarget != pawn) ? JobDefOf.GiveToPackAnimal : JobDefOf.TakeInventory;
                    if (!pawn.CanReach(thing, PathEndMode.ClosestTouch, Danger.Deadly, false, TraverseMode.ByPawn))
                    {
                        opts.Add(new FloatMenuOption("CannotLoadIntoCaravan".Translate(thing.Label, thing) + " (" + "NoPath".Translate() + ")", null, MenuOptionPriority.Default, null, null, 0f, null, null));
                    }
                    else if (MassUtility.WillBeOverEncumberedAfterPickingUp(packTarget, thing, 1))
                    {
                        opts.Add(new FloatMenuOption("CannotLoadIntoCaravan".Translate(thing.Label, thing) + " (" + "TooHeavy".Translate() + ")", null, MenuOptionPriority.Default, null, null, 0f, null, null));
                    }
                    else
                    {
                        LordJob_FormAndSendCaravan lordJob = (LordJob_FormAndSendCaravan)pawn.GetLord().LordJob;
                        float capacityLeft = CaravanFormingUtility.CapacityLeft(lordJob);
                        if (thing.stackCount == 1)
                        {
                            float capacityLeft4 = capacityLeft - thing.GetStatValue(StatDefOf.Mass, true);
                            opts.Add(FloatMenuUtility.DecoratePrioritizedTask(new FloatMenuOption(CaravanFormingUtility.AppendOverweightInfo("LoadIntoCaravan".Translate(thing.Label, thing), capacityLeft4), delegate()
                            {
                                thing.SetForbidden(false, false);
                                Job job              = new Job(jobDef, thing);
                                job.count            = 1;
                                job.checkEncumbrance = (packTarget == pawn);
                                pawn.jobs.TryTakeOrderedJob(job, JobTag.Misc);
                            }, MenuOptionPriority.High, null, null, 0f, null, null), pawn, thing, "ReservedBy"));
                        }
                        else
                        {
                            if (MassUtility.WillBeOverEncumberedAfterPickingUp(packTarget, thing, thing.stackCount))
                            {
                                opts.Add(new FloatMenuOption("CannotLoadIntoCaravanAll".Translate(thing.Label, thing) + " (" + "TooHeavy".Translate() + ")", null, MenuOptionPriority.Default, null, null, 0f, null, null));
                            }
                            else
                            {
                                float capacityLeft2 = capacityLeft - (float)thing.stackCount * thing.GetStatValue(StatDefOf.Mass, true);
                                opts.Add(FloatMenuUtility.DecoratePrioritizedTask(new FloatMenuOption(CaravanFormingUtility.AppendOverweightInfo("LoadIntoCaravanAll".Translate(thing.Label, thing), capacityLeft2), delegate()
                                {
                                    thing.SetForbidden(false, false);
                                    Job job              = new Job(jobDef, thing);
                                    job.count            = thing.stackCount;
                                    job.checkEncumbrance = (packTarget == pawn);
                                    pawn.jobs.TryTakeOrderedJob(job, JobTag.Misc);
                                }, MenuOptionPriority.High, null, null, 0f, null, null), pawn, thing, "ReservedBy"));
                            }
                            opts.Add(FloatMenuUtility.DecoratePrioritizedTask(new FloatMenuOption("LoadIntoCaravanSome".Translate(thing.LabelNoCount, thing), delegate()
                            {
                                int to = Mathf.Min(MassUtility.CountToPickUpUntilOverEncumbered(packTarget, thing), thing.stackCount);
                                Dialog_Slider window = new Dialog_Slider(delegate(int val)
                                {
                                    float capacityLeft3 = capacityLeft - (float)val * thing.GetStatValue(StatDefOf.Mass, true);
                                    return(CaravanFormingUtility.AppendOverweightInfo(string.Format("LoadIntoCaravanCount".Translate(thing.LabelNoCount, thing), val), capacityLeft3));
                                }, 1, to, delegate(int count)
                                {
                                    thing.SetForbidden(false, false);
                                    Job job              = new Job(jobDef, thing);
                                    job.count            = count;
                                    job.checkEncumbrance = (packTarget == pawn);
                                    pawn.jobs.TryTakeOrderedJob(job, JobTag.Misc);
                                }, int.MinValue);
                                Find.WindowStack.Add(window);
                            }, MenuOptionPriority.High, null, null, 0f, null, null), pawn, thing, "ReservedBy"));
                        }
                    }
                }
            }

            if (opts.Count == 0)
            {
                opts.Add(new FloatMenuOption("NoneBrackets".Translate(), null)
                {
                    Disabled = true
                });
            }
            return(opts);
        }
        public static void AddHumanlikeOrders(Vector3 clickPos, Pawn pawn, List <FloatMenuOption> opts)
        {
            IntVec3 c = IntVec3.FromVector3(clickPos);

            foreach (Thing current in c.GetThingList(pawn.Map))
            {
                Thing t = current;
                if (t.def.ingestible != null && pawn.RaceProps.CanEverEat(t) && t.IngestibleNow)
                {
                    string text;
                    if (t.def.ingestible.ingestCommandString.NullOrEmpty())
                    {
                        text = "ConsumeThing".Translate(new object[]
                        {
                            t.LabelShort
                        });
                    }
                    else
                    {
                        text = string.Format(t.def.ingestible.ingestCommandString, t.LabelShort);
                    }
                    FloatMenuOption item = null;
                    if (t.def.IsPleasureDrug && pawn.story != null && pawn.story.traits.DegreeOfTrait(TraitDefOf.DrugDesire) < 0)
                    {
                        item = new FloatMenuOption(text + " (" + TraitDefOf.DrugDesire.DataAtDegree(-1).label + ")", null, MenuOptionPriority.Default, null, null, 0f, null);
                    }
                    else if (!pawn.CanReach(t, PathEndMode.OnCell, Danger.Deadly, false, TraverseMode.ByPawn))
                    {
                        item = new FloatMenuOption(text + " (" + "NoPath".Translate() + ")", null, MenuOptionPriority.Default, null, null, 0f, null);
                    }
                    else
                    {
                        MenuOptionPriority priority = (!(t is Corpse)) ? MenuOptionPriority.Default : MenuOptionPriority.Low;
                        ITWN.PostMenuOption(opts, pawn, current, text, delegate
                        {
                            t.SetForbidden(false, true);
                            Job job   = new Job(JobDefOf.Ingest, t);
                            job.count = FoodUtility.WillIngestStackCountOf(pawn, t.def);
                            pawn.jobs.TryTakeOrderedJob(job);
                        },
                                            priority: priority);
                    }

                    if (item != null)
                    {
                        opts.Add(item);
                    }
                }
            }
            if (pawn.health.capacities.CapableOf(PawnCapacityDefOf.Manipulation))
            {
                foreach (LocalTargetInfo current2 in GenUI.TargetsAt(clickPos, TargetingParameters.ForRescue(pawn), true))
                {
                    Pawn victim = (Pawn)current2.Thing;
                    if (!victim.InBed() && pawn.CanReach(victim, PathEndMode.OnCell, Danger.Deadly))
                    {
                        if ((victim.Faction == Faction.OfPlayer && victim.MentalStateDef == null) || (victim.Faction != Faction.OfPlayer && victim.MentalStateDef == null && !victim.IsPrisonerOfColony && (victim.Faction == null || !victim.Faction.HostileTo(Faction.OfPlayer))))
                        {
                            Pawn victim2 = victim;
                            ITWN.PostMenuOption(opts, pawn, victim2, "Rescue".Translate(new object[]
                            {
                                victim.LabelCap
                            }), delegate
                            {
                                Building_Bed building_Bed = RestUtility.FindBedFor(victim, pawn, false, false, false);
                                if (building_Bed == null)
                                {
                                    string str2;
                                    if (victim.RaceProps.Animal)
                                    {
                                        str2 = "NoAnimalBed".Translate();
                                    }
                                    else
                                    {
                                        str2 = "NoNonPrisonerBed".Translate();
                                    }
                                    Messages.Message("CannotRescue".Translate() + ": " + str2, victim, MessageSound.RejectInput);
                                    return;
                                }
                                Job job   = new Job(JobDefOf.Rescue, victim, building_Bed);
                                job.count = 1;
                                pawn.jobs.TryTakeOrderedJob(job);
                                PlayerKnowledgeDatabase.KnowledgeDemonstrated(ConceptDefOf.Rescuing, KnowledgeAmount.Total);
                            }, MenuOptionPriority.RescueOrCapture, null, victim2, 0f, null);
                        }
                        if (victim.RaceProps.Humanlike && (victim.MentalStateDef != null || victim.Faction != Faction.OfPlayer || (victim.Downed && victim.guilt.IsGuilty)))
                        {
                            Pawn victim2 = victim;
                            ITWN.PostMenuOption(opts, pawn, victim2, "Capture".Translate(new object[]
                            {
                                victim.LabelCap
                            }), delegate
                            {
                                Building_Bed building_Bed = RestUtility.FindBedFor(victim, pawn, true, false, false);
                                if (building_Bed == null)
                                {
                                    Messages.Message("CannotCapture".Translate() + ": " + "NoPrisonerBed".Translate(), victim, MessageSound.RejectInput);
                                    return;
                                }
                                Job job   = new Job(JobDefOf.Capture, victim, building_Bed);
                                job.count = 1;
                                pawn.jobs.TryTakeOrderedJob(job);
                                PlayerKnowledgeDatabase.KnowledgeDemonstrated(ConceptDefOf.Capturing, KnowledgeAmount.Total);
                            }, MenuOptionPriority.RescueOrCapture, null, victim2, 0f, null);
                        }
                    }
                }
                foreach (LocalTargetInfo current3 in GenUI.TargetsAt(clickPos, TargetingParameters.ForRescue(pawn), true))
                {
                    LocalTargetInfo targetInfo = current3;
                    Pawn            victim     = (Pawn)targetInfo.Thing;
                    if (victim.Downed && pawn.CanReach(victim, PathEndMode.OnCell, Danger.Deadly) && Building_CryptosleepCasket.FindCryptosleepCasketFor(victim, pawn) != null)
                    {
                        string label = "CarryToCryptosleepCasket".Translate(new object[]
                        {
                            targetInfo.Thing.LabelCap
                        });
                        JobDef jDef   = JobDefOf.CarryToCryptosleepCasket;
                        Action action = delegate
                        {
                            Building_CryptosleepCasket building_CryptosleepCasket = Building_CryptosleepCasket.FindCryptosleepCasketFor(victim, pawn);
                            if (building_CryptosleepCasket == null)
                            {
                                Messages.Message("CannotCarryToCryptosleepCasket".Translate() + ": " + "NoCryptosleepCasket".Translate(), victim, MessageSound.RejectInput);
                                return;
                            }
                            Job job = new Job(jDef, victim, building_CryptosleepCasket);
                            job.count = 1;
                            pawn.jobs.TryTakeOrderedJob(job);
                        };
                        Pawn victim2 = victim;
                        ITWN.PostMenuOption(opts, pawn, victim2, label, action, MenuOptionPriority.Default, null, victim2, 0f, null);
                    }
                }
            }
            foreach (LocalTargetInfo current4 in GenUI.TargetsAt(clickPos, TargetingParameters.ForStrip(pawn), true))
            {
                LocalTargetInfo stripTarg = current4;
                FloatMenuOption item2     = null;
                if (!pawn.CanReach(stripTarg, PathEndMode.ClosestTouch, Danger.Deadly, false, TraverseMode.ByPawn))
                {
                    item2 = new FloatMenuOption("CannotStrip".Translate(new object[]
                    {
                        stripTarg.Thing.LabelCap
                    }) + " (" + "NoPath".Translate() + ")", null, MenuOptionPriority.Default, null, null, 0f, null);
                }
                else
                {
                    ITWN.PostMenuOption(opts, pawn, stripTarg.Thing, "Strip".Translate(new object[]
                    {
                        stripTarg.Thing.LabelCap
                    }), delegate
                    {
                        stripTarg.Thing.SetForbidden(false, false);
                        pawn.jobs.TryTakeOrderedJob(new Job(JobDefOf.Strip, stripTarg));
                    });
                }

                if (item2 != null)
                {
                    opts.Add(item2);
                }
            }
            if (pawn.equipment != null)
            {
                ThingWithComps equipment = null;
                List <Thing>   thingList = c.GetThingList(pawn.Map);
                for (int i = 0; i < thingList.Count; i++)
                {
                    if (thingList[i].TryGetComp <CompEquippable>() != null)
                    {
                        equipment = (ThingWithComps)thingList[i];
                        break;
                    }
                }
                if (equipment != null)
                {
                    string          labelShort = equipment.LabelShort;
                    FloatMenuOption item3      = null;
                    if (equipment.def.IsWeapon && pawn.story.WorkTagIsDisabled(WorkTags.Violent))
                    {
                        item3 = new FloatMenuOption("CannotEquip".Translate(new object[]
                        {
                            labelShort
                        }) + " (" + "IsIncapableOfViolenceLower".Translate(new object[]
                        {
                            pawn.LabelShort
                        }) + ")", null, MenuOptionPriority.Default, null, null, 0f, null, null);
                    }
                    else if (!pawn.CanReach(equipment, PathEndMode.ClosestTouch, Danger.Deadly, false, TraverseMode.ByPawn))
                    {
                        item3 = new FloatMenuOption("CannotEquip".Translate(new object[]
                        {
                            labelShort
                        }) + " (" + "NoPath".Translate() + ")", null, MenuOptionPriority.Default, null, null, 0f, null, null);
                    }
                    else if (!pawn.health.capacities.CapableOf(PawnCapacityDefOf.Manipulation))
                    {
                        item3 = new FloatMenuOption("CannotEquip".Translate(new object[]
                        {
                            labelShort
                        }) + " (" + "Incapable".Translate() + ")", null, MenuOptionPriority.Default, null, null, 0f, null);
                    }
                    else
                    {
                        string text2 = "Equip".Translate(new object[]
                        {
                            labelShort
                        });
                        if (equipment.def.IsRangedWeapon && pawn.story != null && pawn.story.traits.HasTrait(TraitDefOf.Brawler))
                        {
                            text2 = text2 + " " + "EquipWarningBrawler".Translate();
                        }


                        ITWN.PostMenuOption(opts, pawn, equipment, text2, delegate
                        {
                            equipment.SetForbidden(false, true);
                            pawn.jobs.TryTakeOrderedJob(new Job(JobDefOf.Equip, equipment));
                            MoteMaker.MakeStaticMote(equipment.DrawPos, equipment.Map, ThingDefOf.Mote_FeedbackEquip, 1f);
                            PlayerKnowledgeDatabase.KnowledgeDemonstrated(ConceptDefOf.EquippingWeapons, KnowledgeAmount.Total);
                        });
                    }

                    if (item3 != null)
                    {
                        opts.Add(item3);
                    }
                }
            }
            if (pawn.apparel != null)
            {
                Apparel apparel = pawn.Map.thingGrid.ThingAt <Apparel>(c);
                if (apparel != null)
                {
                    FloatMenuOption item4 = null;
                    if (!pawn.CanReach(apparel, PathEndMode.ClosestTouch, Danger.Deadly, false, TraverseMode.ByPawn))
                    {
                        item4 = new FloatMenuOption("CannotWear".Translate(new object[]
                        {
                            apparel.Label
                        }) + " (" + "NoPath".Translate() + ")", null, MenuOptionPriority.Default, null, null, 0f, null);
                    }
                    else if (!ApparelUtility.HasPartsToWear(pawn, apparel.def))
                    {
                        item4 = new FloatMenuOption("CannotWear".Translate(new object[]
                        {
                            apparel.Label
                        }) + " (" + "CannotWearBecauseOfMissingBodyParts".Translate() + ")", null, MenuOptionPriority.Default, null, null, 0f, null);
                    }
                    else
                    {
                        ITWN.PostMenuOption(opts, pawn, apparel, "ForceWear".Translate(new object[]
                        {
                            apparel.LabelShort
                        }), delegate
                        {
                            apparel.SetForbidden(false, true);
                            Job job = new Job(JobDefOf.Wear, apparel);
                            pawn.jobs.TryTakeOrderedJob(job);
                        },
                                            priority: MenuOptionPriority.High);
                    }

                    if (item4 != null)
                    {
                        opts.Add(item4);
                    }
                }
            }
            if (!pawn.Map.IsPlayerHome)
            {
                Thing item = c.GetFirstItem(pawn.Map);
                if (item != null && item.def.EverHaulable)
                {
                    if (!pawn.CanReach(item, PathEndMode.ClosestTouch, Danger.Deadly, false, TraverseMode.ByPawn))
                    {
                        opts.Add(new FloatMenuOption("CannotPickUp".Translate(new object[]
                        {
                            item.Label
                        }) + " (" + "NoPath".Translate() + ")", null, MenuOptionPriority.Default, null, null, 0f, null, null));
                    }
                    else if (MassUtility.WillBeOverEncumberedAfterPickingUp(pawn, item, 1))
                    {
                        ITWN.PostMenuOption(opts, pawn, item, "CannotPickUp".Translate(new object[]
                        {
                            item.Label
                        }) + " (" + "TooHeavy".Translate() + ")", null);
                    }
                    else if (item.stackCount == 1)
                    {
                        ITWN.PostMenuOption(opts, pawn, item, "PickUp".Translate(new object[]
                        {
                            item.Label
                        }), delegate
                        {
                            item.SetForbidden(false, false);
                            Job job   = new Job(JobDefOf.TakeInventory, item);
                            job.count = 1;
                            pawn.jobs.TryTakeOrderedJob(job);
                        },
                                            priority: MenuOptionPriority.High);
                    }
                    else
                    {
                        if (MassUtility.WillBeOverEncumberedAfterPickingUp(pawn, item, item.stackCount))
                        {
                            ITWN.PostMenuOption(opts, pawn, item, "CannotPickUpAll".Translate(new object[]
                            {
                                item.Label
                            }) + " (" + "TooHeavy".Translate() + ")", null);
                        }
                        else
                        {
                            ITWN.PostMenuOption(opts, pawn, item, "PickUpAll".Translate(new object[]
                            {
                                item.Label
                            }), delegate
                            {
                                item.SetForbidden(false, false);
                                Job job   = new Job(JobDefOf.TakeInventory, item);
                                job.count = item.stackCount;
                                pawn.jobs.TryTakeOrderedJob(job);
                            },
                                                priority: MenuOptionPriority.High);
                        }

                        ITWN.PostMenuOption(opts, pawn, item, "PickUpSome".Translate(new object[]
                        {
                            item.Label
                        }), delegate
                        {
                            int to = Mathf.Min(MassUtility.CountToPickUpUntilOverEncumbered(pawn, item), item.stackCount);
                            Dialog_Slider window = new Dialog_Slider("PickUpCount".Translate(new object[]
                            {
                                item.LabelShort
                            }), 1, to, delegate(int count)
                            {
                                item.SetForbidden(false, false);
                                Job job   = new Job(JobDefOf.TakeInventory, item);
                                job.count = count;
                                pawn.jobs.TryTakeOrderedJob(job);
                            }, -2147483648);
                            Find.WindowStack.Add(window);
                        },
                                            priority: MenuOptionPriority.High);
                    }
                }
            }
            if (!pawn.Map.IsPlayerHome)
            {
                Thing item = c.GetFirstItem(pawn.Map);
                if (item != null && item.def.EverHaulable)
                {
                    Pawn bestPackAnimal = GiveToPackAnimalUtility.PackAnimalWithTheMostFreeSpace(pawn.Map, pawn.Faction);
                    if (bestPackAnimal != null)
                    {
                        if (!pawn.CanReach(item, PathEndMode.ClosestTouch, Danger.Deadly, false, TraverseMode.ByPawn))
                        {
                            opts.Add(new FloatMenuOption("CannotGiveToPackAnimal".Translate(new object[]
                            {
                                item.Label
                            }) + " (" + "NoPath".Translate() + ")", null, MenuOptionPriority.Default, null, null, 0f, null, null));
                        }
                        else if (MassUtility.WillBeOverEncumberedAfterPickingUp(bestPackAnimal, item, 1))
                        {
                            ITWN.PostMenuOption(opts, pawn, item, "CannotGiveToPackAnimal".Translate(new object[]
                            {
                                item.Label
                            }) + " (" + "TooHeavy".Translate() + ")", null);
                        }
                        else if (item.stackCount == 1)
                        {
                            ITWN.PostMenuOption(opts, pawn, item, "GiveToPackAnimal".Translate(new object[]
                            {
                                item.Label
                            }), delegate
                            {
                                item.SetForbidden(false, false);
                                Job job   = new Job(JobDefOf.GiveToPackAnimal, item);
                                job.count = 1;
                                pawn.jobs.TryTakeOrderedJob(job);
                            }, MenuOptionPriority.High);
                        }
                        else
                        {
                            if (MassUtility.WillBeOverEncumberedAfterPickingUp(bestPackAnimal, item, item.stackCount))
                            {
                                ITWN.PostMenuOption(opts, pawn, item, "CannotGiveToPackAnimalAll".Translate(new object[]
                                {
                                    item.Label
                                }) + " (" + "TooHeavy".Translate() + ")", null, MenuOptionPriority.Default, null, null, 0f, null, null);
                            }
                            else
                            {
                                ITWN.PostMenuOption(opts, pawn, item, "GiveToPackAnimalAll".Translate(new object[]
                                {
                                    item.Label
                                }), delegate
                                {
                                    item.SetForbidden(false, false);
                                    Job job   = new Job(JobDefOf.GiveToPackAnimal, item);
                                    job.count = item.stackCount;
                                    pawn.jobs.TryTakeOrderedJob(job);
                                }, MenuOptionPriority.High, null, null, 0f, null, null);
                            }
                            ITWN.PostMenuOption(opts, pawn, item, "GiveToPackAnimalSome".Translate(new object[]
                            {
                                item.Label
                            }), delegate
                            {
                                int to = Mathf.Min(MassUtility.CountToPickUpUntilOverEncumbered(bestPackAnimal, item), item.stackCount);
                                Dialog_Slider window = new Dialog_Slider("GiveToPackAnimalCount".Translate(new object[]
                                {
                                    item.LabelShort
                                }), 1, to, delegate(int count)
                                {
                                    item.SetForbidden(false, false);
                                    Job job   = new Job(JobDefOf.GiveToPackAnimal, item);
                                    job.count = count;
                                    pawn.jobs.TryTakeOrderedJob(job);
                                }, -2147483648);
                                Find.WindowStack.Add(window);
                            }, MenuOptionPriority.High, null, null, 0f, null, null);
                        }
                    }
                }
            }
            if (!pawn.Map.IsPlayerHome)
            {
                foreach (LocalTargetInfo current5 in GenUI.TargetsAt(clickPos, TargetingParameters.ForRescue(pawn), true))
                {
                    Pawn p = (Pawn)current5.Thing;
                    if (p.Faction == Faction.OfPlayer || p.HostFaction == Faction.OfPlayer)
                    {
                        if (!pawn.CanReach(p, PathEndMode.ClosestTouch, Danger.Deadly, false, TraverseMode.ByPawn))
                        {
                            opts.Add(new FloatMenuOption("CannotCarryToExit".Translate(new object[]
                            {
                                p.Label
                            }) + " (" + "NoPath".Translate() + ")", null, MenuOptionPriority.Default, null, null, 0f, null, null));
                        }
                        else
                        {
                            IntVec3 exitSpot;
                            if (!RCellFinder.TryFindBestExitSpot(pawn, out exitSpot, TraverseMode.ByPawn))
                            {
                                ITWN.PostMenuOption(opts, pawn, p, "CannotCarryToExit".Translate(new object[]
                                {
                                    p.Label
                                }) + " (" + "NoPath".Translate() + ")", null, MenuOptionPriority.Default, null, null, 0f, null, null);
                            }
                            else
                            {
                                ITWN.PostMenuOption(opts, pawn, p, "CarryToExit".Translate(new object[]
                                {
                                    p.Label
                                }), delegate
                                {
                                    Job job   = new Job(JobDefOf.CarryDownedPawnToExit, p, exitSpot);
                                    job.count = 1;
                                    pawn.jobs.TryTakeOrderedJob(job);
                                }, MenuOptionPriority.High, null, null, 0f, null, null);
                            }
                        }
                    }
                }
            }
            if (pawn.equipment != null && pawn.equipment.Primary != null && GenUI.TargetsAt(clickPos, TargetingParameters.ForSelf(pawn), true).Any <LocalTargetInfo>())
            {
                Action action2 = delegate
                {
                    pawn.jobs.TryTakeOrderedJob(new Job(JobDefOf.DropEquipment, pawn.equipment.Primary));
                };
                opts.Add(new FloatMenuOption("Drop".Translate(new object[]
                {
                    pawn.equipment.Primary.Label
                }), action2, MenuOptionPriority.Default, null, null, 0f, null, null));
            }
            foreach (LocalTargetInfo current6 in GenUI.TargetsAt(clickPos, TargetingParameters.ForTrade(), true))
            {
                LocalTargetInfo dest = current6;
                if (!pawn.CanReach(dest, PathEndMode.OnCell, Danger.Deadly, false, TraverseMode.ByPawn))
                {
                    opts.Add(new FloatMenuOption("CannotTrade".Translate() + " (" + "NoPath".Translate() + ")", null, MenuOptionPriority.Default, null, null, 0f, null, null));
                }
                else
                {
                    Pawn   pTarg   = (Pawn)dest.Thing;
                    Action action3 = delegate
                    {
                        Job job = new Job(JobDefOf.TradeWithPawn, pTarg);
                        job.playerForced = true;
                        pawn.jobs.TryTakeOrderedJob(job);
                        PlayerKnowledgeDatabase.KnowledgeDemonstrated(ConceptDefOf.InteractingWithTraders, KnowledgeAmount.Total);
                    };
                    string str = string.Empty;
                    if (pTarg.Faction != null)
                    {
                        str = " (" + pTarg.Faction.Name + ")";
                    }
                    Thing thing = dest.Thing;
                    ITWN.PostMenuOption(opts, pawn, pTarg, "TradeWith".Translate(new object[]
                    {
                        pTarg.LabelShort + ", " + pTarg.TraderKind.label
                    }) + str, action3, MenuOptionPriority.InitiateSocial, null, thing, 0f, null, null);
                }
            }
            foreach (Thing current7 in pawn.Map.thingGrid.ThingsAt(c))
            {
                foreach (FloatMenuOption current8 in current7.GetFloatMenuOptions(pawn))
                {
                    opts.Add(current8);
                }
            }
        }
        public static bool FindBetterApparel(
            ref float baseApparelScore, ref Apparel betterApparel, Pawn pawn, Outfit currentOutfit, IEnumerable <Apparel> apparelToCheck, Building dresser)
        {
            if (betterApparel == null)
            {
                baseApparelScore = 0f;
            }
#if BETTER_OUTFIT
            Log.Warning("Begin ApparelUtil.FindBetterApparel(Score: " + baseApparelScore + "    Apparel: " + ((betterApparel == null) ? "<null>" : betterApparel.Label));
#endif
            bool result = false;
#if TRACE && BETTER_OUTFIT
            Log.Message("    Apparel:");
#endif
            foreach (Apparel apparel in apparelToCheck)
            {
#if TRACE && BETTER_OUTFIT
                Log.Message("        " + ((apparel == null) ? "<null>" : apparel.Label));
#endif
                if (!currentOutfit.filter.Allows(apparel.def))
                {
#if TRACE && BETTER_OUTFIT
                    Log.Message("        Filters does not allow");
#endif
                    break;
                }
                if (!currentOutfit.filter.Allows(apparel) ||
                    apparel.IsForbidden(pawn))
                {
#if TRACE && BETTER_OUTFIT
                    Log.Message("        Current Outfit Does Not Allow: " + !currentOutfit.filter.Allows(apparel) + "    or     Is Forbidden: " + apparel.IsForbidden(pawn));
#endif
                    continue;
                }

#if TRACE && BETTER_OUTFIT
                Log.Message("        Keep Forced Apparel: " + Settings.KeepForcedApparel);
#endif
                if (Settings.KeepForcedApparel)
                {
                    bool           skipApparelType = false;
                    List <Apparel> wornApparel     = pawn.apparel.WornApparel;
                    for (int i = 0; i < wornApparel.Count; i++)
                    {
                        try
                        {
                            if (!pawn.outfits.forcedHandler.IsForced(wornApparel[i]) &&
                                !ApparelUtility.CanWearTogether(wornApparel[i].def, apparel.def, pawn.RaceProps.body))
                            {
#if TRACE && BETTER_OUTFIT
                                Log.Message("        Cannot wear together");
#endif
                                skipApparelType = true;
                                break;
                            }
                        }
                        catch (Exception e)
                        {
                            try
                            {
                                Log.Warning("Problem when calling CanWearTogether (" + wornApparel[i]?.Label + ", " + apparel?.Label + ", " + pawn?.RaceProps?.body?.label + ") - " + e.GetType().Name + " " + e.Message);
                            }
                            catch { }
                            skipApparelType = true;
                            break;
                        }
                    }
                    if (skipApparelType)
                    {
                        break;
                    }
                }

                float gain = JobGiver_OptimizeApparel.ApparelScoreGain(pawn, apparel);
#if TRACE && BETTER_OUTFIT
                Log.Message("    Gain: " + gain + "     Base Score: " + baseApparelScore);
#endif
                if (gain >= 0.05f && gain > baseApparelScore)
                {
#if TRACE && BETTER_OUTFIT
                    Log.Message("    Gain is better");
#endif
                    if (ApparelUtility.HasPartsToWear(pawn, apparel.def))
                    {
#if TRACE && BETTER_OUTFIT
                        Log.Message("    Has parts to wear");
#endif
                        if (dresser == null ||
                            ReservationUtility.CanReserveAndReach(pawn, dresser, PathEndMode.OnCell, pawn.NormalMaxDanger(), 1))
                        {
#if TRACE && BETTER_OUTFIT
                            Log.Message("    Can reach dresser");
#endif
                            betterApparel    = apparel;
                            baseApparelScore = gain;
                            result           = true;
                        }
                    }
                }
            }
#if BETTER_OUTFIT
            Log.Warning("End ApparelUtil.FindBetterApparel    result = " + result);
#endif
            return(result);
        }
Exemple #9
0
        /// <inheritdoc/>
        public override ThinkResult TryIssueJobPackage(Pawn pawn, JobIssueParams jobParams)
        {
            ValidateArg.NotNull(pawn, nameof(pawn));

            if (Find.TickManager.TicksGame < _optimizedTick)
            {
                return(ThinkResult.NoJob);
            }

            CompAwesomeInventoryLoadout comp = pawn.TryGetComp <CompAwesomeInventoryLoadout>();

            if (comp?.Loadout == null || comp.Loadout.GetType() == typeof(AwesomeInventoryCostume))
            {
                return(ThinkResult.NoJob);
            }

            List <Thing> list = pawn.inventory?.innerContainer?.ToList();

            if (list == null)
            {
                return(ThinkResult.NoJob);
            }

            if (!list.Any())
            {
                _optimizedTick = _optmizedInterval + Find.TickManager.TicksGame;
                return(ThinkResult.NoJob);
            }

            List <Apparel> wornApparels = pawn.apparel?.WornApparel;

            if (wornApparels == null)
            {
                return(ThinkResult.NoJob);
            }

            AwesomeInventoryCostume costume = comp.Loadout as AwesomeInventoryCostume;

            var thingList = list
                            .Where(t => t is Apparel apparel && ApparelOptionUtility.CanWear(pawn, apparel))
                            .Select(t => new { thing = t, score = JobGiver_OptimizeApparel.ApparelScoreGain(pawn, (Apparel)t) })
                            .Where(thingScore => thingScore.score > 0.05f)
                            .OrderByDescending(s => s.score)
                            .ToList();

            if (!thingList.Any())
            {
                _optimizedTick = _optmizedInterval + Find.TickManager.TicksGame;
                return(ThinkResult.NoJob);
            }

            List <Apparel> wornCostume = null;

            if (costume != null)
            {
                wornCostume = pawn.apparel.WornApparel
                              .AsParallel()
                              .Where(a => costume.CostumeItems.Any(c => c.Allows(a, out _)))
                              .ToList();
            }

            foreach (var t in thingList)
            {
                Thing thing = null;

                if (costume == null)
                {
                    thing = t.thing;
                }
                else
                {
                    foreach (ThingGroupSelector selector in costume.CostumeItems)
                    {
                        if (selector.Allows(t.thing, out _))
                        {
                            thing = t.thing;
                            break;
                        }
                    }

                    if (thing == null)
                    {
                        if (wornCostume.NullOrEmpty() || wornCostume.All(c => ApparelUtility.CanWearTogether(c.def, t.thing.def, BodyDefOf.Human)))
                        {
                            thing = t.thing;
                        }
                    }
                }

                if (thing != null)
                {
                    return(new ThinkResult(
                               new DressJob(AwesomeInventory_JobDefOf.AwesomeInventory_Dress, thing, false)
                               , this
                               , JobTag.ChangingApparel));
                }
            }

            _optimizedTick = _optmizedInterval + Find.TickManager.TicksGame;
            return(ThinkResult.NoJob);
        }
        // Decompiled code is painful to read... Continue at your own risk
        // TODO: Replace this with a cleaner solution
        // Maybe explore FloatMenuMakerMap
        public static List <FloatMenuOption> ChoicesForThing(Thing thing, Pawn pawn, string thingLabelShort)
        {
            var    opts       = new List <FloatMenuOption>();
            var    t          = thing;
            string labelShort = "";
            string label      = thingLabelShort;

            if (thing.stackCount > 1)
            {
                label += " x" + thing.stackCount.ToStringCached();
            }



            // Copied from FloatMenuMakerMap.AddHumanlikeOrders
            if (t.def.ingestible != null && canBeConsumedby[t].Contains(pawn) && t.IngestibleNow)
            {
                string text;
                if (t.def.ingestible.ingestCommandString.NullOrEmpty())
                {
                    text = "ConsumeThing".Translate(thingLabelShort, t);
                }
                else
                {
                    text = string.Format(t.def.ingestible.ingestCommandString, thingLabelShort);
                }
                if (!t.IsSociallyProper(pawn))
                {
                    text = text + " (" + "ReservedForPrisoners".Translate() + ")";
                }
                FloatMenuOption item7;
                if (t.def.IsNonMedicalDrug && pawn.IsTeetotaler())
                {
                    item7 = new FloatMenuOption(text + " (" + TraitDefOf.DrugDesire.DataAtDegree(-1).label + ")", null);
                }
                else if (!pawnCanReach_Oncell_Deadly.Contains(pawn))
                {
                    item7 = new FloatMenuOption(text + " (" + "NoPath".Translate() + ")", null);
                }
                else
                {
                    var priority2 = !(t is Corpse) ? MenuOptionPriority.Default : MenuOptionPriority.Low;
                    item7 = FloatMenuUtility.DecoratePrioritizedTask(new FloatMenuOption(text, delegate
                    {
                        t.SetForbidden(false);
                        var job   = new Job(JobDefOf.Ingest, t);
                        job.count = FoodUtility.WillIngestStackCountOf(pawn, t.def,
                                                                       t.GetStatValue(StatDefOf.Nutrition));
                        pawn.jobs.TryTakeOrderedJob(job);
                    }, priority2), pawn, t);
                }

                opts.Add(item7);
            }

            // Add equipment commands
            // Copied from FloatMenuMakerMap.AddHumanlikeOrders
            if (thing is ThingWithComps equipment && equipment.GetComp <CompEquippable>() != null)
            {
                //ThingWithComps != Thing --> Label is diffrent implementing the override string LabelNoCount
                labelShort = thingLabelShort;
                if (equipment.AllComps != null)
                {
                    int i = 0;
                    for (int count = equipment.AllComps.Count; i < count; i++)
                    {
                        labelShort = equipment.AllComps[i].TransformLabel(labelShort);
                    }
                }


                FloatMenuOption item4;
                if (equipment.def.IsWeapon && pawn.WorkTagIsDisabled(WorkTags.Violent))
                {
                    item4 = new FloatMenuOption(
                        "CannotEquip".Translate(labelShort) + " (" +
                        "IsIncapableOfViolenceLower".Translate(pawn.LabelShort, pawn) + ")", null);
                }
                else if (!pawnCanReach_Touch_Deadly.Contains(pawn))
                {
                    item4 = new FloatMenuOption("CannotEquip".Translate(labelShort) + " (" + "NoPath".Translate() + ")",
                                                null);
                }
                else if (!pawn.health.capacities.CapableOf(PawnCapacityDefOf.Manipulation))
                {
                    item4 = new FloatMenuOption(
                        "CannotEquip".Translate(labelShort) + " (" + "Incapable".Translate() + ")", null);
                }
                else
                {
                    string text5 = "Equip".Translate(labelShort);
                    if (equipment.def.IsRangedWeapon && pawn.story != null &&
                        pawn.story.traits.HasTrait(TraitDefOf.Brawler))
                    {
                        text5 = text5 + " " + "EquipWarningBrawler".Translate();
                    }
                    item4 = FloatMenuUtility.DecoratePrioritizedTask(new FloatMenuOption(text5, delegate
                    {
                        equipment.SetForbidden(false);
                        pawn.jobs.TryTakeOrderedJob(new Job(JobDefOf.Equip, equipment));
                        FleckMaker.Static(equipment.DrawPos, equipment.Map, FleckDefOf.FeedbackEquip);
                        PlayerKnowledgeDatabase.KnowledgeDemonstrated(ConceptDefOf.EquippingWeapons,
                                                                      KnowledgeAmount.Total);
                    }, MenuOptionPriority.High), pawn, equipment);
                }

                opts.Add(item4);
            }

            // Add clothing commands
            var apparel = thing as Apparel;

            if (apparel != null)
            {
                //replaced apparel.Label label (the former would spawm MaxHitPonts)
                FloatMenuOption item5;
                if (!pawnCanReach_Touch_Deadly.Contains(pawn))
                {
                    item5 = new FloatMenuOption(
                        "CannotWear".Translate(label, apparel) + " (" + "NoPath".Translate() + ")", null);
                }
                else if (!ApparelUtility.HasPartsToWear(pawn, apparel.def))
                {
                    item5 = new FloatMenuOption(
                        "CannotWear".Translate(label, apparel) + " (" +
                        "CannotWearBecauseOfMissingBodyParts".Translate() + ")", null);
                }
                else /*Apparel has no override for LabelShort therefor we can still use labelShort from ThingWithComps*/
                {
                    item5 = FloatMenuUtility.DecoratePrioritizedTask(new FloatMenuOption(
                                                                         "ForceWear".Translate(labelShort, apparel), delegate
                    {
                        apparel.SetForbidden(false);
                        var job = new Job(JobDefOf.Wear, apparel);
                        pawn.jobs.TryTakeOrderedJob(job);
                    }, MenuOptionPriority.High), pawn, apparel);
                }
                opts.Add(item5);
            }

            // Add caravan commands

            if (pawn.IsFormingCaravan())
            {
                if (thing != null && thing.def.EverHaulable)
                {
                    var packTarget = GiveToPackAnimalUtility.UsablePackAnimalWithTheMostFreeSpace(pawn) ?? pawn;
                    var jobDef     = packTarget != pawn ? JobDefOf.GiveToPackAnimal : JobDefOf.TakeInventory;
                    //replaced thing.Label label (the former would spawm MaxHitPonts)
                    if (!pawnCanReach_Touch_Deadly.Contains(pawn))
                    {
                        opts.Add(new FloatMenuOption(
                                     "CannotLoadIntoCaravan".Translate(label, thing) + " (" + "NoPath".Translate() + ")",
                                     null));
                    }
                    else if (MassUtility.WillBeOverEncumberedAfterPickingUp(packTarget, thing, 1))
                    {
                        opts.Add(new FloatMenuOption(
                                     "CannotLoadIntoCaravan".Translate(label, thing) + " (" + "TooHeavy".Translate() + ")",
                                     null));
                    }
                    else
                    {
                        var lordJob      = (LordJob_FormAndSendCaravan)pawn.GetLord().LordJob;
                        var capacityLeft = CaravanFormingUtility.CapacityLeft(lordJob);
                        if (thing.stackCount == 1)
                        {
                            var capacityLeft4 = capacityLeft - thing.GetStatValue(StatDefOf.Mass);
                            opts.Add(FloatMenuUtility.DecoratePrioritizedTask(new FloatMenuOption(
                                                                                  CaravanFormingUtility.AppendOverweightInfo(
                                                                                      "LoadIntoCaravan".Translate(label, thing), capacityLeft4), delegate
                            {
                                thing.SetForbidden(false, false);
                                var job              = new Job(jobDef, thing);
                                job.count            = 1;
                                job.checkEncumbrance = packTarget == pawn;
                                pawn.jobs.TryTakeOrderedJob(job);
                            }, MenuOptionPriority.High), pawn, thing));
                        }
                        else
                        {
                            if (MassUtility.WillBeOverEncumberedAfterPickingUp(packTarget, thing, thing.stackCount))
                            {
                                opts.Add(new FloatMenuOption(
                                             "CannotLoadIntoCaravanAll".Translate(label, thing) + " (" +
                                             "TooHeavy".Translate() + ")", null));
                            }
                            else
                            {
                                var capacityLeft2 =
                                    capacityLeft - thing.stackCount * thing.GetStatValue(StatDefOf.Mass);
                                opts.Add(FloatMenuUtility.DecoratePrioritizedTask(new FloatMenuOption(
                                                                                      CaravanFormingUtility.AppendOverweightInfo(
                                                                                          "LoadIntoCaravanAll".Translate(label, thing), capacityLeft2), delegate
                                {
                                    thing.SetForbidden(false, false);
                                    var job              = new Job(jobDef, thing);
                                    job.count            = thing.stackCount;
                                    job.checkEncumbrance = packTarget == pawn;
                                    pawn.jobs.TryTakeOrderedJob(job);
                                }, MenuOptionPriority.High), pawn, thing));
                            }

                            opts.Add(FloatMenuUtility.DecoratePrioritizedTask(new FloatMenuOption(
                                                                                  "LoadIntoCaravanSome".Translate(thingLabelShort, thing), delegate
                            {
                                var to = Mathf.Min(MassUtility.CountToPickUpUntilOverEncumbered(packTarget, thing),
                                                   thing.stackCount);
                                var window = new Dialog_Slider(delegate(int val)
                                {
                                    var capacityLeft3 = capacityLeft - val * thing.GetStatValue(StatDefOf.Mass);
                                    return(CaravanFormingUtility.AppendOverweightInfo(
                                               string.Format("LoadIntoCaravanCount".Translate(thingLabelShort, thing),
                                                             val), capacityLeft3));
                                }, 1, to, delegate(int count)
                                {
                                    thing.SetForbidden(false, false);
                                    var job              = new Job(jobDef, thing);
                                    job.count            = count;
                                    job.checkEncumbrance = packTarget == pawn;
                                    pawn.jobs.TryTakeOrderedJob(job);
                                });
                                Find.WindowStack.Add(window);
                            }, MenuOptionPriority.High), pawn, thing));
                        }
                    }
                }
            }
            return(opts);
        }
        public float ApparelScoreRaw_Temperature([NotNull] Apparel apparel)
        {
            // float minComfyTemperature = pawnSave.RealComfyTemperatures.min;
            // float maxComfyTemperature = pawnSave.RealComfyTemperatures.max;
            Pawn  thisPawn            = this._pawn;
            float minComfyTemperature = thisPawn.ComfortableTemperatureRange().min;
            float maxComfyTemperature = thisPawn.ComfortableTemperatureRange().max;

            // temperature
            FloatRange targetTemperatures = this.TargetTemperatures;

            this.GetInsulationStats(apparel, out float insulationCold, out float insulationHeat);

            string log = apparel.LabelCap + " - InsCold: " + insulationCold + " - InsHeat: " + insulationHeat
                         + " - TargTemp: " + targetTemperatures + "\nMinComfy: " + minComfyTemperature + " - MaxComfy: "
                         + maxComfyTemperature;

            // if this gear is currently worn, we need to make sure the contribution to the pawn's comfy temps is removed so the gear is properly scored
            List <Apparel> wornApparel = thisPawn.apparel.WornApparel;

            if (!wornApparel.NullOrEmpty())
            {
                if (wornApparel.Contains(apparel))
                {
                    // log += "\nPawn is wearer of this apparel.";
                    minComfyTemperature -= insulationCold;
                    maxComfyTemperature -= insulationHeat;
                }
                else
                {
                    // check if the candidate will replace existing gear
                    for (int index = 0; index < wornApparel.Count; index++)
                    {
                        Apparel wornAp = wornApparel[index];
                        if (!ApparelUtility.CanWearTogether(wornAp.def, apparel.def, thisPawn.RaceProps.body))
                        {
                            this.GetInsulationStats(wornAp, out float insulationColdWorn, out float insulationHeatWorn);

                            minComfyTemperature -= insulationColdWorn;
                            maxComfyTemperature -= insulationHeatWorn;

                            // Log.Message(apparel +"-"+ insulationColdWorn + "-" + insulationHeatWorn + "-" + minComfyTemperature + "-" + maxComfyTemperature);
                        }
                    }
                }
            }

            log += "\nBasic stat not worn - MinComfy: " + minComfyTemperature + " - MaxComfy: " + maxComfyTemperature;

            // now for the interesting bit.
            FloatRange temperatureScoreOffset = new FloatRange(0f, 0f);

            // isolation_cold is given as negative numbers < 0 means we're underdressed
            float neededInsulationCold = targetTemperatures.min - minComfyTemperature;

            // isolation_warm is given as positive numbers.
            float neededInsulationWarmth = targetTemperatures.max - maxComfyTemperature;

            FloatRange tempWeight = this.TemperatureWeight;

            log += "\nWeight: " + tempWeight + " - NeedInsCold: " + neededInsulationCold + " - NeedInsWarmth: "
                   + neededInsulationWarmth;

            if (neededInsulationCold < 0)
            {
                // currently too cold
                // caps ap to only consider the needed temp and don't give extra points
                if (neededInsulationCold > insulationCold)
                {
                    temperatureScoreOffset.min += neededInsulationCold;
                }
                else
                {
                    temperatureScoreOffset.min += insulationCold;
                }
            }
            else
            {
                // currently warm enough
                if (insulationCold > neededInsulationCold)
                {
                    // this gear would make us too cold
                    temperatureScoreOffset.min += insulationCold - neededInsulationCold;
                }
            }

            // invert for scoring
            temperatureScoreOffset.min *= -1;

            if (neededInsulationWarmth > 0)
            {
                // currently too warm
                // caps ap to only consider the needed temp and don't give extra points
                if (neededInsulationWarmth < insulationHeat)
                {
                    temperatureScoreOffset.max += neededInsulationWarmth;
                }
                else
                {
                    temperatureScoreOffset.max += insulationHeat;
                }
            }
            else
            {
                // currently cool enough
                if (insulationHeat < neededInsulationWarmth)
                {
                    // this gear would make us too warm
                    temperatureScoreOffset.max += insulationHeat - neededInsulationWarmth;
                }
            }

            // Punish bad apparel
            // temperatureScoreOffset.min *= temperatureScoreOffset.min < 0 ? 2f : 1f;
            // temperatureScoreOffset.max *= temperatureScoreOffset.max < 0 ? 2f : 1f;

            // New
            log += "\nPre-Evaluate: " + temperatureScoreOffset.min + " / " + temperatureScoreOffset.max;

            temperatureScoreOffset.min = Curve.Evaluate(temperatureScoreOffset.min * tempWeight.min);
            temperatureScoreOffset.max = Curve.Evaluate(temperatureScoreOffset.max * tempWeight.max);

            log += "\nScoreOffsetMin: " + temperatureScoreOffset.min + " - ScoreOffsetMax: "
                   + temperatureScoreOffset.max + " *= " + (temperatureScoreOffset.min * temperatureScoreOffset.max);

            Log.Message(log);
            return(temperatureScoreOffset.min * temperatureScoreOffset.max);

            // return 1 + (temperatureScoreOffset.min + temperatureScoreOffset.max) / 15;
        }
Exemple #12
0
        public override GizmoResult GizmoOnGUI(UnityEngine.Vector2 topLeft)
        {
            Rect overRect = new Rect(topLeft.x, topLeft.y, curWidth, Height);

            Widgets.DrawWindowBackground(overRect);

            //Equipment slot
            Pawn           wearer = backpack.wearer;
            ThingWithComps dummy;

            Rect thingIconRect = new Rect(topLeft.x, topLeft.y, widthPerItem, Height / 2);
            int  numOfCurItem  = 0;

            List <Thing> things = wearer.inventory.container.ToList();

            //Draw Gizmo
            for (int i = 0; i < numOfMaxItemsPerRow * numOfRow; i++)
            {
                if (i >= backpack.MaxItem)
                {
                    thingIconRect.x = topLeft.x + widthPerItem * (i % numOfMaxItemsPerRow);
                    thingIconRect.y = topLeft.y + (Height / 2) * (i / numOfMaxItemsPerRow);
                    Widgets.DrawTextureFitted(thingIconRect, NoAvailableTex, 1.0f);
                    continue;
                }

                if (i >= things.Count)
                {
                    thingIconRect.x = topLeft.x + widthPerItem * (i % numOfMaxItemsPerRow);
                    thingIconRect.y = topLeft.y + (Height / 2) * (i / numOfMaxItemsPerRow);
                    Widgets.DrawTextureFitted(thingIconRect, EmptyTex, 1.0f);
                    continue;
                }

                Thing item = things[i];
                Widgets.DrawBox(thingIconRect, 1);
                Widgets.ThingIcon(thingIconRect, item);
                if (thingIconRect.Contains(Event.current.mousePosition))
                {
                    Widgets.DrawTextureFitted(thingIconRect, FilledTex, 1.0f);
                }
                //Interaction with item
                if (Widgets.InvisibleButton(thingIconRect))
                {
                    thingIconSound = SoundDefOf.Click;
                    if (Event.current.button == 0)
                    {
                        //Weapon
                        if (item.def.equipmentType == EquipmentType.Primary)
                        {
                            if (wearer.equipment.Primary != null)
                            {
                                wearer.equipment.TryTransferEquipmentToContainer(wearer.equipment.Primary, wearer.inventory.container, out dummy);
                            }
                            else
                            {
                                backpack.numOfSavedItems--;
                            }
                            wearer.equipment.AddEquipment(item as ThingWithComps);
                            wearer.inventory.container.Remove(item as ThingWithComps);
                            if (wearer.jobs.curJob != null)
                            {
                                wearer.jobs.EndCurrentJob(JobCondition.InterruptForced);
                            }
                        }
                        //Medicine
                        else if (item.def.thingCategories.Contains(medicine))
                        {
                            if (wearer.workSettings.WorkIsActive(WorkTypeDefOf.Doctor))
                            {
                                Designator_ApplyMedicine designator = new Designator_ApplyMedicine();
                                designator.medicine      = item;
                                designator.doctor        = wearer;
                                designator.icon          = item.def.uiIcon;
                                designator.activateSound = SoundDef.Named("Click");

                                DesignatorManager.Select(designator);
                            }
                            else
                            {
                                Messages.Message(txtNoDoctor.Translate(), MessageSound.RejectInput);
                                Messages.Update();
                                thingIconSound = SoundDefOf.ClickReject;
                            }
                        }
                        //Food
                        else if (item.def.thingCategories.Contains(foodMeals))
                        {
                            if (wearer.needs.food.CurCategory != HungerCategory.Fed)
                            {
                                Job jobNew = new Job(JobDefOf.Ingest, item);
                                jobNew.maxNumToCarry   = 1;
                                jobNew.ignoreForbidden = true;
                                wearer.drafter.TakeOrderedJob(jobNew);
                            }
                            else
                            {
                                Messages.Message(txtCannotEatAnymore.Translate(), MessageSound.RejectInput);
                                Messages.Update();
                                thingIconSound = SoundDefOf.ClickReject;
                            }
                        }
                        //Apparel
                        else if (item is Apparel)
                        {
                            //if (!wearer.apparel.CanWearWithoutDroppingAnything(item.def))
                            //    wearer.apparel.WornApparel.Find(apparel => apparel.def.apparel.layers.Any);
                            for (int index = wearer.apparel.WornApparel.Count - 1; index >= 0; --index)
                            {
                                Apparel ap = wearer.apparel.WornApparel[index];
                                if (!ApparelUtility.CanWearTogether(item.def, ap.def))
                                {
                                    Apparel resultingAp;
                                    wearer.apparel.TryDrop(ap, out resultingAp, wearer.Position, false);
                                    wearer.inventory.container.TryAdd(resultingAp);
                                    backpack.numOfSavedItems++;
                                }
                            }
                            wearer.apparel.Wear(item as Apparel);
                            wearer.inventory.container.Remove(item as ThingWithComps);
                            backpack.numOfSavedItems--;
                        }

                        else
                        {
                            //Add another type of item you want to interact
                        }
                    }
                    else if (Event.current.button == 1)
                    {
                        List <FloatMenuOption> options = new List <FloatMenuOption>();
                        options.Add(new FloatMenuOption(txtThingInfo, () =>
                        {
                            Find.WindowStack.Add((Window) new Dialog_InfoCard(item));
                        }));
                        options.Add(new FloatMenuOption(txtDropThing, () =>
                        {
                            Thing dummy1;
                            wearer.inventory.container.TryDrop(item, wearer.Position, ThingPlaceMode.Near, out dummy1);
                        }));

                        Find.WindowStack.Add((Window) new FloatMenu(options, item.LabelCap, false, false));
                    }

                    SoundStarter.PlayOneShotOnCamera(thingIconSound);
                }

                numOfCurItem++;
                thingIconRect.x = topLeft.x + widthPerItem * (numOfCurItem % numOfMaxItemsPerRow);
                thingIconRect.y = topLeft.y + (Height / 2) * (numOfCurItem / numOfMaxItemsPerRow);
            }

            if (numOfCurItem == 0)
            {
                Rect textRect = new Rect(topLeft.x + Width / 2 - textWidth / 2, topLeft.y + Height / 2 - textHeight / 2, textWidth, textHeight);
                Widgets.Label(textRect, txtNoItem.Translate());
            }
            return(new GizmoResult(GizmoState.Clear));
        }
        public static void Postfix(Vector3 clickPos, Pawn pawn, List <FloatMenuOption> opts)
        {
            if (!AwesomeInventoryServiceProvider.TryGetImplementation <IInventoryHelper>(out IInventoryHelper inventoryHelper))
            {
                Log.Error(string.Format(ErrorMessage.NotImplemented, typeof(IInventoryHelper).Name));
                return;
            }

            IntVec3 position = IntVec3.FromVector3(clickPos);

            // Add options for equipment.
            if (pawn.equipment != null)
            {
                List <Thing> things = position.GetThingList(pawn.Map);
                foreach (Thing thing in things)
                {
                    if (thing.TryGetComp <CompEquippable>() != null)
                    {
                        ThingWithComps equipment = (ThingWithComps)thing;

                        if (equipment.def.IsWeapon &&
                            !pawn.WorkTagIsDisabled(WorkTags.Violent) &&
                            pawn.CanReach(equipment, PathEndMode.ClosestTouch, Danger.Deadly) &&
                            pawn.health.capacities.CapableOf(PawnCapacityDefOf.Manipulation) &&
                            !(pawn.IsQuestLodger() && (!equipment.def.IsWeapon || pawn.equipment.Primary != null)) &&
                            EquipmentUtility.CanEquip(equipment, pawn, out _))
                        {
                            string text3 = UIText.AIEquip.Translate(thing.LabelShort);
                            if (equipment.def.IsRangedWeapon && pawn.story != null && pawn.story.traits.HasTrait(TraitDefOf.Brawler))
                            {
                                text3 += " " + UIText.EquipWarningBrawler.Translate();
                            }

                            var option = FloatMenuUtility.DecoratePrioritizedTask(
                                new FloatMenuOption(
                                    text3,
                                    () =>
                            {
                                TaggedString equipWeaponConfirmationDialogText = ThingRequiringRoyalPermissionUtility.GetEquipWeaponConfirmationDialogText(equipment, pawn);
                                CompBladelinkWeapon compBladelinkWeapon        = equipment.TryGetComp <CompBladelinkWeapon>();
                                if (compBladelinkWeapon != null && compBladelinkWeapon.bondedPawn != pawn)
                                {
                                    if (!equipWeaponConfirmationDialogText.NullOrEmpty())
                                    {
                                        equipWeaponConfirmationDialogText += "\n\n";
                                    }

                                    equipWeaponConfirmationDialogText += "BladelinkEquipWarning".Translate();
                                }

                                if (!equipWeaponConfirmationDialogText.NullOrEmpty())
                                {
                                    equipWeaponConfirmationDialogText += "\n\n" + "RoyalWeaponEquipConfirmation".Translate();
                                    Find.WindowStack.Add(
                                        new Dialog_MessageBox(
                                            equipWeaponConfirmationDialogText,
                                            "Yes".Translate(),
                                            () =>
                                    {
                                        Equip();
                                    },
                                            "No".Translate()));
                                }
                                else
                                {
                                    Equip();
                                }
                            },
                                    MenuOptionPriority.High),
                                pawn,
                                equipment);
                            opts.Add(option);
                        }

                        void Equip()
                        {
                            equipment.SetForbidden(value: false);
                            pawn.jobs.TryTakeOrderedJob(JobMaker.MakeJob(AwesomeInventory_JobDefOf.AwesomeInventory_MapEquip, equipment));
                            MoteMaker.MakeStaticMote(equipment.DrawPos, equipment.Map, ThingDefOf.Mote_FeedbackEquip);
                            PlayerKnowledgeDatabase.KnowledgeDemonstrated(ConceptDefOf.EquippingWeapons, KnowledgeAmount.Total);
                        }
                    }
                }
            }

            // Add options for apparel.
            if (pawn.apparel != null)
            {
                Apparel apparel = pawn.Map.thingGrid.ThingAt <Apparel>(position);
                if (apparel != null)
                {
                    if (pawn.CanReach(apparel, PathEndMode.ClosestTouch, Danger.Deadly) &&
                        !apparel.IsBurning() &&
                        !pawn.apparel.WouldReplaceLockedApparel(apparel) &&
                        ApparelUtility.HasPartsToWear(pawn, apparel.def))
                    {
                        FloatMenuOption option = FloatMenuUtility.DecoratePrioritizedTask(
                            new FloatMenuOption(
                                UIText.AIForceWear.Translate(apparel.LabelShort),
                                () =>
                        {
                            DressJob dressJob  = SimplePool <DressJob> .Get();
                            dressJob.def       = AwesomeInventory_JobDefOf.AwesomeInventory_Dress;
                            dressJob.targetA   = apparel;
                            dressJob.ForceWear = true;

                            apparel.SetForbidden(value: false);
                            pawn.jobs.TryTakeOrderedJob(dressJob);
                        },
                                MenuOptionPriority.High),
                            pawn,
                            apparel);
                        opts.Add(option);

                        option = FloatMenuUtility.DecoratePrioritizedTask(
                            new FloatMenuOption(
                                UIText.AIWear.Translate(apparel.LabelShort),
                                () =>
                        {
                            DressJob dressJob  = SimplePool <DressJob> .Get();
                            dressJob.def       = AwesomeInventory_JobDefOf.AwesomeInventory_Dress;
                            dressJob.targetA   = apparel;
                            dressJob.ForceWear = false;

                            apparel.SetForbidden(value: false);
                            pawn.jobs.TryTakeOrderedJob(dressJob);
                        },
                                MenuOptionPriority.High),
                            pawn,
                            apparel);
                        opts.Add(option);
                    }
                }
            }

            List <Thing> items = position.GetThingList(pawn.Map);

            foreach (Thing item in items)
            {
                if (item.def.category == ThingCategory.Item)
                {
                    int count = MassUtility.CountToPickUpUntilOverEncumbered(pawn, item);
                    if (count == 0)
                    {
                        continue;
                    }

                    count = Math.Min(count, item.stackCount);

                    string displayText = UIText.Pickup.Translate(item.LabelNoCount + " x" + count);
                    var    option      = FloatMenuUtility.DecoratePrioritizedTask(
                        new FloatMenuOption(
                            displayText
                            , () =>
                    {
                        Job job   = JobMaker.MakeJob(JobDefOf.TakeInventory, item);
                        job.count = count;
                        pawn.jobs.TryTakeOrderedJob(job);
                    })
                        , pawn
                        , item);
                    opts.Add(option);
                }
            }
        }
 public override IEnumerable <string> ConfigErrors()
 {
     foreach (string err in this.< ConfigErrors > __BaseCallProxy0())
     {
         yield return(err);
     }
     if (this.race == null)
     {
         yield return("no race");
     }
     else if (this.RaceProps.Humanlike && this.backstoryCategory.NullOrEmpty())
     {
         yield return("Humanlike needs backstoryCategory.");
     }
     if (this.baseRecruitDifficulty > 1.0001f)
     {
         yield return(this.defName + " recruitDifficulty is greater than 1. 1 means impossible to recruit.");
     }
     if (this.combatPower < 0f)
     {
         yield return(this.defName + " has no combatPower.");
     }
     if (this.weaponMoney != FloatRange.Zero)
     {
         float minCost = 999999f;
         int   i;
         for (i = 0; i < this.weaponTags.Count; i++)
         {
             IEnumerable <ThingDef> source = from d in DefDatabase <ThingDef> .AllDefs
                                             where d.weaponTags != null && d.weaponTags.Contains(this.weaponTags[i])
                                             select d;
             if (source.Any <ThingDef>())
             {
                 minCost = Mathf.Min(minCost, source.Min((ThingDef d) => PawnWeaponGenerator.CheapestNonDerpPriceFor(d)));
             }
         }
         if (minCost > this.weaponMoney.min)
         {
             yield return(string.Concat(new object[]
             {
                 "Cheapest weapon with one of my weaponTags costs ",
                 minCost,
                 " but weaponMoney min is ",
                 this.weaponMoney.min,
                 ", so could end up weaponless."
             }));
         }
     }
     if (!this.RaceProps.Humanlike && this.lifeStages.Count != this.RaceProps.lifeStageAges.Count)
     {
         yield return(string.Concat(new object[]
         {
             "PawnKindDef defines ",
             this.lifeStages.Count,
             " lifeStages while race def defines ",
             this.RaceProps.lifeStageAges.Count
         }));
     }
     if (this.apparelRequired != null)
     {
         for (int k = 0; k < this.apparelRequired.Count; k++)
         {
             for (int j = k + 1; j < this.apparelRequired.Count; j++)
             {
                 if (!ApparelUtility.CanWearTogether(this.apparelRequired[k], this.apparelRequired[j], this.race.race.body))
                 {
                     yield return(string.Concat(new object[]
                     {
                         "required apparel can't be worn together (",
                         this.apparelRequired[k],
                         ", ",
                         this.apparelRequired[j],
                         ")"
                     }));
                 }
             }
         }
     }
     yield break;
 }
        public void Hide(IntVec3 pos, Map map, CompProperties_ReactiveDefense props)
        {
            if (props.statDefs == null || props.statDefs.Count == 0 || props.statValues == null || props.statValues.Count == 0 || props.statDefs.Count != props.statValues.Count)
            {
                return;
            }
            Pawn pawn = (Pawn)parent;

            if (pawn.Dead)
            {
                if (pawn.apparel.WornApparel.Count > 0)
                {
                    List <Apparel> tap = pawn.apparel.WornApparel.ToList();
                    foreach (Apparel apparel in tap)
                    {
                        pawn.apparel.Remove(apparel);
                    }
                }
                return;
            }

            if (((Pawn)parent).health.hediffSet.GetPartHealth(((Pawn)parent).RaceProps.body.corePart) < ((Pawn)parent).RaceProps.body.corePart.def.hitPoints * props.hpThreshold * ((Pawn)parent).def.race.baseHealthScale)
            {
                //Log.Error("a");
                if (!hidden)
                {
                    if (Props.apparel != null)
                    {
                        Apparel apparel = (Apparel)ThingMaker.MakeThing(Props.apparel);
                        for (int i = 0; i < props.statDefs.Count; i++)
                        {
                            apparel.def.SetStatBaseValue(props.statDefs[i], props.statValues[i]);
                        }
                        if (ApparelUtility.HasPartsToWear(pawn, apparel.def))
                        {
                            if (pawn.apparel == null)
                            {
                                pawn.apparel = new Pawn_ApparelTracker(pawn);
                            }
                            pawn.apparel.Wear(apparel, false);
                        }
                    }
                    if (Props.stopAttacker && !stoppedAttacker)
                    {
                        ((Pawn)lastattack.Instigator).jobs.StartJob(new Job(JobDefOf.Wait_Wander), JobCondition.InterruptForced);
                        stoppedAttacker = true;
                    }
                    ResolveHideGraphic();
                    hidden = true;
                    pawn.jobs.StartJob(new Job(JobDefOf.FleeAndCower, pawn.Position), JobCondition.InterruptForced);
                }
                else
                {
                    //prevent from moving
                    pawn.pather.StopDead();
                }
            }
            else
            {
                if (hidden)
                {
                    if (Props.apparel != null && pawn.apparel != null)
                    {
                        pawn.apparel.DestroyAll();
                    }
                    ResolveBaseGraphic();
                    hidden          = false;
                    stoppedAttacker = false;


                    //allow to move again
//					pawn.pather.ResetToCurrentPosition();
                    pawn.pather.StartPath(pawn.Position, PathEndMode.OnCell);
                }
            }
        }
Exemple #16
0
        static float ApparelScoreRawInsulation(Pawn pawn, Apparel apparel, ExtendedOutfit outfit, NeededWarmth neededWarmth)
        {
            float insulation;

            if (outfit.targetTemperaturesOverride)
            {
                // NOTE: We can't rely on the vanilla check for taking off gear for temperature, because
                // we need to consider all the wardrobe changes taken together; each individual change may
                // note push us over the thresholds, but several changes together may.
                // Return 1 for temperature offsets here, we'll look at the effects of any gear we have to
                // take off below.
                // NOTE: This is still suboptimal, because we're still only considering one piece of apparel
                // to wear at each time. A better solution would be reducing the problem to a series of linear
                // equations, and then solving that system.
                // I'm not sure that's feasible at all; first off for simple computational reasons: the linear
                // system to solve would be fairly massive, optimizing for dozens of pawns and hundreds of pieces
                // of gear simultaneously. Second, many of the stat functions aren't actually linear, and would
                // have to be made to be linear.
                if (pawn.apparel.WornApparel.Contains(apparel))
                {
                    return(1f);
                }

                var currentRange   = pawn.ComfortableTemperatureRange();
                var candidateRange = currentRange;
                var targetRange    = outfit.targetTemperatures;
                var apparelOffset  = GetInsulationStats(apparel);

                // effect of this piece of apparel
                candidateRange.min += apparelOffset.min;
                candidateRange.max += apparelOffset.max;
                foreach (var otherApparel in pawn.apparel.WornApparel)
                {
                    // effect of taking off any other apparel that is incompatible
                    if (!ApparelUtility.CanWearTogether(apparel.def, otherApparel.def, pawn.RaceProps.body))
                    {
                        var otherInsulationRange = GetInsulationStats(otherApparel);

                        candidateRange.min -= otherInsulationRange.min;
                        candidateRange.max -= otherInsulationRange.max;
                    }
                }

                // did we get any closer to our target range? (smaller distance is better, negative values are overkill).
                var currentDistance = new FloatRange(Mathf.Max(currentRange.min - targetRange.min, 0f),
                                                     Mathf.Max(targetRange.max - currentRange.max, 0f));
                var candidateDistance = new FloatRange(Mathf.Max(candidateRange.min - targetRange.min, 0f),
                                                       Mathf.Max(targetRange.max - candidateRange.max, 0f));

                // improvement in distances
                insulation = InsulationFactorCurve.Evaluate(currentDistance.min - candidateDistance.min) +
                             InsulationFactorCurve.Evaluate(currentDistance.max - candidateDistance.max);
#if DEBUG
                Log.Message($"{pawn.Name.ToStringShort} :: {apparel.LabelCap}\n" +
                            $"\ttarget range: {targetRange}, current range: {currentRange}, candidate range {candidateRange}\n" +
                            $"\tcurrent distance: {currentDistance}, candidate distance: {candidateDistance}\n" +
                            $"\timprovement: {(currentDistance.min - candidateDistance.min) + (currentDistance.max - candidateDistance.max)}, insulation score: {insulation}\n");
#endif
            }
            else
            {
                float statValue;
                if (neededWarmth == NeededWarmth.Warm)
                {
                    statValue  = apparel.GetStatValue(StatDefOf.Insulation_Cold, true);
                    insulation = InsulationTemperatureScoreFactorCurve_Need.Evaluate(statValue);
                }
                else if (neededWarmth == NeededWarmth.Cool)
                {
                    statValue  = apparel.GetStatValue(StatDefOf.Insulation_Heat, true);
                    insulation = InsulationTemperatureScoreFactorCurve_Need.Evaluate(statValue);
                }
                else
                {
                    insulation = 1f;
                }
            }
            return(insulation);
        }
Exemple #17
0
        public static void PawnFinaliser(Pawn pawn)
        {
            int meleeSkill = pawn.skills.GetSkill(skillDef: Defs_Rimworld.MeleeSkill).Level;

            if (meleeSkill < 10)
            {
                pawn.skills.GetSkill(skillDef: Defs_Rimworld.MeleeSkill).Level += Rand.RangeInclusive(min: 10 - meleeSkill, max: 10 - meleeSkill + 5);
            }

            float[] choiceArray = { 10 - NVGameComponent.Evilness, 5 + NVGameComponent.Evilness, 5 + NVGameComponent.Evilness };
            var     indexes     = new[] { 0, 1, 2 };

            int choice = indexes.RandomElementByWeight(weightSelector: ind => choiceArray[ind]);

            switch (choice)
            {
            case 1:

                if (PawnGenUtility.AnyPSHediffsExist.IsNotFalse())
                {
                    foreach (BodyPartRecord bodyPartRecord in pawn.RaceProps.body.GetPartsWithTag(tag: Defs_Rimworld.EyeTag))
                    {
                        HediffDef hediff = PawnGenUtility.GetRandomPhotosensitiveHediffDef();

                        if (hediff != null)
                        {
                            pawn.health.AddHediff(def: hediff, part: bodyPartRecord);
                        }
                    }

                    if (ApparelGenUtility.GetNullPSApparelDefByTag(tagsList: pawn.kindDef.apparelTags) is ThingDef appDef)
                    {
                        if (ApparelUtility.HasPartsToWear(p: pawn, apparel: appDef))
                        {
                            Thing apparel = ThingMaker.MakeThing(
                                def: appDef,
                                stuff: appDef.MadeFromStuff ? GenStuff.RandomStuffByCommonalityFor(td: appDef) : null
                                );

                            pawn.apparel.Wear(newApparel: (Apparel)apparel, dropReplacedApparel: false);
                        }
                    }

                    break;
                }
                else
                {
                    goto case 2;
                }

            case 2:

                if (ApparelGenUtility.GetGiveNVApparelDefByTag(tagsList: pawn.kindDef.apparelTags) is ThingDef nvAppDef)
                {
                    if (ApparelUtility.HasPartsToWear(p: pawn, apparel: nvAppDef))
                    {
                        Thing apparel = ThingMaker.MakeThing(
                            def: nvAppDef,
                            stuff: nvAppDef.MadeFromStuff ? GenStuff.RandomStuffByCommonalityFor(td: nvAppDef) : null
                            );
                        PawnGenerator.PostProcessGeneratedGear(apparel, pawn);
                        pawn.apparel.Wear(newApparel: (Apparel)apparel, dropReplacedApparel: false);
                    }
                }

                break;
            }

            if (Rand.Chance(chance: NVGameComponent.Evilness / 8f))
            {
                ThingDef shield = Defs_Rimworld.ShieldDef;

                if (ApparelUtility.HasPartsToWear(p: pawn, apparel: shield))
                {
                    Thing shieldBelt = ThingMaker.MakeThing(def: shield, stuff: shield.MadeFromStuff ? GenStuff.RandomStuffFor(td: shield) : null);
                    PawnGenerator.PostProcessGeneratedGear(shieldBelt, pawn);
                    pawn.apparel.Wear(newApparel: (Apparel)shieldBelt, dropReplacedApparel: false);
                }
            }
        }
Exemple #18
0
        public override void DoWindowContents(Rect inRect)
        {
            ApparelStatCache apparelStatCache = this._pawn.GetApparelStatCache();
            Outfit           currentOutfit    = this._pawn.outfits.CurrentOutfit;

            if (this._dict == null || Find.TickManager.TicksGame % 60 == 0 || GUI.changed)
            {
                List <Apparel> ap = new List <Apparel>(this._pawn.Map.listerThings.ThingsInGroup(ThingRequestGroup.Apparel).OfType <Apparel>().Where(
                                                           x => x.Map.haulDestinationManager.SlotGroupAt(x.Position) != null));

                foreach (Pawn otherPawn in PawnsFinder.AllMaps_FreeColonists.Where(x => x.Map == this._pawn.Map))
                {
                    foreach (Apparel pawnApparel in otherPawn.apparel.WornApparel)
                    {
                        if (otherPawn.outfits.forcedHandler.AllowedToAutomaticallyDrop(pawnApparel))
                        {
                            ap.Add(pawnApparel);
                        }
                    }
                }

                ap = ap.Where(
                    i => !ApparelUtility.CanWearTogether(this._apparel.def, i.def, this._pawn.RaceProps.body) &&
                    currentOutfit.filter.Allows(i)).ToList();


                ap = ap.OrderByDescending(
                    i =>
                {
                    float g = this._pawn.ApparelScoreGain(i);
                    return(g);
                }).ToList();

                this._dict = new Dictionary <Apparel, float>();
                foreach (Apparel currentAppel in ap)
                {
                    float gain = this._pawn.ApparelScoreGain(currentAppel);
                    this._dict.Add(currentAppel, gain);
                }
            }

            Rect groupRect = inRect.ContractedBy(10f);

            groupRect.height -= 100;
            GUI.BeginGroup(groupRect);


            float apparelLabelWidth    = (groupRect.width - 2 * ScoreWidth) / 3 - 8f - 8f;
            float apparelEquippedWidth = apparelLabelWidth;
            float apparelOwnerWidth    = apparelLabelWidth;

            Rect itemRect = new Rect(groupRect.xMin + 4f, groupRect.yMin, groupRect.width - 8f, 28f);

            this.DrawLine(
                ref itemRect,
                null,
                "Apparel",
                apparelLabelWidth,
                null,
                "Equiped",
                apparelEquippedWidth,
                null,
                "Target",
                apparelOwnerWidth,
                "Score",
                "Gain");

            groupRect.yMin += itemRect.height;
            Widgets.DrawLineHorizontal(groupRect.xMin, groupRect.yMin, groupRect.width);
            groupRect.yMin   += 4f;
            groupRect.height -= 4f;
            groupRect.height -= Text.LineHeight * 1.2f * 3f;

            Rect viewRect = new Rect(
                groupRect.xMin,
                groupRect.yMin,
                groupRect.width - 16f, this._dict.Count * 28f + 16f);

            if (viewRect.height < groupRect.height)
            {
                groupRect.height = viewRect.height;
            }

            Rect listRect = viewRect.ContractedBy(4f);

            Widgets.BeginScrollView(groupRect, ref this._scrollPosition, viewRect);


            foreach (KeyValuePair <Apparel, float> kvp in this._dict)
            {
                Apparel currentAppel = kvp.Key;
                float   gain         = kvp.Value;

                itemRect = new Rect(listRect.xMin, listRect.yMin, listRect.width, 28f);
                if (Mouse.IsOver(itemRect))
                {
                    GUI.DrawTexture(itemRect, TexUI.HighlightTex);
                    GUI.color = Color.white;
                }

                Pawn equipped = currentAppel.Wearer;
                Pawn target   = null;

                string gainString = this._pawn.outfits.forcedHandler.AllowedToAutomaticallyDrop(currentAppel)
                                        ? gain.ToString("N3")
                                        : "No Allow";

                this.DrawLine(
                    ref itemRect,
                    currentAppel,
                    currentAppel.LabelCap,
                    apparelLabelWidth,
                    equipped,
                    equipped?.LabelCap,
                    apparelEquippedWidth,
                    target,
                    target?.LabelCap,
                    apparelOwnerWidth,
                    apparelStatCache.ApparelScoreRaw(currentAppel).ToString("N3"),
                    gainString
                    );

                listRect.yMin = itemRect.yMax;
            }

            Widgets.EndScrollView();

            Widgets.DrawLineHorizontal(groupRect.xMin, groupRect.yMax, groupRect.width);

            GUI.color   = Color.white;
            Text.Anchor = TextAnchor.UpperLeft;
            GUI.EndGroup();
        }
Exemple #19
0
        internal static List <FloatMenuOption> ChoicesAtFor(Vector3 clickPos, Pawn pawn)
        {
            IntVec3 clickCell = IntVec3.FromVector3(clickPos);

            DangerUtility.NotifyDirectOrderingThisFrame(pawn);
            List <FloatMenuOption> list = new List <FloatMenuOption>();

            if (!clickCell.InBounds())
            {
                return(list);
            }

            // ***** Beginning of drafted options *****

            if (pawn.Drafted)
            {
                foreach (TargetInfo attackTarg in GenUI.TargetsAt(clickPos, TargetingParameters.ForAttackHostile(), true))
                {
                    // *** Fire at option ***

                    if (pawn.equipment.Primary != null && !pawn.equipment.PrimaryEq.PrimaryVerb.verbProps.MeleeRange)
                    {
                        string str;
                        Action rangedAct = FloatMenuUtility.GetRangedAttackAction(pawn, attackTarg, out str);
                        string text      = "FireAt".Translate(new object[]
                        {
                            attackTarg.Thing.LabelCap
                        });
                        FloatMenuOption floatMenuOption = new FloatMenuOption();
                        floatMenuOption.priority = MenuOptionPriority.High;
                        if (rangedAct == null)
                        {
                            text = text + " (" + str + ")";
                        }
                        else
                        {
                            floatMenuOption.autoTakeable = true;
                            floatMenuOption.action       = new Action(delegate
                            {
                                MoteThrower.ThrowStatic(attackTarg.Thing.DrawPos, ThingDefOf.Mote_FeedbackAttack, 1f);
                                rangedAct();
                            });
                        }
                        floatMenuOption.label = text;
                        list.Add(floatMenuOption);
                    }

                    // *** Melee attack option ***

                    string str2;
                    Action meleeAct = FloatMenuUtility.GetMeleeAttackAction(pawn, attackTarg, out str2);
                    Pawn   pawn2    = attackTarg.Thing as Pawn;
                    string text2;
                    if (pawn2 != null && pawn2.Downed)
                    {
                        text2 = "MeleeAttackToDeath".Translate(new object[]
                        {
                            attackTarg.Thing.LabelCap
                        });
                    }
                    else
                    {
                        text2 = "MeleeAttack".Translate(new object[]
                        {
                            attackTarg.Thing.LabelCap
                        });
                    }
                    Thing           thing            = attackTarg.Thing;
                    FloatMenuOption floatMenuOption2 = new FloatMenuOption(string.Empty, null, MenuOptionPriority.High, null, thing);
                    if (meleeAct == null)
                    {
                        text2 = text2 + " (" + str2 + ")";
                    }
                    else
                    {
                        floatMenuOption2.action = new Action(delegate
                        {
                            MoteThrower.ThrowStatic(attackTarg.Thing.DrawPos, ThingDefOf.Mote_FeedbackAttack, 1f);
                            meleeAct();
                        });
                    }
                    floatMenuOption2.label = text2;
                    list.Add(floatMenuOption2);
                }

                // *** Arrest option ***

                if (pawn.RaceProps.Humanlike && !pawn.Downed)
                {
                    foreach (TargetInfo current2 in GenUI.TargetsAt(clickPos, TargetingParameters.ForArrest(pawn), true))
                    {
                        TargetInfo dest = current2;
                        if (!pawn.CanReach(dest, PathEndMode.OnCell, Danger.Deadly, false, TraverseMode.ByPawn))
                        {
                            list.Add(new FloatMenuOption("CannotArrest".Translate() + " (" + "NoPath".Translate() + ")", null, MenuOptionPriority.Medium, null, null));
                        }
                        else if (!pawn.CanReserve(dest.Thing, 1))
                        {
                            list.Add(new FloatMenuOption("CannotArrest".Translate() + ": " + "Reserved".Translate(), null, MenuOptionPriority.Medium, null, null));
                        }
                        else
                        {
                            Pawn   pTarg  = (Pawn)dest.Thing;
                            Action action = new Action(delegate
                            {
                                Building_Bed building_Bed = RestUtility.FindBedFor(pTarg, pawn, true, false, false);
                                if (building_Bed == null)
                                {
                                    Messages.Message("CannotArrest".Translate() + ": " + "NoPrisonerBed".Translate(), pTarg, MessageSound.RejectInput);
                                    return;
                                }
                                Job job           = new Job(JobDefOf.Arrest, pTarg, building_Bed);
                                job.playerForced  = true;
                                job.maxNumToCarry = 1;
                                pawn.drafter.TakeOrderedJob(job);
                                TutorUtility.DoModalDialogIfNotKnown(ConceptDefOf.ArrestingCreatesEnemies);
                            });
                            List <FloatMenuOption> arg_3F1_0 = list;
                            Thing thing = dest.Thing;
                            arg_3F1_0.Add(new FloatMenuOption("TryToArrest".Translate(new object[]
                            {
                                dest.Thing.LabelCap
                            }), action, MenuOptionPriority.Medium, null, thing));
                        }
                    }
                }

                // *** Goto option ***

                int num = GenRadial.NumCellsInRadius(2.9f);
                for (int i = 0; i < num; i++)
                {
                    IntVec3 curLoc = GenRadial.RadialPattern[i] + clickCell;
                    if (curLoc.Standable())
                    {
                        if (curLoc != pawn.Position)
                        {
                            if (!pawn.CanReach(curLoc, PathEndMode.OnCell, Danger.Deadly, false, TraverseMode.ByPawn))
                            {
                                FloatMenuOption item = new FloatMenuOption("CannotGoNoPath".Translate(), null, MenuOptionPriority.Low, null, null);
                                list.Add(item);
                            }
                            else
                            {
                                Action action2 = new Action(delegate
                                {
                                    IntVec3 dest     = Pawn_DraftController.BestGotoDestNear(curLoc, pawn);
                                    Job job          = new Job(JobDefOf.Goto, dest);
                                    job.playerForced = true;
                                    pawn.drafter.TakeOrderedJob(job);
                                    MoteThrower.ThrowStatic(dest, ThingDefOf.Mote_FeedbackGoto, 1f);
                                });
                                list.Add(new FloatMenuOption("GoHere".Translate(), action2, MenuOptionPriority.Low, null, null)
                                {
                                    autoTakeable = true
                                });
                            }
                        }
                        break;
                    }
                }
            }

            // *** End of drafted options ***

            // *** Beginning of humanlike options ***

            if (pawn.RaceProps.Humanlike)
            {
                int num2 = 0;
                if (pawn.story != null)
                {
                    num2 = pawn.story.traits.DegreeOfTrait(TraitDefOf.DrugDesire);
                }

                // *** Consume option ***

                foreach (Thing current3 in clickCell.GetThingList())
                {
                    Thing t = current3;
                    if (t.def.ingestible != null && pawn.RaceProps.CanEverEat(t) && t.IngestibleNow)
                    {
                        FloatMenuOption item2;
                        if (t.def.ingestible.isPleasureDrug && num2 < 0)
                        {
                            item2 = new FloatMenuOption("ConsumeThing".Translate(new object[]
                            {
                                t.LabelBaseShort
                            }) + " (" + "Teetotaler".Translate() + ")", null, MenuOptionPriority.Medium, null, null);
                        }
                        else if (!pawn.CanReach(t, PathEndMode.OnCell, Danger.Deadly, false, TraverseMode.ByPawn))
                        {
                            item2 = new FloatMenuOption("ConsumeThing".Translate(new object[]
                            {
                                t.LabelBaseShort
                            }) + " (" + "NoPath".Translate() + ")", null, MenuOptionPriority.Medium, null, null);
                        }
                        else if (!pawn.CanReserve(t, 1))
                        {
                            item2 = new FloatMenuOption("ConsumeThing".Translate(new object[]
                            {
                                t.LabelBaseShort
                            }) + " (" + "ReservedBy".Translate(new object[]
                            {
                                Find.Reservations.FirstReserverOf(t, pawn.Faction).LabelBaseShort
                            }) + ")", null, MenuOptionPriority.Medium, null, null);
                        }
                        else
                        {
                            item2 = new FloatMenuOption("ConsumeThing".Translate(new object[]
                            {
                                t.LabelBaseShort
                            }), new Action(delegate
                            {
                                t.SetForbidden(false, true);
                                Job job           = new Job(JobDefOf.Ingest, t);
                                job.maxNumToCarry = t.def.ingestible.maxNumToIngestAtOnce;
                                pawn.drafter.TakeOrderedJob(job);
                            }), MenuOptionPriority.Medium, null, null);
                        }
                        list.Add(item2);
                    }
                }

                // *** Rescue/Capture downed option ***

                foreach (TargetInfo current4 in GenUI.TargetsAt(clickPos, TargetingParameters.ForRescue(pawn), true))
                {
                    Pawn victim = (Pawn)current4.Thing;
                    if (!victim.InBed() && pawn.CanReserveAndReach(victim, PathEndMode.OnCell, Danger.Deadly, 1) && !victim.IsPrisonerOfColony)
                    {
                        if ((victim.Faction == Faction.OfColony && victim.MentalStateDef == null) || (victim.Faction != Faction.OfColony && victim.MentalStateDef == null && !victim.IsPrisonerOfColony && (victim.Faction == null || !victim.Faction.HostileTo(Faction.OfColony))))
                        {
                            List <FloatMenuOption> arg_8E1_0 = list;
                            Pawn victim2 = victim;
                            arg_8E1_0.Add(new FloatMenuOption("Rescue".Translate(new object[]
                            {
                                victim2.LabelCap
                            }), new Action(delegate
                            {
                                Building_Bed building_Bed = RestUtility.FindBedFor(victim, pawn, false, false, false);
                                if (building_Bed == null)
                                {
                                    string str;
                                    if (victim.RaceProps.Animal)
                                    {
                                        str = "NoAnimalBed".Translate();
                                    }
                                    else
                                    {
                                        str = "NoNonPrisonerBed".Translate();
                                    }
                                    Messages.Message("CannotRescue".Translate() + ": " + str, victim, MessageSound.RejectInput);
                                    return;
                                }
                                Job job           = new Job(JobDefOf.Rescue, victim, building_Bed);
                                job.maxNumToCarry = 1;
                                job.playerForced  = true;
                                pawn.drafter.TakeOrderedJob(job);
                                ConceptDatabase.KnowledgeDemonstrated(ConceptDefOf.Rescuing, KnowledgeAmount.Total);
                            }), MenuOptionPriority.Medium, null, victim2));
                        }
                        if (victim.MentalStateDef != null || (victim.RaceProps.Humanlike && victim.Faction != Faction.OfColony))
                        {
                            List <FloatMenuOption> arg_962_0 = list;
                            Pawn victim2 = victim;
                            arg_962_0.Add(new FloatMenuOption("Capture".Translate(new object[]
                            {
                                victim2.LabelCap
                            }), new Action(delegate
                            {
                                Building_Bed building_Bed = RestUtility.FindBedFor(victim, pawn, true, false, false);
                                if (building_Bed == null)
                                {
                                    Messages.Message("CannotCapture".Translate() + ": " + "NoPrisonerBed".Translate(), victim, MessageSound.RejectInput);
                                    return;
                                }
                                Job job           = new Job(JobDefOf.Capture, victim, building_Bed);
                                job.maxNumToCarry = 1;
                                job.playerForced  = true;
                                pawn.drafter.TakeOrderedJob(job);
                                ConceptDatabase.KnowledgeDemonstrated(ConceptDefOf.Capturing, KnowledgeAmount.Total);
                            }), MenuOptionPriority.Medium, null, victim2));
                        }
                    }
                }

                // *** Carry to cryosleep option ***

                foreach (TargetInfo current5 in GenUI.TargetsAt(clickPos, TargetingParameters.ForRescue(pawn), true))
                {
                    TargetInfo targetInfo = current5;
                    Pawn       victim     = (Pawn)targetInfo.Thing;
                    if (victim.Downed && pawn.CanReserveAndReach(victim, PathEndMode.OnCell, Danger.Deadly, 1) && Building_CryptosleepCasket.FindCryptosleepCasketFor(victim, pawn) != null)
                    {
                        string label = "CarryToCryptosleepCasket".Translate(new object[]
                        {
                            targetInfo.Thing.LabelCap
                        });
                        JobDef jDef    = JobDefOf.CarryToCryptosleepCasket;
                        Action action3 = new Action(delegate
                        {
                            Building_CryptosleepCasket building_CryptosleepCasket = Building_CryptosleepCasket.FindCryptosleepCasketFor(victim, pawn);
                            if (building_CryptosleepCasket == null)
                            {
                                Messages.Message("CannotCarryToCryptosleepCasket".Translate() + ": " + "NoCryptosleepCasket".Translate(), victim, MessageSound.RejectInput);
                                return;
                            }
                            Job job           = new Job(jDef, victim, building_CryptosleepCasket);
                            job.maxNumToCarry = 1;
                            job.playerForced  = true;
                            pawn.drafter.TakeOrderedJob(job);
                        });
                        List <FloatMenuOption> arg_A80_0 = list;
                        Pawn victim2 = victim;
                        arg_A80_0.Add(new FloatMenuOption(label, action3, MenuOptionPriority.Medium, null, victim2));
                    }
                }

                // *** Strip option ***

                foreach (TargetInfo current6 in GenUI.TargetsAt(clickPos, TargetingParameters.ForStrip(pawn), true))
                {
                    TargetInfo      stripTarg = current6;
                    FloatMenuOption item3;
                    if (!pawn.CanReach(stripTarg, PathEndMode.ClosestTouch, Danger.Deadly, false, TraverseMode.ByPawn))
                    {
                        item3 = new FloatMenuOption("CannotStrip".Translate(new object[]
                        {
                            stripTarg.Thing.LabelCap
                        }) + " (" + "NoPath".Translate() + ")", null, MenuOptionPriority.Medium, null, null);
                    }
                    else if (!pawn.CanReserveAndReach(stripTarg, PathEndMode.ClosestTouch, Danger.Deadly, 1))
                    {
                        item3 = new FloatMenuOption("CannotStrip".Translate(new object[]
                        {
                            stripTarg.Thing.LabelCap
                        }) + " (" + "ReservedBy".Translate(new object[]
                        {
                            Find.Reservations.FirstReserverOf(stripTarg, pawn.Faction).LabelBaseShort
                        }) + ")", null, MenuOptionPriority.Medium, null, null);
                    }
                    else
                    {
                        item3 = new FloatMenuOption("Strip".Translate(new object[]
                        {
                            stripTarg.Thing.LabelCap
                        }), new Action(delegate
                        {
                            stripTarg.Thing.SetForbidden(false, false);
                            Job job          = new Job(JobDefOf.Strip, stripTarg);
                            job.playerForced = true;
                            pawn.drafter.TakeOrderedJob(job);
                        }), MenuOptionPriority.Medium, null, null);
                    }
                    list.Add(item3);
                }

                // *** Equip option ***

                CompInventory compInventory = pawn.TryGetComp <CompInventory>();      // Need compInventory here for equip and wear options

                if (pawn.equipment != null)
                {
                    ThingWithComps equipment = null;
                    List <Thing>   thingList = clickCell.GetThingList();
                    for (int j = 0; j < thingList.Count; j++)
                    {
                        if (thingList[j].TryGetComp <CompEquippable>() != null)
                        {
                            equipment = (ThingWithComps)thingList[j];
                            break;
                        }
                    }
                    if (equipment != null)
                    {
                        string          eqLabel = GenLabel.ThingLabel(equipment.def, equipment.Stuff, 1);
                        FloatMenuOption equipOption;
                        if (!pawn.CanReach(equipment, PathEndMode.ClosestTouch, Danger.Deadly, false, TraverseMode.ByPawn))
                        {
                            equipOption = new FloatMenuOption("CannotEquip".Translate(new object[]
                            {
                                eqLabel
                            }) + " (" + "NoPath".Translate() + ")", null, MenuOptionPriority.Medium, null, null);
                        }
                        else if (!pawn.CanReserve(equipment, 1))
                        {
                            equipOption = new FloatMenuOption("CannotEquip".Translate(new object[]
                            {
                                eqLabel
                            }) + " (" + "ReservedBy".Translate(new object[]
                            {
                                Find.Reservations.FirstReserverOf(equipment, pawn.Faction).LabelBaseShort
                            }) + ")", null, MenuOptionPriority.Medium, null, null);
                        }
                        else if (!pawn.health.capacities.CapableOf(PawnCapacityDefOf.Manipulation))
                        {
                            equipOption = new FloatMenuOption("CannotEquip".Translate(new object[]
                            {
                                eqLabel
                            }) + " (" + "Incapable".Translate() + ")", null, MenuOptionPriority.Medium, null, null);
                        }
                        else
                        {
                            // Added check for inventory space here
                            int count;
                            if (compInventory != null && !compInventory.CanFitInInventory(equipment, out count, true))
                            {
                                equipOption = new FloatMenuOption("CannotEquip".Translate(new object[] { eqLabel }) + " (" + "CR_InventoryFull".Translate() + ")", null);
                            }
                            else
                            {
                                string equipOptionLabel = "Equip".Translate(new object[]
                                {
                                    eqLabel
                                });
                                if (equipment.def.IsRangedWeapon && pawn.story != null && pawn.story.traits.HasTrait(TraitDefOf.Brawler))
                                {
                                    equipOptionLabel = equipOptionLabel + " " + "EquipWarningBrawler".Translate();
                                }
                                equipOption = new FloatMenuOption(equipOptionLabel, new Action(delegate
                                {
                                    equipment.SetForbidden(false, true);
                                    Job job          = new Job(JobDefOf.Equip, equipment);
                                    job.playerForced = true;
                                    pawn.drafter.TakeOrderedJob(job);
                                    MoteThrower.ThrowStatic(equipment.DrawPos, ThingDefOf.Mote_FeedbackEquip, 1f);
                                    ConceptDatabase.KnowledgeDemonstrated(ConceptDefOf.EquippingWeapons, KnowledgeAmount.Total);
                                }), MenuOptionPriority.Medium, null, null);
                            }
                        }
                        list.Add(equipOption);
                    }
                }

                // *** Wear option ***

                if (pawn.apparel != null)
                {
                    Apparel apparel = Find.ThingGrid.ThingAt <Apparel>(clickCell);
                    if (apparel != null)
                    {
                        FloatMenuOption wearOption;
                        if (!pawn.CanReach(apparel, PathEndMode.ClosestTouch, Danger.Deadly, false, TraverseMode.ByPawn))
                        {
                            wearOption = new FloatMenuOption("CannotWear".Translate(new object[]
                            {
                                apparel.Label
                            }) + " (" + "NoPath".Translate() + ")", null, MenuOptionPriority.Medium, null, null);
                        }
                        else if (!pawn.CanReserve(apparel, 1))
                        {
                            Pawn pawn3 = Find.Reservations.FirstReserverOf(apparel, pawn.Faction);
                            wearOption = new FloatMenuOption("CannotWear".Translate(new object[]
                            {
                                apparel.Label
                            }) + " (" + "ReservedBy".Translate(new object[]
                            {
                                pawn3.LabelBaseShort
                            }) + ")", null, MenuOptionPriority.Medium, null, null);
                        }
                        else if (!ApparelUtility.HasPartsToWear(pawn, apparel.def))
                        {
                            wearOption = new FloatMenuOption("CannotWear".Translate(new object[]
                            {
                                apparel.Label
                            }) + " (" + "CannotWearBecauseOfMissingBodyParts".Translate() + ")", null, MenuOptionPriority.Medium, null, null);
                        }
                        else
                        {
                            // Added check for inventory capacity
                            int count;
                            if (compInventory != null && !compInventory.CanFitInInventory(apparel, out count, false, true))
                            {
                                wearOption = new FloatMenuOption("CannotWear".Translate(new object[] { apparel.Label }) + " (" + "CR_InventoryFull".Translate() + ")", null);
                            }
                            else
                            {
                                wearOption = new FloatMenuOption("ForceWear".Translate(new object[] { apparel.LabelBaseShort }),
                                                                 new Action(delegate
                                {
                                    apparel.SetForbidden(false, true);
                                    Job job          = new Job(JobDefOf.Wear, apparel);
                                    job.playerForced = true;
                                    pawn.drafter.TakeOrderedJob(job);
                                }),
                                                                 MenuOptionPriority.Medium, null, null);
                            }
                        }
                        list.Add(wearOption);
                    }
                }

                // *** NEW: Pick up option ***

                if (compInventory != null)
                {
                    List <Thing> thingList = clickCell.GetThingList();
                    if (!thingList.NullOrEmpty <Thing>())
                    {
                        Thing item = thingList.FirstOrDefault(thing => thing.def.alwaysHaulable && !(thing is Corpse));
                        if (item != null)
                        {
                            FloatMenuOption pickUpOption;
                            int             count = 0;
                            if (!pawn.CanReach(item, PathEndMode.Touch, Danger.Deadly))
                            {
                                pickUpOption = new FloatMenuOption("CR_CannotPickUp".Translate() + " " + item.LabelBaseShort + " (" + "NoPath".Translate() + ")", null);
                            }
                            else if (!pawn.CanReserve(item))
                            {
                                pickUpOption = new FloatMenuOption("CR_CannotPickUp".Translate() + " " + item.LabelBaseShort + " (" + "ReservedBy".Translate(new object[] { Find.Reservations.FirstReserverOf(item, pawn.Faction) }), null);
                            }
                            else if (!compInventory.CanFitInInventory(item, out count))
                            {
                                pickUpOption = new FloatMenuOption("CR_CannotPickUp".Translate() + " " + item.LabelBaseShort + " (" + "CR_InventoryFull".Translate() + ")", null);
                            }
                            else
                            {
                                pickUpOption = new FloatMenuOption("CR_PickUp".Translate() + " " + item.LabelBaseShort,
                                                                   new Action(delegate
                                {
                                    item.SetForbidden(false);
                                    Job job = new Job(JobDefOf.TakeInventory, item)
                                    {
                                        maxNumToCarry = 1
                                    };
                                    job.playerForced = true;
                                    pawn.drafter.TakeOrderedJob(job);
                                }));
                            }
                            list.Add(pickUpOption);
                            if (count > 1 && item.stackCount > 1)
                            {
                                int             numToCarry        = Math.Min(count, item.stackCount);
                                FloatMenuOption pickUpStackOption = new FloatMenuOption("CR_PickUp".Translate() + " " + item.LabelBaseShort + " x" + numToCarry.ToString(),
                                                                                        new Action(delegate
                                {
                                    item.SetForbidden(false);
                                    Job job = new Job(JobDefOf.TakeInventory, item)
                                    {
                                        maxNumToCarry = numToCarry
                                    };
                                    job.playerForced = true;
                                    pawn.drafter.TakeOrderedJob(job);
                                }));
                                list.Add(pickUpStackOption);
                            }
                        }
                    }
                }

                // *** Deposit/drop equipment options ***

                if (pawn.equipment != null && pawn.equipment.Primary != null)
                {
                    Thing thing2 = Find.ThingGrid.ThingAt(clickCell, ThingDefOf.EquipmentRack);
                    if (thing2 != null)
                    {
                        if (!pawn.CanReach(thing2, PathEndMode.ClosestTouch, Danger.Deadly, false, TraverseMode.ByPawn))
                        {
                            list.Add(new FloatMenuOption("CannotDeposit".Translate(new object[]
                            {
                                pawn.equipment.Primary.LabelCap,
                                thing2.def.label
                            }) + " (" + "NoPath".Translate() + ")", null, MenuOptionPriority.Medium, null, null));
                        }
                        else
                        {
                            using (IEnumerator <IntVec3> enumerator7 = GenAdj.CellsOccupiedBy(thing2).GetEnumerator())
                            {
                                while (enumerator7.MoveNext())
                                {
                                    IntVec3 c = enumerator7.Current;
                                    if (c.GetStorable() == null && pawn.CanReserveAndReach(c, PathEndMode.ClosestTouch, Danger.Deadly, 1))
                                    {
                                        Action action4 = new Action(delegate
                                        {
                                            ThingWithComps t;
                                            if (pawn.equipment.TryDropEquipment(pawn.equipment.Primary, out t, pawn.Position, true))
                                            {
                                                t.SetForbidden(false, true);
                                                Job job           = new Job(JobDefOf.HaulToCell, t, c);
                                                job.haulMode      = HaulMode.ToCellStorage;
                                                job.maxNumToCarry = 1;
                                                job.playerForced  = true;
                                                pawn.drafter.TakeOrderedJob(job);
                                            }
                                        });
                                        list.Add(new FloatMenuOption("Deposit".Translate(new object[]
                                        {
                                            pawn.equipment.Primary.LabelCap,
                                            thing2.def.label
                                        }), action4, MenuOptionPriority.Medium, null, null));
                                        break;
                                    }
                                }
                            }
                        }
                    }
                    if (pawn.equipment != null && GenUI.TargetsAt(clickPos, TargetingParameters.ForSelf(pawn), true).Any <TargetInfo>())
                    {
                        Action action5 = new Action(delegate
                        {
                            ThingWithComps thingWithComps;
                            pawn.equipment.TryDropEquipment(pawn.equipment.Primary, out thingWithComps, pawn.Position, true);
                            pawn.drafter.TakeOrderedJob(new Job(JobDefOf.Wait, 20, false));
                        }
                                                    );
                        list.Add(new FloatMenuOption("Drop".Translate(new object[]
                        {
                            pawn.equipment.Primary.LabelCap
                        }), action5, MenuOptionPriority.Medium, null, null));
                    }
                }

                // *** Trade with option ***

                foreach (TargetInfo current7 in GenUI.TargetsAt(clickPos, TargetingParameters.ForTrade(), true))
                {
                    TargetInfo dest2 = current7;
                    if (!pawn.CanReach(dest2, PathEndMode.OnCell, Danger.Deadly, false, TraverseMode.ByPawn))
                    {
                        list.Add(new FloatMenuOption("CannotTrade".Translate() + " (" + "NoPath".Translate() + ")", null, MenuOptionPriority.Medium, null, null));
                    }
                    else if (!pawn.CanReserve(dest2.Thing, 1))
                    {
                        list.Add(new FloatMenuOption("CannotTrade".Translate() + " (" + "Reserved".Translate() + ")", null, MenuOptionPriority.Medium, null, null));
                    }
                    else
                    {
                        Pawn   pTarg   = (Pawn)dest2.Thing;
                        Action action6 = new Action(delegate
                        {
                            Job job          = new Job(JobDefOf.TradeWithPawn, pTarg);
                            job.playerForced = true;
                            pawn.drafter.TakeOrderedJob(job);
                            ConceptDatabase.KnowledgeDemonstrated(ConceptDefOf.InteractingWithTraders, KnowledgeAmount.Total);
                        });
                        string str3 = string.Empty;
                        if (pTarg.Faction != null)
                        {
                            str3 = " (" + pTarg.Faction.name + ")";
                        }
                        List <FloatMenuOption> arg_142E_0 = list;
                        Thing thing = dest2.Thing;
                        arg_142E_0.Add(new FloatMenuOption("TradeWith".Translate(new object[]
                        {
                            pTarg.LabelBaseShort
                        }) + str3, action6, MenuOptionPriority.Medium, null, thing));
                    }
                }
                foreach (Thing current8 in Find.ThingGrid.ThingsAt(clickCell))
                {
                    foreach (FloatMenuOption current9 in current8.GetFloatMenuOptions(pawn))
                    {
                        list.Add(current9);
                    }
                }
            }

            // *** End of humanlike options ***

            // *** Beginning of non-drafted options ***

            if (!pawn.Drafted)
            {
                bool flag  = false;
                bool flag2 = false;
                foreach (Thing current10 in Find.ThingGrid.ThingsAt(clickCell))
                {
                    flag2 = true;
                    if (pawn.CanReach(current10, PathEndMode.Touch, Danger.Deadly, false, TraverseMode.ByPawn))
                    {
                        flag = true;
                        break;
                    }
                }
                if (flag2 && !flag)
                {
                    list.Add(new FloatMenuOption("(" + "NoPath".Translate() + ")", null, MenuOptionPriority.Medium, null, null));
                    return(list);
                }
                foreach (Thing current11 in Find.ThingGrid.ThingsAt(clickCell))
                {
                    Pawn pawn4 = Find.Reservations.FirstReserverOf(current11, pawn.Faction);
                    if (pawn4 != null && pawn4 != pawn)
                    {
                        list.Add(new FloatMenuOption("IsReservedBy".Translate(new object[]
                        {
                            current11.LabelBaseShort.CapitalizeFirst(),
                            pawn4.LabelBaseShort
                        }), null, MenuOptionPriority.Medium, null, null));
                    }
                    else
                    {
                        JobGiver_Work jobGiver_Work = pawn.thinker.TryGetMainTreeThinkNode <JobGiver_Work>();
                        if (jobGiver_Work != null)
                        {
                            foreach (WorkTypeDef current12 in DefDatabase <WorkTypeDef> .AllDefsListForReading)
                            {
                                for (int k = 0; k < current12.workGiversByPriority.Count; k++)
                                {
                                    WorkGiver_Scanner workGiver_Scanner = current12.workGiversByPriority[k].Worker as WorkGiver_Scanner;
                                    if (workGiver_Scanner != null)
                                    {
                                        if (workGiver_Scanner.def.directOrderable)
                                        {
                                            if (!workGiver_Scanner.ShouldSkip(pawn))
                                            {
                                                JobFailReason.Clear();
                                                Job job;
                                                if (!workGiver_Scanner.HasJobOnThingForced(pawn, current11))
                                                {
                                                    job = null;
                                                }
                                                else
                                                {
                                                    job = workGiver_Scanner.JobOnThingForced(pawn, current11);
                                                }
                                                if (workGiver_Scanner.PotentialWorkThingRequest.Accepts(current11) || (workGiver_Scanner.PotentialWorkThingsGlobal(pawn) != null && workGiver_Scanner.PotentialWorkThingsGlobal(pawn).Contains(current11)))
                                                {
                                                    if (job == null)
                                                    {
                                                        if (JobFailReason.HaveReason)
                                                        {
                                                            string label2 = "CannotGenericWork".Translate(new object[]
                                                            {
                                                                workGiver_Scanner.def.verb,
                                                                current11.LabelBaseShort
                                                            }) + " (" + JobFailReason.Reason + ")";
                                                            list.Add(new FloatMenuOption(label2, null, MenuOptionPriority.Medium, null, null));
                                                        }
                                                    }
                                                    else
                                                    {
                                                        string          label;
                                                        WorkTypeDef     workType        = workGiver_Scanner.def.workType;
                                                        Action          action7         = null;
                                                        PawnCapacityDef pawnCapacityDef = workGiver_Scanner.MissingRequiredCapacity(pawn);
                                                        if (pawnCapacityDef != null)
                                                        {
                                                            label = "CannotMissingHealthActivities".Translate(new object[]
                                                            {
                                                                pawnCapacityDef.label
                                                            });
                                                        }
                                                        else if (pawn.jobs.curJob != null && pawn.jobs.curJob.JobIsSameAs(job))
                                                        {
                                                            label = "CannotGenericAlreadyAm".Translate(new object[]
                                                            {
                                                                workType.gerundLabel,
                                                                current11.LabelBaseShort
                                                            });
                                                        }
                                                        else if (pawn.workSettings.GetPriority(workType) == 0)
                                                        {
                                                            label = "CannotPrioritizeIsNotA".Translate(new object[]
                                                            {
                                                                pawn.NameStringShort,
                                                                workType.pawnLabel
                                                            });
                                                        }
                                                        else if (job.def == JobDefOf.Research && current11 is Building_ResearchBench)
                                                        {
                                                            label = "CannotPrioritizeResearch".Translate();
                                                        }
                                                        else if (current11.IsForbidden(pawn))
                                                        {
                                                            label = "CannotPrioritizeForbidden".Translate(new object[]
                                                            {
                                                                current11.Label
                                                            });
                                                        }
                                                        else if (!pawn.CanReach(current11, PathEndMode.Touch, Danger.Deadly, false, TraverseMode.ByPawn))
                                                        {
                                                            label = current11.Label + ": " + "NoPath".Translate();
                                                        }
                                                        else
                                                        {
                                                            label = "PrioritizeGeneric".Translate(new object[]
                                                            {
                                                                workGiver_Scanner.def.gerund,
                                                                current11.Label
                                                            });
                                                            Job         localJob         = job;
                                                            WorkTypeDef localWorkTypeDef = workType;
                                                            action7 = new Action(delegate { pawn.thinker.GetMainTreeThinkNode <JobGiver_Work>().TryStartPrioritizedWorkOn(pawn, localJob, localWorkTypeDef); });
                                                        }
                                                        if (!list.Any(op => op.label == label))
                                                        {
                                                            list.Add(new FloatMenuOption(label, action7, MenuOptionPriority.Medium, null, null));
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }

            // *** End of non-drafted options ***

            foreach (FloatMenuOption current13 in pawn.GetExtraFloatMenuOptionsFor(clickCell))
            {
                list.Add(current13);
            }
            DangerUtility.DoneDirectOrdering();
            return(list);
        }
Exemple #20
0
        private void TryEquipDraggedItem(Pawn p)
        {
            this.droppedDraggedItem = false;
            if (this.draggedItem.def.IsWeapon)
            {
                if (p.story != null && p.story.WorkTagIsDisabled(WorkTags.Violent))
                {
                    Messages.Message("MessageCantEquipIncapableOfViolence".Translate(p.LabelShort, p), p, MessageTypeDefOf.RejectInput, false);
                    this.draggedItem = null;
                    return;
                }
                if (!p.health.capacities.CapableOf(PawnCapacityDefOf.Manipulation))
                {
                    Messages.Message("MessageCantEquipIncapableOfManipulation".Translate(), p, MessageTypeDefOf.RejectInput, false);
                    this.draggedItem = null;
                    return;
                }
            }
            Apparel        apparel        = this.draggedItem as Apparel;
            ThingWithComps thingWithComps = this.draggedItem as ThingWithComps;

            if (apparel != null && p.apparel != null)
            {
                WITab_Caravan_Gear.tmpExistingApparel.Clear();
                WITab_Caravan_Gear.tmpExistingApparel.AddRange(p.apparel.WornApparel);
                for (int i = 0; i < WITab_Caravan_Gear.tmpExistingApparel.Count; i++)
                {
                    if (!ApparelUtility.CanWearTogether(apparel.def, WITab_Caravan_Gear.tmpExistingApparel[i].def, p.RaceProps.body))
                    {
                        p.apparel.Remove(WITab_Caravan_Gear.tmpExistingApparel[i]);
                        Pawn pawn = CaravanInventoryUtility.FindPawnToMoveInventoryTo(WITab_Caravan_Gear.tmpExistingApparel[i], this.Pawns, null, null);
                        if (pawn != null)
                        {
                            pawn.inventory.innerContainer.TryAdd(WITab_Caravan_Gear.tmpExistingApparel[i], true);
                        }
                        else
                        {
                            Log.Warning("Could not find any pawn to move " + WITab_Caravan_Gear.tmpExistingApparel[i] + " to.", false);
                            WITab_Caravan_Gear.tmpExistingApparel[i].Destroy(DestroyMode.Vanish);
                        }
                    }
                }
                p.apparel.Wear((Apparel)apparel.SplitOff(1), false);
                if (p.outfits != null)
                {
                    p.outfits.forcedHandler.SetForced(apparel, true);
                }
            }
            else if (thingWithComps != null && p.equipment != null)
            {
                WITab_Caravan_Gear.tmpExistingEquipment.Clear();
                WITab_Caravan_Gear.tmpExistingEquipment.AddRange(p.equipment.AllEquipmentListForReading);
                for (int j = 0; j < WITab_Caravan_Gear.tmpExistingEquipment.Count; j++)
                {
                    p.equipment.Remove(WITab_Caravan_Gear.tmpExistingEquipment[j]);
                    Pawn pawn2 = CaravanInventoryUtility.FindPawnToMoveInventoryTo(WITab_Caravan_Gear.tmpExistingEquipment[j], this.Pawns, null, null);
                    if (pawn2 != null)
                    {
                        pawn2.inventory.innerContainer.TryAdd(WITab_Caravan_Gear.tmpExistingEquipment[j], true);
                    }
                    else
                    {
                        Log.Warning("Could not find any pawn to move " + WITab_Caravan_Gear.tmpExistingEquipment[j] + " to.", false);
                        WITab_Caravan_Gear.tmpExistingEquipment[j].Destroy(DestroyMode.Vanish);
                    }
                }
                p.equipment.AddEquipment((ThingWithComps)thingWithComps.SplitOff(1));
            }
            else
            {
                Log.Warning(string.Concat(new object[]
                {
                    "Could not make ",
                    p,
                    " equip or wear ",
                    this.draggedItem
                }), false);
            }
            this.draggedItem = null;
        }
Exemple #21
0
        internal static void Wear(this Pawn_ApparelTracker _this, Apparel newApparel, bool dropReplacedApparel = true)
        {
            SlotGroupUtility.Notify_TakingThing(newApparel);
            if (newApparel.Spawned)
            {
                newApparel.DeSpawn();
            }
            if (!ApparelUtility.HasPartsToWear(_this.pawn, newApparel.def))
            {
                Log.Warning(string.Concat(new object[]
                {
                    _this.pawn,
                    " tried to wear ",
                    newApparel,
                    " but he has no body parts required to wear it."
                }));
                return;
            }
            for (int i = _this.WornApparel.Count - 1; i >= 0; i--)
            {
                Apparel apparel = _this.WornApparel[i];
                if (!ApparelUtility.CanWearTogether(newApparel.def, apparel.def))
                {
                    bool forbid = _this.pawn.Faction.HostileTo(Faction.OfPlayer);
                    if (dropReplacedApparel)
                    {
                        Apparel apparel2;
                        if (!_this.TryDrop(apparel, out apparel2, _this.pawn.Position, forbid))
                        {
                            Log.Error(_this.pawn + " could not drop " + apparel);
                            return;
                        }
                    }
                    else
                    {
                        _this.Remove(apparel);
                    }
                }
            }
            if (newApparel.wearer != null)
            {
                Log.Warning(string.Concat(new object[]
                {
                    _this.pawn,
                    " is trying to wear ",
                    newApparel,
                    " but this apparel already has a wearer (",
                    newApparel.wearer,
                    "). This may or may not cause bugs."
                }));
            }
            _this.WornApparel.Add(newApparel);
            newApparel.wearer = _this.pawn;
            _this.SortWornApparelIntoDrawOrder();
            _this.ApparelChanged();

            //CR PART
            CR_Utility.TryUpdateInventory(_this.pawn);     // Apparel was added, update inventory
            MethodInfo methodInfo = typeof(Pawn_ApparelTracker).GetMethod("SortWornApparelIntoDrawOrder", BindingFlags.Instance | BindingFlags.NonPublic);

            methodInfo.Invoke(_this, new object[] { });

            LongEventHandler.ExecuteWhenFinished(new Action(_this.ApparelChanged));
        }
        static void Postfix(Vector3 clickPos, Pawn pawn, List <FloatMenuOption> opts)
        {
            var cell = clickPos.ToIntVec3();

            if (pawn.equipment != null)
            {
                foreach (var equipment in cell.GetThingList(pawn.Map).OfType <ThingWithComps>().Where(t => t.TryGetComp <CompEquippable>() != null).Skip(1))
                {
                    string          labelShort = equipment.LabelShort;
                    FloatMenuOption option;
                    if (equipment.def.IsWeapon && pawn.story.WorkTagIsDisabled(WorkTags.Violent))
                    {
                        option = new FloatMenuOption("CannotEquip".Translate(labelShort) + " (" + "IsIncapableOfViolenceLower".Translate(pawn.LabelShort, pawn) + ")", null, MenuOptionPriority.Default, null, null, 0f, null, null);
                    }
                    else if (!pawn.CanReach(equipment, PathEndMode.ClosestTouch, Danger.Deadly, false, TraverseMode.ByPawn))
                    {
                        option = new FloatMenuOption("CannotEquip".Translate(labelShort) + " (" + "NoPath".Translate() + ")", null, MenuOptionPriority.Default, null, null, 0f, null, null);
                    }
                    else if (!pawn.health.capacities.CapableOf(PawnCapacityDefOf.Manipulation))
                    {
                        option = new FloatMenuOption("CannotEquip".Translate(labelShort) + " (" + "Incapable".Translate() + ")", null, MenuOptionPriority.Default, null, null, 0f, null, null);
                    }
                    else if (equipment.IsBurning())
                    {
                        option = new FloatMenuOption("CannotEquip".Translate(labelShort) + " (" + "BurningLower".Translate() + ")", null, MenuOptionPriority.Default, null, null, 0f, null, null);
                    }
                    else
                    {
                        string text5 = "Equip".Translate(labelShort);
                        if (equipment.def.IsRangedWeapon && pawn.story != null && pawn.story.traits.HasTrait(TraitDefOf.Brawler))
                        {
                            text5 = text5 + " " + "EquipWarningBrawler".Translate();
                        }
                        option = FloatMenuUtility.DecoratePrioritizedTask(new FloatMenuOption(text5, delegate
                        {
                            equipment.SetForbidden(false, true);
                            pawn.jobs.TryTakeOrderedJob(new Job(JobDefOf.Equip, equipment), JobTag.Misc);
                            MoteMaker.MakeStaticMote(equipment.DrawPos, equipment.Map, ThingDefOf.Mote_FeedbackEquip, 1f);
                            PlayerKnowledgeDatabase.KnowledgeDemonstrated(ConceptDefOf.EquippingWeapons, KnowledgeAmount.Total);
                        }, MenuOptionPriority.High, null, null, 0f, null, null), pawn, equipment, "ReservedBy");
                    }
                    opts.Add(option);
                }
            }
            if (pawn.apparel != null)
            {
                foreach (var apparel in cell.GetThingList(pawn.Map).OfType <Apparel>().Skip(1))
                {
                    FloatMenuOption option;
                    if (!pawn.CanReach(apparel, PathEndMode.ClosestTouch, Danger.Deadly, false, TraverseMode.ByPawn))
                    {
                        option = new FloatMenuOption("CannotWear".Translate(apparel.Label, apparel) + " (" + "NoPath".Translate() + ")", null, MenuOptionPriority.Default, null, null, 0f, null, null);
                    }
                    else if (apparel.IsBurning())
                    {
                        option = new FloatMenuOption("CannotWear".Translate(apparel.Label, apparel) + " (" + "BurningLower".Translate() + ")", null, MenuOptionPriority.Default, null, null, 0f, null, null);
                    }
                    else if (!ApparelUtility.HasPartsToWear(pawn, apparel.def))
                    {
                        option = new FloatMenuOption("CannotWear".Translate(apparel.Label, apparel) + " (" + "CannotWearBecauseOfMissingBodyParts".Translate() + ")", null, MenuOptionPriority.Default, null, null, 0f, null, null);
                    }
                    else
                    {
                        option = FloatMenuUtility.DecoratePrioritizedTask(new FloatMenuOption("ForceWear".Translate(apparel.LabelShort, apparel), delegate
                        {
                            apparel.SetForbidden(false, true);
                            Job job = new Job(JobDefOf.Wear, apparel);
                            pawn.jobs.TryTakeOrderedJob(job, JobTag.Misc);
                        }, MenuOptionPriority.High, null, null, 0f, null, null), pawn, apparel, "ReservedBy");
                    }
                    opts.Add(option);
                }
            }
        }
        private void TryEquipDraggedItem(Pawn p)
        {
            droppedDraggedItem = false;
            if (!EquipmentUtility.CanEquip_NewTmp(draggedItem, p, out var cantReason))
            {
                Messages.Message("MessageCantEquipCustom".Translate(cantReason.CapitalizeFirst()), p, MessageTypeDefOf.RejectInput, historical: false);
                draggedItem = null;
                return;
            }
            if (draggedItem.def.IsWeapon)
            {
                if (p.guest.IsPrisoner)
                {
                    Messages.Message("MessageCantEquipCustom".Translate("MessagePrisonerCannotEquipWeapon".Translate(p.Named("PAWN"))), p, MessageTypeDefOf.RejectInput, historical: false);
                    draggedItem = null;
                    return;
                }
                if (p.WorkTagIsDisabled(WorkTags.Violent))
                {
                    Messages.Message("MessageCantEquipIncapableOfViolence".Translate(p.LabelShort, p), p, MessageTypeDefOf.RejectInput, historical: false);
                    draggedItem = null;
                    return;
                }
                if (!p.health.capacities.CapableOf(PawnCapacityDefOf.Manipulation))
                {
                    Messages.Message("MessageCantEquipIncapableOfManipulation".Translate(), p, MessageTypeDefOf.RejectInput, historical: false);
                    draggedItem = null;
                    return;
                }
            }
            Apparel        apparel        = draggedItem as Apparel;
            ThingWithComps thingWithComps = draggedItem as ThingWithComps;

            if (apparel != null && p.apparel != null)
            {
                if (!ApparelUtility.HasPartsToWear(p, apparel.def))
                {
                    Messages.Message("MessageCantWearApparelMissingBodyParts".Translate(p.LabelShort, p), p, MessageTypeDefOf.RejectInput, historical: false);
                    draggedItem = null;
                    return;
                }
                if (CurrentWearerOf(apparel) != null && CurrentWearerOf(apparel).apparel.IsLocked(apparel))
                {
                    Messages.Message("MessageCantUnequipLockedApparel".Translate(), p, MessageTypeDefOf.RejectInput, historical: false);
                    draggedItem = null;
                    return;
                }
                if (p.apparel.WouldReplaceLockedApparel(apparel))
                {
                    Messages.Message("MessageWouldReplaceLockedApparel".Translate(p.LabelShort, p), p, MessageTypeDefOf.RejectInput, historical: false);
                    draggedItem = null;
                    return;
                }
                tmpExistingApparel.Clear();
                tmpExistingApparel.AddRange(p.apparel.WornApparel);
                for (int i = 0; i < tmpExistingApparel.Count; i++)
                {
                    if (!ApparelUtility.CanWearTogether(apparel.def, tmpExistingApparel[i].def, p.RaceProps.body))
                    {
                        p.apparel.Remove(tmpExistingApparel[i]);
                        Pawn pawn = CaravanInventoryUtility.FindPawnToMoveInventoryTo(tmpExistingApparel[i], Pawns, null);
                        if (pawn != null)
                        {
                            pawn.inventory.innerContainer.TryAdd(tmpExistingApparel[i]);
                            continue;
                        }
                        Log.Warning(string.Concat("Could not find any pawn to move ", tmpExistingApparel[i], " to."));
                        tmpExistingApparel[i].Destroy();
                    }
                }
                p.apparel.Wear((Apparel)apparel.SplitOff(1), dropReplacedApparel: false);
                if (p.outfits != null)
                {
                    p.outfits.forcedHandler.SetForced(apparel, forced: true);
                }
            }
            else if (thingWithComps != null && p.equipment != null)
            {
                string personaWeaponConfirmationText = EquipmentUtility.GetPersonaWeaponConfirmationText(draggedItem, p);
                if (!personaWeaponConfirmationText.NullOrEmpty())
                {
                    _ = draggedItem;
                    Find.WindowStack.Add(new Dialog_MessageBox(personaWeaponConfirmationText, "Yes".Translate(), delegate
                    {
                        AddEquipment();
                    }, "No".Translate()));
                    draggedItem = null;
                    return;
                }
                AddEquipment();
            }
            else
            {
                Log.Warning(string.Concat("Could not make ", p, " equip or wear ", draggedItem));
            }
            draggedItem = null;
            void AddEquipment()
            {
                tmpExistingEquipment.Clear();
                tmpExistingEquipment.AddRange(p.equipment.AllEquipmentListForReading);
                for (int j = 0; j < tmpExistingEquipment.Count; j++)
                {
                    p.equipment.Remove(tmpExistingEquipment[j]);
                    Pawn pawn2 = CaravanInventoryUtility.FindPawnToMoveInventoryTo(tmpExistingEquipment[j], Pawns, null);
                    if (pawn2 != null)
                    {
                        pawn2.inventory.innerContainer.TryAdd(tmpExistingEquipment[j]);
                    }
                    else
                    {
                        Log.Warning(string.Concat("Could not find any pawn to move ", tmpExistingEquipment[j], " to."));
                        tmpExistingEquipment[j].Destroy();
                    }
                }
                p.equipment.AddEquipment((ThingWithComps)thingWithComps.SplitOff(1));
            }
        }
Exemple #24
0
        public override IEnumerable <string> ConfigErrors()
        {
            foreach (string item in base.ConfigErrors())
            {
                yield return(item);
            }
            if (backstoryFilters != null && backstoryFiltersOverride != null)
            {
                yield return("both backstoryCategories and backstoryCategoriesOverride are defined");
            }
            if (race == null)
            {
                yield return("no race");
            }
            if (baseRecruitDifficulty > 1.0001f)
            {
                yield return(defName + " recruitDifficulty is greater than 1. 1 means impossible to recruit.");
            }
            if (combatPower < 0f)
            {
                yield return(defName + " has no combatPower.");
            }
            if (weaponMoney != FloatRange.Zero)
            {
                float num = 999999f;
                int   k;
                for (k = 0; k < weaponTags.Count; k++)
                {
                    IEnumerable <ThingDef> source = DefDatabase <ThingDef> .AllDefs.Where((ThingDef d) => d.weaponTags != null && d.weaponTags.Contains(weaponTags[k]));

                    if (source.Any())
                    {
                        num = Mathf.Min(num, source.Min((ThingDef d) => PawnWeaponGenerator.CheapestNonDerpPriceFor(d)));
                    }
                }
                if (num < 999999f && num > weaponMoney.min)
                {
                    yield return("Cheapest weapon with one of my weaponTags costs " + num + " but weaponMoney min is " + weaponMoney.min + ", so could end up weaponless.");
                }
            }
            if (!RaceProps.Humanlike && lifeStages.Count != RaceProps.lifeStageAges.Count)
            {
                yield return("PawnKindDef defines " + lifeStages.Count + " lifeStages while race def defines " + RaceProps.lifeStageAges.Count);
            }
            if (apparelRequired != null)
            {
                for (int j = 0; j < apparelRequired.Count; j++)
                {
                    for (int i = j + 1; i < apparelRequired.Count; i++)
                    {
                        if (!ApparelUtility.CanWearTogether(apparelRequired[j], apparelRequired[i], race.race.body))
                        {
                            yield return("required apparel can't be worn together (" + apparelRequired[j] + ", " + apparelRequired[i] + ")");
                        }
                    }
                }
            }
            if (alternateGraphics != null)
            {
                foreach (AlternateGraphic alternateGraphic in alternateGraphics)
                {
                    if (alternateGraphic.Weight < 0f)
                    {
                        yield return("alternate graphic has negative weight.");
                    }
                }
            }
        }
Exemple #25
0
        public static bool TryGiveJob(JobGiver_OptimizeApparel __instance, ref Job __result, Pawn pawn)
        {
            if (pawn.outfits == null)
            {
                Log.ErrorOnce(string.Concat(pawn, " tried to run JobGiver_OptimizeApparel without an OutfitTracker"), 5643897);
                __result = null;
                return(false);
            }

            if (pawn.Faction != Faction.OfPlayer)
            {
                Log.ErrorOnce(string.Concat("Non-colonist ", pawn, " tried to optimize apparel."), 764323);
                __result = null;
                return(false);
            }

            if (pawn.IsQuestLodger())
            {
                __result = null;
                return(false);
            }

            if (!DebugViewSettings.debugApparelOptimize)
            {
                if (Find.TickManager.TicksGame < pawn.mindState.nextApparelOptimizeTick)
                {
                    __result = null;
                    return(false);
                }
            }
            else
            {
                debugSb = new StringBuilder();
                debugSb.AppendLine(string.Concat("Scanning for ", pawn, " at ", pawn.Position));
            }

            Outfit         currentOutfit = pawn.outfits.CurrentOutfit;
            List <Apparel> wornApparel   = pawn.apparel.WornApparel;

            for (int num = wornApparel.Count - 1; num >= 0; num--)
            {
                if (!currentOutfit.filter.Allows(wornApparel[num]) && pawn.outfits.forcedHandler.AllowedToAutomaticallyDrop(wornApparel[num]) && !pawn.apparel.IsLocked(wornApparel[num]))
                {
                    Job job = JobMaker.MakeJob(JobDefOf.RemoveApparel, wornApparel[num]);
                    job.haulDroppedApparel = true;
                    __result = job;
                    return(false);
                }
            }

            Thing        thing = null;
            float        num2  = 0f;
            List <Thing> list  = pawn.Map.listerThings.ThingsInGroup(ThingRequestGroup.Apparel);

            if (list.Count == 0)
            {
                SetNextOptimizeTick2(pawn);
                __result = null;
                return(false);
            }

            neededWarmth = PawnApparelGenerator.CalculateNeededWarmth(pawn, pawn.Map.Tile, GenLocalDate.Twelfth(pawn));
            //wornApparelScores.Clear();
            List <float> wornApparelScores = new List <float>();

            for (int i = 0; i < wornApparel.Count; i++)
            {
                wornApparelScores.Add(JobGiver_OptimizeApparel.ApparelScoreRaw(pawn, wornApparel[i]));
            }

            for (int j = 0; j < list.Count; j++)
            {
                Apparel apparel = (Apparel)list[j];
                if (currentOutfit.filter.Allows(apparel) && apparel.IsInAnyStorage() && !apparel.IsForbidden(pawn) && !apparel.IsBurning() && (apparel.def.apparel.gender == Gender.None || apparel.def.apparel.gender == pawn.gender))
                {
                    float num3 = JobGiver_OptimizeApparel.ApparelScoreGain_NewTmp(pawn, apparel, wornApparelScores);
                    if (DebugViewSettings.debugApparelOptimize)
                    {
                        debugSb.AppendLine(apparel.LabelCap + ": " + num3.ToString("F2"));
                    }

                    if (!(num3 < 0.05f) && !(num3 < num2) && (!EquipmentUtility.IsBiocoded(apparel) || EquipmentUtility.IsBiocodedFor(apparel, pawn)) && ApparelUtility.HasPartsToWear(pawn, apparel.def) && pawn.CanReserveAndReach(apparel, PathEndMode.OnCell, pawn.NormalMaxDanger()))
                    {
                        thing = apparel;
                        num2  = num3;
                    }
                }
            }

            if (DebugViewSettings.debugApparelOptimize)
            {
                debugSb.AppendLine("BEST: " + thing);
                Log.Message(debugSb.ToString());
                debugSb = null;
            }

            if (thing == null)
            {
                SetNextOptimizeTick2(pawn);
                __result = null;
                return(false);
            }

            __result = JobMaker.MakeJob(JobDefOf.Wear, thing);
            return(false);
        }