Exemplo n.º 1
0
        static Job FindBedrollJob(Job fallbackJob, Pawn pawn)
        {
            if (!pawn.IsColonistPlayerControlled)
            {
                return(fallbackJob);
            }
            Log.Message(pawn + " looking for inventory beds");

            MinifiedThing invBed = (MinifiedThing)FindMinifiedBed(pawn);

            if (invBed == null)
            {
                return(fallbackJob);
            }
            Log.Message(pawn + " found " + invBed);

            Map          map = pawn.Map;
            Building_Bed bed = (Building_Bed)invBed.GetInnerIfMinified();

            Func <IntVec3, Rot4, bool> cellValidatorDir = delegate(IntVec3 c, Rot4 direction)
            {
                if (RegionAndRoomQuery.RoomAtFast(c, map).isPrisonCell != pawn.IsPrisoner)
                {
                    return(false);
                }

                if (!GenConstruct.CanPlaceBlueprintAt(invBed.GetInnerIfMinified().def, c, direction, map).Accepted)
                {
                    return(false);
                }

                if (c.IsForbidden(pawn))
                {
                    return(false);
                }

                for (CellRect.CellRectIterator iterator = GenAdj.OccupiedRect(c, direction, bed.def.size).GetIterator();
                     !iterator.Done(); iterator.MoveNext())
                {
                    foreach (Thing t in iterator.Current.GetThingList(map))
                    {
                        if (!(t is Pawn) && GenConstruct.BlocksConstruction(bed, t))
                        {
                            return(false);
                        }
                    }
                    if (!(map.zoneManager.ZoneAt(c) is null))
                    {
                        return(false);
                    }
                }

                return(true);
            };

            // North/East would be redundant, except for cells on edge ; oh well, too much code to handle that
            Predicate <IntVec3> cellValidator = c => cellValidatorDir(c, Rot4.South) || cellValidatorDir(c, Rot4.West);

            Predicate <IntVec3> goodCellValidator = c =>
                                                    !RegionAndRoomQuery.RoomAt(c, map).PsychologicallyOutdoors&& cellValidator(c);

            IntVec3       placePosition = IntVec3.Invalid;
            IntVec3       root          = pawn.Position;
            TraverseParms trav          = TraverseParms.For(pawn);

            if (!CellFinder.TryFindRandomReachableCellNear(root, map, 4, trav, goodCellValidator, null, out placePosition))
            {
                if (!CellFinder.TryFindRandomReachableCellNear(root, map, 12, trav, goodCellValidator, null, out placePosition))
                {
                    if (!CellFinder.TryFindRandomReachableCellNear(root, map, 4, trav, cellValidator, null, out placePosition))
                    {
                        CellFinder.TryFindRandomReachableCellNear(root, map, 12, trav, cellValidator, null, out placePosition);
                    }
                }
            }

            if (placePosition.IsValid)
            {
                Rot4 dir = cellValidatorDir(placePosition, Rot4.South) ? Rot4.South : Rot4.West;
                Blueprint_Install blueprint = GenConstruct.PlaceBlueprintForInstall(invBed, placePosition, map, dir, pawn.Faction);

                Log.Message(pawn + " placing " + blueprint + " at " + placePosition);

                return(new Job(JobDefOf.PlaceBedroll, invBed, blueprint)
                {
                    haulMode = HaulMode.ToContainer
                });
            }
            Log.Message(pawn + " couldn't find place for " + invBed);

            return(fallbackJob);
        }
Exemplo n.º 2
0
        //protected override Job TryGiveJob(Pawn pawn)
        public static void Postfix(ref Job __result, Pawn pawn)
        {
            if (__result == null)
            {
                return;
            }

            if (!pawn.IsColonistPlayerControlled)
            {
                return;
            }

            Map map = pawn.Map;

            if (!Settings.Get().alsoColonies&& map.IsPlayerHome)
            {
                if (!Settings.Get().alsoColoniesKnown)
                {
                    Settings.Get().alsoColoniesKnown = true;
                    Settings.Get().Write();
                    Find.LetterStack.ReceiveLetter("TD.UseBedrollsUpdated".Translate(),
                                                   TranslatorFormattedStringExtensions.Translate("TD.UpdateNewsColonyMaps", pawn),
                                                   LetterDefOf.NeutralEvent, pawn);
                    // I don't think this really needs to be hugslibs update news or anything. alsoColoniesKnown defaults
                }
                return;
            }

            if (__result.targetA.Thing is Building_Bed ownedBed)
            {
                if (!Settings.Get().distanceCheck || (ownedBed.Position).DistanceTo(pawn.Position) < Settings.Get().distance)
                {
                    return;                    //Have a bed that close enough, no need to get from inventory
                }
            }

            MinifiedThing invBed = (MinifiedThing)FindMinifiedBed(pawn);

            if (invBed == null)
            {
                return;
            }
            Log.Message($"{pawn} found {invBed}");
            Building_Bed bed = (Building_Bed)invBed.GetInnerIfMinified();

            Func <IntVec3, Rot4, bool> cellValidatorDir = delegate(IntVec3 c, Rot4 direction)
            {
                if (RegionAndRoomQuery.RoomAt(c, map).isPrisonCell != pawn.IsPrisoner)
                {
                    return(false);
                }

                if (!GenConstruct.CanPlaceBlueprintAt(invBed.GetInnerIfMinified().def, c, direction, map).Accepted)
                {
                    return(false);
                }

                //Support ReplaceStuff allowing blueprints over beds
                if (EdificeBlocking(invBed.GetInnerIfMinified().def, c, direction, map))
                {
                    return(false);
                }

                if (!GenConstruct.CanPlaceBlueprintAt(invBed.GetInnerIfMinified().def, c, direction, map).Accepted)
                {
                    return(false);
                }

                //Each cell of bed:
                foreach (var pos in GenAdj.OccupiedRect(c, direction, bed.def.size))
                {
                    if (map.zoneManager.ZoneAt(pos) != null)
                    {
                        return(false);
                    }
                    foreach (Thing t in pos.GetThingList(map))
                    {
                        if (!(t is Pawn) && GenConstruct.BlocksConstruction(bed, t))
                        {
                            return(false);
                        }
                    }
                }

                return(true);
            };

            IntVec3 root = invBed.PositionHeld;

            // North/East would be redundant, except for cells on edge ; oh well, too much code to handle that
            Predicate <IntVec3> cellValidator = delegate(IntVec3 c)
            {
                if (!cellValidatorDir(c, Rot4.South) && !cellValidatorDir(c, Rot4.West))
                {
                    return(false);
                }
                using (PawnPath path = map.pathFinder.FindPath(root, c, pawn))
                {
                    return(path.TotalCost < 500);
                }
            };

            Predicate <IntVec3> goodCellValidator = c =>
                                                    !RegionAndRoomQuery.RoomAt(c, map).PsychologicallyOutdoors&& cellValidator(c);

            IntVec3       placePosition = IntVec3.Invalid;
            TraverseParms trav          = TraverseParms.For(pawn);

            if (!CellFinder.TryFindRandomReachableCellNear(root, map, 4, trav, goodCellValidator, null, out placePosition))
            {
                if (!CellFinder.TryFindRandomReachableCellNear(root, map, 12, trav, goodCellValidator, null, out placePosition))
                {
                    if (!CellFinder.TryFindRandomReachableCellNear(root, map, 4, trav, cellValidator, null, out placePosition))
                    {
                        CellFinder.TryFindRandomReachableCellNear(root, map, 12, trav, cellValidator, null, out placePosition);
                    }
                }
            }

            if (placePosition.IsValid)
            {
                Rot4 dir = cellValidatorDir(placePosition, Rot4.South) ? Rot4.South : Rot4.West;
                Blueprint_Install blueprint = GenConstruct.PlaceBlueprintForInstall(invBed, placePosition, map, dir, pawn.Faction);

                Log.Message($"{pawn} placing {blueprint} at {placePosition}");

                __result = new Job(JobDefOf.PlaceBedroll, invBed, blueprint)
                {
                    haulMode = HaulMode.ToContainer
                };
            }
        }