/// <summary> /// Equips tools /// </summary> /// <param name="pawn"></param> /// <param name="def"></param> public static void EquipRigthTool(Pawn pawn, StatDef def) { CompInventory compInventory = ThingCompUtility.TryGetComp <CompInventory>(pawn); bool flag = compInventory != null; if (flag) { ThingWithComps thingWithComps = pawn.equipment.Primary; float stat = GetMaxStat(pawn.equipment.Primary, def); foreach (ThingWithComps slot in compInventory.container) { ThingWithComps thingWithComps2 = slot; bool flag2 = thingWithComps2.def.IsWeapon; if (flag2) { float maxStat = GetMaxStat(thingWithComps2, def); bool flag3 = stat < maxStat; if (flag3) { stat = maxStat; thingWithComps = thingWithComps2; } } } bool unEquipped = thingWithComps != pawn.equipment.Primary; if (unEquipped) { compInventory.TrySwitchToWeapon(thingWithComps); } else { bool flag5 = stat == 0f && def != StatDefOf.WorkSpeedGlobal; if (flag5) { RightTools.EquipRigthTool(pawn, StatDefOf.WorkSpeedGlobal); } } } }
internal static void Notify_PrimaryDestroyed(this Pawn_EquipmentTracker _this) { // Fetch private fields Pawn pawn = (Pawn)pawnFieldInfo.GetValue(_this); _this.Remove(_this.Primary); if (pawn.Spawned) { pawn.stances.CancelBusyStanceSoft(); } CE_Utility.TryUpdateInventory(pawn); // Equipment was destroyed, update inventory // Try switching to the next available weapon CompInventory inventory = pawn.TryGetComp <CompInventory>(); if (inventory != null) { inventory.SwitchToNextViableWeapon(false); } }
private float GetStatFactor(Pawn thisPawn) { float result = 1f; Apparel_Backpack apparelBackpack = ToolsForHaulUtility.TryGetBackpack(thisPawn); CompSlotsBackpack compSlotsBackpack = apparelBackpack?.SlotsComp; if (compSlotsBackpack != null) { result = Mathf.Clamp(compSlotsBackpack.MoveSpeedFactor - compSlotsBackpack.encumberPenalty, 0.5f, 1f); } #if CR CompInventory compInventory = thisPawn.TryGetComp <CompInventory>(); if (compInventory != null) { result = Mathf.Clamp(compInventory.moveSpeedFactor - compInventory.encumberPenalty, 0.1f, 1f); return(result); } #endif return(result); }
public static void Postfix(WorkGiver_InteractAnimal __instance, ref Job __result, Pawn pawn, Pawn tamee) { if (__result != null) { // Check for inventory space int numToCarry = __result.count; CompInventory inventory = pawn.TryGetComp <CompInventory>(); if (inventory != null) { if (inventory.CanFitInInventory(__result.targetA.Thing, out int maxCount)) { __result.count = Mathf.Min(numToCarry, maxCount); pawn.Notify_HoldTrackerItem(__result.targetA.Thing, __result.count); } else // this should patch WorkGiver_Train && WorkGiver_Tame `JobOnThing` { Messages.Message("CE_TamerInventoryFull".Translate(), pawn, MessageTypeDefOf.RejectInput); __result = null; } } } }
static public bool ShouldReload(Pawn p) { //For mechanoids replace the check of is p.RaceProps.HumanLike by custom logic if (p.RaceProps.IsMechanoid && p.IsHacked()) { //return true when a mechanoid is hacked and does not have much ammo. CompInventory inventory = p.TryGetComp <CompInventory>(); ThingWithComps primaryEq = p.equipment.Primary; if (inventory != null && primaryEq != null) { CompAmmoUser ammoUser = primaryEq.TryGetComp <CompAmmoUser>(); if (ammoUser != null) { int ammoCount = inventory.AmmoCountOfDef(ammoUser.CurrentAmmo); int minAmmo = ammoUser.Props.magazineSize == 0 ? 10 : ammoUser.Props.magazineSize; //No magic numbers? if (ammoCount < minAmmo) { return(true); } } } } return(p.RaceProps.Humanlike); }
static Rect FillTab_DrawBars(Rect position, object tab) { bool viewList = (bool)LviewList.GetValue(tab); if (!viewList) { return(position); } Pawn pawn = (Pawn)LSelPawn.GetValue(tab); CompInventory compInventory = pawn.TryGetComp <CompInventory>(); if (compInventory == null) { return(position); } PlayerKnowledgeDatabase.KnowledgeDemonstrated(CE_ConceptDefOf.CE_InventoryWeightBulk, KnowledgeAmount.FrameDisplayed); position.height -= 55f; Rect rect = new Rect(15f, position.yMax + 7.5f, position.width - 10f, 20f); Rect rect2 = new Rect(15f, rect.yMax + 7.5f, position.width - 10f, 20f); Utility_Loadouts.DrawBar(rect2, compInventory.currentBulk, compInventory.capacityBulk, "CE_Bulk".Translate(), pawn.GetBulkTip()); Utility_Loadouts.DrawBar(rect, compInventory.currentWeight, compInventory.capacityWeight, "CE_Weight".Translate(), pawn.GetWeightTip()); Text.Font = GameFont.Small; Text.Anchor = TextAnchor.MiddleCenter; string str = CE_StatDefOf.CarryBulk.ValueToString(compInventory.currentBulk, CE_StatDefOf.CarryBulk.toStringNumberSense, true); string str2 = CE_StatDefOf.CarryBulk.ValueToString(compInventory.capacityBulk, CE_StatDefOf.CarryBulk.toStringNumberSense, true); Widgets.Label(rect2, str + "/" + str2); string str3 = compInventory.currentWeight.ToString("0.#"); string str4 = CE_StatDefOf.CarryWeight.ValueToString(compInventory.capacityWeight, CE_StatDefOf.CarryWeight.toStringNumberSense, true); Widgets.Label(rect, str3 + "/" + str4); Text.Anchor = TextAnchor.UpperLeft; return(position); }
/// <summary> /// Determines whether a pawn can be used to suppress targets /// </summary> /// <returns>True if the pawn has a weapon tagged for suppression and ammo available, false otherwise</returns> private static bool CanBeSuppressor(Pawn pawn, CompInventory comp) { return(comp.rangedWeaponList.Any(w => w.def.IsSuppressive() && w.HasAmmo())); }
/// <summary> /// Determines whether a pawn is elligible to be used as a sniper, going for kills on high value targets /// </summary> /// <returns>True if pawn has a weapon tagged as rifle with ammo available, false otherwise</returns> private static bool CanBeSniper(Pawn pawn, CompInventory comp) { return(comp.rangedWeaponList.Any(w => w.def.IsRifle() && w.HasAmmo())); }
/// <summary> /// Tries to give the pawn a job related to picking up or dropping an item from their inventory. /// </summary> /// <param name="pawn">Pawn to which the job is given.</param> /// <returns>Job that the pawn was instructed to do, be it hauling a dropped Thing or going and getting a Thing.</returns> protected override Job TryGiveJob(Pawn pawn) { // Get inventory CompInventory inventory = pawn.TryGetComp <CompInventory>(); if (inventory == null) { return(null); } RPGILoadout loadout = pawn.GetLoadout(); if (loadout != null) { ThingWithComps dropEq; ThingWithComps droppedEq; if (pawn.equipment.TryDropEquipment(pawn.equipment.Primary, out droppedEq, pawn.Position, false)) { if (droppedEq != null) { return(HaulAIUtility.HaulToStorageJob(pawn, droppedEq)); } } Thing dropThing = new Thing(); int dropCount = 0; Thing droppedThing; if (inventory.container.TryDrop(dropThing, pawn.Position, pawn.Map, ThingPlaceMode.Near, dropCount, out droppedThing)) { if (droppedThing != null) { return(HaulAIUtility.HaulToStorageJob(pawn, droppedThing)); } Log.Error(string.Concat(pawn, " tried dropping ", dropThing, " from loadout but resulting thing is null")); } // Find missing items ItemPriority priority; Thing closestThing; int count; Pawn carriedBy; bool doEquip = false; LoadoutSlot prioritySlot = GetPrioritySlot(pawn, out priority, out closestThing, out count, out carriedBy); // moved logic to detect if should equip vs put in inventory here... if (closestThing != null) { if (closestThing.TryGetComp <CompEquippable>() != null && !(pawn.story != null && pawn.story.WorkTagIsDisabled(WorkTags.Violent)) && (pawn.health != null && pawn.health.capacities.CapableOf(PawnCapacityDefOf.Manipulation)) && (pawn.equipment == null || pawn.equipment.Primary == null || !loadout.Any(s => s.def == pawn.equipment.Primary.def))) { doEquip = true; } if (carriedBy == null) { // Equip gun if unarmed or current gun is not in loadout if (doEquip) { return(new Job(JobDefOf.Equip, closestThing)); } return(new Job(JobDefOf.TakeInventory, closestThing) { count = Mathf.Min(closestThing.stackCount, count) }); } else { // TODO Implement Take from Others //return new Job(CE_JobDefOf.TakeFromOther, closestThing, carriedBy, doEquip ? pawn : null) //{ // count = doEquip ? 1 : Mathf.Min(closestThing.stackCount, count) //}; return(null); } } } return(null); }
/// <summary> /// Find an item that should be dropped from the pawn's inventory and how much to drop. /// </summary> /// <param name="pawn"></param> /// <param name="dropThing">The thing which should be dropped.</param> /// <param name="dropCount">The amount to drop.</param> /// <returns>bool, true indicates that the out variables are filled with something to do work on (drop).</returns> // NOTE (ProfoundDarkness): Ended up doing this by nibbling away at the pawn's inventory (or dictionary representation of ThingDefs/Count). // Probably not efficient but was easier to handle atm. static public bool GetExcessThing(this Pawn pawn, out Thing dropThing, out int dropCount) { //(ProfoundDarkness) Thanks to erdelf on the RimWorldMod discord for helping me figure out some dictionary stuff and C# concepts related to 'Primitives' (pass by Value). CompInventory inventory = pawn.TryGetComp <CompInventory>(); Loadout loadout = pawn.GetLoadout(); List <HoldRecord> records = LoadoutManager.GetHoldRecords(pawn); dropThing = null; dropCount = 0; if (inventory == null || inventory.container == null || loadout == null || loadout.Slots.NullOrEmpty()) { return(false); } Dictionary <ThingDef, int> listing = GetStorageByThingDef(pawn); // iterate over specifics and generics and Chip away at the dictionary. foreach (LoadoutSlot slot in loadout.Slots) { if (slot.thingDef != null && listing.ContainsKey(slot.thingDef)) { listing[slot.thingDef] -= slot.count; if (listing[slot.thingDef] <= 0) { listing.Remove(slot.thingDef); } } if (slot.genericDef != null) { List <ThingDef> killKeys = new List <ThingDef>(); int desiredCount = slot.count; // find dictionary entries which corespond to covered slot. foreach (ThingDef def in listing.Keys.Where(td => slot.genericDef.lambda(td))) { listing[def] -= desiredCount; if (listing[def] <= 0) { desiredCount = 0 - listing[def]; killKeys.Add(def); // the thing in inventory is exausted, forget about it. } else { break; // we have satisifed this loadout so no need to keep enumerating. } } // cleanup dictionary. foreach (ThingDef def in killKeys) { listing.Remove(def); } } } // if there is something left in the dictionary, that is what is to be dropped. // Complicated by the fact that we now consider ammo in guns as part of the inventory... if (listing.Any()) { if (records != null && !records.NullOrEmpty()) { // look at each remaining 'uneaten' thingdef in pawn's inventory. foreach (ThingDef def in listing.Keys) { HoldRecord rec = records.FirstOrDefault(r => r.thingDef == def); if (rec == null) { // the item we have extra of has no HoldRecord, drop it. dropThing = inventory.container.FirstOrDefault(t => t.def == def); if (dropThing != null) { dropCount = listing[def] > dropThing.stackCount ? dropThing.stackCount : listing[def]; return(true); } } else if (rec.count < listing[def]) { // the item we have extra of HAS a HoldRecord but the amount carried is above the limit of the HoldRecord, drop extra. dropThing = pawn.inventory.innerContainer.FirstOrDefault(t => t.def == def); if (dropThing != null) { dropCount = listing[def] - rec.count; dropCount = dropCount > dropThing.stackCount ? dropThing.stackCount : dropCount; return(true); } } } } else { foreach (ThingDef def in listing.Keys) { dropThing = inventory.container.FirstOrDefault(t => t.GetInnerIfMinified().def == def); if (dropThing != null) { dropCount = listing[def] > dropThing.stackCount ? dropThing.stackCount : listing[def]; return(true); } } } } // else return(false); }
static void AddMenuItems(Vector3 clickPos, Pawn pawn, List <FloatMenuOption> opts) { // Stabilize if (pawn.health.capacities.CapableOf(PawnCapacityDefOf.Manipulation)) { foreach (LocalTargetInfo curTarget in GenUI.TargetsAt(clickPos, TargetingParameters.ForRescue(pawn), true)) // !! This needs to be patched into A17 { Pawn patient = (Pawn)curTarget.Thing; if (patient.Downed //&& pawn.CanReserveAndReach(patient, PathEndMode.InteractionCell, Danger.Deadly) && pawn.CanReach(patient, PathEndMode.InteractionCell, Danger.Deadly) && patient.health.hediffSet.GetHediffsTendable().Any(h => h.CanBeStabilized())) { if (pawn.story.WorkTypeIsDisabled(WorkTypeDefOf.Doctor)) { opts.Add(new FloatMenuOption("CE_CannotStabilize".Translate() + ": " + "IncapableOfCapacity".Translate(WorkTypeDefOf.Doctor.gerundLabel), null, MenuOptionPriority.Default)); } else { string label = "CE_Stabilize".Translate(patient.LabelCap); Action action = delegate { if (pawn.inventory == null || pawn.inventory.innerContainer == null || !pawn.inventory.innerContainer.Any(t => t.def.IsMedicine)) { Messages.Message("CE_CannotStabilize".Translate() + ": " + "CE_NoMedicine".Translate(pawn), patient, MessageSound.RejectInput); return; } // Drop medicine from inventory Medicine medicine = (Medicine)pawn.inventory.innerContainer.OrderByDescending(t => t.GetStatValue(StatDefOf.MedicalPotency)).FirstOrDefault(); Thing medThing; if (medicine != null && pawn.inventory.innerContainer.TryDrop(medicine, pawn.Position, pawn.Map, ThingPlaceMode.Direct, 1, out medThing)) { Job job = new Job(CE_JobDefOf.Stabilize, patient, medThing); job.count = 1; pawn.jobs.TryTakeOrderedJob(job); PlayerKnowledgeDatabase.KnowledgeDemonstrated(CE_ConceptDefOf.CE_Stabilizing, KnowledgeAmount.Total); } }; opts.Add(FloatMenuUtility.DecoratePrioritizedTask(new FloatMenuOption(label, action, MenuOptionPriority.Default, null, patient), pawn, patient, "ReservedBy")); } } } } // Item pickup. IntVec3 c = IntVec3.FromVector3(clickPos); CompInventory compInventory = pawn.TryGetComp <CompInventory>(); if (compInventory != null) { List <Thing> thingList = c.GetThingList(pawn.Map); 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)) { opts.Add(new FloatMenuOption("CannotPickUp".Translate() + " " + item.LabelShort + " (" + "NoPath".Translate() + ")", null)); } else if (!compInventory.CanFitInInventory(item, out count)) { opts.Add(new FloatMenuOption("CannotPickUp".Translate(new object[] { item.LabelShort }) + " (" + "CE_InventoryFull".Translate() + ")", null)); } // Pick up x else if (count == 1) { opts.Add(FloatMenuUtility.DecoratePrioritizedTask(new FloatMenuOption("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, JobTag.Misc); pawn.Notify_HoldTrackerJob(job); PlayerKnowledgeDatabase.KnowledgeDemonstrated(CE_ConceptDefOf.CE_InventoryWeightBulk, KnowledgeAmount.SpecificInteraction); }, MenuOptionPriority.High, null, null, 0f, null, null), pawn, item, "ReservedBy")); } else { if (count < item.stackCount) { opts.Add(new FloatMenuOption("CannotPickUpAll".Translate(new object[] { item.Label }) + " (" + "CE_InventoryFull".Translate() + ")", null, MenuOptionPriority.Default, null, null, 0f, null, null)); } else { opts.Add(FloatMenuUtility.DecoratePrioritizedTask(new FloatMenuOption("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, JobTag.Misc); pawn.Notify_HoldTrackerJob(job); PlayerKnowledgeDatabase.KnowledgeDemonstrated(CE_ConceptDefOf.CE_InventoryWeightBulk, KnowledgeAmount.SpecificInteraction); }, MenuOptionPriority.High, null, null, 0f, null, null), pawn, item, "ReservedBy")); } opts.Add(FloatMenuUtility.DecoratePrioritizedTask(new FloatMenuOption("PickUpSome".Translate(new object[] { item.Label }), delegate { int to = Mathf.Min(count, item.stackCount); Dialog_Slider window = new Dialog_Slider("PickUpCount".Translate(new object[] { item.LabelShort }), 1, to, delegate(int selectCount) { item.SetForbidden(false, false); Job job = new Job(JobDefOf.TakeInventory, item); job.count = selectCount; pawn.jobs.TryTakeOrderedJob(job, JobTag.Misc); pawn.Notify_HoldTrackerJob(job); }, -2147483648); Find.WindowStack.Add(window); PlayerKnowledgeDatabase.KnowledgeDemonstrated(CE_ConceptDefOf.CE_InventoryWeightBulk, KnowledgeAmount.SpecificInteraction); }, MenuOptionPriority.High, null, null, 0f, null, null), pawn, item, "ReservedBy")); } } } } }
public static void DrawGreedyCE(PawnModal selPawn, Vector2 size) { // get the inventory comp CompInventory comp = selPawn.Pawn.TryGetComp <CompInventory>(); // set up rects Rect listRect = new Rect( _margin, _topPadding, size.x - 2 * _margin, size.y - _topPadding - _margin); // draw bars at the bottom if (comp != null) { PlayerKnowledgeDatabase.KnowledgeDemonstrated(CE_ConceptDefOf.CE_InventoryWeightBulk, KnowledgeAmount.FrameDisplayed); // adjust rects if comp found listRect.height -= (_margin / 2 + _barHeight) * 2; Rect weightRect = new Rect(_margin, listRect.yMax + _margin / 2, listRect.width, _barHeight); Rect bulkRect = new Rect(_margin, weightRect.yMax + _margin / 2, listRect.width, _barHeight); // draw bars Utility_Loadouts.DrawBar(bulkRect, comp.currentBulk, comp.capacityBulk, "CE_Bulk".Translate(), selPawn.Pawn.GetBulkTip()); Utility_Loadouts.DrawBar(weightRect, comp.currentWeight, comp.capacityWeight, "CE_Weight".Translate(), selPawn.Pawn.GetWeightTip()); // draw text overlays on bars Text.Font = GameFont.Small; Text.Anchor = TextAnchor.MiddleCenter; string currentBulk = CE_StatDefOf.CarryBulk.ValueToString(comp.currentBulk, CE_StatDefOf.CarryBulk.toStringNumberSense); string capacityBulk = CE_StatDefOf.CarryBulk.ValueToString(comp.capacityBulk, CE_StatDefOf.CarryBulk.toStringNumberSense); Widgets.Label(bulkRect, currentBulk + "/" + capacityBulk); string currentWeight = comp.currentWeight.ToString("0.#"); string capacityWeight = CE_StatDefOf.CarryWeight.ValueToString(comp.capacityWeight, CE_StatDefOf.CarryWeight.toStringNumberSense); Widgets.Label(weightRect, currentWeight + "/" + capacityWeight); Text.Anchor = TextAnchor.UpperLeft; } // start drawing list (rip from ITab_Pawn_Gear) GUI.BeginGroup(listRect); Text.Font = GameFont.Small; GUI.color = Color.white; Rect outRect = new Rect(0f, 0f, listRect.width, listRect.height); Rect viewRect = new Rect(0f, 0f, listRect.width - 16f, _scrollViewHeight); Widgets.BeginScrollView(outRect, ref _scrollPosition, viewRect); float num = 0f; Utility.TryDrawComfyTemperatureRange(selPawn.Pawn, ref num, viewRect.width); if (Utility.ShouldShowOverallArmor(selPawn.Pawn)) { Widgets.ListSeparator(ref num, viewRect.width, "OverallArmor".Translate()); Utility.TryDrawOverallArmor(selPawn.Pawn, ref num, viewRect.width, StatDefOf.ArmorRating_Blunt, "ArmorBlunt".Translate(), " " + "CE_MPa".Translate()); Utility.TryDrawOverallArmor(selPawn.Pawn, ref num, viewRect.width, StatDefOf.ArmorRating_Sharp, "ArmorSharp".Translate(), "CE_mmRHA".Translate()); Utility.TryDrawOverallArmor(selPawn.Pawn, ref num, viewRect.width, StatDefOf.ArmorRating_Heat, "ArmorHeat".Translate(), "%"); } if (Utility.ShouldShowEquipment(selPawn.Pawn)) { Widgets.ListSeparator(ref num, viewRect.width, "Equipment".Translate()); foreach (ThingWithComps current in selPawn.Pawn.equipment.AllEquipmentListForReading) { Utility.DrawThingRow(selPawn, ref num, viewRect.width, current); } } if (Utility.ShouldShowApparel(selPawn.Pawn)) { Widgets.ListSeparator(ref num, viewRect.width, "Apparel".Translate()); foreach (Apparel current2 in from ap in selPawn.Pawn.apparel.WornApparel orderby ap.def.apparel.bodyPartGroups[0].listOrder descending select ap) { Utility.DrawThingRow(selPawn, ref num, viewRect.width, current2); } } if (Utility.ShouldShowInventory(selPawn.Pawn)) { num += 3; // Make a little room for the button. float buttonY = num; // Could be accomplished with seperator being after the button... Widgets.ListSeparator(ref num, viewRect.width, "Inventory".Translate()); Loadout curLoadout = selPawn.Pawn.GetLoadout(); if (!(curLoadout == null || curLoadout.Slots.NullOrEmpty())) { Widgets.Label(new Rect(viewRect.width / 4, buttonY, viewRect.width / 4, 26f), selPawn.Pawn.GetLoadout().label); } else { Widgets.Label(new Rect(viewRect.width / 4, buttonY, viewRect.width / 4, 26f), "CE_NoLoadouts".Translate()); } // Select loadout button if (Widgets.ButtonText(new Rect(viewRect.width / 2, buttonY, viewRect.width / 4, 26f), Translator.Translate("CE_SelectLoadout"), true, false, true)) { List <Loadout> loadouts = (from l in LoadoutManager.Loadouts where !l.defaultLoadout select l).ToList(); List <FloatMenuOption> list = new List <FloatMenuOption>(); if (loadouts.Count == 0) { list.Add(new FloatMenuOption(Translator.Translate("CE_NoLoadouts"), null)); } else { for (int i = 0; i < loadouts.Count; i++) { int local_i = i; list.Add(new FloatMenuOption(loadouts[i].LabelCap, delegate { selPawn.Pawn.SetLoadout(loadouts[local_i]); })); } } Find.WindowStack.Add(new FloatMenu(list)); } Rect loadoutButtonRect = new Rect(viewRect.width / 4 * 3, buttonY, viewRect.width / 4, 26f); // button is half the available width... if (Widgets.ButtonText(loadoutButtonRect, "Corgi_OpenLoadout".Translate())) { if (selPawn.Pawn.IsColonist && (curLoadout == null || curLoadout.Slots.NullOrEmpty())) { Loadout loadout = selPawn.Pawn.GenerateLoadoutFromPawn(); LoadoutManager.AddLoadout(loadout); selPawn.Pawn.SetLoadout(loadout); } // Original comments //// UNDONE ideally we'd open the assign (MainTabWindow_OutfitsAndLoadouts) tab as if the user clicked on it here. //// (ProfoundDarkness) But I have no idea how to do that just yet. The attempts I made seem to put the RimWorld UI into a bit of a bad state. //// ie opening the tab like the dialog below. //// Need to understand how RimWorld switches tabs and see if something similar can be done here //// (or just remove the unfinished marker). //// Opening this window is the same way as if from the assign tab so should be correct. Find.WindowStack.Add(new Dialog_ManageLoadouts(selPawn.Pawn.GetLoadout())); } workingInvList.Clear(); workingInvList.AddRange(selPawn.Pawn.inventory.innerContainer); for (int i = 0; i < workingInvList.Count; i++) { Utility.DrawThingRow(selPawn, ref num, viewRect.width, workingInvList[i].GetInnerIfMinified(), true); } } if (Event.current.type == EventType.Layout) { _scrollViewHeight = num + 30f; } Widgets.EndScrollView(); GUI.EndGroup(); GUI.color = Color.white; Text.Anchor = TextAnchor.UpperLeft; }
public static void DrawJealousCE(PawnModal selPawn, Vector2 size) { // Races that don't have a humanoid body will fall back to Greedy tab if (selPawn.Pawn.RaceProps.body != BodyDefOf.Human) { DrawGreedyCE(selPawn, size); return; } // set up rects Rect listRect = new Rect( _margin, _topPadding, size.x - 2 * _margin, size.y - _topPadding - _margin); // get the inventory comp CompInventory comp = selPawn.Pawn.TryGetComp <CompInventory>(); if (comp != null) { PlayerKnowledgeDatabase.KnowledgeDemonstrated(CE_ConceptDefOf.CE_InventoryWeightBulk, KnowledgeAmount.FrameDisplayed); // adjust rects if comp found listRect.height -= (_margin / 2 + _barHeight) * 2; Rect weightRect = new Rect(_margin, listRect.yMax + _margin / 2, listRect.width, _barHeight); Rect bulkRect = new Rect(_margin, weightRect.yMax + _margin / 2, listRect.width, _barHeight); // draw bars Utility_Loadouts.DrawBar(bulkRect, comp.currentBulk, comp.capacityBulk, "CE_Bulk".Translate(), selPawn.Pawn.GetBulkTip()); Utility_Loadouts.DrawBar(weightRect, comp.currentWeight, comp.capacityWeight, "CE_Weight".Translate(), selPawn.Pawn.GetWeightTip()); Utility_DrawCE.DrawBulkBreakdown(selPawn.Pawn, bulkRect); Utility.DrawMassBreakdown(selPawn.Pawn, weightRect); // draw text overlays on bars Text.Font = GameFont.Small; Text.Anchor = TextAnchor.MiddleCenter; string currentBulk = CE_StatDefOf.CarryBulk.ValueToString(comp.currentBulk, CE_StatDefOf.CarryBulk.toStringNumberSense); string capacityBulk = CE_StatDefOf.CarryBulk.ValueToString(comp.capacityBulk, CE_StatDefOf.CarryBulk.toStringNumberSense); Widgets.Label(bulkRect, currentBulk + "/" + capacityBulk); string currentWeight = comp.currentWeight.ToString("0.#"); string capacityWeight = CE_StatDefOf.CarryWeight.ValueToString(comp.capacityWeight, CE_StatDefOf.CarryWeight.toStringNumberSense); Widgets.Label(weightRect, currentWeight + "/" + capacityWeight); Text.Anchor = TextAnchor.UpperLeft; } // start drawing the view GUI.BeginGroup(listRect); Text.Font = GameFont.Small; GUI.color = Color.white; Rect outRect = new Rect(0f, 0f, listRect.width, listRect.height); Rect viewRect = new Rect(0f, 0f, listRect.width - 16f, _scrollViewHeight); Widgets.BeginScrollView(outRect, ref _scrollPosition, viewRect); // draw Mass info and Temperature on the side Vector2 rectStat = new Vector2(374, 0); Utility.TryDrawComfyTemperatureRangeWithImage(selPawn.Pawn, rectStat); // draw armor rating for humanoid on the side Rect rectarmor = new Rect(374f, 84f, 128f, 85f); TooltipHandler.TipRegion(rectarmor, "OverallArmor".Translate()); Rect rectblunt = new Rect(rectarmor.x, rectarmor.y, rectarmor.width, 27f); Utility.TryDrawOverallArmorWithImage(selPawn.Pawn, rectblunt, StatDefOf.ArmorRating_Blunt, "ArmorBlunt".Translate(), ContentFinder <Texture2D> .Get("UI/Icons/Sandy_ArmorBlunt_Icon", true), true, " " + "CE_MPa".Translate()); Rect rectsharp = new Rect(rectarmor.x, rectarmor.y + 30f, rectarmor.width, 27f); Utility.TryDrawOverallArmorWithImage(selPawn.Pawn, rectsharp, StatDefOf.ArmorRating_Sharp, "ArmorSharp".Translate(), ContentFinder <Texture2D> .Get("UI/Icons/Sandy_ArmorSharp_Icon", true), true, "CE_mmRHA".Translate()); Rect rectheat = new Rect(rectarmor.x, rectarmor.y + 60f, rectarmor.width, 27f); Utility.TryDrawOverallArmorWithImage(selPawn.Pawn, rectheat, StatDefOf.ArmorRating_Heat, "ArmorHeat".Translate(), ContentFinder <Texture2D> .Get("UI/Icons/Sandy_ArmorHeat_Icon", true), true); //Pawn Color color = new Color(1f, 1f, 1f, 1f); GUI.color = color; Rect PawnRect = new Rect(374f, 172f, 128f, 128f); Utility.DrawColonist(PawnRect, selPawn.Pawn); // draw equipment (equipment means barrel that can shoot bullets, plank that can slice flesh in half) // It is weapon. SmartRect rectForEquipment = new SmartRect(new Rect(), CorgiBodyPartGroupDefOf.Arse, PawnRect.x, PawnRect.x, null, PawnRect.x, size.x - 20f); rectForEquipment.y = PawnRect.yMax; rectForEquipment.width = _apparelRectWidth; rectForEquipment.height = _apparelRectHeight; if (Utility.ShouldShowEquipment(selPawn.Pawn) && (selPawn.Pawn.RaceProps.body == BodyDefOf.Human)) { Rect primaryRect = rectForEquipment.NextAvailableRect(); GUI.DrawTexture(primaryRect, ContentFinder <Texture2D> .Get("UI/Widgets/DesButBG", true)); TooltipHandler.TipRegion(primaryRect, "Corgi_PrimaryWeapon".Translate()); foreach (ThingWithComps fireShootingBarrel in selPawn.Pawn.equipment.AllEquipmentListForReading) { if (fireShootingBarrel == selPawn.Pawn.equipment.Primary) { Utility.DrawThingRowWithImage(selPawn, primaryRect, fireShootingBarrel); } else { UtilityDraw.DrawThumbnails(selPawn, rectForEquipment, fireShootingBarrel, _apparelOverflow); } } // Draw shield foreach (Apparel apparel in selPawn.Pawn.apparel.WornApparel) { if (apparel.def.apparel.LastLayer == CEApparelLayerDefOf.Shield) { rectForEquipment = rectForEquipment .GetWorkingRect(CorgiBodyPartGroupDefOf.Arse, PawnRect.x, PawnRect.x); UtilityDraw.DrawThumbnails(selPawn, rectForEquipment, apparel, _apparelOverflow); } } } // List order: Head:200-181, Neck:180-101, Torso:100-51, Waist:50-11, Legs:10-0 // Check \steamapps\common\RimWorld\Mods\Core\Defs\Bodies\BodyPartGroups.xml IEnumerable <Apparel> apparels = from ap in selPawn.Pawn.apparel.WornApparel where ap.def.apparel.LastLayer != CEApparelLayerDefOf.Shield orderby ap.def.apparel.bodyPartGroups[0].listOrder descending select ap; IEnumerator <Apparel> apparelCounter = apparels.GetEnumerator(); //Hats. BodyGroup: Fullhead; Layer: Overhead _smartRectHead = _smartRectCurrent = new SmartRect(new Rect(0, 0, _apparelRectWidth, _apparelRectHeight), BodyPartGroupDefOf.UpperHead, _startingXforRect, _startingXforRect, _smartRects, 10, rectStat.x); Rect HeadOverRect = _smartRectCurrent.NextAvailableRect(); GUI.DrawTexture(HeadOverRect, ContentFinder <Texture2D> .Get("UI/Widgets/DesButBG", true)); Rect tipRect1 = HeadOverRect; TooltipHandler.TipRegion(tipRect1, "Sandy_Head".Translate()); // cont is used to Check if there is more apparel in the list bool cont = false; bool hatDrawn = false; // Draw apparels on the head while (apparelCounter.MoveNext()) { Apparel apparel = apparelCounter.Current; if (apparel.def.apparel.bodyPartGroups[0].listOrder > CorgiBodyPartGroupDefOf.Neck.listOrder) { // Check RimWorld.Pawn_ApparelTracker.Wear() for more information on wearing rules if ((apparel.def.apparel.bodyPartGroups.Contains(CorgiBodyPartGroupDefOf.FullHead) || apparel.def.apparel.bodyPartGroups.Contains(CorgiBodyPartGroupDefOf.UpperHead)) && hatDrawn == false) { Utility.DrawThingRowWithImage(selPawn, HeadOverRect, apparel); hatDrawn = true; } else { _smartRectCurrent = _smartRectCurrent .GetWorkingRect(CorgiBodyPartGroupDefOf.UpperHead, _startingXforRect, _startingXforRect); UtilityDraw.DrawThumbnails(selPawn, _smartRectCurrent, apparel, _apparelOverflow); } } else { cont = true; break; } } // Draw apparels on the neck if (cont) { cont = false; do { Apparel apparel = apparelCounter.Current; if (apparel.def.apparel.bodyPartGroups[0].listOrder <= CorgiBodyPartGroupDefOf.Neck.listOrder && apparel.def.apparel.bodyPartGroups[0].listOrder > BodyPartGroupDefOf.Torso.listOrder) { _smartRectCurrent = _smartRectCurrent .GetWorkingRect(CorgiBodyPartGroupDefOf.Neck, _startingXforRect, _startingXforRect); UtilityDraw.DrawThumbnails(selPawn, _smartRectCurrent, apparel, _apparelOverflow); } else { cont = true; break; } } while (apparelCounter.MoveNext()); } #region Draw Torso // Draw apparels on Torso _smartRectCurrent = _smartRectCurrent .GetWorkingRect(CorgiBodyPartGroupDefOf.Torso, _startingXforRect, _startingXforRect); //Shirts. BodyGroup: Torso; Layer: OnSkin Rect TorsoSkinRect = _smartRectCurrent.NextAvailableRect(); GUI.DrawTexture(TorsoSkinRect, ContentFinder <Texture2D> .Get("UI/Widgets/DesButBG", true)); Rect tipRect3 = TorsoSkinRect.ContractedBy(12f); TooltipHandler.TipRegion(tipRect3, "Sandy_TorsoOnSkin".Translate()); //Vests. BodyGroup: Torso; Layer: Middle Rect TorsoMidRect = _smartRectCurrent.NextAvailableRect(); GUI.DrawTexture(TorsoMidRect, ContentFinder <Texture2D> .Get("UI/Widgets/DesButBG", true)); Rect tipRect2 = TorsoMidRect.ContractedBy(12f); TooltipHandler.TipRegion(tipRect2, "Sandy_TorsoMiddle".Translate()); //Dusters. BodyGroup: Torso; Layer: Shell Rect TorsoShellRect = _smartRectCurrent.NextAvailableRect(); GUI.DrawTexture(TorsoShellRect, ContentFinder <Texture2D> .Get("UI/Widgets/DesButBG", true)); Rect tipRect4 = TorsoShellRect.ContractedBy(12f); TooltipHandler.TipRegion(tipRect4, "Sandy_TorsoShell".Translate()); if (cont) { cont = false; do { Apparel apparel = apparelCounter.Current; if (apparel.def.apparel.bodyPartGroups[0].listOrder <= CorgiBodyPartGroupDefOf.Torso.listOrder && apparel.def.apparel.bodyPartGroups[0].listOrder > CorgiBodyPartGroupDefOf.Waist.listOrder) { if (apparel.def.apparel.bodyPartGroups[0] == BodyPartGroupDefOf.Torso) { if (apparel.def.apparel.LastLayer == ApparelLayerDefOf.Shell) { Utility.DrawThingRowWithImage(selPawn, TorsoShellRect, apparel); } else if (apparel.def.apparel.LastLayer == ApparelLayerDefOf.Middle) { Utility.DrawThingRowWithImage(selPawn, TorsoMidRect, apparel); } else if (apparel.def.apparel.LastLayer == ApparelLayerDefOf.OnSkin) { Utility.DrawThingRowWithImage(selPawn, TorsoSkinRect, apparel); } } else { _smartRectCurrent = _smartRectCurrent .GetWorkingRect(CorgiBodyPartGroupDefOf.Torso, _startingXforRect, _startingXforRect); UtilityDraw.DrawThumbnails(selPawn, _smartRectCurrent, apparel, _apparelOverflow); } } else { cont = true; break; } } while (apparelCounter.MoveNext()); } #endregion Draw Torso #region Draw Waist // Draw apparels on waist _smartRectCurrent = _smartRectCurrent .GetWorkingRect(CorgiBodyPartGroupDefOf.Waist, _startingXforRect, _startingXforRect); //Belts. BodyGroup: Waist; Layer: Belt Rect WaistBeltRect = _smartRectCurrent.NextAvailableRect(); GUI.DrawTexture(WaistBeltRect, ContentFinder <Texture2D> .Get("UI/Widgets/DesButBG", true)); Rect tipRect5 = WaistBeltRect.ContractedBy(12f); TooltipHandler.TipRegion(tipRect5, "Sandy_Belt".Translate()); if (cont) { cont = false; do { Apparel apparel = apparelCounter.Current; if (apparel.def.apparel.bodyPartGroups[0].listOrder <= CorgiBodyPartGroupDefOf.Waist.listOrder && apparel.def.apparel.bodyPartGroups[0].listOrder > CorgiBodyPartGroupDefOf.Legs.listOrder) { if (apparel.def.apparel.LastLayer == ApparelLayerDefOf.Belt) { Utility.DrawThingRowWithImage(selPawn, WaistBeltRect, apparel); } else { _smartRectCurrent = _smartRectCurrent .GetWorkingRect(CorgiBodyPartGroupDefOf.Waist, _startingXforRect, _startingXforRect); UtilityDraw.DrawThumbnails(selPawn, _smartRectCurrent, apparel, _apparelOverflow); } } else { cont = true; break; } } while (apparelCounter.MoveNext()); } #endregion Draw Waist #region Draw Legs // Draw apparels on lesg _smartRectCurrent = _smartRectCurrent .GetWorkingRect(CorgiBodyPartGroupDefOf.Legs, _startingXforRect, _startingXforRect); //Pants. BodyGroup: Legs; Layer: OnSkin Rect LegSkinRect = _smartRectCurrent.NextAvailableRect(); GUI.DrawTexture(LegSkinRect, ContentFinder <Texture2D> .Get("UI/Widgets/DesButBG", true)); Rect tipRect6 = LegSkinRect.ContractedBy(12f); TooltipHandler.TipRegion(tipRect6, "Sandy_Pants".Translate()); if (cont) { bool pantWore = false; cont = false; do { Apparel apparel = apparelCounter.Current; if (apparel.def.apparel.bodyPartGroups[0].listOrder <= CorgiBodyPartGroupDefOf.Legs.listOrder && apparel.def.apparel.bodyPartGroups[0].listOrder > 0) { if (apparel.def.apparel.LastLayer == ApparelLayerDefOf.OnSkin && pantWore == false) { Utility.DrawThingRowWithImage(selPawn, LegSkinRect, apparel); pantWore = true; } else { _smartRectCurrent = _smartRectCurrent .GetWorkingRect(CorgiBodyPartGroupDefOf.Legs, _startingXforRect, _startingXforRect); UtilityDraw.DrawThumbnails(selPawn, _smartRectCurrent, apparel, _apparelOverflow); } } else { cont = true; break; } } while (apparelCounter.MoveNext()); } #endregion Draw Legs #region Draw Traits float traitY = _smartRectCurrent.Rect.yMax + _smartRectCurrent.HeightGap; Rect rectTraits = new Rect(_margin, traitY, 80f, 30f); Text.Font = GameFont.Medium; Widgets.Label(rectTraits, "Traits".Translate()); Text.Font = GameFont.Small; float traitX = _margin + 80f; foreach (Trait trait in selPawn.Pawn.story.traits.allTraits) { Rect rectTrait = new Rect(traitX, traitY, rectStat.x - traitX - _margin, Utility.StandardLineHeight); if (Mouse.IsOver(rectTrait)) { Widgets.DrawHighlight(rectTrait); } Widgets.Label(rectTrait, trait.LabelCap); TooltipHandler.TipRegion(rectTrait, trait.TipString(selPawn.Pawn)); traitY += Utility.StandardLineHeight; } #endregion #region Extra Apparels // Put undrawn into overflow list if (cont) { do { _apparelOverflow.Add(apparelCounter.Current); } while (apparelCounter.MoveNext()); } // Try to draw the extras UtilityDraw.DrawApparelToNextRow(selPawn, _smartRectHead, _apparelOverflow); // If there is any more remains, put them into their own category if (_apparelOverflow.Count > 0) { float rollingY1 = traitY; //float rollingY1 = _smartRectCurrent.y + _smartRectCurrent.height + Utility.StandardLineHeight; Widgets.ListSeparator(ref rollingY1, viewRect.width, "Corgi_ExtraApparels".Translate()); _smartRectCurrent = _smartRectCurrent.GetWorkingRect(CorgiBodyPartGroupDefOf.Arse, _margin, _margin); _smartRectCurrent.y = rollingY1 + Utility.StandardLineHeight; do { List <ThingWithComps> tempList = new List <ThingWithComps>(_apparelOverflow); _apparelOverflow.Clear(); foreach (Apparel apparel in tempList) { UtilityDraw.DrawThumbnails(selPawn, _smartRectCurrent, apparel, _apparelOverflow); } if (_apparelOverflow.Count > 0) { SmartRect temp = _smartRectCurrent.CreateSibling(CorgiBodyPartGroupDefOf.Arse); temp.PreviousSibling = _smartRectCurrent; _smartRectCurrent.NextSibling = temp; _smartRectCurrent = temp; continue; } } while (_apparelOverflow.Count > 0); } #endregion Extra Apparels #region Draw Inventory // Draw inventory float rollingY = 0; if (Utility.ShouldShowInventory(selPawn.Pawn)) { rollingY = Math.Max(Math.Max(traitY, _smartRectCurrent.Rect.yMax), rectForEquipment.Rect.yMax); //if (_smartRectCurrent.Rect.yMax > rectForEquipment.Rect.yMax) //{ // rollingY = _smartRectCurrent.Rect.yMax; //} //else //{ // rollingY = rectForEquipment.Rect.yMax; //} rollingY += Utility.StandardLineHeight; rollingY += 3; // Make a little room for the button. float buttonY = rollingY; Widgets.ListSeparator(ref rollingY, viewRect.width, "Inventory".Translate()); Loadout curLoadout = selPawn.Pawn.GetLoadout(); if (!(curLoadout == null || curLoadout.Slots.NullOrEmpty())) { Widgets.Label(new Rect(viewRect.width / 4, buttonY, viewRect.width / 4, 26f), selPawn.Pawn.GetLoadout().label); } else { Widgets.Label(new Rect(viewRect.width / 4, buttonY, viewRect.width / 4, 26f), "CE_NoLoadouts".Translate()); } //Select loadout button if (Widgets.ButtonText(new Rect(viewRect.width / 2, buttonY, viewRect.width / 4, 26f), Translator.Translate("CE_SelectLoadout"), true, false, true)) { List <Loadout> loadouts = (from l in LoadoutManager.Loadouts where !l.defaultLoadout select l).ToList(); List <FloatMenuOption> list = new List <FloatMenuOption>(); if (loadouts.Count == 0) { list.Add(new FloatMenuOption(Translator.Translate("CE_NoLoadouts"), null)); } else { for (int i = 0; i < loadouts.Count; i++) { int local_i = i; list.Add(new FloatMenuOption(loadouts[i].LabelCap, delegate { selPawn.Pawn.SetLoadout(loadouts[local_i]); })); } } Find.WindowStack.Add(new FloatMenu(list)); } Rect loadoutButtonRect = new Rect(viewRect.width / 4 * 3, buttonY, viewRect.width / 4, 26f); // button is half the available width... if (Widgets.ButtonText(loadoutButtonRect, "Corgi_OpenLoadout".Translate())) { if (selPawn.Pawn.IsColonist && (curLoadout == null || curLoadout.Slots.NullOrEmpty())) { Loadout loadout = selPawn.Pawn.GenerateLoadoutFromPawn(); LoadoutManager.AddLoadout(loadout); selPawn.Pawn.SetLoadout(loadout); } // Original comments //// UNDONE ideally we'd open the assign (MainTabWindow_OutfitsAndLoadouts) tab as if the user clicked on it here. //// (ProfoundDarkness) But I have no idea how to do that just yet. The attempts I made seem to put the RimWorld UI into a bit of a bad state. //// ie opening the tab like the dialog below. //// Need to understand how RimWorld switches tabs and see if something similar can be done here //// (or just remove the unfinished marker). //// Opening this window is the same way as if from the assign tab so should be correct. Find.WindowStack.Add(new Dialog_ManageLoadouts(selPawn.Pawn.GetLoadout())); } workingInvList.Clear(); workingInvList.AddRange(selPawn.Pawn.inventory.innerContainer); for (int i = 0; i < workingInvList.Count; i++) { Utility.DrawThingRow(selPawn, ref rollingY, viewRect.width, workingInvList[i].GetInnerIfMinified(), true); } } #endregion Draw Inventory if (Event.current.type == EventType.Layout) { _scrollViewHeight = rollingY + 30f; } Widgets.EndScrollView(); GUI.EndGroup(); GUI.color = Color.white; Text.Anchor = TextAnchor.UpperLeft; Reset(); }
static void DropDownThingMenu(object tab, Thing thing) { Pawn SelPawnForGear = (Pawn)LSelPawnForGear.GetValue(tab); Pawn SelPawn = (Pawn)LSelPawn.GetValue(tab); bool canControl = (bool)LCanControl.GetValue(tab); List <FloatMenuOption> list = new List <FloatMenuOption>(); list.Add(new FloatMenuOption("ThingInfo".Translate(), delegate() { Find.WindowStack.Add(new Dialog_InfoCard(thing)); }, MenuOptionPriority.Default, null, null, 0f, null, null)); //bool canControl = this.CanControl; if (canControl) { ThingWithComps eq = thing as ThingWithComps; bool flag10 = eq != null && eq.TryGetComp <CompEquippable>() != null; if (flag10) { CompInventory compInventory = SelPawnForGear.TryGetComp <CompInventory>(); CompBiocodable compBiocodable = eq.TryGetComp <CompBiocodable>(); bool flag11 = compInventory != null; if (flag11) { string value = GenLabel.ThingLabel(eq.def, eq.Stuff, 1); bool flag12 = compBiocodable != null && compBiocodable.Biocoded && compBiocodable.CodedPawn != SelPawnForGear; FloatMenuOption item; if (flag12) { item = new FloatMenuOption("CannotEquip".Translate(value) + ": " + "BiocodedCodedForSomeoneElse".Translate(), null, MenuOptionPriority.Default, null, null, 0f, null, null); } else { bool flag13 = SelPawnForGear.IsQuestLodger() && !EquipmentUtility.QuestLodgerCanEquip(eq, SelPawnForGear); if (flag13) { TaggedString t = SelPawnForGear.equipment.AllEquipmentListForReading.Contains(eq) ? "CE_CannotPutAway".Translate(value) : "CannotEquip".Translate(value); item = new FloatMenuOption(t + ": " + "CE_CannotChangeEquipment".Translate(), null, MenuOptionPriority.Default, null, null, 0f, null, null); } else { bool flag14 = SelPawnForGear.equipment.AllEquipmentListForReading.Contains(eq) && SelPawnForGear.inventory != null; if (flag14) { item = new FloatMenuOption("CE_PutAway".Translate(value), delegate() { SelPawnForGear.equipment.TryTransferEquipmentToContainer(SelPawnForGear.equipment.Primary, SelPawnForGear.inventory.innerContainer); }, MenuOptionPriority.Default, null, null, 0f, null, null); } else { bool flag15 = !SelPawnForGear.health.capacities.CapableOf(PawnCapacityDefOf.Manipulation); if (flag15) { item = new FloatMenuOption("CannotEquip".Translate(value), null, MenuOptionPriority.Default, null, null, 0f, null, null); } else { string text4 = "Equip".Translate(value); bool flag16 = eq.def.IsRangedWeapon && SelPawnForGear.story != null && SelPawnForGear.story.traits.HasTrait(TraitDefOf.Brawler); if (flag16) { text4 = text4 + " " + "EquipWarningBrawler".Translate(); } item = new FloatMenuOption(text4, (SelPawnForGear.story != null && SelPawnForGear.WorkTagIsDisabled(WorkTags.Violent)) ? null : new Action(delegate() { compInventory.TrySwitchToWeapon(eq); }), MenuOptionPriority.Default, null, null, 0f, null, null); } } } } list.Add(item); } } //Pawn selPawnForGear = SelPawnForGear; //?? List <Apparel> list2; if (SelPawnForGear == null) { list2 = null; } else { Pawn_ApparelTracker apparel2 = SelPawnForGear.apparel; list2 = ((apparel2 != null) ? apparel2.WornApparel : null); } List <Apparel> list3 = list2; using (List <Apparel> .Enumerator enumerator = list3.GetEnumerator()) { while (enumerator.MoveNext()) { Apparel apparel = enumerator.Current; CompReloadable compReloadable = apparel.TryGetComp <CompReloadable>(); bool flag17 = compReloadable != null && compReloadable.AmmoDef == thing.def && compReloadable.NeedsReload(true); if (flag17) { bool flag18 = !SelPawnForGear.Drafted; if (flag18) { FloatMenuOption item2 = new FloatMenuOption("CE_ReloadApparel".Translate(apparel.Label, thing.Label), delegate() { SelPawnForGear.jobs.TryTakeOrderedJob(JobMaker.MakeJob(JobDefOf.Reload, apparel, thing), JobTag.Misc); }, MenuOptionPriority.Default, null, null, 0f, null, null); list.Add(item2); } } } } bool flag19 = canControl && thing.IngestibleNow && SelPawn.RaceProps.CanEverEat(thing); if (flag19) { Action action = delegate() { SoundDefOf.Tick_High.PlayOneShotOnCamera(null); LInterfaceIngest.Invoke(tab, new object[] { thing }); }; string text5 = thing.def.ingestible.ingestCommandString.NullOrEmpty() ? (string)"ConsumeThing".Translate(thing.LabelShort, thing) : string.Format(thing.def.ingestible.ingestCommandString, thing.LabelShort); bool flag20 = SelPawnForGear.IsTeetotaler() && thing.def.IsNonMedicalDrug; if (flag20) { List <FloatMenuOption> list4 = list; string str = text5; string str2 = ": "; TraitDegreeData traitDegreeData = (from x in TraitDefOf.DrugDesire.degreeDatas where x.degree == -1 select x).First <TraitDegreeData>(); list4.Add(new FloatMenuOption(str + str2 + ((traitDegreeData != null) ? traitDegreeData.label : null), null, MenuOptionPriority.Default, null, null, 0f, null, null)); } else { list.Add(new FloatMenuOption(text5, action, MenuOptionPriority.Default, null, null, 0f, null, null)); } } bool flag21 = SelPawnForGear.IsItemQuestLocked(eq); if (flag21) { list.Add(new FloatMenuOption("CE_CannotDropThing".Translate() + ": " + "DropThingLocked".Translate(), null, MenuOptionPriority.Default, null, null, 0f, null, null)); list.Add(new FloatMenuOption("CE_CannotDropThingHaul".Translate() + ": " + "DropThingLocked".Translate(), null, MenuOptionPriority.Default, null, null, 0f, null, null)); } else { list.Add(new FloatMenuOption("DropThing".Translate(), delegate() { SoundDefOf.Tick_High.PlayOneShotOnCamera(null); LInterfaceDrop.Invoke(tab, new object[] { thing }); }, MenuOptionPriority.Default, null, null, 0f, null, null)); list.Add(new FloatMenuOption("CE_DropThingHaul".Translate(), delegate() { SoundDefOf.Tick_High.PlayOneShotOnCamera(null); InterfaceDropHaul(SelPawnForGear, thing, SelPawn); }, MenuOptionPriority.Default, null, null, 0f, null, null)); } bool flag22 = canControl && (bool)LHoldTrackerIsHeld.Invoke(null, new object[] { SelPawnForGear, thing }); //SelPawnForGear.HoldTrackerIsHeld(thing); if (flag22) { Action action2 = delegate() { SoundDefOf.Tick_High.PlayOneShotOnCamera(null); LHoldTrackerForget.Invoke(null, new object[] { SelPawnForGear, thing }); //SelPawnForGear.HoldTrackerForget(thing); }; list.Add(new FloatMenuOption("CE_HoldTrackerForget".Translate(), action2, MenuOptionPriority.Default, null, null, 0f, null, null)); } } FloatMenu window = new FloatMenu(list, thing.LabelCap, false); Find.WindowStack.Add(window); }
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); }
/// <summary> /// Determines whether a pawn has grenades they can use against a target /// </summary> /// <returns>True if the pawn has at least one destructive grenade in their inventory, false otherwise</returns> private static bool CanBeGrenadier(Pawn pawn, CompInventory comp) { return(comp.rangedWeaponList.Any(w => w.def.IsGrenade() && w.def.IsLethal())); }
/// <summary> /// Determines whether a pawn can use a rocket/grenade launcher against fortified targets /// </summary> /// <returns>True if the pawn has a rocket/grenade launcher with ammo in their inventory, false otherwise</returns> private static bool CanBeRocketeer(Pawn pawn, CompInventory comp) { return(comp.rangedWeaponList.Any(w => w.def.IsLauncher() && w.HasAmmo())); }
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); } } }
public static void trySwitchToWeapon(object compInventory, ThingWithComps newEq) { CompInventory comp = (CompInventory)compInventory; comp.TrySwitchToWeapon(newEq); }
public override string GetExplanation(StatRequest req, ToStringNumberSense numberSense) { StringBuilder stringBuilder = new StringBuilder(); stringBuilder.Append(base.GetExplanation(req, numberSense)); if (req.HasThing) { Pawn thisPawn = req.Thing as Pawn; if (thisPawn != null) { if (thisPawn.RaceProps.intelligence >= Intelligence.ToolUser) { if (MapComponent_ToolsForHaul.currentVehicle.ContainsKey(thisPawn)) { Vehicle_Cart vehicle_Cart = MapComponent_ToolsForHaul.currentVehicle[thisPawn] as Vehicle_Cart; if (vehicle_Cart != null) { if (vehicle_Cart.mountableComp.IsMounted && vehicle_Cart.mountableComp.Driver == thisPawn) { stringBuilder.AppendLine(); stringBuilder.AppendLine("VehicleSpeed".Translate() + ": x" + vehicle_Cart.VehicleSpeed); return(stringBuilder.ToString()); } } Vehicle_Turret vehicle_Turret = MapComponent_ToolsForHaul.currentVehicle[req.Thing as Pawn] as Vehicle_Turret; if (vehicle_Turret != null) { if (vehicle_Turret.mountableComp.IsMounted && vehicle_Turret.mountableComp.Driver == thisPawn) { stringBuilder.AppendLine(); stringBuilder.AppendLine("VehicleSpeed".Translate() + ": x" + vehicle_Turret.VehicleSpeed); return(stringBuilder.ToString()); } } } CompInventory compInventory = ThingCompUtility.TryGetComp <CompInventory>(req.Thing); if (compInventory != null) { stringBuilder.AppendLine(); stringBuilder.AppendLine(Translator.Translate("CR_CarriedWeight") + ": x" + GenText.ToStringPercent(compInventory.moveSpeedFactor)); if (compInventory.encumberPenalty > 0f) { stringBuilder.AppendLine(Translator.Translate("CR_Encumbered") + ": -" + GenText.ToStringPercent(compInventory.encumberPenalty)); stringBuilder.AppendLine(Translator.Translate("CR_FinalModifier") + ": x" + GenText.ToStringPercent(this.GetStatFactor(thisPawn))); } } CompSlotsBackpack compSlotsBackpack = ToolsForHaulUtility.TryGetBackpack(thisPawn).TryGetComp <CompSlotsBackpack>(); if (compSlotsBackpack != null) { stringBuilder.AppendLine(); stringBuilder.AppendLine("CR_CarriedWeightBackpack".Translate() + ": x" + compSlotsBackpack.moveSpeedFactor.ToStringPercent()); if (compSlotsBackpack.encumberPenalty > 0f) { stringBuilder.AppendLine("CR_EncumberedBackpack".Translate() + ": -" + compSlotsBackpack.encumberPenalty.ToStringPercent()); stringBuilder.AppendLine("CR_FinalModifierBackpack".Translate() + ": x" + GetStatFactor(thisPawn).ToStringPercent()); } } } } } return(stringBuilder.ToString()); }