mirror of
https://github.com/soarqin/DSP_Mods.git
synced 2026-06-21 06:51:11 +08:00
UXAssist: add buttons to apply logistics auto-config to current planet's facilities
This commit is contained in:
@@ -109,6 +109,241 @@ public static class LogisticsPatch
|
||||
}
|
||||
}
|
||||
|
||||
#region Apply auto-config values to existing facilities on the current planet
|
||||
|
||||
private enum StationKind
|
||||
{
|
||||
Pls,
|
||||
Ils,
|
||||
VeinCollector
|
||||
}
|
||||
|
||||
// === Per-field setters (single source of truth, shared by auto-config-on-build and apply-to-planet) ===
|
||||
|
||||
private static void StationSetChargePower(PlanetFactory factory, StationComponent station) =>
|
||||
factory.powerSystem.consumerPool[station.pcId].workEnergyPerTick =
|
||||
(long)((station.isStellar ? 250000.0 * AutoConfigILSChargePower.Value : 50000.0 * AutoConfigPLSChargePower.Value) + 0.5);
|
||||
|
||||
private static void StationSetTripRangeDrones(PlanetFactory factory, StationComponent station) =>
|
||||
station.tripRangeDrones = Math.Cos((station.isStellar ? AutoConfigILSMaxTripDrone.Value : AutoConfigPLSMaxTripDrone.Value) / 180.0 * Math.PI);
|
||||
|
||||
private static void StationSetDeliveryDrones(PlanetFactory factory, StationComponent station)
|
||||
{
|
||||
var v = station.isStellar ? AutoConfigILSDroneMinDeliver.Value : AutoConfigPLSDroneMinDeliver.Value;
|
||||
station.deliveryDrones = v == 0 ? 1 : v * 10;
|
||||
}
|
||||
|
||||
private static void StationSetPilerCount(PlanetFactory factory, StationComponent station) =>
|
||||
station.pilerCount = station.isStellar ? AutoConfigILSMinPilerValue.Value : AutoConfigPLSMinPilerValue.Value;
|
||||
|
||||
private static void StationFillDrones(PlanetFactory factory, StationComponent station)
|
||||
{
|
||||
var target = station.isStellar ? AutoConfigILSDroneCount.Value : AutoConfigPLSDroneCount.Value;
|
||||
var toFill = Math.Max(0, target - station.idleDroneCount - station.workDroneCount);
|
||||
if (toFill > 0) station.idleDroneCount += GameMain.data.mainPlayer.package.TakeItem((int)KnownItemId.Drone, toFill, out _);
|
||||
}
|
||||
|
||||
private static void StationSetTripRangeShips(PlanetFactory factory, StationComponent station) =>
|
||||
station.tripRangeShips = AutoConfigILSMaxTripShip.Value switch
|
||||
{
|
||||
<= 20 => AutoConfigILSMaxTripShip.Value,
|
||||
<= 40 => AutoConfigILSMaxTripShip.Value * 2 - 20,
|
||||
_ => 10000,
|
||||
} * 2400000.0;
|
||||
|
||||
private static void StationSetWarpDistance(PlanetFactory factory, StationComponent station) =>
|
||||
station.warpEnableDist = AutoConfigILSWarperDistance.Value switch
|
||||
{
|
||||
<= 7 => AutoConfigILSWarperDistance.Value * 0.5 - 0.5,
|
||||
<= 16 => AutoConfigILSWarperDistance.Value - 4.0,
|
||||
<= 20 => AutoConfigILSWarperDistance.Value * 2 - 20.0,
|
||||
_ => 60.0,
|
||||
} * 40000.0;
|
||||
|
||||
private static void StationSetDeliveryShips(PlanetFactory factory, StationComponent station)
|
||||
{
|
||||
var v = AutoConfigILSShipMinDeliver.Value;
|
||||
station.deliveryShips = v == 0 ? 1 : v * 10;
|
||||
}
|
||||
|
||||
private static void StationFillShips(PlanetFactory factory, StationComponent station)
|
||||
{
|
||||
var toFill = Math.Max(0, AutoConfigILSShipCount.Value - station.idleShipCount - station.workShipCount);
|
||||
if (toFill > 0) station.idleShipCount += GameMain.data.mainPlayer.package.TakeItem((int)KnownItemId.Ship, toFill, out _);
|
||||
}
|
||||
|
||||
private static void StationSetIncludeOrbitCollector(PlanetFactory factory, StationComponent station) =>
|
||||
station.includeOrbitCollector = AutoConfigILSIncludeOrbitCollector.Value;
|
||||
|
||||
private static void StationSetWarperNecessary(PlanetFactory factory, StationComponent station) =>
|
||||
station.warperNecessary = AutoConfigILSWarperNecessary.Value;
|
||||
|
||||
/* station.minerId may not be set yet on freshly built collectors, so resolve the minerId from the EntityData. */
|
||||
private static bool VeinCollectorSetHarvestSpeed(PlanetFactory factory, StationComponent station)
|
||||
{
|
||||
ref var entity = ref factory.entityPool[station.entityId];
|
||||
if (entity.id != station.entityId || entity.minerId <= 0 || entity.minerId >= factory.factorySystem.minerCursor) return false;
|
||||
factory.factorySystem.minerPool[entity.minerId].speed = 10000 + AutoConfigVeinCollectorHarvestSpeed.Value * 1000;
|
||||
return true;
|
||||
}
|
||||
|
||||
private static void VeinCollectorSetPilerCount(PlanetFactory factory, StationComponent station) =>
|
||||
station.pilerCount = AutoConfigVeinCollectorMinPilerValue.Value;
|
||||
|
||||
private static void DispenserSetChargePower(PlanetFactory factory, DispenserComponent dispenser) =>
|
||||
factory.powerSystem.consumerPool[dispenser.pcId].workEnergyPerTick = (long)(5000.0 * AutoConfigDispenserChargePower.Value + 0.5);
|
||||
|
||||
private static void DispenserFillCouriers(PlanetFactory factory, DispenserComponent dispenser)
|
||||
{
|
||||
var toFill = Math.Max(0, AutoConfigDispenserCourierCount.Value - dispenser.idleCourierCount - dispenser.workCourierCount);
|
||||
if (toFill > 0) dispenser.idleCourierCount += GameMain.data.mainPlayer.package.TakeItem((int)KnownItemId.Bot, toFill, out _);
|
||||
}
|
||||
|
||||
private static void BattleBaseSetChargePower(PlanetFactory factory, BattleBaseComponent battleBase) =>
|
||||
factory.powerSystem.consumerPool[battleBase.pcId].workEnergyPerTick = (long)(5000.0 * AutoConfigBattleBaseChargePower.Value + 0.5);
|
||||
|
||||
// === Per-facility "apply all settings" (also used as auto-config-on-build entry point) ===
|
||||
|
||||
private static void DoConfigStation(PlanetFactory factory, StationComponent station)
|
||||
{
|
||||
if (station.isCollector) return;
|
||||
if (station.isVeinCollector)
|
||||
{
|
||||
if (VeinCollectorSetHarvestSpeed(factory, station))
|
||||
VeinCollectorSetPilerCount(factory, station);
|
||||
return;
|
||||
}
|
||||
if (!station.isStellar)
|
||||
{
|
||||
StationSetChargePower(factory, station);
|
||||
StationSetTripRangeDrones(factory, station);
|
||||
StationSetDeliveryDrones(factory, station);
|
||||
StationSetPilerCount(factory, station);
|
||||
StationFillDrones(factory, station);
|
||||
return;
|
||||
}
|
||||
StationSetChargePower(factory, station);
|
||||
StationSetTripRangeDrones(factory, station);
|
||||
StationSetTripRangeShips(factory, station);
|
||||
StationSetWarpDistance(factory, station);
|
||||
StationSetDeliveryDrones(factory, station);
|
||||
StationSetDeliveryShips(factory, station);
|
||||
StationSetPilerCount(factory, station);
|
||||
StationSetIncludeOrbitCollector(factory, station);
|
||||
StationSetWarperNecessary(factory, station);
|
||||
StationFillDrones(factory, station);
|
||||
StationFillShips(factory, station);
|
||||
}
|
||||
|
||||
// === Iterate over the current planet's facilities of a given kind ===
|
||||
|
||||
private static void ForEachStation(StationKind kind, Action<PlanetFactory, StationComponent> action)
|
||||
{
|
||||
var factory = GameMain.localPlanet?.factory;
|
||||
var transport = factory?.transport;
|
||||
var stationPool = transport?.stationPool;
|
||||
if (stationPool == null) return;
|
||||
for (var i = transport.stationCursor - 1; i > 0; i--)
|
||||
{
|
||||
var station = stationPool[i];
|
||||
if (station == null || station.id != i || station.isCollector) continue;
|
||||
var skip = kind switch
|
||||
{
|
||||
StationKind.VeinCollector => !station.isVeinCollector,
|
||||
StationKind.Ils => station.isVeinCollector || !station.isStellar,
|
||||
StationKind.Pls => station.isVeinCollector || station.isStellar,
|
||||
_ => true
|
||||
};
|
||||
if (skip) continue;
|
||||
action(factory, station);
|
||||
}
|
||||
RefreshOpenLogisticsWindows();
|
||||
}
|
||||
|
||||
private static void ForEachDispenser(Action<PlanetFactory, DispenserComponent> action)
|
||||
{
|
||||
var factory = GameMain.localPlanet?.factory;
|
||||
var transport = factory?.transport;
|
||||
var dispenserPool = transport?.dispenserPool;
|
||||
if (dispenserPool == null) return;
|
||||
for (var i = transport.dispenserCursor - 1; i > 0; i--)
|
||||
{
|
||||
var dispenser = dispenserPool[i];
|
||||
if (dispenser == null || dispenser.id != i) continue;
|
||||
action(factory, dispenser);
|
||||
}
|
||||
RefreshOpenLogisticsWindows();
|
||||
}
|
||||
|
||||
private static void ForEachBattleBase(Action<PlanetFactory, BattleBaseComponent> action)
|
||||
{
|
||||
var factory = GameMain.localPlanet?.factory;
|
||||
var battleBases = factory?.defenseSystem?.battleBases;
|
||||
if (battleBases?.buffer == null) return;
|
||||
for (var i = battleBases.cursor - 1; i > 0; i--)
|
||||
{
|
||||
var battleBase = battleBases.buffer[i];
|
||||
if (battleBase == null || battleBase.id != i) continue;
|
||||
action(factory, battleBase);
|
||||
}
|
||||
RefreshOpenLogisticsWindows();
|
||||
}
|
||||
|
||||
// Re-populate any open logistic facility detail window so applied values show immediately.
|
||||
private static void RefreshOpenLogisticsWindows()
|
||||
{
|
||||
var uiRoot = UIRoot.instance;
|
||||
if (!uiRoot) return;
|
||||
var uiGame = uiRoot.uiGame;
|
||||
if (!uiGame) return;
|
||||
var stationWindow = uiGame.stationWindow;
|
||||
if (stationWindow && stationWindow.active) stationWindow.OnStationIdChange();
|
||||
var dispenserWindow = uiGame.dispenserWindow;
|
||||
if (dispenserWindow && dispenserWindow.active) dispenserWindow.OnDispenserIdChange();
|
||||
var battleBaseWindow = uiGame.battleBaseWindow;
|
||||
if (battleBaseWindow && battleBaseWindow.active) battleBaseWindow.OnBattleBaseIdChange();
|
||||
}
|
||||
|
||||
// === Public entry points invoked by the config panel buttons ===
|
||||
|
||||
// Dispenser
|
||||
public static void ApplyDispenserChargePower() => ForEachDispenser(DispenserSetChargePower);
|
||||
public static void ApplyDispenserCourierCount() => ForEachDispenser(DispenserFillCouriers);
|
||||
public static void ApplyAllDispenser() => ForEachDispenser((f, d) => { DispenserSetChargePower(f, d); DispenserFillCouriers(f, d); });
|
||||
|
||||
// Battlefield Analysis Base
|
||||
public static void ApplyBattleBaseChargePower() => ForEachBattleBase(BattleBaseSetChargePower);
|
||||
public static void ApplyAllBattleBase() => ForEachBattleBase(BattleBaseSetChargePower);
|
||||
|
||||
// PLS
|
||||
public static void ApplyPLSChargePower() => ForEachStation(StationKind.Pls, StationSetChargePower);
|
||||
public static void ApplyPLSTripRangeDrones() => ForEachStation(StationKind.Pls, StationSetTripRangeDrones);
|
||||
public static void ApplyPLSDroneMinDeliver() => ForEachStation(StationKind.Pls, StationSetDeliveryDrones);
|
||||
public static void ApplyPLSMinPilerValue() => ForEachStation(StationKind.Pls, StationSetPilerCount);
|
||||
public static void ApplyPLSDroneCount() => ForEachStation(StationKind.Pls, StationFillDrones);
|
||||
public static void ApplyAllPLS() => ForEachStation(StationKind.Pls, DoConfigStation);
|
||||
|
||||
// ILS
|
||||
public static void ApplyILSChargePower() => ForEachStation(StationKind.Ils, StationSetChargePower);
|
||||
public static void ApplyILSTripRangeDrones() => ForEachStation(StationKind.Ils, StationSetTripRangeDrones);
|
||||
public static void ApplyILSTripRangeShips() => ForEachStation(StationKind.Ils, StationSetTripRangeShips);
|
||||
public static void ApplyILSWarpDistance() => ForEachStation(StationKind.Ils, StationSetWarpDistance);
|
||||
public static void ApplyILSDroneMinDeliver() => ForEachStation(StationKind.Ils, StationSetDeliveryDrones);
|
||||
public static void ApplyILSShipMinDeliver() => ForEachStation(StationKind.Ils, StationSetDeliveryShips);
|
||||
public static void ApplyILSMinPilerValue() => ForEachStation(StationKind.Ils, StationSetPilerCount);
|
||||
public static void ApplyILSDroneCount() => ForEachStation(StationKind.Ils, StationFillDrones);
|
||||
public static void ApplyILSShipCount() => ForEachStation(StationKind.Ils, StationFillShips);
|
||||
public static void ApplyILSIncludeOrbitCollector() => ForEachStation(StationKind.Ils, StationSetIncludeOrbitCollector);
|
||||
public static void ApplyILSWarperNecessary() => ForEachStation(StationKind.Ils, StationSetWarperNecessary);
|
||||
public static void ApplyAllILS() => ForEachStation(StationKind.Ils, DoConfigStation);
|
||||
|
||||
// Vein Collector (Advanced Mining Machine)
|
||||
public static void ApplyVeinCollectorHarvestSpeed() => ForEachStation(StationKind.VeinCollector, (f, s) => VeinCollectorSetHarvestSpeed(f, s));
|
||||
public static void ApplyVeinCollectorMinPilerValue() => ForEachStation(StationKind.VeinCollector, VeinCollectorSetPilerCount);
|
||||
public static void ApplyAllVeinCollector() => ForEachStation(StationKind.VeinCollector, DoConfigStation);
|
||||
|
||||
#endregion
|
||||
|
||||
private class AutoConfigLogistics : PatchImpl<AutoConfigLogistics>
|
||||
{
|
||||
protected override void OnEnable()
|
||||
@@ -180,66 +415,6 @@ public static class LogisticsPatch
|
||||
}
|
||||
}
|
||||
|
||||
private static void DoConfigStation(PlanetFactory factory, StationComponent station)
|
||||
{
|
||||
if (station.isCollector) return;
|
||||
if (station.isVeinCollector)
|
||||
{
|
||||
/* station.minerId is not set at this point, so we need to fetch the minerId from the EntityData */
|
||||
ref var entity = ref factory.entityPool[station.entityId];
|
||||
if (entity.id != station.entityId || entity.minerId <= 0 || entity.minerId >= factory.factorySystem.minerCursor) return;
|
||||
factory.factorySystem.minerPool[entity.minerId].speed = 10000 + AutoConfigVeinCollectorHarvestSpeed.Value * 1000;
|
||||
station.pilerCount = AutoConfigVeinCollectorMinPilerValue.Value;
|
||||
return;
|
||||
}
|
||||
int toFill;
|
||||
if (!station.isStellar)
|
||||
{
|
||||
factory.powerSystem.consumerPool[station.pcId].workEnergyPerTick = (long)(50000.0 * AutoConfigPLSChargePower.Value + 0.5);
|
||||
station.tripRangeDrones = Math.Cos(AutoConfigPLSMaxTripDrone.Value / 180.0 * Math.PI);
|
||||
station.deliveryDrones = AutoConfigPLSDroneMinDeliver.Value switch { 0 => 1, _ => AutoConfigPLSDroneMinDeliver.Value * 10 };
|
||||
station.pilerCount = AutoConfigPLSMinPilerValue.Value;
|
||||
toFill = Math.Max(0, AutoConfigPLSDroneCount.Value - station.idleDroneCount - station.workDroneCount);
|
||||
if (toFill > 0) station.idleDroneCount += GameMain.data.mainPlayer.package.TakeItem((int)KnownItemId.Drone, toFill, out _);
|
||||
return;
|
||||
}
|
||||
factory.powerSystem.consumerPool[station.pcId].workEnergyPerTick = (long)(250000.0 * AutoConfigILSChargePower.Value + 0.5);
|
||||
station.tripRangeDrones = Math.Cos(AutoConfigILSMaxTripDrone.Value / 180.0 * Math.PI);
|
||||
station.tripRangeShips = AutoConfigILSMaxTripShip.Value switch
|
||||
{
|
||||
<= 20 => AutoConfigILSMaxTripShip.Value,
|
||||
<= 40 => AutoConfigILSMaxTripShip.Value * 2 - 20,
|
||||
_ => 10000,
|
||||
} * 2400000.0;
|
||||
station.warpEnableDist = AutoConfigILSWarperDistance.Value switch
|
||||
{
|
||||
<= 7 => AutoConfigILSWarperDistance.Value * 0.5 - 0.5,
|
||||
<= 16 => AutoConfigILSWarperDistance.Value - 4.0,
|
||||
<= 20 => AutoConfigILSWarperDistance.Value * 2 - 20.0,
|
||||
_ => 60.0,
|
||||
} * 40000.0;
|
||||
station.deliveryDrones = AutoConfigILSDroneMinDeliver.Value switch { 0 => 1, _ => AutoConfigILSDroneMinDeliver.Value * 10 };
|
||||
station.deliveryShips = AutoConfigILSShipMinDeliver.Value switch { 0 => 1, _ => AutoConfigILSShipMinDeliver.Value * 10 };
|
||||
station.pilerCount = AutoConfigILSMinPilerValue.Value;
|
||||
station.includeOrbitCollector = AutoConfigILSIncludeOrbitCollector.Value;
|
||||
station.warperNecessary = AutoConfigILSWarperNecessary.Value;
|
||||
toFill = Math.Max(0, AutoConfigILSDroneCount.Value - station.idleDroneCount - station.workDroneCount);
|
||||
if (toFill > 0) station.idleDroneCount += GameMain.data.mainPlayer.package.TakeItem((int)KnownItemId.Drone, toFill, out _);
|
||||
toFill = Math.Max(0, AutoConfigILSShipCount.Value - station.idleShipCount - station.workShipCount);
|
||||
if (toFill > 0) station.idleShipCount += GameMain.data.mainPlayer.package.TakeItem((int)KnownItemId.Ship, toFill, out _);
|
||||
}
|
||||
|
||||
private static void DoConfigDispenser(PlanetFactory factory, DispenserComponent dispenser)
|
||||
{
|
||||
var toFill = Math.Max(0, AutoConfigDispenserCourierCount.Value - dispenser.idleCourierCount - dispenser.workCourierCount);
|
||||
if (toFill > 0) dispenser.idleCourierCount += GameMain.data.mainPlayer.package.TakeItem((int)KnownItemId.Bot, toFill, out _);
|
||||
}
|
||||
|
||||
private static void DoConfigBattleBase(PlanetFactory factory, BattleBaseComponent battleBase)
|
||||
{
|
||||
factory.powerSystem.consumerPool[battleBase.pcId].workEnergyPerTick = (long)(5000.0 * AutoConfigBattleBaseChargePower.Value + 0.5);
|
||||
}
|
||||
|
||||
[HarmonyPostfix]
|
||||
[HarmonyPatch(typeof(BuildTool_Addon), nameof(BuildTool_Addon.SetDefaultParams))]
|
||||
private static void BuildTool_Addon_SetDefaultParams_Postfix(BuildTool_Addon __instance, int bpIndex)
|
||||
@@ -262,7 +437,7 @@ public static class LogisticsPatch
|
||||
private static void DefenseSystem_NewBattleBaseComponent_Postfix(DefenseSystem __instance, int __result)
|
||||
{
|
||||
if (__result <= 0) return;
|
||||
DoConfigBattleBase(__instance.factory, __instance.battleBases[__result]);
|
||||
BattleBaseSetChargePower(__instance.factory, __instance.battleBases[__result]);
|
||||
}
|
||||
|
||||
[HarmonyPostfix]
|
||||
@@ -270,7 +445,7 @@ public static class LogisticsPatch
|
||||
private static void PlanetTransport_NewDispenserComponent_Postfix(PlanetTransport __instance, int __result)
|
||||
{
|
||||
if (__result <= 0) return;
|
||||
DoConfigDispenser(__instance.factory, __instance.dispenserPool[__result]);
|
||||
DispenserFillCouriers(__instance.factory, __instance.dispenserPool[__result]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user