缺氧MOD开发 从小白到入门(二、第一个修改)
搬砖猫Cat
编辑于 2023年08月17日 21:14

一、准备工作:

前文​已经创建了工程文件,内容如下

代码块
C#
自动换行
复制代码
using System;

namespace FancyOxygenEdit
{
  public class Class1
  {
  }
}
复制成功

首先在前面添加引用文件

代码块
C#
自动换行
复制代码
using HarmonyLib;
using PeterHan.PLib.Options;
using TUNING;
using UnityEngine;
using KMod;
using PeterHan.PLib.Core;
复制成功

然后将第一行的public class Class1修改为public class Paches,其中“Paches”为自定义名称。之后所有的修改都在这个Paches类中进行。

二、开始修改

这里以修改液温调节器的功率和降低温度为例。

1、查找修改对象的内部名称

用Poedit打开strings_preinstalled_zh_klei.po文件,搜索“液温调节器”的英文 如“<link="LIQUIDCONDITIONER&#​34;>液温调节器</link>”中的“LIQUIDCONDITIONER”就是对应的游戏内部名称。

文件路径为:游戏安装文件夹\OxygenNotIncluded\OxygenNotIncluded_Data\StreamingAssets\strings\trings_preinstalled_zh_klei.po

2、查找修改对象的源代码

用dnspy打开Assembly-CSharp.dll,使用搜索功能搜索“LIQUIDCONDITIONER”,搜索结果中有一项CreateBuildingDef,双击即进入代码行,这段即为液温调节器的功能代码。

文件路径为:游戏安装文件夹\OxygenNotIncluded\OxygenNotIncluded_Data\Managed\Assembly-CSharp.dll

完整的代码如下,目前可以不用管具体代码内容,只需要找我们需要修改的代码即可。其他代码意思可以使用翻译软件查询。

代码块
C#
自动换行
复制代码
public class LiquidConditionerConfig : IBuildingConfig
{
	public override BuildingDef CreateBuildingDef()
	{
		string id = "LiquidConditioner";
		int width = 2;
		int height = 2;
		string anim = "liquidconditioner_kanim";
		int hitpoints = 100;
		float construction_time = 120f;
		float[] tier = BUILDINGS.CONSTRUCTION_MASS_KG.TIER6;
		string[] all_METALS = MATERIALS.ALL_METALS;
		float melting_point = 1600f;
		BuildLocationRule build_location_rule = BuildLocationRule.OnFloor;
		EffectorValues tier2 = NOISE_POLLUTION.NOISY.TIER2;
		BuildingDef buildingDef = BuildingTemplates.CreateBuildingDef(id, width, height, anim, hitpoints, construction_time, tier, all_METALS, melting_point, build_location_rule, BUILDINGS.DECOR.NONE, tier2, 0.2f);
		BuildingTemplates.CreateElectricalBuildingDef(buildingDef);
		buildingDef.EnergyConsumptionWhenActive = 1200f;
		buildingDef.SelfHeatKilowattsWhenActive = 0f;
		buildingDef.InputConduitType = ConduitType.Liquid;
		buildingDef.OutputConduitType = ConduitType.Liquid;
		buildingDef.Floodable = false;
		buildingDef.PowerInputOffset = new CellOffset(1, 0);
		buildingDef.UtilityInputOffset = new CellOffset(0, 0);
		buildingDef.PermittedRotations = PermittedRotations.FlipH;
		buildingDef.ViewMode = OverlayModes.LiquidConduits.ID;
		buildingDef.OverheatTemperature = 398.15f;
		buildingDef.LogicInputPorts = LogicOperationalController.CreateSingleInputPortList(new CellOffset(1, 1));
		GeneratedBuildings.RegisterWithOverlay(OverlayScreen.LiquidVentIDs, "LiquidConditioner");
		return buildingDef;
	}

	public override void ConfigureBuildingTemplate(GameObject go, Tag prefab_tag)
	{
		go.AddOrGet<LoopingSounds>();
		AirConditioner airConditioner = go.AddOrGet<AirConditioner>();
		airConditioner.temperatureDelta = -14f;
		airConditioner.maxEnvironmentDelta = -50f;
		airConditioner.isLiquidConditioner = true;
		ConduitConsumer conduitConsumer = go.AddOrGet<ConduitConsumer>();
		conduitConsumer.conduitType = ConduitType.Liquid;
		conduitConsumer.consumptionRate = 10f;
		Storage storage = BuildingTemplates.CreateDefaultStorage(go, false);
		storage.showInUI = true;
		storage.capacityKg = 2f * conduitConsumer.consumptionRate;
		storage.SetDefaultStoredItemModifiers(LiquidConditionerConfig.StoredItemModifiers);
	}


	public override void DoPostConfigureComplete(GameObject go)
	{
		go.AddOrGet<LogicOperationalController>();
		go.AddOrGetDef<PoweredActiveController.Def>();
		go.GetComponent<KPrefabID>().AddTag(GameTags.OverlayBehindConduits, false);
	}


	public const string ID = "LiquidConditioner";


	private static readonly List<Storage.StoredItemModifier> StoredItemModifiers = new List<Storage.StoredItemModifier>
	{
		Storage.StoredItemModifier.Hide,
		Storage.StoredItemModifier.Insulate,
		Storage.StoredItemModifier.Seal
	};
}
复制成功

在这段代码中,功率的代码是“buildingDef.EnergyConsumptionWhenActive = 1200f”,意思是功率为1200瓦,输出温度的代码是“airConditioner.temperatureDelta = -14f”,意思是输出的物质温度降低14度。此外要注意的是,这两段代码分别在“public override BuildingDef CreateBuildingDef”和“public override void ConfigureBuildingTempla”函数中,记下这个区别。

3、开始修改代码

进入工程文件中,在类中添加如下代码

代码块
C#
自动换行
复制代码
[HarmonyPatch(typeof(LiquidConditionerConfig), "CreateBuildingDef")]
public class Patch_LiquidConditionerConfig_Create
{
  public static void Postfix(ref BuildingDef __result)
  {
    __result.EnergyConsumptionWhenActive = 200f;
  }
}
复制成功

第一行 [HarmonyPatch(typeof(“参数1”), "参数2&#​34;)]的意思是需要修改的函数位置,参数1对应的是源文件中的第一行“public class LiquidConditionerConfig : IBuildingConfig”中的“LiquidConditionerConfig”。参数2对应的是功率所在的函数名字“CreateBuildingDef”。

第二行

public class 函数名,是自定义修改的执行函数,名称自定义,我这里为了方便区分使用了“Patch_修改对象_Create”的命名方法

第三行

public static void Postfix(ref BuildingDef __result),是固定写法

第四行

__result.修改对象 = 值;就是需要修改的内容

这里“__result.EnergyConsumptionWhenActive = 200f;”的意思就是修改功率为200瓦。

同理,修改输出温度的代码如下

代码块
C#
自动换行
复制代码
[HarmonyPatch(typeof(LiquidConditionerConfig), "ConfigureBuildingTemplate")]
public class Patch_LiquidConditionerConfig_Configure
{
  public static void Postfix(ref GameObject go, Tag prefab_tag)
  {
    go.AddOrGet<AirConditioner>().temperatureDelta = -20f;  //输出温度 默认-14
  }
}
复制成功

这样一来修改的代码就完成了。

三、mod安装

1、生成dll文件

点击启动,调试生成dll文件,输出窗口中出现如下信息,即表明DLL文件生成成功

代码块
JavaScript
自动换行
复制代码
1>------ 已启动生成: 项目: FancyOxygenEdit, 配置: Debug Any CPU ------
1>  FancyOxygenEdit -> C:\Users\Fancy_HTPC\source\repos\FancyOxygenEdit\FancyOxygenEdit\bin\Debug\FancyOxygenEdit.dll
复制成功

2、建立测试文件夹

新建开发文件夹,用于mod的本地开发测试,如果不想上传到steam的话可以这样直接使用 首先进入缺氧的存档文件夹,例如 C:\Users\User\Documents\Klei\OxygenNotIncluded 在mods文件夹中新建Dev文件夹和mod文件夹,完整的路径为,其中MyMod为自定义名称 C:\Users\User\Documents\Klei\OxygenNotIncluded\mods\Dev\MyMod

3、将生成mod文件“FancyOxygenEdit.dll”和“PLib.dll”拷贝进MyMod文件夹内

4、用文本编辑器新建两个mod.yaml和mod_info.yaml文件

mod.yaml:

代码块
C#
自动换行
复制代码
title: 我的修改合辑			//MOD名称
description: 我的修改合辑		//MOD说明
staticID: MyEdit			//MOD ID
复制成功

mod_info.yaml:

代码块
C#
自动换行
复制代码
supportedContent: ALL			//ALL表示支持本体和DLC
minimumSupportedBuild: 525812	//最小支持的游戏版本号,可以固定写
APIVersion: 2					//游戏API版本
version: "1.0"					//MOD版本号,如果需要上传到STEAM需要用到这个
复制成功

至此这个液温调节器的修改MOD便可以用了,进入游戏内启用对应MOD即可。