public static void StartFormingCaravan(List <Pawn> pawns, List <Pawn> downedPawns, Faction faction, List <TransferableOneWay> transferables, IntVec3 meetingPoint, IntVec3 exitSpot, int startingTile, int destinationTile) { if (startingTile < 0) { Log.Error("Can't start forming caravan because startingTile is invalid."); return; } if (!pawns.NotNullAndAny()) { Log.Error("Can't start forming caravan with 0 pawns."); return; } if (!pawns.NotNullAndAny(x => x is VehiclePawn)) { Log.Error("Can't start forming vehicle caravan without any vehicles"); return; } if (pawns.NotNullAndAny(x => x is VehiclePawn vehicle && vehicle.IsBoat() && (vehicle.movementStatus is VehicleMovementStatus.Online))) { List <TransferableOneWay> list = transferables; list.RemoveAll((TransferableOneWay x) => x.CountToTransfer <= 0 || !x.HasAnyThing || x.AnyThing is Pawn); foreach (Pawn p in pawns) { Lord pLord = p.GetLord(); if (pLord != null) { pLord.Notify_PawnLost(p, PawnLostCondition.ForcedToJoinOtherLord, null); } } List <VehiclePawn> vehicles = pawns.Where(p => p.IsBoat()).Cast <VehiclePawn>().ToList(); List <Pawn> capablePawns = pawns.Where(x => !(x is VehiclePawn) && x.IsColonist && !x.Downed && !x.Dead).ToList(); List <Pawn> prisoners = pawns.Where(x => !(x is VehiclePawn) && !x.IsColonist && !x.RaceProps.Animal).ToList(); int seats = 0; foreach (VehiclePawn vehicle in vehicles) { seats += vehicle.SeatsAvailable; } if ((pawns.Where(p => !p.IsBoat()).ToList().Count + downedPawns.Count) > seats) { Log.Error("Can't start forming caravan with vehicles(s) selected and not enough seats to house all pawns. Seats: " + seats + " Pawns boarding: " + (pawns.Where(x => !(x is VehiclePawn)).ToList().Count + downedPawns.Count)); return; } LordJob_FormAndSendVehicles lordJob = new LordJob_FormAndSendVehicles(list, vehicles, capablePawns, downedPawns, prisoners, meetingPoint, exitSpot, startingTile, destinationTile, true); LordMaker.MakeNewLord(Faction.OfPlayer, lordJob, pawns[0].MapHeld, pawns); vehicles.ForEach(v => v.DisembarkAll()); foreach (Pawn p in pawns) { if (p.Spawned) { p.jobs.EndCurrentJob(JobCondition.InterruptForced, true); } } }
/// <summary> /// Draw items in VehicleCaravan that is currently being formed /// </summary> /// <param name="inRect"></param> /// <param name="curY"></param> /// <param name="tmpSingleThing"></param> /// <param name="instance"></param> public static void DoItemsListForVehicle(Rect inRect, ref float curY, ref List <Thing> tmpSingleThing, ITab_Pawn_FormingCaravan instance) { LordJob_FormAndSendVehicles lordJob_FormAndSendCaravanVehicle = (LordJob_FormAndSendVehicles)(Find.Selector.SingleSelectedThing as Pawn).GetLord().LordJob; Rect position = new Rect(0f, curY, (inRect.width - 10f) / 2f, inRect.height); float a = 0f; GUI.BeginGroup(position); Widgets.ListSeparator(ref a, position.width, "ItemsToLoad".Translate()); bool flag = false; foreach (TransferableOneWay transferableOneWay in lordJob_FormAndSendCaravanVehicle.transferables) { if (transferableOneWay.CountToTransfer > 0 && transferableOneWay.HasAnyThing) { flag = true; MethodInfo doThingRow = AccessTools.Method(type: typeof(ITab_Pawn_FormingCaravan), name: "DoThingRow"); object[] args = new object[] { transferableOneWay.ThingDef, transferableOneWay.CountToTransfer, transferableOneWay.things, position.width, a }; doThingRow.Invoke(instance, args); a = (float)args[4]; } } if (!flag) { Widgets.NoneLabel(ref a, position.width, null); } GUI.EndGroup(); Rect position2 = new Rect((inRect.width + 10f) / 2f, curY, (inRect.width - 10f) / 2f, inRect.height); float b = 0f; GUI.BeginGroup(position2); Widgets.ListSeparator(ref b, position2.width, "LoadedItems".Translate()); bool flag2 = false; foreach (Pawn pawn in lordJob_FormAndSendCaravanVehicle.lord.ownedPawns) { if (!pawn.inventory.UnloadEverything) { foreach (Thing thing in pawn.inventory.innerContainer) { flag2 = true; tmpSingleThing.Clear(); tmpSingleThing.Add(thing); MethodInfo doThingRow = AccessTools.Method(type: typeof(ITab_Pawn_FormingCaravan), name: "DoThingRow"); object[] args = new object[] { thing.def, thing.stackCount, tmpSingleThing, position2.width, b }; doThingRow.Invoke(instance, args); b = (float)args[4]; } } } if (!flag2) { Widgets.NoneLabel(ref b, position.width, null); } GUI.EndGroup(); curY += Mathf.Max(a, b); }
/// <summary> /// Total capacity left for VehicleCaravan currently forming /// </summary> /// <param name="lordJob"></param> public static float CapacityLeft(LordJob_FormAndSendVehicles lordJob) { float num = CollectionsMassCalculator.MassUsageTransferables(lordJob.transferables, IgnorePawnsInventoryMode.IgnoreIfAssignedToUnload, false, false); List <ThingCount> tmpCaravanPawns = new List <ThingCount>(); for (int i = 0; i < lordJob.lord.ownedPawns.Count; i++) { Pawn pawn = lordJob.lord.ownedPawns[i]; tmpCaravanPawns.Add(new ThingCount(pawn, pawn.stackCount)); } num += CollectionsMassCalculator.MassUsage(tmpCaravanPawns, IgnorePawnsInventoryMode.IgnoreIfAssignedToUnload, false, false); float num2 = CollectionsMassCalculator.Capacity(tmpCaravanPawns, null); tmpCaravanPawns.Clear(); return(num2 - num); }