准备
- 一个编程工具:visual studio
- 一个反编译工具:dotPeek
- 一个可运行的游戏:骑马与砍杀2 ,我这里是v1.7.1
新建项目
1.新建一个类库开发项目
2.在游戏目录的Modules下新建文件夹,用于存放自己mod,如:Candyuan Mod
3.在自己mod文件下新建文件:SubModule.xml
<Module>
<Name value="Candyuan Mod"/>
<Id value="CandyuanMod"/>
<Version value="v1.0.0"/>
<SingleplayerModule value="true"/>
<MultiplayerModule value="false"/>
<DependedModules>
<DependedModule Id="Native"/>
<DependedModule Id="SandBoxCore"/>
<DependedModule Id="Sandbox"/>
<DependedModule Id="CustomBattle"/>
<DependedModule Id="StoryMode" />
</DependedModules>
<SubModules>
<SubModule>
<Name value="CandyuanMod"/>
<DLLName value="CandyuanMod.dll"/>
<SubModuleClassType value="CandyuanMod.Main"/>
<Tags>
<Tag key="DedicatedServerType" value="none" />
<Tag key="IsNoRenderModeElement" value="false" />
</Tags>
</SubModule>
</SubModules>
<Xmls/>
</Module>
4.在自己mod文件夹下新建文件夹:bin,再进到bin里新建文件夹:Win64_Shipping_Client。该文件夹作为build的输出路劲,如:E:\SteamLibrary\steamapps\common\Mount & Blade II Bannerlord\Modules\Candyuan Mod\bin\Win64_Shipping_Client
5.在vscode顶部“项目”里的最后一项“属性”,设置build输出路径
6.在vs项目右侧新建Main.cs
找到要打补丁的原代码
1.比如我想修改家族的同伴数上限,用dotPeek打开Mount & Blade II Bannerlord\bin\Win64_Shipping_Client\TaleWorlds.CampaignSystem.dll
2.接着找到命名空间TaleWorlds.CampaignSystem.SandBox.GameComponents
3.打开DefaultClanTierModel类
4.这个类里有一个获得同伴上限的方法
private int GetCompanionLimitFromTier(int clanTier) => clanTier + 3;
接下来我们就要为这个方法写上一个补丁
编写补丁代码
1.点击顶部“项目”下的“添加引用”,引入Mount & Blade II Bannerlord\bin\Win64_Shipping_Client下所有TaleWorlds.*.dll
2.在顶部“工具”下“NuGet包管理器”的”管理...“处搜索下载:HarmonyLib库和Newtonsoft.Json库
3. 编辑main.cs
using HarmonyLib;
using Newtonsoft.Json;
using System;
using System.IO;
using System.Reflection;
using System.Windows;
using TaleWorlds.Core;
using TaleWorlds.Localization;
using TaleWorlds.MountAndBlade;
using Module = TaleWorlds.MountAndBlade.Module;
namespace CandyuanMod
{
public class Main:MBSubModuleBase
{
public static int PartnerNum = 99;//同伴数
public static int TroopNum = 99;//部队数
public static int XpNum = 100;//人物经验倍数
private Config config { get; set; }
protected override void OnSubModuleLoad() {
base.OnSubModuleLoad();
try
{
string path = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "config.json");
if (File.Exists(path))
{
this.config = JsonConvert.DeserializeObject<Config>(File.ReadAllText(path));
Main.PartnerNum = this.config.PartnerNum;
Main.TroopNum = this.config.TroopNum;
Main.XpNum = this.config.XpNum;
}
new Harmony("CandyuanMode").PatchAll();
}
catch (Exception ex)
{
InformationManager.DisplayMessage(new InformationMessage("CandyuanMod error"));
}
}
}
}
4.新建Config.cs
using Newtonsoft.Json;
namespace CandyuanMod
{
internal class Config
{
[JsonProperty("PartnerNum")]
public int PartnerNum { get; set; }
[JsonProperty("TroopNum")]
public int TroopNum { get; set; }
[JsonProperty("XpNum")]
public int XpNum { get; set; }
}
}
5.新建PatchPartnerNum.cs
using HarmonyLib;
using TaleWorlds.CampaignSystem.SandBox.GameComponents;
using TaleWorlds.CampaignSystem;
using TaleWorlds.Library;
namespace CandyuanMod
{
[HarmonyPatch(typeof(DefaultClanTierModel), "GetCompanionLimitFromTier")]
public class PatchPartnerNum
{
private static bool Prefix(int clanTier, ref int __result)
{
ExplainedNumber explainedNumber = new ExplainedNumber(Main.PartnerNum);
__result = MathF.Round(((ExplainedNumber)explainedNumber).ResultNumber);
return false;
}
}
}
其中return false拦截了原来的方法。
6.点击顶部”生成“下"生成解决方案",这样build输出目录便有东西了
7.最后,再到输出目录下新建文件config.json,可以在这里配置你要的同伴数
{
"PartnerNum": 500
}
启动游戏测试
1.选择mod,点击play,如果有弹窗点击comfirm
2.打开家族,查看同伴上限
OK完工!
参考:
【一个家族统治大陆】每一级提升家族同伴与家族部队上限 【数值可自行调整】 - 《骑马与砍杀2:领主》 - 3DMGAME论坛 - Powered by Discuz!
【骑砍2】从零开始,制作自己的骑马与砍杀2MOD(字幕错乱)(搬运)_哔哩哔哩_bilibili
补充:
部队上限
using HarmonyLib;
using TaleWorlds.CampaignSystem;
using TaleWorlds.CampaignSystem.SandBox.GameComponents;
using TaleWorlds.Library;
using TaleWorlds.Localization;
namespace CandyuanMod
{
[HarmonyPatch(typeof(DefaultClanTierModel), "GetPartyLimitForTier")]
public class PatchTroopNum
{
private static bool Prefix(int clanTierToCheck, ref int __result)
{
ExplainedNumber explainedNumber = new ExplainedNumber(Main.TroopNum);
__result = MathF.Round(((ExplainedNumber) explainedNumber).ResultNumber);
return false;
}
}
}
人物经验值倍率
using HarmonyLib;
using TaleWorlds.CampaignSystem;
using TaleWorlds.CampaignSystem.SandBox.GameComponents.Map;
using TaleWorlds.Library;
using TaleWorlds.Localization;
namespace CandyuanMod
{
[HarmonyPatch(typeof(HeroDeveloper), "GainRawXp")]
public class PatchGainRawXp
{
private static void Prefix(ref float rawXp, bool shouldNotify) => rawXp *= Main.XpNum;
}
}
配置文件
{
"PartnerNum": 500,
"TroopNum": 100,
"XpNum": 20
}