public static bool Deploy(CompReloadable comp) { if (!ModLister.RoyaltyInstalled) { Log.ErrorOnce("Shields 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.", 86573384); return(false); } if (comp == null || !comp.CanBeUsed) { return(false); } Pawn wearer = comp.Wearer; Map map = wearer.Map; int num = GenRadial.NumCellsInRadius(4f); for (int i = 0; i < num; i++) { IntVec3 intVec = wearer.Position + GenRadial.RadialPattern[i]; if (intVec.IsValid && intVec.InBounds(map)) { SpawnEffect(GenSpawn.Spawn(ThingDefOf.BroadshieldProjector, intVec, map)); comp.UsedOnce(); return(true); } } Messages.Message("AbilityNotEnoughFreeSpace".Translate(), wearer, MessageTypeDefOf.RejectInput, historical: false); return(false); }
public static bool CanUseConsideringQueuedJobs(Pawn pawn, ThingWithComps gear, bool showMessage = true) { CompReloadable compReloadable = gear.TryGetComp <CompReloadable>(); if (compReloadable == null) { return(true); } string text = null; if (!Event.current.shift) { if (!compReloadable.CanBeUsed) { text = compReloadable.DisabledReason(compReloadable.MinAmmoNeeded(allowForcedReload: false), compReloadable.MaxAmmoNeeded(allowForcedReload: false)); } } else if (TotalChargesFromQueuedJobs(pawn, gear) + 1 > compReloadable.RemainingCharges) { text = compReloadable.DisabledReason(compReloadable.MaxAmmoAmount(), compReloadable.MaxAmmoAmount()); } if (text != null) { if (showMessage) { Messages.Message(text, pawn, MessageTypeDefOf.RejectInput, historical: false); } return(false); } return(true); }
private static void TransformAndExplain(StatRequest req, ref float val, StringBuilder explanation) { CompReloadable compReloadable = req.Thing?.TryGetComp <CompReloadable>(); if (compReloadable != null && compReloadable.RemainingCharges != compReloadable.MaxCharges) { if (compReloadable.AmmoDef != null) { int num = compReloadable.MaxAmmoNeeded(allowForcedReload: true); float num2 = (0f - compReloadable.AmmoDef.BaseMarketValue) * (float)num; val += num2; explanation?.AppendLine("StatsReport_ReloadMarketValue".Translate(NamedArgumentUtility.Named(compReloadable.AmmoDef, "AMMO"), num.Named("COUNT")) + ": " + num2.ToStringMoneyOffset()); } else if (compReloadable.Props.destroyOnEmpty) { float num3 = (float)compReloadable.RemainingCharges / (float)compReloadable.MaxCharges; explanation?.AppendLine("StatsReport_ReloadRemainingChargesMultipler".Translate(compReloadable.Props.ChargeNounArgument, compReloadable.LabelRemaining) + ": x" + num3.ToStringPercent()); val *= num3; } if (val < 0f) { val = 0f; } } }
public static IEnumerable <Pair <CompReloadable, Thing> > FindPotentiallyReloadableGear(Pawn pawn, List <Thing> potentialAmmo) { if (pawn.apparel == null) { yield break; } List <Apparel> worn = pawn.apparel.WornApparel; for (int i = 0; i < worn.Count; i++) { CompReloadable comp = worn[i].TryGetComp <CompReloadable>(); if (comp?.AmmoDef == null) { continue; } for (int j = 0; j < potentialAmmo.Count; j++) { Thing thing = potentialAmmo[j]; if (thing.def == comp.Props.ammoDef) { yield return(new Pair <CompReloadable, Thing>(comp, thing)); } } } }
public void ExposeData() { Scribe_Deep.Look(ref wornApparel, "wornApparel", this); Scribe_Collections.Look(ref lockedApparel, "lockedApparel", LookMode.Reference); Scribe_Values.Look(ref lastApparelWearoutTick, "lastApparelWearoutTick", 0); if (Scribe.mode == LoadSaveMode.ResolvingCrossRefs) { SortWornApparelIntoDrawOrder(); } if (Scribe.mode != LoadSaveMode.PostLoadInit) { return; } if (lockedApparel != null) { lockedApparel.RemoveAll((Apparel x) => x == null); } foreach (Apparel item in WornApparel) { CompReloadable comp = item.GetComp <CompReloadable>(); if (comp == null) { continue; } foreach (Verb allVerb in comp.AllVerbs) { allVerb.caster = pawn; } } }
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); } CompReloadable reloadableCompSource = base.ReloadableCompSource; Pawn casterPawn = CasterPawn; if (casterPawn == null || reloadableCompSource == null || !reloadableCompSource.CanBeUsed) { return(false); } IntVec3 cell = currentTarget.Cell; Map map = casterPawn.Map; reloadableCompSource.UsedOnce(); PawnFlyer pawnFlyer = PawnFlyer.MakeFlyer(ThingDefOf.PawnJumper, casterPawn, cell); if (pawnFlyer != null) { GenSpawn.Spawn(pawnFlyer, cell, map); return(true); } return(false); }
public static Job MakeReloadJob(CompReloadable comp, List <Thing> chosenAmmo) { Job job = JobMaker.MakeJob(JobDefOf.Reload, comp.parent); job.targetQueueB = chosenAmmo.Select((Thing t) => new LocalTargetInfo(t)).ToList(); job.count = chosenAmmo.Sum((Thing t) => t.stackCount); job.count = Math.Min(job.count, comp.MaxAmmoNeeded(allowForcedReload: true)); return(job); }
public static void Pop(CompReloadable comp) { if (comp != null && comp.CanBeUsed) { ThingWithComps parent = comp.parent; Pawn wearer = comp.Wearer; GenExplosion.DoExplosion(wearer.Position, wearer.Map, parent.GetStatValue(StatDefOf.SmokepopBeltRadius), DamageDefOf.Smoke, null, -1, -1f, null, null, null, null, ThingDefOf.Gas_Smoke, 1f); comp.UsedOnce(); } }
public static List <Thing> FindEnoughAmmo(Pawn pawn, IntVec3 rootCell, CompReloadable comp, bool forceReload) { if (comp == null) { return(null); } IntRange desiredQuantity = new IntRange(comp.MinAmmoNeeded(forceReload), comp.MaxAmmoNeeded(forceReload)); return(RefuelWorkGiverUtility.FindEnoughReservableThings(pawn, rootCell, desiredQuantity, (Thing t) => t.def == comp.AmmoDef)); }
protected override Job TryGiveJob(Pawn pawn) { CompReloadable compReloadable = ReloadableUtility.FindSomeReloadableComponent(pawn, allowForcedReload: false); if (compReloadable == null) { return(null); } List <Thing> list = ReloadableUtility.FindEnoughAmmo(pawn, pawn.Position, compReloadable, forceReload: false); if (list == null) { return(null); } return(MakeReloadJob(compReloadable, list)); }
public static CompReloadable FindSomeReloadableComponent(Pawn pawn, bool allowForcedReload) { if (pawn.apparel == null) { return(null); } List <Apparel> wornApparel = pawn.apparel.WornApparel; for (int i = 0; i < wornApparel.Count; i++) { CompReloadable compReloadable = wornApparel[i].TryGetComp <CompReloadable>(); if (compReloadable != null && compReloadable.NeedsReload(allowForcedReload)) { return(compReloadable); } } return(null); }
public static int TotalChargesFromQueuedJobs(Pawn pawn, ThingWithComps gear) { CompReloadable compReloadable = gear.TryGetComp <CompReloadable>(); int num = 0; if (compReloadable != null && pawn != null) { foreach (Job item in pawn.jobs.AllJobs()) { Verb verbToUse = item.verbToUse; if (verbToUse != null && compReloadable == verbToUse.ReloadableCompSource) { num++; } } return(num); } return(num); }
protected override IEnumerable <Toil> MakeNewToils() { CompReloadable comp = Gear?.TryGetComp <CompReloadable>(); this.FailOn(() => comp == null); this.FailOn(() => comp.Wearer != pawn); this.FailOn(() => !comp.NeedsReload(allowForcedReload: true)); this.FailOnDestroyedOrNull(TargetIndex.A); this.FailOnIncapable(PawnCapacityDefOf.Manipulation); Toil getNextIngredient = Toils_General.Label(); yield return(getNextIngredient); foreach (Toil item in ReloadAsMuchAsPossible(comp)) { yield return(item); } yield return(Toils_JobTransforms.ExtractNextTargetFromQueue(TargetIndex.B)); yield return(Toils_Goto.GotoThing(TargetIndex.B, PathEndMode.ClosestTouch).FailOnDespawnedNullOrForbidden(TargetIndex.B).FailOnSomeonePhysicallyInteracting(TargetIndex.B)); yield return(Toils_Haul.StartCarryThing(TargetIndex.B, putRemainderInQueue: false, subtractNumTakenFromJobCount: true).FailOnDestroyedNullOrForbidden(TargetIndex.B)); yield return(Toils_Jump.JumpIf(getNextIngredient, () => !job.GetTargetQueue(TargetIndex.B).NullOrEmpty())); foreach (Toil item2 in ReloadAsMuchAsPossible(comp)) { yield return(item2); } Toil toil = new Toil(); toil.initAction = delegate { Thing carriedThing = pawn.carryTracker.CarriedThing; if (carriedThing != null && !carriedThing.Destroyed) { pawn.carryTracker.TryDropCarriedThing(pawn.Position, ThingPlaceMode.Near, out var _); } }; toil.defaultCompleteMode = ToilCompleteMode.Instant; yield return(toil); }
private IEnumerable <Toil> ReloadAsMuchAsPossible(CompReloadable comp) { Toil done = Toils_General.Label(); yield return(Toils_Jump.JumpIf(done, () => pawn.carryTracker.CarriedThing == null || pawn.carryTracker.CarriedThing.stackCount < comp.MinAmmoNeeded(allowForcedReload: true))); yield return(Toils_General.Wait(comp.Props.baseReloadTicks).WithProgressBarToilDelay(TargetIndex.A)); Toil toil = new Toil(); toil.initAction = delegate { Thing carriedThing = pawn.carryTracker.CarriedThing; comp.ReloadFrom(carriedThing); }; toil.defaultCompleteMode = ToilCompleteMode.Instant; yield return(toil); yield return(done); }
public Command_Reloadable(CompReloadable comp) { this.comp = comp; }
public static Pawn WearerOf(CompReloadable comp) { return((comp.ParentHolder as Pawn_ApparelTracker)?.pawn); }