Added support for hot tubs

This commit is contained in:
2026-09-06 02:59:49 +02:00
parent 6a3ec60c22
commit 6519ec5d97
+228 -54
View File
@@ -1,7 +1,8 @@
using BepInEx; using BepInEx;
using BepInEx.Configuration; using BepInEx.Configuration;
using UnityEngine;
using System.Collections.Generic; using System.Collections.Generic;
using UnityEngine;
using static UnityEngine.GraphicsBuffer;
namespace AutoRefillFires namespace AutoRefillFires
{ {
@@ -45,6 +46,7 @@ namespace AutoRefillFires
private ConfigEntry<bool> _fillWallTorches; private ConfigEntry<bool> _fillWallTorches;
private ConfigEntry<bool> _fillBraziers; private ConfigEntry<bool> _fillBraziers;
private ConfigEntry<bool> _fillBonfires; private ConfigEntry<bool> _fillBonfires;
private ConfigEntry<bool> _fillHotTubs;
private ConfigEntry<bool> _fillOtherFireplaces; private ConfigEntry<bool> _fillOtherFireplaces;
private ConfigEntry<int> _keepFuelReserve; private ConfigEntry<int> _keepFuelReserve;
private ConfigEntry<FuelSourcePriority> _fuelSourcePriority; private ConfigEntry<FuelSourcePriority> _fuelSourcePriority;
@@ -160,6 +162,13 @@ namespace AutoRefillFires
"Automatically refill bonfires." "Automatically refill bonfires."
); );
_fillHotTubs = Config.Bind(
"Fireplace Types",
"FillHotTubs",
true,
"Automatically refill hot tubs."
);
_fillOtherFireplaces = Config.Bind( _fillOtherFireplaces = Config.Bind(
"Fireplace Types", "Fireplace Types",
"FillOtherFireplaces", "FillOtherFireplaces",
@@ -297,6 +306,11 @@ namespace AutoRefillFires
result = _fillBonfires.Value; result = _fillBonfires.Value;
matchedRule = "FillBonfires"; matchedRule = "FillBonfires";
} }
else if (objectName.Contains("hottub") || objectName.Contains("hot_tub"))
{
result = _fillHotTubs.Value;
matchedRule = "FillHotTubs";
}
else else
{ {
result = _fillOtherFireplaces.Value; result = _fillOtherFireplaces.Value;
@@ -319,6 +333,17 @@ namespace AutoRefillFires
FindObjectsSortMode.None FindObjectsSortMode.None
); );
Smelter[] smelters = null;
if (_fillHotTubs.Value)
{
smelters =
Object.FindObjectsByType<Smelter>(
FindObjectsInactive.Exclude,
FindObjectsSortMode.None
);
}
Container[] containers = null; Container[] containers = null;
if (_useNearbyContainers.Value) if (_useNearbyContainers.Value)
@@ -432,9 +457,197 @@ namespace AutoRefillFires
); );
} }
if (_fillHotTubs.Value && smelters != null)
{
RefillNearbyHotTubs(
player,
smelters,
containers
);
}
LogDebug("Scan end."); LogDebug("Scan end.");
} }
private void RefillNearbyHotTubs(
Player player,
Smelter[] smelters,
Container[] containers)
{
int hotTubsInRange = 0;
foreach (Smelter smelter in smelters)
{
if (smelter == null)
continue;
string objectName =
smelter.gameObject.name
.Replace("(Clone)", "")
.ToLowerInvariant();
if (objectName != "piece_bathtub")
continue;
float distance = Vector3.Distance(
player.transform.position,
smelter.transform.position
);
if (distance > _radius.Value)
continue;
hotTubsInRange++;
LogDebug(
$"Hot tub in range: " +
$"name='{smelter.gameObject.name}', " +
$"distance={distance:0.0}m"
);
TryRefillHotTub(
player,
smelter,
containers
);
}
LogDebug(
$"Hot tub scan end: inRange={hotTubsInRange}"
);
}
private void TryRefillHotTub(
Player player,
Smelter smelter,
Container[] containers)
{
if (smelter == null)
return;
ZNetView nview =
smelter.GetComponent<ZNetView>();
if (nview == null)
nview = smelter.GetComponentInParent<ZNetView>();
if (nview == null || !nview.IsValid())
{
LogDebug("Hot tub: invalid ZNetView.");
return;
}
ZDO zdo = nview.GetZDO();
if (zdo == null)
{
LogDebug("Hot tub: ZDO is null.");
return;
}
if (
smelter.m_fuelItem == null ||
smelter.m_fuelItem.m_itemData == null ||
smelter.m_fuelItem.m_itemData.m_shared == null
)
{
LogDebug("Hot tub: fuel item is null.");
return;
}
string fuelName =
smelter.m_fuelItem.m_itemData.m_shared.m_name;
float currentFuel =
zdo.GetFloat(
ZDOVars.s_fuel,
0f
);
float maxFuel =
smelter.m_maxFuel;
if (maxFuel <= 0f)
return;
float fuelPercent =
currentFuel / maxFuel;
LogDebug(
$"Hot tub fuel state: " +
$"fuel='{fuelName}', " +
$"current={currentFuel:0.00}, " +
$"max={maxFuel:0.00}, " +
$"percent={fuelPercent * 100f:0.0}%, " +
$"threshold={_refillBelowPercent.Value * 100f:0.0}%"
);
if (fuelPercent >= _refillBelowPercent.Value)
{
LogDebug(
"Skipping hot tub - fuelPercent >= threshold."
);
return;
}
int missingFuel =
Mathf.CeilToInt(
maxFuel - currentFuel
);
int requestedFuel =
_refillToMax.Value
? missingFuel
: Mathf.Min(
_refillAmount.Value,
missingFuel
);
if (requestedFuel <= 0)
return;
LogDebug(
$"Hot tub refill requested: " +
$"missing={missingFuel}, " +
$"requested={requestedFuel}"
);
int fuelConsumed =
ConsumeFuel(
player,
smelter.transform,
fuelName,
requestedFuel,
containers
);
if (fuelConsumed <= 0)
{
LogDebug(
"Hot tub refill stopped: no usable fuel."
);
return;
}
for (int i = 0; i < fuelConsumed; i++)
{
nview.InvokeRPC(
"RPC_AddFuel",
new object[0]
);
}
LogInfo(
$"Refilled hot tub: " +
$"{currentFuel:0.0}/{maxFuel:0.0}, " +
$"fuel={fuelName}, " +
$"added={fuelConsumed}, " +
$"mode={(_refillToMax.Value ? "max" : "fixed")}"
);
}
private bool IsOwnPiece(Player player, Fireplace fireplace) private bool IsOwnPiece(Player player, Fireplace fireplace)
{ {
Piece piece = fireplace.GetComponent<Piece>(); Piece piece = fireplace.GetComponent<Piece>();
@@ -584,7 +797,7 @@ namespace AutoRefillFires
int fuelConsumed = ConsumeFuel( int fuelConsumed = ConsumeFuel(
player, player,
fireplace, fireplace.transform,
fuelName, fuelName,
requestedFuel, requestedFuel,
containers containers
@@ -683,11 +896,10 @@ namespace AutoRefillFires
private int ConsumeFuel( private int ConsumeFuel(
Player player, Player player,
Fireplace fireplace, Transform target,
string fuelName, string fuelName,
int requestedAmount, int requestedAmount,
Container[] containers Container[] containers)
)
{ {
if (requestedAmount <= 0) if (requestedAmount <= 0)
return 0; return 0;
@@ -708,7 +920,7 @@ namespace AutoRefillFires
if (_useNearbyContainers.Value && containers != null) if (_useNearbyContainers.Value && containers != null)
{ {
consumed += ConsumeFuelFromNearbyContainers( consumed += ConsumeFuelFromNearbyContainers(
fireplace, target,
fuelName, fuelName,
requestedAmount - consumed, requestedAmount - consumed,
containers containers
@@ -739,7 +951,7 @@ namespace AutoRefillFires
) )
{ {
consumed += ConsumeFuelFromNearbyContainers( consumed += ConsumeFuelFromNearbyContainers(
fireplace, target,
fuelName, fuelName,
requestedAmount - consumed, requestedAmount - consumed,
containers containers
@@ -758,19 +970,16 @@ namespace AutoRefillFires
} }
private int ConsumeFuelFromNearbyContainers( private int ConsumeFuelFromNearbyContainers(
Fireplace fireplace, Transform target,
string fuelName, string fuelName,
int requestedAmount, int requestedAmount,
Container[] containers) Container[] containers)
{ {
if (requestedAmount <= 0) if (requestedAmount <= 0)
return 0; return 0;
if (containers == null || containers.Length == 0) if (containers == null || containers.Length == 0)
{
LogDebug("Container scan: no loaded containers available.");
return 0; return 0;
}
List<ContainerCandidate> candidates = List<ContainerCandidate> candidates =
new List<ContainerCandidate>(); new List<ContainerCandidate>();
@@ -781,7 +990,7 @@ namespace AutoRefillFires
continue; continue;
float distance = Vector3.Distance( float distance = Vector3.Distance(
fireplace.transform.position, target.position,
container.transform.position container.transform.position
); );
@@ -819,26 +1028,15 @@ namespace AutoRefillFires
(a, b) => a.Distance.CompareTo(b.Distance) (a, b) => a.Distance.CompareTo(b.Distance)
); );
LogDebug(
$"Container candidates: " +
$"fuel='{fuelName}', " +
$"usable={candidates.Count}, " +
$"radius={_containerRadius.Value:0.0}m"
);
int consumed = 0; int consumed = 0;
int containersUsed = 0;
foreach (ContainerCandidate candidate in candidates) foreach (ContainerCandidate candidate in candidates)
{ {
if (consumed >= requestedAmount) if (consumed >= requestedAmount)
break; break;
Container container =
candidate.Container;
Inventory inventory = Inventory inventory =
container.GetInventory(); candidate.Container.GetInventory();
if (inventory == null) if (inventory == null)
continue; continue;
@@ -855,47 +1053,23 @@ namespace AutoRefillFires
if (usableFuel <= 0) if (usableFuel <= 0)
continue; continue;
int remainingNeeded =
requestedAmount - consumed;
int amountToTake = int amountToTake =
Mathf.Min( Mathf.Min(
remainingNeeded, requestedAmount - consumed,
usableFuel usableFuel
); );
if (amountToTake <= 0)
continue;
inventory.RemoveItem( inventory.RemoveItem(
fuelName, fuelName,
amountToTake amountToTake
); );
consumed += amountToTake; consumed += amountToTake;
containersUsed++;
LogDebug( LogDebug(
$"Container '{container.name}' " + $"Container '{candidate.Container.name}' " +
$"({candidate.Distance:0.0}m): " + $"({candidate.Distance:0.0}m): " +
$"consumed={amountToTake}x {fuelName}, " + $"consumed={amountToTake}x {fuelName}"
$"before={availableFuel}, " +
$"remaining={availableFuel - amountToTake}"
);
}
if (consumed <= 0)
{
LogDebug(
$"Container result: no usable '{fuelName}' found."
);
}
else
{
LogDebug(
$"Container result: " +
$"consumed={consumed}x {fuelName}, " +
$"containersUsed={containersUsed}"
); );
} }