Skip to content

Commit

Permalink
Update to 0.18.1.4
Browse files Browse the repository at this point in the history
- It's now possible to kill Wandering Caravans.
- Fixed a nasty bug with ridiculously long queues.
- Bit of a code cleanup.
- Reduced stack fragmentation caused by picking up partial stacks when the colonist could've picked up more.
  • Loading branch information
Mehni committed Feb 3, 2018
1 parent 77aea76 commit f3da6d7
Show file tree
Hide file tree
Showing 9 changed files with 84 additions and 118 deletions.
2 changes: 1 addition & 1 deletion About/About.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
<url>https://ludeon.com/forums/index.php?topic=35832</url>
<description>"Greatest hauling mod ever" - Chicken Plucker

v0.18.1.3
v0.18.1.4

Colonists will gather stuff in their inventory, then haul it all to a stockpile.

Expand Down
Binary file modified Assemblies/PickUpAndHaul.dll
Binary file not shown.
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ public HashSet<Thing> GetHashSet()

public void RegisterHauledItem(Thing thing)
{
this.TakenToInventory.Add(thing);
this.TakenToInventory.Add(thing);
}

public override void PostExposeData()
Expand Down
19 changes: 11 additions & 8 deletions Source/PickUpAndHaul/PickUpAndHaul/HarmonyPatches.cs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ static HarmonyPatches()
new HarmonyMethod(typeof(HarmonyPatches), nameof(IdleJoy_Postfix)), null);

if (ModCompatibilityCheck.KnownConflict) Log.Message("Pick Up And Haul has found a conflicting mod and will lay dormant.");
if (!ModCompatibilityCheck.KnownConflict) Log.Message("PickUpAndHaul v0.18.1.3 welcomes you to RimWorld with pointless logspam.");
else Log.Message("PickUpAndHaul v0.18.1.4 welcomes you to RimWorld with pointless logspam.");
}

private static bool Drop_Prefix(ref Pawn pawn, ref Thing thing)
Expand Down Expand Up @@ -68,18 +68,22 @@ private static void Pawn_InventoryTracker_PostFix(Pawn_InventoryTracker __instan
Log.Warning(__instance.pawn + " cannot Pick Up and Haul. Does not inherit from BasePawn. Patch failed or mod incompatibility.");
return;
}

HashSet<Thing> carriedThing = takenToInventory.GetHashSet();

if (__instance.pawn.Spawned && __instance.pawn.Faction.IsPlayer) //weird issue with worldpawns and guests
//if (__instance.pawn.Spawned) //weird issue with worldpawns was caused by not having the comp
//{
// if (__instance.pawn.Faction?.IsPlayer ?? false) //roaming muffalo
// {
if (carriedThing?.Count != 0)
{
if (carriedThing?.Count != 0)
if (carriedThing.Contains(item))
{
if (carriedThing.Contains(item))
{
carriedThing.Remove(item);
}
carriedThing.Remove(item);
}
}
// }
//}
}

private static void JobDriver_HaulToCell_PostFix(JobDriver_HaulToCell __instance)
Expand Down Expand Up @@ -145,7 +149,6 @@ public static IEnumerable<CodeInstruction> FloatMenuMakerMad_AddHumanlikeOrders_
// //{ instructionList[i + 5].labels = instruction.labels;}
// instructionList.RemoveRange(i, 5);
// patched = true;

}
yield return instruction;
}
Expand Down
50 changes: 27 additions & 23 deletions Source/PickUpAndHaul/PickUpAndHaul/JobDriver_HaulToInventory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
using Verse.AI;
using System.Diagnostics;
using UnityEngine;
using Verse.Sound;

namespace PickUpAndHaul
{
Expand All @@ -32,7 +31,7 @@ protected override IEnumerable<Toil> MakeNewToils()
{
initAction = () =>
{
this.pawn.pather.StartPath(this.TargetThingA, PathEndMode.ClosestTouch); //thing to change in case of persistent tweener issues. Shouldn't happen though.
this.pawn.pather.StartPath(this.TargetThingA, PathEndMode.ClosestTouch);
},
defaultCompleteMode = ToilCompleteMode.PatherArrival
};
Expand All @@ -46,24 +45,22 @@ protected override IEnumerable<Toil> MakeNewToils()
Pawn actor = this.pawn;
Thing thing = actor.CurJob.GetTarget(TargetIndex.A).Thing;
Toils_Haul.ErrorCheckForCarry(actor, thing);
int num = Mathf.Min(this.job.count, thing.stackCount, MassUtility.CountToPickUpUntilOverEncumbered(actor, thing)); //hauling jobs are stupid and the count is often set to 99999

int num = Mathf.Min(thing.stackCount, MassUtility.CountToPickUpUntilOverEncumbered(actor, thing));
if (num <= 0)
{
Job haul = HaulAIUtility.HaulToStorageJob(actor, thing);
if (haul != null)

if (haul?.TryMakePreToilReservations(actor) ?? false)
{
if (haul.TryMakePreToilReservations(actor))
{
actor.jobs.jobQueue.EnqueueFirst(haul, new JobTag?(JobTag.Misc));
return;
}
actor.jobs.jobQueue.EnqueueFirst(haul, new JobTag?(JobTag.Misc));
}
actor.jobs.curDriver.JumpToToil(wait);
}
else
{
actor.inventory.GetDirectlyHeldThings().TryAdd(thing.SplitOff(num), false);
//Merging and unmerging messes up the picked up ID (which already gets messed up enough)
actor.inventory.GetDirectlyHeldThings().TryAdd(thing.SplitOff(num), false);
takenToInventory.RegisterHauledItem(thing);
}
}
Expand All @@ -72,7 +69,7 @@ protected override IEnumerable<Toil> MakeNewToils()
yield return CheckDuplicateItemsToHaulToInventory(reserveTargetA, TargetIndex.A, false);
yield return wait;
}


//regular Toils_Haul.CheckForGetOpportunityDuplicate isn't going to work for our purposes, since we're not carrying anything.
//Carrying something yields weird results with unspawning errors when transfering to inventory, so we copy-past-- I mean, implement our own.
Expand All @@ -85,29 +82,36 @@ public static Toil CheckDuplicateItemsToHaulToInventory(Toil getHaulTargetToil,
Job curJob = actor.jobs.curJob;

Predicate<Thing> validator = (Thing t) => t.Spawned
&& HaulAIUtility.PawnCanAutomaticallyHaulFast(actor, t, false)
&& (takeFromValidStorage || !t.IsInValidStorage())
&& !t.IsForbidden(actor)
&& actor.CanReserve(t, 1, -1, null, false)
&& (extraValidator == null || extraValidator(t));
&& HaulAIUtility.PawnCanAutomaticallyHaulFast(actor, t, false)
&& (takeFromValidStorage || !t.IsInValidStorage())
&& !t.IsForbidden(actor)
&& actor.CanReserve(t, 1, -1, null, false)
&& (extraValidator == null || extraValidator(t));

Thing thing = GenClosest.ClosestThingReachable(actor.Position, actor.Map, ThingRequest.ForGroup(ThingRequestGroup.HaulableAlways), PathEndMode.ClosestTouch,
TraverseParms.For(actor, Danger.Deadly, TraverseMode.ByPawn, false), 8f, validator, null, 0, -1, false, RegionType.Set_Passable, false);
if (thing != null && MassUtility.EncumbrancePercent(actor) <= 0.90f)
{
curJob.SetTarget(haulableInd, thing);
actor.jobs.curDriver.JumpToToil(getHaulTargetToil);
return;
}
else if (thing != null)
if (thing != null)
{
Job haul = HaulAIUtility.HaulToStorageJob(actor, thing);
if (haul != null) //because it can return null, and that ruins my day.
if (haul?.TryMakePreToilReservations(actor) ?? false)
{
if (haul.TryMakePreToilReservations(actor))
{
actor.jobs.jobQueue.EnqueueFirst(haul, new JobTag?(JobTag.Misc));
return;
}
actor.jobs.jobQueue.EnqueueFirst(haul, new JobTag?(JobTag.Misc));
return;
}
}
if (thing == null && actor.jobs.jobQueue.Count == 0)
{
Job job = new Job(PickUpAndHaulJobDefOf.UnloadYourHauledInventory);
if (job.TryMakePreToilReservations(actor))
{
actor.jobs.jobQueue.EnqueueFirst(job, new JobTag?(JobTag.Misc));
return;
}
}
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ public class JobDriver_UnloadYourHauledInventory : JobDriver
{
private int countToDrop = -1;

private const int UnloadDuration = 10;
private const int UnloadDuration = 3;

public override void ExposeData()
{
Expand All @@ -27,7 +27,7 @@ public override bool TryMakePreToilReservations()


/// <summary>
/// Find spot, reserve spot, goto spot,
/// Find spot, reserve spot, pull thing out of inventory, go to spot, drop stuff, repeat.
/// </summary>
/// <returns></returns>
[DebuggerHidden]
Expand All @@ -37,7 +37,7 @@ protected override IEnumerable<Toil> MakeNewToils()
HashSet<Thing> carriedThing = takenToInventory.GetHashSet();

Toil wait = Toils_General.Wait(UnloadDuration);
Toil celebrate = Toils_General.Wait(10);
Toil celebrate = Toils_General.Wait(UnloadDuration);


yield return wait;
Expand All @@ -55,7 +55,9 @@ protected override IEnumerable<Toil> MakeNewToils()

if (unloadableThing.Count != 0)
{
if (!StoreUtility.TryFindStoreCellNearColonyDesperate(unloadableThing.Thing, this.pawn, out IntVec3 c))
StoragePriority currentPriority = HaulAIUtility.StoragePriorityAtFor(pawn.Position, unloadableThing.Thing);
if (!StoreUtility.TryFindBestBetterStoreCellFor(unloadableThing.Thing, pawn, pawn.Map, currentPriority, pawn.Faction, out IntVec3 c, true))
//if (!StoreUtility.TryFindStoreCellNearColonyDesperate(unloadableThing.Thing, this.pawn, out IntVec3 c))
{
this.pawn.inventory.innerContainer.TryDrop(unloadableThing.Thing, ThingPlaceMode.Near, unloadableThing.Thing.stackCount, out Thing thing, null);
this.EndJobWith(JobCondition.Succeeded);
Expand Down Expand Up @@ -111,41 +113,41 @@ protected override IEnumerable<Toil> MakeNewToils()
ThingStackPart FirstUnloadableThing(Pawn pawn)
{
CompHauledToInventory takenToInventory = pawn.TryGetComp<CompHauledToInventory>();
HashSet<Thing> carriedThing = takenToInventory.GetHashSet();

//List<Thing> mergedList = pawn.inventory.innerContainer.Union(carriedThing).ToList();
HashSet<Thing> carriedThings = takenToInventory.GetHashSet();

//List<Thing> mergedList = pawn.inventory.innerContainer.Union(carriedThing).ToList();

//TODO: Merge stacks upon unload.

//find the overlap.
var potentialThingToUnload =
IEnumerable<Thing> potentialThingsToUnload =
from t in pawn.inventory.innerContainer
where carriedThing.Contains(t)
where carriedThings.Contains(t)
select t;

foreach (Thing thing in carriedThing)
foreach (Thing thing in carriedThings)
{

//partially picked up stacks get a different thingID in inventory
if (!potentialThingToUnload.Contains(thing))
if (!potentialThingsToUnload.Contains(thing))
{
carriedThing.Remove(thing);
ThingDef stragglerDef = thing.def;

//we have no method of grabbing the newly generated thingID. This is the solution to that.
var dirtyStragglers =
IEnumerable<Thing> dirtyStragglers =
from straggler in pawn.inventory.innerContainer
where straggler.def == stragglerDef
select straggler;
select straggler;

carriedThings.Remove(thing);

foreach (Thing dirtyStraggler in dirtyStragglers)
{
Predicate<Thing> validator = (Thing t) => t.def == stragglerDef;
carriedThing.RemoveWhere(validator);
//Predicate<Thing> validator = (Thing t) => t.def == stragglerDef;
//carriedThings.RemoveWhere(validator);
return new ThingStackPart(dirtyStraggler, dirtyStraggler.stackCount);
}

}
return new ThingStackPart(thing, thing.stackCount); //pawn.inventory.innerContainer.Intersect(carriedThing).Max(t => t.stackCount));
return new ThingStackPart(thing, thing.stackCount);
}
return default(ThingStackPart);
}
Expand Down
39 changes: 10 additions & 29 deletions Source/PickUpAndHaul/PickUpAndHaul/PawnUnloadChecker.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ public class PawnUnloadChecker

public static void CheckIfPawnShouldUnloadInventory(Pawn pawn, bool forced = false)
{

Job job = new Job(PickUpAndHaulJobDefOf.UnloadYourHauledInventory);
CompHauledToInventory takenToInventory = pawn.TryGetComp<CompHauledToInventory>();
if (takenToInventory == null)
Expand All @@ -23,28 +22,21 @@ public static void CheckIfPawnShouldUnloadInventory(Pawn pawn, bool forced = fal
return;
}
HashSet<Thing> carriedThing = takenToInventory.GetHashSet();

if (ModCompatibilityCheck.KnownConflict)
{
return;
}

if (pawn.Faction != Faction.OfPlayer || !pawn.RaceProps.Humanlike)
{
return;
}

if (carriedThing?.Count == 0 || pawn.inventory.innerContainer.Count == 0)
{
return;
}
if (ModCompatibilityCheck.KnownConflict) return;
if (pawn.Faction != Faction.OfPlayer || !pawn.RaceProps.Humanlike) return;
if (carriedThing?.Count == 0 || pawn.inventory.innerContainer.Count == 0) return;

if (carriedThing.Count != 0)
{
Thing thing = null;
try
{
carriedThing.Contains(thing);
if (carriedThing.Contains(thing))
{
carriedThing.Remove(thing);
Log.Warning(pawn + " removed thing null from Pick Up and Haul inventory");
}
}
catch (Exception arg)
{
Expand All @@ -53,7 +45,7 @@ public static void CheckIfPawnShouldUnloadInventory(Pawn pawn, bool forced = fal
pawn.inventory.UnloadEverything = true;
}
}

if (forced)
{
if (job.TryMakePreToilReservations(pawn))
Expand All @@ -63,7 +55,7 @@ public static void CheckIfPawnShouldUnloadInventory(Pawn pawn, bool forced = fal
}
}

if (MassUtility.EncumbrancePercent(pawn) >= 0.90f || carriedThing.Count >= 2)
if (MassUtility.EncumbrancePercent(pawn) >= 0.90f || carriedThing.Count >= 1)
{
if (job.TryMakePreToilReservations(pawn))
{
Expand All @@ -79,26 +71,15 @@ public static void CheckIfPawnShouldUnloadInventory(Pawn pawn, bool forced = fal
CompRottable compRottable = rottable.TryGetComp<CompRottable>();
if (compRottable != null)
{
//Log.Message(pawn + " compRottable" + rottable);
if (compRottable.TicksUntilRotAtCurrentTemp < 30000)
{
//Log.Message(pawn + " " + compRottable.TicksUntilRotAtCurrentTemp);
pawn.jobs.jobQueue.EnqueueFirst(job, new JobTag?(JobTag.Misc));
return;
}
}
}
}

//if (carriedThing.Count >= 3) //try to unload a bit less aggressively
//{
// if (job.TryMakePreToilReservations(pawn))
// {
// pawn.jobs.jobQueue.EnqueueFirst(job, new JobTag?(JobTag.Misc));
// return;
// }
//}

if (Find.TickManager.TicksGame % 50 == 0 && pawn.inventory.innerContainer.Count < carriedThing.Count)
{
Log.Warning("[PickUpAndHaul] " + pawn + " inventory was found out of sync with haul index. Pawn will drop their inventory.");
Expand Down
4 changes: 2 additions & 2 deletions Source/PickUpAndHaul/PickUpAndHaul/Properties/AssemblyInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,5 +32,5 @@
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("0.18.1.3")]
[assembly: AssemblyFileVersion("1.0.0.545")]
[assembly: AssemblyVersion("0.18.1.4")]
[assembly: AssemblyFileVersion("1.0.0.548")]
Loading

0 comments on commit f3da6d7

Please sign in to comment.