Skip to content

Commit

Permalink
#691 fixed Distance Issue for Food
Browse files Browse the repository at this point in the history
  • Loading branch information
Sn1p3rr3c0n committed Mar 12, 2023
1 parent f4c6dc1 commit 558f09d
Show file tree
Hide file tree
Showing 4 changed files with 108 additions and 52 deletions.
14 changes: 8 additions & 6 deletions Source/ProjectRimFactory/Common/ConditionalPatchHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ public static class ConditionalPatchHelper
{
public class TogglePatch
{
private bool Patched = false;
private bool patched = false;
public bool Status => patched;

private readonly MethodInfo base_m;
private readonly HarmonyMethod trans_hm = null;
Expand All @@ -35,17 +36,17 @@ public TogglePatch(MethodInfo base_method, MethodInfo prefix = null, MethodInfo

public void PatchHandler(bool patch)
{
if (patch && !Patched)
if (patch && !patched)
{
harmony_instance.Patch(base_m, pre_hm, post_hm, trans_hm);
Patched = true;
patched = true;
}
else if (Patched && !patch)
else if (patched && !patch)
{
if (trans_m != null) harmony_instance.Unpatch(base_m, trans_m);
if (pre_m != null) harmony_instance.Unpatch(base_m, pre_m);
if (post_m != null) harmony_instance.Unpatch(base_m, post_m);
Patched = false;
patched = false;
}
}

Expand All @@ -56,7 +57,8 @@ public void PatchHandler(bool patch)

public static TogglePatch Patch_Reachability_CanReach = new TogglePatch(
AccessTools.Method(typeof(Verse.Reachability), "CanReach", new Type[] { typeof(IntVec3), typeof(LocalTargetInfo), typeof(PathEndMode), typeof(TraverseParms) }),
AccessTools.Method(typeof(ProjectRimFactory.Common.HarmonyPatches.Patch_Reachability_CanReach), "Prefix")
null,
AccessTools.Method(typeof(ProjectRimFactory.Common.HarmonyPatches.Patch_Reachability_CanReach), "Postfix")
);

public static TogglePatch Patch_WealthWatcher_CalculateWealthItems = new TogglePatch(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,10 +49,11 @@ static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> inst

yield return new CodeInstruction(OpCodes.Ldloca_S, instruction.operand);
yield return new CodeInstruction(OpCodes.Ldloc_S, Thingarg);

yield return new CodeInstruction(OpCodes.Ldarg_0);
yield return new CodeInstruction(OpCodes.Ldarg_1);
yield return new CodeInstruction(OpCodes.Call, AccessTools.Method(
typeof(Patch_FoodUtility_SpawnedFoodSearchInnerScan),
nameof(Patch_FoodUtility_SpawnedFoodSearchInnerScan.isCanIOPortGetItem), new[] { typeof(float).MakeByRefType(), typeof(Thing) }));
nameof(Patch_FoodUtility_SpawnedFoodSearchInnerScan.isIOPortBetter), new[] { typeof(float).MakeByRefType(), typeof(Thing), typeof(Pawn), typeof(IntVec3) }));
continue;
}

Expand Down Expand Up @@ -84,7 +85,7 @@ public static void findClosestPort(Pawn pawn, IntVec3 root)

if (pawn.Faction == null || !pawn.Faction.IsPlayer) return;

//Not Optimal for the search. might need update
//TODO: Not Optimal for the search. might need update
var closest = AdvancedIO_PatchHelper.GetClosestPort(pawn.Map, pawn.Position);
mindist = closest.Key;
closestPort = closest.Value;
Expand All @@ -94,38 +95,37 @@ public static void findClosestPort(Pawn pawn, IntVec3 root)
private static Thing ioPortSelectedFor = null;


public static void isCanIOPortGetItem(ref float Distance, Thing thing)
/// <summary>
/// Checks if the IO Port is a better or the only Option
/// </summary>
/// <param name="Distance"></param>
/// <param name="thing"></param>
public static void isIOPortBetter(ref float Distance, Thing thing, Pawn pawn, IntVec3 start)
{
ioPortSelected = false;
if (mindist < Distance && closestPort != null && ((AdvancedIO_PatchHelper.CanMoveItem(closestPort, thing))))
{
Distance = mindist;
ioPortSelected = true;
ioPortSelectedFor = thing;

//If the Port is Closer then it is a better choice
//#691 If the Port is the only Option it must be used
if ( mindist < Distance || (ConditionalPatchHelper.Patch_Reachability_CanReach.Status && pawn.Map.reachability.CanReach(start,thing,Verse.AI.PathEndMode.Touch, TraverseParms.For(pawn)) && Patch_Reachability_CanReach.CanReachThing(thing) ))
{
//Check if the Port can be used
//TODO: Check TODO in Line 88
if (closestPort != null && AdvancedIO_PatchHelper.CanMoveItem(closestPort, thing))
{
Distance = mindist;
ioPortSelected = true;
ioPortSelectedFor = thing;
}
}
}

public static void moveItemIfNeeded(Thing thing)
{
//When using replimat it might replace thing
if (thing != ioPortSelectedFor)
{
return;
}
if (ioPortSelected && thing != null)
{
ioPortSelected = false;
try
{
thing.Position = closestPort.Position;
}
catch (NullReferenceException)
{
Log.Message($"moveItemIfNeeded NullReferenceException - {thing} - {closestPort}");
}

}
if (thing != ioPortSelectedFor || !ioPortSelected || thing == null) return;

ioPortSelected = false;
closestPort.PlaceThingNow(thing);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,29 +7,78 @@ namespace ProjectRimFactory.Common.HarmonyPatches
//Managed by ConditionalPatchHelper.Update_Patch_Reachability_CanReach
class Patch_Reachability_CanReach
{
public static bool Prefix(IntVec3 start, LocalTargetInfo dest, PathEndMode peMode, TraverseParms traverseParams, out bool __result, Map ___map, Reachability __instance)
//canReachThing Holds the Last item that was checked and Required the use of a Advanced IO Port
//This is used in other patches to force the use of an IO Port
private static Thing canReachThing =null;
public static bool CanReachThing(Thing thing)
{
__result = false;
if (dest.Thing == null || dest.Thing.def.category != ThingCategory.Item) return true;
var ret = thing == canReachThing;
canReachThing = null;
return ret;
}

/// <summary>
/// This Patch allows Pawns to receive Items from a Advanced IO Port when the direct Path to the DSU(current Item Location) is Blocked
/// This Patch has a noticeable Performance Impact and shall only be use if the Path is Blocked
/// </summary>
/// <param name="start"></param>
/// <param name="dest"></param>
/// <param name="peMode"></param>
/// <param name="traverseParams"></param>
/// <param name="__result"></param>
/// <param name="___map"></param>
/// <param name="__instance"></param>
public static void Postfix(IntVec3 start, LocalTargetInfo dest, PathEndMode peMode, TraverseParms traverseParams, ref bool __result, Map ___map, Reachability __instance)
{
//There is already a Path
if (__result) return;

var thing = dest.Thing;


//Ignore everything that is not a Item
if (thing == null || thing.def.category != ThingCategory.Item) return;

//Quickly get the Map Component (abort if nonexistent)
var mapcomp = PatchStorageUtil.GetPRFMapComponent(___map);
if (mapcomp == null) return true;
//Not optimal lets correct that later
var ThingPos = dest.Thing.Position;
if (mapcomp.ShouldHideItemsAtPos(ThingPos))
if (mapcomp == null) return;

//Is in a DSU
if (hasPathToItem(thing,mapcomp,__instance,start,traverseParams))
{
//Is in a DSU
var pathToIO = mapcomp.GetadvancedIOLocations.Where(p => p.Value.boundStorageUnit?.GetPosition == ThingPos && __instance.CanReach(start, p.Key, PathEndMode.Touch, traverseParams)).Any();
if (pathToIO)
{
__result = true;
return false;
}
canReachThing = thing;
__result = true;
}
}

//I think i need to rework how, what and where stuff is save for event caching

private static bool hasPathToItem(Thing thing, PRFMapComponent mapComp, Reachability reachability, IntVec3 start, TraverseParms traverseParams)
{
var ThingPos = thing.Position;

return true;
}
//Quickly Check if the Item is in a Storage Unit
//TODO: Rework that -> This includes items in PRF Crates & Excludes items from Cold Storage(Note they currently have bigger issues)
if (!mapComp.ShouldHideItemsAtPos(ThingPos)) return false;

var AdvancedIOLocations = mapComp.GetadvancedIOLocations;
var cnt = AdvancedIOLocations.Count;
//Check Every Advanced IO Port
for (int i = 0; i < cnt; i++)
{
var current = AdvancedIOLocations.ElementAt(i);

//Check if that Port has access to the Item
//TODO: Rework that -> Is the Use of the Position really best?
if (current.Value.boundStorageUnit?.GetPosition == ThingPos)
{
//The Port has access to the Item
//Now check if we can reach that Port
if (reachability.CanReach(start, current.Key, PathEndMode.Touch, traverseParams)) return true;
}
}

return false;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -68,14 +68,19 @@ private void updateQueue()
if (CanGetNewItem && placementQueue.Count > 0)
{
var nextItemInQueue = placementQueue[0];
if (nextItemInQueue != null)
{
placementQueue[0].Position = this.Position;
}
PlaceThingNow(nextItemInQueue);
placementQueue.RemoveAt(0);
}
}

public void PlaceThingNow(Thing thing)
{
if (thing != null)
{
thing.Position = this.Position;
}
}

public override void Tick()
{
updateQueue();
Expand Down

0 comments on commit 558f09d

Please sign in to comment.