Exemple #1
0
        public static void TentBlueprintRect(Thing constructible, ref Thing __result)
        {
            if (constructible is TentBlueprint_Install tbi && tbi.ThingToInstall is NCS_Tent tent)
            {
                __result = null;

                foreach (var se in tent.sketch.Entities)
                {
                    foreach (var t in se.OccupiedRect.MovedBy(constructible.Position).SelectMany(c => c.GetThingList(constructible.Map)))
                    {
                        if (
                            (se is SketchRoof && (                             //allow early fail out so edge cases only have to be checked once (cells in SketchRoof will be a super set of the cells from other entities)
                                 t is Plant ||                                 // only check plants under roofs, other stuff will be checked again if it collides with buildables (walls/ doors)
                                 !(t is Pawn p && p.IsColonistPlayerControlled)
                                 )) &&
                            t != tbi.MiniToInstallOrBuildingToReinstall &&
                            !(t.TryGetComp <TentSpawnedComp>() is TentSpawnedComp tsc && tsc.tent.Equals(tent)) &&                            // Ignore buildings spawned by the tent (since they'll get vanished)
                            GenConstruct.BlocksConstruction(constructible, t)
                            )
                        {
                            __result = t;
                            return;
                        }
                    }
                }
            }
        }
        public static bool IsGoodStoreCell(IntVec3 c, Map map, Thing t, Pawn carrier, Faction faction)
        {
            if (carrier != null && c.IsForbidden(carrier))
            {
                return(false);
            }

            if (!(bool)_noStorageBlockersInMethod.Invoke(null, new object[] { c, map, t }))
            {
                Log.Error("Storage blockers found at " + c + " for " + t);
                return(false);
            }
            if (carrier != null)
            {
                if (!carrier.CanReserveNew(c))
                {
                    Log.Error("Carrier " + carrier + " can't reserve new at " + c);
                    return(false);
                }
            }
            else if (faction != null)
            {
                var pawn = GetReservationClaimant(map.reservationManager, c, faction);
                if (pawn != null)
                {
                    // Pawn Drone, ProjectRimFactory.Drones.Pawn_Drone, PRFDrone, Dorks
                    Log.Error("Pawn " + pawn + ", " + pawn.def.thingClass.FullName + ", " + pawn.def.defName + ", " + pawn.Faction + " already reserved " + c);
                    return(false);
                }
            }
            if (c.ContainsStaticFire(map))
            {
                Log.Message("Fire at " + c);
                return(false);
            }
            List <Thing> thingList = c.GetThingList(map);

            for (int i = 0; i < thingList.Count; i++)
            {
                if (thingList[i] is IConstructible && GenConstruct.BlocksConstruction(thingList[i], t))
                {
                    Log.Error("BlocksConstruction at " + c);
                    return(false);
                }
            }
            return(carrier == null || carrier.Map.reachability.CanReach(t.SpawnedOrAnyParentSpawned ? t.PositionHeld : carrier.PositionHeld, c, PathEndMode.ClosestTouch, TraverseParms.For(carrier, Danger.Deadly, TraverseMode.ByPawn, false, false, false)));
        }
        public static Thing FirstReservableBlockingThing(Thing constructible, Pawn pawnToIgnore)
        {
            Thing thing = constructible is Blueprint b?GenConstruct.MiniToInstallOrBuildingToReinstall(b) : null;

            foreach (var pos in constructible.OccupiedRect())
            {
                foreach (Thing t in pos.GetThingList(constructible.Map))
                {
                    if (GenConstruct.BlocksConstruction(constructible, t) && t != pawnToIgnore && t != thing && pawnToIgnore.CanReserve(t))
                    {
                        return(t);
                    }
                }
            }

            return(null);
        }
        private static void ResolveDeadLock(RemoveRoofModel model)
        {
            foreach (Thing thing in model.WaitingThings.ToList())
            {
                Thing        lastFound   = thing;
                List <Thing> foundThings = new List <Thing>()
                {
                    lastFound
                };

                while (true)
                {
                    IntVec3        spawnCell = GetDeltaCell(lastFound, model.MousePos, model.GhostPosition);
                    List <IntVec3> rect      = GenAdj.OccupiedRect(spawnCell, lastFound.Rotate(model.Rotation), lastFound.def.size).ToList();
                    if (lastFound.def.hasInteractionCell)
                    {
                        rect.Add(Verse.ThingUtility.InteractionCellWhenAt(lastFound.def, spawnCell, lastFound.Rotate(model.Rotation), lastFound.MapHeld));
                    }
                    IEnumerable <Thing> thingsOnCell = rect.SelectMany(c => c.GetThingList(lastFound.MapHeld).Where(t => t.def.blueprintDef != null && t.def.Minifiable));
                    lastFound = thingsOnCell.FirstOrDefault(t => GenConstruct.BlocksConstruction(lastFound, t) && model.WaitingThings.Contains(t))
                                ?? ThingUtility.BlockAdjacentInteractionCell(lastFound, spawnCell, lastFound.Rotate(model.Rotation));
                    if (lastFound == null || foundThings.Contains(lastFound))
                    {
                        break;
                    }

                    foundThings.Add(lastFound);
                }

                if (lastFound == null)
                {
                    continue;
                }
                else
                {
                    thing.Map.designationManager.AddDesignation(new Designation(thing, DesignationDefOf.Uninstall));
                }
            }
        }
Exemple #5
0
        public static IEnumerable <Thing> MakeWayFor(Thing blueprint, ThingCategory category)
        {
            if (blueprint.Faction != Faction.OfPlayer)
            {
                yield break;
            }

            Map map = blueprint.Map;

            foreach (IntVec3 cell in GenAdj.CellsOccupiedBy(blueprint))
            {
                foreach (Thing thing in cell.GetThingList(map))
                {
                    if (thing.def.category == category)
                    {
                        if (GenConstruct.BlocksConstruction(blueprint, thing))
                        {
                            yield return(thing);
                        }
                    }
                }
            }
        }
Exemple #6
0
        // RimWorld.PawnUtility.PawnBlockingPathAt
        public static Thing ThingBlockingPathAt(IntVec3 c, Thing thing)
        {
            List <Thing> thingList = c.GetThingList(thing.Map);

            if (thingList.Count == 0)
            {
                return(null);
            }

            for (int i = 0; i < thingList.Count; i++)
            {
                Thing thing2 = thingList[i];
                if (thing.def.EverHaulable)
                {
                    if (GenConstruct.BlocksConstruction(thing, thing2)) //&& thing != pawnToIgnore && thing != thingToIgnore)
                    {
                        return(thing);
                    }
                }
            }

            return(null);
        }
        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);
        }
        public override void DesignateSingleCell(IntVec3 c)
        {
            if (_mode == Mode.Select)
            {
                List <Thing> things = this.ReinstallableInCell(c);
                if (things.Any())
                {
                    if (_originFound == false)
                    {
                        _originFound = true;
                        _origin      = c;
                    }

                    DesignatedThings.AddRange(things);
                    things.ForEach(thing => DesignateThing(thing));
                }
            }
            else if (_mode == Mode.Place)
            {
                GenConstruct_CanPlaceBlueprintAt_Patch.Mode = BlueprintMode.Place;
                HashSet <Thing>                       placedThings  = new HashSet <Thing>();
                Dictionary <Thing, Thing>             twinThings    = new Dictionary <Thing, Thing>();
                Dictionary <Thing, Blueprint_Install> blueprintWork = new Dictionary <Thing, Blueprint_Install>();
                Dictionary <Thing, IntVec3>           siblingWork   = new Dictionary <Thing, IntVec3>();

                IntVec3 mousePos = UI.MouseCell();
                foreach (Thing designatedThing in DesignatedThings)
                {
                    IntVec3      drawCell     = GetDeltaCell(designatedThing, mousePos, _ghostPos);
                    List <Thing> things       = drawCell.GetThingList(designatedThing.MapHeld);
                    bool         foundTwin    = false;
                    bool         foundSibling = false;
                    foreach (Thing thingOnCell in things)
                    {
                        if (DesignatedThings.Contains(thingOnCell))
                        {
                            if (designatedThing.IdenticalWith(_rotation, thingOnCell))
                            {
                                if (blueprintWork.TryGetValue(thingOnCell, out Blueprint_Install install))
                                {
                                    Thing twin = this.GetTailInTwinThings(twinThings, designatedThing);

                                    _setBuildingToReinstall.Invoke(install, new[] { twin });
                                    blueprintWork[twin] = install;
                                    blueprintWork.Remove(thingOnCell);
                                    placedThings.Add(twin);
                                }
                                else if (siblingWork.TryGetValue(thingOnCell, out IntVec3 position))
                                {
                                    Thing twin = this.GetTailInTwinThings(twinThings, designatedThing);
                                    _ghostPos[twin] = position;
                                    siblingWork.Remove(thingOnCell);
                                    siblingWork[twin] = position;
                                    placedThings.Add(thingOnCell);
                                }
                                else
                                {
                                    twinThings[thingOnCell]    = designatedThing;
                                    _ghostPos[designatedThing] = _ghostPos[thingOnCell];
                                    placedThings.Add(thingOnCell);
                                }

                                this.Map.designationManager.TryRemoveDesignationOn(thingOnCell, MoveBaseDefOf.MoveBase);

                                foundTwin = true;
                                break;
                            }
                            else if (!GenConstruct.BlocksConstruction(designatedThing, thingOnCell))
                            {
                                continue;
                            }
                            else
                            {
                                foundSibling = true;
                                Thing twin = this.GetTailInTwinThings(twinThings, designatedThing);
                                siblingWork[twin] = _ghostPos[twin] = _ghostPos[designatedThing];
                                break;
                            }
                        }
                    }

                    if (foundTwin || foundSibling)
                    {
                        continue;
                    }

                    Thing twin1 = this.GetTailInTwinThings(twinThings, designatedThing);


                    AcceptanceReport report = GenConstruct.CanPlaceBlueprintAt(
                        twin1.def
                        , drawCell
                        , GetRotation(twin1)
                        , twin1.MapHeld
                        , false
                        , null
                        , twin1);

                    if (report.Accepted)
                    {
                        Building building = twin1 as Building;
                        blueprintWork[building] = GenConstruct.PlaceBlueprintForReinstall(building, drawCell, building.MapHeld, GetRotation(building), Faction.OfPlayer);
                        placedThings.Add(building);
                    }
                }

                RemoveRoofModel model =
                    InitModel(
                        DesignatedThings
                        , DesignatedThings.Except(placedThings).ToList()
                        , DesignatedThings.First().MapHeld
                        , mousePos
                        , _rotation
                        , _ghostPos);

                ResolveDeadLock(model);

                this.KeepDesignation = true;
                _mode = Mode.Select;
                Find.DesignatorManager.Deselect();
            }
        }
Exemple #9
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
                };
            }
        }