507 lines
14 KiB
Plaintext
507 lines
14 KiB
Plaintext
根据向量相似度分析,与 'WorkGiver_Scanner' 最相关的代码定义如下:
|
|
|
|
---
|
|
**文件路径 (精确匹配):** `C:\Steam\steamapps\common\RimWorld\Data\dll1.6\RimWorld\WorkGiver_Scanner.txt`
|
|
|
|
```csharp
|
|
public abstract class WorkGiver_Scanner : WorkGiver
|
|
{
|
|
public virtual ThingRequest PotentialWorkThingRequest => ThingRequest.ForGroup(ThingRequestGroup.Undefined);
|
|
|
|
public virtual int MaxRegionsToScanBeforeGlobalSearch => -1;
|
|
|
|
public virtual bool Prioritized => false;
|
|
|
|
public virtual bool AllowUnreachable => false;
|
|
|
|
public virtual PathEndMode PathEndMode => PathEndMode.Touch;
|
|
|
|
public virtual IEnumerable<IntVec3> PotentialWorkCellsGlobal(Pawn pawn)
|
|
{
|
|
return Enumerable.Empty<IntVec3>();
|
|
}
|
|
|
|
public virtual IEnumerable<Thing> PotentialWorkThingsGlobal(Pawn pawn)
|
|
{
|
|
return null;
|
|
}
|
|
|
|
public virtual Danger MaxPathDanger(Pawn pawn)
|
|
{
|
|
return pawn.NormalMaxDanger();
|
|
}
|
|
|
|
public virtual bool HasJobOnThing(Pawn pawn, Thing t, bool forced = false)
|
|
{
|
|
return JobOnThing(pawn, t, forced) != null;
|
|
}
|
|
|
|
public virtual string JobInfo(Pawn pawn, Job job)
|
|
{
|
|
return string.Empty;
|
|
}
|
|
|
|
public virtual Job JobOnThing(Pawn pawn, Thing t, bool forced = false)
|
|
{
|
|
return null;
|
|
}
|
|
|
|
public virtual bool HasJobOnCell(Pawn pawn, IntVec3 c, bool forced = false)
|
|
{
|
|
return JobOnCell(pawn, c, forced) != null;
|
|
}
|
|
|
|
public virtual Job JobOnCell(Pawn pawn, IntVec3 cell, bool forced = false)
|
|
{
|
|
return null;
|
|
}
|
|
|
|
public virtual float GetPriority(Pawn pawn, TargetInfo t)
|
|
{
|
|
return 0f;
|
|
}
|
|
|
|
public virtual string PostProcessedGerund(Job job)
|
|
{
|
|
return def.gerund;
|
|
}
|
|
|
|
public float GetPriority(Pawn pawn, IntVec3 cell)
|
|
{
|
|
return GetPriority(pawn, new TargetInfo(cell, pawn.Map));
|
|
}
|
|
|
|
public virtual ReservationLayerDef GetReservationLayer(Pawn pawn, LocalTargetInfo target)
|
|
{
|
|
return null;
|
|
}
|
|
}
|
|
```
|
|
---
|
|
**文件路径:** `C:\Steam\steamapps\common\RimWorld\Data\dll1.6\RimWorld\WorkGiver_HaulToSubcoreScanner.txt`
|
|
**相似度:** 0.5742
|
|
|
|
```csharp
|
|
public class WorkGiver_HaulToSubcoreScanner : WorkGiver_Scanner
|
|
{
|
|
public override ThingRequest PotentialWorkThingRequest => ThingRequest.ForGroup(ThingRequestGroup.SubcoreScanner);
|
|
|
|
public override bool HasJobOnThing(Pawn pawn, Thing t, bool forced = false)
|
|
{
|
|
if (!ModLister.CheckBiotech("Haul to subcore scanner"))
|
|
{
|
|
return false;
|
|
}
|
|
if (!(t is Building_SubcoreScanner { State: SubcoreScannerState.WaitingForIngredients } building_SubcoreScanner))
|
|
{
|
|
return false;
|
|
}
|
|
if (!pawn.CanReserve(t, 1, -1, null, forced))
|
|
{
|
|
return false;
|
|
}
|
|
return FindIngredients(pawn, building_SubcoreScanner).Thing != null;
|
|
}
|
|
|
|
public override Job JobOnThing(Pawn pawn, Thing t, bool forced = false)
|
|
{
|
|
if (!(t is Building_SubcoreScanner { State: SubcoreScannerState.WaitingForIngredients } building_SubcoreScanner))
|
|
{
|
|
return null;
|
|
}
|
|
ThingCount thingCount = FindIngredients(pawn, building_SubcoreScanner);
|
|
if (thingCount.Thing != null)
|
|
{
|
|
Job job = HaulAIUtility.HaulToContainerJob(pawn, thingCount.Thing, t);
|
|
job.count = Mathf.Min(job.count, thingCount.Count);
|
|
return job;
|
|
}
|
|
return null;
|
|
}
|
|
|
|
private ThingCount FindIngredients(Pawn pawn, Building_SubcoreScanner scanner)
|
|
{
|
|
Thing thing = GenClosest.ClosestThingReachable(pawn.Position, pawn.Map, ThingRequest.ForGroup(ThingRequestGroup.HaulableEver), PathEndMode.ClosestTouch, TraverseParms.For(pawn), 9999f, Validator);
|
|
if (thing == null)
|
|
{
|
|
return default(ThingCount);
|
|
}
|
|
int requiredCountOf = scanner.GetRequiredCountOf(thing.def);
|
|
return new ThingCount(thing, Mathf.Min(thing.stackCount, requiredCountOf));
|
|
bool Validator(Thing x)
|
|
{
|
|
if (!pawn.CanReserve(x))
|
|
{
|
|
return false;
|
|
}
|
|
if (x.IsForbidden(pawn))
|
|
{
|
|
return false;
|
|
}
|
|
return scanner.CanAcceptIngredient(x);
|
|
}
|
|
}
|
|
}
|
|
```
|
|
---
|
|
**文件路径:** `C:\Steam\steamapps\common\RimWorld\Data\dll1.6\RimWorld\WorkGiver_HaulToBiosculpterPod.txt`
|
|
**相似度:** 0.5453
|
|
|
|
```csharp
|
|
public class WorkGiver_HaulToBiosculpterPod : WorkGiver_Scanner
|
|
{
|
|
public override ThingRequest PotentialWorkThingRequest => ThingRequest.ForDef(ThingDefOf.BiosculpterPod);
|
|
|
|
public override PathEndMode PathEndMode => PathEndMode.Touch;
|
|
|
|
public override bool HasJobOnThing(Pawn pawn, Thing t, bool forced = false)
|
|
{
|
|
if (!ModLister.CheckIdeology("Biosculpting"))
|
|
{
|
|
return false;
|
|
}
|
|
if (!pawn.CanReserve(t, 1, -1, null, forced))
|
|
{
|
|
return false;
|
|
}
|
|
if (pawn.Map.designationManager.DesignationOn(t, DesignationDefOf.Deconstruct) != null)
|
|
{
|
|
return false;
|
|
}
|
|
CompBiosculpterPod compBiosculpterPod = t.TryGetComp<CompBiosculpterPod>();
|
|
if (compBiosculpterPod == null || !compBiosculpterPod.PowerOn || compBiosculpterPod.State != 0 || (!forced && !compBiosculpterPod.autoLoadNutrition))
|
|
{
|
|
return false;
|
|
}
|
|
if (t.IsBurning())
|
|
{
|
|
return false;
|
|
}
|
|
if (compBiosculpterPod.RequiredNutritionRemaining > 0f)
|
|
{
|
|
if (FindNutrition(pawn, compBiosculpterPod).Thing == null)
|
|
{
|
|
JobFailReason.Is("NoFood".Translate());
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
public override Job JobOnThing(Pawn pawn, Thing t, bool forced = false)
|
|
{
|
|
CompBiosculpterPod compBiosculpterPod = t.TryGetComp<CompBiosculpterPod>();
|
|
if (compBiosculpterPod == null)
|
|
{
|
|
return null;
|
|
}
|
|
if (compBiosculpterPod.RequiredNutritionRemaining > 0f)
|
|
{
|
|
ThingCount thingCount = FindNutrition(pawn, compBiosculpterPod);
|
|
if (thingCount.Thing != null)
|
|
{
|
|
Job job = HaulAIUtility.HaulToContainerJob(pawn, thingCount.Thing, t);
|
|
job.count = Mathf.Min(job.count, thingCount.Count);
|
|
return job;
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
|
|
private ThingCount FindNutrition(Pawn pawn, CompBiosculpterPod pod)
|
|
{
|
|
Thing thing = GenClosest.ClosestThingReachable(pawn.Position, pawn.Map, ThingRequest.ForGroup(ThingRequestGroup.FoodSourceNotPlantOrTree), PathEndMode.ClosestTouch, TraverseParms.For(pawn), 9999f, Validator);
|
|
if (thing == null)
|
|
{
|
|
return default(ThingCount);
|
|
}
|
|
int b = Mathf.CeilToInt(pod.RequiredNutritionRemaining / thing.GetStatValue(StatDefOf.Nutrition));
|
|
return new ThingCount(thing, Mathf.Min(thing.stackCount, b));
|
|
bool Validator(Thing x)
|
|
{
|
|
if (x.IsForbidden(pawn) || !pawn.CanReserve(x))
|
|
{
|
|
return false;
|
|
}
|
|
if (!pod.CanAcceptNutrition(x))
|
|
{
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
```
|
|
---
|
|
**文件路径:** `C:\Steam\steamapps\common\RimWorld\Data\dll1.6\RimWorld\WorkGiver_ConstructFinishFrames.txt`
|
|
**相似度:** 0.5184
|
|
|
|
```csharp
|
|
public class WorkGiver_ConstructFinishFrames : WorkGiver_Scanner
|
|
{
|
|
public override PathEndMode PathEndMode => PathEndMode.Touch;
|
|
|
|
public override ThingRequest PotentialWorkThingRequest => ThingRequest.ForGroup(ThingRequestGroup.BuildingFrame);
|
|
|
|
public override Danger MaxPathDanger(Pawn pawn)
|
|
{
|
|
return Danger.Deadly;
|
|
}
|
|
|
|
public override Job JobOnThing(Pawn pawn, Thing t, bool forced = false)
|
|
{
|
|
if (t.Faction != pawn.Faction)
|
|
{
|
|
return null;
|
|
}
|
|
if (!(t is Frame frame))
|
|
{
|
|
return null;
|
|
}
|
|
if (!frame.IsCompleted())
|
|
{
|
|
return null;
|
|
}
|
|
if (!GenConstruct.CanTouchTargetFromValidCell(frame, pawn))
|
|
{
|
|
return null;
|
|
}
|
|
if (GenConstruct.FirstBlockingThing(frame, pawn) != null)
|
|
{
|
|
return GenConstruct.HandleBlockingThingJob(frame, pawn, forced);
|
|
}
|
|
if (!GenConstruct.CanConstruct(frame, pawn, checkSkills: true, forced))
|
|
{
|
|
return null;
|
|
}
|
|
return JobMaker.MakeJob(JobDefOf.FinishFrame, frame);
|
|
}
|
|
}
|
|
```
|
|
---
|
|
**文件路径:** `C:\Steam\steamapps\common\RimWorld\Data\dll1.6\RimWorld\WorkGiver_CookFillHopper.txt`
|
|
**相似度:** 0.5093
|
|
|
|
```csharp
|
|
public class WorkGiver_CookFillHopper : WorkGiver_Scanner
|
|
{
|
|
private static string TheOnlyAvailableFoodIsInStorageOfHigherPriorityTrans;
|
|
|
|
private static string NoFoodToFillHopperTrans;
|
|
|
|
public override ThingRequest PotentialWorkThingRequest => ThingRequest.ForDef(ThingDefOf.Hopper);
|
|
|
|
public override PathEndMode PathEndMode => PathEndMode.ClosestTouch;
|
|
|
|
public WorkGiver_CookFillHopper()
|
|
{
|
|
if (TheOnlyAvailableFoodIsInStorageOfHigherPriorityTrans == null)
|
|
{
|
|
TheOnlyAvailableFoodIsInStorageOfHigherPriorityTrans = "TheOnlyAvailableFoodIsInStorageOfHigherPriority".Translate();
|
|
}
|
|
if (NoFoodToFillHopperTrans == null)
|
|
{
|
|
NoFoodToFillHopperTrans = "NoFoodToFillHopper".Translate();
|
|
}
|
|
}
|
|
|
|
public override Job JobOnThing(Pawn pawn, Thing thing, bool forced = false)
|
|
{
|
|
if (!(thing is ISlotGroupParent hopperSgp))
|
|
{
|
|
return null;
|
|
}
|
|
if (!pawn.CanReserve(thing.Position))
|
|
{
|
|
return null;
|
|
}
|
|
float num = 0f;
|
|
List<Thing> list = pawn.Map.thingGrid.ThingsListAt(thing.Position);
|
|
for (int i = 0; i < list.Count; i++)
|
|
{
|
|
Thing thing2 = list[i];
|
|
if (Building_NutrientPasteDispenser.IsAcceptableFeedstock(thing2.def))
|
|
{
|
|
num = (float)thing2.stackCount / (float)thing2.def.stackLimit;
|
|
}
|
|
}
|
|
if (num > 0.35f)
|
|
{
|
|
JobFailReason.Is("AlreadyFilledLower".Translate());
|
|
return null;
|
|
}
|
|
return HopperFillFoodJob(pawn, hopperSgp, forced);
|
|
}
|
|
|
|
public static Job HopperFillFoodJob(Pawn pawn, ISlotGroupParent hopperSgp, bool forced)
|
|
{
|
|
Building building = (Building)hopperSgp;
|
|
if (!pawn.CanReserveAndReach(building.Position, PathEndMode.Touch, pawn.NormalMaxDanger()))
|
|
{
|
|
return null;
|
|
}
|
|
ThingDef thingDef = null;
|
|
Thing firstItem = building.Position.GetFirstItem(building.Map);
|
|
if (firstItem != null)
|
|
{
|
|
if (!Building_NutrientPasteDispenser.IsAcceptableFeedstock(firstItem.def))
|
|
{
|
|
if (firstItem.IsForbidden(pawn))
|
|
{
|
|
return null;
|
|
}
|
|
return HaulAIUtility.HaulAsideJobFor(pawn, firstItem);
|
|
}
|
|
thingDef = firstItem.def;
|
|
}
|
|
List<Thing> list = ((thingDef != null) ? pawn.Map.listerThings.ThingsOfDef(thingDef) : pawn.Map.listerThings.ThingsInGroup(ThingRequestGroup.FoodSourceNotPlantOrTree));
|
|
bool flag = false;
|
|
for (int i = 0; i < list.Count; i++)
|
|
{
|
|
Thing thing = list[i];
|
|
if (!thing.def.IsNutritionGivingIngestible || (thing.def.ingestible.preferability != FoodPreferability.RawBad && thing.def.ingestible.preferability != FoodPreferability.RawTasty) || !HaulAIUtility.PawnCanAutomaticallyHaul(pawn, thing, forced) || !pawn.Map.haulDestinationManager.SlotGroupAt(building.Position).Settings.AllowedToAccept(thing))
|
|
{
|
|
continue;
|
|
}
|
|
if ((int)StoreUtility.CurrentStoragePriorityOf(thing, forced) >= (int)hopperSgp.GetSlotGroup().Settings.Priority)
|
|
{
|
|
flag = true;
|
|
JobFailReason.Is(TheOnlyAvailableFoodIsInStorageOfHigherPriorityTrans);
|
|
continue;
|
|
}
|
|
Job job = HaulAIUtility.HaulToCellStorageJob(pawn, thing, building.Position, fitInStoreCell: true);
|
|
if (job != null)
|
|
{
|
|
return job;
|
|
}
|
|
}
|
|
if (!flag)
|
|
{
|
|
JobFailReason.Is(NoFoodToFillHopperTrans);
|
|
}
|
|
return null;
|
|
}
|
|
}
|
|
```
|
|
---
|
|
**文件路径:** `C:\Steam\steamapps\common\RimWorld\Data\dll1.6\RimWorld\WorkGiver_InteractAnimal.txt`
|
|
**相似度:** 0.5082
|
|
|
|
```csharp
|
|
public abstract class WorkGiver_InteractAnimal : WorkGiver_Scanner
|
|
{
|
|
protected static string NoUsableFoodTrans;
|
|
|
|
protected static string AnimalInteractedTooRecentlyTrans;
|
|
|
|
private static string CantInteractAnimalDownedTrans;
|
|
|
|
private static string CantInteractAnimalAsleepTrans;
|
|
|
|
private static string CantInteractAnimalBusyTrans;
|
|
|
|
protected bool canInteractWhileSleeping;
|
|
|
|
public override PathEndMode PathEndMode => PathEndMode.OnCell;
|
|
|
|
public static void ResetStaticData()
|
|
{
|
|
NoUsableFoodTrans = "NoUsableFood".Translate();
|
|
AnimalInteractedTooRecentlyTrans = "AnimalInteractedTooRecently".Translate();
|
|
CantInteractAnimalDownedTrans = "CantInteractAnimalDowned".Translate();
|
|
CantInteractAnimalAsleepTrans = "CantInteractAnimalAsleep".Translate();
|
|
CantInteractAnimalBusyTrans = "CantInteractAnimalBusy".Translate();
|
|
}
|
|
|
|
protected virtual bool CanInteractWithAnimal(Pawn pawn, Pawn animal, bool forced)
|
|
{
|
|
if (CanInteractWithAnimal(pawn, animal, out var jobFailReason, forced, canInteractWhileSleeping))
|
|
{
|
|
return true;
|
|
}
|
|
if (jobFailReason != null)
|
|
{
|
|
JobFailReason.Is(jobFailReason);
|
|
}
|
|
return false;
|
|
}
|
|
|
|
public static bool CanInteractWithAnimal(Pawn pawn, Pawn animal, out string jobFailReason, bool forced, bool canInteractWhileSleeping = false, bool ignoreSkillRequirements = false, bool canInteractWhileRoaming = false)
|
|
{
|
|
jobFailReason = null;
|
|
if (!pawn.CanReserve(animal, 1, -1, null, forced))
|
|
{
|
|
return false;
|
|
}
|
|
if (animal.Downed)
|
|
{
|
|
jobFailReason = CantInteractAnimalDownedTrans;
|
|
return false;
|
|
}
|
|
if (!animal.Awake() && !canInteractWhileSleeping)
|
|
{
|
|
jobFailReason = CantInteractAnimalAsleepTrans;
|
|
return false;
|
|
}
|
|
if (!animal.CanCasuallyInteractNow(twoWayInteraction: false, canInteractWhileSleeping, canInteractWhileRoaming))
|
|
{
|
|
jobFailReason = CantInteractAnimalBusyTrans;
|
|
return false;
|
|
}
|
|
int num = TrainableUtility.MinimumHandlingSkill(animal);
|
|
if (!ignoreSkillRequirements && num > pawn.skills.GetSkill(SkillDefOf.Animals).Level)
|
|
{
|
|
jobFailReason = "AnimalsSkillTooLow".Translate(num);
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
protected bool HasFoodToInteractAnimal(Pawn pawn, Pawn tamee)
|
|
{
|
|
ThingOwner<Thing> innerContainer = pawn.inventory.innerContainer;
|
|
int num = 0;
|
|
float num2 = JobDriver_InteractAnimal.RequiredNutritionPerFeed(tamee);
|
|
float num3 = 0f;
|
|
for (int i = 0; i < innerContainer.Count; i++)
|
|
{
|
|
Thing thing = innerContainer[i];
|
|
if (!tamee.WillEat(thing, pawn) || (int)thing.def.ingestible.preferability > 5 || thing.def.IsDrug)
|
|
{
|
|
continue;
|
|
}
|
|
for (int j = 0; j < thing.stackCount; j++)
|
|
{
|
|
num3 += thing.GetStatValue(StatDefOf.Nutrition);
|
|
if (num3 >= num2)
|
|
{
|
|
num++;
|
|
num3 = 0f;
|
|
}
|
|
if (num >= 2)
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
protected Job TakeFoodForAnimalInteractJob(Pawn pawn, Pawn tamee)
|
|
{
|
|
ThingDef foodDef;
|
|
Thing thing = FoodUtility.BestFoodSourceOnMap(pawn, tamee, desperate: false, out foodDef, FoodPreferability.RawTasty, allowPlant: false, allowDrug: false, allowCorpse: false, allowDispenserFull: false, allowDispenserEmpty: false, allowForbidden: false, allowSociallyImproper: false, allowHarvest: false, forceScanWholeMap: false, ignoreReservations: false, calculateWantedStackCount: false, FoodPreferability.Undefined, JobDriver_InteractAnimal.RequiredNutritionPerFeed(tamee) * 2f * 4f);
|
|
if (thing == null)
|
|
{
|
|
return null;
|
|
}
|
|
float wantedNutrition = JobDriver_InteractAnimal.RequiredNutritionPerFeed(tamee) * 2f * 4f;
|
|
float nutrition = FoodUtility.GetNutrition(tamee, thing, foodDef);
|
|
int count = FoodUtility.StackCountForNutrition(wantedNutrition, nutrition);
|
|
Job job = JobMaker.MakeJob(JobDefOf.TakeInventory, thing);
|
|
job.count = count;
|
|
return job;
|
|
}
|
|
}
|
|
``` |