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);
        }
Beispiel #4
0
 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);
                         }
                     }
                 }
             }
         }
     }
 }
Beispiel #5
0
        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;
         }
     }
 }
Beispiel #10
0
        // 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;
                }
            }
        }
Beispiel #11
0
 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();
     }
 }
Beispiel #12
0
        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)); });
                }
            }
        }
Beispiel #14
0
 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);
        }
Beispiel #17
0
        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();
     }
 }
Beispiel #19
0
        // 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);
 }