private static Thing FindBestAmmo(Pawn pawn, Building_TurretGunCE reloadable) { //ThingFilter filter = refuelable.TryGetComp<CompRefuelable>().Props.fuelFilter; AmmoDef requestedAmmo = reloadable.CompAmmo.SelectedAmmo; // try to find currently selected ammo first var bestAmmo = FindBestAmmo(pawn, requestedAmmo); // this code is mostly for siege raids, so they can use all the ammo dropped (and get more ammo) // otherwise, they will wait forever for an HE ammo drop, without using the incendiary shells next to them if (bestAmmo == null && !pawn.IsColonist && requestedAmmo.AmmoSetDefs != null) { // if there isn't any, try to find some ammo from same ammo set foreach (AmmoSetDef set in requestedAmmo.AmmoSetDefs) { foreach (AmmoLink link in set.ammoTypes) { bestAmmo = FindBestAmmo(pawn, link.ammo); if (bestAmmo != null) { return(bestAmmo); } } } } return(bestAmmo); }
public static void Postfix(ref string __result, Thing target) { var selectedThing = Find.Selector.SingleSelectedThing; if (__result.NullOrEmpty() && selectedThing != null) { // Create CE Tooltip StringBuilder stringBuilder = new StringBuilder(); Verb_LaunchProjectileCE verbCE = null; Pawn pawn = selectedThing as Pawn; if (pawn != null && pawn != target && pawn.equipment != null && pawn.equipment.Primary != null && pawn.equipment.PrimaryEq.PrimaryVerb is Verb_LaunchProjectileCE) { verbCE = pawn.equipment.PrimaryEq.PrimaryVerb as Verb_LaunchProjectileCE; } Building_TurretGunCE turret = selectedThing as Building_TurretGunCE; if (turret != null && turret != target) { verbCE = turret.AttackVerb as Verb_LaunchProjectileCE; } if (verbCE != null) { stringBuilder.AppendLine(); stringBuilder.Append("ShotBy".Translate(selectedThing.LabelShort, selectedThing) + ":\n"); string obstructReport; if (verbCE.CanHitTarget(target, out obstructReport)) { ShiftVecReport report = verbCE.ShiftVecReportFor(target); stringBuilder.Append(report.GetTextReadout()); } else { stringBuilder.Append("CannotHit".Translate()); if (!obstructReport.NullOrEmpty()) { stringBuilder.Append(" " + obstructReport + "."); } } Pawn pawn2 = target as Pawn; if (pawn2 != null && pawn2.Faction == null && !pawn2.InAggroMentalState) { float manhunterOnDamageChance; if (verbCE.IsMeleeAttack) { manhunterOnDamageChance = PawnUtility.GetManhunterOnDamageChance(pawn2, 0f, selectedThing); } else { manhunterOnDamageChance = PawnUtility.GetManhunterOnDamageChance(pawn2, selectedThing); } if (manhunterOnDamageChance > 0f) { stringBuilder.AppendLine(); stringBuilder.AppendLine(string.Format("{0}: {1}", "ManhunterPerHit".Translate(), manhunterOnDamageChance.ToStringPercent())); } } } __result = stringBuilder.ToString(); } }
public static Job MakeReloadJob(Pawn pawn, Building_TurretGunCE turret) { var compAmmo = turret.CompAmmo; if (compAmmo == null) { CELogger.Error($"{pawn} tried to create a reload job on a thing ({turret}) that's not reloadable."); return(null); } if (!compAmmo.UseAmmo) { return(MakeReloadJobNoAmmo(turret)); } var ammo = FindBestAmmo(pawn, turret); if (ammo == null) { CELogger.Error($"{pawn} tried to create a reload job without ammo. This should have been checked earlier."); return(null); } CELogger.Message($"Making a reload job for {pawn}, {turret} and {ammo}"); Job job = JobMaker.MakeJob(CE_JobDefOf.ReloadTurret, turret, ammo); job.count = Mathf.Min(ammo.stackCount, turret.CompAmmo.MissingToFullMagazine); return(job); }
static void Prefix(Building_TurretGunCE __instance) { if (__instance.GetType().GetField("mannableComp", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(__instance) is CompMannable mannable && __instance.CompAmmo.UseAmmo) { CompInventory inv = ThingCompUtility.TryGetComp <CompInventory>(mannable.ManningPawn); if (mannable.ManningPawn.IsColonist && inv != null) { Thing thing = inv.container.FirstOrDefault((Thing x) => x.def == __instance.CompAmmo.SelectedAmmo); if (thing == null) { AmmoDef ammoDef = __instance.CompAmmo.SelectedAmmo; if (ammoDef != null && CombatExtendedUtil.HasAmmo(ammoDef)) { int magazineSize = __instance.CompAmmo.Props.magazineSize; if (CombatExtendedUtil.TryRemoveAmmo(ammoDef, magazineSize, out Thing ammo)) { inv.UpdateInventory(); if (!inv.container.TryAdd(ammo as ThingWithComps)) { Log.Error("Failed to add ammo to pawn inventory"); CombatExtendedUtil.AddAmmo(ammo); } } } } } } }
static void Postfix(Command_Reload __instance, ref FloatMenu __result) { if (__instance.compAmmo.turret == null) { List <FloatMenuOption> options = __result.GetType().GetField("options", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(__result) as List <FloatMenuOption>; List <AmmoDef> list = new List <AmmoDef>(); foreach (AmmoLink curLink in __instance.compAmmo.Props.ammoSet.ammoTypes) { if (CombatExtendedUtil.HasAmmo(curLink.ammo)) { bool containsLabelCap = false; foreach (var o in options) { if (o.Label.Equals(curLink.ammo.ammoClass.LabelCap)) { containsLabelCap = true; break; } } if (!containsLabelCap) { options.Insert(0, new FloatMenuOption( curLink.ammo.ammoClass.LabelCap, delegate { if (__instance.compAmmo.SelectedAmmo != curLink.ammo || __instance.compAmmo.CurMagCount < __instance.compAmmo.Props.magazineSize) { __instance.compAmmo.SelectedAmmo = curLink.ammo; Building_TurretGunCE turret = __instance.compAmmo.turret; if (turret == null || turret.MannableComp == null) { if (CombatExtendedUtil.TryRemoveAmmo(curLink.ammo, __instance.compAmmo.Props.magazineSize, out Thing ammo)) { __instance.compAmmo.TryUnload(); if (!__instance.compAmmo.CompInventory.container.TryAdd(ammo as ThingWithComps)) { Log.Error("Failed to reload ammo"); CombatExtendedUtil.AddAmmo(ammo); } __instance.compAmmo.CompInventory.UpdateInventory(); if (turret != null) { __instance.compAmmo.turret.TryOrderReload(); } else { __instance.compAmmo.TryStartReload(); } } } } }, MenuOptionPriority.Default, null, null, 0f, null, null));
static void Postfix(Building_TurretGunCE __instance) { if (Base.Instance.GetExtendedDataStorage().GetExtendedDataFor(__instance.Map).rogueAI is Building_RogueAI controller) { if (controller.controlledTurrets.Contains(__instance)) { GenDraw.DrawLineBetween(__instance.Position.ToVector3Shifted(), controller.Position.ToVector3Shifted(), SimpleColor.Green); } } }
static void Postfix(Building_TurretGunCE __instance, ref bool __result) { if (Base.Instance.GetExtendedDataStorage().GetExtendedDataFor(__instance.Map).rogueAI is Building_RogueAI rogueAI) { if (rogueAI.controlledTurrets.Contains(__instance)) { __result = true; } } }
private static Job MakeReloadJobNoAmmo(Building_TurretGunCE turret) { var compAmmo = turret.CompAmmo; if (compAmmo == null) { CELogger.Error("Tried to create a reload job on a thing that's not reloadable."); return(null); } return(JobMaker.MakeJob(CE_JobDefOf.ReloadTurret, turret, null)); }
static void Postfix(Building_TurretGunCE __instance, TurretTop ___top) { if (__instance.GetComp <CompMountable>() is CompMountable comp && comp.Active) { //TODO: look into performance of this. Try to avoid Traverse. float curRotation = Traverse.Create(___top).Property("CurRotation").GetValue <float>(); if (__instance.Rotation != comp.mountedTo.Rotation) { Traverse.Create(___top).Property("CurRotation").SetValue(comp.mountedTo.Rotation.AsAngle); __instance.Rotation = comp.mountedTo.Rotation; } } }
// used to manually re-arm turrets static void Postfix(WorkGiver_ReloadTurret __instance, ref bool __result, Pawn pawn, Thing t, bool forced) { Building_TurretGunCE turret = t as Building_TurretGunCE; if (__result == false && turret != null && !turret.def.hasInteractionCell) { if (WorldComp.HasStorages(turret.Map) && CombatExtendedUtil.HasAmmo(turret.CompAmmo.SelectedAmmo)) { WS = GenClosest.ClosestThingReachable(turret.Position, turret.Map, ThingRequest.ForDef(WorldComp.WeaponStorageDef), Verse.AI.PathEndMode.ClosestTouch, TraverseParms.For(pawn, pawn.NormalMaxDanger(), TraverseMode.ByPawn, false), 100) as Building; __result = WS != null; } } }
static void Postfix(Building_TurretGunCE __instance, ref string __result) { if (MoreInfo_Settings.showLoadedAmmoStats && __instance != null && __instance.Gun != null) { StringBuilder builder = new StringBuilder(); builder.Append(__result); var ammoComp = __instance.Gun.TryGetComp <CompAmmoUser>(); if (ammoComp != null) { builder.AppendInNewLine(ammoComp.CurrentAmmo.LabelCap); builder.AppendInNewLine(ammoComp.CurAmmoProjectile.GetProjectileReadout(__instance)); } __result = builder.ToString().TrimEndNewlines(); } }
private static Thing FindBestAmmo(Pawn pawn, Building_TurretGunCE reloadable) { //ThingFilter filter = refuelable.TryGetComp<CompRefuelable>().Props.fuelFilter; var requestedAmmo = reloadable.CompAmmo.SelectedAmmo; Predicate <Thing> validator = (Thing potentialAmmo) => { if (potentialAmmo.IsForbidden(pawn) || !pawn.CanReserve(potentialAmmo)) { return(false); } return(GetPathCost(pawn, potentialAmmo) <= MaxPathCost); }; return(GenClosest.ClosestThingReachable(pawn.Position, pawn.Map, ThingRequest.ForDef(requestedAmmo), PathEndMode.ClosestTouch, TraverseParms.For(pawn), 9999f, validator)); }
private void LetMountedToWaitIfReserved() { Building_TurretGunCE turret = (Building_TurretGunCE)parent; if (turret.Map != null && turret.Map.reservationManager.IsReservedByAnyoneOf(turret, Faction.OfPlayer)) { if (mountedTo.CurJobDef != JobDefOf.Wait_Combat && mountedTo.CurJobDef != WTH_DefOf.WTH_Mechanoid_Rest) { mountedTo.jobs.StartJob(new Job(JobDefOf.Wait_Combat) { expiryInterval = 10000 }, JobCondition.InterruptForced); mountedTo.jobs.curDriver.AddFailCondition(delegate { return(!turret.Map.reservationManager.IsReservedByAnyoneOf(turret, Faction.OfPlayer)); }); } } }
static bool Prefix(WorkGiver_ReloadTurret __instance, ref Job __result, Pawn pawn, Thing t, bool forced) { if (Patch_WorkGiver_ReloadTurret_HasJobOnThing.WS != null) { Building_TurretGunCE turret = t as Building_TurretGunCE; __result = new Job( DefDatabase <JobDef> .GetNamed("ReloadTurret", true), t, new StoredAmmo( Patch_WorkGiver_ReloadTurret_HasJobOnThing.WS, turret.CompAmmo.SelectedAmmo, turret.CompAmmo.Props.magazineSize, forced)); Patch_WorkGiver_ReloadTurret_HasJobOnThing.WS = null; return(false); } return(true); }
/// <summary> /// This method is a direct copy/paste of the <see cref="RefuelWorkGiverUtility"/> private FindAllFuel method. /// /// Finds all relevant ammo in order of distance. /// </summary> /// <param name="pawn"></param> /// <param name="reloadable"></param> /// <returns></returns> private static List <Thing> FindAllAmmo(Pawn pawn, Building_TurretGunCE reloadable) { int quantity = reloadable.CompAmmo.MissingToFullMagazine; var ammoKind = reloadable.CompAmmo.SelectedAmmo; Predicate <Thing> validator = (Thing potentialAmmo) => { if (potentialAmmo.IsForbidden(pawn) || !pawn.CanReserve(potentialAmmo)) { return(false); } return(GetPathCost(pawn, potentialAmmo) <= MaxPathCost); }; Region region = reloadable.Position.GetRegion(pawn.Map); TraverseParms traverseParams = TraverseParms.For(pawn); Verse.RegionEntryPredicate entryCondition = (Region from, Region r) => r.Allows(traverseParams, isDestination: false); var chosenThings = new List <Thing>(); int accumulatedQuantity = 0; Verse.RegionProcessor regionProcessor = (Region r) => { List <Thing> list = r.ListerThings.ThingsMatching(ThingRequest.ForDef(ammoKind)); foreach (var thing in list) { if (validator(thing) && !chosenThings.Contains(thing) && ReachabilityWithinRegion.ThingFromRegionListerReachable(thing, r, PathEndMode.ClosestTouch, pawn)) { chosenThings.Add(thing); accumulatedQuantity += thing.stackCount; if (accumulatedQuantity >= quantity) { return(true); } } } return(false); }; RegionTraverser.BreadthFirstTraverse(region, entryCondition, regionProcessor, 99999); if (accumulatedQuantity >= quantity) { return(chosenThings); } return(null); }
private Gizmo GetControlTurretCancelGizmo(Building_TurretGunCE turret, int index) { Command_Action_Highlight command = new Command_Action_Highlight(); command.defaultLabel = "WTH_Gizmo_ControlTurretCancel_Label".Translate() + index; command.defaultDesc = "WTH_Gizmo_ControlTurretCancel_Description".Translate(); command.parent = this; command.thing = turret; bool iconFound = Base.Instance.cancelControlTurretTextures.TryGetValue(turret.def.defName, out Texture2D icon); if (iconFound) { command.icon = icon; } command.action = delegate { CancelControlTurret(turret); }; return(command); }
static void Prefix(Pawn_JobTracker __instance, Job newJob, JobCondition lastJobEndCondition, ThinkNode jobGiver, bool resumeCurJobAfterwards, bool cancelBusyStances, ThinkTreeDef thinkTree, JobTag?tag, bool fromQueue) { if (newJob != null && newJob.targetB != null && newJob.targetB.Thing is StoredAmmo sa) { Pawn pawn = __instance.GetType().GetField("pawn", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(__instance) as Pawn; Building_TurretGunCE turret = newJob.targetA.Thing as Building_TurretGunCE; FieldInfo fi = sa.root.GetType().GetField("AllowAdds", BindingFlags.Instance | BindingFlags.Public); try { fi.SetValue(sa.root, false); IntVec3 pos; Building building = sa.root as Building; if (sa.forced || sa.root == null) { pos = pawn.Position; } else { pos = building.InteractionCell; } if (!CombatExtendedUtil.TryDropAmmo(sa.ammoDef, sa.ammoCount, pos, sa.root.Map, out Thing t)) { Log.Error("Could not get ammo"); } else { newJob.targetB = t; newJob.count = t.stackCount; } } finally { fi.SetValue(sa.root, true); } } }
public static void Postfix(ref string __result, Thing target) { if (__result.NullOrEmpty() && Find.Selector.SingleSelectedThing != null) { // Create CE Tooltip StringBuilder stringBuilder = new StringBuilder(); Verb_LaunchProjectileCE verbCE = null; Pawn pawn = Find.Selector.SingleSelectedThing as Pawn; if (pawn != null && pawn != target && pawn.equipment != null && pawn.equipment.Primary != null && pawn.equipment.PrimaryEq.PrimaryVerb is Verb_LaunchProjectileCE) { verbCE = pawn.equipment.PrimaryEq.PrimaryVerb as Verb_LaunchProjectileCE; } Building_TurretGunCE turret = Find.Selector.SingleSelectedThing as Building_TurretGunCE; if (turret != null && turret != target) { verbCE = turret.AttackVerb as Verb_LaunchProjectileCE; } if (verbCE != null) { stringBuilder.AppendLine(); stringBuilder.Append("ShotBy".Translate(new object[] { Find.Selector.SingleSelectedThing.LabelShort }) + ":\n"); string obstructReport; if (verbCE.CanHitTarget(target, out obstructReport)) { ShiftVecReport report = verbCE.ShiftVecReportFor(target); stringBuilder.Append(report.GetTextReadout()); } else { stringBuilder.Append("CannotHit".Translate()); if (!obstructReport.NullOrEmpty()) { stringBuilder.Append(" " + obstructReport + "."); } } } __result = stringBuilder.ToString(); } }
// Token: 0x0600011F RID: 287 RVA: 0x0000DBBC File Offset: 0x0000BDBC public override void WarmupComplete() { Log.Error(ShotsPerBurst.ToString()); float lengthHorizontal = (this.currentTarget.Cell - this.caster.Position).LengthHorizontal; int num = (int)Mathf.Lerp(30f, 240f, lengthHorizontal / 100f); bool flag = this.ShouldAim && !this._isAiming; if (flag) { Building_TurretGunCE building_TurretGunCE = this.caster as Building_TurretGunCE; bool flag2 = building_TurretGunCE != null; if (flag2) { building_TurretGunCE.burstWarmupTicksLeft += num; this._isAiming = true; return; } bool flag3 = base.ShooterPawn != null; if (flag3) { base.ShooterPawn.stances.SetStance(new Stance_Warmup(num, this.currentTarget, this)); this._isAiming = true; return; } } base.WarmupComplete(); this._isAiming = false; Pawn shooterPawn = base.ShooterPawn; bool flag4 = ((shooterPawn != null) ? shooterPawn.skills : null) != null && this.currentTarget.Thing is Pawn; if (flag4) { float num2 = this.verbProps.AdjustedFullCycleTime(this, base.ShooterPawn); num2 += num.TicksToSeconds(); float num3 = this.currentTarget.Thing.HostileTo(base.ShooterPawn) ? 170f : 20f; num3 *= num2; base.ShooterPawn.skills.Learn(SkillDefOf.Shooting, num3, false); } }
private static Thing FindBestAmmo(Pawn pawn, Building_TurretGunCE turret) { AmmoDef requestedAmmo = turret.CompAmmo.SelectedAmmo; var bestAmmo = FindBestAmmo(pawn, requestedAmmo); // try to find currently selected ammo first if (bestAmmo == null && turret.CompAmmo.EmptyMagazine && requestedAmmo.AmmoSetDefs != null) { //Turret's selected ammo not available, and magazine is empty. Pick a new ammo from the set to load. foreach (AmmoSetDef set in requestedAmmo.AmmoSetDefs) { foreach (AmmoLink link in set.ammoTypes) { bestAmmo = FindBestAmmo(pawn, link.ammo); if (bestAmmo != null) { return(bestAmmo); } } } } return(bestAmmo); }
private void CancelControlTurret(Building_TurretGunCE turret) { controlledTurrets.Remove(turret); }