private void TakeFromCaravan(Caravan caravan, List <ThingCount> demands, Faction enemyFaction) { List <Thing> list = new List <Thing>(); for (int i = 0; i < demands.Count; i++) { ThingCount thingCount = demands[i]; if (thingCount.Thing is Pawn) { Pawn pawn = (Pawn)thingCount.Thing; caravan.RemovePawn(pawn); foreach (Thing thing in ThingOwnerUtility.GetAllThingsRecursively(pawn, false)) { list.Add(thing); thing.holdingOwner.Take(thing); } enemyFaction.kidnapped.KidnapPawn(pawn, null); } else { thingCount.Thing.SplitOff(thingCount.Count).Destroy(DestroyMode.Vanish); } } for (int j = 0; j < list.Count; j++) { if (!list[j].Destroyed) { CaravanInventoryUtility.GiveThing(caravan, list[j]); } } }
public static void SimulateTradeableTransfer(List <Thing> all, List <Tradeable> tradeables, List <ThingCount> outThingsAfterTransfer) { outThingsAfterTransfer.Clear(); for (int i = 0; i < all.Count; i++) { outThingsAfterTransfer.Add(new ThingCount(all[i], all[i].stackCount)); } for (int j = 0; j < tradeables.Count; j++) { int countToTransferToSource = tradeables[j].CountToTransferToSource; int countToTransferToDestination = tradeables[j].CountToTransferToDestination; if (countToTransferToSource > 0) { TransferableUtility.TransferNoSplit(tradeables[j].thingsTrader, countToTransferToSource, delegate(Thing originalThing, int toTake) { outThingsAfterTransfer.Add(new ThingCount(originalThing, toTake)); }, false, false); } else if (countToTransferToDestination > 0) { TransferableUtility.TransferNoSplit(tradeables[j].thingsColony, countToTransferToDestination, delegate(Thing originalThing, int toTake) { for (int k = 0; k < outThingsAfterTransfer.Count; k++) { ThingCount thingCount = outThingsAfterTransfer[k]; if (thingCount.Thing == originalThing) { outThingsAfterTransfer[k] = thingCount.WithCount(thingCount.Count - toTake); break; } } }, false, false); } } }
public static float ApproxDaysUntilRot(List <ThingCount> potentiallyFood, int tile, WorldPath path = null, float nextTileCostLeft = 0f, int caravanTicksPerMove = 3300) { DaysUntilRotCalculator.tmpTicksToArrive.Clear(); if (path != null && path.Found) { CaravanArrivalTimeEstimator.EstimatedTicksToArriveToEvery(tile, path.LastNode, path, nextTileCostLeft, caravanTicksPerMove, Find.TickManager.TicksAbs, DaysUntilRotCalculator.tmpTicksToArrive); } DaysUntilRotCalculator.tmpNutritions.Clear(); for (int i = 0; i < potentiallyFood.Count; i++) { ThingCount thingCount = potentiallyFood[i]; if (thingCount.Count > 0 && thingCount.Thing.def.IsNutritionGivingIngestible) { CompRottable compRottable = thingCount.Thing.TryGetComp <CompRottable>(); float first; if (compRottable != null && compRottable.Active) { first = (float)DaysUntilRotCalculator.ApproxTicksUntilRot_AssumeTimePassesBy(compRottable, tile, DaysUntilRotCalculator.tmpTicksToArrive) / 60000f; } else { first = 600f; } float second = thingCount.Thing.GetStatValue(StatDefOf.Nutrition, true) * (float)thingCount.Count; DaysUntilRotCalculator.tmpNutritions.Add(new Pair <float, float>(first, second)); } } return(GenMath.WeightedMedian(DaysUntilRotCalculator.tmpNutritions, 600f, 0.5f)); }
static bool UsePuahFirstUnloadableThing(ref ThingCount __result, Pawn pawn) { if (!haulToInventory.Value || !enabled.Value) { return(true); } __result = JooStoreUtility.PuahFirstUnloadableThing(pawn); return(false); }
public override void Notify_Starting() { base.Notify_Starting(); ThingCount thingCount = LoadTransportersJobUtility.FindThingToLoad(this.pawn, base.Container.TryGetComp <CompTransporter>()); this.job.targetA = thingCount.Thing; this.job.count = thingCount.Count; this.initialCount = thingCount.Count; this.pawn.Reserve(thingCount.Thing, this.job, 1, -1, null, true); }
public override void Notify_Starting() { base.Notify_Starting(); ThingCount thingCount = ((!job.targetA.IsValid) ? LoadTransportersJobUtility.FindThingToLoad(pawn, base.Container.TryGetComp <CompTransporter>()) : new ThingCount(job.targetA.Thing, job.targetA.Thing.stackCount)); job.targetA = thingCount.Thing; job.count = thingCount.Count; initialCount = thingCount.Count; pawn.Reserve(thingCount.Thing, job); }
internal void <> m__1(Thing originalThing, int toTake) { for (int i = 0; i < this.outThingsAfterTransfer.Count; i++) { ThingCount thingCount = this.outThingsAfterTransfer[i]; if (thingCount.Thing == originalThing) { this.outThingsAfterTransfer[i] = thingCount.WithCount(thingCount.Count - toTake); break; } } }
protected override IEnumerable <Toil> MakeNewToils() { this.FailOnDespawnedOrNull(TargetIndex.A); yield return(Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.Touch)); yield return(Toils_General.Wait(10, TargetIndex.None)); yield return(new Toil { initAction = delegate() { Pawn otherPawn = this.OtherPawn; if (!otherPawn.inventory.UnloadEverything) { base.EndJobWith(JobCondition.Succeeded); } else { ThingCount firstUnloadableThing = otherPawn.inventory.FirstUnloadableThing; IntVec3 c; if (!firstUnloadableThing.Thing.def.EverStorable(false) || !this.pawn.health.capacities.CapableOf(PawnCapacityDefOf.Manipulation) || !StoreUtility.TryFindStoreCellNearColonyDesperate(firstUnloadableThing.Thing, this.pawn, out c)) { Thing thing; otherPawn.inventory.innerContainer.TryDrop(firstUnloadableThing.Thing, ThingPlaceMode.Near, firstUnloadableThing.Count, out thing, null, null); base.EndJobWith(JobCondition.Succeeded); if (thing != null) { thing.SetForbidden(false, false); } } else { Thing thing2; otherPawn.inventory.innerContainer.TryTransferToContainer(firstUnloadableThing.Thing, this.pawn.carryTracker.innerContainer, firstUnloadableThing.Count, out thing2, true); this.job.count = thing2.stackCount; this.job.SetTarget(TargetIndex.B, thing2); this.job.SetTarget(TargetIndex.C, c); firstUnloadableThing.Thing.SetForbidden(false, false); } } } }); yield return(Toils_Reserve.Reserve(TargetIndex.C, 1, -1, null)); Toil carryToCell = Toils_Haul.CarryHauledThingToCell(TargetIndex.C); yield return(carryToCell); yield return(Toils_Haul.PlaceHauledThingInCell(TargetIndex.C, carryToCell, true)); yield break; }
public static void Postfix(Pawn_InventoryTracker __instance, ref ThingCount __result) { if (__result == default(ThingCount) || !__result.Thing.def.IsWeapon) { return; } else { Pawn pawn = __instance.pawn; GoldfishModule pawnMemory = GoldfishModule.GetGoldfishForPawn(pawn); if ( pawnMemory == null || !pawn.IsColonist || pawn.equipment == null || __instance.innerContainer == null ) { return; } List <ThingDefStuffDefPair> desiredSidearms = pawnMemory.RememberedWeapons.ListFullCopy(); if (pawn.equipment.Primary != null) { if (desiredSidearms.Contains(pawn.equipment.Primary.toThingDefStuffDefPair())) { desiredSidearms.Remove(pawn.equipment.Primary.toThingDefStuffDefPair()); } } int inventoryOffset = 0; //TODO: this does not preserve best possible weapon, just whichever one is first in inventory. Maybe fix? while (inventoryOffset < __instance.innerContainer.Count) { Thing candidate = __instance.innerContainer[inventoryOffset]; if (candidate.def.IsWeapon & desiredSidearms.Contains(candidate.toThingDefStuffDefPair())) { desiredSidearms.Remove(candidate.toThingDefStuffDefPair()); } else { __result = new ThingCount(candidate, candidate.stackCount); return; } inventoryOffset++; } __result = default(ThingCount); return; } }
protected override IEnumerable <Toil> MakeNewToils() { this.FailOnDespawnedOrNull(TargetIndex.A); yield return(Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.Touch)); yield return(Toils_General.Wait(10)); Toil toil = new Toil(); toil.initAction = delegate { Pawn otherPawn = OtherPawn; if (!otherPawn.inventory.UnloadEverything) { EndJobWith(JobCondition.Succeeded); } else { ThingCount firstUnloadableThing = otherPawn.inventory.FirstUnloadableThing; if (!firstUnloadableThing.Thing.def.EverStorable(willMinifyIfPossible: false) || !pawn.health.capacities.CapableOf(PawnCapacityDefOf.Manipulation) || !StoreUtility.TryFindStoreCellNearColonyDesperate(firstUnloadableThing.Thing, pawn, out var storeCell)) { otherPawn.inventory.innerContainer.TryDrop(firstUnloadableThing.Thing, ThingPlaceMode.Near, firstUnloadableThing.Count, out var lastResultingThing); EndJobWith(JobCondition.Succeeded); lastResultingThing?.SetForbidden(value: false, warnOnFail: false); } else { otherPawn.inventory.innerContainer.TryTransferToContainer(firstUnloadableThing.Thing, pawn.carryTracker.innerContainer, firstUnloadableThing.Count, out var resultingTransferredItem); job.count = resultingTransferredItem.stackCount; job.SetTarget(TargetIndex.B, resultingTransferredItem); job.SetTarget(TargetIndex.C, storeCell); firstUnloadableThing.Thing.SetForbidden(value: false, warnOnFail: false); } } }; yield return(toil); yield return(Toils_Reserve.Reserve(TargetIndex.C)); Toil carryToCell = Toils_Haul.CarryHauledThingToCell(TargetIndex.C); yield return(carryToCell); yield return(Toils_Haul.PlaceHauledThingInCell(TargetIndex.C, carryToCell, storageMode: true)); }
public override void Notify_Starting() { base.Notify_Starting(); ThingCount thingCount = LoadPitJobUtility.FindThingToLoad(this.pawn, base.Container.TryGetComp <CompPit>()); this.job.targetA = thingCount.Thing; this.job.count = thingCount.Count; this.initialCount = thingCount.Count; this.pawn.Reserve(thingCount.Thing, this.job, 1, -1, null, true); foreach (Pawn p in this.Map.mapPawns.SpawnedPawnsInFaction(Faction.OfPlayer)) { bool flag3 = p.needs != null && p.needs.mood != null && p.needs.mood.thoughts != null; if (flag3) { p.needs.mood.thoughts.memories.TryGainMemory(ThoughtDef.Named("PD_ThrownPrisonerIntoPit"), null); p.needs.mood.thoughts.memories.TryGainMemory(ThoughtDef.Named("PD_ThrownPrisonerIntoPitImLovinIt"), null); } } }
static bool CheckKanbanSettings(Map map, IntVec3 cell, ThingCount thingCount, ref int countToDrop) { if (!cell.TryGetKanbanSettings(map, out var ks, out var slotGroup)) { return(false); } var thing = thingCount.Thing; int stackLimit = Math.Max(1, (int)(thing.def.stackLimit * ks.srt / 100f)); KSLog.Message($"[UnloadHauledInventory] {thing.LabelCap} x{thing.stackCount} / limit = {stackLimit}"); List <Thing> things = map.thingGrid.ThingsListAt(cell); for (int i = 0; i < things.Count; i++) { Thing t = things[i]; if (!t.def.EverStorable(false)) { continue; // skip non-storable things as they aren't actually *in* the stockpile } if (!t.CanStackWith(thing)) { continue; // skip it if it cannot stack with thing to haul } if (t.stackCount >= stackLimit) { continue; // no need to refill until count is below threshold } int needMax = stackLimit - t.stackCount; countToDrop = Math.Min(thing.stackCount, needMax); KSLog.Message($" drop to stack => stack: {t.stackCount}, countToDrop: {countToDrop}"); return(true); } countToDrop = thing.stackCount > stackLimit ? stackLimit : thing.stackCount; KSLog.Message($" drop to empty cell => countToDrop: {countToDrop}"); return(true); }
public static void Postfix_FirstUnloadableThing(Pawn_InventoryTracker __instance, ref ThingCount __result) { if (__result.Thing is SurvivalTool tool && tool.InUse) { bool foundNewThing = false; // Had to iterate through because a lambda expression in this case isn't possible for (int i = 0; i < __instance.innerContainer.Count; i++) { Thing newThing = __instance.innerContainer[i]; if (newThing as SurvivalTool == null || !((SurvivalTool)newThing).InUse) { __result = new ThingCount(newThing, newThing.stackCount); foundNewThing = true; break; } } if (!foundNewThing) { __result = default(ThingCount); } } }
private void TakeFromCaravan(Caravan caravan, List <ThingCount> demands, Faction enemyFaction) { List <Thing> list = new List <Thing>(); for (int i = 0; i < demands.Count; i++) { ThingCount thingCount = demands[i]; if (thingCount.Thing is Pawn) { Pawn pawn = (Pawn)thingCount.Thing; caravan.RemovePawn(pawn); foreach (Thing item in ThingOwnerUtility.GetAllThingsRecursively(pawn, allowUnreal: false)) { list.Add(item); item.holdingOwner.Take(item); } if (pawn.RaceProps.Humanlike) { enemyFaction.kidnapped.Kidnap(pawn, null); } else if (!Find.WorldPawns.Contains(pawn)) { Find.WorldPawns.PassToWorld(pawn); } } else { thingCount.Thing.SplitOff(thingCount.Count).Destroy(); } } for (int j = 0; j < list.Count; j++) { if (!list[j].Destroyed) { CaravanInventoryUtility.GiveThing(caravan, list[j]); } } }
public Job MakeShardingJob(Pawn selPawn, IBillGiver billGiver, int count) { var bills = billGiver.BillStack.Bills; Bill workBill = null; foreach (var bill in bills) { if (!bill.suspended && (bill.PawnAllowedToStartAnew(selPawn)) && bill.ingredientFilter.Allows(this.parent)) { Log.Message(bill.ingredientFilter.AllowedThingDefs.ToStringSafeEnumerable()); workBill = bill; break; } } if (workBill == null) // this techprinter didn't have a suitable bill, so add one I guess { Bill newBill; if (count == 1) { newBill = BillUtility.MakeNewBill(Base.DefOf.DTechprintingRecipe); } else { newBill = BillUtility.MakeNewBill(Base.DefOf.DTechprintingStackRecipe); } newBill.ingredientFilter.SetDisallowAll(); newBill.ingredientFilter.SetAllow(this.parent.def, true); billGiver.BillStack.AddBill(newBill); workBill = newBill; } ThingCount tc = new ThingCount(this.parent, count); Job haulOff; return(WorkGiver_DoBill.TryStartNewDoBillJob(selPawn, workBill, billGiver, new List <ThingCount> { tc }, out haulOff, false)); }
private static bool Prefix(Pawn_InventoryTracker __instance, ref ThingCount __result) { if (__instance.innerContainer.Count == 0) { __result = default; return(false); } tmpDrugsToKeep.Clear(); if (__instance.pawn.drugs?.CurrentPolicy != null) { var currentPolicy = __instance.pawn.drugs.CurrentPolicy; for (var i = 0; i < currentPolicy.Count; i++) { if (currentPolicy[i].takeToInventory > 0) { tmpDrugsToKeep.Add(new ThingDefCount(currentPolicy[i].drug, currentPolicy[i].takeToInventory)); } } } Thing bestInstrument = null; if (!__instance.pawn.NonHumanlikeOrWildMan() && !__instance.pawn.WorkTagIsDisabled(WorkTags.Artistic)) { var artSkill = __instance.pawn.skills.GetSkill(SkillDefOf.Artistic).levelInt; IEnumerable <Thing> heldInstruments = __instance.innerContainer .Where(PerformanceManager.IsInstrument) .Where(x => !x.TryGetComp <CompMusicalInstrument>().Props.isBuilding) .OrderByDescending(x => x.TryGetComp <CompMusicalInstrument>().WeightedSuitability(artSkill)); if (heldInstruments.Any()) { bestInstrument = heldInstruments.FirstOrDefault(); } } if (tmpDrugsToKeep.Any() || bestInstrument != null) { foreach (var thing in __instance.innerContainer) { if (thing.def.IsDrug) { var num = -1; for (var k = 0; k < tmpDrugsToKeep.Count; k++) { if (thing.def != tmpDrugsToKeep[k].ThingDef) { continue; } num = k; break; } if (num < 0) { __result = new ThingCount(thing, thing.stackCount); return(false); } if (thing.stackCount > tmpDrugsToKeep[num].Count) { __result = new ThingCount(thing, thing.stackCount - tmpDrugsToKeep[num].Count); return(false); } tmpDrugsToKeep[num] = new ThingDefCount(tmpDrugsToKeep[num].ThingDef, tmpDrugsToKeep[num].Count - thing.stackCount); } else if (PerformanceManager.IsInstrument(thing)) { if (bestInstrument == null) { __result = new ThingCount(thing, thing.stackCount); return(false); } if (bestInstrument.GetHashCode() == thing.GetHashCode()) { continue; } __result = new ThingCount(thing, thing.stackCount); return(false); } else { __result = new ThingCount(thing, thing.stackCount); return(false); } } __result = default; return(false); } __result = new ThingCount(__instance.innerContainer[0], __instance.innerContainer[0].stackCount); return(false); }
public bool MoveNext() { uint num = (uint)this.$PC; this.$PC = -1; switch (num) { case 0u: this.FailOnDespawnedOrNull(TargetIndex.A); this.$current = Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.Touch); if (!this.$disposing) { this.$PC = 1; } return(true); case 1u: this.$current = Toils_General.Wait(10, TargetIndex.None); if (!this.$disposing) { this.$PC = 2; } return(true); case 2u: { Toil dropOrStartCarrying = new Toil(); dropOrStartCarrying.initAction = delegate() { Pawn otherPawn = base.OtherPawn; if (!otherPawn.inventory.UnloadEverything) { base.EndJobWith(JobCondition.Succeeded); } else { ThingCount firstUnloadableThing = otherPawn.inventory.FirstUnloadableThing; IntVec3 c; if (!firstUnloadableThing.Thing.def.EverStorable(false) || !this.pawn.health.capacities.CapableOf(PawnCapacityDefOf.Manipulation) || !StoreUtility.TryFindStoreCellNearColonyDesperate(firstUnloadableThing.Thing, this.pawn, out c)) { Thing thing; otherPawn.inventory.innerContainer.TryDrop(firstUnloadableThing.Thing, ThingPlaceMode.Near, firstUnloadableThing.Count, out thing, null, null); base.EndJobWith(JobCondition.Succeeded); if (thing != null) { thing.SetForbidden(false, false); } } else { Thing thing2; otherPawn.inventory.innerContainer.TryTransferToContainer(firstUnloadableThing.Thing, this.pawn.carryTracker.innerContainer, firstUnloadableThing.Count, out thing2, true); this.job.count = thing2.stackCount; this.job.SetTarget(TargetIndex.B, thing2); this.job.SetTarget(TargetIndex.C, c); firstUnloadableThing.Thing.SetForbidden(false, false); } } }; this.$current = dropOrStartCarrying; if (!this.$disposing) { this.$PC = 3; } return(true); } case 3u: this.$current = Toils_Reserve.Reserve(TargetIndex.C, 1, -1, null); if (!this.$disposing) { this.$PC = 4; } return(true); case 4u: carryToCell = Toils_Haul.CarryHauledThingToCell(TargetIndex.C); this.$current = carryToCell; if (!this.$disposing) { this.$PC = 5; } return(true); case 5u: this.$current = Toils_Haul.PlaceHauledThingInCell(TargetIndex.C, carryToCell, true); if (!this.$disposing) { this.$PC = 6; } return(true); case 6u: this.$PC = -1; break; } return(false); }
public static string ThingsLabel(List <ThingCount> things, string prefix = " - ") { GenLabel.tmpThingsLabelElements.Clear(); using (List <ThingCount> .Enumerator enumerator = things.GetEnumerator()) { while (enumerator.MoveNext()) { ThingCount thing = enumerator.Current; GenLabel.LabelElement labelElement = (from elem in GenLabel.tmpThingsLabelElements where thing.Thing.def.stackLimit > 1 && elem.thingTemplate.def == thing.Thing.def && elem.thingTemplate.Stuff == thing.Thing.Stuff select elem).FirstOrDefault <GenLabel.LabelElement>(); if (labelElement != null) { labelElement.count += thing.Count; } else { GenLabel.tmpThingsLabelElements.Add(new GenLabel.LabelElement { thingTemplate = thing.Thing, count = thing.Count }); } } } GenLabel.tmpThingsLabelElements.Sort(delegate(GenLabel.LabelElement lhs, GenLabel.LabelElement rhs) { int num = TransferableComparer_Category.Compare(lhs.thingTemplate.def, rhs.thingTemplate.def); if (num != 0) { return(num); } return(lhs.thingTemplate.MarketValue.CompareTo(rhs.thingTemplate.MarketValue)); }); StringBuilder stringBuilder = new StringBuilder(); foreach (GenLabel.LabelElement labelElement2 in GenLabel.tmpThingsLabelElements) { string str = string.Empty; if (labelElement2.thingTemplate.ParentHolder is Pawn_ApparelTracker) { str = " (" + "WornBy".Translate(new object[] { ((Pawn)labelElement2.thingTemplate.ParentHolder.ParentHolder).LabelShort }) + ")"; } else if (labelElement2.thingTemplate.ParentHolder is Pawn_EquipmentTracker) { str = " (" + "EquippedBy".Translate(new object[] { ((Pawn)labelElement2.thingTemplate.ParentHolder.ParentHolder).LabelShort }) + ")"; } if (labelElement2.count == 1) { stringBuilder.AppendLine(prefix + labelElement2.thingTemplate.LabelCap + str); } else { stringBuilder.AppendLine(prefix + GenLabel.ThingLabel(labelElement2.thingTemplate.def, labelElement2.thingTemplate.Stuff, labelElement2.count).CapitalizeFirst() + str); } } GenLabel.tmpThingsLabelElements.Clear(); return(stringBuilder.ToString().TrimEndNewlines()); }
protected override IEnumerable <Toil> MakeNewToils() { yield return(Toils_General.Wait(10, TargetIndex.None)); yield return(new Toil { initAction = delegate() { Thing MarkedThing = CompUnloadChecker.getFirstMarked(pawn); if (MarkedThing == null) { EndJobWith(JobCondition.Succeeded); return; } // if (pawn.equipment.Contains(MarkedThing)) { Equipment = (ThingWithComps)MarkedThing; Apparel = null; } else { Apparel = pawn.apparel.Contains(MarkedThing) ? (Apparel)MarkedThing : null; Equipment = null; } ThingCount firstUnloadableThing = MarkedThing == null ? default(ThingCount) : new ThingCount(MarkedThing, MarkedThing.stackCount); IntVec3 c; if (!StoreUtility.TryFindStoreCellNearColonyDesperate(firstUnloadableThing.Thing, pawn, out c)) { Thing thing; pawn.inventory.innerContainer.TryDrop(firstUnloadableThing.Thing, ThingPlaceMode.Near, firstUnloadableThing.Count, out thing, null, null); EndJobWith(JobCondition.Succeeded); return; } job.SetTarget(TargetIndex.A, firstUnloadableThing.Thing); job.SetTarget(TargetIndex.B, c); countToDrop = firstUnloadableThing.Count; } }); yield return(Toils_Reserve.Reserve(TargetIndex.B, 1, -1, null)); yield return(Toils_Goto.GotoCell(TargetIndex.B, PathEndMode.Touch).FailOnDestroyedOrNull(TargetIndex.A).FailOn(delegate() { return !stillUnloadable(pawn.CurJob.GetTarget(TargetIndex.A).Thing); })); //preintiating unequip-delay Toil unequip = new Toil { initAction = delegate() { if (Equipment != null) { pawn.equipment.TryTransferEquipmentToContainer(Equipment, pawn.inventory.innerContainer); } else if (Apparel != null) { ThingOwner <Apparel> a = Traverse.Create(pawn.apparel).Field("wornApparel").GetValue <ThingOwner <Apparel> >(); a.TryTransferToContainer(Apparel, pawn.inventory.innerContainer); } } }; //if equiped, wait unequipping time Toil wait = new Toil(); wait.initAction = delegate() { ticker = 0; duration = Apparel != null?Apparel.GetStatValue(StatDefOf.EquipDelay, true) * 60f : Equipment != null ? 30 : 0; pawn.pather.StopDead(); }; wait.tickAction = delegate() { if (ticker >= duration) { ReadyForNextToil(); } ticker++; }; wait.defaultCompleteMode = ToilCompleteMode.Never; wait.WithProgressBar(TargetIndex.A, () => ticker / duration); //unequip to inventory yield return(wait); yield return(unequip); //hold in hands yield return(new Toil { initAction = delegate() { Thing thing = job.GetTarget(TargetIndex.A).Thing; CompUnloadChecker c = thing.TryGetComp <CompUnloadChecker>(); if (c == null || !c.ShouldUnload) { EndJobWith(JobCondition.Incompletable); return; } if (thing == null || !pawn.inventory.innerContainer.Contains(thing)) { EndJobWith(JobCondition.Incompletable); return; } if (!pawn.health.capacities.CapableOf(PawnCapacityDefOf.Manipulation) || !thing.def.EverStorable(false)) { pawn.inventory.innerContainer.TryDrop(thing, ThingPlaceMode.Near, countToDrop, out thing, null, null); EndJobWith(JobCondition.Succeeded); } else { pawn.inventory.innerContainer.TryTransferToContainer(thing, pawn.carryTracker.innerContainer, countToDrop, out thing, true); job.count = countToDrop; job.SetTarget(TargetIndex.A, thing); } thing.SetForbidden(false, false); } }); Toil carryToCell = Toils_Haul.CarryHauledThingToCell(TargetIndex.B).FailOnDestroyedOrNull(TargetIndex.A).FailOn(delegate() { return(!stillUnloadable(pawn.CurJob.GetTarget(TargetIndex.A).Thing)); }); yield return(carryToCell); yield return(Toils_Haul.PlaceHauledThingInCell(TargetIndex.B, carryToCell, true)); yield break; }
public History( ThingCount[] thingCounts, Color[] colors = null ) { // get range of colors if not set if( colors == null ) { // default to white for single line if( thingCounts.Length == 1 ) { colors = new[] { Color.white }; } // rainbow! else { colors = HSV_Helper.Range( thingCounts.Length ); } } // create a chapter for each label for( int i = 0; i < thingCounts.Length; i++ ) { _chapters.Add( new Chapter( thingCounts[i], Size, colors[i % colors.Length] ) ); } // show all by default _chaptersShown.AddRange( _chapters ); }
public Chapter( ThingCount thingCount, int size, Color color ) : this() { this.label = thingCount.thingDef.LabelCap; this.ThingCount = thingCount; this.size = size; lineColor = color; }
protected override IEnumerable <Toil> MakeNewToils() { yield return(Toils_General.Wait(10)); Toil toil = new Toil(); toil.initAction = delegate { if (!pawn.inventory.UnloadEverything) { EndJobWith(JobCondition.Succeeded); } else { ThingCount firstUnloadableThing = pawn.inventory.FirstUnloadableThing; if (!StoreUtility.TryFindStoreCellNearColonyDesperate(firstUnloadableThing.Thing, pawn, out var storeCell)) { pawn.inventory.innerContainer.TryDrop(firstUnloadableThing.Thing, ThingPlaceMode.Near, firstUnloadableThing.Count, out var _); EndJobWith(JobCondition.Succeeded); } else { job.SetTarget(TargetIndex.A, firstUnloadableThing.Thing); job.SetTarget(TargetIndex.B, storeCell); countToDrop = firstUnloadableThing.Count; } } }; yield return(toil); yield return(Toils_Reserve.Reserve(TargetIndex.B)); yield return(Toils_Goto.GotoCell(TargetIndex.B, PathEndMode.Touch)); Toil toil2 = new Toil(); toil2.initAction = delegate { Thing lastResultingThing = job.GetTarget(TargetIndex.A).Thing; if (lastResultingThing == null || !pawn.inventory.innerContainer.Contains(lastResultingThing)) { EndJobWith(JobCondition.Incompletable); } else { if (!pawn.health.capacities.CapableOf(PawnCapacityDefOf.Manipulation) || !lastResultingThing.def.EverStorable(willMinifyIfPossible: false)) { pawn.inventory.innerContainer.TryDrop(lastResultingThing, ThingPlaceMode.Near, countToDrop, out lastResultingThing); EndJobWith(JobCondition.Succeeded); } else { pawn.inventory.innerContainer.TryTransferToContainer(lastResultingThing, pawn.carryTracker.innerContainer, countToDrop, out lastResultingThing); job.count = countToDrop; job.SetTarget(TargetIndex.A, lastResultingThing); } lastResultingThing.SetForbidden(value: false, warnOnFail: false); } }; yield return(toil2); Toil carryToCell = Toils_Haul.CarryHauledThingToCell(TargetIndex.B); yield return(carryToCell); yield return(Toils_Haul.PlaceHauledThingInCell(TargetIndex.B, carryToCell, storageMode: true)); }
/// <summary> /// Find spot, reserve spot, pull thing out of inventory, go to spot, drop stuff, repeat. /// </summary> /// <returns></returns> protected override IEnumerable <Toil> MakeNewToils() { CompHauledToInventory takenToInventory = pawn.TryGetComp <CompHauledToInventory>(); HashSet <Thing> carriedThing = takenToInventory.GetHashSet(); if (ModCompatibilityCheck.ExtendedStorageIsActive) { //ES takes at least ~10 ticks to move from the feeder to the stockpile, so workaround ahoy UnloadDuration = 20; } Toil wait = Toils_General.Wait(UnloadDuration); Toil celebrate = Toils_General.Wait(UnloadDuration); yield return(wait); Toil findSpot = new Toil { initAction = () => { ThingCount unloadableThing = FirstUnloadableThing(pawn); if (unloadableThing.Count == 0 && carriedThing.Count == 0) { this.EndJobWith(JobCondition.Succeeded); } if (unloadableThing.Count != 0) { //StoragePriority currentPriority = StoreUtility.StoragePriorityAtFor(pawn.Position, unloadableThing.Thing); 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); this.EndJobWith(JobCondition.Succeeded); } else { this.job.SetTarget(TargetIndex.A, unloadableThing.Thing); this.job.SetTarget(TargetIndex.B, c); this.countToDrop = unloadableThing.Thing.stackCount; } } } }; yield return(findSpot); yield return(Toils_Reserve.Reserve(TargetIndex.B)); yield return(new Toil { initAction = delegate { Thing thing = this.job.GetTarget(TargetIndex.A).Thing; if (thing == null || !this.pawn.inventory.innerContainer.Contains(thing)) { carriedThing.Remove(thing); pawn.jobs.curDriver.JumpToToil(wait); return; } if (!this.pawn.health.capacities.CapableOf(PawnCapacityDefOf.Manipulation) || !thing.def.EverStorable(false)) { this.pawn.inventory.innerContainer.TryDrop(thing, ThingPlaceMode.Near, this.countToDrop, out thing); this.EndJobWith(JobCondition.Succeeded); carriedThing.Remove(thing); } else { this.pawn.inventory.innerContainer.TryTransferToContainer(thing, this.pawn.carryTracker.innerContainer, this.countToDrop, out thing); this.job.count = this.countToDrop; this.job.SetTarget(TargetIndex.A, thing); carriedThing.Remove(thing); } try { ((Action)(() => { if (ModCompatibilityCheck.CombatExtendedIsActive) { //CombatExtended.CompInventory ceCompInventory = pawn.GetComp<CombatExtended.CompInventory>(); //ceCompInventory.UpdateInventory(); } }))(); } catch (TypeLoadException) { } thing.SetForbidden(false, false); } }); Toil carryToCell = Toils_Haul.CarryHauledThingToCell(TargetIndex.B); yield return(Toils_Goto.GotoCell(TargetIndex.B, PathEndMode.Touch)); yield return(carryToCell); yield return(Toils_Haul.PlaceHauledThingInCell(TargetIndex.B, carryToCell, true)); //If the original cell is full, PlaceHauledThingInCell will set a different TargetIndex resulting in errors on yield return Toils_Reserve.Release. //We still gotta release though, mostly because of Extended Storage. Toil releaseReservation = new Toil { initAction = () => { if (pawn.Map.reservationManager.ReservedBy(this.job.targetB, pawn, pawn.CurJob) && !ModCompatibilityCheck.HCSKIsActive) { pawn.Map.reservationManager.Release(this.job.targetB, pawn, pawn.CurJob); } } }; yield return(releaseReservation); yield return(Toils_Jump.Jump(wait)); yield return(celebrate); }
public override void DrawPanelReadout(ref float curY, float width) { // we need the window's size to be able to do a scrollbar, but are not directly given that size. Rect outRect = ArchitectCategoryTab.InfoRect.AtZero(); // our window actually starts from curY outRect.yMin = curY; // our contents height is given by final curY - which we conveniently saved Rect viewRect = new Rect(0f, 0f, width, _panelHeight); // if contents are larger than available canvas, leave some room for scrollbar if (viewRect.height > outRect.height) { outRect.width -= 16f; width -= 16f; } // since we're going to work in new GUI group (through the scrollview), we'll need to keep track of // our own relative Y position. float oldY = curY; curY = 0f; // start scrollrect Widgets.BeginScrollView(outRect, ref _scrollPosition, viewRect); // list of objects to be build Text.Font = GameFont.Tiny; foreach (var buildables in Blueprint.GroupedBuildables) { // count float curX = 5f; Widgets.Label(new Rect(5f, curY, width * .2f, 100f), buildables.Value.Count + "x"); curX += width * .2f; // stuff selector float height = 0f; if (buildables.Value.First().Stuff != null) { string label = buildables.Value.First().Stuff.LabelAsStuff.CapitalizeFirst() + " " + buildables.Key.label; Rect iconRect = new Rect(curX, curY, 12f, 12f); curX += 16f; height = Text.CalcHeight(label, width - curX) + _lineOffset; Rect labelRect = new Rect(curX, curY, width - curX, height); Rect buttonRect = new Rect(curX - 16f, curY, width - curX + 16f, height + _lineOffset); if (Mouse.IsOver(buttonRect)) { GUI.DrawTexture(buttonRect, TexUI.HighlightTex); GUI.color = GenUI.MouseoverColor; } GUI.DrawTexture(iconRect, Resources.Icon_Edit); GUI.color = Color.white; Widgets.Label(labelRect, label); if (Widgets.ButtonInvisible(buttonRect)) { Blueprint.DrawStuffMenu(buildables.Key); } } else { // label float labelWidth = width - curX; string label = buildables.Key.LabelCap; height = Text.CalcHeight(label, labelWidth) + _lineOffset; Widgets.Label(new Rect(curX, curY, labelWidth, height), label); } // next line curY += height + _lineOffset; } // complete cost list curY += 12f; Text.Font = GameFont.Small; Widgets.Label(new Rect(0f, curY, width, 24f), "Fluffy.Blueprint.Cost".Translate()); curY += 24f; Text.Font = GameFont.Tiny; List <ThingCount> costlist = Blueprint.CostListAdjusted; for (int i = 0; i < costlist.Count; i++) { ThingCount thingCount = costlist[i]; Texture2D image; if (thingCount.ThingDef == null) { image = BaseContent.BadTex; } else { image = thingCount.ThingDef.uiIcon; } GUI.DrawTexture(new Rect(0f, curY, 20f, 20f), image); if (thingCount.ThingDef != null && thingCount.ThingDef.resourceReadoutPriority != ResourceCountPriority.Uncounted && Find.VisibleMap.resourceCounter.GetCount(thingCount.ThingDef) < thingCount.Count) { GUI.color = Color.red; } Widgets.Label(new Rect(26f, curY + 2f, 50f, 100f), thingCount.Count.ToString()); GUI.color = Color.white; string text; if (thingCount.ThingDef == null) { text = "(" + "UnchosenStuff".Translate() + ")"; } else { text = thingCount.ThingDef.LabelCap; } float height = Text.CalcHeight(text, width - 60f) - 2f; Widgets.Label(new Rect(60f, curY + 2f, width - 60f, height), text); curY += height + _lineOffset; } Widgets.EndScrollView(); _panelHeight = curY; // need to give some extra offset to properly align description. // also, add back in our internal offset curY += 28f + oldY; }
public bool MoveNext() { uint num = (uint)this.$PC; this.$PC = -1; switch (num) { case 0u: this.$current = Toils_General.Wait(10, TargetIndex.None); if (!this.$disposing) { this.$PC = 1; } return(true); case 1u: { Toil pickItem = new Toil(); pickItem.initAction = delegate() { if (!this.pawn.inventory.UnloadEverything) { base.EndJobWith(JobCondition.Succeeded); } else { ThingCount firstUnloadableThing = this.pawn.inventory.FirstUnloadableThing; IntVec3 c; if (!StoreUtility.TryFindStoreCellNearColonyDesperate(firstUnloadableThing.Thing, this.pawn, out c)) { Thing thing; this.pawn.inventory.innerContainer.TryDrop(firstUnloadableThing.Thing, ThingPlaceMode.Near, firstUnloadableThing.Count, out thing, null, null); base.EndJobWith(JobCondition.Succeeded); } else { this.job.SetTarget(TargetIndex.A, firstUnloadableThing.Thing); this.job.SetTarget(TargetIndex.B, c); this.countToDrop = firstUnloadableThing.Count; } } }; this.$current = pickItem; if (!this.$disposing) { this.$PC = 2; } return(true); } case 2u: this.$current = Toils_Reserve.Reserve(TargetIndex.B, 1, -1, null); if (!this.$disposing) { this.$PC = 3; } return(true); case 3u: this.$current = Toils_Goto.GotoCell(TargetIndex.B, PathEndMode.Touch); if (!this.$disposing) { this.$PC = 4; } return(true); case 4u: { Toil dropOrStartCarrying = new Toil(); dropOrStartCarrying.initAction = delegate() { Thing thing = this.job.GetTarget(TargetIndex.A).Thing; if (thing == null || !this.pawn.inventory.innerContainer.Contains(thing)) { base.EndJobWith(JobCondition.Incompletable); return; } if (!this.pawn.health.capacities.CapableOf(PawnCapacityDefOf.Manipulation) || !thing.def.EverStorable(false)) { this.pawn.inventory.innerContainer.TryDrop(thing, ThingPlaceMode.Near, this.countToDrop, out thing, null, null); base.EndJobWith(JobCondition.Succeeded); } else { this.pawn.inventory.innerContainer.TryTransferToContainer(thing, this.pawn.carryTracker.innerContainer, this.countToDrop, out thing, true); this.job.count = this.countToDrop; this.job.SetTarget(TargetIndex.A, thing); } thing.SetForbidden(false, false); }; this.$current = dropOrStartCarrying; if (!this.$disposing) { this.$PC = 5; } return(true); } case 5u: carryToCell = Toils_Haul.CarryHauledThingToCell(TargetIndex.B); this.$current = carryToCell; if (!this.$disposing) { this.$PC = 6; } return(true); case 6u: this.$current = Toils_Haul.PlaceHauledThingInCell(TargetIndex.B, carryToCell, true); if (!this.$disposing) { this.$PC = 7; } return(true); case 7u: this.$PC = -1; break; } return(false); }
protected override IEnumerable <Toil> MakeNewToils() { yield return(Toils_General.Wait(10, TargetIndex.None)); yield return(new Toil { initAction = delegate() { if (!this.pawn.inventory.UnloadEverything) { base.EndJobWith(JobCondition.Succeeded); } else { ThingCount firstUnloadableThing = this.pawn.inventory.FirstUnloadableThing; IntVec3 c; if (!StoreUtility.TryFindStoreCellNearColonyDesperate(firstUnloadableThing.Thing, this.pawn, out c)) { Thing thing; this.pawn.inventory.innerContainer.TryDrop(firstUnloadableThing.Thing, ThingPlaceMode.Near, firstUnloadableThing.Count, out thing, null, null); base.EndJobWith(JobCondition.Succeeded); } else { this.job.SetTarget(TargetIndex.A, firstUnloadableThing.Thing); this.job.SetTarget(TargetIndex.B, c); this.countToDrop = firstUnloadableThing.Count; } } } }); yield return(Toils_Reserve.Reserve(TargetIndex.B, 1, -1, null)); yield return(Toils_Goto.GotoCell(TargetIndex.B, PathEndMode.Touch)); yield return(new Toil { initAction = delegate() { Thing thing = this.job.GetTarget(TargetIndex.A).Thing; if (thing == null || !this.pawn.inventory.innerContainer.Contains(thing)) { base.EndJobWith(JobCondition.Incompletable); return; } if (!this.pawn.health.capacities.CapableOf(PawnCapacityDefOf.Manipulation) || !thing.def.EverStorable(false)) { this.pawn.inventory.innerContainer.TryDrop(thing, ThingPlaceMode.Near, this.countToDrop, out thing, null, null); base.EndJobWith(JobCondition.Succeeded); } else { this.pawn.inventory.innerContainer.TryTransferToContainer(thing, this.pawn.carryTracker.innerContainer, this.countToDrop, out thing, true); this.job.count = this.countToDrop; this.job.SetTarget(TargetIndex.A, thing); } thing.SetForbidden(false, false); } }); Toil carryToCell = Toils_Haul.CarryHauledThingToCell(TargetIndex.B); yield return(carryToCell); yield return(Toils_Haul.PlaceHauledThingInCell(TargetIndex.B, carryToCell, true)); yield break; }
static public void OptimizePath(List <ThingCount> q, Thing Starter = null) { if (q.Count > 0) { int x = 0; int idx = 0; int n = 0; ThingCount out_of_all_things_they_didnt_add_a_simple_swap = default(ThingCount); if (Starter != null) { if (q[0].Thing.Position == null) { n = int.MaxValue; } else { n = q[0].Thing.Position.DistanceToSquared(Starter.Position); } for (int i = 1; i < q.Count(); i++) { if (q[i].Thing.Position == null) { continue; } x = q[i].Thing.Position.DistanceToSquared(Starter.Position); if (Math.Abs(x) < Math.Abs(n)) { n = x; idx = i; } } if (idx != 0) { out_of_all_things_they_didnt_add_a_simple_swap = q[idx]; q[idx] = q[0]; q[0] = out_of_all_things_they_didnt_add_a_simple_swap; } } for (int i = 0; i < q.Count() - 1; i++) { if (q[i + 1].Thing.Position == null) { continue; } n = q[i].Thing.Position.DistanceToSquared(q[i + 1].Thing.Position); idx = i + 1; for (int c = i + 2; c < q.Count(); c++) { if (q[c].Thing.Position == null) { continue; } x = q[i].Thing.Position.DistanceToSquared(q[c].Thing.Position); if (Math.Abs(x) < Math.Abs(n)) { n = x; idx = c; } } if (idx != i + 1) { out_of_all_things_they_didnt_add_a_simple_swap = q[idx]; q[idx] = q[i + 1]; q[i + 1] = out_of_all_things_they_didnt_add_a_simple_swap; } } } }
static bool TryFindBestBillIngredientsInSet_AllowMix(List <Thing> availableThings, Bill bill, List <ThingCount> chosen) { chosen.Clear(); List <ThingCount> chosenInThisStep = new List <ThingCount>(); for (int i = 0; i < bill.recipe.ingredients.Count; i++) { IngredientCount ingredientCount = bill.recipe.ingredients[i]; float num = ingredientCount.GetBaseCount(); chosenInThisStep.Clear(); for (int j = 0; j < availableThings.Count; j++) { Thing thing = availableThings[j]; if (ingredientCount.filter.Allows(thing)) { if (ingredientCount.IsFixedIngredient || bill.ingredientFilter.Allows(thing)) { float num2 = bill.recipe.IngredientValueGetter.ValuePerUnitOf(thing.def); int num3 = Mathf.Min(Mathf.CeilToInt(num / num2), thing.stackCount); ThingCountUtility.AddToList(chosen, thing, num3); ThingCountUtility.AddToList(chosenInThisStep, thing, num3); num -= (float)num3 * num2; if (num <= 0.0001f) { break; } } } } if (num > 0.0001f) { return(false); } //patch: do another pass eliminating as many resources as possible. starting with the biggest resources, //have we allocated more than we may need? And at least 2 different things. if (num < -0.0001f && chosenInThisStep.Count > 1) { num = -num; chosenInThisStep.SortByDescending(ta => bill.recipe.IngredientValueGetter.ValuePerUnitOf(ta.Thing.def)); for (int j = 0; j < chosenInThisStep.Count && num > 0.0001f; j++) { ThingCount ta = chosenInThisStep[j]; float valuePerUnit = bill.recipe.IngredientValueGetter.ValuePerUnitOf(ta.Thing.def); //can we remove at least one instance of the current ingredient? if (valuePerUnit < num) { //determine how many instances we can remove int instancesToRemove = 0; while (valuePerUnit < num && instancesToRemove < ta.Count) { num -= valuePerUnit - 0.0001f; //adding a small amount since the precision loss of float causes problems where subtraction leads to 0.04999 instead of 0.05 instancesToRemove++; } if (instancesToRemove != 0) { ThingCountUtility.AddToList(chosen, ta.Thing, -instancesToRemove); } } } } chosen.RemoveAll(ta => ta.Count <= 0); } return(true); }