commit e1fd2d30d6077041816703820e077fb5e489617f Author: Lilian Jónsdóttir Date: Mon Dec 18 22:24:51 2023 -0800 AutoDropBedding 1.1.0 diff --git a/AutoDropBedding/AutoDropBeddingMenu.cs b/AutoDropBedding/AutoDropBeddingMenu.cs new file mode 100755 index 0000000..284ad00 --- /dev/null +++ b/AutoDropBedding/AutoDropBeddingMenu.cs @@ -0,0 +1,41 @@ +using AutoDropBedding; + +namespace XRL.World.Parts +{ + public class AutoDropBeddingMenu : IPart + { + private static string NAME = "SetUpBedroll"; + + public override bool WantEvent(int ID, int cascade) => + ID == InventoryActionEvent.ID || + ID == GetCookingActionsEvent.ID || + base.WantEvent(ID, cascade); + + public override bool HandleEvent(GetCookingActionsEvent E) + { + if (Config.AddMenuOptionToCamp && Helpers.HasBedroll()) + { + Helpers.Log("Adding menu option."); + E.AddAction(NAME, + "Lay out bedding", + NAME, + Key: 'b', + Default: 0, + Priority: 200); + } + + return base.HandleEvent(E); + } + + public override bool HandleEvent(InventoryActionEvent E) + { + if (E.Command == NAME) + { + Helpers.Log("Got setup bed command."); + Helpers.PutDownBedroll(campfireCell: E.CellTarget); + E.RequestInterfaceExit(); + } + return base.HandleEvent(E); + } + } +} diff --git a/AutoDropBedding/Config.cs b/AutoDropBedding/Config.cs new file mode 100755 index 0000000..fefb4a4 --- /dev/null +++ b/AutoDropBedding/Config.cs @@ -0,0 +1,12 @@ +using static XRL.UI.Options; + +namespace AutoDropBedding +{ + public static class Config + { + public static bool AutoDrop => GetOption("AutoDropBedding_AutoDrop").EqualsNoCase("Yes"); + public static bool AddMenuOptionToCamp => GetOption("AutoDropBedding_AddMenuOptionToCamp").EqualsNoCase("Yes"); + public static bool DebugLogging => GetOption("AutoDropBedding_DebugLogging").EqualsNoCase("Yes"); + public static bool CompanionDrop => GetOption("AutoDropbedding_CompanionDrop").EqualsNoCase("Yes"); + } +} diff --git a/AutoDropBedding/Extensions.cs b/AutoDropBedding/Extensions.cs new file mode 100755 index 0000000..b415524 --- /dev/null +++ b/AutoDropBedding/Extensions.cs @@ -0,0 +1,30 @@ +using System; +using System.Collections.Generic; +using XRL.World; + +// maybe this is a little extra but whatever +namespace AutoDropBedding +{ + public static class Extensions + { + // todo: find other things that set bedding on fire + private static readonly List Firestarters = new List() {"Campfire", "BlueCampfire"}; + + public static bool HasAnyLiquid(this Cell cell) + { + foreach (var _ in cell.GetObjects(o => o.HasPart("LiquidVolume"))) + return true; + return false; + } + + public static bool HasFirestarter(this Cell cell) + { + foreach (string thing in Firestarters) + { + if (cell.HasObject(thing)) + return true; + } + return false; + } + } +} diff --git a/AutoDropBedding/HarmonyPatches/Patch_Survival_Camp.cs b/AutoDropBedding/HarmonyPatches/Patch_Survival_Camp.cs new file mode 100755 index 0000000..aba1038 --- /dev/null +++ b/AutoDropBedding/HarmonyPatches/Patch_Survival_Camp.cs @@ -0,0 +1,25 @@ +using HarmonyLib; +using XRL.World; +using XRL.World.Parts.Skill; + +namespace AutoDropBedding.HarmonyPatches +{ + [HarmonyPatch(typeof(Survival_Camp), nameof(Survival_Camp.AttemptCamp))] + public static class Patch_Survival_Camp + { + public static void Postfix(ref bool __result, GameObject Actor) + { + if (__result && Actor.IsPlayer() && Config.AutoDrop) + { + Helpers.PutDownBedroll(who: Actor, first: true); + if (Config.CompanionDrop) + { + foreach (var companion in Actor.GetCompanions()) + { + Helpers.PutDownBedroll(who: companion, first: true); + } + } + } + } + } +} diff --git a/AutoDropBedding/Helpers.cs b/AutoDropBedding/Helpers.cs new file mode 100755 index 0000000..8b77e01 --- /dev/null +++ b/AutoDropBedding/Helpers.cs @@ -0,0 +1,122 @@ +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); + } + } + } +} diff --git a/AutoDropBedding/ObjectBlueprints.xml b/AutoDropBedding/ObjectBlueprints.xml new file mode 100755 index 0000000..e60957b --- /dev/null +++ b/AutoDropBedding/ObjectBlueprints.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/AutoDropBedding/Options.xml b/AutoDropBedding/Options.xml new file mode 100755 index 0000000..e7015f6 --- /dev/null +++ b/AutoDropBedding/Options.xml @@ -0,0 +1,7 @@ + + + diff --git a/AutoDropBedding/manifest.json b/AutoDropBedding/manifest.json new file mode 100755 index 0000000..2f124b2 --- /dev/null +++ b/AutoDropBedding/manifest.json @@ -0,0 +1,8 @@ +{ + "id": "AutoDropBedding", + "title": "{{auto drop bedding|Auto Drop Bedding}}", + "description": "Put out a bedroll when you make camp, if you have one. Also adds the option to lay out bedding to the campfire menu.", + "version": "1.1.0", + "author": "{{paisley|Celediel}}", + "previewImage": "preview.png" +} \ No newline at end of file diff --git a/AutoDropBedding/preview.png b/AutoDropBedding/preview.png new file mode 100755 index 0000000..8ac6f7a Binary files /dev/null and b/AutoDropBedding/preview.png differ diff --git a/AutoDropBedding/screenshot_campfire.png b/AutoDropBedding/screenshot_campfire.png new file mode 100755 index 0000000..8ac6f7a Binary files /dev/null and b/AutoDropBedding/screenshot_campfire.png differ diff --git a/AutoDropBedding/screenshot_menu.png b/AutoDropBedding/screenshot_menu.png new file mode 100755 index 0000000..0c42178 Binary files /dev/null and b/AutoDropBedding/screenshot_menu.png differ diff --git a/AutoDropBedding/workshop.json b/AutoDropBedding/workshop.json new file mode 100755 index 0000000..44ffe8a --- /dev/null +++ b/AutoDropBedding/workshop.json @@ -0,0 +1,8 @@ +{ + "WorkshopId": 2721168249, + "Title": "Auto Drop Bedding", + "Description": "Put out a bedroll when you make camp, if you have one. Also adds the option to lay out bedding to the campfire menu.", + "Tags": "Script,UX", + "Visibility": "2", + "ImagePath": "preview.png" +} \ No newline at end of file