Added support for hot tubs
This commit is contained in:
@@ -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}"
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user