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; } } } }
public BedState(BedTracker.Bed bed, bool state) { Bed = bed; State = state; }