Example #1
0
        public static Thing ClosestPowerSource(Pawn pawn)
        {
            Thing closestPowerSource =
                GenClosest.ClosestThingReachable(
                    pawn.Position, pawn.Map, ThingRequest.ForGroup(ThingRequestGroup.BuildingArtificial), PathEndMode.ClosestTouch, TraverseParms.For(pawn), 9999f,
                    thing => EnergyNeedUtility.BestClosestPowerSource(pawn, thing));

            return(closestPowerSource);
        }
Example #2
0
        protected override Job TryGiveJob(Pawn pawn)
        {
            if (pawn.Downed)
            {
                return(null);
            }

            Need_Energy energy = pawn.needs.TryGetNeed <Need_Energy>();

            if (energy == null)
            {
                return(null);
            }

            if (energy.CurLevelPercentage >= Need_Energy.rechargePercentage)
            {
                return(null);
            }

            if (Find.TickManager.TicksGame < GetLastTryTick(pawn) + 2500)
            {
                return(null);
            }
            SetLastTryTick(pawn, Find.TickManager.TicksGame);

            //See if we got a nearby powernet to tap into.
            Thing closestPowerSource = EnergyNeedUtility.ClosestPowerSource(pawn);

            if (closestPowerSource != null)
            {
                Building building = closestPowerSource as Building;
                if (closestPowerSource != null && building != null && building.PowerComp != null && building.PowerComp.PowerNet.CurrentStoredEnergy() > 50f)
                {
                    //Find a suitable spot to drain from.
                    IntVec3 drainSpot = closestPowerSource.Position;

                    //Give out job to go out and tap it.
                    if (drainSpot.Walkable(pawn.Map) && drainSpot.InAllowedArea(pawn) && pawn.CanReserve(new LocalTargetInfo(drainSpot)) && pawn.CanReach(drainSpot, PathEndMode.OnCell, Danger.Deadly))
                    {
                        return(new Job(JobDefOf.ChJAndroidRecharge, closestPowerSource));
                    }

                    //Check surrounding cells.
                    foreach (IntVec3 adjCell in GenAdj.CellsAdjacentCardinal(building).OrderByDescending(selector => selector.DistanceTo(pawn.Position)))
                    {
                        if (adjCell.Walkable(pawn.Map) && adjCell.InAllowedArea(pawn) && pawn.CanReserve(new LocalTargetInfo(adjCell)) && pawn.CanReach(adjCell, PathEndMode.OnCell, Danger.Deadly))
                        {
                            return(new Job(JobDefOf.ChJAndroidRecharge, closestPowerSource, adjCell));
                        }
                    }
                }
            }

            //No power source? Try looking for a consumable resource.

            //In the inventory. (Or being carried)
            if (pawn.carryTracker is Pawn_CarryTracker carryTracker && carryTracker.CarriedThing is Thing carriedThing && carriedThing.TryGetComp <EnergySourceComp>() is EnergySourceComp carriedThingComp && carriedThingComp.EnergyProps.isConsumable)
            {
                if (carriedThing.stackCount > 0)
                {
                    return(new Job(JobDefOf.ChJAndroidRechargeEnergyComp, new LocalTargetInfo(carriedThing))
                    {
                        count = carriedThing.stackCount
                    });
                }
            }
            if (pawn.inventory is Pawn_InventoryTracker inventory && inventory.innerContainer.Any(thing => thing.TryGetComp <EnergySourceComp>() is EnergySourceComp comp && comp.EnergyProps.isConsumable))
            {
                Thing validEnergySource =
                    inventory.innerContainer.FirstOrDefault(
                        thing =>
                        thing.TryGetComp <EnergySourceComp>() is EnergySourceComp energySource &&
                        energySource.EnergyProps.isConsumable
                        );
                if (validEnergySource != null)
                {
                    //Use enough to get satisfied.
                    EnergySourceComp energySourceComp = validEnergySource.TryGetComp <EnergySourceComp>();

                    int thingCount = (int)Math.Ceiling((energy.MaxLevel - energy.CurLevel) / energySourceComp.EnergyProps.energyWhenConsumed);
                    thingCount = Math.Min(thingCount, validEnergySource.stackCount);

                    if (thingCount > 0)
                    {
                        return(new Job(JobDefOf.ChJAndroidRechargeEnergyComp, new LocalTargetInfo(validEnergySource))
                        {
                            count = thingCount
                        });
                    }
                }
            }

            //On the map.
            Thing closestConsumablePowerSource =
                GenClosest.ClosestThingReachable(
                    pawn.Position, pawn.Map, ThingRequest.ForGroup(ThingRequestGroup.HaulableEver), PathEndMode.OnCell, TraverseParms.For(pawn), 9999f,
                    thing => thing.TryGetComp <EnergySourceComp>() != null && !thing.IsForbidden(pawn) && pawn.CanReserve(new LocalTargetInfo(thing)) && thing.Position.InAllowedArea(pawn) && pawn.CanReach(new LocalTargetInfo(thing), PathEndMode.OnCell, Danger.Deadly));

            if (closestConsumablePowerSource != null)
            {
                EnergySourceComp energySourceComp = closestConsumablePowerSource.TryGetComp <EnergySourceComp>();
                if (energySourceComp != null)
                {
                    int thingCount = (int)Math.Ceiling((energy.MaxLevel - energy.CurLevel) / energySourceComp.EnergyProps.energyWhenConsumed);
                    if (thingCount > 0)
                    {
                        return(new Job(JobDefOf.ChJAndroidRechargeEnergyComp, new LocalTargetInfo(closestConsumablePowerSource))
                        {
                            count = thingCount
                        });
                    }
                }
            }

            return(null);
        }