[SOLVED] Finding Closest Mineable Rock

Started by Viceroy, January 04, 2016, 04:10:00 PM

Previous topic - Next topic

Viceroy

Hello all, I am working on getting my mod Horrors back up and running, however there is one hurdle in the way presently:

Previously I could locate the closest rock to my digger using this code:

public static Thing ClosestRock(Pawn digger, float rockSearchRadius)
        {
            Predicate<Thing> validator = delegate(Thing t)
            {
                Building building = t as Building;
                if (t.def.eType != EntityType.Rock)
                {
                    return false;
                }

                return (building.Position.CanReach(digger.Position, PathMode.Touch, TraverseMode.NoPassDoors, Danger.Some) && RockAttackUtility.IsGoodTrashTargetFor(t, digger));
                // return (caccoonBuilding.Position.CanReach(kidnapper.Position, PathMode.OnCell, TraverseMode.NoPassDoors, Danger.Some) && caccoonBuilding.container.Empty && ReservationUtility.CanReserve(kidnapper, caccoonBuilding, ReservationType.Use));
            };
            return (Building)GenClosest.ClosestThingReachable(digger.Position, ThingRequest.ForGroup(ThingRequestGroup.Building), PathMode.Touch, TraverseParms.For(digger, Danger.Deadly, true), rockSearchRadius, validator, null, -1);
        }
    }


However, since the update, I no longer have a 'ThingRequestGroup.Building', it only describes items that are Artificial in nature and such. And the ThingRequestGroup is an enumerated integer that I cannot (Or don't know how to) alter.

So I tried everything I could think of on that approach, failed, and retook arms from another front, namely I looked at the 'JobGiver_Manhunter' code to determine how it targets turrets, the code is as follows (abridged):

private Thing FindTurretTarget(Pawn pawn)
{
return AttackTargetFinder.BestAttackTarget(pawn, (Thing t) => t is Building, 70f, 0f, TargetScanFlags.NeedLOSToPawns | TargetScanFlags.NeedLOSToNonPawns | TargetScanFlags.NeedReachable | TargetScanFlags.OnlyTargetCombatBuildings, default(IntVec3), 3.40282347E+38f);
}


But if I use that code to find a target I am running into another problem... It has to be hostile. So I dropped the 'TargetScanFlags.OnlyTargetCombatBuildings' flag in the hopes that it will work, but the class still has a check for hostility...

So I copied the class and created my own version where I merely removed the 'isHostile' check... But no joy.

Anyone have any suggestions regarding a possible way to approach this?

Thank you to anyone willing to read my issue and those whom reply, beforehand.
Dog goes moo!

Viceroy

Okay so I went back to the first approach and tweaked it to check for defs and not for request groups.


private Thing FindRockTarget(Pawn pawn)
{
            Predicate<Thing> validator = delegate(Thing t)
            {
                Building building = t as Building;
                if (!t.def.mineable)
                {
                    return false;
                }

                return (building.Position.CanReach(pawn.Position, PathEndMode.Touch, TraverseMode.NoPassClosedDoors, Danger.Deadly) && HiveUtility.IsInHive(t));
              };

            Thing thingToReturn;
            thingToReturn = GenClosest.ClosestThingReachable(pawn.Position, ThingRequest.ForDef(ThingDef.Named("Sandstone")), PathEndMode.Touch, TraverseParms.For(pawn), 30f, validator, null, -1);
            if (thingToReturn != null)
            {
                return GenClosest.ClosestThingReachable(pawn.Position, ThingRequest.ForDef(ThingDef.Named("Sandstone")), PathEndMode.Touch, TraverseParms.For(pawn), 30f, validator, null, -1);
            }
            thingToReturn = GenClosest.ClosestThingReachable(pawn.Position, ThingRequest.ForDef(ThingDef.Named("Marble")), PathEndMode.Touch, TraverseParms.For(pawn), 30f, validator, null, -1);
            if (thingToReturn != null)
            {
                return GenClosest.ClosestThingReachable(pawn.Position, ThingRequest.ForDef(ThingDef.Named("Marble")), PathEndMode.Touch, TraverseParms.For(pawn), 30f, validator, null, -1);
            }
            thingToReturn = GenClosest.ClosestThingReachable(pawn.Position, ThingRequest.ForDef(ThingDef.Named("Granite")), PathEndMode.Touch, TraverseParms.For(pawn), 30f, validator, null, -1);
            if (thingToReturn != null)
            {
                return GenClosest.ClosestThingReachable(pawn.Position, ThingRequest.ForDef(ThingDef.Named("Granite")), PathEndMode.Touch, TraverseParms.For(pawn), 30f, validator, null, -1);
            }
            thingToReturn = GenClosest.ClosestThingReachable(pawn.Position, ThingRequest.ForDef(ThingDef.Named("Limestone")), PathEndMode.Touch, TraverseParms.For(pawn), 30f, validator, null, -1);
            if (thingToReturn != null)
            {
                return GenClosest.ClosestThingReachable(pawn.Position, ThingRequest.ForDef(ThingDef.Named("Limestone")), PathEndMode.Touch, TraverseParms.For(pawn), 30f, validator, null, -1);
            }
            thingToReturn = GenClosest.ClosestThingReachable(pawn.Position, ThingRequest.ForDef(ThingDef.Named("Slate")), PathEndMode.Touch, TraverseParms.For(pawn), 30f, validator, null, -1);
            if (thingToReturn != null)
            {
                return GenClosest.ClosestThingReachable(pawn.Position, ThingRequest.ForDef(ThingDef.Named("Slate")), PathEndMode.Touch, TraverseParms.For(pawn), 30f, validator, null, -1);
            }
            thingToReturn = GenClosest.ClosestThingReachable(pawn.Position, ThingRequest.ForDef(ThingDef.Named("Wall")), PathEndMode.Touch, TraverseParms.For(pawn), 30f, validator, null, -1);
            return null;
        }


Not elegant, probably slower than the previous solution. But at least it works!

;D
Dog goes moo!