qud-mods/AutoDropBedding/Helpers.cs

123 lines
3.5 KiB
C#
Executable file

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<GameObject> 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<Cell> 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<Cell> 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<Cell> 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<GameObject> 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<GameObject>.XDidY(who, "set out", newBed.a + newBed.ShortDisplayName);
}
}
}
}