mirror of
https://github.com/soarqin/DSP_Mods.git
synced 2025-12-10 07:23:28 +08:00
WIP for logistic_hub
This commit is contained in:
321
LogisticHub/Module/StationManager.cs
Normal file
321
LogisticHub/Module/StationManager.cs
Normal file
@@ -0,0 +1,321 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using HarmonyLib;
|
||||
using UXAssist.Common;
|
||||
|
||||
namespace LogisticHub.Module;
|
||||
|
||||
public class PlanetStations
|
||||
{
|
||||
public readonly List<int>[][] StorageIndices = [null, null];
|
||||
|
||||
public void AddStationStorage(bool demand, int id, int stationId, int storageIdx)
|
||||
{
|
||||
var stations = StorageIndices[demand ? 1 : 0];
|
||||
if (stations == null || id >= stations.Length)
|
||||
{
|
||||
Array.Resize(ref stations, AuxData.AlignUpToPowerOf2(id + 1));
|
||||
StorageIndices[demand ? 1 : 0] = stations;
|
||||
}
|
||||
|
||||
var list = stations[id];
|
||||
if (list == null)
|
||||
{
|
||||
list = [];
|
||||
stations[id] = list;
|
||||
}
|
||||
|
||||
var value = stationId * 100 + storageIdx;
|
||||
var index = list.BinarySearch(value);
|
||||
if (index < 0)
|
||||
list.Insert(~index, value);
|
||||
}
|
||||
|
||||
public void RemoveStationStorage(bool demand, int id, int stationId, int storageIdx)
|
||||
{
|
||||
var stations = StorageIndices[demand ? 1 : 0];
|
||||
if (stations == null || id >= stations.Length)
|
||||
return;
|
||||
var list = stations[id];
|
||||
if (list == null)
|
||||
return;
|
||||
|
||||
var value = stationId * 100 + storageIdx;
|
||||
var index = list.BinarySearch(value);
|
||||
if (index >= 0)
|
||||
list.RemoveAt(index);
|
||||
}
|
||||
}
|
||||
|
||||
public class StationManager : PatchImpl<StationManager>
|
||||
{
|
||||
private static PlanetStations[] _stations;
|
||||
|
||||
public static void Init()
|
||||
{
|
||||
GameLogic.OnGameBegin += () =>
|
||||
{
|
||||
_stations = null;
|
||||
var data = GameMain.data;
|
||||
for (var index = data.factoryCount - 1; index >= 0; index--)
|
||||
{
|
||||
var factory = data.factories[index];
|
||||
if (factory == null || factory.index != index) continue;
|
||||
var planetIndex = factory.index;
|
||||
var stations = StationsByPlanet(planetIndex);
|
||||
var transport = factory.transport;
|
||||
var pool = transport.stationPool;
|
||||
for (var i = transport.stationCursor - 1; i > 0; i--)
|
||||
{
|
||||
var station = pool[i];
|
||||
if (station == null || station.id != i || station.isCollector || station.isVeinCollector) continue;
|
||||
UpdateStationInfo(stations, station);
|
||||
}
|
||||
}
|
||||
};
|
||||
Enable(true);
|
||||
}
|
||||
|
||||
public static void Uninit()
|
||||
{
|
||||
Enable(false);
|
||||
}
|
||||
|
||||
private static int ItemIdToIndex(int itemId)
|
||||
{
|
||||
return itemId switch
|
||||
{
|
||||
>= 1000 and < 2000 => itemId - 1000,
|
||||
>= 5000 and < 5050 => itemId - 5000 + 900,
|
||||
>= 6000 and < 6050 => itemId - 6000 + 950,
|
||||
_ => -1
|
||||
};
|
||||
}
|
||||
|
||||
public static int IndexToItemId(int index)
|
||||
{
|
||||
return index switch
|
||||
{
|
||||
< 900 => index + 1000,
|
||||
< 950 => index - 900 + 5000,
|
||||
< 1000 => index - 950 + 6000,
|
||||
_ => -1
|
||||
};
|
||||
}
|
||||
|
||||
public static PlanetStations GetStations(int planetIndex)
|
||||
{
|
||||
return _stations != null && planetIndex < _stations.Length ? _stations[planetIndex] : null;
|
||||
}
|
||||
|
||||
private static PlanetStations StationsByPlanet(int planetIndex)
|
||||
{
|
||||
if (_stations == null || _stations.Length <= planetIndex)
|
||||
Array.Resize(ref _stations, AuxData.AlignUpToPowerOf2(planetIndex + 1));
|
||||
var stations = _stations[planetIndex];
|
||||
if (stations != null) return stations;
|
||||
stations = new PlanetStations();
|
||||
_stations[planetIndex] = stations;
|
||||
return stations;
|
||||
}
|
||||
|
||||
private static void DebugLog()
|
||||
{
|
||||
for (var idx = 0; idx < _stations.Length; idx++)
|
||||
{
|
||||
var stations = _stations[idx];
|
||||
if (stations == null) continue;
|
||||
LogisticHub.Logger.LogDebug($"Planet {idx}:");
|
||||
for (var i = 0; i < 2; i++)
|
||||
{
|
||||
var storage = stations.StorageIndices[i];
|
||||
if (storage == null) continue;
|
||||
LogisticHub.Logger.LogDebug(i == 1 ? " Demand:" : " Supply:");
|
||||
for (var j = 0; j < storage.Length; j++)
|
||||
{
|
||||
var list = storage[j];
|
||||
if (list == null) continue;
|
||||
var count = list.Count;
|
||||
if (count <= 0) continue;
|
||||
var itemId = IndexToItemId(j);
|
||||
LogisticHub.Logger.LogDebug($" {itemId}: {string.Join(", ", list)}");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void UpdateStationInfo(PlanetStations stations, StationComponent station, int storageIdx = -1)
|
||||
{
|
||||
var storage = station.storage;
|
||||
var stationId = station.id;
|
||||
if (storageIdx >= 0)
|
||||
{
|
||||
if (storageIdx >= storage.Length) return;
|
||||
var itemId = ItemIdToIndex(storage[storageIdx].itemId);
|
||||
if (itemId <= 0) return;
|
||||
var logic = storage[storageIdx].localLogic;
|
||||
switch (logic)
|
||||
{
|
||||
case ELogisticStorage.Demand:
|
||||
stations.AddStationStorage(true, itemId, stationId, storageIdx);
|
||||
break;
|
||||
case ELogisticStorage.Supply:
|
||||
stations.AddStationStorage(false, itemId, stationId, storageIdx);
|
||||
break;
|
||||
case ELogisticStorage.None:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
for (var i = storage.Length - 1; i >= 0; i--)
|
||||
{
|
||||
var itemId = ItemIdToIndex(storage[i].itemId);
|
||||
if (itemId <= 0) continue;
|
||||
var logic = storage[i].localLogic;
|
||||
switch (logic)
|
||||
{
|
||||
case ELogisticStorage.Demand:
|
||||
stations.AddStationStorage(true, itemId, stationId, i);
|
||||
break;
|
||||
case ELogisticStorage.Supply:
|
||||
stations.AddStationStorage(false, itemId, stationId, i);
|
||||
break;
|
||||
case ELogisticStorage.None:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void RemoveStationInfo(PlanetStations stations, StationComponent station, int storageIdx = -1)
|
||||
{
|
||||
var storage = station.storage;
|
||||
var stationId = station.id;
|
||||
if (storageIdx >= 0)
|
||||
{
|
||||
var itemId = ItemIdToIndex(storage[storageIdx].itemId);
|
||||
if (itemId <= 0) return;
|
||||
var logic = storage[storageIdx].localLogic;
|
||||
switch (logic)
|
||||
{
|
||||
case ELogisticStorage.Demand:
|
||||
stations.RemoveStationStorage(true, itemId, stationId, storageIdx);
|
||||
break;
|
||||
case ELogisticStorage.Supply:
|
||||
stations.RemoveStationStorage(false, itemId, stationId, storageIdx);
|
||||
break;
|
||||
case ELogisticStorage.None:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
for (var i = storage.Length - 1; i >= 0; i--)
|
||||
{
|
||||
var itemId = ItemIdToIndex(storage[i].itemId);
|
||||
if (itemId <= 0) continue;
|
||||
var logic = storage[i].localLogic;
|
||||
switch (logic)
|
||||
{
|
||||
case ELogisticStorage.Demand:
|
||||
stations.RemoveStationStorage(true, itemId, stationId, i);
|
||||
break;
|
||||
case ELogisticStorage.Supply:
|
||||
stations.RemoveStationStorage(false, itemId, stationId, i);
|
||||
break;
|
||||
case ELogisticStorage.None:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[HarmonyPostfix]
|
||||
[HarmonyPatch(typeof(PlanetTransport), nameof(PlanetTransport.Init))]
|
||||
private static void PlanetTransport_Init_Postfix(PlanetTransport __instance)
|
||||
{
|
||||
var factory = __instance.factory;
|
||||
var planetIndex = factory.index;
|
||||
|
||||
if (_stations == null || _stations.Length <= planetIndex)
|
||||
Array.Resize(ref _stations, AuxData.AlignUpToPowerOf2(planetIndex + 1));
|
||||
var stations = new PlanetStations();
|
||||
_stations[planetIndex] = stations;
|
||||
|
||||
var pool = __instance.stationPool;
|
||||
for (var i = __instance.stationCursor - 1; i > 0; i--)
|
||||
{
|
||||
var station = pool[i];
|
||||
if (station == null || station.id != i || station.isCollector || station.isVeinCollector) continue;
|
||||
UpdateStationInfo(stations, station);
|
||||
}
|
||||
// DebugLog();
|
||||
}
|
||||
|
||||
[HarmonyPostfix]
|
||||
[HarmonyPatch(typeof(BuildingParameters), nameof(BuildingParameters.ApplyPrebuildParametersToEntity))]
|
||||
private static void BuildingParameters_ApplyPrebuildParametersToEntity_Postfix(int entityId, PlanetFactory factory)
|
||||
{
|
||||
if (entityId <= 0) return;
|
||||
ref var entity = ref factory.entityPool[entityId];
|
||||
var stationId = entity.stationId;
|
||||
if (stationId <= 0) return;
|
||||
var station = factory.transport.stationPool[stationId];
|
||||
if (station == null || station.id != stationId || station.isCollector || station.isVeinCollector) return;
|
||||
UpdateStationInfo(StationsByPlanet(factory.index), station);
|
||||
// DebugLog();
|
||||
}
|
||||
|
||||
[HarmonyPrefix]
|
||||
[HarmonyPatch(typeof(PlanetTransport), nameof(PlanetTransport.RemoveStationComponent))]
|
||||
private static void PlanetTransport_RemoveStationComponent_Prefix(PlanetTransport __instance, int id)
|
||||
{
|
||||
if (id <= 0) return;
|
||||
var station = __instance.stationPool[id];
|
||||
if (station == null || station.id != id || station.isCollector || station.isVeinCollector) return;
|
||||
RemoveStationInfo(StationsByPlanet(__instance.factory.index), station);
|
||||
// DebugLog();
|
||||
}
|
||||
|
||||
[HarmonyPrefix]
|
||||
[HarmonyPatch(typeof(PlanetTransport), nameof(PlanetTransport.SetStationStorage))]
|
||||
private static void PlanetTransport_SetStationStorage_Prefix(PlanetTransport __instance, int stationId, int storageIdx, int itemId, ELogisticStorage localLogic, out bool __state)
|
||||
{
|
||||
var station = __instance.stationPool[stationId];
|
||||
if (station == null || station.id != stationId || station.isCollector || station.isVeinCollector || storageIdx < 0 || storageIdx >= station.storage.Length)
|
||||
{
|
||||
__state = false;
|
||||
return;
|
||||
}
|
||||
|
||||
ref var storage = ref station.storage[storageIdx];
|
||||
var oldItemId = storage.itemId;
|
||||
var oldLocalLogic = storage.localLogic;
|
||||
if (localLogic == oldLocalLogic && itemId == oldItemId)
|
||||
{
|
||||
__state = false;
|
||||
return;
|
||||
}
|
||||
|
||||
if (oldItemId > 0 && oldLocalLogic != ELogisticStorage.None)
|
||||
RemoveStationInfo(StationsByPlanet(__instance.factory.index), station, storageIdx);
|
||||
__state = localLogic != ELogisticStorage.None;
|
||||
// if (!__state) DebugLog();
|
||||
}
|
||||
|
||||
[HarmonyPostfix]
|
||||
[HarmonyPatch(typeof(PlanetTransport), nameof(PlanetTransport.SetStationStorage))]
|
||||
private static void PlanetTransport_SetStationStorage_Postfix(PlanetTransport __instance, int stationId, int storageIdx, bool __state)
|
||||
{
|
||||
if (!__state) return;
|
||||
var station = __instance.stationPool[stationId];
|
||||
UpdateStationInfo(StationsByPlanet(__instance.factory.index), station, storageIdx);
|
||||
// DebugLog();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user