private static void ForEachAction(Vector3Int position, bool bedIsUsed, BedTracker.Bed bed, ref BedStateObject stateObject)
 {
     if (bed.Colony == stateObject.Colony && !stateObject.Beds.ContainsKey(bed))
     {
         stateObject.Beds.Add(bed, new CachedBedState()
         {
             Position = position, Taken = bedIsUsed
         });
     }
 }
 static void Postfix(ColonyBeds __instance, ref bool __result, Vector3Int position, ref Vector3Int bedPosition, ref BedTracker.Bed bed, int boxradius)
 {
     if (!__result)
     {
         // Log.WriteWarning("   ... But game did not find a bed either");
     }
 }
        static bool Prefix(ColonyBeds __instance, ref bool __result, Vector3Int position, out Vector3Int bedPosition, out BedTracker.Bed bed, int boxradius)
        {
            bed         = null;
            bedPosition = Vector3Int.invalidPos;

            if (__instance.Owner == null)
            {
                return(true);
            }

            var trackers = CustomBedTracker.trackers;

            lock (trackers)
            {
                CustomBedTracker tracker;
                if (!trackers.TryGetValue(__instance.Owner, out tracker))
                {
                    return(true);
                }

                lock (tracker)
                {
                    if (tracker.TryGetClosestUnused(position, out bedPosition, out bed, boxradius))
                    {
                        __result = true;
                        return(false);
                    }
                }
            }

            // Log.WriteWarning("FindCloserBed: Did not find any available beds");
            return(true);
        }
        public bool TryGetClosestUnused(Vector3Int position, out Vector3Int bedPosition, out BedTracker.Bed bed, int boxradius)
        {
            Vector3Int address = Chunk.GetChunkAddress(position);

            bedPosition = Vector3Int.invalidPos;
            bed         = null;

            int chunkRadius = (boxradius / Chunk.ChunkSize) + 1;
            int bedDistance = boxradius;

            lock (chunks)
            {
                Chunk chunk;
                if (chunks.TryGetValue(address, out chunk))
                {
                    FindClosestBed(chunk, position, ref bedPosition, ref bed, ref bedDistance);
                }

                for (int currentStep = 1; currentStep <= chunkRadius; ++currentStep)
                {
                    Vector3Int minimum = address - currentStep;
                    Vector3Int maximum = address + currentStep;

                    for (int x = minimum.x; x <= maximum.x; ++x)
                    {
                        for (int y = minimum.y; y <= maximum.y; ++y)
                        {
                            for (int z = minimum.y; z <= maximum.z; ++z)
                            {
                                if (chunks.TryGetValue(new Vector3Int(x, y, z), out chunk))
                                {
                                    FindClosestBed(chunk, position, ref bedPosition, ref bed, ref bedDistance);
                                }
                            }
                        }
                    }

                    if (bed != null)
                    {
                        return(true);
                    }
                }
            }

            return(bed != null);
        }
        private void FindClosestBed(Chunk chunk, Vector3Int position, ref Vector3Int bedPosition, ref BedTracker.Bed bed, ref int bedDistance)
        {
            if (chunk.AvailableBeds == 0)
            {
                return;
            }

            if (chunk.AvailableBeds < OptimizationAvailableBedThreshold && !chunk.WithinRange(position, bedDistance))
            {
                return;
            }

            int resultDistance = bedDistance * bedDistance;

            lock (chunk)
            {
                foreach (var bedEntry in chunk.Beds)
                {
                    var localBed = bedEntry.Value;

                    if (localBed.State || !localBed.Bed.IsValid)
                    {
                        continue;
                    }

                    var localBedPos = bedEntry.Key;

                    int distance = (localBedPos - position).Magnitude;
                    if (distance < resultDistance)
                    {
                        resultDistance = distance;
                        bedDistance    = Math.Sqrt(distance);
                        bedPosition    = localBedPos;
                        bed            = localBed.Bed;
                    }
                }
            }
        }
Beispiel #6
0
 public BedState(BedTracker.Bed bed, bool state)
 {
     Bed   = bed;
     State = state;
 }