1
0
mirror of https://github.com/soarqin/DSP_Mods.git synced 2025-12-08 19:33:27 +08:00
Files
DSP_Mods/Dustbin/StoragePatch.cs
2023-08-15 21:20:02 +08:00

172 lines
6.4 KiB
C#

using System.IO;
using System.Reflection;
using HarmonyLib;
using NebulaAPI;
using UnityEngine;
namespace Dustbin;
[HarmonyPatch]
public static class StoragePatch
{
public static readonly FieldInfo IsDustbinField = AccessTools.Field(typeof(StorageComponent), "IsDustbin");
private static MyCheckBox _storageDustbinCheckBox;
private static int _lastStorageId;
public static void Reset()
{
_lastStorageId = 0;
}
public static void Export(BinaryWriter w)
{
var tempStream = new MemoryStream();
var tempWriter = new BinaryWriter(tempStream);
var factories = GameMain.data.factories;
var factoryCount = GameMain.data.factoryCount;
for (var i = 0; i < factoryCount; i++)
{
var factory = factories[i];
var storage = factory?.factoryStorage;
var storagePool = storage?.storagePool;
if (storagePool == null) continue;
var cursor = storage.storageCursor;
var count = 0;
for (var j = 1; j < cursor; j++)
{
if (storagePool[j] == null || storagePool[j].id != j) continue;
if (!(bool)IsDustbinField.GetValue(storagePool[j])) continue;
tempWriter.Write(j);
count++;
}
if (count == 0) continue;
tempWriter.Flush();
tempStream.Position = 0;
w.Write((byte)1);
w.Write(factory.planetId);
w.Write(count);
/* FixMe: May BinaryWriter not sync with its BaseStream while subclass overrides Write()? */
tempStream.CopyTo(w.BaseStream);
tempStream.SetLength(0);
}
tempWriter.Dispose();
tempStream.Dispose();
}
public static void Import(BinaryReader r)
{
while (r.PeekChar() == 1)
{
r.ReadByte();
var planetId = r.ReadInt32();
var planet = GameMain.data.galaxy.PlanetById(planetId);
var storagePool = planet?.factory?.factoryStorage?.storagePool;
if (storagePool == null)
{
for (var count = r.ReadInt32(); count > 0; count--)
{
r.ReadInt32();
}
continue;
}
for (var count = r.ReadInt32(); count > 0; count--)
{
var id = r.ReadInt32();
if (id > 0 && id < storagePool.Length && storagePool[id] != null && storagePool[id].id == id)
{
IsDustbinField.SetValue(storagePool[id], true);
}
}
}
}
[HarmonyPostfix]
[HarmonyPatch(typeof(UIStorageWindow), "_OnCreate")]
private static void UIStorageWindow__OnCreate_Postfix(UIStorageWindow __instance)
{
_storageDustbinCheckBox = MyCheckBox.CreateCheckBox(false, __instance.transform, 50f, 50f, Localization.language == Language.zhCN ? "垃圾桶" : "Dustbin");
var window = __instance;
_storageDustbinCheckBox.OnChecked += () =>
{
var storageId = window.storageId;
if (storageId <= 0) return;
var storagePool = window.factoryStorage.storagePool;
if (storagePool[storageId].id != storageId) return;
var enabled = _storageDustbinCheckBox.Checked;
IsDustbinField.SetValue(storagePool[storageId], enabled);
if (!NebulaModAPI.IsMultiplayerActive) return;
var planetId = window.factory.planetId;
NebulaModAPI.MultiplayerSession.Network.SendPacketToLocalStar(new NebulaSupport.Packet.ToggleEvent(planetId, storageId, enabled));
};
}
[HarmonyPostfix]
[HarmonyPatch(typeof(UIStorageWindow), "_OnUpdate")]
private static void UIStorageWindow__OnUpdate_Postfix(UIStorageWindow __instance)
{
var storageId = __instance.storageId;
if (_lastStorageId == storageId) return;
_lastStorageId = storageId;
if (storageId <= 0) return;
var storagePool = __instance.factoryStorage.storagePool;
if (storagePool[storageId].id != storageId) return;
_storageDustbinCheckBox.Checked = (bool)IsDustbinField.GetValue(storagePool[storageId]);
if (__instance.transform is RectTransform rectTrans)
{
_storageDustbinCheckBox.rectTrans.anchoredPosition3D = new Vector3(50, 58 - rectTrans.sizeDelta.y, 0);
}
}
/* Adopt fix from starfi5h's NebulaCompatiblilityAssist */
[HarmonyPostfix]
[HarmonyPatch(typeof(UIStorageGrid), "OnStorageSizeChanged")]
private static void UIStorageGrid_OnStorageSizeChanged_Postfix()
{
// Due to storage window is empty when open in client, the size will change after receiving data from host
_lastStorageId = 0; // Refresh UI to reposition button on client side
}
[HarmonyPrefix]
[HarmonyPatch(typeof(StorageComponent), "AddItem",
new[] { typeof(int), typeof(int), typeof(int), typeof(int), typeof(bool) },
new[]
{
ArgumentType.Normal, ArgumentType.Normal, ArgumentType.Normal, ArgumentType.Out, ArgumentType.Normal
})]
private static bool StorageComponent_AddItem_Prefix(ref int __result, StorageComponent __instance, int itemId, int count, int inc,
ref int remainInc, bool useBan = false)
{
if (!(bool)IsDustbinField.GetValue(__instance)) return true;
remainInc = inc;
__result = count;
var fluidArr = Dustbin.IsFluid;
var sandsPerItem = Dustbin.SandsFactors[itemId < fluidArr.Length && fluidArr[itemId]
? 0
: itemId switch
{
1005 => 2,
1003 => 3,
1013 => 4,
_ => 1,
}];
if (sandsPerItem <= 0) return false;
var player = GameMain.mainPlayer;
var addCount = count * sandsPerItem;
player.sandCount += addCount;
GameMain.history.OnSandCountChange(player.sandCount, addCount);
return false;
}
/* We keep this to make MOD compatible with older version */
[HarmonyPostfix]
[HarmonyPatch(typeof(StorageComponent), "Import")]
private static void StorageComponent_Import_Postfix(StorageComponent __instance)
{
if (__instance.bans >= 0)
return;
__instance.bans = -__instance.bans - 1;
IsDustbinField.SetValue(__instance, true);
}
}