コード例 #1
0
 public void Register(Building_Turret t)
 {
     if (!Turrets.Contains(t))
     {
         Turrets.Add(t);
     }
 }
コード例 #2
0
        private static bool IsValidTarget(Building_TurretGun __instance, Thing t)
        {
            Building_Turret building_Turret = __instance;
            Pawn            pawn            = t as Pawn;

            if (pawn != null)
            {
                if (__instance.AttackVerb.ProjectileFliesOverhead())
                {
                    RoofDef roofDef = building_Turret.Map.roofGrid.RoofAt(t.Position);
                    if (roofDef != null && roofDef.isThickRoof)
                    {
                        return(false);
                    }
                }

                if (mannableComp == null)
                {
                    return(!GenAI.MachinesLike(building_Turret.Faction, pawn));
                }

                if (pawn.RaceProps.Animal && pawn.Faction == Faction.OfPlayer)
                {
                    return(false);
                }
            }

            return(true);
        }
コード例 #3
0
        public static void Postfix(Pawn pawn, Building_Turret tube, ref Thing __result)
        {
            if (__result != null)
            {
                return;
            }
            var               turret = tube as Building_ShipTurret;
            StorageSettings   allowedShellsSettings = ThingCompUtility.TryGetComp <CompChangeableProjectilePlural>(turret.gun).allowedShellsSettings;
            Predicate <Thing> pred = (Thing x) =>
            {
                if (ForbidUtility.IsForbidden(x, pawn) || !ReservationUtility.CanReserve(pawn, x, 1, -1, (ReservationLayerDef)null, false))
                {
                    return(false);
                }
                else
                {
                    return(allowedShellsSettings?.AllowedToAccept(x) ?? true);
                }
            };

            foreach (String defName in shellDefNames)
            {
                var val = ThingDef.Named(defName);
                __result = GenClosest.ClosestThingReachable(pawn.Position, pawn.Map, ThingRequest.ForDef(val), PathEndMode.ClosestTouch, TraverseParms.For(pawn), 9999f, pred);
                if (__result != null)
                {
                    return;
                }
            }
        }
コード例 #4
0
 public void Unregister(Building_Turret t)
 {
     if (Turrets.Contains(t))
     {
         Turrets.Remove(t);
     }
 }
コード例 #5
0
        public override void Tick()
        {
            if (pawn.pather != null && pawn.pather.nextCell.GetDoor(pawn.Map) != null)
            {
                Building_Door d = pawn.pather.nextCell.GetDoor(pawn.Map);
                if (pawn.health.hediffSet.HasHediff(HediffDefOfPsychology.Saboteur) & !d.HoldOpen && !pawn.Drafted && Rand.Value < 0.05f)
                {
                    d.HoldOpenInt(true);
                }
            }
            if (pawn.IsHashIntervalTick(10000) && Rand.Value < 0.25f)
            {
                switch (Rand.RangeInclusive(0, 10))
                {
                case 0:
                    Building breakdownAble = FindBreakDownTargetFor(pawn);
                    if (breakdownAble != null)
                    {
                        pawn.jobs.StartJob(new Job(JobDefOfPsychology.Sabotage, breakdownAble), JobCondition.InterruptOptional, null, false, false, null);
                    }
                    break;

                default:
                    Building_Turret turret = FindTurretFor(pawn);
                    if (turret != null)
                    {
                        turret.GetComp <CompFlickable>().WantSwitchOn(false);
                        turret.Map.designationManager.AddDesignation(new Designation(turret, DesignationDefOf.Flick));
                        pawn.jobs.StartJob(new Job(JobDefOf.Flick, turret), JobCondition.InterruptOptional, null, false, false, null);
                    }
                    break;
                }
            }
        }
コード例 #6
0
        public static Thing GetAttacker(Pawn pawn, Thing target, bool attackingHive)
        {
            Pawn            pawnTarget   = target as Pawn;
            Insect          enemyBug     = target as Insect;
            Building_Turret turretTarget = target as Building_Turret;
            bool            recentAttack = false;

            if (pawnTarget != null)
            {
                recentAttack = pawnTarget.mindState.lastAttackTargetTick <= Find.TickManager.TicksGame && pawnTarget.mindState.lastAttackTargetTick > Find.TickManager.TicksGame - ticksInAttackMode;
            }
            else if (turretTarget != null)
            {
                recentAttack = turretTarget.LastAttackTargetTick <= Find.TickManager.TicksGame && turretTarget.LastAttackTargetTick > Find.TickManager.TicksGame - ticksInAttackMode;
            }
            int  dist = IntVec3Utility.ManhattanDistanceFlat(pawn.PositionHeld, target.PositionHeld);
            bool withinHiveAndInVisual = JobGiver_InsectGather.WithinHive(pawn, target, false) && GenSight.LineOfSight(pawn.Position, target.Position, pawn.Map, true, null, 0, 0);
            bool enemyPawnThreat       = (withinHiveAndInVisual || (attackingHive && recentAttack)) && dist < maxAttackDistance;
            bool enemyInsectThreat     = enemyBug != null && enemyBug.Faction != pawn.Faction && GenSight.LineOfSight(pawn.Position, enemyBug.Position, pawn.Map, true, null, 0, 0) && dist < 30;

            if (enemyPawnThreat || enemyInsectThreat)
            {
                if (pawn.CanReach(target, PathEndMode.Touch, Danger.Deadly, true, TraverseMode.PassDoors))
                {
                    return(target);
                }
            }
            return(null);
        }
コード例 #7
0
        public static Job MakeReloadJob(Pawn pawn, Building_Turret turret)
        {
            var compAmmo = turret.GetAmmo();

            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, compAmmo.MissingToFullMagazine);
            return(job);
        }
コード例 #8
0
        public static int AdjustedTurretBurstWarmupTicks(int warmupTicks, Building_Turret turret)
        {
            var   extensionValues  = TurretFrameworkExtension.Get(turret.def);
            float warmupTicksFloat = warmupTicks;

            // Multiply the burstWarmupTicksLeft by the manning pawn's aiming delay factor if applicable
            if (extensionValues.useManningPawnAimingDelayFactor)
            {
                var mannableComp = turret.TryGetComp <CompMannable>();
                if (mannableComp != null)
                {
                    var manningPawn = mannableComp.ManningPawn;
                    if (manningPawn != null)
                    {
                        float manningPawnAimingDelayFactor = manningPawn.GetStatValue(StatDefOf.AimingDelayFactor);
                        warmupTicksFloat *= manningPawnAimingDelayFactor;
                    }
                }
            }

            // Multiply based on upgrade
            if (turret.IsUpgraded(out CompUpgradable upgradableComp))
            {
                warmupTicksFloat *= upgradableComp.Props.turretBurstWarmupTimeFactor;
            }

            return(Mathf.RoundToInt(warmupTicksFloat));
        }
コード例 #9
0
 public static CompMannable GetMannable(this Building_Turret turret)
 {
     if (turret is Building_TurretGunCE ceturret)
     {
         return(ceturret.MannableComp);
     }
     return(turret.TryGetComp <CompMannable>());
 }
コード例 #10
0
 static bool Prefix(TurretTop __instance, Building_Turret ___parentTurret)
 {
     if (___parentTurret.GetComp <CompMountable>() is CompMountable comp && comp.Active && !___parentTurret.CurrentTarget.IsValid)
     {
         return(false);
     }
     return(true);
 }
コード例 #11
0
 private static float TurretTopDrawSizeToUse(float original, Building_Turret turret)
 {
     if (turret.IsUpgraded(out CompUpgradable upgradableComp) && upgradableComp.Props.turretTopDrawSize != -1)
     {
         return(upgradableComp.Props.turretTopDrawSize);
     }
     return(original);
 }
コード例 #12
0
 public static void Postfix(Building_Turret __instance, ref float __result)
 {
     // Set to 0 if turret is manned
     if (__instance.TryGetComp <CompMannable>() is CompMannable mannableComp && mannableComp.MannedNow)
     {
         __result = 0;
     }
 }
コード例 #13
0
 private static Vector2 TurretTopOffsetToUse(Vector2 original, Building_Turret turret)
 {
     if (turret.IsUpgraded(out CompUpgradable uC) && uC.Props.turretTopOffset != null)
     {
         return(uC.Props.turretTopOffset);
     }
     return(original);
 }
コード例 #14
0
 public static Thing FirstShieldInRange(this Building_Turret turret)
 {
     return(SHIELDS.FirstOrDefault(p =>
                                   p.First.Map == turret.Map && p.First.Position.InHorDistOf(turret.Position,
                                                                                             turret.AttackVerb.verbProps.range) &&
                                   p.Second.Active &&
                                   p.Second.Props.interceptAirProjectiles).First);
 }
コード例 #15
0
 public static bool Prefix(Building_Turret ___parentTurret)
 {
     // Don't draw the turret top if the turret is retracted
     if (___parentTurret.IsSubmersible(out CompSubmersible retractableComp) && retractableComp.Submerged)
     {
         return(false);
     }
     return(true);
 }
コード例 #16
0
        static bool Prefix(TurretTop __instance)
        {
            Building_Turret parentTurret = Traverse.Create(__instance).Field("parentTurret").GetValue <Building_Turret>();

            if (parentTurret.GetComp <CompMountable>() is CompMountable comp && comp.Active && !parentTurret.CurrentTarget.IsValid)
            {
                return(false);
            }
            return(true);
        }
コード例 #17
0
 public static void IgnoreShoulderTurret(Building_Turret __instance, ref bool __result, IAttackTargetSearcher disabledFor)
 {
     if (__instance != null)
     {
         if (__instance.GetType() == typeof(Building_Turret_Shoulder))
         {
             __result = true;
         }
     }
 }
コード例 #18
0
        public static bool ShouldReload(this Building_Turret turret, float threshold = 0.5f, bool ensureAmmoType = true)
        {
            var ammo = turret.GetAmmo();

            if (ammo == null)
            {
                return(false);
            }
            return((ammo.HasMagazine && ammo.CurMagCount <= ammo.Props.magazineSize * threshold) || (ensureAmmoType && ammo.CurrentAmmo != ammo.SelectedAmmo));
        }
コード例 #19
0
        private static bool ShouldApply(StatRequest req, out Building_Turret turret)
        {
            turret = null;
            if (req.Thing is Pawn pawn)
            {
                turret = pawn.MannedThing() as Building_Turret;
            }

            return(turret != null);
        }
コード例 #20
0
        public static bool AffectedByEMP(this Building_Turret turret)
        {
            // If turret is upgraded and affectedByEMP is defined, return upgradeComp' affectedByEMP
            if (turret.IsUpgraded(out var upgradableComp) && upgradableComp.Props.affectedByEMP.HasValue)
            {
                return(upgradableComp.Props.affectedByEMP.Value);
            }

            // Otherwise return the DefModExtension's value
            return(TurretFrameworkExtension.Get(turret.def).affectedByEMP);
        }
コード例 #21
0
        private static Job MakeReloadJobNoAmmo(Building_Turret turret)
        {
            var compAmmo = turret.GetAmmo();

            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));
        }
コード例 #22
0
        //Checks before called (ONLY when in SCANNER):
        // - PawnCanUseWorkGiver(pawn, this)
        //      - nonColonistCanDo || isColonist
        //      - !WorkTagIsDisabled(def.workTags)
        //      - !ShouldSkip(pawn, false)
        //      - MissingRequiredCapacity(pawn) == null
        // - !t.IsForbidden(pawn)
        // - this.PotentialWorkThingRequest.Accepts(t),
        /// <summary>
        /// Called after HasJobOnThing by WorkGiver_Scanner, or by Building_TurretGunCE when turret tryReload with manningPawn
        /// </summary>
        /// <param name="pawn"></param>
        /// <param name="t"></param>
        /// <param name="forced"></param>
        /// <returns></returns>
        public override Job JobOnThing(Pawn pawn, Thing t, bool forced = false)
        {
            Building_Turret turret = t as Building_Turret;

            if (turret == null)
            {
                CELogger.Error($"{pawn} tried to make a reload job on a {t} which isn't a turret. This should never be reached.");
            }

            // NOTE: The removal of the code that used to be here disables reloading turrets directly from one's inventory.
            // The player would need to drop the ammo the pawn is holding first.

            return(JobGiverUtils_Reload.MakeReloadJob(pawn, turret));
        }
コード例 #23
0
 public static Thing GetGun(this Building_Turret turret)
 {
     if (turret is Building_TurretGunCE ceturret)
     {
         return(ceturret.Gun);
     }
     if (enabled)
     {
         GetGunFunction gfunc;
         if (getGun.TryGetValue(turret.GetType(), out gfunc))
         {
             return(gfunc(turret));
         }
     }
     CELogger.Warn("Asked to get gun on an unknown turret type: " + turret);
     return(null);
 }
コード例 #24
0
        /// <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_Turret reloadable)
        {
            var compAmmo = reloadable.GetAmmo();
            int quantity = compAmmo.MissingToFullMagazine;
            var ammoKind = 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);
        }
コード例 #25
0
 public static bool GetReloading(this Building_Turret turret)
 {
     if (turret is Building_TurretGunCE ceturret)
     {
         return(ceturret.isReloading);
     }
     if (enabled)
     {
         GetReloadingFunction func;
         if (getReloading.TryGetValue(turret.GetType(), out func))
         {
             return(func(turret));
         }
     }
     CELogger.Warn("Asked to get reloading on an unknown turret type: " + turret);
     return(false);
 }
コード例 #26
0
 public static void SetReloading(this Building_Turret turret, bool reloading)
 {
     if (turret is Building_TurretGunCE ceturret)
     {
         ceturret.isReloading = reloading;
         return;
     }
     if (enabled)
     {
         SetReloadingFunction func;
         if (setReloading.TryGetValue(turret.GetType(), out func))
         {
             func(turret, reloading);
             return;
         }
     }
     CELogger.Warn("Asked to set reloading on an unknown turret type: " + turret);
 }
コード例 #27
0
        public static void TryOrderReload(this Building_Turret turret, bool forced = false)
        {
            if (turret is Building_TurretGunCE ceturret)
            {
                ceturret.TryOrderReload(forced);;
                return;
            }
            var compAmmo = turret.GetAmmo();

            if ((compAmmo.CurrentAmmo == compAmmo.SelectedAmmo && (!compAmmo.HasMagazine || compAmmo.CurMagCount == compAmmo.Props.magazineSize)))
            {
                return;
            }
            var mannableComp = turret.GetMannable();

            if (!mannableComp?.MannedNow ?? true)
            {
                return;
            }

            //Only have manningPawn reload after a long time of no firing
            if (!forced && compAmmo.CurMagCount != 0)
            {
                return;
            }

            //Already reserved for manning
            Pawn manningPawn = mannableComp.ManningPawn;

            if (manningPawn != null)
            {
                if (!JobGiverUtils_Reload.CanReload(manningPawn, turret))
                {
                    return;
                }
                var jobOnThing = JobGiverUtils_Reload.MakeReloadJob(manningPawn, turret);

                if (jobOnThing != null)
                {
                    manningPawn.jobs.StartJob(jobOnThing, JobCondition.Ongoing, null, manningPawn.CurJob?.def != CE_JobDefOf.ReloadTurret);
                }
            }
        }
コード例 #28
0
        public static bool TryFindNewTarget(Building_TurretGun __instance, ref LocalTargetInfo __result)
        {
            Building_Turret       building_Turret      = __instance;
            IAttackTargetSearcher attackTargetSearcher = TargSearcher(__instance);
            Faction faction = attackTargetSearcher.Thing.Faction;
            float   range   = __instance.AttackVerb.verbProps.range;

            if (Rand.Value < 0.5f && __instance.AttackVerb.ProjectileFliesOverhead() && faction.HostileTo(Faction.OfPlayer) &&
                building_Turret.Map.listerBuildings.allBuildingsColonist.Where(delegate(Building x)
            {
                float num = __instance.AttackVerb.verbProps.EffectiveMinRange(x, __instance);
                float num2 = x.Position.DistanceToSquared(building_Turret.Position);
                return(num2 > num * num && num2 < range * range);
            }).TryRandomElement(out Building result))
            {
                __result = result;
                return(false);
            }

            TargetScanFlags targetScanFlags = TargetScanFlags.NeedThreat | TargetScanFlags.NeedAutoTargetable;

            if (!__instance.AttackVerb.ProjectileFliesOverhead())
            {
                targetScanFlags |= TargetScanFlags.NeedLOSToAll;
                targetScanFlags |= TargetScanFlags.LOSBlockableByGas;
            }

            if (__instance.AttackVerb.IsIncendiary())
            {
                targetScanFlags |= TargetScanFlags.NeedNonBurning;
            }

            if (IsMortar(__instance))
            {
                targetScanFlags |= TargetScanFlags.NeedNotUnderThickRoof;
            }

            //return (Thing)AttackTargetFinder.BestShootTargetFromCurrentPosition(attackTargetSearcher, targetScanFlags, IsValidTarget);
            __result = null;
            return(false);
        }
コード例 #29
0
 public bool ExternalViolenceFor(Thing thing)
 {
     if (this.externalViolence)
     {
         return(true);
     }
     if (this.externalViolenceForMechanoids)
     {
         Pawn pawn = thing as Pawn;
         if (pawn != null && pawn.RaceProps.IsMechanoid)
         {
             return(true);
         }
         Building_Turret building_Turret = thing as Building_Turret;
         if (building_Turret != null)
         {
             return(true);
         }
     }
     return(false);
 }
コード例 #30
0
        public static Building_Turret FindTurretFor(Pawn p)
        {
            Predicate <Thing> turretValidator = delegate(Thing t)
            {
                Building_TurretGun building_Turret3 = (Building_TurretGun)t;
                if (!p.CanReserveAndReach(t, PathEndMode.OnCell, Danger.Some))
                {
                    return(false);
                }
                return(building_Turret3.GetComp <CompFlickable>().SwitchIsOn&& !building_Turret3.IsBurning());
            };
            ThingDef          thingDef         = ThingDefOf.TurretGun;
            Predicate <Thing> validator        = (Thing b) => turretValidator(b);
            Building_Turret   building_Turret2 = (Building_Turret)GenClosest.ClosestThingReachable(p.Position, p.Map, ThingRequest.ForDef(thingDef), PathEndMode.OnCell, TraverseParms.For(p, Danger.Deadly, TraverseMode.ByPawn, false), 9999f, validator, null, -1, false);

            if (building_Turret2 != null)
            {
                return(building_Turret2);
            }
            return(null);
        }