private float GetThingPriority(Pawn pawn, Thing t, bool forced = false)
        {
            Building_TurretGunCE turret = t as Building_TurretGunCE;

            if (pawn == null)
            {
                //Log.Message("Checking " + turret.ThingID + ", found pawn == null");
                return(0f);
            }
            if (turret == null || turret.IsForbidden(pawn) || !Checks(pawn, turret, forced))
            {
                return(0f);
            }

            if (!turret.Active)
            {
                return(1f);
            }
            if (turret.EmptyMagazine)
            {
                return(9f);
            }
            if (turret.AutoReloadableMagazine)
            {
                return(5f);
            }
            return(1f);
        }
Exemple #2
0
        public override bool HasJobOnThing(Pawn pawn, Thing t, bool forced = false)
        {
            Building_TurretGunCE turret = t as Building_TurretGunCE;

            if (turret == null || (!forced && !turret.AllowAutomaticReload))
            {
                return(false);
            }

            if (!turret.NeedsReload ||
                !pawn.CanReserveAndReach(turret, PathEndMode.ClosestTouch, Danger.Deadly) ||
                turret.IsForbidden(pawn.Faction))
            {
                return(false);
            }
            if (!turret.CompAmmo.UseAmmo)
            {
                return(true);
            }
            Thing ammo = GenClosest.ClosestThingReachable(pawn.Position, pawn.Map,
                                                          ThingRequest.ForDef(turret.CompAmmo.SelectedAmmo),
                                                          PathEndMode.ClosestTouch,
                                                          TraverseParms.For(pawn, Danger.Deadly, TraverseMode.ByPawn),
                                                          80,
                                                          x => !x.IsForbidden(pawn) && pawn.CanReserve(x));

            return(ammo != null);
        }
        public Pawn BestNonJobUser(IEnumerable <Pawn> pawns, Building_TurretGunCE turret, out bool fromInventory, bool forced = false)
        {
            fromInventory = false;

            if (!pawns.Any())
            {
                return(null);
            }

            //Cut a significant portion of pawns
            pawns = pawns.Where(p => !ShouldSkip(p) && !p.Downed && !p.Dead && p.Spawned && (p.mindState?.Active ?? true) &&
                                (!p.mindState?.mentalStateHandler?.InMentalState ?? true) && !turret.IsForbidden(p) &&
                                (turret.Faction == p.Faction || turret.Faction?.RelationKindWith(p.Faction) == FactionRelationKind.Ally) &&
                                p.CanReserveAndReach(new LocalTargetInfo(turret), PathEndMode.InteractionCell, forced ? Danger.Deadly : p.NormalMaxDanger(), GenClosestAmmo.pawnsPerTurret, -1, null, forced));

            //No pawns remaining => quit
            if (!pawns.Any())
            {
                return(null);
            }

            //If no ammo is used, minimize distance
            if (!turret.CompAmmo?.UseAmmo ?? true)
            {
                return(pawns.MinBy(x => x.Position.DistanceTo(turret.Position)));
            }

            //ELSE: ammo is used, pawns remain
            turret.UpdateNearbyAmmo(forced);
            var hasNearbyAmmo = turret.nearestViableAmmo != null;

            int amount = turret.CompAmmo.Props.magazineSize;

            if (turret.CompAmmo.CurrentAmmo == turret.CompAmmo.SelectedAmmo)
            {
                amount -= turret.CompAmmo.CurMagCount;
            }

            if (hasNearbyAmmo)
            {
                pawns = pawns.OrderBy(x => x.Position.DistanceTo(turret.Position));
            }

            var  bestNonInventoryDistance = 9999f;
            Pawn bestPawn        = null;
            var  minimumDistance = hasNearbyAmmo ? turret.Position.DistanceTo(turret.nearestViableAmmo.Position) : 0f;

            //Sort through ASCENDING DISTANCE TO TURRET -- e.g, inventory ammo is preferred
            foreach (var p in pawns)
            {
                if (PawnClosestAmmo(p, turret, out fromInventory, forced) == null)
                {
                    continue;
                }

                if (fromInventory)
                {
                    if (p.Position.DistanceTo(turret.Position) < bestNonInventoryDistance + minimumDistance)
                    {
                        return(p);
                    }
                }
                else if (hasNearbyAmmo)
                {
                    var dist = p.Position.DistanceTo(turret.nearestViableAmmo.Position);

                    if (dist < bestNonInventoryDistance)
                    {
                        bestNonInventoryDistance = dist;
                        bestPawn = p;
                    }
                }
            }

            fromInventory = false;
            return(bestPawn);
        }