static void RespectRequirementsPatch([NotNull] IPlantToGrowSettable settable, [NotNull] Pawn pawn, ref bool __result) { if (!__result) { return; } IntVec3 c; if (settable is Zone_Growing growingZone) { c = growingZone.Cells[0]; } else { c = ((Thing)settable).Position; } var plant = WorkGiver_Grower.CalculateWantedPlantDef(c, pawn.Map); if (plant == null) { return; } __result = plant.IsValidFor(pawn); }
public static void Postfix(Pawn pawn, TargetInfo t, ref float __result, WorkGiver_Grower __instance) { IntVec3 cell = t.Cell; var zone = (Zone_Growing)pawn.Map.zoneManager.AllZones.FirstOrFallback(x => x is Zone_Growing growZone && growZone.cells.Contains(cell)); if (zone != null) { __result = zone != null && PriorityTracker.growingZonePriorities.TryGetValue(zone, out PriorityIntHolder intp) ? intp.Int : (int)Priority.Normal; } else { foreach (Building b in pawn.Map.listerBuildings.allBuildingsColonist) { if (b is Building_PlantGrower building) { CellRect.CellRectIterator cri = building.OccupiedRect().GetIterator(); while (!cri.Done()) { Priority priority = PriorityTracker.plantBuildingPriorities.TryGetValue(building, out PriorityIntHolder intp) ? (Priority)intp.Int : Priority.Normal; __result = (float)priority; cri.MoveNext(); } } } } }
private static void Postfix(IPlantToGrowSettable settable, Pawn pawn, ref bool __result) { if (__result) { ThingDef plant = WorkGiver_Grower.CalculateWantedPlantDef((settable as Zone_Growing)?.Cells[0] ?? ((Thing)settable).Position, pawn.Map); __result = RaceAddonTools.CheckPlant(pawn.def, plant); } }
public void FixWorkGiver_Grower() { if (WorkGiver is WorkGiver_Grower grower) { Debug.Log($"plant to grow: {Traverse.Create( grower ).Field( "wantedPlantDef" ).GetValue<ThingDef>()?.defName ?? "NULL"} :: " + $"calculated plant to grow: {WorkGiver_Grower.CalculateWantedPlantDef( _cell, _map )?.defName ?? "NULL"}"); _wantedPlantDefFieldInfo.SetValue(null, null); } }
public static bool FrostPlantSeason(IntVec3 c, Map map) { ThingDef val = WorkGiver_Grower.CalculateWantedPlantDef(c, map); if (val != null && val.thingClass == typeof(FrostPlant)) { return(GrowthSeasonNowFrostPlant(c, map)); } return(false); }
public static bool Patch_GrowthSeasonNow(ref bool __result, ref IntVec3 c, Map map, bool forSowing) { ThingDef val = WorkGiver_Grower.CalculateWantedPlantDef(c, map); if (val != null && val.thingClass == typeof(FrostPlant)) { __result = GrowthSeasonNowFrostPlant(c, map); return(false); } return(true); }
private static IEnumerable <IntVec3> PotentialWorkCellsGlobalIE(WorkGiver_Grower __instance, Pawn pawn) { Danger maxDanger = pawn.NormalMaxDanger(); List <Building> bList = pawn.Map.listerBuildings.allBuildingsColonist; for (int j = 0; j < bList.Count; j++) { Building_PlantGrower building_PlantGrower = bList[j] as Building_PlantGrower; if (building_PlantGrower == null || !__instance.ExtraRequirements(building_PlantGrower, pawn) || building_PlantGrower.IsForbidden(pawn) || //!pawn.CanReach(building_PlantGrower, PathEndMode.OnCell, maxDanger) || building_PlantGrower.IsBurning()) { continue; } foreach (IntVec3 item in building_PlantGrower.OccupiedRect()) { yield return(item); } wantedPlantDef = null; } wantedPlantDef = null; List <Zone> zonesList = pawn.Map.zoneManager.AllZones; for (int j = 0; j < zonesList.Count; j++) { Zone_Growing growZone = zonesList[j] as Zone_Growing; if (growZone == null) { continue; } if (growZone.cells.Count == 0) { Log.ErrorOnce("Grow zone has 0 cells: " + growZone, -563487); } else if (__instance.ExtraRequirements(growZone, pawn) && !growZone.ContainsStaticFire && pawn.CanReach(growZone.Cells.First(), PathEndMode.OnCell, maxDanger)) { for (int k = 0; k < growZone.cells.Count; k++) { yield return(growZone.cells[k]); } wantedPlantDef = null; growZone = null; } } wantedPlantDef = null; }
public override Job JobOnCell(Pawn pawn, IntVec3 c, bool forced = false) { Plant plant = c.GetPlant(pawn.Map); Map map = pawn.Map; ThingDef wantedPlantDef = WorkGiver_Grower.CalculateWantedPlantDef(c, pawn.Map); if (plant == null || plant.def == wantedPlantDef) { return(null); } LocalTargetInfo target = plant; bool ignoreOtherReservations = forced; if (!pawn.CanReserve(target, 1, -1, null, ignoreOtherReservations) || plant.IsForbidden(pawn)) { return(null); } return(new Job(JobDefOf.CutPlant, plant)); }
static bool RespectRestrictionsPatch([NotNull] Pawn pawn, IntVec3 c, bool forced, ref Job __result) { if (pawn.Map == null) { return(true); } var plant = WorkGiver_Grower.CalculateWantedPlantDef(c, pawn.Map); if (plant != null) { if (!plant.IsValidFor(pawn)) { __result = null; return(false); } } return(true); }
public override bool HasJobOnCell(Pawn pawn, IntVec3 c, bool forced = false) { Plant plant = c.GetPlant(pawn.Map); ThingDef wantedPlantDef = WorkGiver_Grower.CalculateWantedPlantDef(c, pawn.Map); if (plant == null || plant.def == wantedPlantDef) { return(false); } if (c.IsForbidden(pawn)) { return(false); } LocalTargetInfo target = plant; bool ignoreOtherReservations = forced; if (!pawn.CanReserve(target, 1, -1, null, ignoreOtherReservations)) { return(false); } return(true); }
//public static bool IsForbidden(this Thing t, Pawn pawn) public static bool IsForbiddenByType(Thing thing, Pawn pawn, WorkGiver_Grower workGiver) { if (!Mod.settings.zoneHarvestableToggle || !(workGiver is WorkGiver_GrowerHarvest)) { return(thing.IsForbidden(pawn)); } //WorkGiver_GrowerHarvest now //Reimplementing IsForbidden with ForbidHarvestBuildingMapComp instead of forbidden comp if (!ForbidUtility.CaresAboutForbidden(pawn, false)) { return(false); } if (thing.Spawned && thing.Position.IsForbidden(pawn)) { return(true); } //if (thing.IsForbidden(pawn.Faction) || thing.IsForbidden(pawn.HostFaction)) //{ // return true; //} return(!thing.CanHarvest()); }
public static bool PotentialWorkCellsGlobal(WorkGiver_Grower __instance, ref IEnumerable <IntVec3> __result, Pawn pawn) { __result = PotentialWorkCellsGlobalIE(__instance, pawn); return(false); }
private static bool JobOnCellTest(WorkGiverDef def, Pawn pawn, IntVec3 c, bool forced = false) { Map map = pawn.Map; if (c.IsForbidden(pawn)) { #if DEBUG Log.Warning("IsForbidden"); #endif PlantSowing_Cache.ReregisterObject(map, c, awaitingPlantCellsMapDict); return(false); } if (!PlantUtility.GrowthSeasonNow(c, map, forSowing: true)) { #if DEBUG Log.Warning("GrowthSeasonNow"); #endif return(false); } ThingDef localWantedPlantDef = WorkGiver_Grower.CalculateWantedPlantDef(c, map); WorkGiver_GrowerSow.wantedPlantDef = localWantedPlantDef; if (localWantedPlantDef == null) { #if DEBUG Log.Warning("localWantedPlantDef==null"); #endif return(false); } List <Thing> thingList = c.GetThingList(map); bool flag = false; for (int i = 0; i < thingList.Count; i++) { Thing thing = thingList[i]; if (thing.def == localWantedPlantDef) { #if DEBUG Log.Warning("thing.def == localWantedPlantDef... RemoveObjectFromAwaitingHaulingHashSets"); #endif PlantSowing_Cache.ReregisterObject(map, c, awaitingPlantCellsMapDict); //JumboCellCache.AddObjectToActionableObjects(map, c, c, awaitingPlantCellsMapDict); return(false); } if ((thing is Blueprint || thing is Frame) && thing.Faction == pawn.Faction) { flag = true; } } if (flag) { Thing edifice = c.GetEdifice(map); if (edifice == null || edifice.def.fertility < 0f) { #if DEBUG Log.Warning("fertility"); #endif return(false); } } if (localWantedPlantDef.plant.cavePlant) { if (!c.Roofed(map)) { #if DEBUG Log.Warning("cavePlant"); #endif return(false); } if (map.glowGrid.GameGlowAt(c, ignoreCavePlants: true) > 0f) { #if DEBUG Log.Warning("GameGlowAt"); #endif return(false); } } if (localWantedPlantDef.plant.interferesWithRoof && c.Roofed(pawn.Map)) { return(false); } Plant plant = c.GetPlant(map); if (plant != null && plant.def.plant.blockAdjacentSow) { if (!pawn.CanReserve(plant, 1, -1, null, forced) || plant.IsForbidden(pawn)) { #if DEBUG Log.Warning("blockAdjacentSow"); #endif return(false); } return(true); // JobMaker.MakeJob(JobDefOf.CutPlant, plant); } Thing thing2 = PlantUtility.AdjacentSowBlocker(localWantedPlantDef, c, map); if (thing2 != null) { Plant plant2 = thing2 as Plant; if (plant2 != null && pawn.CanReserve(plant2, 1, -1, null, forced) && !plant2.IsForbidden(pawn)) { IPlantToGrowSettable plantToGrowSettable = plant2.Position.GetPlantToGrowSettable(plant2.Map); if (plantToGrowSettable == null || plantToGrowSettable.GetPlantDefToGrow() != plant2.def) { return(true); // JobMaker.MakeJob(JobDefOf.CutPlant, plant2); } } #if DEBUG Log.Warning("AdjacentSowBlocker"); #endif PlantSowing_Cache.ReregisterObject(map, c, awaitingPlantCellsMapDict); return(false); } if (localWantedPlantDef.plant.sowMinSkill > 0 && pawn.skills != null && pawn.skills.GetSkill(SkillDefOf.Plants).Level < localWantedPlantDef.plant.sowMinSkill) { #if DEBUG Log.Warning("UnderAllowedSkill"); #endif return(false); } for (int j = 0; j < thingList.Count; j++) { Thing thing3 = thingList[j]; if (!thing3.def.BlocksPlanting()) { continue; } if (!pawn.CanReserve(thing3, 1, -1, null, forced)) { #if DEBUG Log.Warning("!CanReserve"); #endif PlantSowing_Cache.ReregisterObject(map, c, awaitingPlantCellsMapDict); return(false); } if (thing3.def.category == ThingCategory.Plant) { if (!thing3.IsForbidden(pawn)) { return(true); // JobMaker.MakeJob(JobDefOf.CutPlant, thing3); } #if DEBUG Log.Warning("Plant IsForbidden"); #endif PlantSowing_Cache.ReregisterObject(map, c, awaitingPlantCellsMapDict); return(false); } if (thing3.def.EverHaulable) { return(true); //HaulAIUtility.HaulAsideJobFor(pawn, thing3); } #if DEBUG Log.Warning("EverHaulable"); #endif PlantSowing_Cache.ReregisterObject(map, c, awaitingPlantCellsMapDict); return(false); } if (!localWantedPlantDef.CanEverPlantAt(c, map)) { #if DEBUG Log.Warning("CanEverPlantAt_NewTemp"); #endif PlantSowing_Cache.ReregisterObject(map, c, awaitingPlantCellsMapDict); return(false); } if (!PlantUtility.GrowthSeasonNow(c, map, forSowing: true)) { #if DEBUG Log.Warning("GrowthSeasonNow"); #endif return(false); } if (!pawn.CanReserve(c, 1, -1, null, forced)) { #if DEBUG Log.Warning("!pawn.CanReserve(c"); #endif PlantSowing_Cache.ReregisterObject(map, c, awaitingPlantCellsMapDict); //JumboCellCache.AddObjectToActionableObjects(map, c, c, awaitingPlantCellsMapDict); return(false); } //Job job = JobMaker.MakeJob(JobDefOf.Sow, c); //job.plantDefToSow = wantedPlantDef; return(true); //job; }
internal static IntVec3 ClosestLocationReachable(WorkGiver_Grower workGiver_Grower, Pawn pawn) { Danger maxDanger = pawn.NormalMaxDanger(); //wantedPlantDef = null; //List<Zone> zonesList = pawn.Map.zoneManager.AllZones; //for (int j = 0; j < zonesList.Count; j++) //{ //if (growZone.cells.Count == 0) //{ //Log.ErrorOnce("Grow zone has 0 cells: " + growZone, -563487); //} bool forced = false; Map map = pawn.Map; ZoneManager zoneManager = pawn.Map.zoneManager; foreach (IntVec3 actionableLocation in PlantSowing_Cache.GetClosestActionableLocations(pawn, map, awaitingPlantCellsMapDict)) { List <Thing> thingsAtLocation = GridsUtility.GetThingList(actionableLocation, map); foreach (Thing thingAtLocation in thingsAtLocation) { if (thingAtLocation is Building_PlantGrower building_PlantGrower) { if (building_PlantGrower == null || !workGiver_Grower.ExtraRequirements(building_PlantGrower, pawn) || building_PlantGrower.IsForbidden(pawn) || !pawn.CanReach(building_PlantGrower, PathEndMode.OnCell, maxDanger) //|| building_PlantGrower.IsBurning() ) { continue; } //foreach (IntVec3 item in building_PlantGrower.OccupiedRect()) //{ //return item; //TODO ADD check //} return(actionableLocation); } } if (!(zoneManager.ZoneAt(actionableLocation) is Zone_Growing growZone)) { continue; } if (!workGiver_Grower.ExtraRequirements(growZone, pawn)) { continue; } if (!JobOnCellTest(workGiver_Grower.def, pawn, actionableLocation, forced)) { continue; } //!growZone.ContainsStaticFire && if (!workGiver_Grower.HasJobOnCell(pawn, actionableLocation)) { continue; } if (!pawn.CanReach(actionableLocation, PathEndMode.OnCell, maxDanger)) { continue; } return(actionableLocation); } //wantedPlantDef = null; return(IntVec3.Invalid); }
public static void AddObjectToActionableObjects(Map map, IntVec3 location, List <HashSet <IntVec3>[]> awaitingActionZoomLevels) { int jumboCellWidth; int mapSizeX = map.Size.x; int mapSizeZ = map.Size.z; int zoomLevel; //---START--- For plant sowing ThingDef localWantedPlantDef = WorkGiver_Grower.CalculateWantedPlantDef(location, map); if (localWantedPlantDef == null) { return; } List <Thing> thingList = location.GetThingList(map); for (int i = 0; i < thingList.Count; i++) { Thing thing = thingList[i]; if (thing.def == localWantedPlantDef) { return; } } if (map.physicalInteractionReservationManager.IsReserved(location)) { return; } Thing thing2 = PlantUtility.AdjacentSowBlocker(localWantedPlantDef, location, map); if (thing2 != null) { if (thing2 is Plant plant2 && !plant2.IsForbidden(Faction.OfPlayer)) { IPlantToGrowSettable plantToGrowSettable = plant2.Position.GetPlantToGrowSettable(plant2.Map); if (plantToGrowSettable != null && plantToGrowSettable.GetPlantDefToGrow() == plant2.def) { return; } } } for (int j = 0; j < thingList.Count; j++) { Thing thing3 = thingList[j]; if (!thing3.def.BlocksPlanting()) { continue; } if (thing3.def.category == ThingCategory.Plant) { if (!thing3.IsForbidden(Faction.OfPlayer)) { break; // JobMaker.MakeJob(JobDefOf.CutPlant, thing3); } Log.Warning("Plant IsForbidden"); return; } if (thing3.def.EverHaulable) { break; //HaulAIUtility.HaulAsideJobFor(pawn, thing3); } return; } //TODO fix null check? find root cause. Or maybe it was just from a bad save? //if (localWantedPlantDef != null &&!localWantedPlantDef.CanEverPlantAt_NewTemp(location, map, true)) // this change helps with boulders blocking growing zones. likely at a small performance cost if (localWantedPlantDef != null && (!location.InBounds(map) || (double)map.fertilityGrid.FertilityAt(location) < localWantedPlantDef.plant.fertilityMin)) { return; } //---END-- zoomLevel = 0; do { jumboCellWidth = getJumboCellWidth(zoomLevel); HashSet <IntVec3>[] awaitingActionGrid = awaitingActionZoomLevels[zoomLevel]; int jumboCellIndex = CellToIndexCustom(location, mapSizeX, jumboCellWidth); HashSet <IntVec3> hashset = awaitingActionGrid[jumboCellIndex]; if (hashset == null) { hashset = new HashSet <IntVec3>(); lock (awaitingActionGrid) { awaitingActionGrid[jumboCellIndex] = hashset; } } lock (hashset) { hashset.Add(location); } zoomLevel++; } while (jumboCellWidth < mapSizeX || jumboCellWidth < mapSizeZ); }
public static bool JobOnCell(WorkGiver_GrowerSow __instance, ref Job __result, Pawn pawn, IntVec3 c, bool forced = false) { Map map = pawn.Map; if (c.IsForbidden(pawn)) { __result = null; return(false); } if (!PlantUtility.GrowthSeasonNow(c, map, forSowing: true)) { __result = null; return(false); } ThingDef localWantedPlantDef = WorkGiver_Grower.CalculateWantedPlantDef(c, map); wantedPlantDef = localWantedPlantDef; if (localWantedPlantDef == null) { __result = null; return(false); } List <Thing> thingList = c.GetThingList(map); bool flag = false; for (int i = 0; i < thingList.Count; i++) { Thing thing = thingList[i]; if (thing.def == localWantedPlantDef) { __result = null; return(false); } if ((thing is Blueprint || thing is Frame) && thing.Faction == pawn.Faction) { flag = true; } } if (flag) { Thing edifice = c.GetEdifice(map); if (edifice == null || edifice.def.fertility < 0f) { __result = null; return(false); } } if (localWantedPlantDef.plant.cavePlant) { if (!c.Roofed(map)) { JobFailReason.Is(CantSowCavePlantBecauseUnroofedTrans); __result = null; return(false); } if (map.glowGrid.GameGlowAt(c, ignoreCavePlants: true) > 0f) { JobFailReason.Is(CantSowCavePlantBecauseOfLightTrans); __result = null; return(false); } } if (localWantedPlantDef.plant.interferesWithRoof && c.Roofed(pawn.Map)) { __result = null; return(false); } Plant plant = c.GetPlant(map); if (plant != null && plant.def.plant.blockAdjacentSow) { if (!pawn.CanReserve(plant, 1, -1, null, forced) || plant.IsForbidden(pawn)) { __result = null; return(false); } __result = JobMaker.MakeJob(JobDefOf.CutPlant, plant); return(false); } Thing thing2 = PlantUtility.AdjacentSowBlocker(localWantedPlantDef, c, map); if (thing2 != null) { Plant plant2 = thing2 as Plant; if (plant2 != null && pawn.CanReserve(plant2, 1, -1, null, forced) && !plant2.IsForbidden(pawn)) { IPlantToGrowSettable plantToGrowSettable = plant2.Position.GetPlantToGrowSettable(plant2.Map); if (plantToGrowSettable == null || plantToGrowSettable.GetPlantDefToGrow() != plant2.def) { __result = JobMaker.MakeJob(JobDefOf.CutPlant, plant2); return(false); } } __result = null; return(false); } ThingDef thingdef = localWantedPlantDef; if (thingdef != null && thingdef.plant != null && thingdef.plant.sowMinSkill > 0 && pawn != null && pawn.skills != null && pawn.skills.GetSkill(SkillDefOf.Plants).Level < localWantedPlantDef.plant.sowMinSkill) { WorkGiver workGiver = __instance; JobFailReason.Is("UnderAllowedSkill".Translate(localWantedPlantDef.plant.sowMinSkill), workGiver.def.label); __result = null; return(false); } for (int j = 0; j < thingList.Count; j++) { Thing thing3 = thingList[j]; if (!thing3.def.BlocksPlanting()) { continue; } if (!pawn.CanReserve(thing3, 1, -1, null, forced)) { __result = null; return(false); } if (thing3.def.category == ThingCategory.Plant) { if (!thing3.IsForbidden(pawn)) { __result = JobMaker.MakeJob(JobDefOf.CutPlant, thing3); return(false); } __result = null; return(false); } if (thing3.def.EverHaulable) { __result = HaulAIUtility.HaulAsideJobFor(pawn, thing3); return(false); } __result = null; return(false); } if (!localWantedPlantDef.CanEverPlantAt_NewTemp(c, map) || !PlantUtility.GrowthSeasonNow(c, map, forSowing: true) || !pawn.CanReserve(c, 1, -1, null, forced)) { __result = null; return(false); } Job job = JobMaker.MakeJob(JobDefOf.Sow, c); job.plantDefToSow = localWantedPlantDef; __result = job; return(false); }
public static bool PotentialWorkCellsGlobal(WorkGiver_Grower __instance, ref IEnumerable <IntVec3> __result, Pawn pawn) { List <IntVec3> result = new List <IntVec3>(); Danger maxDanger = pawn.NormalMaxDanger(); List <Building_PlantGrower> bList = ListerBuildings_Patch.get_AllBuildingsColonistBuilding_PlantGrower(pawn.Map.listerBuildings); //List<Building> bList = pawn.Map.listerBuildings.allBuildingsColonist; sw1.Reset(); sw2.Reset(); sw3.Reset(); sw4.Reset(); sw5.Reset(); sw6.Reset(); sw7.Reset(); sw7.Start(); for (int j = 0; j < bList.Count; j++) { bool flag = false;; Building_PlantGrower building_PlantGrower = bList[j]; // as Building_PlantGrower; sw1.Start(); flag = building_PlantGrower == null; sw1.Stop(); if (flag) { continue; } sw2.Start(); flag = !ExtraRequirements(building_PlantGrower, pawn); sw2.Stop(); if (flag) { continue; } sw3.Start(); flag = building_PlantGrower.IsForbidden(pawn); sw3.Stop(); if (flag) { continue; } sw4.Start(); flag = !pawn.CanReach(building_PlantGrower, PathEndMode.OnCell, maxDanger); sw4.Stop(); if (flag) { continue; } sw5.Start(); flag = building_PlantGrower.IsBurning(); sw5.Stop(); if (flag) { continue; } sw6.Start(); foreach (IntVec3 item in building_PlantGrower.OccupiedRect()) { result.Add(item); } sw6.Stop(); wantedPlantDef = null; } sw7.Stop(); Log.Message("1: " + sw1.ElapsedMilliseconds.ToString() + "ms"); Log.Message("2: " + sw2.ElapsedMilliseconds.ToString() + "ms"); Log.Message("3: " + sw3.ElapsedMilliseconds.ToString() + "ms"); Log.Message("4: " + sw4.ElapsedMilliseconds.ToString() + "ms"); Log.Message("5: " + sw5.ElapsedMilliseconds.ToString() + "ms"); Log.Message("6: " + sw6.ElapsedMilliseconds.ToString() + "ms"); Log.Message("7: " + sw6.ElapsedMilliseconds.ToString() + "ms"); wantedPlantDef = null; List <Zone> zonesList = pawn.Map.zoneManager.AllZones; for (int j = 0; j < zonesList.Count; j++) { Zone_Growing growZone = zonesList[j] as Zone_Growing; if (growZone == null) { continue; } if (growZone.cells.Count == 0) { Log.ErrorOnce("Grow zone has 0 cells: " + growZone, -563487); } else if (ExtraRequirements(growZone, pawn) && !growZone.ContainsStaticFire && pawn.CanReach(growZone.Cells[0], PathEndMode.OnCell, maxDanger)) { for (int k = 0; k < growZone.cells.Count; k++) { result.Add(growZone.cells[k]); } wantedPlantDef = null; } } wantedPlantDef = null; __result = result; return(false); }