// TryCastShotFrom(muzzlePos) public bool TryCastShotFrom(Vector3 muzzlePos) { if (!TryFindCEShootLineFromTo(caster.Position, currentTarget, out var shootLine)) { return(false); } if (projectilePropsCE.pelletCount < 1) { Log.Error(EquipmentSource.LabelCap + " tried firing with pelletCount less than 1."); return(false); } ShiftVecReport report = ShiftVecReportFor(currentTarget); bool pelletMechanicsOnly = false; numShotsFired = (int)AccessTools.Field(typeof(Verb_LaunchProjectileCE), "numShotsFired").GetValue(this); shotAngle = (float)AccessTools.Field(typeof(Verb_LaunchProjectileCE), "shotAngle").GetValue(this); shotRotation = (float)AccessTools.Field(typeof(Verb_LaunchProjectileCE), "shotRotation").GetValue(this); shotSpeed = (float)AccessTools.Field(typeof(Verb_LaunchProjectileCE), "shotSpeed").GetValue(this); for (int i = 0; i < projectilePropsCE.pelletCount; i++) { ProjectileCE projectile = (ProjectileCE)ThingMaker.MakeThing(Projectile, null); GenSpawn.Spawn(projectile, shootLine.Source, caster.Map); ShiftTarget(report, pelletMechanicsOnly); //New aiming algorithm projectile.canTargetSelf = false; var targDist = (muzzlePos.ToIntVec3().ToIntVec2.ToVector2Shifted() - currentTarget.Cell.ToIntVec2.ToVector2Shifted()).magnitude; if (targDist <= 2) { targDist *= 2; // Double to account for divide by 4 in ProjectileCE minimum collision distance calculations } // projectile.minCollisionSqr = Mathf.Pow(targDist, 2); projectile.intendedTarget = currentTarget.Thing; projectile.mount = caster.Position.GetThingList(caster.Map).FirstOrDefault(t => t is Pawn && t != caster); projectile.AccuracyFactor = report.accuracyFactor * report.swayDegrees * ((numShotsFired + 1) * 0.75f); projectile.Launch( Shooter, //Shooter instead of caster to give turret operators' records the damage/kills obtained new Vector2(muzzlePos.x, muzzlePos.z), shotAngle, shotRotation, ShotHeight, ShotSpeed, EquipmentSource ); pelletMechanicsOnly = true; } /// Log.Message("Fired from "+caster.ThingID+" at "+ShotHeight); /// pelletMechanicsOnly = false; numShotsFired++; if (CompAmmo != null && !CompAmmo.CanBeFiredNow) { CompAmmo?.TryStartReload(); } if (CompReloadable != null) { CompReloadable.UsedOnce(); } return(true); }
public static IEnumerable <Gizmo> Postfix(IEnumerable <Gizmo> __result, CompReloadable __instance) { foreach (Gizmo g in __result) { yield return(g); } void TryReloadArmor() { ThingWithComps gear = __instance.parent; Pawn wearer = __instance.Wearer; Job j = null; bool gotJob = Harmony_JobGiver_Reload_TryGiveJob.Prefix(wearer, ref j); if (j != null) { wearer.jobs.StartJob(j, JobCondition.InterruptForced, null, wearer.CurJob?.def != j.def, true); } }; yield return(new Command_ReloadArmor { compReloadable = __instance, action = TryReloadArmor, defaultLabel = (string)"CE_ReloadLabel".Translate() + " worn armor", defaultDesc = "CE_ReloadDesc".Translate(), icon = ContentFinder <Texture2D> .Get("UI/Buttons/Reload", true) }); }
protected override bool TryCastShot() { Pawn casterPawn = this.CasterPawn; if (casterPawn == null) { return(false); } foreach (CompUseEffect compUseEffect in base.EquipmentSource.GetComps <CompUseEffect>()) { if (compUseEffect.CanBeUsedBy(casterPawn, out string failReason)) { compUseEffect.DoEffect(casterPawn); } else { Messages.Message(failReason, casterPawn, MessageTypeDefOf.NegativeEvent, false); } } CompReloadable reloadableCompSource = base.ReloadableCompSource; if (reloadableCompSource != null) { reloadableCompSource.UsedOnce(); } return(true); }
public static void EMP(CompReloadable comp) { if (comp == null || !comp.CanBeUsed) { return; } ThingWithComps parent = comp.parent; Pawn wearer = comp.Wearer; GenExplosion.DoExplosion(wearer.Position, wearer.Map, parent.GetStatValue(AvaliDefs.ExplodeEMPRadius, true), DamageDefOf.EMP, (Thing)null, -1, -1f, (SoundDef)null, (ThingDef)null, (ThingDef)null, (Thing)null, (ThingDef)null, 0.0f, 1, false, (ThingDef)null, 0.0f, 1, 0.0f, false, new float?(), (List <Thing>)null); comp.UsedOnce(); }
protected override bool TryCastShot() { if (!ModLister.RoyaltyInstalled) { Log.ErrorOnce("Items with jump capability are a Royalty-specific game system. If you want to use this code please check ModLister.RoyaltyInstalled before calling it. See rules on the Ludeon forum for more info.", 550187797); return(false); } #pragma warning disable CS0436 // Type conflicts with imported type CompReloadable reloadableCompSource = base.ReloadableCompSource; #pragma warning restore CS0436 // Type conflicts with imported type Pawn casterPawn = CasterPawn; if (casterPawn == null || reloadableCompSource == null || !reloadableCompSource.CanBeUsed) { return(false); } // Log.Message("reloadableCompSource " + reloadableCompSource.Props.chargeNoun); IntVec3 cell = currentTarget.Cell; Map map = casterPawn.Map; CompReloadableDual reloadableDual = reloadableCompSource as CompReloadableDual; if (reloadableDual != null) { if (this.verbProps.label == reloadableDual.Props.chargeNoun) { reloadableDual.UsedOnce(); // Log.Message("reloadableDual UsedOnce " + reloadableDual.RemainingCharges); } else if (this.verbProps.label == reloadableDual.Props.chargeNounSecondry) { reloadableDual.UsedOnceSecondry(); // Log.Message("reloadableDual UsedOnceSecondry " + reloadableDual.RemainingChargesSecondry); } } else { if (this.verbProps.label == reloadableCompSource.Props.chargeNoun) { reloadableCompSource.UsedOnce(); // Log.Message("reloadableCompSource UsedOnce " + reloadableCompSource.RemainingCharges); } } PawnFlyer pawnFlyer = PawnFlyer.MakeFlyer(verbProps.defaultProjectile ?? ThingDefOf.PawnJumper, casterPawn, cell); if (pawnFlyer != null) { GenSpawn.Spawn(pawnFlyer, cell, map); return(true); } return(false); }
public virtual bool Available() { if (verbProps.consumeFuelPerShot > 0f) { CompRefuelable compRefuelable = caster.TryGetComp <CompRefuelable>(); if (compRefuelable != null && compRefuelable.Fuel < verbProps.consumeFuelPerShot) { return(false); } } CompReloadable compReloadable = EquipmentSource?.GetComp <CompReloadable>(); if (compReloadable != null && !compReloadable.CanBeUsed) { return(false); } return(true); }
internal static bool Prefix(Pawn pawn, ref Job __result) { CompReloadable compReloadable = ReloadableUtility.FindSomeReloadableComponent(pawn, false); if (compReloadable != null) { var inventoryAmmo = pawn?.inventory?.innerContainer?.InnerListForReading?.Find(thing => thing.def == compReloadable.AmmoDef); if (inventoryAmmo != null) { int dropCount = Mathf.Min(compReloadable.MaxAmmoNeeded(true), inventoryAmmo.stackCount); pawn.inventory.innerContainer.TryDrop(inventoryAmmo, pawn.Position, pawn.Map, ThingPlaceMode.Direct, dropCount, out Thing dropThing); var droppedAmmo = new List <Thing> { dropThing }; __result = JobGiver_Reload.MakeReloadJob(compReloadable, droppedAmmo); return(false); } } return(true); }
public static bool Prefix(StatRequest req, ref float val, StringBuilder explanation) { if (req != null && req.Thing != null && req.Thing.def != null) { if (req.Thing.def.IsRangedWeapon) { CompReloadable compReloadable = req.Thing.TryGetComp <CompReloadable>(); if (compReloadable != null) { if (compReloadable.AmmoDef != null && compReloadable.RemainingCharges != 0) { int num = compReloadable.RemainingCharges; float chargesPrice = compReloadable.AmmoDef.BaseMarketValue * (float)num; val += chargesPrice; explanation?.AppendLine("StatsReport_ReloadMarketValue".Translate(NamedArgumentUtility.Named(compReloadable.AmmoDef, "AMMO"), num.Named("COUNT")) + ": " + chargesPrice.ToStringMoneyOffset()); } return(false); } } } return(true); }
public static bool AddHumanlikeOrders(Vector3 clickPos, Pawn pawn, List <FloatMenuOption> opts) { IntVec3 c = IntVec3.FromVector3(clickPos); foreach (Thing thing in c.GetThingList(pawn.Map)) { Pawn pawn2; if ((pawn2 = (thing as Pawn)) != null) { Lord lord = pawn2.GetLord(); if (lord != null && lord.CurLordToil != null) { IEnumerable <FloatMenuOption> enumerable = lord.CurLordToil.ExtraFloatMenuOptions(pawn2, pawn); if (enumerable != null) { foreach (FloatMenuOption item8 in enumerable) { opts.Add(item8); } } } } } if (pawn.health.capacities.CapableOf(PawnCapacityDefOf.Manipulation)) { foreach (LocalTargetInfo item9 in GenUI.TargetsAt_NewTemp(clickPos, TargetingParameters.ForArrest(pawn), thingsOnly: true)) { bool flag = item9.HasThing && item9.Thing is Pawn && ((Pawn)item9.Thing).IsWildMan(); if (pawn.Drafted || flag) { if (item9.Thing is Pawn && (pawn.InSameExtraFaction((Pawn)item9.Thing, ExtraFactionType.HomeFaction) || pawn.InSameExtraFaction((Pawn)item9.Thing, ExtraFactionType.MiniFaction))) { opts.Add(new FloatMenuOption("CannotArrest".Translate() + ": " + "SameFaction".Translate((Pawn)item9.Thing), null)); } else if (!pawn.CanReach(item9, PathEndMode.OnCell, Danger.Deadly)) { opts.Add(new FloatMenuOption("CannotArrest".Translate() + ": " + "NoPath".Translate().CapitalizeFirst(), null)); } else { Pawn pTarg2 = (Pawn)item9.Thing; Action action = delegate { Building_Bed building_Bed3 = RestUtility.FindBedFor(pTarg2, pawn, sleeperWillBePrisoner: true, checkSocialProperness: false); if (building_Bed3 == null) { building_Bed3 = RestUtility.FindBedFor(pTarg2, pawn, sleeperWillBePrisoner: true, checkSocialProperness: false, ignoreOtherReservations: true); } if (building_Bed3 == null) { Messages.Message("CannotArrest".Translate() + ": " + "NoPrisonerBed".Translate(), pTarg2, MessageTypeDefOf.RejectInput, historical: false); } else { Job job19 = JobMaker.MakeJob(JobDefOf.Arrest, pTarg2, building_Bed3); job19.count = 1; pawn.jobs.TryTakeOrderedJob(job19); if (pTarg2.Faction != null && ((pTarg2.Faction != Faction.OfPlayer && !pTarg2.Faction.Hidden) || pTarg2.IsQuestLodger())) { TutorUtility.DoModalDialogIfNotKnown(ConceptDefOf.ArrestingCreatesEnemies, pTarg2.GetAcceptArrestChance(pawn).ToStringPercent()); } } }; opts.Add(FloatMenuUtility.DecoratePrioritizedTask(new FloatMenuOption("TryToArrest".Translate(item9.Thing.LabelCap, item9.Thing, pTarg2.GetAcceptArrestChance(pawn).ToStringPercent()), action, MenuOptionPriority.High, null, item9.Thing), pawn, pTarg2)); } } } } foreach (Thing thing2 in c.GetThingList(pawn.Map)) { Thing t = thing2; if (t.def.ingestible != null && pawn.RaceProps.CanEverEat(t) && t.IngestibleNow) { string text = (!t.def.ingestible.ingestCommandString.NullOrEmpty()) ? string.Format(t.def.ingestible.ingestCommandString, t.LabelShort) : ((string)"ConsumeThing".Translate(t.LabelShort, t)); if (!t.IsSociallyProper(pawn)) { text = text + ": " + "ReservedForPrisoners".Translate().CapitalizeFirst(); } FloatMenuOption floatMenuOption; if (t.def.IsNonMedicalDrug && pawn.IsTeetotaler()) { floatMenuOption = new FloatMenuOption(text + ": " + TraitDefOf.DrugDesire.DataAtDegree(-1).GetLabelCapFor(pawn), null); } else if (FoodUtility.InappropriateForTitle(t.def, pawn, allowIfStarving: true)) { floatMenuOption = new FloatMenuOption(text + ": " + "FoodBelowTitleRequirements".Translate(pawn.royalty.MostSeniorTitle.def.GetLabelFor(pawn)), null); } else if (!pawn.CanReach(t, PathEndMode.OnCell, Danger.Deadly)) { floatMenuOption = new FloatMenuOption(text + ": " + "NoPath".Translate().CapitalizeFirst(), null); } else { MenuOptionPriority priority = (t is Corpse) ? MenuOptionPriority.Low : MenuOptionPriority.Default; int maxAmountToPickup = FoodUtility.GetMaxAmountToPickup(t, pawn, FoodUtility.WillIngestStackCountOf(pawn, t.def, t.GetStatValue(StatDefOf.Nutrition))); floatMenuOption = FloatMenuUtility.DecoratePrioritizedTask(new FloatMenuOption(text, delegate { int maxAmountToPickup2 = FoodUtility.GetMaxAmountToPickup(t, pawn, FoodUtility.WillIngestStackCountOf(pawn, t.def, t.GetStatValue(StatDefOf.Nutrition))); if (maxAmountToPickup2 != 0) { t.SetForbidden(value: false); Job job18 = JobMaker.MakeJob(JobDefOf.Ingest, t); job18.count = maxAmountToPickup2; pawn.jobs.TryTakeOrderedJob(job18); } }, priority), pawn, t); if (maxAmountToPickup == 0) { floatMenuOption.action = null; } } opts.Add(floatMenuOption); } } foreach (LocalTargetInfo item10 in GenUI.TargetsAt_NewTemp(clickPos, TargetingParameters.ForQuestPawnsWhoWillJoinColony(pawn), thingsOnly: true)) { Pawn toHelpPawn = (Pawn)item10.Thing; FloatMenuOption item4 = pawn.CanReach(item10, PathEndMode.Touch, Danger.Deadly) ? FloatMenuUtility.DecoratePrioritizedTask(new FloatMenuOption(toHelpPawn.IsPrisoner ? "FreePrisoner".Translate() : "OfferHelp".Translate(), delegate { pawn.jobs.TryTakeOrderedJob(JobMaker.MakeJob(JobDefOf.OfferHelp, toHelpPawn)); }, MenuOptionPriority.RescueOrCapture, null, toHelpPawn), pawn, toHelpPawn) : new FloatMenuOption("CannotGoNoPath".Translate(), null); opts.Add(item4); } if (pawn.health.capacities.CapableOf(PawnCapacityDefOf.Manipulation)) { foreach (Thing thing3 in c.GetThingList(pawn.Map)) { Corpse corpse = thing3 as Corpse; if (corpse != null && corpse.IsInValidStorage()) { StoragePriority priority2 = StoreUtility.CurrentHaulDestinationOf(corpse).GetStoreSettings().Priority; if (StoreUtility.TryFindBestBetterNonSlotGroupStorageFor(corpse, pawn, pawn.Map, priority2, Faction.OfPlayer, out IHaulDestination haulDestination, acceptSamePriority: true) && haulDestination.GetStoreSettings().Priority == priority2 && haulDestination is Building_Grave) { Building_Grave grave = haulDestination as Building_Grave; string label = "PrioritizeGeneric".Translate("Burying".Translate(), corpse.Label); opts.Add(FloatMenuUtility.DecoratePrioritizedTask(new FloatMenuOption(label, delegate { pawn.jobs.TryTakeOrderedJob(HaulAIUtility.HaulToContainerJob(pawn, corpse, grave)); }), pawn, new LocalTargetInfo(corpse))); } } } foreach (LocalTargetInfo item11 in GenUI.TargetsAt_NewTemp(clickPos, TargetingParameters.ForRescue(pawn), thingsOnly: true)) { Pawn victim3 = (Pawn)item11.Thing; if (!victim3.InBed() && pawn.CanReserveAndReach(victim3, PathEndMode.OnCell, Danger.Deadly, 1, -1, null, ignoreOtherReservations: true) && !victim3.mindState.WillJoinColonyIfRescued) { if (!victim3.IsPrisonerOfColony && (!victim3.InMentalState || victim3.health.hediffSet.HasHediff(HediffDefOf.Scaria)) && (victim3.Faction == Faction.OfPlayer || victim3.Faction == null || !victim3.Faction.HostileTo(Faction.OfPlayer))) { opts.Add(FloatMenuUtility.DecoratePrioritizedTask(new FloatMenuOption("Rescue".Translate(victim3.LabelCap, victim3), delegate { Building_Bed building_Bed2 = RestUtility.FindBedFor(victim3, pawn, sleeperWillBePrisoner: false, checkSocialProperness: false); if (building_Bed2 == null) { building_Bed2 = RestUtility.FindBedFor(victim3, pawn, sleeperWillBePrisoner: false, checkSocialProperness: false, ignoreOtherReservations: true); } if (building_Bed2 == null) { string t3 = (!victim3.RaceProps.Animal) ? ((string)"NoNonPrisonerBed".Translate()) : ((string)"NoAnimalBed".Translate()); Messages.Message("CannotRescue".Translate() + ": " + t3, victim3, MessageTypeDefOf.RejectInput, historical: false); } else { Job job17 = JobMaker.MakeJob(JobDefOf.Rescue, victim3, building_Bed2); job17.count = 1; pawn.jobs.TryTakeOrderedJob(job17); PlayerKnowledgeDatabase.KnowledgeDemonstrated(ConceptDefOf.Rescuing, KnowledgeAmount.Total); } }, MenuOptionPriority.RescueOrCapture, null, victim3), pawn, victim3)); } if (victim3.RaceProps.Humanlike && (victim3.InMentalState || victim3.Faction != Faction.OfPlayer || (victim3.Downed && (victim3.guilt.IsGuilty || victim3.IsPrisonerOfColony)))) { TaggedString taggedString = "Capture".Translate(victim3.LabelCap, victim3); if (victim3.Faction != null && victim3.Faction != Faction.OfPlayer && !victim3.Faction.Hidden && !victim3.Faction.HostileTo(Faction.OfPlayer) && !victim3.IsPrisonerOfColony) { taggedString += ": " + "AngersFaction".Translate().CapitalizeFirst(); } opts.Add(FloatMenuUtility.DecoratePrioritizedTask(new FloatMenuOption(taggedString, delegate { Building_Bed building_Bed = RestUtility.FindBedFor(victim3, pawn, sleeperWillBePrisoner: true, checkSocialProperness: false); if (building_Bed == null) { building_Bed = RestUtility.FindBedFor(victim3, pawn, sleeperWillBePrisoner: true, checkSocialProperness: false, ignoreOtherReservations: true); } if (building_Bed == null) { Messages.Message("CannotCapture".Translate() + ": " + "NoPrisonerBed".Translate(), victim3, MessageTypeDefOf.RejectInput, historical: false); } else { Job job16 = JobMaker.MakeJob(JobDefOf.Capture, victim3, building_Bed); job16.count = 1; pawn.jobs.TryTakeOrderedJob(job16); PlayerKnowledgeDatabase.KnowledgeDemonstrated(ConceptDefOf.Capturing, KnowledgeAmount.Total); if (victim3.Faction != null && victim3.Faction != Faction.OfPlayer && !victim3.Faction.Hidden && !victim3.Faction.HostileTo(Faction.OfPlayer) && !victim3.IsPrisonerOfColony) { Messages.Message("MessageCapturingWillAngerFaction".Translate(victim3.Named("PAWN")).AdjustedFor(victim3), victim3, MessageTypeDefOf.CautionInput, historical: false); } } }, MenuOptionPriority.RescueOrCapture, null, victim3), pawn, victim3)); } } } foreach (LocalTargetInfo item12 in GenUI.TargetsAt_NewTemp(clickPos, TargetingParameters.ForRescue(pawn), thingsOnly: true)) { LocalTargetInfo localTargetInfo = item12; Pawn victim2 = (Pawn)localTargetInfo.Thing; if (victim2.Downed && pawn.CanReserveAndReach(victim2, PathEndMode.OnCell, Danger.Deadly, 1, -1, null, ignoreOtherReservations: true) && Building_CryptosleepCasket.FindCryptosleepCasketFor(victim2, pawn, ignoreOtherReservations: true) != null) { string text2 = "CarryToCryptosleepCasket".Translate(localTargetInfo.Thing.LabelCap, localTargetInfo.Thing); JobDef jDef = JobDefOf.CarryToCryptosleepCasket; Action action2 = delegate { Building_CryptosleepCasket building_CryptosleepCasket = Building_CryptosleepCasket.FindCryptosleepCasketFor(victim2, pawn); if (building_CryptosleepCasket == null) { building_CryptosleepCasket = Building_CryptosleepCasket.FindCryptosleepCasketFor(victim2, pawn, ignoreOtherReservations: true); } if (building_CryptosleepCasket == null) { Messages.Message("CannotCarryToCryptosleepCasket".Translate() + ": " + "NoCryptosleepCasket".Translate(), victim2, MessageTypeDefOf.RejectInput, historical: false); } else { Job job15 = JobMaker.MakeJob(jDef, victim2, building_CryptosleepCasket); job15.count = 1; pawn.jobs.TryTakeOrderedJob(job15); } }; if (victim2.IsQuestLodger()) { text2 += " (" + "CryptosleepCasketGuestsNotAllowed".Translate() + ")"; opts.Add(FloatMenuUtility.DecoratePrioritizedTask(new FloatMenuOption(text2, null, MenuOptionPriority.Default, null, victim2), pawn, victim2)); } else if (victim2.GetExtraHostFaction() != null) { text2 += " (" + "CryptosleepCasketGuestPrisonersNotAllowed".Translate() + ")"; opts.Add(FloatMenuUtility.DecoratePrioritizedTask(new FloatMenuOption(text2, null, MenuOptionPriority.Default, null, victim2), pawn, victim2)); } else { opts.Add(FloatMenuUtility.DecoratePrioritizedTask(new FloatMenuOption(text2, action2, MenuOptionPriority.Default, null, victim2), pawn, victim2)); } } } if (ModsConfig.RoyaltyActive) { foreach (LocalTargetInfo item13 in GenUI.TargetsAt_NewTemp(clickPos, TargetingParameters.ForShuttle(pawn), thingsOnly: true)) { LocalTargetInfo localTargetInfo2 = item13; Pawn victim = (Pawn)localTargetInfo2.Thing; Predicate <Thing> validator = (Thing thing) => thing.TryGetComp <CompShuttle>()?.IsAllowedNow(victim) ?? false; Thing shuttleThing = GenClosest.ClosestThingReachable(victim.Position, victim.Map, ThingRequest.ForDef(ThingDefOf.Shuttle), PathEndMode.ClosestTouch, TraverseParms.For(pawn), 9999f, validator); if (shuttleThing != null && pawn.CanReserveAndReach(victim, PathEndMode.OnCell, Danger.Deadly, 1, -1, null, ignoreOtherReservations: true) && !pawn.WorkTypeIsDisabled(WorkTypeDefOf.Hauling)) { string label2 = "CarryToShuttle".Translate(localTargetInfo2.Thing); Action action3 = delegate { CompShuttle compShuttle = shuttleThing.TryGetComp <CompShuttle>(); if (!compShuttle.LoadingInProgressOrReadyToLaunch) { TransporterUtility.InitiateLoading(Gen.YieldSingle(compShuttle.Transporter)); } Job job14 = JobMaker.MakeJob(JobDefOf.HaulToTransporter, victim, shuttleThing); job14.ignoreForbidden = true; job14.count = 1; pawn.jobs.TryTakeOrderedJob(job14); }; opts.Add(FloatMenuUtility.DecoratePrioritizedTask(new FloatMenuOption(label2, action3), pawn, victim)); } } } } foreach (LocalTargetInfo item14 in GenUI.TargetsAt_NewTemp(clickPos, TargetingParameters.ForStrip(pawn), thingsOnly: true)) { LocalTargetInfo stripTarg = item14; FloatMenuOption item5 = pawn.CanReach(stripTarg, PathEndMode.ClosestTouch, Danger.Deadly) ? ((stripTarg.Pawn == null || !stripTarg.Pawn.HasExtraHomeFaction()) ? FloatMenuUtility.DecoratePrioritizedTask(new FloatMenuOption("Strip".Translate(stripTarg.Thing.LabelCap, stripTarg.Thing), delegate { stripTarg.Thing.SetForbidden(value: false, warnOnFail: false); pawn.jobs.TryTakeOrderedJob(JobMaker.MakeJob(JobDefOf.Strip, stripTarg)); StrippableUtility.CheckSendStrippingImpactsGoodwillMessage(stripTarg.Thing); }), pawn, stripTarg) : new FloatMenuOption("CannotStrip".Translate(stripTarg.Thing.LabelCap, stripTarg.Thing) + ": " + "QuestRelated".Translate().CapitalizeFirst(), null)) : new FloatMenuOption("CannotStrip".Translate(stripTarg.Thing.LabelCap, stripTarg.Thing) + ": " + "NoPath".Translate().CapitalizeFirst(), null); opts.Add(item5); } ThingWithComps equipment; if (pawn.equipment != null) { 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 item6; string cantReason; if (equipment.def.IsWeapon && pawn.WorkTagIsDisabled(WorkTags.Violent)) { item6 = new FloatMenuOption("CannotEquip".Translate(labelShort) + ": " + "IsIncapableOfViolenceLower".Translate(pawn.LabelShort, pawn), null); } else if (!pawn.CanReach(equipment, PathEndMode.ClosestTouch, Danger.Deadly)) { item6 = new FloatMenuOption("CannotEquip".Translate(labelShort) + ": " + "NoPath".Translate().CapitalizeFirst(), null); } else if (!pawn.health.capacities.CapableOf(PawnCapacityDefOf.Manipulation)) { item6 = new FloatMenuOption("CannotEquip".Translate(labelShort) + ": " + "Incapable".Translate(), null); } else if (equipment.IsBurning()) { item6 = new FloatMenuOption("CannotEquip".Translate(labelShort) + ": " + "BurningLower".Translate(), null); } else if (pawn.IsQuestLodger() && !EquipmentUtility.QuestLodgerCanEquip(equipment, pawn)) { item6 = new FloatMenuOption("CannotEquip".Translate(labelShort) + ": " + "QuestRelated".Translate().CapitalizeFirst(), null); } else if (!EquipmentUtility.CanEquip_NewTmp(equipment, pawn, out cantReason, checkBonded: false)) { item6 = new FloatMenuOption("CannotEquip".Translate(labelShort) + ": " + cantReason.CapitalizeFirst(), null); } else { string text3 = "Equip".Translate(labelShort); if (equipment.def.IsRangedWeapon && pawn.story != null && pawn.story.traits.HasTrait(TraitDefOf.Brawler)) { text3 += " " + "EquipWarningBrawler".Translate(); } if (EquipmentUtility.AlreadyBondedToWeapon(equipment, pawn)) { text3 += " " + "BladelinkAlreadyBonded".Translate(); TaggedString dialogText = "BladelinkAlreadyBondedDialog".Translate(pawn.Named("PAWN"), equipment.Named("WEAPON"), pawn.equipment.bondedWeapon.Named("BONDEDWEAPON")); item6 = FloatMenuUtility.DecoratePrioritizedTask(new FloatMenuOption(text3, delegate { Find.WindowStack.Add(new Dialog_MessageBox(dialogText)); }, MenuOptionPriority.High), pawn, equipment); } else { item6 = FloatMenuUtility.DecoratePrioritizedTask(new FloatMenuOption(text3, delegate { string personaWeaponConfirmationText = EquipmentUtility.GetPersonaWeaponConfirmationText(equipment, pawn); if (!personaWeaponConfirmationText.NullOrEmpty()) { Find.WindowStack.Add(new Dialog_MessageBox(personaWeaponConfirmationText, "Yes".Translate(), delegate { Equip(); }, "No".Translate())); } else { Equip(); } }, MenuOptionPriority.High), pawn, equipment); } } opts.Add(item6); } } foreach (Pair <CompReloadable, Thing> item15 in ReloadableUtility.FindPotentiallyReloadableGear(pawn, c.GetThingList(pawn.Map))) { CompReloadable comp = item15.First; Thing second = item15.Second; string text4 = "Reload".Translate(comp.parent.Named("GEAR"), NamedArgumentUtility.Named(comp.AmmoDef, "AMMO")) + " (" + comp.LabelRemaining + ")"; List <Thing> chosenAmmo; if (!pawn.CanReach(second, PathEndMode.ClosestTouch, Danger.Deadly)) { opts.Add(new FloatMenuOption(text4 + ": " + "NoPath".Translate().CapitalizeFirst(), null)); } else if (!comp.NeedsReload(allowForcedReload: true)) { opts.Add(new FloatMenuOption(text4 + ": " + "ReloadFull".Translate(), null)); } else if ((chosenAmmo = ReloadableUtility.FindEnoughAmmo(pawn, second.Position, comp, forceReload: true)) == null) { opts.Add(new FloatMenuOption(text4 + ": " + "ReloadNotEnough".Translate(), null)); } else { Action action4 = delegate { pawn.jobs.TryTakeOrderedJob(JobGiver_Reload.MakeReloadJob(comp, chosenAmmo)); }; opts.Add(FloatMenuUtility.DecoratePrioritizedTask(new FloatMenuOption(text4, action4), pawn, second)); } } if (pawn.apparel != null) { if (pawn.Map.thingGrid.ThingAt(c, ThingCategory.Item) is Apparel apparel) { string key = "CannotWear"; string key2 = "ForceWear"; if (apparel.def.apparel.LastLayer.IsUtilityLayer) { key = "CannotEquipApparel"; key2 = "ForceEquipApparel"; } string cantReason2; FloatMenuOption item7 = (!pawn.CanReach(apparel, PathEndMode.ClosestTouch, Danger.Deadly)) ? new FloatMenuOption(key.Translate(apparel.Label, apparel) + ": " + "NoPath".Translate().CapitalizeFirst(), null) : (apparel.IsBurning() ? new FloatMenuOption(key.Translate(apparel.Label, apparel) + ": " + "Burning".Translate(), null) : (pawn.apparel.WouldReplaceLockedApparel(apparel) ? new FloatMenuOption(key.Translate(apparel.Label, apparel) + ": " + "WouldReplaceLockedApparel".Translate().CapitalizeFirst(), null) : ((!ApparelUtility.HasPartsToWear(pawn, apparel.def)) ? new FloatMenuOption(key.Translate(apparel.Label, apparel) + ": " + "CannotWearBecauseOfMissingBodyParts".Translate(), null) : (EquipmentUtility.CanEquip_NewTmp(apparel, pawn, out cantReason2) ? FloatMenuUtility.DecoratePrioritizedTask(new FloatMenuOption(key2.Translate(apparel.LabelShort, apparel), delegate { apparel.SetForbidden(value: false); Job job13 = JobMaker.MakeJob(JobDefOf.Wear, apparel); pawn.jobs.TryTakeOrderedJob(job13); }, MenuOptionPriority.High), pawn, apparel) : new FloatMenuOption(key.Translate(apparel.Label, apparel) + ": " + cantReason2, null))))); opts.Add(item7); } } if (pawn.IsFormingCaravan()) { Thing item3 = c.GetFirstItem(pawn.Map); if (item3 != null && item3.def.EverHaulable && item3.def.canLoadIntoCaravan) { Pawn packTarget = GiveToPackAnimalUtility.UsablePackAnimalWithTheMostFreeSpace(pawn) ?? pawn; JobDef jobDef = (packTarget == pawn) ? JobDefOf.TakeInventory : JobDefOf.GiveToPackAnimal; if (!pawn.CanReach(item3, PathEndMode.ClosestTouch, Danger.Deadly)) { opts.Add(new FloatMenuOption("CannotLoadIntoCaravan".Translate(item3.Label, item3) + ": " + "NoPath".Translate().CapitalizeFirst(), null)); } else if (MassUtility.WillBeOverEncumberedAfterPickingUp(packTarget, item3, 1)) { opts.Add(new FloatMenuOption("CannotLoadIntoCaravan".Translate(item3.Label, item3) + ": " + "TooHeavy".Translate(), null)); } else { LordJob_FormAndSendCaravan lordJob = (LordJob_FormAndSendCaravan)pawn.GetLord().LordJob; float capacityLeft = CaravanFormingUtility.CapacityLeft(lordJob); if (item3.stackCount == 1) { float capacityLeft2 = capacityLeft - item3.GetStatValue(StatDefOf.Mass); opts.Add(FloatMenuUtility.DecoratePrioritizedTask(new FloatMenuOption(CaravanFormingUtility.AppendOverweightInfo("LoadIntoCaravan".Translate(item3.Label, item3), capacityLeft2), delegate { item3.SetForbidden(value: false, warnOnFail: false); Job job12 = JobMaker.MakeJob(jobDef, item3); job12.count = 1; job12.checkEncumbrance = (packTarget == pawn); pawn.jobs.TryTakeOrderedJob(job12); }, MenuOptionPriority.High), pawn, item3)); } else { if (MassUtility.WillBeOverEncumberedAfterPickingUp(packTarget, item3, item3.stackCount)) { opts.Add(new FloatMenuOption("CannotLoadIntoCaravanAll".Translate(item3.Label, item3) + ": " + "TooHeavy".Translate(), null)); } else { float capacityLeft3 = capacityLeft - (float)item3.stackCount * item3.GetStatValue(StatDefOf.Mass); opts.Add(FloatMenuUtility.DecoratePrioritizedTask(new FloatMenuOption(CaravanFormingUtility.AppendOverweightInfo("LoadIntoCaravanAll".Translate(item3.Label, item3), capacityLeft3), delegate { item3.SetForbidden(value: false, warnOnFail: false); Job job11 = JobMaker.MakeJob(jobDef, item3); job11.count = item3.stackCount; job11.checkEncumbrance = (packTarget == pawn); pawn.jobs.TryTakeOrderedJob(job11); }, MenuOptionPriority.High), pawn, item3)); } opts.Add(FloatMenuUtility.DecoratePrioritizedTask(new FloatMenuOption("LoadIntoCaravanSome".Translate(item3.LabelNoCount, item3), delegate { int to3 = Mathf.Min(MassUtility.CountToPickUpUntilOverEncumbered(packTarget, item3), item3.stackCount); Dialog_Slider window3 = new Dialog_Slider(delegate(int val) { float capacityLeft4 = capacityLeft - (float)val * item3.GetStatValue(StatDefOf.Mass); return(CaravanFormingUtility.AppendOverweightInfo(string.Format("LoadIntoCaravanCount".Translate(item3.LabelNoCount, item3), val), capacityLeft4)); }, 1, to3, delegate(int count) { item3.SetForbidden(value: false, warnOnFail: false); Job job10 = JobMaker.MakeJob(jobDef, item3); job10.count = count; job10.checkEncumbrance = (packTarget == pawn); pawn.jobs.TryTakeOrderedJob(job10); }); Find.WindowStack.Add(window3); }, MenuOptionPriority.High), pawn, item3)); } } } } if (!pawn.Map.IsPlayerHome && !pawn.IsFormingCaravan()) { Thing item2 = c.GetFirstItem(pawn.Map); if (item2 != null && item2.def.EverHaulable) { if (!pawn.CanReach(item2, PathEndMode.ClosestTouch, Danger.Deadly)) { opts.Add(new FloatMenuOption("CannotPickUp".Translate(item2.Label, item2) + ": " + "NoPath".Translate().CapitalizeFirst(), null)); } else if (MassUtility.WillBeOverEncumberedAfterPickingUp(pawn, item2, 1)) { opts.Add(new FloatMenuOption("CannotPickUp".Translate(item2.Label, item2) + ": " + "TooHeavy".Translate(), null)); } else if (item2.stackCount == 1) { opts.Add(FloatMenuUtility.DecoratePrioritizedTask(new FloatMenuOption("PickUp".Translate(item2.Label, item2), delegate { item2.SetForbidden(value: false, warnOnFail: false); Job job9 = JobMaker.MakeJob(JobDefOf.TakeInventory, item2); job9.count = 1; job9.checkEncumbrance = true; pawn.jobs.TryTakeOrderedJob(job9); }, MenuOptionPriority.High), pawn, item2)); } else { if (MassUtility.WillBeOverEncumberedAfterPickingUp(pawn, item2, item2.stackCount)) { opts.Add(new FloatMenuOption("CannotPickUpAll".Translate(item2.Label, item2) + ": " + "TooHeavy".Translate(), null)); } else { opts.Add(FloatMenuUtility.DecoratePrioritizedTask(new FloatMenuOption("PickUpAll".Translate(item2.Label, item2), delegate { item2.SetForbidden(value: false, warnOnFail: false); Job job8 = JobMaker.MakeJob(JobDefOf.TakeInventory, item2); job8.count = item2.stackCount; job8.checkEncumbrance = true; pawn.jobs.TryTakeOrderedJob(job8); }, MenuOptionPriority.High), pawn, item2)); } opts.Add(FloatMenuUtility.DecoratePrioritizedTask(new FloatMenuOption("PickUpSome".Translate(item2.LabelNoCount, item2), delegate { int to2 = Mathf.Min(MassUtility.CountToPickUpUntilOverEncumbered(pawn, item2), item2.stackCount); Dialog_Slider window2 = new Dialog_Slider("PickUpCount".Translate(item2.LabelNoCount, item2), 1, to2, delegate(int count) { item2.SetForbidden(value: false, warnOnFail: false); Job job7 = JobMaker.MakeJob(JobDefOf.TakeInventory, item2); job7.count = count; job7.checkEncumbrance = true; pawn.jobs.TryTakeOrderedJob(job7); }); Find.WindowStack.Add(window2); }, MenuOptionPriority.High), pawn, item2)); } } } if (!pawn.Map.IsPlayerHome && !pawn.IsFormingCaravan()) { Thing item = c.GetFirstItem(pawn.Map); if (item != null && item.def.EverHaulable) { Pawn bestPackAnimal = GiveToPackAnimalUtility.UsablePackAnimalWithTheMostFreeSpace(pawn); if (bestPackAnimal != null) { if (!pawn.CanReach(item, PathEndMode.ClosestTouch, Danger.Deadly)) { opts.Add(new FloatMenuOption("CannotGiveToPackAnimal".Translate(item.Label, item) + ": " + "NoPath".Translate().CapitalizeFirst(), null)); } else if (MassUtility.WillBeOverEncumberedAfterPickingUp(bestPackAnimal, item, 1)) { opts.Add(new FloatMenuOption("CannotGiveToPackAnimal".Translate(item.Label, item) + ": " + "TooHeavy".Translate(), null)); } else if (item.stackCount == 1) { opts.Add(FloatMenuUtility.DecoratePrioritizedTask(new FloatMenuOption("GiveToPackAnimal".Translate(item.Label, item), delegate { item.SetForbidden(value: false, warnOnFail: false); Job job6 = JobMaker.MakeJob(JobDefOf.GiveToPackAnimal, item); job6.count = 1; pawn.jobs.TryTakeOrderedJob(job6); }, MenuOptionPriority.High), pawn, item)); } else { if (MassUtility.WillBeOverEncumberedAfterPickingUp(bestPackAnimal, item, item.stackCount)) { opts.Add(new FloatMenuOption("CannotGiveToPackAnimalAll".Translate(item.Label, item) + ": " + "TooHeavy".Translate(), null)); } else { opts.Add(FloatMenuUtility.DecoratePrioritizedTask(new FloatMenuOption("GiveToPackAnimalAll".Translate(item.Label, item), delegate { item.SetForbidden(value: false, warnOnFail: false); Job job5 = JobMaker.MakeJob(JobDefOf.GiveToPackAnimal, item); job5.count = item.stackCount; pawn.jobs.TryTakeOrderedJob(job5); }, MenuOptionPriority.High), pawn, item)); } opts.Add(FloatMenuUtility.DecoratePrioritizedTask(new FloatMenuOption("GiveToPackAnimalSome".Translate(item.LabelNoCount, item), delegate { int to = Mathf.Min(MassUtility.CountToPickUpUntilOverEncumbered(bestPackAnimal, item), item.stackCount); Dialog_Slider window = new Dialog_Slider("GiveToPackAnimalCount".Translate(item.LabelNoCount, item), 1, to, delegate(int count) { item.SetForbidden(value: false, warnOnFail: false); Job job4 = JobMaker.MakeJob(JobDefOf.GiveToPackAnimal, item); job4.count = count; pawn.jobs.TryTakeOrderedJob(job4); }); Find.WindowStack.Add(window); }, MenuOptionPriority.High), pawn, item)); } } } } if (!pawn.Map.IsPlayerHome && pawn.Map.exitMapGrid.MapUsesExitGrid) { foreach (LocalTargetInfo item16 in GenUI.TargetsAt_NewTemp(clickPos, TargetingParameters.ForRescue(pawn), thingsOnly: true)) { Pawn p = (Pawn)item16.Thing; if (p.Faction == Faction.OfPlayer || p.IsPrisonerOfColony || CaravanUtility.ShouldAutoCapture(p, Faction.OfPlayer)) { IntVec3 exitSpot; if (!pawn.CanReach(p, PathEndMode.ClosestTouch, Danger.Deadly)) { opts.Add(new FloatMenuOption("CannotCarryToExit".Translate(p.Label, p) + ": " + "NoPath".Translate().CapitalizeFirst(), null)); } else if (!RCellFinder.TryFindBestExitSpot(pawn, out exitSpot)) { opts.Add(new FloatMenuOption("CannotCarryToExit".Translate(p.Label, p) + ": " + "NoPath".Translate().CapitalizeFirst(), null)); } else { TaggedString taggedString2 = (p.Faction == Faction.OfPlayer || p.IsPrisonerOfColony) ? "CarryToExit".Translate(p.Label, p) : "CarryToExitAndCapture".Translate(p.Label, p); opts.Add(FloatMenuUtility.DecoratePrioritizedTask(new FloatMenuOption(taggedString2, delegate { Job job3 = JobMaker.MakeJob(JobDefOf.CarryDownedPawnToExit, p, exitSpot); job3.count = 1; job3.failIfCantJoinOrCreateCaravan = true; pawn.jobs.TryTakeOrderedJob(job3); }, MenuOptionPriority.High), pawn, item16)); } } } } if (pawn.equipment != null && pawn.equipment.Primary != null && GenUI.TargetsAt_NewTemp(clickPos, TargetingParameters.ForSelf(pawn), thingsOnly: true).Any()) { if (pawn.IsQuestLodger() && !EquipmentUtility.QuestLodgerCanUnequip(pawn.equipment.Primary, pawn)) { opts.Add(new FloatMenuOption("CannotDrop".Translate(pawn.equipment.Primary.Label, pawn.equipment.Primary) + ": " + "QuestRelated".Translate().CapitalizeFirst(), null)); } else { Action action5 = delegate { pawn.jobs.TryTakeOrderedJob(JobMaker.MakeJob(JobDefOf.DropEquipment, pawn.equipment.Primary)); }; opts.Add(new FloatMenuOption("Drop".Translate(pawn.equipment.Primary.Label, pawn.equipment.Primary), action5, MenuOptionPriority.Default, null, pawn)); } } foreach (LocalTargetInfo item17 in GenUI.TargetsAt_NewTemp(clickPos, TargetingParameters.ForTrade(), thingsOnly: true)) { if (!pawn.CanReach(item17, PathEndMode.OnCell, Danger.Deadly)) { opts.Add(new FloatMenuOption("CannotTrade".Translate() + ": " + "NoPath".Translate().CapitalizeFirst(), null)); } else if (pawn.skills.GetSkill(SkillDefOf.Social).TotallyDisabled) { opts.Add(new FloatMenuOption("CannotPrioritizeWorkTypeDisabled".Translate(SkillDefOf.Social.LabelCap), null)); } else if (!pawn.CanTradeWith(((Pawn)item17.Thing).Faction, ((Pawn)item17.Thing).TraderKind)) { opts.Add(new FloatMenuOption("CannotTradeMissingTitleAbility".Translate(), null)); } else { Pawn pTarg = (Pawn)item17.Thing; Action action6 = delegate { Job job2 = JobMaker.MakeJob(JobDefOf.TradeWithPawn, pTarg); job2.playerForced = true; pawn.jobs.TryTakeOrderedJob(job2); PlayerKnowledgeDatabase.KnowledgeDemonstrated(ConceptDefOf.InteractingWithTraders, KnowledgeAmount.Total); }; string t2 = ""; if (pTarg.Faction != null) { t2 = " (" + pTarg.Faction.Name + ")"; } opts.Add(FloatMenuUtility.DecoratePrioritizedTask(new FloatMenuOption("TradeWith".Translate(pTarg.LabelShort + ", " + pTarg.TraderKind.label) + t2, action6, MenuOptionPriority.InitiateSocial, null, item17.Thing), pawn, pTarg)); } } foreach (LocalTargetInfo casket in GenUI.TargetsAt_NewTemp(clickPos, TargetingParameters.ForOpen(pawn), thingsOnly: true)) { if (!pawn.CanReach(casket, PathEndMode.OnCell, Danger.Deadly)) { opts.Add(new FloatMenuOption("CannotOpen".Translate(casket.Thing) + ": " + "NoPath".Translate().CapitalizeFirst(), null)); } else if (!pawn.health.capacities.CapableOf(PawnCapacityDefOf.Manipulation)) { opts.Add(new FloatMenuOption("CannotOpen".Translate(casket.Thing) + ": " + "Incapable".Translate(), null)); } else if (casket.Thing.Map.designationManager.DesignationOn(casket.Thing, DesignationDefOf.Open) == null) { opts.Add(FloatMenuUtility.DecoratePrioritizedTask(new FloatMenuOption("Open".Translate(casket.Thing), delegate { Job job = JobMaker.MakeJob(JobDefOf.Open, casket.Thing); job.ignoreDesignations = true; pawn.jobs.TryTakeOrderedJob(job); }, MenuOptionPriority.High), pawn, casket.Thing)); } } foreach (Thing item18 in pawn.Map.thingGrid.ThingsAt(c)) { foreach (FloatMenuOption floatMenuOption2 in item18.GetFloatMenuOptions(pawn)) { opts.Add(floatMenuOption2); } } void Equip() { equipment.SetForbidden(value: false); pawn.jobs.TryTakeOrderedJob(JobMaker.MakeJob(JobDefOf.Equip, equipment)); MoteMaker.MakeStaticMote(equipment.DrawPos, equipment.Map, ThingDefOf.Mote_FeedbackEquip); PlayerKnowledgeDatabase.KnowledgeDemonstrated(ConceptDefOf.EquippingWeapons, KnowledgeAmount.Total); } return(false); }
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) { object comp = SelPawnForGear.getCompInventory(); CompBiocodable compBiocodable = eq.TryGetComp <CompBiocodable>(); bool flag11 = comp != 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() { CEAccess.trySwitchToWeapon(comp, 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); }
protected override (bool success, Vector3 launchPos, float angle) TryCastShotInternal() { IntVec3 exitTarget = caster.Position.CellFromDistAngle(Building_Artillery.MaxMapDistance, heading); if (!target.HasWorldObject && !target.HasThing) { return(false, Vector3.zero, 0); } ThingDef projectile = Projectile; if (projectile is null) { return(false, Vector3.zero, 0); } bool flag = TryFindShootLineFromTo(caster.Position, exitTarget, out ShootLine shootLine); if (verbProps.stopBurstWithoutLos && !flag) { return(false, Vector3.zero, 0); } if (EquipmentSource != null) { CompChangeableProjectile comp = EquipmentSource.GetComp <CompChangeableProjectile>(); if (comp != null) { comp.Notify_ProjectileLaunched(); } CompReloadable comp2 = EquipmentSource.GetComp <CompReloadable>(); if (comp2 != null) { comp2.UsedOnce(); } } Thing launcher = caster; Thing equipment = EquipmentSource; CompMannable compMannable = caster.TryGetComp <CompMannable>(); if (compMannable != null && compMannable.ManningPawn != null) { launcher = compMannable.ManningPawn; equipment = caster; } Vector3 launchPos = caster.DrawPos; Projectile projectile2 = (Projectile)GenSpawn.Spawn(projectile, caster.Position, caster.Map, WipeMode.Vanish); if (projectile2.AllComps.NullOrEmpty()) { AccessTools.Field(typeof(ThingWithComps), "comps").SetValue(projectile2, new List <ThingComp>()); } projectile2.AllComps.Add(new CompProjectileExitMap(CasterTWC) { airDefenseDef = AntiAircraftDefOf.FlakProjectile, target = target.WorldObject as AerialVehicleInFlight, spawnPos = Building_Artillery.RandomWorldPosition(caster.Map.Tile, 1).FirstOrDefault() }); if (caster.def.GetModExtension <ProjectilePropertiesDefModExtension>() is ProjectilePropertiesDefModExtension projectileProps) { projectile2.AllComps.Add(new CompTurretProjectileProperties(CasterTWC) { speed = projectileProps.speed > 0 ? projectileProps.speed : projectile2.def.projectile.speed, hitflag = ProjectileHitFlags.IntendedTarget, hitflags = null }); } ThrowDebugText("ToHit" + (canHitNonTargetPawnsNow ? "\nchntp" : "")); launchPos += new Vector3(VerbProps.shootOffset.x, 0, VerbProps.shootOffset.y).RotatedBy(heading); projectile2.Launch(launcher, launchPos, exitTarget, exitTarget, ProjectileHitFlags.IntendedTarget, equipment); ThrowDebugText("Hit\nDest", shootLine.Dest); return(true, launchPos, heading); }
/// <summary> /// Fires a projectile using the new aiming system /// </summary> /// <returns>True for successful shot, false otherwise</returns> public override bool TryCastShot() { if (!TryFindCEShootLineFromTo(caster.Position, currentTarget, out var shootLine)) { return(false); } if (projectilePropsCE.pelletCount < 1) { Log.Error(EquipmentSource.LabelCap + " tried firing with pelletCount less than 1."); return(false); } bool instant = false; float spreadDegrees = 0; float aperatureSize = 0; if (Projectile.projectile is ProjectilePropertiesCE pprop) { instant = pprop.isInstant; spreadDegrees = (EquipmentSource?.GetStatValue(StatDef.Named("ShotSpread")) ?? 0) * pprop.spreadMult; aperatureSize = 0.03f; } ShiftVecReport report = ShiftVecReportFor(currentTarget); bool pelletMechanicsOnly = false; for (int i = 0; i < projectilePropsCE.pelletCount; i++) { ProjectileCE projectile = (ProjectileCE)ThingMaker.MakeThing(Projectile, null); GenSpawn.Spawn(projectile, shootLine.Source, caster.Map); ShiftTarget(report, pelletMechanicsOnly, instant); //New aiming algorithm projectile.canTargetSelf = false; var targetDistance = (sourceLoc - currentTarget.Cell.ToIntVec2.ToVector2Shifted()).magnitude; projectile.minCollisionDistance = GetMinCollisionDistance(targetDistance); projectile.intendedTarget = currentTarget; projectile.mount = caster.Position.GetThingList(caster.Map).FirstOrDefault(t => t is Pawn && t != caster); projectile.AccuracyFactor = report.accuracyFactor * report.swayDegrees * ((numShotsFired + 1) * 0.75f); if (instant) { var shotHeight = ShotHeight; float tsa = AdjustShotHeight(caster, currentTarget, ref shotHeight); projectile.RayCast( Shooter, verbProps, sourceLoc, shotAngle + tsa, shotRotation, shotHeight, ShotSpeed, spreadDegrees, aperatureSize, EquipmentSource); } else { projectile.Launch( Shooter, //Shooter instead of caster to give turret operators' records the damage/kills obtained sourceLoc, shotAngle, shotRotation, ShotHeight, ShotSpeed, EquipmentSource); } pelletMechanicsOnly = true; } /* * Notify the lighting tracker that shots fired with muzzle flash value of VerbPropsCE.muzzleFlashScale */ LightingTracker.Notify_ShotsFiredAt(caster.Position, intensity: VerbPropsCE.muzzleFlashScale); pelletMechanicsOnly = false; numShotsFired++; if (CompAmmo != null && !CompAmmo.CanBeFiredNow) { CompAmmo?.TryStartReload(); } if (CompReloadable != null) { CompReloadable.UsedOnce(); } return(true); }
//[HarmonyPrefix] static bool Prefix(ref bool __result, Verb_LaunchProjectile __instance, LocalTargetInfo ___currentTarget) { if (__instance.verbProps.forcedMissRadius < 0.5f || __instance.verbProps.requireLineOfSight) { // Assuming this is not a mortar-like thing // Perform vanilla logic return(true); } else { // Perform the same vanilla checks if (___currentTarget.HasThing && ___currentTarget.Thing.Map != __instance.caster.Map) { __result = false; return(false); } ThingDef projectile = __instance.Projectile; if (projectile == null) { __result = false; return(false); } ShootLine shootLine = default(ShootLine); bool flag = __instance.TryFindShootLineFromTo(__instance.caster.Position, ___currentTarget, out shootLine); if (__instance.verbProps.stopBurstWithoutLos && !flag) { __result = false; return(false); } // Vanilla checks pass, we can shoot if (__instance.EquipmentSource != null) { CompChangeableProjectile comp = __instance.EquipmentSource.GetComp <CompChangeableProjectile>(); if (comp != null) { comp.Notify_ProjectileLaunched(); } CompReloadable comp2 = __instance.EquipmentSource.GetComp <CompReloadable>(); if (comp2 != null) { comp2.UsedOnce(); } } Thing launcher = __instance.caster; Thing equipment = __instance.EquipmentSource; CompMannable compMannable = __instance.caster.TryGetComp <CompMannable>(); if (compMannable != null && compMannable.ManningPawn != null) { launcher = compMannable.ManningPawn; equipment = __instance.caster; // Earn skills if (compMannable.ManningPawn.skills != null) { int skillsAffectingAccuracy = 0; if (Settings.intellectualAffectsMortarAccuracy) { skillsAffectingAccuracy++; } if (Settings.shootingAffectsMortarAccuracy) { skillsAffectingAccuracy++; } float skillXP = __instance.verbProps.AdjustedFullCycleTime(__instance, __instance.CasterPawn) * 100; skillXP = Mathf.Clamp(skillXP, 0, 200); skillXP /= skillsAffectingAccuracy; if (Settings.intellectualAffectsMortarAccuracy) { compMannable.ManningPawn.skills.Learn(SkillDefOf.Intellectual, skillXP, false); } if (Settings.shootingAffectsMortarAccuracy) { compMannable.ManningPawn.skills.Learn(SkillDefOf.Shooting, skillXP, false); } } } Vector3 drawPos = __instance.caster.DrawPos; Projectile projectile2 = (Projectile)GenSpawn.Spawn(projectile, shootLine.Source, __instance.caster.Map, WipeMode.Vanish); // If targetting a pawn if (Settings.targetLeading) { if (___currentTarget != null && ___currentTarget.Thing != null && ___currentTarget.Thing is Pawn targetPawn && targetPawn.pather.curPath != null) { List <IntVec3> nodes = new List <IntVec3>(targetPawn.pather.curPath.NodesReversed); nodes.Reverse(); // Purge outdated nodes from list for (int i = 0; i < nodes.Count; i++) { if (nodes[i] == targetPawn.Position) { // Remove all previous nodes nodes.RemoveRange(0, i); //Log.Message("Removed " + i + " entries. First node is now " + nodes[0].ToString()); break; } } // Path of target pawn from current to destination // Need travel speed of pawn, estimate Vec3 they will be in based on travel speed of our projectile float targetMoveSpeed = targetPawn.GetStatValue(StatDefOf.MoveSpeed); float projectileMoveSpeed = projectile.projectile.speed; // Estimate position target will be in after this amount of time IntVec3 bestTarget = targetPawn.Position; float bestTimeOffset = float.MaxValue; //Log.Message("Default time offset = " + Mathf.Abs(((targetPawn.Position - caster.Position).LengthHorizontal) / projectileMoveSpeed)); float accumulatedTargetTime = 0f; IntVec3 previousPosition = targetPawn.Position; foreach (IntVec3 pathPosition in nodes) { float projectileDistanceFromTarget = (pathPosition - __instance.caster.Position).LengthHorizontal; float timeForProjectileToReachPosition = projectileDistanceFromTarget / projectileMoveSpeed; //float pawnDistanceFromTarget = (pathPosition - targetPawn.Position).LengthHorizontal; //float timeForPawnToReachPosition = pawnDistanceFromTarget / targetMoveSpeed; float pawnDistanceFromLastPositionToHere = (pathPosition - previousPosition).LengthHorizontal; float timeForPawnToReachPositionFromLastPosition = pawnDistanceFromLastPositionToHere / targetMoveSpeed; accumulatedTargetTime += timeForPawnToReachPositionFromLastPosition; float timeOffset = Mathf.Abs(timeForProjectileToReachPosition - accumulatedTargetTime); if (timeOffset < bestTimeOffset) { bestTarget = pathPosition; bestTimeOffset = timeOffset; //Log.Message("Position " + pathPosition.ToString() + " is better. Time offset is " + timeOffset); } else { //Log.Message("Position " + pathPosition.ToString() + " is not better. Time offset is " + timeOffset); } previousPosition = pathPosition; } //Log.Message("Initial target cell = " + currentTarget.Cell.ToString() + " and new target is " + bestTarget.ToString()); ___currentTarget = new LocalTargetInfo(bestTarget); } } float adjustedForcedMissRadius = GetAdjustedForcedMissRadius(__instance, ___currentTarget); ProjectileHitFlags projectileHitFlags = ProjectileHitFlags.All; IntVec3 targetPosition = ___currentTarget.Cell; //if (adjustedForcedMissRadius > 0.5f) { if (MP.enabled) { Rand.PushState(); } // Calculate random target position using a uniform distribution float randomCircleArea = Rand.Range(0, Mathf.PI * adjustedForcedMissRadius * adjustedForcedMissRadius); float radiusOfRandomCircle = Mathf.Sqrt(randomCircleArea / Mathf.PI); float randomAngle = Rand.Range(0, 2 * Mathf.PI); targetPosition = new IntVec3( (int)(targetPosition.x + radiusOfRandomCircle * Mathf.Cos(randomAngle)), targetPosition.y, (int)(targetPosition.z + radiusOfRandomCircle * Mathf.Sin(randomAngle)) ); if (MP.enabled) { Rand.PopState(); } } //Log.Message("Final target is " + c.ToString()); projectile2.Launch(launcher, drawPos, targetPosition, ___currentTarget, projectileHitFlags, equipment, null); } __result = true; return(false); }
protected virtual (bool success, Vector3 launchPos, float angle) TryCastShotInternal() { if (currentTarget.HasThing && currentTarget.Thing.Map != caster.Map) { return(false, Vector3.zero, 0); } ThingDef projectile = Projectile; if (projectile == null) { return(false, Vector3.zero, 0); } ShootLine shootLine; bool flag = TryFindShootLineFromTo(caster.Position, currentTarget, out shootLine); if (verbProps.stopBurstWithoutLos && !flag) { return(false, Vector3.zero, 0); } if (EquipmentSource != null) { CompChangeableProjectile comp = EquipmentSource.GetComp <CompChangeableProjectile>(); if (comp != null) { comp.Notify_ProjectileLaunched(); } CompReloadable comp2 = EquipmentSource.GetComp <CompReloadable>(); if (comp2 != null) { comp2.UsedOnce(); } } Thing launcher = caster; Thing equipment = EquipmentSource; CompMannable compMannable = caster.TryGetComp <CompMannable>(); if (compMannable != null && compMannable.ManningPawn != null) { launcher = compMannable.ManningPawn; equipment = caster; } Vector3 launchPos = caster.DrawPos; float angle = launchPos.AngleToPoint(currentTarget.CenterVector3); Projectile projectile2 = (Projectile)GenSpawn.Spawn(projectile, shootLine.Source, caster.Map, WipeMode.Vanish); if (caster.def.GetModExtension <ProjectilePropertiesDefModExtension>() is ProjectilePropertiesDefModExtension projectileProps) { projectile2.AllComps.Insert(0, new CompTurretProjectileProperties(CasterTWC) { speed = projectileProps.speed > 0 ? projectileProps.speed : projectile2.def.projectile.speed, hitflag = projectileProps.projectileHitFlag, hitflags = projectileProps.hitFlagDef }); } if (verbProps.forcedMissRadius > 0.5f) { float num = VerbUtility.CalculateAdjustedForcedMiss(verbProps.forcedMissRadius, currentTarget.Cell - caster.Position); if (num > 0.5f) { int max = GenRadial.NumCellsInRadius(num); int num2 = Rand.Range(0, max); if (num2 > 0) { IntVec3 c = currentTarget.Cell + GenRadial.RadialPattern[num2]; launchPos += new Vector3(VerbProps.shootOffset.x, 0, VerbProps.shootOffset.y).RotatedBy(angle); ThrowDebugText("ToRadius"); ThrowDebugText("Rad\nDest", c); ProjectileHitFlags projectileHitFlags = ProjectileHitFlags.NonTargetWorld; if (Rand.Chance(0.5f)) { projectileHitFlags = ProjectileHitFlags.All; } if (!canHitNonTargetPawnsNow) { projectileHitFlags &= ~ProjectileHitFlags.NonTargetPawns; } projectile2.Launch(launcher, launchPos, c, currentTarget, projectileHitFlags, equipment, null); return(true, launchPos, angle); } } } ShotReport shotReport = ShotReport.HitReportFor(caster, this, currentTarget); Thing randomCoverToMissInto = shotReport.GetRandomCoverToMissInto(); ThingDef targetCoverDef = (randomCoverToMissInto != null) ? randomCoverToMissInto.def : null; if (!Rand.Chance(shotReport.AimOnTargetChance_IgnoringPosture)) { shootLine.ChangeDestToMissWild(shotReport.AimOnTargetChance_StandardTarget); ThrowDebugText("ToWild" + (canHitNonTargetPawnsNow ? "\nchntp" : "")); ThrowDebugText("Wild\nDest", shootLine.Dest); ProjectileHitFlags projectileHitFlags2 = ProjectileHitFlags.NonTargetWorld; if (Rand.Chance(0.5f) && canHitNonTargetPawnsNow) { projectileHitFlags2 |= ProjectileHitFlags.NonTargetPawns; } launchPos += new Vector3(VerbProps.shootOffset.x, 0, VerbProps.shootOffset.y).RotatedBy(angle); projectile2.Launch(launcher, launchPos, shootLine.Dest, currentTarget, projectileHitFlags2, equipment, targetCoverDef); return(true, launchPos, angle); } if (currentTarget.Thing != null && currentTarget.Thing.def.category == ThingCategory.Pawn && !Rand.Chance(shotReport.PassCoverChance)) { ThrowDebugText("ToCover" + (canHitNonTargetPawnsNow ? "\nchntp" : "")); ThrowDebugText("Cover\nDest", randomCoverToMissInto.Position); ProjectileHitFlags projectileHitFlags3 = ProjectileHitFlags.NonTargetWorld; if (canHitNonTargetPawnsNow) { projectileHitFlags3 |= ProjectileHitFlags.NonTargetPawns; } launchPos += new Vector3(VerbProps.shootOffset.x, 0, VerbProps.shootOffset.y).RotatedBy(angle); projectile2.Launch(launcher, launchPos, randomCoverToMissInto, currentTarget, projectileHitFlags3, equipment, targetCoverDef); return(true, launchPos, angle); } ProjectileHitFlags projectileHitFlags4 = ProjectileHitFlags.IntendedTarget; if (canHitNonTargetPawnsNow) { projectileHitFlags4 |= ProjectileHitFlags.NonTargetPawns; } if (!currentTarget.HasThing || currentTarget.Thing.def.Fillage == FillCategory.Full) { projectileHitFlags4 |= ProjectileHitFlags.NonTargetWorld; } ThrowDebugText("ToHit" + (canHitNonTargetPawnsNow ? "\nchntp" : "")); if (currentTarget.Thing != null) { angle = launchPos.AngleToPoint(currentTarget.CenterVector3); launchPos += new Vector3(VerbProps.shootOffset.x, 0, VerbProps.shootOffset.y).RotatedBy(angle); projectile2.Launch(launcher, launchPos, currentTarget, currentTarget, projectileHitFlags4, equipment, targetCoverDef); ThrowDebugText("Hit\nDest", currentTarget.Cell); } else { angle = launchPos.AngleToPoint(shootLine.Dest.ToVector3Shifted()); launchPos += new Vector3(VerbProps.shootOffset.x, 0, VerbProps.shootOffset.y).RotatedBy(angle); projectile2.Launch(launcher, launchPos, shootLine.Dest, currentTarget, projectileHitFlags4, equipment, targetCoverDef); ThrowDebugText("Hit\nDest", shootLine.Dest); } return(true, launchPos, angle); }
protected override bool TryCastShot() { if (this.currentTarget.HasThing && this.currentTarget.Thing.Map != this.caster.Map) { return(false); } ThingDef projectile = this.Projectile; if (projectile == null) { return(false); } ShootLine shootLine; bool flag = base.TryFindShootLineFromTo(this.caster.Position, this.currentTarget, out shootLine); if (this.verbProps.stopBurstWithoutLos && !flag) { return(false); } if (base.EquipmentSource != null) { CompChangeableProjectile comp = base.EquipmentSource.GetComp <CompChangeableProjectile>(); if (comp != null) { comp.Notify_ProjectileLaunched(); } CompReloadable comp2 = base.EquipmentSource.GetComp <CompReloadable>(); if (comp2 != null) { comp2.UsedOnce(); } } Thing launcher = this.caster; Thing equipment = base.EquipmentSource; CompMannable compMannable = this.caster.TryGetComp <CompMannable>(); if (compMannable != null && compMannable.ManningPawn != null) { launcher = compMannable.ManningPawn; equipment = this.caster; } Vector3 drawPos = this.caster.DrawPos; var casterTurret = caster as Building_TurretGun; Thing gun = null; if (casterTurret != null) { gun = casterTurret.gun; } var newSource = ApplyOffset(shootLine.Source, shootLine.Dest); var newSourceVec = newSource.ToVector3(); Projectile projectile2 = (Projectile)GenSpawn.Spawn(projectile, this.caster.Position, this.caster.Map, WipeMode.Vanish); if (this.verbProps.ForcedMissRadius > 0.5f) { float num = VerbUtility.CalculateAdjustedForcedMiss(this.verbProps.ForcedMissRadius, this.currentTarget.Cell - this.caster.Position); if (num > 0.5f) { int max = GenRadial.NumCellsInRadius(num); int num2 = Rand.Range(0, max); if (num2 > 0) { IntVec3 c = this.currentTarget.Cell + GenRadial.RadialPattern[num2]; this.ThrowDebugText("ToRadius"); this.ThrowDebugText("Rad\nDest", c); ProjectileHitFlags projectileHitFlags = ProjectileHitFlags.NonTargetWorld; if (Rand.Chance(0.5f)) { projectileHitFlags = ProjectileHitFlags.All; } if (!this.canHitNonTargetPawnsNow) { projectileHitFlags &= ~ProjectileHitFlags.NonTargetPawns; } projectile2.Launch(launcher, newSourceVec, c, this.currentTarget, projectileHitFlags, false, equipment, null); return(true); } } } ShotReport shotReport = ShotReport.HitReportFor(this.caster, this, this.currentTarget); Thing randomCoverToMissInto = shotReport.GetRandomCoverToMissInto(); ThingDef targetCoverDef = (randomCoverToMissInto != null) ? randomCoverToMissInto.def : null; if (!Rand.Chance(shotReport.AimOnTargetChance_IgnoringPosture)) { shootLine.ChangeDestToMissWild(shotReport.AimOnTargetChance_StandardTarget); this.ThrowDebugText("ToWild" + (this.canHitNonTargetPawnsNow ? "\nchntp" : "")); this.ThrowDebugText("Wild\nDest", shootLine.Dest); ProjectileHitFlags projectileHitFlags2 = ProjectileHitFlags.NonTargetWorld; if (Rand.Chance(0.5f) && this.canHitNonTargetPawnsNow) { projectileHitFlags2 |= ProjectileHitFlags.NonTargetPawns; } projectile2.Launch(launcher, newSourceVec, shootLine.Dest, this.currentTarget, projectileHitFlags2, false, equipment, targetCoverDef); return(true); } if (this.currentTarget.Thing != null && this.currentTarget.Thing.def.category == ThingCategory.Pawn && !Rand.Chance(shotReport.PassCoverChance)) { this.ThrowDebugText("ToCover" + (this.canHitNonTargetPawnsNow ? "\nchntp" : "")); this.ThrowDebugText("Cover\nDest", randomCoverToMissInto.Position); ProjectileHitFlags projectileHitFlags3 = ProjectileHitFlags.NonTargetWorld; if (this.canHitNonTargetPawnsNow) { projectileHitFlags3 |= ProjectileHitFlags.NonTargetPawns; } projectile2.Launch(launcher, newSourceVec, randomCoverToMissInto, this.currentTarget, projectileHitFlags3, false, equipment, targetCoverDef); return(true); } ProjectileHitFlags projectileHitFlags4 = ProjectileHitFlags.IntendedTarget; if (this.canHitNonTargetPawnsNow) { projectileHitFlags4 |= ProjectileHitFlags.NonTargetPawns; } if (!this.currentTarget.HasThing || this.currentTarget.Thing.def.Fillage == FillCategory.Full) { projectileHitFlags4 |= ProjectileHitFlags.NonTargetWorld; } this.ThrowDebugText("ToHit" + (this.canHitNonTargetPawnsNow ? "\nchntp" : "")); if (this.currentTarget.Thing != null) { projectile2.Launch(launcher, newSourceVec, this.currentTarget, this.currentTarget, projectileHitFlags4, false, equipment, targetCoverDef); this.ThrowDebugText("Hit\nDest", this.currentTarget.Cell); } else { projectile2.Launch(launcher, newSourceVec, shootLine.Dest, this.currentTarget, projectileHitFlags4, false, equipment, targetCoverDef); this.ThrowDebugText("Hit\nDest", shootLine.Dest); } return(true); }