123 lines
3.5 KiB
C#
123 lines
3.5 KiB
C#
|
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);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|