1
0
mirror of https://github.com/soarqin/DSP_Mods.git synced 2025-12-08 21:33:28 +08:00

Dustbin v1.3.0

This commit is contained in:
2023-11-07 00:21:09 +08:00
parent 5d58a2a8fa
commit 269f98c995
8 changed files with 331 additions and 74 deletions

View File

@@ -571,20 +571,6 @@ public static class FactoryPatch
set.Remove(v);
}
[HarmonyPostfix]
[HarmonyPatch(typeof(UXAssist.PlanetFunctions), nameof(UXAssist.PlanetFunctions.RecreatePlanet))]
private static void UXAssist_PlanetFunctions_RecreatePlanet_Postfix()
{
var player = GameMain.mainPlayer;
if (player == null) return;
var factory = GameMain.localPlanet?.factory;
if (factory == null) return;
if (BeltSignalGeneratorEnabled.Value)
{
RemovePlanetSignalBelts(factory.index);
}
}
[HarmonyPostfix]
[HarmonyPatch(typeof(GameMain), nameof(GameMain.Begin))]
private static void GameMain_Begin_Postfix()
@@ -592,15 +578,17 @@ public static class FactoryPatch
if (BeltSignalGeneratorEnabled.Value) InitSignalBelts();
InitItemSources();
}
[HarmonyPostfix]
[HarmonyPatch(typeof(PlanetFactory), nameof(PlanetFactory.Init))]
private static void PlanetFactory_Init_Postfix(PlanetFactory __instance)
[HarmonyPatch(typeof(DigitalSystem), MethodType.Constructor, typeof(PlanetData))]
private static void DigitalSystem_Constructor_Postfix(PlanetData _planet)
{
if (BeltSignalGeneratorEnabled.Value)
{
RemovePlanetSignalBelts(__instance.index);
}
if (!BeltSignalGeneratorEnabled.Value) return;
var player = GameMain.mainPlayer;
if (player == null) return;
var factory = _planet?.factory;
if (factory == null) return;
RemovePlanetSignalBelts(factory.index);
}
[HarmonyPrefix]
@@ -735,6 +723,7 @@ public static class FactoryPatch
var beltId = pair.Key;
ref var belt = ref cargoTraffic.beltPool[beltId];
var cargoPath = cargoTraffic.GetCargoPath(belt.segPathId);
if (cargoPath == null) continue;
int itemId;
if ((itemId = cargoPath.TryPickItem(belt.segIndex + belt.segPivotOffset - 5, 12, out var stack, out _)) > 0)
{
@@ -749,6 +738,7 @@ public static class FactoryPatch
var beltId = pair.Key;
ref var belt = ref cargoTraffic.beltPool[beltId];
var cargoPath = cargoTraffic.GetCargoPath(belt.segPathId);
if (cargoPath == null) continue;
var segIndex = belt.segIndex + belt.segPivotOffset;
if (!cargoPath.GetCargoAtIndex(segIndex, out var cargo, out var cargoId, out var _)) break;
var itemId = cargo.item;
@@ -759,7 +749,9 @@ public static class FactoryPatch
{
var cargoTraffic1 = factories[(int)(n >> 32)].cargoTraffic;
ref var belt1 = ref cargoTraffic1.beltPool[(int)(n & 0x7FFFFFFF)];
if (!cargoTraffic1.GetCargoPath(belt1.segPathId).TryInsertItem(belt1.segIndex + belt1.segPivotOffset, itemId, stack, inc)) continue;
cargoPath = cargoTraffic1.GetCargoPath(belt1.segPathId);
if (cargoPath == null) continue;
if (!cargoPath.TryInsertItem(belt1.segIndex + belt1.segPivotOffset, itemId, stack, inc)) continue;
cargoPath.TryPickItem(segIndex - 5, 12, out var stack1, out var inc1);
if (inc1 != inc || stack1 != stack)
cargoPath.TryPickItem(segIndex - 5, 12, out _, out _);
@@ -779,9 +771,11 @@ public static class FactoryPatch
var beltId = pair.Key;
ref var belt = ref cargoTraffic.beltPool[beltId];
var cargoPath = cargoTraffic.GetCargoPath(belt.segPathId);
if (cargoPath == null) continue;
var stack = beltSignal.Stack;
var inc = beltSignal.Inc;
if (!cargoTraffic.GetCargoPath(belt.segPathId).TryInsertItem(belt.segIndex + belt.segPivotOffset, signalId, stack, inc)) continue;
if (!cargoPath.TryInsertItem(belt.segIndex + belt.segPivotOffset, signalId, stack, inc)) continue;
productRegister[signalId] += stack;
if (!countRecipe) continue;
var sources = beltSignal.Sources;

211
Dustbin/BeltSignal.cs Normal file
View File

@@ -0,0 +1,211 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using HarmonyLib;
using UnityEngine;
namespace Dustbin;
public static class BeltSignal
{
private static HashSet<int>[] _signalBelts;
private static int _signalBeltsCapacity;
private static bool _initialized;
private static AssetBundle _bundle;
private static Harmony _patch;
public static void Enable(bool on)
{
if (on)
{
_patch ??= Harmony.CreateAndPatchAll(typeof(BeltSignal));
InitSignalBelts();
}
else
{
_patch?.UnpatchSelf();
_patch = null;
_signalBelts = null;
_signalBeltsCapacity = 0;
}
}
[HarmonyPostfix, HarmonyPriority(Priority.Last), HarmonyPatch(typeof(VFPreload), "InvokeOnLoadWorkEnded")]
private static void VFPreload_InvokeOnLoadWorkEnded_Postfix()
{
if (_initialized) return;
var pluginfolder = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
_bundle = AssetBundle.LoadFromFile($"{pluginfolder}/dustbin.assetbundle");
var signals = LDB._signals;
var index = signals.dataArray.Length;
var p = new SignalProto
{
ID = 410,
Name = "DUSTBIN",
GridIndex = 3110,
IconPath = "Assets/signal-410.png",
_iconSprite = _bundle.LoadAsset<Sprite>("Assets/signal-410.png"),
SID = ""
};
p.name = p.Name.Translate();
signals.dataArray = signals.dataArray.AddItem(p).ToArray();
signals.dataIndices[p.ID] = index;
_initialized = true;
}
private static void InitSignalBelts()
{
if (!GameMain.isRunning) return;
_signalBelts = new HashSet<int>[64];
_signalBeltsCapacity = 64;
var factories = GameMain.data?.factories;
if (factories == null) return;
foreach (var factory in factories)
{
var entitySignPool = factory?.entitySignPool;
if (entitySignPool == null) continue;
var cargoTraffic = factory.cargoTraffic;
var beltPool = cargoTraffic.beltPool;
for (var i = cargoTraffic.beltCursor - 1; i > 0; i--)
{
if (beltPool[i].id != i) continue;
ref var signal = ref entitySignPool[beltPool[i].entityId];
var signalId = signal.iconId0;
if (signalId != 410U) continue;
SetSignalBelt(factory.index, i);
}
}
}
private static void SetSignalBelt(int factory, int beltId)
{
var signalBelts = GetOrCreateSignalBelts(factory);
signalBelts.Add(beltId);
}
private static HashSet<int> GetOrCreateSignalBelts(int index)
{
HashSet<int> obj;
if (index < 0) return null;
if (index >= _signalBeltsCapacity)
{
var newCapacity = _signalBeltsCapacity * 2;
var newSignalBelts = new HashSet<int>[newCapacity];
Array.Copy(_signalBelts, newSignalBelts, _signalBeltsCapacity);
_signalBelts = newSignalBelts;
_signalBeltsCapacity = newCapacity;
}
else
{
obj = _signalBelts[index];
if (obj != null) return obj;
}
obj = new HashSet<int>();
_signalBelts[index] = obj;
return obj;
}
private static HashSet<int> GetSignalBelts(int index)
{
return index >= 0 && index < _signalBeltsCapacity ? _signalBelts[index] : null;
}
private static void RemoveSignalBelt(int factory, int beltId)
{
GetSignalBelts(factory)?.Remove(beltId);
}
private static void RemovePlanetSignalBelts(int factory)
{
GetSignalBelts(factory)?.Clear();
}
[HarmonyPostfix]
[HarmonyPatch(typeof(DigitalSystem), MethodType.Constructor, typeof(PlanetData))]
private static void DigitalSystem_Constructor_Postfix(PlanetData _planet)
{
var player = GameMain.mainPlayer;
if (player == null) return;
var factory = _planet?.factory;
if (factory == null) return;
RemovePlanetSignalBelts(factory.index);
}
[HarmonyPostfix]
[HarmonyPatch(typeof(GameMain), nameof(GameMain.Begin))]
private static void GameMain_Begin_Postfix()
{
InitSignalBelts();
}
[HarmonyPrefix]
[HarmonyPatch(typeof(CargoTraffic), nameof(CargoTraffic.RemoveBeltComponent))]
public static void CargoTraffic_RemoveBeltComponent_Prefix(int id)
{
var planet = GameMain.localPlanet;
if (planet == null) return;
RemoveSignalBelt(planet.factoryIndex, id);
}
[HarmonyPostfix]
[HarmonyPatch(typeof(CargoTraffic), nameof(CargoTraffic.SetBeltSignalIcon))]
public static void CargoTraffic_SetBeltSignalIcon_Postfix(CargoTraffic __instance, int signalId, int entityId)
{
var planet = GameMain.localPlanet;
if (planet == null) return;
var factory = __instance.factory;
var factoryIndex = planet.factoryIndex;
var beltId = factory.entityPool[entityId].beltId;
if (signalId == 410)
{
SetSignalBelt(factoryIndex, beltId);
}
else
{
RemoveSignalBelt(factoryIndex, beltId);
}
}
[HarmonyTranspiler]
[HarmonyPatch(typeof(GameData), "GameTick")]
public static IEnumerable<CodeInstruction> GameData_GameTick_Transpiler(IEnumerable<CodeInstruction> instructions, ILGenerator generator)
{
var matcher = new CodeMatcher(instructions, generator);
matcher.MatchForward(false,
new CodeMatch(OpCodes.Call, AccessTools.Method(typeof(PerformanceMonitor), nameof(PerformanceMonitor.EndSample)))
).Advance(1).Insert(
new CodeInstruction(OpCodes.Call, AccessTools.Method(typeof(BeltSignal), nameof(ProcessBeltSignals)))
);
return matcher.InstructionEnumeration();
}
public static void ProcessBeltSignals()
{
var factories = GameMain.data?.factories;
if (factories == null) return;
foreach (var factory in factories)
{
if (factory == null) continue;
var index = factory.index;
var belts = GetSignalBelts(index);
if (belts == null || belts.Count == 0) continue;
var consumeRegister = GameMain.statistics.production.factoryStatPool[index].consumeRegister;
var cargoTraffic = factory.cargoTraffic;
foreach (var beltId in belts)
{
ref var belt = ref cargoTraffic.beltPool[beltId];
var cargoPath = cargoTraffic.GetCargoPath(belt.segPathId);
if (cargoPath == null) continue;
int itemId;
if ((itemId = cargoPath.TryPickItem(belt.segIndex + belt.segPivotOffset - 5, 12, out var stack, out _)) <= 0) continue;
consumeRegister[itemId] += stack;
Dustbin.CalcGetSands(itemId, stack);
}
}
}
}

View File

@@ -1,9 +1,9 @@
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using BepInEx;
using crecheng.DSPModSave;
using HarmonyLib;
using NebulaAPI;
namespace Dustbin;
@@ -20,7 +20,6 @@ public class Dustbin : BaseUnityPlugin, IModCanSave, IMultiplayerMod
public new static readonly BepInEx.Logging.ManualLogSource Logger =
BepInEx.Logging.Logger.CreateLogSource(PluginInfo.PLUGIN_NAME);
private bool _cfgEnabled = true;
public static readonly int[] SandsFactors = new int[12001];
public bool CheckVersion(string hostVersion, string clientVersion)
@@ -30,7 +29,9 @@ public class Dustbin : BaseUnityPlugin, IModCanSave, IMultiplayerMod
private void Awake()
{
_cfgEnabled = Config.Bind("General", "Enabled", _cfgEnabled, "enable/disable this plugin").Value;
var storageDustbin = Config.Bind("General", "StorageDustbin", true, "Can turn storages into dustbins").Value;
var tankDustbin = Config.Bind("General", "TankDustbin", true, "Can turn tanks into dustbins").Value;
var belgSignalDustbin = Config.Bind("General", "BeltSignalDustbin", true, "Add belt signal as dustbin").Value;
var sandsFactorsStr = Config.Bind("General", "SandsFactors", "", "Sands get from different items\nFormat: id1:value1|id2:value2|...").Value;
foreach (var s in sandsFactorsStr.Split('|'))
{
@@ -40,22 +41,39 @@ public class Dustbin : BaseUnityPlugin, IModCanSave, IMultiplayerMod
if (!int.TryParse(sp[1], out var factor)) continue;
SandsFactors[id] = factor;
}
Harmony.CreateAndPatchAll(typeof(Dustbin));
Harmony.CreateAndPatchAll(typeof(StoragePatch));
Harmony.CreateAndPatchAll(typeof(TankPatch));
if (storageDustbin) StoragePatch.Enable(true);
if (tankDustbin) TankPatch.Enable(true);
NebulaModAPI.RegisterPackets(Assembly.GetExecutingAssembly());
NebulaModAPI.OnPlanetLoadFinished += RequestPlanetDustbinData;
if (storageDustbin || tankDustbin)
{
NebulaModAPI.RegisterPackets(Assembly.GetExecutingAssembly());
NebulaModAPI.OnPlanetLoadFinished += RequestPlanetDustbinData;
}
if (belgSignalDustbin) BeltSignal.Enable(true);
}
[HarmonyPrefix]
[HarmonyPatch(typeof(GameMain), "Start")]
private static void GameMain_Start_Prefix()
private void OnDestroy()
{
StoragePatch.Reset();
TankPatch.Reset();
TankPatch.Enable(false);
StoragePatch.Enable(false);
BeltSignal.Enable(false);
NebulaModAPI.OnPlanetLoadFinished -= RequestPlanetDustbinData;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static int CalcGetSands(int itemId, int count)
{
var sandsPerItem = itemId <= 12000 ? Dustbin.SandsFactors[itemId] : 0;
if (sandsPerItem <= 0) return count;
var player = GameMain.mainPlayer;
var addCount = count * sandsPerItem;
player.sandCount += addCount;
GameMain.history.OnSandCountChange(player.sandCount, addCount);
return count;
}
#region IModSave
public void Export(BinaryWriter w)
{
w.Write(ModSaveVersion);
@@ -74,7 +92,9 @@ public class Dustbin : BaseUnityPlugin, IModCanSave, IMultiplayerMod
public void IntoOtherSave()
{
}
#endregion
#region IMultiplayerMod
public static byte[] ExportData(PlanetFactory factory)
{
var planetId = factory.planetId;
@@ -162,4 +182,5 @@ public class Dustbin : BaseUnityPlugin, IModCanSave, IMultiplayerMod
if (NebulaModAPI.IsMultiplayerActive && NebulaModAPI.MultiplayerSession.LocalPlayer.IsClient)
NebulaModAPI.MultiplayerSession.Network.SendPacket(new NebulaSupport.Packet.ToggleEvent(planetId, 0, false));
}
#endregion
}

View File

@@ -5,22 +5,24 @@
## Changelog
* 1.3.0
* Reworked dustbin support for Tanks, to improve performance and resolve known bugs.
+ Be note that the whole tank logic is optimized which may get a slight better performance even if you don't use them as dustbin.
* [Nebula Mupltiplayer Mod](https://dsp.thunderstore.io/package/nebula/NebulaMultiplayerMod/) and bug fixes from [ModFixerOne](https://dsp.thunderstore.io/package/starfi5h/ModFixerOne/) by [starfi5h](https://github.com/starfi5h/).
+ Add a belt signal(you can find it in first tab of signal selection panel) as dustbin, which is the simplest way to destroy items.
+ Reworked dustbin support for Tanks, to improve performance and resolve known bugs.
- Be note that the whole tank logic is optimized which may get a slight better performance even if you don't use them as dustbin.
+ Config entry for sands gain from destroyed items are changed to a more flexible format.
+ [Nebula Mupltiplayer Mod](https://dsp.thunderstore.io/package/nebula/NebulaMultiplayerMod/) and bug fixes from [ModFixerOne](https://dsp.thunderstore.io/package/starfi5h/ModFixerOne/) by [starfi5h](https://github.com/starfi5h/).
* 1.2.1
* Fix dynamic array bug in codes, which causes various bugs and errors.
+ Fix dynamic array bug in codes, which causes various bugs and errors.
* 1.2.0
* Use [DSPModSave](https://dsp.thunderstore.io/package/CommonAPI/DSPModSave/) to save dustbin specified data now, which fixes [#1](https://github.com/soarqin/DSP_Mods/issues/1).
* Fix issue for storages on multiple planets.
* Fix issue for multi-level tanks.
* Add a note in README for known bug on tank.
+ Use [DSPModSave](https://dsp.thunderstore.io/package/CommonAPI/DSPModSave/) to save dustbin specified data now, which fixes [#1](https://github.com/soarqin/DSP_Mods/issues/1).
+ Fix issue for storages on multiple planets.
+ Fix issue for multi-level tanks.
+ Add a note in README for known bug on tank.
* 1.1.0
* Rewrite whole plugin, make a checkbox on UI so that you can turn storages into dustbin by just ticking it.
* Can turn tank into dustbin now.
+ Rewrite whole plugin, make a checkbox on UI so that you can turn storages into dustbin by just ticking it.
+ Can turn tank into dustbin now.
## Usage
@@ -31,22 +33,24 @@
## 更新日志
* 1.3.0
* 重写了储液罐的垃圾桶实现以提高性能并解决已知的bug
+ 注意:整个储液罐逻辑都被优化了,即使你不把他们作为垃圾桶使用,也可能会获得轻微的性能提升
* [Nebula Mupltiplayer Mod](https://dsp.thunderstore.io/package/nebula/NebulaMultiplayerMod/)支持和Bug修正来自[starfi5h](https://github.com/starfi5h/)的[ModFixerOne](https://dsp.thunderstore.io/package/starfi5h/ModFixerOne/)
+ 添加了一个传送带信号(可以在信号选择面板的第一个页签中找到)作为垃圾桶,这是目前销毁物品最简单的方法
+ 重写了储液罐的垃圾桶实现以提高性能并解决已知的bug
- 注意:整个储液罐逻辑都被优化了,即使你不把他们作为垃圾桶使用,也可能会获得轻微的性能提升
+ 从销毁的物品中获得沙子的配置已变为更灵活的设置项格式
+ [Nebula Mupltiplayer Mod](https://dsp.thunderstore.io/package/nebula/NebulaMultiplayerMod/)支持和Bug修正来自[starfi5h](https://github.com/starfi5h/)的[ModFixerOne](https://dsp.thunderstore.io/package/starfi5h/ModFixerOne/)
* 1.2.1
* 修正了代码中的动态数组Bug该Bug可能导致各种问题
+ 修正了代码中的动态数组Bug该Bug可能导致各种问题
* 1.2.0
* 现在使用[DSPModSave](https://dsp.thunderstore.io/package/CommonAPI/DSPModSave/)来保存垃圾桶的数据,修正了[#1](https://github.com/soarqin/DSP_Mods/issues/1)
* 修正了多星球上的储物仓问题
* 修正了多层储液罐的问题
* 在README中添加了一个已知储液罐Bug的说明
+ 现在使用[DSPModSave](https://dsp.thunderstore.io/package/CommonAPI/DSPModSave/)来保存垃圾桶的数据,修正了[#1](https://github.com/soarqin/DSP_Mods/issues/1)
+ 修正了多星球上的储物仓问题
+ 修正了多层储液罐的问题
+ 在README中添加了一个已知储液罐Bug的说明
* 1.1.0
* 重写了整个插件现在可以在仓储类建筑的UI上勾选来将其转变为垃圾桶
* 现在可以将储液罐转变为垃圾桶
+ 重写了整个插件现在可以在仓储类建筑的UI上勾选来将其转变为垃圾桶
+ 现在可以将储液罐转变为垃圾桶
## 使用说明

View File

@@ -1,7 +1,6 @@
using System.Collections.Generic;
using System.IO;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using HarmonyLib;
using NebulaAPI;
using UnityEngine;
@@ -13,6 +12,20 @@ public static class StoragePatch
{
private static UI.MyCheckBox _storageDustbinCheckBox;
private static int _lastStorageId;
private static Harmony _patch;
public static void Enable(bool on)
{
if (on)
{
_patch ??= Harmony.CreateAndPatchAll(typeof(StoragePatch));
}
else
{
_patch?.UnpatchSelf();
_patch = null;
}
}
public static void Reset()
{
@@ -82,6 +95,13 @@ public static class StoragePatch
}
}
[HarmonyPrefix]
[HarmonyPatch(typeof(GameMain), "Start")]
private static void GameMain_Start_Prefix()
{
Reset();
}
[HarmonyPostfix]
[HarmonyPatch(typeof(UIStorageWindow), "_OnCreate")]
private static void UIStorageWindow__OnCreate_Postfix(UIStorageWindow __instance)
@@ -128,18 +148,6 @@ public static class StoragePatch
_lastStorageId = 0; // Refresh UI to reposition button on client side
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static int DustbinAddItem(int itemId, int count)
{
var sandsPerItem = itemId <= 12000 ? 0 : Dustbin.SandsFactors[itemId];
if (sandsPerItem <= 0) return count;
var player = GameMain.mainPlayer;
var addCount = count * sandsPerItem;
player.sandCount += addCount;
GameMain.history.OnSandCountChange(player.sandCount, addCount);
return count;
}
[HarmonyTranspiler]
[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 })]
@@ -155,7 +163,7 @@ public static class StoragePatch
new CodeInstruction(OpCodes.Brfalse, label1),
new CodeInstruction(OpCodes.Ldarg_1),
new CodeInstruction(OpCodes.Ldarg_2),
new CodeInstruction(OpCodes.Call, AccessTools.Method(typeof(StoragePatch), nameof(StoragePatch.DustbinAddItem))),
new CodeInstruction(OpCodes.Call, AccessTools.Method(typeof(Dustbin), nameof(Dustbin.CalcGetSands))),
new CodeInstruction(OpCodes.Ret)
);
matcher.Labels.Add(label1);

View File

@@ -1,5 +1,4 @@
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using HarmonyLib;
using NebulaAPI;
@@ -11,6 +10,20 @@ public static class TankPatch
{
private static UI.MyCheckBox _tankDustbinCheckBox;
private static int _lastTankId;
private static Harmony _patch;
public static void Enable(bool on)
{
if (on)
{
_patch ??= Harmony.CreateAndPatchAll(typeof(TankPatch));
}
else
{
_patch?.UnpatchSelf();
_patch = null;
}
}
public static void Reset()
{
@@ -86,6 +99,13 @@ public static class TankPatch
}
}
[HarmonyPrefix]
[HarmonyPatch(typeof(GameMain), "Start")]
private static void GameMain_Start_Prefix()
{
Reset();
}
[HarmonyPostfix]
[HarmonyPatch(typeof(UITankWindow), "_OnCreate")]
private static void UITankWindow__OnCreate_Postfix(UITankWindow __instance)

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 21 KiB

View File

@@ -1,5 +1,4 @@
using System;
using UnityEngine;
using UnityEngine;
using UXAssist.UI;
using UXAssist.Common;