├── Multifunction_mod ├── multifunctionpanel ├── app.config ├── Patchs │ ├── TankComponentPatch.cs │ ├── SpraycoaterComponentPatch.cs │ ├── Multifunction_modGameLogic.cs │ ├── BuildTool_ClickPatch.cs │ ├── SomePatch.cs │ ├── FactorySystemPatch.cs │ ├── StorageComponentPatch.cs │ ├── DriftBuildingsPatch.cs │ ├── PowerSystemPatch.cs │ ├── UIControlPanelPatch.cs │ ├── PlanetFactoryPatch.cs │ ├── PasteAnywayPatch.cs │ ├── PlayerPatch.cs │ ├── CombatPatch.cs │ ├── UIPatch.cs │ ├── PlanetTransportPatch.cs │ ├── DysonPatch.cs │ ├── StationComponentPatch.cs │ └── CargoTrafficPatch.cs ├── Utils │ └── SplitIncUtil.cs ├── Models │ ├── SeedPlanetWater.cs │ └── PropertyData.cs ├── Properties │ └── AssemblyInfo.cs ├── Multifunctionpatch.cs ├── Multifunction_mod.csproj ├── MultifunctionTranslate.cs └── Constant.cs ├── Multifunction_mod.sln ├── README.md ├── .gitattributes └── .gitignore /Multifunction_mod/multifunctionpanel: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/blacksnipebiu/Multifunction_mod/HEAD/Multifunction_mod/multifunctionpanel -------------------------------------------------------------------------------- /Multifunction_mod/app.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /Multifunction_mod/Patchs/TankComponentPatch.cs: -------------------------------------------------------------------------------- 1 | using HarmonyLib; 2 | using static Multifunction_mod.Multifunction; 3 | 4 | namespace Multifunction_mod.Patchs 5 | { 6 | public class TankComponentPatch 7 | { 8 | [HarmonyPrefix] 9 | [HarmonyPatch(typeof(TankComponent), "GameTick")] 10 | public static void TankComponentGameTickPatchPrefix(ref TankComponent __instance) 11 | { 12 | if (!TankMaxproliferator.Value) 13 | { 14 | return; 15 | } 16 | __instance.fluidInc = __instance.fluidCount * incAbility; 17 | } 18 | 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /Multifunction_mod/Utils/SplitIncUtil.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace Multifunction_mod.Utils 8 | { 9 | internal class SplitIncUtil 10 | { 11 | public static int split_inc(ref int itemcount, ref int iteminc, int splitcount) 12 | { 13 | if (itemcount == 0) 14 | { 15 | iteminc = 0; 16 | return 0; 17 | } 18 | int num = iteminc / itemcount; 19 | int num2 = iteminc - num * itemcount; 20 | itemcount -= splitcount; 21 | num2 -= itemcount; 22 | num = ((num2 > 0) ? (num * splitcount + num2) : (num * splitcount)); 23 | iteminc -= num; 24 | return num; 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /Multifunction_mod/Models/SeedPlanetWater.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Linq; 3 | 4 | namespace Multifunction_mod.Models 5 | { 6 | public class SeedPlanetWater 7 | { 8 | public long seedKey64 { get; set; } 9 | public Dictionary waterTypes { get; set; } 10 | 11 | public SeedPlanetWater() 12 | { 13 | waterTypes = new Dictionary(); 14 | } 15 | 16 | public SeedPlanetWater(long seed) 17 | { 18 | seedKey64 = seed; 19 | waterTypes = new Dictionary(); 20 | } 21 | 22 | public string ToStr() 23 | { 24 | string result = seedKey64 + ","; 25 | result += string.Join("", waterTypes.Select(x => x.Key + ":" + x.Value + "-")); 26 | return result; 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /Multifunction_mod/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // 有关程序集的一般信息由以下 6 | // 控制。更改这些特性值可修改 7 | // 与程序集关联的信息。 8 | [assembly: AssemblyTitle("Multifunction_mod")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("Multifunction_mod")] 13 | [assembly: AssemblyCopyright("Copyright © 2022")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // 将 ComVisible 设置为 false 会使此程序集中的类型 18 | //对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型 19 | //请将此类型的 ComVisible 特性设置为 true。 20 | [assembly: ComVisible(false)] 21 | 22 | // 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID 23 | [assembly: Guid("d898890a-6afd-4680-84d6-0b5ebf5656c9")] 24 | 25 | // 程序集的版本信息由下列四个值组成: 26 | // 27 | // 主版本 28 | // 次版本 29 | // 生成号 30 | // 修订号 31 | // 32 | //可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值 33 | //通过使用 "*",如下所示: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /Multifunction_mod/Patchs/SpraycoaterComponentPatch.cs: -------------------------------------------------------------------------------- 1 | using HarmonyLib; 2 | using static Multifunction_mod.Multifunction; 3 | 4 | namespace Multifunction_mod.Patchs 5 | { 6 | public class SpraycoaterComponentPatch 7 | { 8 | [HarmonyPrefix] 9 | [HarmonyPatch(typeof(SpraycoaterComponent), "InternalUpdate")] 10 | public static void SpraycoaterComponentInternalUpdatePrefix(ref SpraycoaterComponent __instance) 11 | { 12 | if (!Maxproliferator.Value) 13 | { 14 | return; 15 | } 16 | Multifunctionpatch.ability = __instance.incAbility; 17 | __instance.incAbility = 10; 18 | } 19 | 20 | [HarmonyPostfix] 21 | [HarmonyPatch(typeof(SpraycoaterComponent), "InternalUpdate")] 22 | public static void SpraycoaterComponentInternalUpdatePostfix(ref SpraycoaterComponent __instance) 23 | { 24 | if (Maxproliferator.Value || __instance.incAbility <= 4) 25 | { 26 | return; 27 | } 28 | __instance.incAbility = Multifunctionpatch.ability; 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /Multifunction_mod/Patchs/Multifunction_modGameLogic.cs: -------------------------------------------------------------------------------- 1 | using HarmonyLib; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | 8 | namespace Multifunction_mod.Patchs 9 | { 10 | internal class Multifunction_modGameLogic 11 | { 12 | public static Action OnDataLoaded; 13 | public static Action OnGameBegin; 14 | public static Action OnGameEnd; 15 | 16 | [HarmonyPostfix] 17 | [HarmonyPatch(typeof(VFPreload), "InvokeOnLoadWorkEnded")] 18 | public static void VFPreload_InvokeOnLoadWorkEnded_Postfix() 19 | { 20 | OnDataLoaded?.Invoke(); 21 | } 22 | 23 | [HarmonyPostfix, HarmonyPriority(Priority.First)] 24 | [HarmonyPatch(typeof(GameMain), nameof(GameMain.Begin))] 25 | public static void GameMain_Begin_Postfix() 26 | { 27 | OnGameBegin?.Invoke(); 28 | } 29 | 30 | [HarmonyPostfix, HarmonyPriority(Priority.Last)] 31 | [HarmonyPatch(typeof(GameMain), nameof(GameMain.End))] 32 | public static void GameMain_End_Postfix() 33 | { 34 | OnGameEnd?.Invoke(); 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /Multifunction_mod.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 17 4 | VisualStudioVersion = 17.1.32414.318 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Multifunction_mod", "Multifunction_mod\Multifunction_mod.csproj", "{D898890A-6AFD-4680-84D6-0B5EBF5656C9}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Release|Any CPU = Release|Any CPU 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {D898890A-6AFD-4680-84D6-0B5EBF5656C9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 15 | {D898890A-6AFD-4680-84D6-0B5EBF5656C9}.Debug|Any CPU.Build.0 = Debug|Any CPU 16 | {D898890A-6AFD-4680-84D6-0B5EBF5656C9}.Release|Any CPU.ActiveCfg = Release|Any CPU 17 | {D898890A-6AFD-4680-84D6-0B5EBF5656C9}.Release|Any CPU.Build.0 = Release|Any CPU 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | GlobalSection(ExtensibilityGlobals) = postSolution 23 | SolutionGuid = {91EA0BB5-5F24-429F-9E11-EFE4D294FD20} 24 | EndGlobalSection 25 | EndGlobal 26 | -------------------------------------------------------------------------------- /Multifunction_mod/Patchs/BuildTool_ClickPatch.cs: -------------------------------------------------------------------------------- 1 | using HarmonyLib; 2 | using static Multifunction_mod.Multifunction; 3 | 4 | namespace Multifunction_mod.Patchs 5 | { 6 | public class BuildTool_ClickPatch 7 | { 8 | [HarmonyPrefix] 9 | [HarmonyPatch(typeof(BuildTool_Click), "CheckBuildConditions")] 10 | public static bool CheckBuildConditionsPatchPrefix(BuildTool_Click __instance, ref bool __result) 11 | { 12 | if (!PasteBuildAnyWay && !build_station_nocondition.Value) 13 | { 14 | return true; 15 | } 16 | for (int i = 0; i < __instance.buildPreviews.Count; i++) 17 | { 18 | var prefab = __instance.buildPreviews[i]?.item?.prefabDesc; 19 | if (prefab != null && prefab.veinMiner) 20 | { 21 | return true; 22 | } 23 | if (build_station_nocondition.Value && !PasteBuildAnyWay && !(prefab.isStation || prefab.isStation || prefab.isCollectStation)) 24 | { 25 | return true; 26 | } 27 | } 28 | __result = true; 29 | return false; 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /Multifunction_mod/Patchs/SomePatch.cs: -------------------------------------------------------------------------------- 1 | using HarmonyLib; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Numerics; 5 | using System.Reflection.Emit; 6 | using UnityEngine; 7 | using static Multifunction_mod.Multifunction; 8 | using Quaternion = UnityEngine.Quaternion; 9 | using Vector3 = UnityEngine.Vector3; 10 | 11 | namespace Multifunction_mod.Patchs 12 | { 13 | public class SomePatch 14 | { 15 | 16 | 17 | [HarmonyPrefix] 18 | [HarmonyPatch(typeof(DispenserComponent), "InternalTick")] 19 | public static void DispenserComponentInternalTickPrefix(ref DispenserComponent __instance) 20 | { 21 | if (!Stationfullenergy.Value) 22 | { 23 | return; 24 | } 25 | __instance.energy = __instance.energyMax; 26 | } 27 | 28 | [HarmonyPostfix] 29 | [HarmonyPatch(typeof(PropertySystem), "GetItemTotalProperty")] 30 | public static void GetItemTotalPropertyPatch(ref int __result) 31 | { 32 | if (!Property9999999) 33 | return; 34 | __result = int.MaxValue; 35 | } 36 | 37 | [HarmonyPostfix] 38 | [HarmonyPatch(typeof(ItemProto), "isFluid")] 39 | public static void ItemProtoisFluidPatch(ref bool __result) 40 | { 41 | if (!Tankcontentall.Value) 42 | { 43 | return; 44 | } 45 | __result = true; 46 | } 47 | 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /Multifunction_mod/Patchs/FactorySystemPatch.cs: -------------------------------------------------------------------------------- 1 | using HarmonyLib; 2 | using static Multifunction_mod.Multifunction; 3 | 4 | namespace Multifunction_mod.Patchs 5 | { 6 | public class FactorySystemPatch 7 | { 8 | 9 | [HarmonyPostfix] 10 | [HarmonyPatch(typeof(FactorySystem), "NewEjectorComponent")] 11 | public static void NewEjectorComponentPatch(ref int __result, FactorySystem __instance) 12 | { 13 | if (!quickEjector) 14 | { 15 | return; 16 | } 17 | __instance.ejectorPool[__result].bulletCount = int.MaxValue; 18 | __instance.ejectorPool[__result].bulletId = 1501; 19 | __instance.ejectorPool[__result].coldSpend = 5; 20 | __instance.ejectorPool[__result].chargeSpend = 4; 21 | } 22 | 23 | [HarmonyPostfix] 24 | [HarmonyPatch(typeof(FactorySystem), "NewSiloComponent")] 25 | public static void NewSiloComponentPatch(ref int __result, FactorySystem __instance) 26 | { 27 | if (!quicksilo) 28 | { 29 | return; 30 | } 31 | __instance.siloPool[__result].bulletCount = int.MaxValue; 32 | __instance.siloPool[__result].bulletId = 1503; 33 | __instance.siloPool[__result].coldSpend = 40; 34 | __instance.siloPool[__result].chargeSpend = 80; 35 | 36 | } 37 | 38 | [HarmonyPrefix] 39 | [HarmonyPatch(typeof(FactoryStorage), "NewTankComponent")] 40 | public static void NewTankComponentPatch(ref int fCount) 41 | { 42 | if (!Infinitestoragetank.Value) 43 | return; 44 | fCount = int.MaxValue - 200; 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /Multifunction_mod/Patchs/StorageComponentPatch.cs: -------------------------------------------------------------------------------- 1 | using HarmonyLib; 2 | using System; 3 | using static Multifunction_mod.Multifunction; 4 | 5 | namespace Multifunction_mod.Patchs 6 | { 7 | public class StorageComponentPatch 8 | { 9 | [HarmonyPostfix] 10 | [HarmonyPatch(typeof(StorageComponent), "Import")] 11 | public static void StorageComponentImportPatch(StorageComponent __instance) 12 | { 13 | if (StackMultiple.Value > 1) 14 | { 15 | for (int i = 0; i < __instance.size; i++) 16 | { 17 | if (__instance.entityId > 0 && __instance.grids[i].itemId > 0) 18 | { 19 | ItemProto itemProto = LDB.items.Select(__instance.grids[i].itemId); 20 | if (itemProto != null) 21 | { 22 | __instance.grids[i].stackSize = itemProto.StackSize * StackMultiple.Value; 23 | } 24 | } 25 | } 26 | } 27 | } 28 | 29 | [HarmonyPostfix] 30 | [HarmonyPatch(typeof(StorageComponent), "LoadStatic")] 31 | public static void Postfix() 32 | { 33 | if (StackMultiple.Value > 1) 34 | { 35 | ItemProto[] dataArray = LDB.items.dataArray; 36 | for (int j = 0; j < dataArray.Length; j++) 37 | { 38 | StorageComponent.itemStackCount[dataArray[j].ID] = dataArray[j].StackSize * StackMultiple.Value; 39 | } 40 | } 41 | 42 | } 43 | 44 | [HarmonyPostfix] 45 | [HarmonyPatch(typeof(StorageComponent), "GetItemCount", new Type[] { typeof(int) })] 46 | public static void GetItemCountPatch(StorageComponent __instance, int itemId, ref int __result) 47 | { 48 | if (ArchitectMode.Value) 49 | { 50 | if (itemId <= 0 || itemId >= 6007 || __instance == null || __instance.id != GameMain.mainPlayer.package.id) return; 51 | if (LDB.items.Select(itemId).CanBuild && __result == 0) __result = 100; 52 | } 53 | } 54 | 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /Multifunction_mod/Multifunctionpatch.cs: -------------------------------------------------------------------------------- 1 | using HarmonyLib; 2 | using Multifunction_mod.Patchs; 3 | using static Multifunction_mod.Multifunction; 4 | 5 | namespace Multifunction_mod 6 | { 7 | public class Multifunctionpatch 8 | { 9 | public static Harmony harmony; 10 | public static int ability = 4; 11 | 12 | public static void Patchallmethod() 13 | { 14 | harmony = new Harmony(GUID); 15 | var m = typeof(StorageComponent).GetMethods(); 16 | foreach (var i in m) 17 | { 18 | if (i.Name == "TakeTailItems" && i.ReturnType == typeof(void)) 19 | { 20 | var prefix = typeof(Multifunctionpatch).GetMethod("TakeTailItemsPatch"); 21 | harmony.Patch(i, new HarmonyMethod(prefix)); 22 | break; 23 | } 24 | } 25 | 26 | harmony.PatchAll(typeof(Multifunction_modGameLogic)); 27 | harmony.PatchAll(typeof(DysonPatch)); 28 | harmony.PatchAll(typeof(PlayerPatch)); 29 | harmony.PatchAll(typeof(PowerSystemPatch)); 30 | harmony.PatchAll(typeof(PlanetFactoryPatch)); 31 | harmony.PatchAll(typeof(StorageComponentPatch)); 32 | harmony.PatchAll(typeof(StationComponentPatch)); 33 | harmony.PatchAll(typeof(FactorySystemPatch)); 34 | harmony.PatchAll(typeof(CargoTrafficPatch)); 35 | harmony.PatchAll(typeof(SomePatch)); 36 | harmony.PatchAll(typeof(UIPatch)); 37 | harmony.PatchAll(typeof(PlanetTransportPatch)); 38 | harmony.PatchAll(typeof(TankComponentPatch)); 39 | harmony.PatchAll(typeof(SpraycoaterComponentPatch)); 40 | harmony.PatchAll(typeof(CombatPatch)); 41 | harmony.PatchAll(typeof(BuildTool_ClickPatch)); 42 | } 43 | 44 | public static bool TakeTailItemsPatch(StorageComponent __instance, ref int itemId) 45 | { 46 | if (ArchitectMode.Value) 47 | { 48 | if (itemId <= 0 || itemId >= 6007 || __instance == null || __instance.id != GameMain.mainPlayer.package.id) return true; 49 | if (LDB.items.Select(itemId).CanBuild) return false; 50 | } 51 | return true; 52 | } 53 | 54 | } 55 | 56 | } 57 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Multifunction Mod(Dyson Sphere Program) 2 | 3 | 一个为《戴森球计划》提供“OP 面板”和大量质量生活增强的综合功能 Mod。集成机甲强化、建筑与电力调整、矿脉与海洋管理、物流站扩展、量子传输站、戴森云/壳增强等功能,支持中英双语界面。 4 | 5 | ## 功能概览 6 | 7 | - 人物/机甲 8 | - 走路、跳跃、采矿、制造、研究速度调节 9 | - 小飞机数量/速度/任务点调整;可设为不耗能 10 | - 机甲能量无限、无需翘曲器曲速飞行 11 | - 快速手搓、快速采矿、快速制造、直接获取物品 12 | - 锁血、假死、玩家攻速 Max、战斗相关倍率(战机耐久/速度/射速等) 13 | 14 | - 建筑与电力 15 | - 建筑秒完成、蓝图建造无需材料、操作范围不受限制 16 | - 设备不耗电、物流站永久满电、物流站内置喷涂/发电 17 | - 风力涡轮机无限能源/覆盖全球/超长连接 18 | - 建造无需条件、强制粘贴蓝图 19 | 20 | - 物流站与储液站 21 | - 额外存储倍率、堆叠倍率、增产点数上限 22 | - 储液站:无限容量、任意内容存储、无限增产 23 | - 机甲物流:需求/回收支持仓库与物流站;建筑/物品优先进入玩家背包 24 | - 传送带信号功能(BeltSignal) 25 | 26 | - 量子传输站(星球/星系级) 27 | - 星球级/星系级翘曲全面供应 28 | - 星球级材料供应与拿取:物流站、矿机、发射井/弹射器、研究站、电力设备、组装机 29 | - 自定义量子耗能(每件物品) 30 | - 自动改名为“星球量子传输站”“星系量子传输站” 31 | 32 | - 矿脉与海洋管理 33 | - 生成/移动单矿与整堆、整理/切割为指定行数、删除/掩埋全部矿 34 | - 获取所有矿并批量调整;添加油井速率/矿脉数量 35 | - 铺平星球(含地基/自定义颜色),改变/还原海洋类型,恢复所有星球海洋类型 36 | 37 | - 戴森云/壳 38 | - 跳过太阳帆吸收/子弹阶段、每帧吸收、全球打帆、间隔发射 39 | - 打开戴森壳半径上下限、初始化/保存/导入蓝图 40 | - 注意:涉及戴森壳/云半径与跳过阶段的操作可能不可逆,使用前请务必备份存档 41 | 42 | - 其它 43 | - 成就重新检测、传送、夜灯、垃圾站/丢垃圾速率、窗口显示与缩放 44 | 45 | > 以上为核心类别与常见项,完整开关与数值请在游戏内 OP 面板查看。 46 | 47 | ## 使用方式 48 | 49 | - 打开 OP 面板:默认快捷键 `LeftAlt + 1` 50 | - 面板标题会显示版本号,支持拖动与缩放 51 | - 面板内可勾选“改变窗口快捷键”,按提示录入新热键 52 | - 面板分类:`人物`、`建筑`、`星球`、`戴森球`、`其它功能`、`机甲物流` 53 | - 高危操作提示: 54 | - “极速弹射器/发射井”“跳过太阳帆阶段”“开放壳半径上下限”等,均可能造成异常,请先备份存档 55 | 56 | ## 安装 57 | 58 | - 前置:需要 BepInEx(Harmony)环境,适用于《戴森球计划》的插件加载 59 | - 手动安装: 60 | 1. 构建生成 `Multifunction_mod.dll` 61 | 2. 将 `Multifunction_mod.dll` 置于 `Dyson Sphere Program/BepInEx/plugins/Multifunction_mod/` 62 | 3. 启动游戏,进入存档后按 `LeftAlt + 1` 打开 OP 面板 63 | - 配置文件:`BepInEx/config/cn.blacksnipe.dsp.Multfuntion_mod.cfg` 64 | - 所有开关与数值均可在游戏中通过 OP 面板调整;必要时也可直接编辑该配置文件 65 | 66 | ## 构建与调试 67 | 68 | - 打开 `Multifunction_mod.sln`(建议使用 Visual Studio 2022) 69 | - 根据你本机的游戏安装路径,调整项目引用: 70 | - `Assembly-CSharp.dll`、`UnityEngine*.dll`、`BepInEx.dll`、`0Harmony.dll` 71 | - `Multifunction_mod.csproj` 包含构建后事件: 72 | - 结束游戏进程、将生成的 `Multifunction_mod.dll` 拷贝到 `BepInEx/plugins/Multifunction_mod/`、通过 Steam 启动游戏 73 | - 如你的路径不同,请在 `.csproj` 中修改对应 HintPath 与 PostBuildEvent 74 | 75 | ## 本地化 76 | 77 | - 自动根据游戏语言显示中英文(见 `MultifunctionTranslate.cs`) 78 | - 面板与提示文本提供中英双语翻译 79 | 80 | ## 元信息 81 | 82 | - 命名空间:`Multifunction_mod` 83 | - 入口类:`Multifunction`(继承 `BaseUnityPlugin`,含 `[BepInPlugin]` 注解) 84 | - 主面板资源:嵌入式 `multifunctionpanel` 资产 85 | 86 | ## 反馈 87 | 88 | - 若遇到兼容性或异常行为,请提供日志与复现步骤(建议附带存档备份),并说明你启用的具体开关/数值与使用场景 89 | 90 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # Set default behavior to automatically normalize line endings. 3 | ############################################################################### 4 | * text=auto 5 | 6 | ############################################################################### 7 | # Set default behavior for command prompt diff. 8 | # 9 | # This is need for earlier builds of msysgit that does not have it on by 10 | # default for csharp files. 11 | # Note: This is only used by command line 12 | ############################################################################### 13 | #*.cs diff=csharp 14 | 15 | ############################################################################### 16 | # Set the merge driver for project and solution files 17 | # 18 | # Merging from the command prompt will add diff markers to the files if there 19 | # are conflicts (Merging from VS is not affected by the settings below, in VS 20 | # the diff markers are never inserted). Diff markers may cause the following 21 | # file extensions to fail to load in VS. An alternative would be to treat 22 | # these files as binary and thus will always conflict and require user 23 | # intervention with every merge. To do so, just uncomment the entries below 24 | ############################################################################### 25 | #*.sln merge=binary 26 | #*.csproj merge=binary 27 | #*.vbproj merge=binary 28 | #*.vcxproj merge=binary 29 | #*.vcproj merge=binary 30 | #*.dbproj merge=binary 31 | #*.fsproj merge=binary 32 | #*.lsproj merge=binary 33 | #*.wixproj merge=binary 34 | #*.modelproj merge=binary 35 | #*.sqlproj merge=binary 36 | #*.wwaproj merge=binary 37 | 38 | ############################################################################### 39 | # behavior for image files 40 | # 41 | # image files are treated as binary by default. 42 | ############################################################################### 43 | #*.jpg binary 44 | #*.png binary 45 | #*.gif binary 46 | 47 | ############################################################################### 48 | # diff behavior for common document formats 49 | # 50 | # Convert binary document formats to text before diffing them. This feature 51 | # is only available from the command line. Turn it on by uncommenting the 52 | # entries below. 53 | ############################################################################### 54 | #*.doc diff=astextplain 55 | #*.DOC diff=astextplain 56 | #*.docx diff=astextplain 57 | #*.DOCX diff=astextplain 58 | #*.dot diff=astextplain 59 | #*.DOT diff=astextplain 60 | #*.pdf diff=astextplain 61 | #*.PDF diff=astextplain 62 | #*.rtf diff=astextplain 63 | #*.RTF diff=astextplain 64 | -------------------------------------------------------------------------------- /Multifunction_mod/Patchs/DriftBuildingsPatch.cs: -------------------------------------------------------------------------------- 1 | using HarmonyLib; 2 | using static Multifunction_mod.Multifunction; 3 | 4 | namespace Multifunction_mod.Patchs 5 | { 6 | public class DriftBuildingsPatch 7 | { 8 | public static bool IsPatched; 9 | [HarmonyPrefix] 10 | [HarmonyPatch(typeof(BuildTool_Click), "UpdatePreviewModels")] 11 | public static void Prefix(ref BuildTool_Click __instance) 12 | { 13 | if (!DriftBuildings) 14 | return; 15 | for (int i = 0; i < __instance.buildPreviews.Count; i++) 16 | { 17 | var bp = __instance.buildPreviews[i]; 18 | bp.lpos *= DriftBuildingHeight; 19 | bp.lpos2 *= DriftBuildingHeight; 20 | } 21 | } 22 | 23 | [HarmonyPrefix] 24 | [HarmonyPatch(typeof(BuildTool_BlueprintPaste), "CreatePrebuilds")] 25 | public static void BuildTool_BlueprintPasteCreatePrebuildsPatch(ref BuildTool_BlueprintPaste __instance) 26 | { 27 | if (!DriftBuildings) 28 | return; 29 | for (int i = 0; i < __instance.bpCursor; i++) 30 | { 31 | var bp = __instance.bpPool[i]; 32 | if (bp.desc.isBelt) 33 | { 34 | bp.lpos *= DriftBuildingHeight; 35 | bp.lpos2 *= DriftBuildingHeight; 36 | } 37 | } 38 | } 39 | 40 | [HarmonyPrefix] 41 | [HarmonyPatch(typeof(BuildTool_BlueprintPaste), "UpdatePreviewModels")] 42 | public static void BuildTool_BlueprintPastePrefix(ref BuildTool_BlueprintPaste __instance) 43 | { 44 | if (!DriftBuildings) 45 | return; 46 | for (int i = 0; i < __instance.bpCursor; i++) 47 | { 48 | var bp = __instance.bpPool[i]; 49 | if (bp.desc.isBelt) 50 | { 51 | bp.lpos *= DriftBuildingHeight; 52 | bp.lpos2 *= DriftBuildingHeight; 53 | } 54 | } 55 | } 56 | 57 | [HarmonyPostfix] 58 | [HarmonyPatch(typeof(BuildTool_BlueprintPaste), "UpdatePreviewModels")] 59 | public static void BuildTool_BlueprintPastePostfix(ref BuildTool_BlueprintPaste __instance) 60 | { 61 | if (!DriftBuildings) 62 | return; 63 | for (int i = 0; i < __instance.bpCursor; i++) 64 | { 65 | var bp = __instance.bpPool[i]; 66 | if (bp.desc.isBelt) 67 | { 68 | bp.lpos /= DriftBuildingHeight; 69 | bp.lpos2 /= DriftBuildingHeight; 70 | } 71 | 72 | } 73 | } 74 | 75 | [HarmonyPrefix] 76 | [HarmonyPatch(typeof(BuildTool_BlueprintPaste), "AlterBPGPUIModel")] 77 | public static void BuildTool_BlueprintPasteAlterBPGPUIModelPatch(ref BuildPreview _bp) 78 | { 79 | if (!DriftBuildings) 80 | return; 81 | _bp.lpos *= DriftBuildingHeight; 82 | _bp.lpos2 *= DriftBuildingHeight; 83 | } 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /Multifunction_mod/Patchs/PowerSystemPatch.cs: -------------------------------------------------------------------------------- 1 | using HarmonyLib; 2 | using static Multifunction_mod.Multifunction; 3 | 4 | namespace Multifunction_mod.Patchs 5 | { 6 | public class PowerSystemPatch 7 | { 8 | [HarmonyPostfix] 9 | [HarmonyPatch(typeof(PowerSystem), "NewGeneratorComponent")] 10 | public static void PowerSystemNewGeneratorComponent(ref int __result, PowerSystem __instance) 11 | { 12 | if (InfineteStarPower.Value && __instance.genPool[__result].fuelMask == 4) 13 | { 14 | __instance.genPool[__result].fuelId = 1803; 15 | __instance.genPool[__result].fuelCount = 100; 16 | __instance.genPool[__result].fuelEnergy = long.MaxValue; 17 | __instance.genPool[__result].genEnergyPerTick = 1000000000000; 18 | } 19 | if (WindturbinesUnlimitedEnergy.Value && __instance.genPool[__result].wind) 20 | { 21 | __instance.genPool[__result].genEnergyPerTick = 100_000_000_0000; 22 | } 23 | } 24 | 25 | [HarmonyPostfix] 26 | [HarmonyPatch(typeof(PowerSystem), "NewConsumerComponent")] 27 | public static void PowerSystemNewConsumerComponent(ref int __result, PowerSystem __instance) 28 | { 29 | if (!Buildingnoconsume.Value) 30 | { 31 | return; 32 | } 33 | int entityId = __instance.consumerPool[__result].entityId; 34 | int modelIndex = __instance.factory.entityPool[entityId].modelIndex; 35 | 36 | if (modelIndex > 0) 37 | { 38 | ModelProto modelProto = LDB.models.modelArray[modelIndex]; 39 | if (modelProto?.prefabDesc != null && modelProto.prefabDesc.isFieldGenerator) 40 | { 41 | return; 42 | } 43 | } 44 | __instance.consumerPool[__result].requiredEnergy = 0; 45 | __instance.consumerPool[__result].idleEnergyPerTick = 0; 46 | __instance.consumerPool[__result].workEnergyPerTick = 0; 47 | } 48 | 49 | [HarmonyPrefix] 50 | [HarmonyPatch(typeof(PowerSystem), "NewNodeComponent")] 51 | public static void NewNodeComponentPatchPrefix(PowerSystem __instance, ref int entityId, ref float conn, ref float cover) 52 | { 53 | var itemID = __instance.factory.entityPool[entityId].protoId; 54 | if (PlanetPower_bool.Value && itemID == 2210) 55 | { 56 | cover = GameMain.localPlanet.realRadius * 4; 57 | if (farconnectdistance) 58 | { 59 | conn = GameMain.localPlanet.realRadius * 1.5f; 60 | farconnectdistance = false; 61 | } 62 | } 63 | else if (Windturbinescovertheglobe.Value && itemID == 2203) 64 | { 65 | cover = GameMain.localPlanet.realRadius * 4; 66 | } 67 | } 68 | 69 | [HarmonyPostfix] 70 | [HarmonyPatch(typeof(PowerSystem), "NewNodeComponent")] 71 | public static void NewNodeComponentPatchPostfix(ref int __result, PowerSystem __instance) 72 | { 73 | if (!Buildingnoconsume.Value || GameMain.localPlanet.factory.entityPool[__instance.nodePool[__result].entityId].stationId > 0) 74 | { 75 | return; 76 | } 77 | __instance.nodePool[__result].requiredEnergy = 0; 78 | __instance.nodePool[__result].idleEnergyPerTick = 0; 79 | } 80 | 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /Multifunction_mod/Patchs/UIControlPanelPatch.cs: -------------------------------------------------------------------------------- 1 | using HarmonyLib; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Reflection.Emit; 6 | using System.Text; 7 | using System.Threading.Tasks; 8 | 9 | namespace Multifunction_mod.Patchs 10 | { 11 | internal class UIControlPanelPatch 12 | { 13 | private static Harmony _patch; 14 | private static bool enable; 15 | public static bool Enable 16 | { 17 | get => enable; 18 | set 19 | { 20 | if (enable == value) return; 21 | enable = value; 22 | if (enable) 23 | { 24 | _patch = Harmony.CreateAndPatchAll(typeof(UIControlPanelPatch)); 25 | } 26 | else 27 | { 28 | _patch.UnpatchSelf(); 29 | } 30 | } 31 | } 32 | [HarmonyTranspiler] 33 | [HarmonyPatch(typeof(UIControlPanelStationInspector), "OnDroneIconClick")] 34 | public static IEnumerable OnDroneIconClickPatch(IEnumerable instructions) 35 | { 36 | var codeMacher = new CodeMatcher(instructions). 37 | MatchForward(false, new CodeMatch(OpCodes.Call, AccessTools.Method(typeof(UIControlPanelStationInspector), "get_isLocal"))) 38 | .Set(OpCodes.Nop, null); 39 | return codeMacher.InstructionEnumeration(); 40 | } 41 | [HarmonyTranspiler] 42 | [HarmonyPatch(typeof(UIControlPanelStationInspector), "OnShipIconClick")] 43 | public static IEnumerable OnShipIconClickPatch(IEnumerable instructions) 44 | { 45 | var codeMacher = new CodeMatcher(instructions). 46 | MatchForward(false, new CodeMatch(OpCodes.Call, AccessTools.Method(typeof(UIControlPanelStationInspector), "get_isLocal"))) 47 | .Set(OpCodes.Nop, null); 48 | return codeMacher.InstructionEnumeration(); 49 | } 50 | [HarmonyTranspiler] 51 | [HarmonyPatch(typeof(UIControlPanelStationInspector), "OnWarperIconClick")] 52 | public static IEnumerable OnWarperIconClickPatch(IEnumerable instructions) 53 | { 54 | var codeMacher = new CodeMatcher(instructions). 55 | MatchForward(false, new CodeMatch(OpCodes.Call, AccessTools.Method(typeof(UIControlPanelStationInspector), "get_isLocal"))) 56 | .Set(OpCodes.Nop, null); 57 | return codeMacher.InstructionEnumeration(); 58 | } 59 | 60 | [HarmonyTranspiler] 61 | [HarmonyPatch(typeof(UIControlPanelStationStorage), "OnItemIconMouseDown")] 62 | public static IEnumerable OnItemIconMouseDownPatch(IEnumerable instructions) 63 | { 64 | var codeMacher = new CodeMatcher(instructions). 65 | MatchForward(false, new CodeMatch(OpCodes.Call, AccessTools.Method(typeof(UIControlPanelStationStorage), "get_isLocal"))) 66 | .Set(OpCodes.Nop, null) 67 | .MatchForward(false, new CodeMatch(OpCodes.Call, AccessTools.Method(typeof(UIControlPanelStationStorage), "get_isLocal"))) 68 | .Set(OpCodes.Nop, null); 69 | return codeMacher.InstructionEnumeration(); 70 | } 71 | 72 | [HarmonyTranspiler] 73 | [HarmonyPatch(typeof(UIControlPanelDispenserInspector), "OnItemIconMouseDown")] 74 | public static IEnumerable OnDispenserItemIconMouseDownPatch(IEnumerable instructions) 75 | { 76 | var codeMacher = new CodeMatcher(instructions). 77 | MatchForward(false, new CodeMatch(OpCodes.Call, AccessTools.Method(typeof(UIControlPanelDispenserInspector), "get_isLocal"))) 78 | .Set(OpCodes.Nop, null) 79 | .MatchForward(false, new CodeMatch(OpCodes.Call, AccessTools.Method(typeof(UIControlPanelDispenserInspector), "get_isLocal"))) 80 | .Set(OpCodes.Nop, null); 81 | return codeMacher.InstructionEnumeration(); 82 | } 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /Multifunction_mod/Patchs/PlanetFactoryPatch.cs: -------------------------------------------------------------------------------- 1 | using HarmonyLib; 2 | using static Multifunction_mod.Multifunction; 3 | 4 | namespace Multifunction_mod.Patchs 5 | { 6 | public class PlanetFactoryPatch 7 | { 8 | 9 | [HarmonyPostfix] 10 | [HarmonyPatch(typeof(PlanetFactory), "ComputeFlattenTerrainReform")] 11 | public static void PlanetFactoryNoComsumeSand(ref int costSandCount) 12 | { 13 | if (!InfiniteSand.Value) 14 | { 15 | return; 16 | } 17 | if (GameMain.mainPlayer != null && GameMain.mainPlayer.sandCount < int.MaxValue) 18 | { 19 | GameMain.mainPlayer.SetSandCount(int.MaxValue); 20 | } 21 | costSandCount = 0; 22 | } 23 | 24 | [HarmonyPostfix] 25 | [HarmonyPatch(typeof(PlanetFactory), "UpgradeEntityWithComponents")] 26 | public static void UpgradeEntityWithComponentsPatch(int entityId, PlanetFactory __instance) 27 | { 28 | if (!Buildingnoconsume.Value || entityId == 0 || __instance.entityPool[entityId].id == 0) 29 | return; 30 | if (GameMain.localPlanet.factory.entityPool[entityId].stationId > 0) 31 | { 32 | return; 33 | } 34 | int powerConId = __instance.entityPool[entityId].powerConId; 35 | if (powerConId <= 0) 36 | { 37 | return; 38 | } 39 | __instance.powerSystem.consumerPool[powerConId].idleEnergyPerTick = 0; 40 | __instance.powerSystem.consumerPool[powerConId].workEnergyPerTick = 0; 41 | } 42 | 43 | [HarmonyPrefix] 44 | [HarmonyPatch(typeof(PlanetFactory), "TakeBackItemsInEntity")] 45 | public static bool TakeBackItemsInEntityPatch() 46 | { 47 | return !entityitemnoneed; 48 | } 49 | 50 | [HarmonyPrefix] 51 | [HarmonyPatch(typeof(PlanetFactory), "CreateEntityLogicComponents")] 52 | public static void CreateEntityLogicComponentsPatch(PlanetFactory __instance, int entityId, PrefabDesc desc, int prebuildId) 53 | { 54 | if (desc.isStation && !string.IsNullOrEmpty(AutoChangeStationName.Value)) 55 | { 56 | __instance.WriteExtraInfoOnPrebuild(prebuildId, AutoChangeStationName.Value.getTranslate()); 57 | } 58 | } 59 | 60 | [HarmonyPrefix] 61 | [HarmonyPatch(typeof(ConstructionSystem), "GameTick")] 62 | public static void ConstructionSystemGameTick(ConstructionSystem __instance) 63 | { 64 | if (BuildNotime_bool.Value) 65 | { 66 | PlanetFactory planetFactory = player?.factory; 67 | if (GameMain.localPlanet == null || planetFactory == null) 68 | { 69 | return; 70 | } 71 | 72 | PrebuildData[] prebuildPool = planetFactory.prebuildPool; 73 | if (planetFactory.prebuildCount <= 0) 74 | { 75 | return; 76 | } 77 | 78 | int num = 0; 79 | PlanetFactory.batchBuild = true; 80 | HighStopwatch highStopwatch = new HighStopwatch(); 81 | highStopwatch.Begin(); 82 | planetFactory.BeginFlattenTerrain(); 83 | for (int i = planetFactory.prebuildCursor - 1; i > 0; i--) 84 | { 85 | if (prebuildPool[i].itemRequired > 0 && !Infinitething.Value && !ArchitectMode.Value) continue; 86 | if (prebuildPool[i].id == i && !prebuildPool[i].isDestroyed) 87 | { 88 | planetFactory.BuildFinally(GameMain.mainPlayer, prebuildPool[i].id, false); 89 | num++; 90 | } 91 | } 92 | 93 | planetFactory.EndFlattenTerrain(); 94 | 95 | PlanetFactory.batchBuild = false; 96 | if (num > 0) 97 | { 98 | GameMain.localPlanet.physics?.raycastLogic?.NotifyBatchObjectRemove(); 99 | GameMain.localPlanet.audio?.SetPlanetAudioDirty(); 100 | } 101 | } 102 | } 103 | 104 | 105 | } 106 | } 107 | -------------------------------------------------------------------------------- /Multifunction_mod/Patchs/PasteAnywayPatch.cs: -------------------------------------------------------------------------------- 1 | using HarmonyLib; 2 | using UnityEngine; 3 | using static Multifunction_mod.Multifunction; 4 | 5 | namespace Multifunction_mod.Patchs 6 | { 7 | public class PasteAnywayPatch 8 | { 9 | public static bool IsPatched { get; internal set; } 10 | 11 | [HarmonyPrefix] 12 | [HarmonyPatch(typeof(BuildTool_Inserter), "CheckBuildConditions")] 13 | public static bool BuildTool_InserterCheckBuildConditionsPatch(ref bool __result) 14 | { 15 | if (PasteBuildAnyWay) 16 | { 17 | __result = true; 18 | return false; 19 | } 20 | return true; 21 | } 22 | 23 | [HarmonyPrefix] 24 | [HarmonyPatch(typeof(BuildTool_Addon), "CheckBuildConditions")] 25 | public static bool BuildTool_AddonCheckBuildConditionsPatch(ref bool __result) 26 | { 27 | if (PasteBuildAnyWay) 28 | { 29 | __result = true; 30 | return false; 31 | } 32 | return true; 33 | } 34 | 35 | [HarmonyPrefix] 36 | [HarmonyPatch(typeof(BuildTool_Path), "CheckBuildConditions")] 37 | public static bool BuildTool_PathCheckBuildConditionsPatch(ref bool __result, BuildTool_Path __instance) 38 | { 39 | if (PasteBuildAnyWay) 40 | { 41 | int count = __instance.buildPreviews.Count; 42 | float num39 = __instance.altitude; 43 | float num40 = __instance.altitude; 44 | float num41 = __instance.tilt; 45 | float num42 = __instance.tilt; 46 | 47 | if (count > 0) 48 | { 49 | num39 = (__instance.buildPreviews[0].lpos.magnitude - __instance.planet.realRadius - 0.2f) / 1.3333333f; 50 | num40 = (__instance.buildPreviews[count - 1].lpos.magnitude - __instance.planet.realRadius - 0.2f) / 1.3333333f; 51 | num39 = Mathf.Round(num39 * 100f) / 100f; 52 | num40 = Mathf.Round(num40 * 100f) / 100f; 53 | if ((double)num39 < 0.041) 54 | { 55 | num39 = 0f; 56 | } 57 | if ((double)num40 < 0.041) 58 | { 59 | num40 = 0f; 60 | } 61 | num41 = __instance.buildPreviews[0].tilt; 62 | num42 = __instance.buildPreviews[count - 1].tilt; 63 | } 64 | if (num39 > 0f || num40 > 0f || num41 != 0f || num42 != 0f) 65 | { 66 | BuildModel model3 = __instance.actionBuild.model; 67 | model3.cursorText += ""; 68 | if (num39 > 0f || num40 > 0f) 69 | { 70 | string arg; 71 | if (num39 == num40) 72 | { 73 | arg = string.Format("{0:0.##}", num39); 74 | } 75 | else 76 | { 77 | arg = string.Format("{0:0.##}\u2006~\u2006{1:0.##}", num39, num40); 78 | } 79 | BuildModel model4 = __instance.actionBuild.model; 80 | model4.cursorText += string.Format("传送带高度提示".Translate(), arg); 81 | } 82 | if (num41 != 0f || num42 != 0f) 83 | { 84 | string arg2; 85 | if (num41 == num42) 86 | { 87 | arg2 = string.Format("{0:+0.#;-0.#;0}°", -num41); 88 | } 89 | else 90 | { 91 | arg2 = string.Format("{0:+0.#;-0.#;0}\u2006~\u2006{1:+0.#;-0.#;0}", -num41, -num42); 92 | } 93 | BuildModel model5 = __instance.actionBuild.model; 94 | model5.cursorText += string.Format("传送带倾斜提示".Translate(), arg2); 95 | } 96 | BuildModel model6 = __instance.actionBuild.model; 97 | model6.cursorText += ""; 98 | } 99 | __result = true; 100 | return false; 101 | } 102 | return true; 103 | } 104 | } 105 | } 106 | -------------------------------------------------------------------------------- /Multifunction_mod/Patchs/PlayerPatch.cs: -------------------------------------------------------------------------------- 1 | using HarmonyLib; 2 | using UnityEngine; 3 | using static Multifunction_mod.Multifunction; 4 | 5 | namespace Multifunction_mod.Patchs 6 | { 7 | public class PlayerPatch 8 | { 9 | //无翘曲器曲速 10 | [HarmonyPostfix] 11 | [HarmonyPatch(typeof(Mecha), "UseWarper")] 12 | public static void EnoughWarperPatch(ref bool __result) 13 | { 14 | if (noneedwarp.Value) 15 | { 16 | __result = true; 17 | } 18 | } 19 | 20 | [HarmonyPrefix] 21 | [HarmonyPatch(typeof(Mecha), "UseEnergy")] 22 | public static bool InfiniteplayerpowerPatch(Mecha __instance, ref float __result) 23 | { 24 | if (Infiniteplayerpower.Value) 25 | { 26 | __result = 1; 27 | __instance.coreEnergy = __instance.coreEnergyCap; 28 | return false; 29 | } 30 | return true; 31 | } 32 | 33 | [HarmonyPrefix] 34 | [HarmonyPatch(typeof(MechaForge), "GameTick")] 35 | public static void Prefix(ref MechaForge __instance) 36 | { 37 | if (QuickHandcraft.Value && __instance.tasks.Count > 0) 38 | { 39 | __instance.tasks[0].tick = __instance.tasks[0].tickSpend; 40 | } 41 | } 42 | 43 | [HarmonyPostfix] 44 | [HarmonyPatch(typeof(PlayerAction_Mine), "GameTick")] 45 | public static void PlayerAction_MineGameTickPatch(ref PlayerAction_Mine __instance) 46 | { 47 | if (QuickPlayerMine.Value && __instance.miningId > 0 && GameMain.localPlanet != null) 48 | { 49 | var factory = __instance.player.factory; 50 | if (__instance.miningType == EObjectType.Vegetable) 51 | { 52 | VegeData vegeData = factory.GetVegeData(__instance.miningId); 53 | VegeProto vegeProto = LDB.veges.Select(vegeData.protoId); 54 | if (vegeProto != null) 55 | { 56 | __instance.miningTick = LDB.veges.Select(factory.GetVegeData(__instance.miningId).protoId).MiningTime * 10000; 57 | } 58 | } 59 | else if (__instance.miningType == EObjectType.Vein) 60 | { 61 | VeinData veinData = factory.GetVeinData(__instance.miningId); 62 | VeinProto veinProto = LDB.veins.Select((int)veinData.type); 63 | if (veinProto != null) 64 | { 65 | __instance.miningTick = veinProto.MiningTime * 10000; 66 | } 67 | } 68 | } 69 | } 70 | 71 | [HarmonyPostfix] 72 | [HarmonyPatch(typeof(PlayerAction_Inspect), "GetObjectSelectDistance")] 73 | public static void PlayerAction_InspectPatch(ref float __result) 74 | { 75 | if (InspectDisNoLimit.Value) 76 | { 77 | __result = 400; 78 | } 79 | } 80 | 81 | [HarmonyPostfix] 82 | [HarmonyPatch(typeof(BuildTool_Click), "_OnInit")] 83 | public static void DeterminePreviewsPatch(BuildTool_Click __instance) 84 | { 85 | __instance.dotsSnapped = new Vector3[Buildmaxlen.Value]; 86 | } 87 | 88 | [HarmonyPrefix] 89 | [HarmonyPatch(typeof(BuildTool_BlueprintPaste), "CheckBuildConditions")] 90 | public static bool Prefix(BuildTool_BlueprintPaste __instance, ref bool __result) 91 | { 92 | if (pasteanyway && __instance.bpPool != null) 93 | { 94 | for (int i = 0; i < __instance.bpPool.Length; i++) 95 | { 96 | var prefab = __instance.bpPool[i]?.item?.prefabDesc; 97 | if (prefab != null && prefab.veinMiner) 98 | { 99 | return true; 100 | } 101 | } 102 | __result = true; 103 | return false; 104 | } 105 | return true; 106 | } 107 | 108 | [HarmonyPrefix] 109 | [HarmonyPatch(typeof(Player), "TryAddItemToPackage")] 110 | public static bool PlayerTryAddItemToPackage(int itemId) 111 | { 112 | if (!dismantle_but_nobuild.Value || itemId == 1099) 113 | { 114 | return true; 115 | } 116 | return false; 117 | } 118 | 119 | [HarmonyPrefix] 120 | [HarmonyPatch(typeof(Player), "SendItemToPlayer")] 121 | public static bool PlayerSendItemToPlayer(ref int itemId, ref int itemCount, ref int itemInc, bool toPackage, ItemBundle sentList) 122 | { 123 | if (!dismantle_but_nobuild.Value || itemId == 1099) 124 | { 125 | return true; 126 | } 127 | 128 | if (itemId > 0 && itemCount > 0 && toPackage) 129 | { 130 | sentList?.Alter(itemId, itemCount); 131 | itemId = 0; 132 | itemCount = 0; 133 | itemInc = 0; 134 | return false; 135 | } 136 | return true; 137 | } 138 | } 139 | } 140 | -------------------------------------------------------------------------------- /Multifunction_mod/Multifunction_mod.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {D898890A-6AFD-4680-84D6-0B5EBF5656C9} 8 | Library 9 | Properties 10 | Multifunction_mod 11 | Multifunction_mod 12 | v4.7.2 13 | 10.0 14 | 512 15 | true 16 | 17 | 18 | true 19 | full 20 | false 21 | bin\Debug\ 22 | DEBUG;TRACE 23 | prompt 24 | 4 25 | 26 | 27 | pdbonly 28 | true 29 | bin\Release\ 30 | TRACE 31 | prompt 32 | 4 33 | 34 | 35 | 36 | E:\Game\SteamLibrary\steamapps\common\Dyson Sphere Program\BepInEx\core\0Harmony.dll 37 | 38 | 39 | E:\Game\SteamLibrary\steamapps\common\Dyson Sphere Program\DSPGAME_Data\Managed\Assembly-CSharp.dll 40 | 41 | 42 | E:\Game\SteamLibrary\steamapps\common\Dyson Sphere Program\BepInEx\core\BepInEx.dll 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | E:\Game\SteamLibrary\steamapps\common\Dyson Sphere Program\DSPGAME_Data\Managed\UnityEngine.dll 55 | 56 | 57 | E:\Game\SteamLibrary\steamapps\common\Dyson Sphere Program\DSPGAME_Data\Managed\UnityEngine.AssetBundleModule.dll 58 | 59 | 60 | E:\Game\SteamLibrary\steamapps\common\Dyson Sphere Program\DSPGAME_Data\Managed\UnityEngine.CoreModule.dll 61 | 62 | 63 | E:\Game\SteamLibrary\steamapps\common\Dyson Sphere Program\DSPGAME_Data\Managed\UnityEngine.ImageConversionModule.dll 64 | 65 | 66 | E:\Game\SteamLibrary\steamapps\common\Dyson Sphere Program\DSPGAME_Data\Managed\UnityEngine.IMGUIModule.dll 67 | 68 | 69 | E:\Game\SteamLibrary\steamapps\common\Dyson Sphere Program\DSPGAME_Data\Managed\UnityEngine.InputLegacyModule.dll 70 | 71 | 72 | E:\Game\SteamLibrary\steamapps\common\Dyson Sphere Program\DSPGAME_Data\Managed\UnityEngine.InputModule.dll 73 | 74 | 75 | E:\Game\SteamLibrary\steamapps\common\Dyson Sphere Program\DSPGAME_Data\Managed\UnityEngine.PhysicsModule.dll 76 | 77 | 78 | E:\Game\SteamLibrary\steamapps\common\Dyson Sphere Program\DSPGAME_Data\Managed\UnityEngine.TextCoreModule.dll 79 | 80 | 81 | E:\Game\SteamLibrary\steamapps\common\Dyson Sphere Program\DSPGAME_Data\Managed\UnityEngine.TextRenderingModule.dll 82 | 83 | 84 | E:\Game\SteamLibrary\steamapps\common\Dyson Sphere Program\DSPGAME_Data\Managed\UnityEngine.UI.dll 85 | 86 | 87 | E:\Game\SteamLibrary\steamapps\common\Dyson Sphere Program\DSPGAME_Data\Managed\UnityEngine.UIModule.dll 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | taskkill /f /im DSPGAME.exe 130 | mkdir "E:\Game\SteamLibrary\steamapps\common\Dyson Sphere Program\BepInEx\plugins\$(ProjectName)" 131 | del /q "E:\Game\SteamLibrary\steamapps\common\Dyson Sphere Program\BepInEx\plugins\$(ProjectName)\$(TargetFileName)" 132 | copy "$(TargetPath)" "E:\Game\SteamLibrary\steamapps\common\Dyson Sphere Program\BepInEx\plugins\$(ProjectName)\$(TargetFileName)" 133 | start steam://rungameid/1366540 134 | 135 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | ## 4 | ## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore 5 | 6 | # User-specific files 7 | *.rsuser 8 | *.suo 9 | *.user 10 | *.userosscache 11 | *.sln.docstates 12 | 13 | # User-specific files (MonoDevelop/Xamarin Studio) 14 | *.userprefs 15 | 16 | # Mono auto generated files 17 | mono_crash.* 18 | 19 | # Build results 20 | [Dd]ebug/ 21 | [Dd]ebugPublic/ 22 | [Rr]elease/ 23 | [Rr]eleases/ 24 | x64/ 25 | x86/ 26 | [Ww][Ii][Nn]32/ 27 | [Aa][Rr][Mm]/ 28 | [Aa][Rr][Mm]64/ 29 | bld/ 30 | [Bb]in/ 31 | [Oo]bj/ 32 | [Oo]ut/ 33 | [Ll]og/ 34 | [Ll]ogs/ 35 | 36 | # Visual Studio 2015/2017 cache/options directory 37 | .vs/ 38 | # Uncomment if you have tasks that create the project's static files in wwwroot 39 | #wwwroot/ 40 | 41 | # Visual Studio 2017 auto generated files 42 | Generated\ Files/ 43 | 44 | # MSTest test Results 45 | [Tt]est[Rr]esult*/ 46 | [Bb]uild[Ll]og.* 47 | 48 | # NUnit 49 | *.VisualState.xml 50 | TestResult.xml 51 | nunit-*.xml 52 | 53 | # Build Results of an ATL Project 54 | [Dd]ebugPS/ 55 | [Rr]eleasePS/ 56 | dlldata.c 57 | 58 | # Benchmark Results 59 | BenchmarkDotNet.Artifacts/ 60 | 61 | # .NET Core 62 | project.lock.json 63 | project.fragment.lock.json 64 | artifacts/ 65 | 66 | # ASP.NET Scaffolding 67 | ScaffoldingReadMe.txt 68 | 69 | # StyleCop 70 | StyleCopReport.xml 71 | 72 | # Files built by Visual Studio 73 | *_i.c 74 | *_p.c 75 | *_h.h 76 | *.ilk 77 | *.meta 78 | *.obj 79 | *.iobj 80 | *.pch 81 | *.pdb 82 | *.ipdb 83 | *.pgc 84 | *.pgd 85 | *.rsp 86 | *.sbr 87 | *.tlb 88 | *.tli 89 | *.tlh 90 | *.tmp 91 | *.tmp_proj 92 | *_wpftmp.csproj 93 | *.log 94 | *.vspscc 95 | *.vssscc 96 | .builds 97 | *.pidb 98 | *.svclog 99 | *.scc 100 | 101 | # Chutzpah Test files 102 | _Chutzpah* 103 | 104 | # Visual C++ cache files 105 | ipch/ 106 | *.aps 107 | *.ncb 108 | *.opendb 109 | *.opensdf 110 | *.sdf 111 | *.cachefile 112 | *.VC.db 113 | *.VC.VC.opendb 114 | 115 | # Visual Studio profiler 116 | *.psess 117 | *.vsp 118 | *.vspx 119 | *.sap 120 | 121 | # Visual Studio Trace Files 122 | *.e2e 123 | 124 | # TFS 2012 Local Workspace 125 | $tf/ 126 | 127 | # Guidance Automation Toolkit 128 | *.gpState 129 | 130 | # ReSharper is a .NET coding add-in 131 | _ReSharper*/ 132 | *.[Rr]e[Ss]harper 133 | *.DotSettings.user 134 | 135 | # TeamCity is a build add-in 136 | _TeamCity* 137 | 138 | # DotCover is a Code Coverage Tool 139 | *.dotCover 140 | 141 | # AxoCover is a Code Coverage Tool 142 | .axoCover/* 143 | !.axoCover/settings.json 144 | 145 | # Coverlet is a free, cross platform Code Coverage Tool 146 | coverage*.json 147 | coverage*.xml 148 | coverage*.info 149 | 150 | # Visual Studio code coverage results 151 | *.coverage 152 | *.coveragexml 153 | 154 | # NCrunch 155 | _NCrunch_* 156 | .*crunch*.local.xml 157 | nCrunchTemp_* 158 | 159 | # MightyMoose 160 | *.mm.* 161 | AutoTest.Net/ 162 | 163 | # Web workbench (sass) 164 | .sass-cache/ 165 | 166 | # Installshield output folder 167 | [Ee]xpress/ 168 | 169 | # DocProject is a documentation generator add-in 170 | DocProject/buildhelp/ 171 | DocProject/Help/*.HxT 172 | DocProject/Help/*.HxC 173 | DocProject/Help/*.hhc 174 | DocProject/Help/*.hhk 175 | DocProject/Help/*.hhp 176 | DocProject/Help/Html2 177 | DocProject/Help/html 178 | 179 | # Click-Once directory 180 | publish/ 181 | 182 | # Publish Web Output 183 | *.[Pp]ublish.xml 184 | *.azurePubxml 185 | # Note: Comment the next line if you want to checkin your web deploy settings, 186 | # but database connection strings (with potential passwords) will be unencrypted 187 | *.pubxml 188 | *.publishproj 189 | 190 | # Microsoft Azure Web App publish settings. Comment the next line if you want to 191 | # checkin your Azure Web App publish settings, but sensitive information contained 192 | # in these scripts will be unencrypted 193 | PublishScripts/ 194 | 195 | # NuGet Packages 196 | *.nupkg 197 | # NuGet Symbol Packages 198 | *.snupkg 199 | # The packages folder can be ignored because of Package Restore 200 | **/[Pp]ackages/* 201 | # except build/, which is used as an MSBuild target. 202 | !**/[Pp]ackages/build/ 203 | # Uncomment if necessary however generally it will be regenerated when needed 204 | #!**/[Pp]ackages/repositories.config 205 | # NuGet v3's project.json files produces more ignorable files 206 | *.nuget.props 207 | *.nuget.targets 208 | 209 | # Microsoft Azure Build Output 210 | csx/ 211 | *.build.csdef 212 | 213 | # Microsoft Azure Emulator 214 | ecf/ 215 | rcf/ 216 | 217 | # Windows Store app package directories and files 218 | AppPackages/ 219 | BundleArtifacts/ 220 | Package.StoreAssociation.xml 221 | _pkginfo.txt 222 | *.appx 223 | *.appxbundle 224 | *.appxupload 225 | 226 | # Visual Studio cache files 227 | # files ending in .cache can be ignored 228 | *.[Cc]ache 229 | # but keep track of directories ending in .cache 230 | !?*.[Cc]ache/ 231 | 232 | # Others 233 | ClientBin/ 234 | ~$* 235 | *~ 236 | *.dbmdl 237 | *.dbproj.schemaview 238 | *.jfm 239 | *.pfx 240 | *.publishsettings 241 | orleans.codegen.cs 242 | 243 | # Including strong name files can present a security risk 244 | # (https://github.com/github/gitignore/pull/2483#issue-259490424) 245 | #*.snk 246 | 247 | # Since there are multiple workflows, uncomment next line to ignore bower_components 248 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) 249 | #bower_components/ 250 | 251 | # RIA/Silverlight projects 252 | Generated_Code/ 253 | 254 | # Backup & report files from converting an old project file 255 | # to a newer Visual Studio version. Backup files are not needed, 256 | # because we have git ;-) 257 | _UpgradeReport_Files/ 258 | Backup*/ 259 | UpgradeLog*.XML 260 | UpgradeLog*.htm 261 | ServiceFabricBackup/ 262 | *.rptproj.bak 263 | 264 | # SQL Server files 265 | *.mdf 266 | *.ldf 267 | *.ndf 268 | 269 | # Business Intelligence projects 270 | *.rdl.data 271 | *.bim.layout 272 | *.bim_*.settings 273 | *.rptproj.rsuser 274 | *- [Bb]ackup.rdl 275 | *- [Bb]ackup ([0-9]).rdl 276 | *- [Bb]ackup ([0-9][0-9]).rdl 277 | 278 | # Microsoft Fakes 279 | FakesAssemblies/ 280 | 281 | # GhostDoc plugin setting file 282 | *.GhostDoc.xml 283 | 284 | # Node.js Tools for Visual Studio 285 | .ntvs_analysis.dat 286 | node_modules/ 287 | 288 | # Visual Studio 6 build log 289 | *.plg 290 | 291 | # Visual Studio 6 workspace options file 292 | *.opt 293 | 294 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.) 295 | *.vbw 296 | 297 | # Visual Studio LightSwitch build output 298 | **/*.HTMLClient/GeneratedArtifacts 299 | **/*.DesktopClient/GeneratedArtifacts 300 | **/*.DesktopClient/ModelManifest.xml 301 | **/*.Server/GeneratedArtifacts 302 | **/*.Server/ModelManifest.xml 303 | _Pvt_Extensions 304 | 305 | # Paket dependency manager 306 | .paket/paket.exe 307 | paket-files/ 308 | 309 | # FAKE - F# Make 310 | .fake/ 311 | 312 | # CodeRush personal settings 313 | .cr/personal 314 | 315 | # Python Tools for Visual Studio (PTVS) 316 | __pycache__/ 317 | *.pyc 318 | 319 | # Cake - Uncomment if you are using it 320 | # tools/** 321 | # !tools/packages.config 322 | 323 | # Tabs Studio 324 | *.tss 325 | 326 | # Telerik's JustMock configuration file 327 | *.jmconfig 328 | 329 | # BizTalk build output 330 | *.btp.cs 331 | *.btm.cs 332 | *.odx.cs 333 | *.xsd.cs 334 | 335 | # OpenCover UI analysis results 336 | OpenCover/ 337 | 338 | # Azure Stream Analytics local run output 339 | ASALocalRun/ 340 | 341 | # MSBuild Binary and Structured Log 342 | *.binlog 343 | 344 | # NVidia Nsight GPU debugger configuration file 345 | *.nvuser 346 | 347 | # MFractors (Xamarin productivity tool) working folder 348 | .mfractor/ 349 | 350 | # Local History for Visual Studio 351 | .localhistory/ 352 | 353 | # BeatPulse healthcheck temp database 354 | healthchecksdb 355 | 356 | # Backup folder for Package Reference Convert tool in Visual Studio 2017 357 | MigrationBackup/ 358 | 359 | # Ionide (cross platform F# VS Code tools) working folder 360 | .ionide/ 361 | 362 | # Fody - auto-generated XML schema 363 | FodyWeavers.xsd -------------------------------------------------------------------------------- /Multifunction_mod/Patchs/CombatPatch.cs: -------------------------------------------------------------------------------- 1 | using HarmonyLib; 2 | using System; 3 | using static Multifunction_mod.Multifunction; 4 | 5 | namespace Multifunction_mod.Patchs 6 | { 7 | public class CombatPatch 8 | { 9 | [HarmonyPrefix] 10 | [HarmonyPatch(typeof(Mecha), "TakeDamage")] 11 | public static bool MechaTakeDamage(Mecha __instance) 12 | { 13 | if (LockPlayerHp.Value) 14 | { 15 | return false; 16 | } 17 | 18 | return true; 19 | } 20 | 21 | [HarmonyPrefix] 22 | [HarmonyPatch(typeof(Mecha), "UpdateCombatStats")] 23 | public static void MechaTakeUpdateCombatStats(Mecha __instance) 24 | { 25 | if (LockPlayerHp.Value) 26 | { 27 | __instance.energyShieldEnergy = __instance.energyShieldCapacity; 28 | } 29 | } 30 | 31 | [HarmonyPrefix] 32 | [HarmonyPatch(typeof(ConstructionSystem), "GameTick")] 33 | public static void PlanetFactoryGameTick(ConstructionSystem __instance) 34 | { 35 | if (LockBuildHp.Value || LockEnemyHp.Value) 36 | { 37 | CombatStat[] buffer = __instance.factory.skillSystem.combatStats.buffer; 38 | foreach (CombatStat combatStat in buffer) 39 | { 40 | if (LockBuildHp.Value && combatStat.objectType == 0) 41 | { 42 | buffer[combatStat.id].hp = combatStat.hpMax; 43 | } 44 | if (LockEnemyHp.Value && combatStat.objectType == 4) 45 | { 46 | buffer[combatStat.id].hp = combatStat.hpMax; 47 | } 48 | } 49 | } 50 | } 51 | 52 | [HarmonyPrefix] 53 | [HarmonyPatch(typeof(Mecha), "TickLaserFireCondition")] 54 | public static void MechaTickLaserFireCondition(Mecha __instance) 55 | { 56 | if (PlayerQuickAttack.Value) 57 | { 58 | __instance.laserFire = 0; 59 | __instance.laserEnergy = __instance.laserEnergyCapacity; 60 | } 61 | } 62 | 63 | [HarmonyPrefix] 64 | [HarmonyPatch(typeof(Mecha), "TestLaserTurretEnergy")] 65 | public static bool MechaTestLaserTurretEnergy(ref bool __result) 66 | { 67 | if (PlayerQuickAttack.Value) 68 | { 69 | __result = true; 70 | return false; 71 | } 72 | return true; 73 | } 74 | 75 | [HarmonyPrefix] 76 | [HarmonyPatch(typeof(SkillSystem), "GameTick")] 77 | public static void SkillSystemGameTick(SkillSystem __instance) 78 | { 79 | if (killEnemys.Count > 0) 80 | { 81 | var enemydata = killEnemys.Dequeue(); 82 | 83 | if (enemydata.id > 0) 84 | { 85 | if (enemydata.combatStatId > 0 && __instance.combatStats.buffer[enemydata.combatStatId].id == enemydata.combatStatId) 86 | { 87 | __instance.combatStats.buffer[enemydata.combatStatId].hp = 0; 88 | } 89 | else if (enemydata.originAstroId > 1000000) 90 | { 91 | ref EnemyData reference = ref __instance.sector.enemyPool[enemydata.id]; 92 | __instance.sector.KillEnemyFinal(reference.id, ref CombatStat.empty); 93 | } 94 | else if (enemydata.originAstroId > 100 && enemydata.originAstroId <= 204899 && enemydata.originAstroId % 100 > 0) 95 | { 96 | PlanetFactory planetFactory = __instance.astroFactories[enemydata.originAstroId]; 97 | ref EnemyData reference = ref planetFactory.enemyPool[enemydata.id]; 98 | planetFactory.KillEnemyFinally(reference.id, ref CombatStat.empty); 99 | } 100 | } 101 | } 102 | } 103 | 104 | [HarmonyPrefix] 105 | [HarmonyPatch(typeof(EnemyDFHiveSystem), "GameTickLogic")] 106 | public static void EnemyDFHiveSystemPreGameTickLogic(EnemyDFHiveSystem __instance) 107 | { 108 | if (SpaceAlwaysClearThreat.Value) 109 | { 110 | __instance.evolve.threat = 0; 111 | __instance.evolve.threatshr = 0; 112 | } 113 | if (SpaceAlwaysMaxThreat.Value && __instance.evolve.threat < __instance.evolve.maxThreat && __instance.evolve.waveTicks == 0) 114 | { 115 | if (GameMain.localStar != null && __instance.starData.index == GameMain.localStar.index) 116 | { 117 | __instance.evolve.threat = __instance.evolve.maxThreat * 2 + 1; 118 | __instance.evolve.threatshr = __instance.evolve.maxThreat * 2 + 1; 119 | } 120 | } 121 | } 122 | 123 | [HarmonyPostfix] 124 | [HarmonyPatch(typeof(EnemyDFHiveSystem), "GameTickLogic")] 125 | public static void EnemyDFHiveSystemGameTickLogic(EnemyDFHiveSystem __instance) 126 | { 127 | if (SpaceAlwaysClearThreat.Value) 128 | { 129 | __instance.evolve.threat = 0; 130 | __instance.evolve.threatshr = 0; 131 | } 132 | if (SpaceAlwaysMaxThreat.Value && __instance.evolve.threat < __instance.evolve.maxThreat && __instance.evolve.waveTicks == 0) 133 | { 134 | if (GameMain.localStar != null && __instance.starData.index == GameMain.localStar.index) 135 | { 136 | __instance.evolve.threat = __instance.evolve.maxThreat * 2 + 1; 137 | __instance.evolve.threatshr = __instance.evolve.maxThreat * 2 + 1; 138 | } 139 | } 140 | 141 | if (PlayerFakeDeath.Value && __instance.isLocal) 142 | { 143 | __instance.local_player_exist_alive = false; 144 | __instance.local_player_in_range = false; 145 | } 146 | } 147 | 148 | [HarmonyPrefix] 149 | [HarmonyPatch(typeof(DFGBaseComponent), "UpdateFactoryThreat")] 150 | public static void DFGBaseComponentPreLogicTick(DFGBaseComponent __instance, ref float power_threat_factor, ref float player_threat) 151 | { 152 | if (LocalAlwaysClearThreat.Value) 153 | { 154 | power_threat_factor = 0; 155 | player_threat = 0; 156 | __instance.evolve.threat = 0; 157 | __instance.evolve.threatshr = 0; 158 | } 159 | if (LocalAlwaysMaxThreat.Value && __instance.evolve.threat < __instance.evolve.maxThreat && __instance.evolve.waveTicks == 0) 160 | { 161 | if (GameMain.localPlanet != null && __instance.groundSystem.factory.planet.index == GameMain.localPlanet.index) 162 | { 163 | __instance.evolve.threat = __instance.evolve.maxThreat * 2 + 1; 164 | __instance.evolve.threatshr = __instance.evolve.maxThreat * 2 + 1; 165 | } 166 | } 167 | } 168 | 169 | [HarmonyPostfix] 170 | [HarmonyPatch(typeof(DFGBaseComponent), "UpdateFactoryThreat")] 171 | public static void DFGBaseComponentLogicTick(DFGBaseComponent __instance, ref float power_threat_factor, ref float player_threat) 172 | { 173 | if (LocalAlwaysClearThreat.Value) 174 | { 175 | power_threat_factor = 0; 176 | player_threat = 0; 177 | __instance.evolve.threat = 0; 178 | __instance.evolve.threatshr = 0; 179 | } 180 | if (LocalAlwaysMaxThreat.Value && __instance.evolve.threat < __instance.evolve.maxThreat && __instance.evolve.waveTicks == 0) 181 | { 182 | if (GameMain.localPlanet != null && __instance.groundSystem.factory.planet.index == GameMain.localPlanet.index) 183 | { 184 | __instance.evolve.threat = __instance.evolve.maxThreat * 2 + 1; 185 | __instance.evolve.threatshr = __instance.evolve.maxThreat * 2 + 1; 186 | } 187 | } 188 | } 189 | 190 | [HarmonyPostfix] 191 | [HarmonyPatch(typeof(EnemyBuilderComponent), "LogicTick")] 192 | public static void EnemyBuilderComponentBuildLogic_Ground(EnemyBuilderComponent __instance) 193 | { 194 | if (DarkFogBuilderQuickBuild.Value) 195 | { 196 | __instance.energy = __instance.maxEnergy; 197 | __instance.matter = __instance.maxMatter; 198 | __instance.sp = __instance.spMax; 199 | __instance.buildCDTime = 0; 200 | } 201 | } 202 | 203 | [HarmonyPrefix] 204 | [HarmonyPatch(typeof(TurretComponent), "InternalUpdate")] 205 | public static void TurretComponentInternalUpdate(ref TurretComponent __instance) 206 | { 207 | if (TurrentKeepSuperNoval.Value) 208 | { 209 | __instance.supernovaTick = 901; 210 | __instance.supernovaStrength = 30f; 211 | } 212 | } 213 | 214 | [HarmonyPrefix] 215 | [HarmonyPatch(typeof(HatredList), "HateTarget", new Type[] { typeof(ETargetType), typeof(int), typeof(int), typeof(int), typeof(EHatredOperation), })] 216 | public static bool HatredListHateTarget(ETargetType type) 217 | { 218 | if (PlayerFakeDeath.Value && type == ETargetType.Player) 219 | { 220 | return false; 221 | } 222 | return true; 223 | } 224 | [HarmonyPostfix] 225 | [HarmonyPatch(typeof(EnemyDFGroundSystem), "GameTickLogic_Prepare")] 226 | public static void EnemyDFGroundSystemGameTickLogic(EnemyDFGroundSystem __instance) 227 | { 228 | if (PlayerFakeDeath.Value && __instance.isLocalLoaded) 229 | { 230 | __instance.local_player_exist_alive = false; 231 | } 232 | } 233 | 234 | } 235 | } 236 | -------------------------------------------------------------------------------- /Multifunction_mod/Patchs/UIPatch.cs: -------------------------------------------------------------------------------- 1 | using HarmonyLib; 2 | using static Multifunction_mod.Multifunction; 3 | 4 | namespace Multifunction_mod.Patchs 5 | { 6 | public class UIPatch 7 | { 8 | public static bool tempisInstantItem; 9 | //关闭窗口快捷键 10 | [HarmonyPrefix] 11 | [HarmonyPatch(typeof(UIGame), "On_E_Switch")] 12 | public static bool CloseWindowPatch() 13 | { 14 | if (guidraw.DisplayingWindow) 15 | { 16 | guidraw.CloseMainWindow(); 17 | return false; 18 | } 19 | return true; 20 | } 21 | 22 | [HarmonyPostfix] 23 | [HarmonyPatch(typeof(UIReplicatorWindow), "SetSelectedRecipeIndex")] 24 | public static void UIReplicatorWindowSetSelectedRecipe(ref UIReplicatorWindow __instance) 25 | { 26 | if (!isInstantItem.Value || !tempisInstantItem || !(Traverse.Create(__instance).Field("selectedRecipe").GetValue() is RecipeProto recipe)) 27 | { 28 | return; 29 | } 30 | Player mainPlayer = GameMain.mainPlayer; 31 | RecipeProto recipeProto = recipe; 32 | if (recipe == null) return; 33 | int num = 1; 34 | if (__instance.multipliers.ContainsKey(recipe.ID)) 35 | { 36 | num = __instance.multipliers[recipe.ID]; 37 | } 38 | if (num < 1) 39 | { 40 | num = 1; 41 | } 42 | else if (num > 10) 43 | { 44 | num = 10; 45 | } 46 | for (int i = 0; i < recipeProto.Results.Length; i++) 47 | { 48 | int num2 = recipeProto.Results[i]; 49 | int stackSize = LDB.items.Select(num2).StackSize; 50 | int num3 = __instance.isBatch ? (num * stackSize) : num; 51 | int num4 = mainPlayer.TryAddItemToPackage(num2, num3, 0, true, 0); 52 | int num5 = num3 - num4; 53 | if (num5 > 0) 54 | { 55 | ItemProto itemProto = LDB.items.Select(num2); 56 | if (itemProto != null) 57 | { 58 | UIRealtimeTip.Popup(string.Format("背包已满未添加".Translate(), num5, itemProto.name), true, 0); 59 | } 60 | } 61 | if (num4 > 0) 62 | { 63 | UIItemup.Up(num2, num4); 64 | } 65 | mainPlayer.mecha.AddProductionStat(num2, num3, mainPlayer.nearestFactory); 66 | } 67 | } 68 | 69 | [HarmonyPostfix] 70 | [HarmonyPatch(typeof(UIReplicatorWindow), "_OnOpen")] 71 | public static void UIReplicatorWindow_OnOpen(ref UIReplicatorWindow __instance) 72 | { 73 | if (!isInstantItem.Value) 74 | { 75 | return; 76 | } 77 | __instance.isInstantItem = tempisInstantItem; 78 | __instance.instantItemSwitch.gameObject.SetActive(true); 79 | __instance.instantItemSwitch.SetToggleNoEvent(tempisInstantItem); 80 | if (tempisInstantItem) 81 | { 82 | Traverse.Create(__instance).Method("RefreshRecipeIcons").GetValue(); 83 | } 84 | __instance.instantItemSwitch.SetToggleNoEvent(tempisInstantItem); 85 | __instance.batchSwitch.gameObject.SetActive(tempisInstantItem); 86 | __instance.batchSwitch.SetToggleNoEvent(true); 87 | __instance.sandboxAddUsefulItemButton.gameObject.SetActive(tempisInstantItem); 88 | __instance.sandboxClearPackageButton.gameObject.SetActive(tempisInstantItem); 89 | } 90 | 91 | [HarmonyPostfix] 92 | [HarmonyPatch(typeof(UIReplicatorWindow), "OnInstantSwitchClick")] 93 | public static void UIReplicatorWindowOnInstantSwitchClick(ref UIReplicatorWindow __instance) 94 | { 95 | if (!isInstantItem.Value) 96 | { 97 | return; 98 | } 99 | tempisInstantItem = __instance.isInstantItem; 100 | __instance.sandboxAddUsefulItemButton.gameObject.SetActive(tempisInstantItem); 101 | __instance.sandboxClearPackageButton.gameObject.SetActive(tempisInstantItem); 102 | } 103 | 104 | [HarmonyPrefix] 105 | [HarmonyPatch(typeof(UIReplicatorWindow), "OnOkButtonClick")] 106 | public static bool UIReplicatorWindowOnOkButtonClick(ref UIReplicatorWindow __instance) 107 | { 108 | if (!isInstantItem.Value || !tempisInstantItem) 109 | { 110 | return true; 111 | } 112 | var selectedRecipe = Traverse.Create(__instance).Field("selectedRecipe").GetValue() as RecipeProto; 113 | if (selectedRecipe == null) 114 | { 115 | return false; 116 | } 117 | int id = selectedRecipe.ID; 118 | int num = 1; 119 | if (__instance.multipliers.ContainsKey(id)) 120 | { 121 | num = __instance.multipliers[id]; 122 | } 123 | if (num < 1) 124 | { 125 | num = 1; 126 | } 127 | else if (num > 10) 128 | { 129 | num = 10; 130 | } 131 | Player mainPlayer = GameMain.mainPlayer; 132 | RecipeProto recipeProto = LDB.recipes.Select(id); 133 | for (int i = 0; i < recipeProto.Results.Length; i++) 134 | { 135 | int num2 = recipeProto.Results[i]; 136 | int stackSize = LDB.items.Select(num2).StackSize; 137 | int num3 = __instance.isBatch ? (num * stackSize) : num; 138 | int num4 = mainPlayer.TryAddItemToPackage(num2, num3, 0, true, 0); 139 | int num5 = num3 - num4; 140 | if (num5 > 0) 141 | { 142 | ItemProto itemProto = LDB.items.Select(num2); 143 | if (itemProto != null) 144 | { 145 | UIRealtimeTip.Popup(string.Format("背包已满未添加".Translate(), num5, itemProto.name), true, 0); 146 | } 147 | } 148 | if (num4 > 0) 149 | { 150 | UIItemup.Up(num2, num4); 151 | } 152 | mainPlayer.mecha.AddProductionStat(num2, num3, mainPlayer.nearestFactory); 153 | } 154 | return false; 155 | } 156 | 157 | [HarmonyPrefix] 158 | [HarmonyPatch(typeof(UITechTree), "_OnUpdate")] 159 | public static void UITechTreeSelectTechPatch(UITechTree __instance) 160 | { 161 | if (!unlockpointtech || __instance.selected == null) 162 | { 163 | return; 164 | } 165 | TechProto techProto = __instance.selected.techProto; 166 | if (GameMain.history.techStates[techProto.ID].unlocked || techProto.MaxLevel > 10) return; 167 | if (techProto.Level < techProto.MaxLevel) 168 | { 169 | for (int level = 1; level < techProto.MaxLevel; ++level) 170 | { 171 | for (int i = 0; i < techProto.itemArray.Length; i++) 172 | { 173 | AddComsumeItemtoTotal(techProto.Items[i], (int)(techProto.ItemPoints[i] * techProto.GetHashNeeded(techProto.Level) / 3600)); 174 | } 175 | GameMain.history.UnlockTechFunction(techProto.UnlockFunctions[0], techProto.UnlockValues[0], level); 176 | } 177 | GameMain.history.UnlockTech(techProto.ID); 178 | } 179 | if (!GameMain.history.techStates[techProto.ID].unlocked) 180 | { 181 | for (int i = 0; i < techProto.itemArray.Length; i++) 182 | { 183 | AddComsumeItemtoTotal(techProto.Items[i], (int)(techProto.ItemPoints[i] * techProto.GetHashNeeded(techProto.Level) / 3600)); 184 | } 185 | GameMain.history.UnlockTech(techProto.ID); 186 | } 187 | } 188 | 189 | [HarmonyPrefix] 190 | [HarmonyPatch(typeof(UITechTree), "UpdateScale")] 191 | public static bool UITechTreeUpdateScalePatch(UITechTree __instance) 192 | { 193 | if (unlockpointtech && (__instance.selected != null || __instance.centerViewNode != null)) return false; 194 | return true; 195 | } 196 | 197 | [HarmonyPostfix] 198 | [HarmonyPatch(typeof(UIStationStorage), "GetAdditionStorage")] 199 | public static void UIStationWindow_OnOpen(UIStationStorage __instance, ref int __result) 200 | { 201 | if (StationStoExtra.Value == 0 || __instance.station.isCollector) 202 | return; 203 | int basemax = __instance.station.isStellar ? 10000 : 5000; 204 | __result += StationStoExtra.Value * basemax; 205 | } 206 | 207 | [HarmonyPostfix] 208 | [HarmonyPatch(typeof(UIAbnormalityTip), "_OnOpen")] 209 | public static void UIAbnormalityTipDeterminePatch(UIAbnormalityTip __instance) 210 | { 211 | if (CloseUIAbnormalityTip.Value) 212 | { 213 | __instance._Close(); 214 | } 215 | } 216 | 217 | [HarmonyPostfix] 218 | [HarmonyPatch(typeof(UIStarmap), "UpdateCursorView")] 219 | public static void UIStarmapUpdateCursorView(UIStarmap __instance) 220 | { 221 | if (EnableTp.Value) 222 | { 223 | if (__instance.focusPlanet != null) 224 | { 225 | Player mainPlayer = GameMain.mainPlayer; 226 | __instance.fastTravelButton.gameObject.SetActive(mainPlayer.planetId != __instance.focusPlanet.planet.id && !mainPlayer.warping); 227 | } 228 | } 229 | } 230 | 231 | [HarmonyPostfix] 232 | [HarmonyPatch(typeof(UIStarmap), "OnFastTravelButtonClick")] 233 | public static void UIStarmapOnFastTravelButtonClick(UIStarmap __instance) 234 | { 235 | if (EnableTp.Value) 236 | { 237 | if (__instance.focusPlanet != null) 238 | { 239 | GameMain.mainPlayer.controller.actionSail.StartFastTravelToPlanet(__instance.focusPlanet.planet); 240 | } 241 | } 242 | } 243 | } 244 | } 245 | -------------------------------------------------------------------------------- /Multifunction_mod/Patchs/PlanetTransportPatch.cs: -------------------------------------------------------------------------------- 1 | using HarmonyLib; 2 | using System; 3 | using static Multifunction_mod.Multifunction; 4 | 5 | namespace Multifunction_mod.Patchs 6 | { 7 | public class PlanetTransportPatch 8 | { 9 | //自动改名 10 | [HarmonyPostfix] 11 | [HarmonyPatch(typeof(PlanetTransport), "NewStationComponent")] 12 | public static void PlanetTransportNewStationComponent(ref StationComponent __result, PlanetTransport __instance, int _entityId) 13 | { 14 | if (__result.isCollector) 15 | { 16 | CollectorStation.Add(__result.gid); 17 | return; 18 | } 19 | else if (__result.isVeinCollector) 20 | { 21 | return; 22 | } 23 | if (!string.IsNullOrEmpty(AutoChangeStationName.Value)) 24 | { 25 | __instance.factory.WriteExtraInfoOnEntity(_entityId, AutoChangeStationName.Value.getTranslate()); 26 | } 27 | if (Buildingnoconsume.Value) 28 | { 29 | GameMain.localPlanet.factory.powerSystem.consumerPool[__result.pcId].idleEnergyPerTick = 1000; 30 | } 31 | } 32 | 33 | 34 | 35 | [HarmonyPrefix] 36 | [HarmonyPatch(typeof(PlanetTransport), "RemoveStationComponent")] 37 | public static void PlanetTransportRemoveStationComponent(PlanetTransport __instance, int id) 38 | { 39 | if (__instance.stationPool[id] != null && __instance.stationPool[id].id != 0 && __instance.stationPool[id].isCollector) 40 | { 41 | int gid = __instance.stationPool[id].gid; 42 | if (CollectorStation.Contains(gid)) 43 | { 44 | CollectorStation.Remove(gid); 45 | } 46 | } 47 | } 48 | 49 | [HarmonyPrefix] 50 | [HarmonyPatch(typeof(PlanetTransport), "SetStationStorage")] 51 | public static bool UIStationWindow_SetStationStorage(PlanetTransport __instance, int stationId, int storageIdx, int itemId, int itemCountMax, ELogisticStorage localLogic, ELogisticStorage remoteLogic, Player player) 52 | { 53 | if (StationStoExtra.Value <= 0) 54 | { 55 | return true; 56 | } 57 | if (itemId != 0 && LDB.items.Select(itemId) == null) 58 | { 59 | itemId = 0; 60 | } 61 | StationComponent stationComponent = __instance.GetStationComponent(stationId); 62 | bool flag = false; 63 | bool flag2 = false; 64 | if (stationComponent != null) 65 | { 66 | if (!stationComponent.isStellar) 67 | { 68 | remoteLogic = ELogisticStorage.None; 69 | } 70 | if (itemId <= 0) 71 | { 72 | itemId = 0; 73 | itemCountMax = 0; 74 | localLogic = ELogisticStorage.None; 75 | remoteLogic = ELogisticStorage.None; 76 | } 77 | int modelIndex = __instance.factory.entityPool[stationComponent.entityId].modelIndex; 78 | ModelProto modelProto = LDB.models.Select(modelIndex); 79 | int num = 0; 80 | if (modelProto != null) 81 | { 82 | num = modelProto.prefabDesc.stationMaxItemCount; 83 | } 84 | 85 | int basemax = stationComponent.isStellar ? 10000 : 5000; 86 | int maxvalue = num + (StationStoExtra.Value + 1) * basemax; 87 | if (itemCountMax > maxvalue) 88 | { 89 | itemCountMax = maxvalue; 90 | } 91 | if (storageIdx >= 0 && storageIdx < stationComponent.storage.Length) 92 | { 93 | StationStore stationStore = stationComponent.storage[storageIdx]; 94 | if (stationStore.localLogic != localLogic) 95 | { 96 | flag = true; 97 | } 98 | if (stationStore.remoteLogic != remoteLogic) 99 | { 100 | flag2 = true; 101 | } 102 | if (stationStore.itemId == itemId) 103 | { 104 | stationComponent.storage[storageIdx].max = itemCountMax; 105 | stationComponent.storage[storageIdx].localLogic = localLogic; 106 | stationComponent.storage[storageIdx].remoteLogic = remoteLogic; 107 | } 108 | else 109 | { 110 | if (stationStore.localLogic != ELogisticStorage.None || localLogic != ELogisticStorage.None) 111 | { 112 | flag = true; 113 | } 114 | if (stationStore.remoteLogic != ELogisticStorage.None || remoteLogic != ELogisticStorage.None) 115 | { 116 | flag2 = true; 117 | } 118 | if (stationStore.count > 0 && stationStore.itemId > 0 && player != null) 119 | { 120 | int num3 = player.TryAddItemToPackage(stationStore.itemId, stationStore.count, stationStore.inc, true, 0); 121 | UIItemup.Up(stationStore.itemId, num3); 122 | if (num3 < stationStore.count) 123 | { 124 | UIRealtimeTip.Popup("无法收回仓储物品".Translate(), true, 0); 125 | } 126 | } 127 | stationComponent.storage[storageIdx].itemId = itemId; 128 | stationComponent.storage[storageIdx].count = 0; 129 | stationComponent.storage[storageIdx].inc = 0; 130 | stationComponent.storage[storageIdx].localOrder = 0; 131 | stationComponent.storage[storageIdx].remoteOrder = 0; 132 | stationComponent.storage[storageIdx].max = itemCountMax; 133 | stationComponent.storage[storageIdx].localLogic = localLogic; 134 | stationComponent.storage[storageIdx].remoteLogic = remoteLogic; 135 | } 136 | if (itemId == 0) 137 | { 138 | stationComponent.storage[storageIdx] = default(StationStore); 139 | for (int i = 0; i < stationComponent.slots.Length; i++) 140 | { 141 | if (stationComponent.slots[i].dir == IODir.Output && stationComponent.slots[i].storageIdx - 1 == storageIdx) 142 | { 143 | stationComponent.slots[i].counter = 0; 144 | stationComponent.slots[i].storageIdx = 0; 145 | stationComponent.slots[i].dir = IODir.Output; 146 | } 147 | } 148 | } 149 | } 150 | if (!stationComponent.isStellar) 151 | { 152 | flag2 = false; 153 | } 154 | } 155 | if (flag) 156 | { 157 | __instance.RefreshStationTraffic(stationId); 158 | } 159 | if (flag2) 160 | { 161 | __instance.gameData.galacticTransport.RefreshTraffic(stationComponent.gid); 162 | } 163 | return false; 164 | } 165 | 166 | [HarmonyPrefix] 167 | [HarmonyPatch(typeof(PlanetTransport), "GameTick")] 168 | public static void PlanetTransportGameTick(long time, PlanetTransport __instance) 169 | { 170 | int num = (int)(time % 20L); 171 | if (num < 0) 172 | { 173 | num += 20; 174 | } 175 | int num2 = (int)(time % 60L); 176 | if (num2 < 0) 177 | { 178 | num2 += 60; 179 | } 180 | bool localTick = num == 0; 181 | bool remoteTick = num2 == 0; 182 | FactoryProductionStat factoryProductionStat = GameMain.statistics.production.factoryStatPool[__instance.factory.index]; 183 | int[] productRegister = factoryProductionStat.productRegister; 184 | int[] consumeRegister = factoryProductionStat.consumeRegister; 185 | for (int i = __instance.stationPool.Length - 1; i > 0; i--) 186 | { 187 | StationComponent sc = __instance.stationPool[i]; 188 | if (sc == null || sc.id != i) 189 | { 190 | continue; 191 | } 192 | if (localTick) 193 | { 194 | if (Stationfullenergy.Value) 195 | { 196 | sc.energy = sc.energyMax; 197 | } 198 | if (StationMaxproliferator.Value) 199 | { 200 | for (int j = 0; j < sc.storage.Length; j++) 201 | if (sc.storage[j].itemId > 0) 202 | sc.storage[j].inc = sc.storage[j].count * incAbility; 203 | } 204 | if (StationfullCount) 205 | { 206 | StationComponentPatch.StationFullItemCount(sc); 207 | } 208 | } 209 | if (sc.isCollector || sc.isVeinCollector) continue; 210 | if (StationSpray.Value) 211 | { 212 | StationComponentPatch.StationSprayInc(sc, consumeRegister); 213 | } 214 | if (StationPowerGen.Value) 215 | { 216 | StationComponentPatch.StationPowerGeneration(sc, consumeRegister); 217 | } 218 | if (localTick) 219 | { 220 | if (Station_infiniteWarp_bool.Value && sc.isStellar) 221 | sc.warperCount = 50; 222 | } 223 | string stationComponentName = __instance.factory.ReadExtraInfoOnEntity(sc.entityId); 224 | if (!string.IsNullOrEmpty(stationComponentName)) 225 | { 226 | switch (stationComponentName) 227 | { 228 | case "星球无限供货机": 229 | if (!StationfullCount_bool.Value && remoteTick || StationfullCount) 230 | continue; 231 | StationComponentPatch.StationFullItemCount(sc); 232 | break; 233 | case "垃圾站": 234 | case "Station_trash": 235 | if (!StationTrash.Value && remoteTick) 236 | continue; 237 | StationComponentPatch.StationTrashMethod(sc, consumeRegister); 238 | break; 239 | case "喷涂加工厂": 240 | if (!StationSprayer.Value || StationSpray.Value) 241 | continue; 242 | StationComponentPatch.StationSprayInc(sc, consumeRegister); 243 | break; 244 | case "星球熔炉矿机": 245 | if (!StationMinerSmelter.Value) 246 | continue; 247 | if (remoteTick) 248 | { 249 | StationComponentPatch.StationMine(sc, __instance.planet, productRegister); 250 | } 251 | StationComponentPatch.StationFurnaceMiner(sc, time, consumeRegister, productRegister); 252 | break; 253 | case "星球矿机": 254 | case "Station_miner": 255 | if (!StationMiner.Value) 256 | continue; 257 | if (remoteTick) 258 | { 259 | StationComponentPatch.StationMine(sc, __instance.planet, productRegister); 260 | } 261 | break; 262 | case "星球量子传输站": 263 | case "星系量子传输站": 264 | break; 265 | } 266 | } 267 | } 268 | } 269 | 270 | } 271 | } 272 | -------------------------------------------------------------------------------- /Multifunction_mod/Patchs/DysonPatch.cs: -------------------------------------------------------------------------------- 1 | using HarmonyLib; 2 | using System.Collections.Generic; 3 | using System.Reflection.Emit; 4 | using System; 5 | using static Multifunction_mod.Multifunction; 6 | using System.Reflection; 7 | using static EjectorComponent; 8 | using UnityEngine; 9 | 10 | namespace Multifunction_mod.Patchs 11 | { 12 | public class DysonPatch 13 | { 14 | [HarmonyPostfix] 15 | [HarmonyPatch(typeof(DysonSphere), "Init")] 16 | public static void DysonSphereInit(ref DysonSphere __instance) 17 | { 18 | if (ChangeDysonradius.Value) 19 | { 20 | __instance.minOrbitRadius = 100; 21 | __instance.maxOrbitRadius = MaxOrbitRadiusConfig.Value; 22 | } 23 | } 24 | 25 | [HarmonyPrefix] 26 | [HarmonyPatch(typeof(DysonSphereLayer), "GameTick")] 27 | public static void DysonSphereLayerGameTick(ref DysonSphereLayer __instance, long gameTick) 28 | { 29 | if (!QuickabortSwarm.Value) 30 | return; 31 | int num = (int)(gameTick % 120L); 32 | for (int i = 1; i < __instance.nodeCursor; i++) 33 | { 34 | DysonNode dysonNode = __instance.nodePool[i]; 35 | if (dysonNode?.id == i && dysonNode.id % 120 == num && dysonNode.sp == dysonNode.spMax) 36 | { 37 | for (int j = 1; j <= Solarsailsabsorbeveryframe.Value; j++) 38 | { 39 | dysonNode.OrderConstructCp(gameTick, __instance.dysonSphere.swarm); 40 | } 41 | } 42 | } 43 | } 44 | 45 | [HarmonyPrefix] 46 | [HarmonyPatch(typeof(DysonSwarm), "AbsorbSail")] 47 | public static bool DysonSwarmPatch1(ref DysonSwarm __instance, ref bool __result, DysonNode node) 48 | { 49 | if (!quickabsorbsolar.Value) 50 | { 51 | return true; 52 | } 53 | if (__instance.expiryCursor == __instance.expiryEnding) 54 | { 55 | __result = false; 56 | return false; 57 | } 58 | __instance.expiryEnding--; 59 | if (__instance.expiryEnding < 0) 60 | { 61 | __instance.expiryEnding += __instance.sailCapacity; 62 | } 63 | int num = __instance.expiryEnding; 64 | int index = __instance.expiryOrder[num].index; 65 | if (__instance.expiryOrder[num].time == 0) 66 | { 67 | Assert.CannotBeReached(); 68 | __result = false; 69 | return false; 70 | } 71 | __instance.expiryOrder[num].time = 0; 72 | __instance.expiryOrder[num].index = 0; 73 | if (node != null && node.ConstructCp() != null) 74 | { 75 | __instance.dysonSphere.productRegister[11903]++; 76 | } 77 | __instance.RemoveSolarSail(index); 78 | return false; 79 | } 80 | 81 | } 82 | 83 | public class EjectAnywayPatch 84 | { 85 | public static string Patchid => GUID+"."+nameof(EjectAnywayPatch); 86 | private static Harmony _patch; 87 | private static bool enable; 88 | public static bool Enable 89 | { 90 | get => enable; 91 | set 92 | { 93 | if (enable == value) return; 94 | enable = value; 95 | if (enable) 96 | { 97 | _patch = Harmony.CreateAndPatchAll(typeof(EjectAnywayPatch), Patchid); 98 | } 99 | else 100 | { 101 | _patch.UnpatchSelf(); 102 | } 103 | } 104 | } 105 | 106 | [HarmonyTranspiler, HarmonyPriority(Priority.Last)] 107 | [HarmonyPatch(typeof(EjectorComponent), nameof(EjectorComponent.InternalUpdate))] 108 | private static IEnumerable EjectorComponent_InternalUpdate_Transpiler(IEnumerable instructions, ILGenerator generator) 109 | { 110 | var matcher = new CodeMatcher(instructions, generator); 111 | matcher.End().MatchBack( 112 | true, 113 | new CodeMatch(OpCodes.Ldarg_0), 114 | new CodeMatch(OpCodes.Ldfld, AccessTools.Field(typeof(EjectorComponent), nameof(EjectorComponent.autoOrbit))) 115 | ).Insert( 116 | //设置 this.targetState = EjectorComponent.ETargetState.OK 117 | new CodeInstruction(OpCodes.Ldarg_0), // 加载 this 118 | new CodeInstruction(OpCodes.Ldc_I4_1), // 加载 EjectorComponent.ETargetState.OK 119 | new CodeInstruction(OpCodes.Stfld, AccessTools.Field(typeof(EjectorComponent), nameof(EjectorComponent.targetState))), // 存储到 this.targetState 120 | 121 | new CodeInstruction(OpCodes.Ldc_I4_1), // 加载 true 122 | new CodeInstruction(OpCodes.Stloc_3) // 存储到 flag 123 | ); 124 | return matcher.InstructionEnumeration(); 125 | } 126 | 127 | 128 | } 129 | public struct Tempsail 130 | { 131 | public DysonSail ss; 132 | public int orbitid; 133 | public long time; 134 | public void FromData(in VectorLF3 delta1, in VectorLF3 delta2, int orbitId) 135 | { 136 | ss.px = (float)delta1.x; 137 | ss.py = (float)delta1.y; 138 | ss.pz = (float)delta1.z; 139 | ss.vx = (float)delta2.x; 140 | ss.vy = (float)delta2.y; 141 | ss.vz = (float)delta2.z; 142 | ss.gs = 1f; 143 | orbitid = orbitId; 144 | time = (long)(GameMain.history.solarSailLife * 60f + 0.1f); 145 | } 146 | } 147 | public class SkipBulletPatch 148 | { 149 | private static long _sailLifeTime; 150 | public static string Patchid => GUID + "." + nameof(SkipBulletPatch); 151 | private static Tempsail[][] _sailsCache; 152 | private static int[] _sailsCacheLen, _sailsCacheCapacity; 153 | 154 | private static Harmony _patch; 155 | private static bool enable; 156 | public static bool Enable 157 | { 158 | get => enable; 159 | set 160 | { 161 | if (enable == value) return; 162 | enable = value; 163 | Init(); 164 | if (enable) 165 | { 166 | _patch = Harmony.CreateAndPatchAll(typeof(SkipBulletPatch),Patchid); 167 | Multifunction_modGameLogic.OnGameBegin += GameMain_Begin_Postfix; 168 | UpdateSailLifeTime(); 169 | } 170 | else 171 | { 172 | _patch?.UnpatchSelf(); 173 | Multifunction_modGameLogic.OnGameBegin -= GameMain_Begin_Postfix; 174 | } 175 | } 176 | } 177 | public static bool CheckPatched() 178 | { 179 | var patches = Harmony.GetPatchInfo(typeof(EjectorComponent).GetMethod(nameof(EjectorComponent.InternalUpdate))); 180 | return patches.Transpilers.Count > 0; 181 | } 182 | 183 | private static void GameMain_Begin_Postfix() 184 | { 185 | Init(); 186 | } 187 | private static void UpdateSailLifeTime() 188 | { 189 | if (GameMain.history == null) return; 190 | _sailLifeTime = (long)(GameMain.history.solarSailLife * 60f + 0.1f); 191 | } 192 | 193 | public static void Init() 194 | { 195 | var galaxy = GameMain.data?.galaxy; 196 | if (galaxy == null) return; 197 | var starCount = GameMain.data.galaxy.starCount; 198 | _sailsCache = new Tempsail[starCount][]; 199 | _sailsCacheLen = new int[starCount]; 200 | _sailsCacheCapacity = new int[starCount]; 201 | Array.Clear(_sailsCacheLen, 0, starCount); 202 | Array.Clear(_sailsCacheCapacity, 0, starCount); 203 | UpdateSailLifeTime(); 204 | } 205 | 206 | [HarmonyPostfix] 207 | [HarmonyPatch(typeof(GameHistoryData), nameof(GameHistoryData.UnlockTechFunction))] 208 | private static void GameHistoryData_SetForNewGame_Postfix(int func) 209 | { 210 | if (func == 12) 211 | { 212 | UpdateSailLifeTime(); 213 | } 214 | } 215 | 216 | [HarmonyTranspiler] 217 | [HarmonyPatch(typeof(EjectorComponent), nameof(EjectorComponent.InternalUpdate))] 218 | private static IEnumerable EjectorComponent_InternalUpdate_Transpiler(IEnumerable instructions, ILGenerator generator) 219 | { 220 | var matcher = new CodeMatcher(instructions, generator); 221 | var endLabel = generator.DefineLabel(); // 定义跳转目标标签 222 | matcher 223 | .MatchForward( 224 | true, 225 | new CodeMatch(OpCodes.Ldc_R4, 10f), 226 | new CodeMatch(OpCodes.Stfld)) 227 | .Advance(1) 228 | .Insert( 229 | new CodeInstruction(OpCodes.Ldarg_0), 230 | new CodeInstruction(OpCodes.Ldfld,AccessTools.Field(typeof(EjectorComponent),nameof(EjectorComponent.fired))), 231 | new CodeInstruction(OpCodes.Brtrue, endLabel)) 232 | .MatchForward( 233 | true, 234 | new CodeMatch(OpCodes.Pop) 235 | ).Insert( 236 | new CodeInstruction(OpCodes.Nop).WithLabels(endLabel), 237 | new CodeInstruction(OpCodes.Ldarg_3), 238 | new CodeInstruction(OpCodes.Ldarg_3), 239 | new CodeInstruction(OpCodes.Ldarg_0), 240 | new CodeInstruction(OpCodes.Ldfld, AccessTools.Field(typeof(EjectorComponent), nameof(EjectorComponent.orbitId))), 241 | new CodeInstruction(OpCodes.Ldloc_S, 9), 242 | new CodeInstruction(OpCodes.Ldloc_S, 11), 243 | new CodeInstruction(OpCodes.Call, AccessTools.Method(typeof(SkipBulletPatch), nameof(AddDysonSail)))); 244 | //matcher.Start().Advance(start).RemoveInstructions(end - start).Insert( 245 | // new CodeInstruction(OpCodes.Ldarg_3), 246 | // new CodeInstruction(OpCodes.Ldarg_0), 247 | // new CodeInstruction(OpCodes.Ldfld, AccessTools.Field(typeof(EjectorComponent), nameof(EjectorComponent.orbitId))), 248 | // new CodeInstruction(OpCodes.Ldloc_S, 9), 249 | // new CodeInstruction(OpCodes.Ldloc_S, 11), 250 | // new CodeInstruction(OpCodes.Call, AccessTools.Method(typeof(SkipBulletPatch), nameof(AddDysonSail))) 251 | //); 252 | return matcher.InstructionEnumeration(); 253 | } 254 | 255 | private static void AddDysonSail(DysonSwarm swarm, int orbitId, VectorLF3 uPos, VectorLF3 endVec) 256 | { 257 | var index = swarm.starData.index; 258 | var delta1 = endVec - swarm.starData.uPosition; 259 | var delta2 = VectorLF3.Cross(endVec - uPos, swarm.orbits[orbitId].up).normalized * Math.Sqrt(swarm.dysonSphere.gravity / swarm.orbits[orbitId].radius); 260 | lock (swarm) 261 | { 262 | var cache = _sailsCache[index]; 263 | var len = _sailsCacheLen[index]; 264 | if (cache == null) 265 | { 266 | SetSailsCacheCapacity(index, 256); 267 | cache = _sailsCache[index]; 268 | } 269 | else 270 | { 271 | var capacity = _sailsCacheCapacity[index]; 272 | if (len >= capacity) 273 | { 274 | SetSailsCacheCapacity(index, capacity * 2); 275 | cache = _sailsCache[index]; 276 | } 277 | } 278 | _sailsCacheLen[index] = len + 1; 279 | cache[len].time = _sailLifeTime; 280 | cache[len].FromData(delta1, delta2, orbitId); 281 | } 282 | } 283 | 284 | private static void SetSailsCacheCapacity(int index, int capacity) 285 | { 286 | var newCache = new Tempsail[capacity]; 287 | var len = _sailsCacheLen[index]; 288 | if (len > 0) 289 | { 290 | Array.Copy(_sailsCache[index], newCache, len); 291 | } 292 | _sailsCache[index] = newCache; 293 | _sailsCacheCapacity[index] = capacity; 294 | } 295 | 296 | [HarmonyPrefix] 297 | [HarmonyPatch(typeof(DysonSwarm), "GameTick")] 298 | public static void DysonSwarmPatch(ref DysonSwarm __instance, long time) 299 | { 300 | if (__instance.starData == null || _sailsCacheLen==null) return; 301 | var sdIndex = __instance.starData.index; 302 | if (_sailsCacheLen[sdIndex] == 0) return; 303 | for (int i = _sailsCacheLen[sdIndex] - 1; i >= 0; i--) 304 | { 305 | Tempsail tempsail = _sailsCache[sdIndex][i]; 306 | __instance.AddSolarSail(tempsail.ss, tempsail.orbitid, tempsail.time + time); 307 | } 308 | _sailsCacheLen[sdIndex] = 0; 309 | } 310 | } 311 | } -------------------------------------------------------------------------------- /Multifunction_mod/MultifunctionTranslate.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace Multifunction_mod 4 | { 5 | public static class MultifunctionTranslate 6 | { 7 | private static Dictionary TranslateDict = new Dictionary(); 8 | public static string getTranslate(this string s) 9 | { 10 | string result = Multifunction.IsEnglish && TranslateDict.ContainsKey(s) && TranslateDict[s].Length > 0 ? TranslateDict[s] : s; 11 | //if (!TranslateDict.ContainsKey(s)) 12 | //{ 13 | // Debug.Log(s); 14 | //} 15 | return result; 16 | } 17 | public static void regallTranslate() 18 | { 19 | TranslateDict.Clear(); 20 | TranslateDict.Add("OP面板", "OP Pannel"); 21 | TranslateDict.Add("人物", "Player"); 22 | TranslateDict.Add("建筑", "Building"); 23 | TranslateDict.Add("星球", "Planet"); 24 | TranslateDict.Add("戴森球", "DysonSphere"); 25 | TranslateDict.Add("其它功能", "Other"); 26 | TranslateDict.Add("机甲物流", "Mechalogistics"); 27 | TranslateDict.Add("防止面板穿透", "ClosePanel"); 28 | 29 | TranslateDict.Add("走路速度", "Move speed"); 30 | TranslateDict.Add("研发速度", "Research speed"); 31 | TranslateDict.Add("配送机速度", "Dispenser speed"); 32 | TranslateDict.Add("配送机载量", "Delivery airload"); 33 | TranslateDict.Add("机甲制造MAX", "Mecha makes MAX"); 34 | TranslateDict.Add("机甲采矿MAX", "Mecha mining MAX"); 35 | TranslateDict.Add("背包", "Player Package"); 36 | TranslateDict.Add("加一行", "Add a line"); 37 | TranslateDict.Add("减一行", "Reduce a line"); 38 | TranslateDict.Add("加一列", "Add a column"); 39 | TranslateDict.Add("减一列", "Reduce a column"); 40 | TranslateDict.Add("小飞机速度", "Construction drones flight speed"); 41 | TranslateDict.Add("小飞机任务点数", "Construction drone task count"); 42 | TranslateDict.Add("小飞机数量", "Construction drones"); 43 | TranslateDict.Add("采矿速度", "Mecha mining speed"); 44 | TranslateDict.Add("制造速度", "Mecha produce speed"); 45 | TranslateDict.Add("最大航行速度", "Max sail speed"); 46 | TranslateDict.Add("最大曲速", "Max warp speed"); 47 | TranslateDict.Add("跳跃速度", "Jump speed"); 48 | TranslateDict.Add("建造范围", "Building range"); 49 | TranslateDict.Add("核心功率", "Core Generation"); 50 | TranslateDict.Add("运输机速度", "Logistics drone flight speed"); 51 | TranslateDict.Add("运输船速度", "Logistics vessel navigate speed"); 52 | TranslateDict.Add("运输机载量", "Logistics drone carrying capacity"); 53 | TranslateDict.Add("运输船载量", "Logistics vessel carrying capacity"); 54 | TranslateDict.Add("采矿机速度倍率", "Mining speed"); 55 | TranslateDict.Add("极速分拣器数量", "Sorter cargo stacking"); 56 | TranslateDict.Add("建筑堆叠高度", "Vertical construction"); 57 | TranslateDict.Add("货物集装数量", "Output Cargo Stack Count"); 58 | TranslateDict.Add("小飞机不耗能", "Construction drones no consumption"); 59 | TranslateDict.Add("无需翘曲器曲速飞行", "Mecha don't need space warper"); 60 | TranslateDict.Add("无限物品", "Infinite item"); 61 | TranslateDict.Add("锁定背包", "Lock the package"); 62 | TranslateDict.Add("建筑师模式", "ArchitectMode"); 63 | TranslateDict.Add("无限机甲能量", "Infinite mecha energy"); 64 | TranslateDict.Add("不往背包放东西", "Don't put things in the player's package"); 65 | TranslateDict.Add("建筑秒完成", "Construction completed in seconds"); 66 | TranslateDict.Add("蓝图建造无需材料", "No materials required for blueprint construction"); 67 | TranslateDict.Add("科技点击解锁", "Technology click to unlock"); 68 | TranslateDict.Add("物品列表(Tab)", "ItemList(Tab)"); 69 | TranslateDict.Add("物流背包堆叠倍率", "Delivery Package Stack Size"); 70 | 71 | TranslateDict.Add("以下功能需改名", "The following features need to be renamed"); 72 | TranslateDict.Add("无限元数据", "Infinite Property"); 73 | TranslateDict.Add("无限沙土", "Infinite Sand"); 74 | TranslateDict.Add("停止修改", "Stop change value"); 75 | TranslateDict.Add("启动修改", "Start change value"); 76 | TranslateDict.Add("清空背包", "Clear the package"); 77 | TranslateDict.Add("初始化玩家", "Initialize player"); 78 | TranslateDict.Add("增加背包大小", "Add package size"); 79 | TranslateDict.Add("直接获取物品", "InstantItem Mode"); 80 | TranslateDict.Add("减少背包大小", "Reduce package size"); 81 | TranslateDict.Add("解锁全部科技", "Unlock all tech."); 82 | TranslateDict.Add("回退无穷科技", "Lock all Infinite tech."); 83 | TranslateDict.Add("初始化太阳帆轨道", "Initialize the solar sail orbit"); 84 | TranslateDict.Add("点击删除下列戴森壳层级", "Click to delete the following Dyson shell layers"); 85 | TranslateDict.Add("注意事项:戴森云和戴森壳不要出现一层轨道都没有的情况(用前存档)", "Note: The Dyson cloud and Dyson shell do not have a layer of orbits (save before use)"); 86 | 87 | TranslateDict.Add("建造数量最大值", "Max buildings num"); 88 | TranslateDict.Add("额外存储倍率", "Station storage extra multiply"); 89 | TranslateDict.Add("物流站功能", "Station storage functions"); 90 | TranslateDict.Add("储液站功能", "Storage tank functions"); 91 | TranslateDict.Add("其它建筑功能", "Other building functions"); 92 | TranslateDict.Add("储液站无限增产", "The station increases production indefinitely"); 93 | TranslateDict.Add("建筑抬升", "Building uplift"); 94 | TranslateDict.Add("风力涡轮机覆盖全球", "Wind turbines cover the globe"); 95 | TranslateDict.Add("内置喷涂", "Station Built-in spraying"); 96 | TranslateDict.Add("内置发电", "Built-in power generation"); 97 | TranslateDict.Add("实时更改全部物流站存储倍率", "Real-time changes Station storage max"); 98 | TranslateDict.Add("无限储液站", "Infinite storage tank"); 99 | TranslateDict.Add("星球无限供货机", "Planet infinite item station"); 100 | TranslateDict.Add("要啥有啥", "All stations infinite item"); 101 | TranslateDict.Add("建造无需条件", "Build no conditions"); 102 | TranslateDict.Add("无需赤道造采集器", "Collector no equatorial condition"); 103 | TranslateDict.Add("强行近距离建造物流站", "Station no too close condition"); 104 | TranslateDict.Add("无限翘曲", "Station infinite space warpers"); 105 | TranslateDict.Add("人造恒星无限能源", "Artificial star infinite power"); 106 | TranslateDict.Add("风力涡轮机无限能源", "Wind Turbines Unlimited Energy"); 107 | TranslateDict.Add("极速轨道弹射器(慎用)", "Extremely quick Ejector(Danger)"); 108 | TranslateDict.Add("极速垂直发射井(慎用)", "Extremely quick Silo(Danger"); 109 | TranslateDict.Add("星球电网(人造恒星)", "Plnaet Power(Artificial star)"); 110 | TranslateDict.Add("电力设备", "Electrical equipment"); 111 | TranslateDict.Add("覆盖全球", "Global coverage"); 112 | TranslateDict.Add("超长连接", "Long connection"); 113 | TranslateDict.Add("新建设备不耗电", "New buildings dont't require power"); 114 | TranslateDict.Add("永久满电", "Stations full energy"); 115 | TranslateDict.Add("无限增产", "Station Max proliferator"); 116 | TranslateDict.Add("传送带信号功能", "BeltSignal Function"); 117 | TranslateDict.Add("储液站任意存", "Anything can store in water tank"); 118 | TranslateDict.Add("量子耗能/个", "Quantum comsume energy each"); 119 | TranslateDict.Add("量子传输站", "Quantum Transmission Station"); 120 | TranslateDict.Add("星球级材料供应", "Planet Material supply"); 121 | TranslateDict.Add("星球级物流站材料供应", "Planet Station Material supply"); 122 | TranslateDict.Add("星球级矿机材料供应", "Planet Mining facility Material supply"); 123 | TranslateDict.Add("星球级发射井弹射器材料供应", "Planet Silo and Ejector Material supply"); 124 | TranslateDict.Add("星球级研究站材料供应", "Planet Lab Material supply"); 125 | TranslateDict.Add("星球级电力设备材料供应", "Planet Power facility Material supply"); 126 | TranslateDict.Add("星球级组装机材料供应", "Planet Assmeblers Material supply"); 127 | TranslateDict.Add("星球级翘曲全面供应", "Planet Quantum Transmission Station warper supply"); 128 | TranslateDict.Add("星系级翘曲全面供应", "Star Quantum Transmission Station warper supply"); 129 | TranslateDict.Add("自动改名\"星球量子传输站\"", "auto. change name\"星球量子传输站\""); 130 | TranslateDict.Add("自动改名\"星系量子传输站\"", "auto. change name\"星系量子传输站\""); 131 | TranslateDict.Add("星系量子不突破上限", "Star Quantum Transmission Station don't exceed the upper limit"); 132 | TranslateDict.Add("星球量子充电功率", "Planet Quantum Transmission Station max charging power"); 133 | TranslateDict.Add("星系量子充电功率", "Star Quantum Transmission Station max charging power"); 134 | 135 | TranslateDict.Add("\"生成矿物\":鼠标左键生成矿物,鼠标右键取消。\"删除矿物\":按x键进入拆除模式可拆除矿物。", "\"Generate Vein\":left mouse button generate vein,right mouse button cancel.\"delete vein\":Press the x key to enter the removal mode to delete the vein"); 136 | TranslateDict.Add("生成矿物", "Generate Vein"); 137 | TranslateDict.Add("移动单矿", "Change position of the vein"); 138 | TranslateDict.Add("移动矿堆", "Change position of the veingroup"); 139 | TranslateDict.Add("获取所有矿", "Get all veins and change"); 140 | TranslateDict.Add("删除矿物", "delete vein"); 141 | TranslateDict.Add("还原海洋", "Restore the ocean"); 142 | TranslateDict.Add("整理所有矿", "Organize all mines"); 143 | TranslateDict.Add("切割出", "Cut out"); 144 | TranslateDict.Add("整理为", "Organized as"); 145 | TranslateDict.Add("个", "veins"); 146 | TranslateDict.Add("行", "lines"); 147 | TranslateDict.Add("铺平整个星球", "Pave the whole planet"); 148 | TranslateDict.Add("还原全部海洋", "Restore the whole ocean"); 149 | TranslateDict.Add("铺平整个星球(地基)", "Pave the whole planet(Foundation)"); 150 | TranslateDict.Add("铺平整个星球(自定义颜色)", "Pave the whole planet(Custom color)"); 151 | TranslateDict.Add("掩埋全部矿", "bury all veins"); 152 | TranslateDict.Add("删除全部矿", "delete all veins"); 153 | TranslateDict.Add("添加油井速率", "Add oil interval"); 154 | TranslateDict.Add("添加矿脉数量", "Add vein interval"); 155 | TranslateDict.Add("无穷", "Infinite"); 156 | TranslateDict.Add("生成矿物模式", "Add vein Mode"); 157 | TranslateDict.Add("点按", "Click"); 158 | TranslateDict.Add("按压", "Press"); 159 | TranslateDict.Add("删除当前星球所有建筑", "Dismantle all buildings"); 160 | TranslateDict.Add("删除当前星球所有建筑(不掉落)", "Dismantle all buildings(no drop)"); 161 | TranslateDict.Add("初始化当前星球", "Initialize the current planet"); 162 | TranslateDict.Add("初始化当前星球(不要海洋)", "Initialize the current planet(no ocean)"); 163 | TranslateDict.Add("星球矿机", "Station_miner"); 164 | TranslateDict.Add("自动改名", "auto. change name\"Station_miner\""); 165 | TranslateDict.Add("星球矿机无消耗", "Station_miner no comsumption veins"); 166 | TranslateDict.Add("采矿速率", "mining speed"); 167 | TranslateDict.Add("垃圾站", "Station_trash"); 168 | TranslateDict.Add("不需要沙土", "no need for soil pile"); 169 | TranslateDict.Add("改变海洋类型", "Change water type"); 170 | TranslateDict.Add("还原所有海洋类型", "Restore all water types"); 171 | TranslateDict.Add("不排列", "Do not arrange"); 172 | TranslateDict.Add("切割矿脉", "Cutting veins"); 173 | TranslateDict.Add("超密铺采集器", "Ultra-dense shop collector"); 174 | TranslateDict.Add("设置当前星球海洋类型", "Sets the current planetary ocean type"); 175 | TranslateDict.Add("恢复所有星球海洋类型", "Restore all planetary ocean types"); 176 | 177 | TranslateDict.Add("初始化当前戴森球", "Clear current DysonSphere"); 178 | TranslateDict.Add("瞬间完成戴森球(用前存档)", "Finish DysonSphere(Remember to save)"); 179 | TranslateDict.Add("保存戴森球", "save DysonSphere"); 180 | TranslateDict.Add("打开戴森球蓝图文件夹", "Open DysonSphere Blueprint folder"); 181 | TranslateDict.Add("导入戴森球", "Load DysonSphere"); 182 | TranslateDict.Add("跳过太阳帆吸收阶段", "Skip the solar sail absorption phase"); 183 | TranslateDict.Add("跳过太阳帆子弹阶段", "Skip the solar sail bullet stage"); 184 | TranslateDict.Add("太阳帆帧吸收", "abort solarsail every frame"); 185 | TranslateDict.Add("全球打帆", "Sail anywhere in the planet"); 186 | TranslateDict.Add("间隔发射", "Eject average"); 187 | TranslateDict.Add("开放戴森壳半径上下限(用前存档)", "Open the upper and lower limits of the Dyson shell radius (save before use)"); 188 | 189 | TranslateDict.Add("最大半径", "maxOrbitRadius"); 190 | TranslateDict.Add("最小半径", "minOrbitRadius"); 191 | TranslateDict.Add("戴森云和戴森壳至少要有一层,否则会出bug", "Dyson swarm must have at least one orbit.Dyson shell must have al least one layer"); 192 | 193 | TranslateDict.Add("丢垃圾速率", "throw trash speed"); 194 | TranslateDict.Add("以下设置需要进入存档", "The follow config need to load game"); 195 | TranslateDict.Add("丢垃圾(整活用)", "throw trash"); 196 | TranslateDict.Add("夜灯", "Sunlight"); 197 | TranslateDict.Add("蓝图强制粘贴", "Enforce to paste blueprint"); 198 | TranslateDict.Add("成就重新检测", "Recheck Achievements"); 199 | TranslateDict.Add("以下设置需要重启游戏", "The follow config need restart the game"); 200 | TranslateDict.Add("设置", "Set"); 201 | TranslateDict.Add("冶炼倍数", "Multiple smelt"); 202 | TranslateDict.Add("堆叠倍率", "Multiple stack"); 203 | TranslateDict.Add("操作范围不受限制", "Inspect no limit"); 204 | TranslateDict.Add("全部手搓", "All item can handcraft"); 205 | TranslateDict.Add("无材料生产", "No material produce"); 206 | TranslateDict.Add("快速生产", "Quick produce"); 207 | TranslateDict.Add("关闭异常提示", "Turn off exception prompts"); 208 | TranslateDict.Add("增产点数上限10", "The maximum number of production increase points is 10"); 209 | TranslateDict.Add("建筑铺设无需条件", "No conditions are required for the laying of the building"); 210 | TranslateDict.Add("关闭所有碰撞体", "Close all colliders"); 211 | TranslateDict.Add("取消所有勾选", "Uncheck all ticks"); 212 | 213 | TranslateDict.Add("窗口颜色及透明度", "Window color and alpha"); 214 | TranslateDict.Add("应用", "Confirm"); 215 | TranslateDict.Add("窗口字体颜色", "Window font color"); 216 | TranslateDict.Add("快捷键", "QuickKey"); 217 | TranslateDict.Add("改变窗口快捷键", "Change QuickKey"); 218 | TranslateDict.Add("点击确认", "Click to confirm"); 219 | 220 | 221 | TranslateDict.Add("储存", "Store"); 222 | TranslateDict.Add("需求", "Need"); 223 | TranslateDict.Add("回收", "Recycle"); 224 | TranslateDict.Add("强化机甲物流", "Strengthen mecha logistics"); 225 | TranslateDict.Add("机甲物流专用星", "Mecha logistics Planet"); 226 | TranslateDict.Add("回收使用储物仓", "Recycle use storage"); 227 | TranslateDict.Add("需求使用储物仓", "Provide use storage"); 228 | TranslateDict.Add("回收使用物流站", "Recycle use station"); 229 | TranslateDict.Add("需求使用物流站", "Provide use station"); 230 | } 231 | } 232 | } 233 | -------------------------------------------------------------------------------- /Multifunction_mod/Patchs/StationComponentPatch.cs: -------------------------------------------------------------------------------- 1 | using HarmonyLib; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Reflection.Emit; 6 | using System.Reflection; 7 | using UnityEngine; 8 | using static Multifunction_mod.Multifunction; 9 | 10 | namespace Multifunction_mod.Patchs 11 | { 12 | public class StationComponentPatch 13 | { 14 | private static HashSet tempids=new HashSet(); 15 | [HarmonyPrefix] 16 | [HarmonyPatch(typeof(StationComponent), "Init")] 17 | public static void StationComponentInit(ref int _extraStorage, StationComponent __instance) 18 | { 19 | if (StationStoExtra.Value <= 0) 20 | { 21 | return; 22 | } 23 | int basemax = __instance.isStellar ? 10000 : 5000; 24 | _extraStorage = (StationStoExtra.Value + 1) * basemax; 25 | } 26 | 27 | /// 28 | /// 获取目标星球目标矿脉数量 29 | /// 30 | /// 31 | /// 32 | /// 33 | public static int GetNumberOfVein(int itemid, PlanetData pd) 34 | { 35 | EVeinType evt = LDB.veins.GetVeinTypeByItemId(itemid); 36 | if (evt == EVeinType.None) 37 | { 38 | return 0; 39 | } 40 | if (evt == EVeinType.Oil) 41 | { 42 | long[] veinAmounts = new long[64]; 43 | pd.SummarizeVeinAmountsByFilter(ref veinAmounts, tempids, UIRoot.instance.uiGame.veinAmountDisplayFilter); 44 | int collectspeed = (int)(veinAmounts[7] * VeinData.oilSpeedMultiplier + 0.5); 45 | if (collectspeed > 1) return collectspeed; 46 | } 47 | return pd.factory.veinPool.Count(x => x.type == evt); 48 | } 49 | 50 | /// 51 | /// 物流站采矿 52 | /// 53 | /// 54 | /// 55 | /// 56 | /// 57 | public static int MineVein(int itemid, int minenumber, PlanetData pd) 58 | { 59 | if (pd.waterItemId == itemid) 60 | { 61 | return (int)(30 * GameMain.history.miningSpeedScale * Stationminenumber.Value); 62 | } 63 | if (minenumber <= 0) return 0; 64 | int getmine = 0; 65 | int maxmineNumber = itemid != 1007 ? (int)(minenumber * GameMain.history.miningSpeedScale / 2) : (int)(minenumber * GameMain.history.miningSpeedScale); 66 | int neednumber = itemid != 1007 ? (int)(maxmineNumber * GameMain.history.miningCostRate / 2) : (int)(maxmineNumber * GameMain.history.miningCostRate); 67 | if (GameMain.data.gameDesc.isInfiniteResource) 68 | return maxmineNumber; 69 | if (LDB.veins.GetVeinTypeByItemId(itemid) == EVeinType.None || pd == null) 70 | { 71 | return 0; 72 | } 73 | if (neednumber == 0) 74 | { 75 | return maxmineNumber; 76 | } 77 | foreach (VeinData i in pd.factory.veinPool) 78 | { 79 | if (i.type != LDB.veins.GetVeinTypeByItemId(itemid)) 80 | continue; 81 | if (i.amount == 1) 82 | { 83 | continue; 84 | } 85 | if (i.amount > neednumber - getmine) 86 | { 87 | if (itemid == 1007 && i.amount * VeinData.oilSpeedMultiplier <= 0.1) 88 | { 89 | int dis = veinproperty.oillowerlimit - i.amount; 90 | pd.factory.veinPool[i.id].amount += dis; 91 | pd.factory.veinGroups[i.groupIndex].amount += dis; 92 | getmine += (int)(0.1 * GameMain.history.miningSpeedScale * Stationminenumber.Value); 93 | } 94 | else 95 | { 96 | pd.factory.veinPool[i.id].amount -= neednumber; 97 | pd.factory.veinGroups[i.groupIndex].amount -= neednumber; 98 | getmine = maxmineNumber; 99 | } 100 | } 101 | else 102 | { 103 | getmine += i.amount - 1; 104 | pd.factory.veinPool[i.id].amount = 1; 105 | pd.factory.veinGroups[i.groupIndex].amount -= i.amount - 1; 106 | } 107 | if (getmine >= maxmineNumber) break; 108 | } 109 | return getmine; 110 | } 111 | 112 | /// 113 | /// 物流站星球采矿 114 | /// 115 | /// 116 | /// 117 | public static void StationMine(StationComponent sc, PlanetData pd, int[] productRegister) 118 | { 119 | for (int i = 0; i < sc.storage.Length && sc.energy > 0; i++) 120 | { 121 | ref StationStore store = ref sc.storage[i]; 122 | int itemID = store.itemId; 123 | if (itemID <= 0 || store.count >= store.max) 124 | continue; 125 | int veinNumbers = GetNumberOfVein(itemID, pd); 126 | int pointminenum = veinNumbers * Stationminenumber.Value; 127 | if (veinNumbers > 0 && pointminenum == 0) pointminenum = 1; 128 | else if (veinNumbers == 0 && itemID != pd.waterItemId) continue; 129 | 130 | if (!Stationfullenergy.Value && sc.energy <= pointminenum * GameMain.history.miningSpeedScale * 5000) 131 | { 132 | pointminenum = (int)(sc.energy*0.9f / (GameMain.history.miningSpeedScale * 5000)); 133 | } 134 | int minenum = MineVein(itemID, pointminenum, pd); 135 | if (minenum <= 0) 136 | { 137 | continue; 138 | } 139 | lock (productRegister) 140 | { 141 | productRegister[itemID] += minenum; 142 | sc.storage[i].count += minenum; 143 | if (!Stationfullenergy.Value) 144 | sc.energy -= minenum * 5000; 145 | } 146 | } 147 | } 148 | 149 | /// 150 | /// 物流站内置发电 151 | /// 152 | /// 153 | /// 154 | public static void StationPowerGeneration(StationComponent sc, int[] consumeRegister) 155 | { 156 | if (sc == null || sc.storage == null || sc.energy >= sc.energyMax - 1000000) return; 157 | ref StationStore store = ref sc.storage[sc.storage.Length - 1]; 158 | if (store.itemId <= 0 || store.count <= 0) 159 | return; 160 | ItemProto ip = LDB.items.Select(store.itemId); 161 | if (ip.HeatValue > 0 && sc.energy + ip.HeatValue < sc.energyMax) 162 | { 163 | int num = Math.Min(store.count, (int)((sc.energyMax - sc.energy) / ip.HeatValue)); 164 | sc.energy += num * ip.HeatValue; 165 | store.count -= num; 166 | if (num > 0) 167 | { 168 | lock (consumeRegister) 169 | { 170 | consumeRegister[ip.ID] = num; 171 | } 172 | } 173 | } 174 | } 175 | 176 | /// 177 | /// 物流站内置喷涂 178 | /// 179 | /// 180 | public static void StationSprayInc(StationComponent sc, int[] consumeRegister) 181 | { 182 | int incIndex = -1; 183 | for (int i = 0; i < sc.storage.Length; i++) 184 | { 185 | if (sc.storage[i].itemId == 1143) 186 | { 187 | incIndex = i; 188 | if (sc.storage[i].count == 0) return; 189 | break; 190 | } 191 | } 192 | if (incIndex == -1) 193 | return; 194 | for (int i = 0; i < sc.storage.Length; i++) 195 | { 196 | ref StationStore store = ref sc.storage[i]; 197 | ref StationStore incstore = ref sc.storage[incIndex]; 198 | if (store.itemId == 1143 || store.itemId <= 0 || store.count <= 0) continue; 199 | 200 | int needinc = store.count * incAbility - store.inc; 201 | int needNumber = Math.Min((int)Math.Ceiling(needinc / 296.0), incstore.count); 202 | if (needNumber == 0) continue; 203 | lock (consumeRegister) 204 | { 205 | consumeRegister[1143] = needNumber; 206 | store.inc += (incstore.count >= needNumber ? needNumber : incstore.count) * 296; 207 | incstore.count -= needNumber; 208 | } 209 | if (store.count == 0) 210 | { 211 | store.inc = 0; 212 | } 213 | } 214 | } 215 | 216 | /// 217 | /// 物流站满货物 218 | /// 219 | /// 220 | public static void StationFullItemCount(StationComponent sc) 221 | { 222 | for (int i = 0; i < sc.storage.Length; i++) 223 | { 224 | if (sc.storage[i].itemId <= 0) 225 | continue; 226 | sc.storage[i].count = sc.storage[i].max; 227 | } 228 | } 229 | 230 | /// 231 | /// 物流站垃圾站 232 | /// 233 | /// 234 | public static void StationTrashMethod(StationComponent sc, int[] consumeRegister) 235 | { 236 | long addSand = 0; 237 | for (int i = 0; i < sc.storage.Length && sc.energy > 0; i++) 238 | { 239 | ref StationStore store = ref sc.storage[i]; 240 | int itemID = store.itemId; 241 | if (itemID <= 0) continue; 242 | int trashnum = store.count; 243 | if (sc.energy > trashnum * 10000) 244 | { 245 | lock (consumeRegister) 246 | { 247 | consumeRegister[itemID] = trashnum; 248 | sc.storage[i].count -= trashnum; 249 | if (!Stationfullenergy.Value) 250 | sc.energy -= trashnum * 10000; 251 | } 252 | if (needtrashsand.Value) 253 | { 254 | addSand += trashnum * 100; 255 | } 256 | } 257 | } 258 | if (addSand > 0) 259 | { 260 | player.sandCountChanged -= UIRoot.instance.uiGame.OnSandCountChanged; 261 | player.SetSandCount(player.sandCount + addSand); 262 | player.sandCountChanged += UIRoot.instance.uiGame.OnSandCountChanged; 263 | } 264 | } 265 | 266 | /// 267 | /// 星球熔炉矿机 268 | /// 269 | /// 270 | /// 271 | public static void StationFurnaceMiner(StationComponent sc, long time, int[] consumeRegister, int[] productRegister) 272 | { 273 | List storageItems = sc.storage.Select(x => x.itemId).ToList(); 274 | storageItems.ForEach(itemId => 275 | { 276 | if (itemId <= 0 || !smeltRecipes.ContainsKey(itemId)) return; 277 | smeltRecipes[itemId].ForEach(rp => 278 | { 279 | int spendtime = rp.TimeSpend / 2; 280 | if (spendtime < 2) { } 281 | else if (time % spendtime != 0) return; 282 | if (!rp.Results.All(storageItems.Contains) || !rp.Items.All(storageItems.Contains)) 283 | return; 284 | for (int i = 0; i < rp.ResultCounts.Length; i++) 285 | { 286 | int index = storageItems.IndexOf(rp.Results[i]); 287 | if (sc.storage[index].count > sc.storage[index].max) 288 | { 289 | return; 290 | } 291 | } 292 | int smelters = StationMinerSmelterNum.Value; 293 | int costenergypertime = 1440000; 294 | int doublecostenergypertime = 2880000; 295 | int smeltTime = smelters; 296 | int incsmeltTime = smeltTime; 297 | int len = rp.Items.Length; 298 | for (int i = 0; i < len; i++) 299 | { 300 | if (rp.ItemCounts[i] == 0) continue; 301 | int index = storageItems.IndexOf(rp.Items[i]); 302 | int tempcount = sc.storage[index].count / rp.ItemCounts[i]; 303 | smeltTime = Math.Min(smeltTime, tempcount); 304 | incsmeltTime = Math.Min(Math.Min(incsmeltTime, tempcount), sc.storage[index].inc / incAbility); 305 | } 306 | if (Stationfullenergy.Value) 307 | { 308 | smeltTime = smeltTime - incsmeltTime; 309 | } 310 | else 311 | { 312 | incsmeltTime = (int)Math.Min(incsmeltTime, sc.energy / doublecostenergypertime); 313 | sc.energy -= incsmeltTime * doublecostenergypertime; 314 | smeltTime = (int)Math.Min(smeltTime - incsmeltTime, sc.energy / costenergypertime); 315 | } 316 | if (smeltTime + incsmeltTime == 0) return; 317 | if (!Stationfullenergy.Value) 318 | { 319 | sc.energy -= smeltTime * costenergypertime; 320 | } 321 | for (int i = 0; i < len; i++) 322 | { 323 | int consumeCount = rp.ItemCounts[i] * (smeltTime + incsmeltTime); 324 | lock (consumeRegister) 325 | { 326 | int index = storageItems.IndexOf(rp.Items[i]); 327 | sc.storage[index].count -= consumeCount; 328 | sc.storage[index].inc -= incsmeltTime * rp.ItemCounts[i] * incAbility; 329 | sc.storage[index].inc = Math.Max(0, Math.Min(sc.storage[index].count * incAbility, sc.storage[index].inc)); 330 | consumeRegister[rp.Items[i]] = consumeCount; 331 | } 332 | } 333 | for (int i = 0; i < rp.ResultCounts.Length; i++) 334 | { 335 | lock (productRegister) 336 | { 337 | int addcount = (int)(rp.ResultCounts[i] * (smeltTime + incsmeltTime * (1 + Cargo.incTableMilli[incAbility]))); 338 | int index = storageItems.IndexOf(rp.Results[i]); 339 | sc.storage[index].count += addcount; 340 | productRegister[rp.Results[i]] = addcount; 341 | } 342 | } 343 | }); 344 | }); 345 | } 346 | 347 | } 348 | } 349 | -------------------------------------------------------------------------------- /Multifunction_mod/Constant.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using UnityEngine; 3 | 4 | namespace Multifunction_mod 5 | { 6 | public class Constant 7 | { 8 | public static List nodepos = new List(); 9 | public static double[,] posxz = new double[10, 2]{ 10 | {0,1 }, 11 | { 0.1563, -0.9877}, 12 | { 0.3089,-0.9511 }, 13 | { 0.4539, -0.8911 }, 14 | { 0.5877, -0.8091 }, 15 | { 0.7071, -0.7071 }, 16 | { 0.8091, -0.5877 }, 17 | { 0.8910, -0.4540 }, 18 | { 0.9511, -0.3089 }, 19 | { 0.9877, -0.1564 }, 20 | }; 21 | public static double[,] dysonposxyz1 = new double[7, 2] 22 | { 23 | {7431.4, 6691.3}, 24 | {8090.2, 5877.9}, 25 | {8660.3, 5000.0}, 26 | {9135.5, 4067.4}, 27 | {9510.6, 3090.2}, 28 | {9781.5, 2079.1}, 29 | {9945.2, 1045.3}, 30 | }; 31 | public static double[,] dysonposxyz2 = new double[14, 3] 32 | { 33 | {-1045.3, 0.0, 9945.2}, 34 | {-2079.1, 0.0, 9781.5}, 35 | {-3090.2, 0.0, 9510.6}, 36 | {-4067.4, 0.0, 9135.4}, 37 | {-5000.0, 0.0, 8660.2}, 38 | {-5877.9, 0.0, 8090.2}, 39 | {-6691.3, 0.0, 7431.4}, 40 | {-7431.5, 0.0, 6691.3}, 41 | {-8090.2, 0.0, 5877.9}, 42 | {-8660.3, 0.0, 5000.0}, 43 | {-9135.5, 0.0, 4067.4}, 44 | {-9510.6, 0.0, 3090.2}, 45 | {-9781.5, 0.0, 2079.1}, 46 | {-9945.2, 0.0, 1045.3}, 47 | }; 48 | public static double[,] dysonposxyz3 = new double[98, 3] 49 | { 50 | {1143.5, 1149.8, 10879.8}, 51 | {1124.7, 2287.0, 10700.7}, 52 | {1093.5, 3399.2, 10404.3}, 53 | {1050.4, 4474.1, 9994.0}, 54 | {995.8, 5500.0, 9474.1}, 55 | {930.2, 6465.6, 8850.4}, 56 | {854.5, 7360.4, 8129.8}, 57 | {1699.6, 7360.4, 7996.0}, 58 | {1850.2, 6465.6, 8704.7}, 59 | {1980.6, 5500.0, 9318.1}, 60 | {2089.3, 4474.1, 9829.4}, 61 | {2175.1, 3399.2, 10233.0}, 62 | {2237.0, 2287.0, 10524.5}, 63 | {2274.5, 1149.8, 10700.7}, 64 | {3380.6, 1149.8, 10404.3}, 65 | {3324.9, 2287.0, 10233.0}, 66 | {3232.8, 3399.2, 9949.6}, 67 | {3105.3, 4474.1, 9557.2}, 68 | {2943.8, 5500.0, 9060.0}, 69 | {2750.0, 6465.6, 8463.6}, 70 | {2526.1, 7360.4, 7774.5}, 71 | {3324.9, 7360.4, 7467.9}, 72 | {3619.6, 6465.6, 8129.8}, 73 | {3874.7, 5500.0, 8702.7}, 74 | {4087.3, 4474.1, 9180.2}, 75 | {4255.1, 3399.2, 9557.2}, 76 | {4376.3, 2287.0, 9829.4}, 77 | {4449.6, 1149.8, 9993.9}, 78 | {5469.9, 1149.8, 9474.1}, 79 | {5379.8, 2287.0, 9318.1}, 80 | {5230.8, 3399.2, 9060.0}, 81 | {5024.5, 4474.1, 8702.7}, 82 | {4763.1, 5500.0, 8250.0}, 83 | {4449.6, 6465.6, 7706.9}, 84 | {4087.3, 7360.4, 7079.4}, 85 | {4804.9, 7360.4, 6613.4}, 86 | {5230.8, 6465.6, 7199.6}, 87 | {5599.4, 5500.0, 7706.9}, 88 | {5906.7, 4474.1, 8129.8}, 89 | {6149.2, 3399.2, 8463.6}, 90 | {6324.4, 2287.0, 8704.7}, 91 | {6430.2, 1149.8, 8850.4}, 92 | {7320.1, 1149.8, 8129.8}, 93 | {7199.6, 2287.0, 7995.9}, 94 | {7000.2, 3399.2, 7774.5}, 95 | {6724.1, 4474.1, 7467.9}, 96 | {6374.3, 5500.0, 7079.4}, 97 | {5954.7, 6465.6, 6613.4}, 98 | {5469.9, 7360.4, 6074.9}, 99 | {6074.9, 7360.4, 5469.9}, 100 | {6613.4, 6465.6, 5954.7}, 101 | {7079.4, 5500.0, 6374.3}, 102 | {7467.9, 4474.1, 6724.1}, 103 | {7774.5, 3399.2, 7000.2}, 104 | {7996.0, 2287.0, 7199.6}, 105 | {8129.8, 1149.8, 7320.1}, 106 | {8850.4, 1149.8, 6430.2}, 107 | {8704.7, 2287.0, 6324.3}, 108 | {8463.6, 3399.2, 6149.2}, 109 | {8129.8, 4474.1, 5906.6}, 110 | {7706.9, 5500.0, 5599.4}, 111 | {7199.6, 6465.6, 5230.8}, 112 | {6613.4, 7360.4, 4804.9}, 113 | {7079.4, 7360.4, 4087.3}, 114 | {7706.9, 6465.6, 4449.6}, 115 | {8250.0, 5500.0, 4763.1}, 116 | {8702.7, 4474.1, 5024.5}, 117 | {9060.0, 3399.2, 5230.8}, 118 | {9318.1, 2287.0, 5379.8}, 119 | {9474.1, 1149.8, 5469.9}, 120 | {9994.0, 1149.8, 4449.6}, 121 | {9829.4, 2287.0, 4376.3}, 122 | {9557.2, 3399.2, 4255.1}, 123 | {9180.2, 4474.1, 4087.3}, 124 | {8702.7, 5500.0, 3874.7}, 125 | {8129.8, 6465.6, 3619.6}, 126 | {7467.9, 7360.4, 3324.9}, 127 | {7774.5, 7360.4, 2526.1}, 128 | {8463.6, 6465.6, 2750.0}, 129 | {9060.0, 5500.0, 2943.8}, 130 | {9557.2, 4474.1, 3105.3}, 131 | {9949.6, 3399.2, 3232.8}, 132 | {10233.0, 2287.0, 3324.9}, 133 | {10404.3, 1149.8, 3380.6}, 134 | {10700.7, 1149.8, 2274.5}, 135 | {10524.5, 2287.0, 2237.0}, 136 | {10233.0, 3399.2, 2175.1}, 137 | {9829.4, 4474.1, 2089.3}, 138 | {9318.1, 5500.0, 1980.6}, 139 | {8704.7, 6465.6, 1850.2}, 140 | {7996.0, 7360.4, 1699.6}, 141 | {8129.8, 7360.4, 854.5}, 142 | {8850.4, 6465.6, 930.2}, 143 | {9474.1, 5500.0, 995.8}, 144 | {9994.0, 4474.1, 1050.4}, 145 | {10404.3, 3399.2, 1093.5}, 146 | {10700.7, 2287.0, 1124.7}, 147 | {10879.8, 1149.8, 1143.5}, 148 | }; 149 | public static double[,] dysonposxyz4 = new double[244, 3] 150 | { 151 | {0.0, 9659.3, 2588.2}, 152 | {-943.9, 8910.1, -4440.7}, 153 | {-1846.5, 8910.1, -4147.4}, 154 | {-2668.5, 8910.1, -3672.9}, 155 | {-3373.8, 8910.1, -3037.8}, 156 | {-3931.7, 8910.1, -2270.0}, 157 | {-4317.7, 8910.1, -1402.9}, 158 | {-4515.0, 8910.1, -474.6}, 159 | {-4515.0, 8910.1, 474.5}, 160 | {-4317.7, 8910.1, 1402.9}, 161 | {-3931.7, 8910.1, 2269.9}, 162 | {-3373.8, 8910.1, 3037.8}, 163 | {-2668.5, 8910.1, 3672.9}, 164 | {-1846.6, 8910.1, 4147.4}, 165 | {-943.9, 8910.1, 4440.7}, 166 | {2588.2, 9659.3, 0.0}, 167 | {0.0, 10000.0, 0.0}, 168 | {2461.5, 9659.3, 799.8}, 169 | {-745.1, 9335.8, 3505.4}, 170 | {-1457.6, 9335.8, 3273.9}, 171 | {-2106.4, 9335.8, 2899.3}, 172 | {-2663.2, 9335.8, 2397.9}, 173 | {-3103.6, 9335.8, 1791.8}, 174 | {-3408.3, 9335.8, 1107.4}, 175 | {-3564.1, 9335.8, 374.6}, 176 | {-3564.0, 9335.8, -374.6}, 177 | {-3408.3, 9335.8, -1107.4}, 178 | {-3103.5, 9335.8, -1791.9}, 179 | {-2663.2, 9335.8, -2398.0}, 180 | {-2106.4, 9335.8, -2899.3}, 181 | {-1457.6, 9335.8, -3273.9}, 182 | {-745.1, 9335.8, -3505.4}, 183 | {799.8, 9659.3, 2461.5}, 184 | {1521.3, 9659.3, 2093.9}, 185 | {-799.8, 9659.3, -2461.5}, 186 | {-1521.3, 9659.3, -2093.9}, 187 | {-2093.9, 9659.3, -1521.3}, 188 | {-2461.5, 9659.3, -799.8}, 189 | {-2588.2, 9659.3, 0.0}, 190 | {-2461.5, 9659.3, 799.8}, 191 | {-2093.9, 9659.3, 1521.3}, 192 | {-1521.3, 9659.3, 2093.9}, 193 | {-799.8, 9659.3, 2461.5}, 194 | {2093.9, 9659.3, 1521.3}, 195 | {163.5, 9876.9, -1555.8}, 196 | {-636.3, 9876.9, 1429.1}, 197 | {-1215.7, 9876.9, 984.5}, 198 | {-1530.2, 9876.9, 325.2}, 199 | {-1511.0, 9876.9, -404.9}, 200 | {-1162.5, 9876.9, -1046.8}, 201 | {-560.6, 9876.9, -1460.4}, 202 | {852.0, 9876.9, -1312.0}, 203 | {1354.8, 9876.9, -782.2}, 204 | {1562.2, 9876.9, -81.9}, 205 | {1429.1, 9876.9, 636.3}, 206 | {984.5, 9876.9, 1215.7}, 207 | {325.2, 9876.9, 1530.2}, 208 | {2461.5, 9659.3, -799.8}, 209 | {2093.9, 9659.3, -1521.3}, 210 | {1521.3, 9659.3, -2093.9}, 211 | {799.8, 9659.3, -2461.5}, 212 | {0.0, 9659.3, -2588.2}, 213 | {0.0, 9335.8, -3583.7}, 214 | {0.0, 8910.1, -4539.9}, 215 | {943.9, 8910.1, -4440.7}, 216 | {745.1, 9335.8, -3505.4}, 217 | {1457.6, 9335.8, -3273.9}, 218 | {1846.5, 8910.1, -4147.4}, 219 | {2668.5, 8910.1, -3672.9}, 220 | {2106.4, 9335.8, -2899.3}, 221 | {2663.2, 9335.8, -2397.9}, 222 | {3373.8, 8910.1, -3037.8}, 223 | {3103.6, 9335.8, -1791.8}, 224 | {3931.7, 8910.1, -2270.0}, 225 | {3408.3, 9335.8, -1107.4}, 226 | {4317.7, 8910.1, -1402.9}, 227 | {3564.0, 9335.8, -374.6}, 228 | {4515.0, 8910.1, -474.6}, 229 | {3564.0, 9335.8, 374.6}, 230 | {4515.0, 8910.1, 474.5}, 231 | {3408.3, 9335.8, 1107.4}, 232 | {4317.7, 8910.1, 1402.9}, 233 | {3103.6, 9335.8, 1791.8}, 234 | {3931.7, 8910.1, 2269.9}, 235 | {2663.2, 9335.8, 2397.9}, 236 | {3373.8, 8910.1, 3037.8}, 237 | {2106.4, 9335.8, 2899.3}, 238 | {2668.5, 8910.1, 3672.9}, 239 | {1457.6, 9335.8, 3273.9}, 240 | {1846.5, 8910.1, 4147.4}, 241 | {745.1, 9335.8, 3505.4}, 242 | {943.9, 8910.1, 4440.7}, 243 | {0.0, 9335.8, 3583.7}, 244 | {0.0, 8910.1, 4539.9}, 245 | {-522.6, 8660.3, 4972.6}, 246 | {522.6, 8660.3, 4972.6}, 247 | {0.0, 8386.7, 5446.4}, 248 | {614.4, 8090.2, 5845.7}, 249 | {-1545.1, 8660.3, 4755.3}, 250 | {-2500.0, 8660.3, 4330.1}, 251 | {-3345.7, 8660.3, 3715.7}, 252 | {-4045.1, 8660.3, 2938.9}, 253 | {-4567.7, 8660.3, 2033.7}, 254 | {-4890.7, 8660.3, 1039.5}, 255 | {-5000.0, 8660.3, 0.0}, 256 | {-4890.7, 8660.3, -1039.6}, 257 | {-4567.7, 8660.3, -2033.7}, 258 | {-4045.1, 8660.3, -2939.0}, 259 | {-3345.6, 8660.3, -3715.8}, 260 | {-2500.0, 8660.3, -4330.2}, 261 | {-1545.0, 8660.3, -4755.3}, 262 | {-522.6, 8660.3, -4972.6}, 263 | {522.6, 8660.3, -4972.6}, 264 | {1545.1, 8660.3, -4755.3}, 265 | {2500.0, 8660.3, -4330.1}, 266 | {3345.7, 8660.3, -3715.7}, 267 | {4045.1, 8660.3, -2938.9}, 268 | {4567.7, 8660.3, -2033.7}, 269 | {4890.7, 8660.3, -1039.6}, 270 | {5000.0, 8660.3, 0.0}, 271 | {4890.7, 8660.3, 1039.6}, 272 | {4567.7, 8660.3, 2033.7}, 273 | {4045.1, 8660.3, 2938.9}, 274 | {3345.7, 8660.3, 3715.7}, 275 | {2500.0, 8660.3, 4330.1}, 276 | {1545.1, 8660.3, 4755.3}, 277 | {1132.4, 8386.7, 5327.4}, 278 | {1816.4, 8090.2, 5590.2}, 279 | {2215.2, 8386.7, 4975.5}, 280 | {3201.3, 8386.7, 4406.2}, 281 | {2938.9, 8090.2, 5090.4}, 282 | {2559.7, 7771.5, 5749.1}, 283 | {1308.4, 7771.5, 6155.7}, 284 | {0.0, 7771.5, 6293.2}, 285 | {-614.4, 8090.2, 5845.7}, 286 | {-1132.4, 8386.7, 5327.4}, 287 | {-1816.4, 8090.2, 5590.2}, 288 | {-1308.4, 7771.5, 6155.7}, 289 | {-699.4, 7431.4, 6654.7}, 290 | {-2067.7, 7431.4, 6363.8}, 291 | {-2559.7, 7771.5, 5749.1}, 292 | {-2215.3, 8386.7, 4975.5}, 293 | {-3345.7, 7431.4, 5794.8}, 294 | {-2938.9, 8090.2, 5090.4}, 295 | {-3201.3, 8386.7, 4406.2}, 296 | {-3699.1, 7771.5, 5091.3}, 297 | {-4477.4, 7431.4, 4972.6}, 298 | {-3933.1, 8090.2, 4368.1}, 299 | {-4047.5, 8386.7, 3644.3}, 300 | {-4676.8, 7771.5, 4211.0}, 301 | {-5413.4, 7431.4, 3933.0}, 302 | {-4755.3, 8090.2, 3454.9}, 303 | {-4716.7, 8386.7, 2723.2}, 304 | {-5450.1, 7771.5, 3146.6}, 305 | {-6112.8, 7431.4, 2721.6}, 306 | {-5369.7, 8090.2, 2390.7}, 307 | {-5179.8, 8386.7, 1683.0}, 308 | {-5985.2, 7771.5, 1944.7}, 309 | {-6545.1, 7431.4, 1391.2}, 310 | {-5749.4, 8090.2, 1222.0}, 311 | {-5416.6, 8386.7, 569.3}, 312 | {-6258.7, 7771.5, 657.8}, 313 | {-6691.3, 7431.4, 0.0}, 314 | {-5877.9, 8090.2, 0.0}, 315 | {-5416.6, 8386.7, -569.3}, 316 | {-6258.7, 7771.5, -657.9}, 317 | {-6545.1, 7431.4, -1391.2}, 318 | {-5749.4, 8090.2, -1222.1}, 319 | {-5179.8, 8386.7, -1683.1}, 320 | {-5985.2, 7771.5, -1944.8}, 321 | {-6112.8, 7431.4, -2721.6}, 322 | {-5369.7, 8090.2, -2390.8}, 323 | {-4716.7, 8386.7, -2723.2}, 324 | {-5450.0, 7771.5, -3146.6}, 325 | {-5413.3, 7431.4, -3933.1}, 326 | {-4755.3, 8090.2, -3455.0}, 327 | {-4047.4, 8386.7, -3644.4}, 328 | {-4676.7, 7771.5, -4211.0}, 329 | {-4477.3, 7431.4, -4972.7}, 330 | {-3933.0, 8090.2, -4368.1}, 331 | {-3201.3, 8386.7, -4406.3}, 332 | {-3699.0, 7771.5, -5091.3}, 333 | {-3345.6, 7431.4, -5794.9}, 334 | {-2938.9, 8090.2, -5090.4}, 335 | {-2215.2, 8386.7, -4975.5}, 336 | {-2559.6, 7771.5, -5749.2}, 337 | {-2067.7, 7431.4, -6363.8}, 338 | {-1816.3, 8090.2, -5590.2}, 339 | {-1132.3, 8386.7, -5327.4}, 340 | {-1308.4, 7771.5, -6155.7}, 341 | {-699.4, 7431.4, -6654.7}, 342 | {-614.3, 8090.2, -5845.7}, 343 | {0.0, 8386.7, -5446.4}, 344 | {0.0, 7771.5, -6293.2}, 345 | {699.4, 7431.4, -6654.7}, 346 | {614.4, 8090.2, -5845.7}, 347 | {1132.4, 8386.7, -5327.4}, 348 | {1308.4, 7771.5, -6155.7}, 349 | {2067.7, 7431.4, -6363.8}, 350 | {1816.4, 8090.2, -5590.2}, 351 | {2215.2, 8386.7, -4975.5}, 352 | {2559.7, 7771.5, -5749.1}, 353 | {3345.7, 7431.4, -5794.8}, 354 | {2938.9, 8090.2, -5090.4}, 355 | {3201.3, 8386.7, -4406.2}, 356 | {3699.1, 7771.5, -5091.3}, 357 | {4477.4, 7431.4, -4972.6}, 358 | {3933.1, 8090.2, -4368.1}, 359 | {4047.5, 8386.7, -3644.3}, 360 | {4676.8, 7771.5, -4211.0}, 361 | {5413.4, 7431.4, -3933.1}, 362 | {4755.3, 8090.2, -3454.9}, 363 | {4716.7, 8386.7, -2723.2}, 364 | {5450.1, 7771.5, -3146.6}, 365 | {6112.8, 7431.4, -2721.6}, 366 | {5369.7, 8090.2, -2390.7}, 367 | {5179.8, 8386.7, -1683.0}, 368 | {5985.2, 7771.5, -1944.7}, 369 | {6545.1, 7431.4, -1391.2}, 370 | {5749.4, 8090.2, -1222.1}, 371 | {5416.6, 8386.7, -569.3}, 372 | {6258.7, 7771.5, -657.8}, 373 | {6691.3, 7431.4, 0.0}, 374 | {5877.9, 8090.2, 0.0}, 375 | {5416.6, 8386.7, 569.3}, 376 | {6258.7, 7771.5, 657.8}, 377 | {6545.1, 7431.4, 1391.2}, 378 | {5749.4, 8090.2, 1222.1}, 379 | {5179.8, 8386.7, 1683.0}, 380 | {5985.2, 7771.5, 1944.7}, 381 | {6112.8, 7431.4, 2721.6}, 382 | {5369.7, 8090.2, 2390.7}, 383 | {4716.7, 8386.7, 2723.2}, 384 | {5450.1, 7771.5, 3146.6}, 385 | {5413.4, 7431.4, 3933.0}, 386 | {4755.3, 8090.2, 3454.9}, 387 | {4047.5, 8386.7, 3644.3}, 388 | {4676.8, 7771.5, 4211.0}, 389 | {4477.4, 7431.4, 4972.6}, 390 | {3933.1, 8090.2, 4368.1}, 391 | {3699.1, 7771.5, 5091.3}, 392 | {3345.7, 7431.4, 5794.8}, 393 | {2067.7, 7431.4, 6363.8}, 394 | {699.4, 7431.4, 6654.7}, 395 | }; 396 | public static void preparedraw() 397 | { 398 | nodepos.Add(new Vector3(0, 0, 1)); 399 | nodepos.Add(new Vector3(0, 0, -1)); 400 | nodepos.Add(new Vector3(1, 0, 0)); 401 | nodepos.Add(new Vector3(-1, 0, 0)); 402 | for (int j = 0; j < 7; j++) 403 | { 404 | Vector3 pos1 = new Vector3((float)dysonposxyz1[j, 0], (float)dysonposxyz1[j, 1], 0) / 10000; 405 | Vector3 pos3 = new Vector3((float)dysonposxyz1[j, 0], -(float)dysonposxyz1[j, 1], 0) / 10000; 406 | Vector3 pos2 = new Vector3(-(float)dysonposxyz1[j, 0], (float)dysonposxyz1[j, 1], 0) / 10000; 407 | Vector3 pos4 = new Vector3(-(float)dysonposxyz1[j, 0], -(float)dysonposxyz1[j, 1], 0) / 10000; 408 | nodepos.Add(pos1); 409 | nodepos.Add(pos2); 410 | nodepos.Add(pos3); 411 | nodepos.Add(pos4); 412 | } 413 | for (int j = 0; j < 7; j++) 414 | { 415 | Vector3 pos1 = new Vector3(0, (float)dysonposxyz1[j, 1], (float)dysonposxyz1[j, 0]) / 10000; 416 | Vector3 pos2 = new Vector3(0, (float)dysonposxyz1[j, 1], -(float)dysonposxyz1[j, 0]) / 10000; 417 | Vector3 pos3 = new Vector3(0, -(float)dysonposxyz1[j, 1], (float)dysonposxyz1[j, 0]) / 10000; 418 | Vector3 pos4 = new Vector3(0, -(float)dysonposxyz1[j, 1], -(float)dysonposxyz1[j, 0]) / 10000; 419 | nodepos.Add(pos1); 420 | nodepos.Add(pos2); 421 | nodepos.Add(pos3); 422 | nodepos.Add(pos4); 423 | } 424 | for (int j = 0; j < 14; j++) 425 | { 426 | Vector3 pos1 = new Vector3((float)dysonposxyz2[j, 0], (float)dysonposxyz2[j, 1], (float)dysonposxyz2[j, 2]) / 10000; 427 | Vector3 pos2 = new Vector3(-(float)dysonposxyz2[j, 0], (float)dysonposxyz2[j, 1], (float)dysonposxyz2[j, 2]) / 10000; 428 | nodepos.Add(pos1); 429 | nodepos.Add(pos2); 430 | } 431 | for (int j = 0; j < 14; j++) 432 | { 433 | Vector3 pos1 = new Vector3(-(float)dysonposxyz2[j, 0], (float)dysonposxyz2[j, 1], -(float)dysonposxyz2[j, 2]) / 10000; 434 | Vector3 pos2 = new Vector3((float)dysonposxyz2[j, 0], (float)dysonposxyz2[j, 1], -(float)dysonposxyz2[j, 2]) / 10000; 435 | nodepos.Add(pos1); 436 | nodepos.Add(pos2); 437 | } 438 | int[,] temp = new int[8, 3] { { 1, 1, 1 }, { 1, 1, -1 }, { 1, -1, 1 }, { 1, -1, -1 }, { -1, 1, 1 }, { -1, 1, -1 }, { -1, -1, 1 }, { -1, -1, -1 } }; 439 | for (int i = 0; i < 8; i++) 440 | { 441 | for (int j = 0; j < 98; j++) 442 | { 443 | Vector3 pos = new Vector3((float)dysonposxyz3[j, 0] * temp[i, 0], (float)dysonposxyz3[j, 1] * temp[i, 1], (float)dysonposxyz3[j, 2] * temp[i, 2]) / 11000; 444 | 445 | nodepos.Add(pos); 446 | } 447 | } 448 | for (int j = 0; j < 244; j++) 449 | { 450 | Vector3 pos1 = new Vector3((float)dysonposxyz4[j, 0], (float)dysonposxyz4[j, 1], (float)dysonposxyz4[j, 2]) / 10000; 451 | Vector3 pos2 = new Vector3((float)dysonposxyz4[j, 0], -(float)dysonposxyz4[j, 1], (float)dysonposxyz4[j, 2]) / 10000; 452 | nodepos.Add(pos1); 453 | nodepos.Add(pos2); 454 | } 455 | 456 | 457 | } 458 | 459 | } 460 | } 461 | -------------------------------------------------------------------------------- /Multifunction_mod/Patchs/CargoTrafficPatch.cs: -------------------------------------------------------------------------------- 1 | using HarmonyLib; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using static Multifunction_mod.Multifunction; 6 | 7 | namespace Multifunction_mod.Patchs 8 | { 9 | public class CargoTrafficPatch 10 | { 11 | [HarmonyPostfix] 12 | [HarmonyPatch(typeof(CargoTraffic), "SetBeltSignalIcon")] 13 | public static void SetBeltSignalIconPatch(int signalId, int entityId, CargoTraffic __instance) 14 | { 15 | if (!BeltSignalFunction.Value) return; 16 | int factoryIndex = __instance.factory.index; 17 | int beltid = __instance.factory.entityPool[entityId].beltId; 18 | if (!Beltsignal.ContainsKey(factoryIndex)) 19 | Beltsignal.Add(factoryIndex, new Dictionary()); 20 | if (!Beltsignal[factoryIndex].ContainsKey(beltid)) 21 | Beltsignal[factoryIndex].Add(beltid, signalId); 22 | else 23 | Beltsignal[factoryIndex][beltid] = signalId; 24 | if (Beltsignalnumberoutput.ContainsKey(factoryIndex) && Beltsignalnumberoutput[factoryIndex].ContainsKey(beltid) && signalId != 601) 25 | { 26 | Beltsignalnumberoutput[factoryIndex].Remove(beltid); 27 | } 28 | } 29 | 30 | [HarmonyPostfix] 31 | [HarmonyPatch(typeof(CargoTraffic), "SetBeltSignalNumber")] 32 | public static void SetBeltSignalNumberPatch(float number, int entityId, CargoTraffic __instance) 33 | { 34 | if (!BeltSignalFunction.Value) return; 35 | if (__instance.factory.entitySignPool[entityId].iconType != 0U && __instance.factory.entitySignPool[entityId].iconId0 != 0U) 36 | { 37 | int factoryIndex = __instance.factory.index; 38 | int beltid = __instance.factory.entityPool[entityId].beltId; 39 | if (__instance.factory.entitySignPool[entityId].iconId0 == 600) { } 40 | else if (__instance.factory.entitySignPool[entityId].iconId0 == 601) 41 | { 42 | if (!Beltsignalnumberoutput.ContainsKey(factoryIndex)) 43 | { 44 | Beltsignalnumberoutput.Add(factoryIndex, new Dictionary()); 45 | } 46 | if (!Beltsignalnumberoutput[factoryIndex].ContainsKey(beltid)) 47 | Beltsignalnumberoutput[factoryIndex].Add(beltid, (int)number); 48 | else 49 | Beltsignalnumberoutput[factoryIndex][beltid] = (int)number; 50 | } 51 | else 52 | { 53 | if (Beltsignalnumberoutput.ContainsKey(factoryIndex) && Beltsignalnumberoutput[factoryIndex].ContainsKey(beltid)) 54 | { 55 | Beltsignalnumberoutput[factoryIndex][beltid] = (int)number; 56 | } 57 | } 58 | } 59 | } 60 | 61 | [HarmonyPrefix] 62 | [HarmonyPatch(typeof(CargoTraffic), "TryPickItemAtRear")] 63 | public static void Prefix(ref int[] needs) 64 | { 65 | if (!Tankcontentall.Value || needs == null) 66 | { 67 | return; 68 | } 69 | if (ItemProto.fluids == needs) 70 | needs = null; 71 | } 72 | 73 | [HarmonyPrefix] 74 | [HarmonyPatch(typeof(CargoTraffic), "RemoveBeltComponent")] 75 | public static void Prefix(CargoTraffic __instance, int id) 76 | { 77 | if (!BeltSignalFunction.Value) return; 78 | int factoryIndex = __instance.factory.index; 79 | if (Beltsignal.ContainsKey(factoryIndex) && Beltsignal[factoryIndex].ContainsKey(id)) 80 | Beltsignal[factoryIndex].Remove(id); 81 | if (Beltsignalnumberoutput.ContainsKey(factoryIndex) && Beltsignalnumberoutput[factoryIndex].ContainsKey(id)) 82 | Beltsignalnumberoutput[factoryIndex].Remove(id); 83 | } 84 | 85 | [HarmonyPrefix] 86 | [HarmonyPatch(typeof(CargoTraffic), "SplitterGameTick")] 87 | public static void CargoTrafficSplitterGameTickPatch(CargoTraffic __instance) 88 | { 89 | CargoSignalFunction(__instance); 90 | } 91 | 92 | [HarmonyPostfix] 93 | [HarmonyPatch(typeof(GameMain), "FixedUpdate")] 94 | public static void CargoTrafficGameTickPatch() 95 | { 96 | if (!GameMain.isPaused) 97 | { 98 | for (int i = 0; i < GameMain.data.factoryCount; i++) 99 | { 100 | CargoSignalFunction(GameMain.data.factories[i].cargoTraffic); 101 | } 102 | } 103 | } 104 | 105 | public static void CargoSignalFunction(CargoTraffic __instance) 106 | { 107 | if (!BeltSignalFunction.Value || !FinallyInit) return; 108 | int factoryIndex = __instance.factory.index; 109 | if (!Beltsignal.ContainsKey(factoryIndex)) return; 110 | FactorySystem fs = __instance.factory.factorySystem; 111 | foreach (KeyValuePair wap2 in Beltsignal[factoryIndex]) 112 | { 113 | int signalID = wap2.Value; 114 | if (signalID == 404) 115 | { 116 | __instance.TryPickItem(wap2.Key, 0, 0, out _, out _); 117 | } 118 | else if (1000 <= signalID && signalID < 20000) 119 | { 120 | int outputbeltID = wap2.Key; 121 | var belt = fs.traffic.beltPool[outputbeltID]; 122 | int index = belt.segIndex + belt.segPivotOffset; 123 | int beltnumber = (int)fs.factory.entitySignPool[fs.traffic.beltPool[outputbeltID].entityId].count0; 124 | if (beltnumber == 999999) 125 | { 126 | __instance.TryInsertItem(outputbeltID, 0, signalID, 1, 0); 127 | } 128 | else if (beltnumber > 999900 && beltnumber % 10 != 0) 129 | { 130 | int t = beltnumber % 100; 131 | int stack1 = t % 10; 132 | int inc1 = ((t / 10 >= 3 ? 4 : t / 10)) * stack1; 133 | __instance.TryInsertItem(outputbeltID, 0, signalID, (byte)stack1, (byte)inc1); 134 | } 135 | else if (beltnumber >= 11 && beltnumber <= 14) 136 | { 137 | bool breakfor = false; 138 | int stackNum = beltnumber % 10; 139 | CargoPath cargoPath = __instance.GetCargoPath(belt.segPathId); 140 | cargoPath.GetCargoAtIndex(index, out Cargo cargo, out _, out _); 141 | if (cargo.item > 0) 142 | { 143 | continue; 144 | } 145 | if (fs.factory.transport?.stationPool != null) 146 | { 147 | foreach (StationComponent sc in fs.factory.transport.stationPool) 148 | { 149 | if (breakfor) break; 150 | if (sc == null || sc.storage == null) 151 | { 152 | continue; 153 | } 154 | for (int i = 0; i < sc.storage.Length; i++) 155 | { 156 | if (sc.storage[i].itemId != signalID) 157 | { 158 | continue; 159 | } 160 | if (sc.storage[i].count < stackNum) 161 | break; 162 | int inc1 = Math.Min(sc.storage[i].inc, 4 * stackNum); 163 | if (cargoPath.TryInsertItem(index, signalID, (byte)stackNum, (byte)inc1)) 164 | { 165 | sc.storage[i].count -= stackNum; 166 | sc.storage[i].inc -= inc1; 167 | } 168 | breakfor = true; 169 | } 170 | } 171 | } 172 | if (breakfor) continue; 173 | if (fs.factory.factoryStorage != null) 174 | { 175 | var storagePool = fs.factory.factoryStorage.storagePool; 176 | if (storagePool != null) 177 | { 178 | foreach (StorageComponent sc in storagePool) 179 | { 180 | if (breakfor) break; 181 | if (sc == null || sc.isEmpty || sc.GetItemCount(signalID) < stackNum) 182 | { 183 | continue; 184 | } 185 | sc.TakeItem(signalID, stackNum, out int inc1); 186 | if (!cargoPath.TryInsertItem(index, signalID, (byte)stackNum, (byte)inc1)) 187 | { 188 | sc.AddItem(signalID, stackNum, inc1, out _); 189 | } 190 | breakfor = true; 191 | break; 192 | } 193 | } 194 | if (breakfor) continue; 195 | var tankPool = fs.factory.factoryStorage.tankPool; 196 | if (tankPool != null) 197 | { 198 | foreach (TankComponent tc in tankPool) 199 | { 200 | if (breakfor) break; 201 | if (tc.fluidId != signalID || tc.id <= 0 || tc.fluidCount < stackNum) 202 | { 203 | continue; 204 | } 205 | int inc1 = Math.Min(tc.fluidInc, stackNum * 4); 206 | if (cargoPath.TryInsertItem(index, signalID, (byte)stackNum, (byte)inc1)) 207 | { 208 | fs.factory.factoryStorage.tankPool[tc.id].fluidInc -= inc1; 209 | fs.factory.factoryStorage.tankPool[tc.id].fluidCount -= stackNum; 210 | } 211 | breakfor = true; 212 | break; 213 | } 214 | } 215 | } 216 | } 217 | else if (beltnumber >= 21 && beltnumber <= 24 && fs.minerPool != null) 218 | { 219 | int statckNum = beltnumber % 20; 220 | var cargoPath = __instance.GetCargoPath(belt.segPathId); 221 | cargoPath.GetCargoAtIndex(index, out Cargo cargo, out _, out _); 222 | if (cargo.item > 0) 223 | { 224 | continue; 225 | } 226 | foreach (MinerComponent mc in fs.minerPool) 227 | { 228 | if (mc.id > 0 && mc.entityId > 0 && mc.productId == signalID && mc.productCount >= statckNum) 229 | { 230 | fs.minerPool[mc.id].productCount -= cargoPath.TryInsertItem(index, signalID, (byte)statckNum, 0) ? statckNum : 0; 231 | break; 232 | } 233 | } 234 | } 235 | 236 | } 237 | else if (signalID == 405) 238 | { 239 | BeltComponent belt = fs.traffic.beltPool[wap2.Key]; 240 | CargoPath cargoPath = __instance.GetCargoPath(belt.segPathId); 241 | byte stack; 242 | byte inc; 243 | int num1 = belt.segIndex + belt.segPivotOffset; 244 | cargoPath.GetCargoAtIndex(num1, out Cargo cargo, out _, out _); 245 | int itemid = cargo.item; 246 | if (itemid < 1000) continue; 247 | bool breakfor; 248 | switch (fs.factory.entitySignPool[belt.entityId].count0) 249 | { 250 | case 1: 251 | if (itemid != 1006 && itemid != 1007 && itemid != 1011 && itemid != 1109 && itemid != 1114 && itemid != 1120 && itemid != 1801 && itemid != 1802) continue; 252 | var genPool = fs.factory.powerSystem?.genPool; 253 | if (genPool == null) continue; 254 | foreach (PowerGeneratorComponent pgc in genPool) 255 | { 256 | if (pgc.id <= 0 || pgc.fuelCount > 2) 257 | { 258 | continue; 259 | } 260 | if (pgc.fuelMask == 1 && itemid != 1802) 261 | { 262 | if (itemid == genPool[pgc.id].fuelId) 263 | { 264 | cargoPath.TryPickItem(num1 - 5, 12, out stack, out inc); 265 | genPool[pgc.id].SetNewFuel(itemid, (short)(genPool[pgc.id].fuelCount + stack), inc); 266 | break; 267 | } 268 | else if (pgc.fuelCount == 0) 269 | { 270 | cargoPath.TryPickItem(num1 - 5, 12, out stack, out inc); 271 | genPool[pgc.id].SetNewFuel(itemid, (short)(genPool[pgc.id].fuelCount + stack), inc); 272 | break; 273 | } 274 | } 275 | if (pgc.fuelMask == 2 && itemid == 1802) 276 | { 277 | cargoPath.TryPickItem(num1 - 5, 12, out stack, out inc); 278 | genPool[pgc.id].SetNewFuel(1802, (short)(genPool[pgc.id].fuelCount + stack), inc); 279 | break; 280 | } 281 | } 282 | break; 283 | case 5: 284 | if (fs.assemblerPool == null) continue; 285 | breakfor = false; 286 | foreach (AssemblerComponent ac in fs.assemblerPool) 287 | { 288 | if (breakfor) break; 289 | if (ac.id <= 0 || ac.entityId <= 0 || ac.recipeId <= 0) 290 | { 291 | continue; 292 | } 293 | for (int i = 0; i < ac.served.Length; i++) 294 | { 295 | if (itemid != ac.requires[i]) continue; 296 | if (ac.served[i] < 0) 297 | { 298 | ac.served[i] = 0; 299 | continue; 300 | } 301 | if (ac.served[i] <= ac.requireCounts[i] * 2) 302 | { 303 | var itemId = cargoPath.TryPickItem(num1 - 5, 12, out stack, out inc); 304 | if (itemId == 0) return; 305 | ac.served[i] += stack; 306 | ac.incServed[i] += inc; 307 | breakfor = true; 308 | break; 309 | } 310 | } 311 | } 312 | break; 313 | case 6: 314 | if (fs.factory.transport == null || fs.factory.transport.stationPool == null) continue; 315 | breakfor = false; 316 | foreach (StationComponent sc in fs.factory.transport.stationPool) 317 | { 318 | if (sc == null || sc.storage == null) 319 | { 320 | continue; 321 | } 322 | for (int i = 0; i < sc.storage.Length; i++) 323 | { 324 | if (sc.storage[i].itemId != itemid || sc.storage[i].count >= sc.storage[i].max) continue; 325 | cargoPath.TryPickItem(num1 - 5, 12, out stack, out inc); 326 | sc.AddItem(itemid, stack, inc); 327 | breakfor = true; 328 | break; 329 | } 330 | if (breakfor) break; 331 | } 332 | break; 333 | case 8: 334 | if (fs.labPool == null) continue; 335 | breakfor = false; 336 | foreach (LabComponent lc in fs.labPool) 337 | { 338 | if (breakfor) break; 339 | if (lc.id <= 0 || lc.entityId <= 0) 340 | { 341 | continue; 342 | } 343 | if (lc.researchMode) 344 | { 345 | if (itemid < 6001 || itemid > 6006) continue; 346 | for (int i = 0; i < lc.matrixPoints.Length; i++) 347 | { 348 | if (itemid != 6001 + i) continue; 349 | if (lc.matrixServed[i] <= 36000) 350 | { 351 | int itemId = cargoPath.TryPickItem(num1 - 5, 12, out stack, out inc); 352 | if (itemId == 0) return; 353 | lc.matrixServed[i] += 3600 * stack; 354 | lc.matrixIncServed[i] += inc; 355 | break; 356 | } 357 | } 358 | } 359 | else if (lc.matrixMode) 360 | { 361 | for (int i = 0; i < lc.served.Length; i++) 362 | { 363 | if (itemid != lc.requires[i]) continue; 364 | if (lc.served[i] <= lc.requireCounts[i] * 2) 365 | { 366 | int itemId = cargoPath.TryPickItem(num1 - 5, 12, out stack, out inc); 367 | if (itemId == 0) return; 368 | lc.served[i] += stack; 369 | lc.incServed[i] += inc; 370 | break; 371 | } 372 | } 373 | } 374 | } 375 | 376 | if (itemid != 1503 && itemid != 1501 && itemid != 1209 && itemid != 1803 && itemid != 1804) continue; 377 | if (itemid == 1209 || itemid == 1803 || itemid == 1804) 378 | { 379 | if (fs.factory.powerSystem == null || fs.factory.powerSystem.genPool == null) continue; 380 | foreach (PowerGeneratorComponent pgc in fs.factory.powerSystem.genPool) 381 | { 382 | if (pgc.id <= 0) 383 | { 384 | continue; 385 | } 386 | if (pgc.gamma) 387 | { 388 | if (itemid != 1209) continue; 389 | if (pgc.catalystPoint == 0) 390 | { 391 | int itemId = cargoPath.TryPickItem(num1 - 5, 12, out stack, out inc); 392 | if (itemId == 0) return; 393 | fs.factory.powerSystem.genPool[pgc.id].catalystPoint += 3600 * stack; 394 | fs.factory.powerSystem.genPool[pgc.id].catalystIncPoint += 3600 * inc; 395 | breakfor = true; 396 | break; 397 | } 398 | 399 | } 400 | else if (pgc.fuelMask == 4 && (itemid == 1803 || itemid == 1804) && pgc.fuelCount <= 2) 401 | { 402 | if (itemid != 1803 && itemid != 1804) continue; 403 | int itemId = cargoPath.TryPickItem(num1 - 5, 12, out stack, out inc); 404 | if (itemId == 0) return; 405 | fs.factory.powerSystem.genPool[pgc.id].SetNewFuel(itemid, (short)(fs.factory.powerSystem.genPool[pgc.id].fuelCount + stack), inc); 406 | breakfor = true; 407 | break; 408 | } 409 | } 410 | } 411 | else if (itemid == 1503) 412 | { 413 | if (fs.siloPool == null) continue; 414 | foreach (SiloComponent sc in fs.siloPool) 415 | { 416 | if (sc.id <= 0 || sc.entityId <= 0 || sc.bulletCount > 1) 417 | { 418 | continue; 419 | } 420 | cargoPath.TryPickItem(num1 - 5, 12, out stack, out inc); 421 | fs.siloPool[sc.id].bulletCount += stack; 422 | fs.siloPool[sc.id].bulletInc += inc; 423 | break; 424 | } 425 | } 426 | else if (itemid == 1501) 427 | { 428 | if (fs.ejectorPool == null) continue; 429 | foreach (EjectorComponent ec in fs.ejectorPool) 430 | { 431 | if (ec.id <= 0 || ec.entityId <= 0 || ec.bulletCount > 1) 432 | { 433 | continue; 434 | } 435 | cargoPath.TryPickItem(num1 - 5, 12, out stack, out inc); 436 | fs.ejectorPool[ec.id].bulletCount += stack; 437 | fs.ejectorPool[ec.id].bulletInc += inc; 438 | break; 439 | } 440 | } 441 | break; 442 | case 9: 443 | break; 444 | } 445 | } 446 | else if (signalID == 600 && Beltsignalnumberoutput.ContainsKey(factoryIndex)) 447 | { 448 | int index = (int)fs.factory.entitySignPool[fs.traffic.beltPool[wap2.Key].entityId].count0; 449 | var outputbeltID = Beltsignalnumberoutput[factoryIndex].FirstOrDefault(x => x.Value == index).Key; 450 | if (index <= 0 || outputbeltID <= 0) 451 | { 452 | continue; 453 | } 454 | int itemId = __instance.TryPickItem(wap2.Key, 0, 0, out byte stack, out byte inc); 455 | if (itemId < 1000) continue; 456 | if (!__instance.TryInsertItem(outputbeltID, 0, itemId, stack, inc)) 457 | { 458 | __instance.TryInsertItem(wap2.Key, 0, itemId, stack, inc); 459 | } 460 | } 461 | } 462 | } 463 | } 464 | } 465 | -------------------------------------------------------------------------------- /Multifunction_mod/Models/PropertyData.cs: -------------------------------------------------------------------------------- 1 | namespace Multifunction_mod.Models 2 | { 3 | public class PropertyData 4 | { 5 | private float walkSpeed; 6 | private float techSpeed; 7 | private float droneSpeed; 8 | private float droneMovement; 9 | private float droneCount; 10 | private float maxSailSpeed; 11 | private float maxWarpSpeed; 12 | private float buildArea; 13 | private float reactorPowerGen; 14 | private float logisticCourierSpeed; 15 | private float logisticDroneSpeedScale; 16 | private float logisticShipSpeedScale; 17 | private float logisticCourierCarries; 18 | private float logisticDroneCarries; 19 | private float logisticShipCarries; 20 | private float miningCostRate; 21 | private float miningSpeedScale; 22 | private float labLevel; 23 | private float storageLevel; 24 | private float stackSizeMultiplier; 25 | 26 | /// 27 | /// 走路速度 28 | /// 29 | public float WalkSpeed 30 | { 31 | get 32 | { 33 | return walkSpeed; 34 | } 35 | 36 | set 37 | { 38 | if (value == 0 || value == walkSpeed) return; 39 | walkSpeed = value; 40 | if (!CheckCondition()) return; 41 | GameMain.mainPlayer.mecha.walkSpeed = value; 42 | } 43 | } 44 | 45 | /// 46 | /// 研发速度 47 | /// 48 | public float TechSpeed 49 | { 50 | get 51 | { 52 | return techSpeed; 53 | } 54 | 55 | set 56 | { 57 | if (value == 0 || value == techSpeed) return; 58 | techSpeed = value; 59 | if (!CheckCondition()) return; 60 | GameMain.history.techSpeed = (int)value; 61 | } 62 | } 63 | 64 | /// 65 | /// 小飞机速度 66 | /// 67 | public float DroneSpeed 68 | { 69 | get 70 | { 71 | return droneSpeed; 72 | } 73 | 74 | set 75 | { 76 | if (value == 0 || value == droneSpeed) return; 77 | droneSpeed = value; 78 | if (!CheckCondition()) return; 79 | GameMain.history.constructionDroneSpeed = value; 80 | } 81 | } 82 | 83 | /// 84 | /// 小飞机数量 85 | /// 86 | public float DroneCount 87 | { 88 | get 89 | { 90 | return droneCount; 91 | } 92 | 93 | set 94 | { 95 | if (value == 0 || value == droneCount) return; 96 | droneCount = value; 97 | if (!CheckCondition()) return; 98 | int changedvalue = (int)(value - GameMain.mainPlayer.mecha.constructionModule.droneCount); 99 | GameMain.mainPlayer.mecha.constructionModule.droneCount += changedvalue; 100 | GameMain.mainPlayer.mecha.constructionModule.droneAliveCount += changedvalue; 101 | GameMain.mainPlayer.mecha.constructionModule.droneIdleCount += changedvalue; 102 | } 103 | } 104 | 105 | /// 106 | /// 最大航行速度 107 | /// 108 | public float MaxSailSpeed 109 | { 110 | get 111 | { 112 | return maxSailSpeed; 113 | } 114 | 115 | set 116 | { 117 | if (value == 0 || value == maxSailSpeed) return; 118 | maxSailSpeed = value; 119 | if (!CheckCondition()) return; 120 | GameMain.mainPlayer.mecha.maxSailSpeed = (int)value * 1000; 121 | } 122 | } 123 | 124 | /// 125 | /// 最大曲速 126 | /// 127 | public float MaxWarpSpeed 128 | { 129 | get 130 | { 131 | return maxWarpSpeed; 132 | } 133 | 134 | set 135 | { 136 | if (value == 0 || value == maxWarpSpeed) return; 137 | maxWarpSpeed = value; 138 | if (!CheckCondition()) return; 139 | GameMain.mainPlayer.mecha.maxWarpSpeed = (int)value * 1000 * 480; 140 | } 141 | } 142 | 143 | /// 144 | /// 建造范围 145 | /// 146 | public float BuildArea 147 | { 148 | get 149 | { 150 | return buildArea; 151 | } 152 | 153 | set 154 | { 155 | if (value == 0 || value == buildArea) return; 156 | buildArea = value; 157 | if (!CheckCondition()) return; 158 | GameMain.mainPlayer.mecha.buildArea = value; 159 | } 160 | } 161 | 162 | /// 163 | /// 核心功率 164 | /// 165 | public float ReactorPowerGen 166 | { 167 | get 168 | { 169 | return reactorPowerGen; 170 | } 171 | 172 | set 173 | { 174 | if (value == 0 || value == reactorPowerGen) return; 175 | reactorPowerGen = value; 176 | if (!CheckCondition()) return; 177 | GameMain.mainPlayer.mecha.reactorPowerGen = value; 178 | } 179 | } 180 | 181 | /// 182 | /// 配送机速度 183 | /// 184 | public float LogisticCourierSpeed 185 | { 186 | get 187 | { 188 | return logisticCourierSpeed; 189 | } 190 | 191 | set 192 | { 193 | if (value == 0 || value == logisticCourierSpeed) return; 194 | logisticCourierSpeed = value; 195 | if (!CheckCondition()) return; 196 | GameMain.history.logisticCourierSpeed = (int)value; 197 | } 198 | } 199 | 200 | /// 201 | /// 运输机速度 202 | /// 203 | public float LogisticDroneSpeedScale 204 | { 205 | get 206 | { 207 | return logisticDroneSpeedScale; 208 | } 209 | 210 | set 211 | { 212 | if (value == 0 || value == logisticDroneSpeedScale) return; 213 | logisticDroneSpeedScale = value; 214 | if (!CheckCondition()) return; 215 | GameMain.history.logisticDroneSpeedScale = value; 216 | } 217 | } 218 | 219 | /// 220 | /// 运输船速度 221 | /// 222 | public float LogisticShipSpeedScale 223 | { 224 | get 225 | { 226 | return logisticShipSpeedScale; 227 | } 228 | 229 | set 230 | { 231 | if (value == 0 || value == logisticShipSpeedScale) return; 232 | logisticShipSpeedScale = value; 233 | if (!CheckCondition()) return; 234 | GameMain.history.logisticShipSpeedScale = value; 235 | } 236 | } 237 | 238 | /// 239 | /// 配送机载量 240 | /// 241 | public float LogisticCourierCarries 242 | { 243 | get 244 | { 245 | return logisticCourierCarries; 246 | } 247 | 248 | set 249 | { 250 | if (value == 0 || value == logisticCourierCarries) return; 251 | logisticCourierCarries = value; 252 | if (!CheckCondition()) return; 253 | GameMain.history.logisticCourierCarries = (int)value; 254 | } 255 | } 256 | 257 | /// 258 | /// 运输机载量 259 | /// 260 | public float LogisticDroneCarries 261 | { 262 | get 263 | { 264 | return logisticDroneCarries; 265 | } 266 | 267 | set 268 | { 269 | if (value == 0 || value == logisticDroneCarries) return; 270 | logisticDroneCarries = (int)(value / 50) * 50; 271 | if (!CheckCondition()) return; 272 | GameMain.history.logisticDroneCarries = (int)value; 273 | } 274 | } 275 | 276 | /// 277 | /// 运输船载量 278 | /// 279 | public float LogisticShipCarries 280 | { 281 | get 282 | { 283 | return logisticShipCarries; 284 | } 285 | 286 | set 287 | { 288 | if (value == 0 || value == logisticShipCarries) return; 289 | logisticShipCarries = (int)(value / 500) * 500; 290 | if (!CheckCondition()) return; 291 | GameMain.history.logisticShipCarries = (int)value; 292 | } 293 | } 294 | 295 | public float MiningCostRate 296 | { 297 | get 298 | { 299 | return miningCostRate; 300 | } 301 | 302 | set 303 | { 304 | if (value == 0 || value == miningCostRate) return; 305 | miningCostRate = value; 306 | if (!CheckCondition()) return; 307 | GameMain.history.miningCostRate = value; 308 | } 309 | } 310 | 311 | /// 312 | /// 采矿机速度倍率 313 | /// 314 | public float MiningSpeedScale 315 | { 316 | get 317 | { 318 | return miningSpeedScale; 319 | } 320 | 321 | set 322 | { 323 | if (value == 0 || value == miningSpeedScale) return; 324 | miningSpeedScale = value; 325 | if (!CheckCondition()) return; 326 | GameMain.history.miningSpeedScale = value; 327 | } 328 | } 329 | 330 | /// 331 | /// 建筑堆叠高度 332 | /// 333 | public float LabLevel 334 | { 335 | get 336 | { 337 | return labLevel; 338 | } 339 | 340 | set 341 | { 342 | if (value == 0 || value == labLevel) return; 343 | labLevel = value; 344 | if (!CheckCondition()) return; 345 | GameMain.history.storageLevel = (int)value; 346 | GameMain.history.labLevel = (int)value; 347 | } 348 | } 349 | 350 | /// 351 | /// 货物集装数量 352 | /// 353 | public float StorageLevel 354 | { 355 | get 356 | { 357 | return storageLevel; 358 | } 359 | 360 | set 361 | { 362 | if (value == 0 || value == storageLevel) return; 363 | storageLevel = value; 364 | if (!CheckCondition()) return; 365 | GameMain.history.stationPilerLevel = (int)value; 366 | } 367 | } 368 | 369 | /// 370 | /// 物流背包堆叠倍率 371 | /// 372 | public float StackSizeMultiplier 373 | { 374 | get 375 | { 376 | return stackSizeMultiplier; 377 | } 378 | 379 | set 380 | { 381 | if (value == 0 || value == stackSizeMultiplier) return; 382 | stackSizeMultiplier = value; 383 | if (!CheckCondition()) return; 384 | GameMain.mainPlayer.deliveryPackage.stackSizeMultiplier = (int)value; 385 | } 386 | } 387 | 388 | private float kineticDamageScale; 389 | /// 390 | /// 动能伤害系数 391 | /// 392 | public float KineticDamageScale 393 | { 394 | get { return kineticDamageScale; } 395 | set 396 | { 397 | if (value == 0 || value == kineticDamageScale) return; 398 | kineticDamageScale = value; 399 | if (!CheckCondition()) return; 400 | GameMain.history.kineticDamageScale = value; 401 | } 402 | } 403 | /// 404 | /// 能量伤害系数 405 | /// 406 | private float energyDamageScale; 407 | public float EnergyDamageScale 408 | { 409 | get { return energyDamageScale; } 410 | set 411 | { 412 | if (value == 0 || value == energyDamageScale) return; 413 | energyDamageScale = value; 414 | if (!CheckCondition()) return; 415 | GameMain.history.energyDamageScale = value; 416 | } 417 | } 418 | /// 419 | /// 爆破伤害系数 420 | /// 421 | private float blastDamageScale; 422 | public float BlastDamageScale 423 | { 424 | get { return blastDamageScale; } 425 | set 426 | { 427 | if (value == 0 || value == blastDamageScale) return; 428 | blastDamageScale = value; 429 | if (!CheckCondition()) return; 430 | GameMain.history.blastDamageScale = value; 431 | } 432 | } 433 | 434 | /// 435 | /// 电磁伤害系数 436 | /// 437 | private float magneticDamageScale; 438 | 439 | public float MagneticDamageScale 440 | { 441 | get { return magneticDamageScale; } 442 | set 443 | { 444 | if (value == 0 || value == magneticDamageScale) return; 445 | magneticDamageScale = value; 446 | if (!CheckCondition()) return; 447 | GameMain.history.magneticDamageScale = value; 448 | } 449 | } 450 | 451 | private float globalHpEnhancement; 452 | 453 | public float GlobalHpEnhancement 454 | { 455 | get => globalHpEnhancement; 456 | set 457 | { 458 | if (value == 0 || value == globalHpEnhancement) return; 459 | globalHpEnhancement = value; 460 | if (!CheckCondition()) return; 461 | GameMain.history.globalHpEnhancement = value; 462 | } 463 | } 464 | 465 | 466 | private float energyShieldRadius; 467 | 468 | 469 | /// 470 | /// 玩家护盾半径 471 | /// 472 | public float EnergyShieldRadius 473 | { 474 | get { return energyShieldRadius; } 475 | set 476 | { 477 | if (value == 0 || value == energyShieldRadius) return; 478 | energyShieldRadius = value; 479 | if (!CheckCondition()) return; 480 | GameMain.mainPlayer.mecha.energyShieldRadius = value; 481 | } 482 | } 483 | 484 | private long energyShieldCapacity; 485 | /// 486 | /// 玩家护盾能量上限 487 | /// 488 | public long EnergyShieldCapacity 489 | { 490 | get { return energyShieldCapacity; } 491 | set 492 | { 493 | if (value == 0 || value == energyShieldCapacity) return; 494 | if (value > 990_000_000_000) value = 1_000_000_000_000; 495 | if (value < 1000) value = 0; 496 | energyShieldCapacity = value; 497 | if (!CheckCondition()) return; 498 | GameMain.mainPlayer.mecha.energyShieldCapacity = (long)value; 499 | } 500 | } 501 | 502 | private float combatDroneDamageRatio; 503 | 504 | /// 505 | /// 战斗飞机伤害倍率 506 | /// 507 | public float CombatDroneDamageRatio 508 | { 509 | get { return combatDroneDamageRatio; } 510 | set 511 | { 512 | if (value == 0 || value == combatDroneDamageRatio) return; 513 | combatDroneDamageRatio = value; 514 | if (!CheckCondition()) return; 515 | GameMain.history.combatDroneDamageRatio = value; 516 | } 517 | } 518 | 519 | private float combatDroneROFRatio; 520 | 521 | /// 522 | /// 战斗飞机攻击速度倍率 523 | /// 524 | public float CombatDroneROFRatio 525 | { 526 | get { return combatDroneROFRatio; } 527 | set 528 | { 529 | if (value == 0 || value == combatDroneROFRatio) return; 530 | combatDroneROFRatio = value; 531 | if (!CheckCondition()) return; 532 | GameMain.history.combatDroneROFRatio = value; 533 | } 534 | } 535 | 536 | private float combatDroneDurabilityRatio; 537 | 538 | /// 539 | /// 战斗飞机耐久度倍率 540 | /// 541 | public float CombatDroneDurabilityRatio 542 | { 543 | get { return combatDroneDurabilityRatio; } 544 | set 545 | { 546 | if (value == 0 || value == combatDroneDurabilityRatio) return; 547 | combatDroneDurabilityRatio = value; 548 | if (!CheckCondition()) return; 549 | GameMain.history.combatDroneDurabilityRatio = value; 550 | } 551 | } 552 | 553 | private float enemyDropScale; 554 | 555 | /// 556 | /// 残骸产出倍率 557 | /// 558 | public float EnemyDropScale 559 | { 560 | get { return enemyDropScale; } 561 | set 562 | { 563 | if (value == 0 || value == enemyDropScale) return; 564 | enemyDropScale = value; 565 | if (!CheckCondition()) return; 566 | GameMain.history.enemyDropScale = value; 567 | } 568 | } 569 | 570 | 571 | private float combatDroneSpeedRatio; 572 | 573 | /// 574 | /// 战斗飞机速度倍率 575 | /// 576 | public float CombatDroneSpeedRatio 577 | { 578 | get { return combatDroneSpeedRatio; } 579 | set 580 | { 581 | if (value == 0 || value == combatDroneSpeedRatio) return; 582 | combatDroneSpeedRatio = value; 583 | if (!CheckCondition()) return; 584 | GameMain.history.combatDroneSpeedRatio = value; 585 | } 586 | } 587 | 588 | 589 | private float combatShipSpeedRatio; 590 | 591 | 592 | /// 593 | /// 战斗飞船速度倍率 594 | /// 595 | public float CombatShipSpeedRatio 596 | { 597 | get { return combatShipSpeedRatio; } 598 | set 599 | { 600 | if (value == 0 || value == combatShipSpeedRatio) return; 601 | combatShipSpeedRatio = value; 602 | if (!CheckCondition()) return; 603 | GameMain.history.combatShipSpeedRatio = value; 604 | } 605 | } 606 | 607 | 608 | private float combatShipDamageRatio; 609 | 610 | /// 611 | /// 战斗飞船伤害倍率 612 | /// 613 | public float CombatShipDamageRatio 614 | { 615 | get { return combatShipDamageRatio; } 616 | set 617 | { 618 | if (value == 0 || value == combatShipDamageRatio) return; 619 | combatShipDamageRatio = value; 620 | if (!CheckCondition()) return; 621 | GameMain.history.combatShipDamageRatio = value; 622 | } 623 | } 624 | 625 | 626 | private float combatShipROFRatio; 627 | 628 | /// 629 | /// 战斗飞船攻击速度倍率 630 | /// 631 | public float CombatShipROFRatio 632 | { 633 | get { return combatShipROFRatio; } 634 | set 635 | { 636 | if (value == 0 || value == combatShipROFRatio) return; 637 | combatShipROFRatio = value; 638 | if (!CheckCondition()) return; 639 | GameMain.history.combatShipROFRatio = value; 640 | } 641 | } 642 | 643 | 644 | private float combatShipDurabilityRatio; 645 | 646 | /// 647 | /// 战斗飞船耐久度倍率 648 | /// 649 | public float CombatShipDurabilityRatio 650 | { 651 | get { return combatShipDurabilityRatio; } 652 | set 653 | { 654 | if (value == 0 || value == combatShipDurabilityRatio) return; 655 | combatShipDurabilityRatio = value; 656 | if (!CheckCondition()) return; 657 | GameMain.history.combatShipDurabilityRatio = value; 658 | } 659 | } 660 | 661 | 662 | private float planetaryATFieldEnergyRate; 663 | 664 | /// 665 | /// 星球防御盾能量倍率 666 | /// 667 | public float PlanetaryATFieldEnergyRate 668 | { 669 | get { return planetaryATFieldEnergyRate; } 670 | set 671 | { 672 | if (value == 0 || value == planetaryATFieldEnergyRate) return; 673 | planetaryATFieldEnergyRate = value; 674 | if (!CheckCondition()) return; 675 | GameMain.history.planetaryATFieldEnergyRate = (long)value * Configs.freeMode.planetaryATFieldEnergyRate; 676 | } 677 | } 678 | 679 | 680 | private int hpMaxUpgrade; 681 | 682 | /// 683 | /// 玩家额外血量 684 | /// 685 | public int HpMaxUpgrade 686 | { 687 | get { return hpMaxUpgrade; } 688 | set 689 | { 690 | if (value == 0 || value == hpMaxUpgrade) return; 691 | if (value < 100) value = 0; 692 | hpMaxUpgrade = value; 693 | if (!CheckCondition()) return; 694 | GameMain.mainPlayer.mecha.hpMaxUpgrade = (int)value * 100; 695 | } 696 | } 697 | 698 | private float laserAttackLocalRange; 699 | 700 | /// 701 | /// 机甲激光攻击范围 702 | /// 703 | public float LaserAttackLocalRange 704 | { 705 | get { return laserAttackLocalRange; } 706 | set 707 | { 708 | if (value == 0 || value == laserAttackLocalRange) return; 709 | laserAttackLocalRange = value; 710 | if (!CheckCondition()) return; 711 | GameMain.mainPlayer.mecha.laserLocalAttackRange = (int)value; 712 | } 713 | } 714 | 715 | private float laserAttackSpaceRange; 716 | 717 | /// 718 | /// 机甲激光太空攻击范围 719 | /// 720 | public float LaserAttackSpaceRange 721 | { 722 | get { return laserAttackSpaceRange; } 723 | set 724 | { 725 | if (value == 0 || value == laserAttackSpaceRange) return; 726 | laserAttackSpaceRange = value / 10 * 10; 727 | if (!CheckCondition()) return; 728 | GameMain.mainPlayer.mecha.laserSpaceAttackRange = (int)value; 729 | } 730 | } 731 | 732 | private float laserAttackDamage; 733 | /// 734 | /// 机甲激光伤害 735 | /// 736 | public float LaserAttackDamage 737 | { 738 | get { return laserAttackDamage; } 739 | set 740 | { 741 | if (value == 0 || value == laserAttackDamage) return; 742 | if (value < 5) value = 0; 743 | laserAttackDamage = value; 744 | if (!CheckCondition()) return; 745 | GameMain.mainPlayer.mecha.laserLocalDamage = (int)value * 100; 746 | GameMain.mainPlayer.mecha.laserSpaceDamage = (int)value * 100; 747 | } 748 | } 749 | 750 | private float laserEnergyCapacity; 751 | 752 | /// 753 | /// 机甲激光能量存储上限 754 | /// 755 | public float LaserEnergyCapacity 756 | { 757 | get { return laserEnergyCapacity; } 758 | set 759 | { 760 | if (value == 0 || value == laserEnergyCapacity) return; 761 | if (value < 1000) value = 0; 762 | laserEnergyCapacity = value; 763 | if (!CheckCondition()) return; 764 | GameMain.mainPlayer.mecha.laserEnergyCapacity = (int)value; 765 | } 766 | } 767 | 768 | private float laserEnergyCost; 769 | 770 | /// 771 | /// 机甲激光消耗能量 772 | /// 773 | public float LaserEnergyCost 774 | { 775 | get { return laserEnergyCost; } 776 | set 777 | { 778 | if (value == 0 || value == laserEnergyCost) return; 779 | if (value < 10) value = 0; 780 | laserEnergyCost = value; 781 | if (!CheckCondition()) return; 782 | GameMain.mainPlayer.mecha.laserLocalEnergyCost = (int)value; 783 | GameMain.mainPlayer.mecha.laserSpaceEnergyCost = (int)value; 784 | } 785 | } 786 | 787 | public void SetContent(Mecha mecha, GameHistoryData historyData, int stackSizeMultiplier) 788 | { 789 | walkSpeed = mecha.walkSpeed; 790 | techSpeed = historyData.techSpeed; 791 | droneSpeed = historyData.constructionDroneSpeed; 792 | droneMovement = historyData.constructionDroneMovement; 793 | droneCount = mecha.constructionModule.droneCount; 794 | maxSailSpeed = mecha.maxSailSpeed / 1000; 795 | maxWarpSpeed = mecha.maxWarpSpeed / 480000; 796 | buildArea = mecha.buildArea; 797 | reactorPowerGen = (float)mecha.reactorPowerGen; 798 | logisticCourierSpeed = historyData.logisticCourierSpeed > 0 ? historyData.logisticCourierSpeed : 6; 799 | logisticDroneSpeedScale = historyData.logisticDroneSpeedScale > 0 ? historyData.logisticDroneSpeedScale : 3; 800 | logisticShipSpeedScale = historyData.logisticShipSpeedScale > 0 ? historyData.logisticShipSpeedScale : 5; 801 | logisticCourierCarries = historyData.logisticCourierCarries > 0 ? historyData.logisticDroneCarries : 3; 802 | logisticDroneCarries = historyData.logisticDroneCarries > 0 ? historyData.logisticDroneCarries : 100; 803 | logisticShipCarries = historyData.logisticShipCarries > 0 ? historyData.logisticShipCarries : 100; 804 | miningCostRate = historyData.miningCostRate; 805 | miningSpeedScale = historyData.miningSpeedScale; 806 | labLevel = historyData.labLevel; 807 | storageLevel = historyData.storageLevel; 808 | globalHpEnhancement = historyData.globalHpEnhancement; 809 | this.stackSizeMultiplier = stackSizeMultiplier; 810 | 811 | 812 | kineticDamageScale = historyData.kineticDamageScale; 813 | energyDamageScale = historyData.energyDamageScale; 814 | blastDamageScale = historyData.blastDamageScale; 815 | magneticDamageScale = historyData.magneticDamageScale; 816 | 817 | energyShieldRadius = mecha.energyShieldRadius; 818 | energyShieldCapacity = mecha.energyShieldCapacity; 819 | hpMaxUpgrade = mecha.hpMaxUpgrade / 100; 820 | laserAttackLocalRange = mecha.laserLocalAttackRange; 821 | laserAttackSpaceRange = mecha.laserSpaceAttackRange; 822 | laserAttackDamage = mecha.laserLocalDamage / 100; 823 | laserEnergyCapacity = mecha.laserEnergyCapacity; 824 | laserEnergyCost = mecha.laserLocalEnergyCost; 825 | 826 | combatDroneDamageRatio = historyData.combatDroneDamageRatio; 827 | combatDroneROFRatio = historyData.combatDroneROFRatio; 828 | combatDroneDurabilityRatio = historyData.combatDroneDurabilityRatio; 829 | combatDroneSpeedRatio = historyData.combatDroneSpeedRatio; 830 | enemyDropScale = historyData.enemyDropScale; 831 | 832 | combatShipDamageRatio = historyData.combatShipDamageRatio; 833 | combatShipROFRatio = historyData.combatShipROFRatio; 834 | combatShipDurabilityRatio = historyData.combatShipDurabilityRatio; 835 | combatShipSpeedRatio = historyData.combatShipSpeedRatio; 836 | 837 | planetaryATFieldEnergyRate = historyData.planetaryATFieldEnergyRate / Configs.freeMode.planetaryATFieldEnergyRate; 838 | } 839 | 840 | bool CheckCondition() 841 | { 842 | return GameMain.mainPlayer != null && GameMain.mainPlayer.mecha != null && GameMain.history != null; 843 | } 844 | } 845 | } 846 | --------------------------------------------------------------------------------