using System.Collections.Generic; using Verse; using Verse.AI; using RimWorld; namespace ArachnaeSwarm { public class WorkGiver_ArachnaeSow : WorkGiver_Grower { protected static string CantSowCavePlantBecauseOfLightTrans; protected static string CantSowCavePlantBecauseUnroofedTrans; public override PathEndMode PathEndMode => PathEndMode.ClosestTouch; public static void ResetStaticData() { CantSowCavePlantBecauseOfLightTrans = "CantSowCavePlantBecauseOfLight".Translate(); CantSowCavePlantBecauseUnroofedTrans = "CantSowCavePlantBecauseUnroofed".Translate(); } protected override bool ExtraRequirements(IPlantToGrowSettable settable, Pawn pawn) { if (!settable.CanAcceptSowNow()) { return false; } IntVec3 c; if (settable is Zone_Growing zone_Growing) { if (!zone_Growing.allowSow) { return false; } c = zone_Growing.Cells[0]; } else { c = ((Thing)settable).Position; } ThingDef wantedPlantDef = WorkGiver_Grower.CalculateWantedPlantDef(c, pawn.Map); if (wantedPlantDef == null) { return false; } return true; } public override Job JobOnCell(Pawn pawn, IntVec3 c, bool forced = false) { Map map = pawn.Map; if (c.GetVacuum(pawn.Map) >= 0.5f) { return null; } // 直接计算 wantedPlantDef ThingDef wantedPlantDefLocal = WorkGiver_Grower.CalculateWantedPlantDef(c, map); if (wantedPlantDefLocal == null) { return null; } if (!PlantUtility.GrowthSeasonNow(c, map, wantedPlantDefLocal)) { return null; } List thingList = c.GetThingList(map); Zone_Growing zone_Growing = c.GetZone(map) as Zone_Growing; bool flag = false; for (int i = 0; i < thingList.Count; i++) { Thing thing = thingList[i]; if (thing.def == wantedPlantDefLocal) { return null; } 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) { return null; } } if (wantedPlantDefLocal.plant.diesToLight) { if (!c.Roofed(map) && !map.GameConditionManager.IsAlwaysDarkOutside) { JobFailReason.Is(CantSowCavePlantBecauseUnroofedTrans); return null; } if (map.glowGrid.GroundGlowAt(c, ignoreCavePlants: true) > 0f) { JobFailReason.Is(CantSowCavePlantBecauseOfLightTrans); return null; } } if (wantedPlantDefLocal.plant.interferesWithRoof && c.Roofed(pawn.Map)) { return null; } Plant plant = c.GetPlant(map); if (plant != null) // 只要地块上有植物 { // 如果地块上的植物不是我们想要种植的植物,就割除 if (plant.def != wantedPlantDefLocal) { if (!pawn.CanReserve(plant, 1, -1, null, forced) || plant.IsForbidden(pawn)) { return null; } if (zone_Growing != null && !zone_Growing.allowCut) { return null; } if (!forced && plant.TryGetComp(out var comp) && comp.PreventCutting) { return null; } if (!PlantUtility.PawnWillingToCutPlant_Job(plant, pawn)) { return null; } return JobMaker.MakeJob(JobDefOf.CutPlant, plant); } // 如果地块上的植物是我们想要种植的植物,并且它阻碍了相邻播种,则不割除 // 因为它已经是我们想要种植的植物了 if (plant.def.plant.blockAdjacentSow) { return null; } } Thing thing2 = PlantUtility.AdjacentSowBlocker(wantedPlantDefLocal, c, map); if (thing2 != null) { if (thing2 is Plant plant2) { // 如果阻碍播种的是植物,并且不是我们想要种植的植物,就割除 if (plant2.def != wantedPlantDefLocal) { if (pawn.CanReserveAndReach(plant2, PathEndMode.Touch, Danger.Deadly, 1, -1, null, forced) && !plant2.IsForbidden(pawn)) { IPlantToGrowSettable plantToGrowSettable = plant2.Position.GetPlantToGrowSettable(plant2.Map); if (plantToGrowSettable == null || plantToGrowSettable.GetPlantDefToGrow() != plant2.def) { Zone_Growing zone_Growing2 = c.GetZone(map) as Zone_Growing; Zone_Growing zone_Growing3 = c.GetZone(map) as Zone_Growing; if ((zone_Growing2 != null && !zone_Growing2.allowCut) || (zone_Growing3 != null && !zone_Growing3.allowCut && plant2.def == zone_Growing3.GetPlantDefToGrow())) { return null; } } if (!forced && thing2.TryGetComp(out CompPlantPreventCutting comp2) && comp2.PreventCutting) { return null; } if (!PlantUtility.PawnWillingToCutPlant_Job(plant2, pawn)) { return null; } if (PlantUtility.TreeMarkedForExtraction(plant2)) { return null; } return JobMaker.MakeJob(JobDefOf.CutPlant, plant2); } } } else if (thing2.def.EverHaulable) { return HaulAIUtility.HaulAsideJobFor(pawn, thing2); } return null; } if (wantedPlantDefLocal.plant.sowMinSkill > 0 && ((pawn.skills != null && pawn.skills.GetSkill(SkillDefOf.Plants).Level < wantedPlantDefLocal.plant.sowMinSkill) || (pawn.IsColonyMech && pawn.RaceProps.mechFixedSkillLevel < wantedPlantDefLocal.plant.sowMinSkill))) { JobFailReason.Is("UnderAllowedSkill".Translate(wantedPlantDefLocal.plant.sowMinSkill), def.label); return null; } 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)) { return null; } if (thing3.def.category == ThingCategory.Plant) { // 如果阻碍播种的是植物,并且不是我们想要种植的植物,就割除 if (thing3.def != wantedPlantDefLocal) { if (thing3.IsForbidden(pawn)) { return null; } if (zone_Growing != null && !zone_Growing.allowCut) { return null; } if (!forced && thing3.TryGetComp(out var comp3) && comp3.PreventCutting) { return null; } if (!PlantUtility.PawnWillingToCutPlant_Job(thing3, pawn)) { return null; } if (PlantUtility.TreeMarkedForExtraction(thing3)) { return null; } return JobMaker.MakeJob(JobDefOf.CutPlant, thing3); } } else if (thing3.def.EverHaulable) { return HaulAIUtility.HaulAsideJobFor(pawn, thing3); } return null; } if (!wantedPlantDefLocal.CanNowPlantAt(c, map) || !PlantUtility.GrowthSeasonNow(c, map, wantedPlantDefLocal) || !pawn.CanReserve(c, 1, -1, null, forced)) { return null; } Job job = JobMaker.MakeJob(JobDefOf.Sow, c); job.plantDefToSow = wantedPlantDefLocal; return job; } } }