public static void AddWeaponReloadOrders(List <FloatMenuOption> opts, Vector3 clickPos, Pawn pawn) { var c = IntVec3.FromVector3(clickPos); foreach (var thing in c.GetThingList(pawn.Map)) { if (thing.TryGetComp <CompReloadable>() is CompReloadable comp) { var text = "Reloading.Unload".Translate(comp.parent.Named("GEAR")) + " (" + comp.ShotsRemaining + "/" + comp.Props.MaxShots + ")"; if (comp.ShotsRemaining == 0) { text += ": " + "Reloading.NoAmmo".Translate(); opts.Add(new FloatMenuOption(text, null)); } else { opts.Add(new FloatMenuOption(text, () => pawn.jobs.TryTakeOrderedJob(JobMaker.MakeJob(ReloadingDefOf.Unload, thing)))); } } } foreach (var reloadable in pawn.AllReloadComps()) { foreach (var thing in c.GetThingList(pawn.Map)) { if (reloadable.CanReloadFrom(thing)) { var text = (reloadable.Parent is Thing ? "Reload" : "Reloading.Reload").Translate( reloadable.Parent.Named("GEAR"), thing.def.Named("AMMO")) + " (" + reloadable.ShotsRemaining + "/" + reloadable.MaxShots + ")"; var failed = false; var ammo = new List <Thing>(); if (!pawn.CanReach(thing, PathEndMode.ClosestTouch, Danger.Deadly)) { text += ": " + "NoPath".Translate().CapitalizeFirst(); failed = true; } else if (!reloadable.NeedsReload()) { text += ": " + "ReloadFull".Translate(); failed = true; } else if ((ammo = JobGiver_Reload.FindAmmo(pawn, c, reloadable)).NullOrEmpty()) { text += ": " + "ReloadNotEnough".Translate(); failed = true; } if (failed) { opts.Add(new FloatMenuOption(text, null)); } else { opts.Add(FloatMenuUtility.DecoratePrioritizedTask( new FloatMenuOption(text, () => pawn.jobs.TryTakeOrderedJob( JobGiver_Reload.MakeReloadJob(reloadable, ammo))), pawn, thing)); } } else if (thing == pawn) { foreach (var item in pawn.inventory.innerContainer) { if (reloadable.CanReloadFrom(item)) { var text = (reloadable.Parent is Thing ? "Reload" : "Reloading.Reload").Translate( reloadable.Parent.Named("GEAR"), item.def.Named("AMMO")) + " (" + reloadable.ShotsRemaining + "/" + reloadable.MaxShots + ")"; if (!reloadable.NeedsReload()) { opts.Add(new FloatMenuOption(text + ": " + "ReloadFull".Translate(), null)); } else { opts.Add( new FloatMenuOption(text, () => pawn.jobs.TryTakeOrderedJob( JobGiver_ReloadFromInventory.MakeReloadJob(reloadable, item)))); } } } } } } }
public static void ReloadWeaponIfEndingCooldown(Stance_Busy __instance) { if (__instance.verb?.EquipmentSource == null) { return; } var pawn = __instance.verb.CasterPawn; if (pawn == null) { return; } var reloadable = __instance.verb.GetReloadable(); if (reloadable == null || reloadable.ShotsRemaining != 0 || pawn.stances.curStance.StanceBusy) { return; } var item = pawn.inventory.innerContainer.FirstOrDefault(t => reloadable.CanReloadFrom(t)); if (item == null) { if (!pawn.IsColonist && reloadable.Parent is ThingWithComps eq && !pawn.equipment.TryDropEquipment(eq, out var result, pawn.Position)) { Log.Message("Failed to drop " + result); } pawn.jobs.EndCurrentJob(JobCondition.InterruptForced); if (pawn.inventory.innerContainer.FirstOrDefault(t => t.def.IsWeapon && t.def.equipmentType == EquipmentType.Primary) is ThingWithComps newWeapon) { if (reloadable.Parent == pawn.equipment.Primary && reloadable.Parent is ThingWithComps oldWeapon) { pawn.inventory.innerContainer.TryAddOrTransfer(oldWeapon, false); } pawn.inventory.innerContainer.TryTransferToContainer(newWeapon, pawn.equipment.GetDirectlyHeldThings(), 1, false); } if (!pawn.IsColonist && (pawn.equipment.Primary?.def.IsMeleeWeapon ?? true)) { pawn.GetLord()?.CurLordToil?.UpdateAllDuties(); } return; } var job = new Job(pawn.CurJobDef, pawn.CurJob.targetA, pawn.CurJob.targetB, pawn.CurJob.targetC) { canUseRangedWeapon = pawn.CurJob.canUseRangedWeapon, verbToUse = __instance.verb, endIfCantShootInMelee = pawn.CurJob.endIfCantShootInMelee }; pawn.jobs.EndCurrentJob(JobCondition.InterruptForced); pawn.jobs.TryTakeOrderedJob(JobGiver_ReloadFromInventory.MakeReloadJob(reloadable, item), JobTag.UnspecifiedLordDuty); if (!pawn.IsColonist) { pawn.GetLord()?.CurLordToil?.UpdateAllDuties(); } else { pawn.jobs.TryTakeOrderedJob(job, JobTag.UnspecifiedLordDuty, true); } }