using System.Collections.Generic; using System.Linq; using XRL.Core; using XRL.Rules; using XRL.World; namespace AutoDropBedding { public static class Helpers { public static void Log(string msg) { if (Config.DebugLogging) UnityEngine.Debug.Log("[AutoDropBedding] " + msg); } public static List GetBedsInInventory(GameObject who = null) { Helpers.Log("Checking for beds in inventory."); return who.Inventory.GetObjects(o => o.HasPart("Bed")); } public static Cell FindNearestCampfire(GameObject who = null) { foreach (var cell in who.CurrentCell.GetAdjacentCells()) { if (cell.HasFirestarter()) { Helpers.Log("Found campfire in cell " + cell.Pos2D.ToString()); return cell; } } Helpers.Log("Couldn't find campfire???"); return null; } public static bool HasBedroll(GameObject who = null) { if (who == null) who = XRLCore.Core?.Game?.Player?.Body; foreach (var _ in GetBedsInInventory(who)) return true; return false; } public static Cell PickBedrollCell(Cell dropperCell, Cell campfireCell) { if (dropperCell == null) dropperCell = XRLCore.Core?.Game?.Player?.Body.CurrentCell; if (campfireCell == null) campfireCell = FindNearestCampfire(XRLCore.Core?.Game?.Player?.Body); Log("Picking cell for bed."); List nearDropperCells = dropperCell.GetAdjacentCells(); nearDropperCells.Add(dropperCell); // ensure bedroll isn't dropped in campfire if dropper is in same cell if (campfireCell == null) { Log("Couldn't find a campfire anywhere, falling back to player cell."); return dropperCell; } string nearbyMsg = "cells nearby: "; nearDropperCells.ForEach(cell => nearbyMsg += cell.Pos2D.ToString() + " "); Log(nearbyMsg); List nearCampfireCells = campfireCell.GetAdjacentCells() .Where(cell => cell.IsEmpty() && cell.IsVisible() && !cell.HasFirestarter() && !cell.HasAnyLiquid()) .ToList(); string campMsg = "cells nearby campfire: "; nearCampfireCells.ForEach(cell => campMsg += cell.Pos2D.ToString() + " "); Log(campMsg); List commonCells = nearDropperCells.Intersect(nearCampfireCells).ToList(); string commonMsg = "common cells: "; commonCells.ForEach(cell => commonMsg += cell.Pos2D.ToString() + " "); Log(commonMsg); // return random cell adjacent to both campfire and bedroll dropper, or dropper cell if none int randy = Stat.GetSeededRandomGenerator(dropperCell.Pos2D.ToString()).Next(0, commonCells.Count); return commonCells.Count > 0 ? commonCells[randy] : dropperCell; } public static void PutDownBedroll(GameObject who = null, Cell campfireCell = null, bool first = false) { if (who == null) who = XRLCore.Core?.Game?.Player?.Body; if (campfireCell == null) campfireCell = FindNearestCampfire(who); if (HasBedroll(who)) { Cell bedrollCell = PickBedrollCell(who.CurrentCell, campfireCell); GameObject bed; List beds = GetBedsInInventory(who); if (first || beds.Count == 1) bed = beds[0]; else bed = XRL.UI.PickItem.ShowPicker(beds); // why isn't there Inventory.Drop() or something var newBed = bedrollCell.AddObject(bed); who.Inventory.RemoveObject(bed); Log("Putting " + newBed.ShortDisplayName + " into cell."); IComponent.XDidY(who, "set out", newBed.a + newBed.ShortDisplayName); } } } }