Skip to content

Commit 94c30c4

Browse files
committed
upload
1 parent 7232152 commit 94c30c4

File tree

14 files changed

+1278
-4
lines changed

14 files changed

+1278
-4
lines changed

docs/dev/first-mod.md

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,17 @@ sidebar_position: 2
66

77
本教程将指导你创建一个简单的 Mod ,实现修改游戏内某个基础功能的功能。
88

9+
:::info
10+
本教程的 Mod 代码储存在 [Github](https://github.com/dead-cells-core-modding/docs-zh/blob/main/modproject/FirstDeadCellsMod) 上。
11+
:::
12+
913
## 创建 Mod 项目
1014

1115
- 打开命令行工具
1216
- 创建一个新的库项目:
1317

1418
```bash
15-
dotnet new classlib -n FirstDeadCellsMod -f 9.0
19+
dotnet new classlib -n FirstDeadCellsMod -f net9.0
1620
```
1721

1822
- 进入项目目录:
@@ -68,6 +72,9 @@ namespace FirstDeadCellsMod
6872

6973
<!--模组主类的FullName-->
7074
<ModMain>FirstDeadCellsMod.FirstDeadCells</ModMain>
75+
76+
<!--在生成时自动安装Mod-->
77+
<!--<AutoInstallMod>true</AutoInstallMod>-->
7178
</PropertyGroup>
7279

7380
```
@@ -92,7 +99,7 @@ dotnet build
9299
你应该能看到类似这样的日志条目:
93100

94101
```text
95-
[20:09:48 INF][MyFirstMod] 你好,世界
102+
[13:47:52 INF][FirstDeadCells] 你好,世界
96103
```
97104

98105
:::

docs/dev/first-weapon.md

Lines changed: 200 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,200 @@
1+
---
2+
sidebar_position: 3
3+
---
4+
5+
# 创造第一个武器
6+
7+
本教程将指导你创建一个简单的 Mod ,实现修改游戏内某个基础功能的功能。
8+
9+
:::info
10+
本教程的 Mod 代码储存在 [Github](https://github.com/dead-cells-core-modding/docs-zh/blob/main/modproject/FirstWeapon) 上。
11+
12+
本章节大部分代码来自 **Frostbite**。感谢 Frostbite 对本教程的帮助。
13+
:::
14+
15+
:::warning
16+
本教程假设你拥有以下技能:
17+
18+
- C# 编程基础
19+
- 死亡细胞基础 Mod 制作 ([教程](https://www.bilibili.com/opus/681293864647000128))
20+
21+
:::
22+
23+
## 创建 Mod 项目
24+
25+
按照[教程](./first-mod.md)创造名为 **FirstWeapon** 的 Mod 项目。
26+
27+
## 制作 res.pak
28+
29+
按照[教程](https://www.bilibili.com/opus/681993184170999904)制作一个**diff pak****CDB**中应包括:
30+
31+
- 一个名为 **OtherDashSword** 新武器以及它对应的 **item**
32+
33+
:::tip
34+
**OtherDashSword** 可以换为其他名字。
35+
:::
36+
37+
一个现成的 [res.pak](https://github.com/dead-cells-core-modding/docs-zh/blob/main/modproject/FirstWeapon/res.pak)
38+
39+
### 复制 res.pak
40+
41+
- 将上一步获得的**res.pak**复制到项目根目录下。
42+
- 修改**FirstWeapon.csproj**,添加以下内容
43+
44+
```xml
45+
<ItemGroup>
46+
<!--将res.pak文件复制到bin\Debug\net9.0目录-->
47+
<None Update="res.pak">
48+
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
49+
</None>
50+
51+
<!--将res.pak文件复制到最终的输出目录-->
52+
<OutputFiles Include="res.pak" />
53+
</ItemGroup>
54+
```
55+
56+
## 编写代码
57+
58+
### 加载 res.pak
59+
60+
- 修改`FirstWeaponMod.FirstWeapon`类,使其实现`IOnGameEndInit`接口。
61+
62+
```csharp
63+
//加载res.pak并刷新CDB
64+
void IOnGameEndInit.OnGameEndInit()
65+
{
66+
var res = Info.ModRoot!.GetFilePath("res.pak"); //获取 Mod 根目录 下的 res.pak 文件的绝对路径
67+
FsPak.Instance.FileSystem.loadPak(res.AsHaxeString()); //加载 res.pak
68+
var json = CDBManager.Class.instance.getAlteredCDB(); //获取合并后的 CDB Json
69+
Data.Class.loadJson( //加载合并后的 CDB Json
70+
json,
71+
default);
72+
}
73+
```
74+
75+
:::info
76+
成功加载 **res.pak** 后,你可以在日志中看到类似的内容:
77+
78+
```text
79+
[14:30:13 INF][FsPak] Loading pak from C:\SteamLibrary\steamapps\common\Dead Cells\coremod\mods\FirstWeapon\res.pak
80+
```
81+
82+
:::
83+
84+
:::info
85+
`IOnGameExit`接口和`IOnGameEndInit`接口都是**事件系统**的一部分。它们会在对应的**事件**触发时被调用。
86+
87+
- `IOnGameExit` 将会在游戏退出前调用。
88+
- `OnGameEndInit` 将会在游戏初始化后被调用。
89+
- `IOnHeroUpdate` 将会在游戏内每帧调用一次。
90+
91+
:::
92+
93+
### 创造武器类
94+
95+
创造一个 `FirstWeaponMod.OtherDashSwordWeapon` 类,使其继承于`DashSword`类并实现`IHxbitSerializable<object>`接口。
96+
97+
```csharp
98+
//武器类
99+
internal class OtherDashSwordWeapon :
100+
DashSword, //基类
101+
IHxbitSerializable<object>
102+
{
103+
104+
//默认构造方法
105+
public OtherDashSwordWeapon(Hero o, InventItem i) : base(o, i)
106+
{
107+
}
108+
109+
//留空
110+
object IHxbitSerializable<object>.GetData()
111+
{
112+
return new(); //TODO
113+
}
114+
115+
//留空
116+
void IHxbitSerializable<object>.SetData(object data)
117+
{
118+
//TODO
119+
}
120+
121+
// 测试效果——每帧增加10细胞
122+
public override void fixedUpdate()
123+
{
124+
base.fixedUpdate();
125+
bool noStats = false;
126+
this.owner.addCells(10, new HaxeProxy.Runtime.Ref<bool>(ref noStats));
127+
}
128+
}
129+
```
130+
131+
:::info
132+
`IHxbitSerializable<>`接口用于保存游戏对象的数据。
133+
134+
为了简单起见,武器类并没有直接继承于 `Weapon`类(所有武器的基类),而是继承于`DashSword`类。
135+
:::
136+
137+
### 注册新武器
138+
139+
仅仅将新武器的信息添加到 **CDB** 中是仍然是不够的。
140+
141+
为了让游戏可以识别新武器,还需要修改`FirstWeaponMod.FirstWeapon`类,添加以下内容:
142+
143+
```csharp
144+
public override void Initialize()
145+
{
146+
Logger.Information("你好,世界");
147+
148+
Hook__Weapon.create += Hook__Weapon_create; //挂钩 $Weapon.create
149+
}
150+
151+
private Weapon Hook__Weapon_create(Hook__Weapon.orig_create orig, dc.en.Hero o, InventItem i)
152+
{
153+
var id = i._itemData.id.ToString(); //获取武器id
154+
if(id == "OtherDashSword")
155+
{
156+
return new OtherDashSwordWeapon(o, i); //返回自定义的武器
157+
}
158+
else
159+
{
160+
return orig(o, i); //调用原始方法
161+
}
162+
}
163+
```
164+
165+
### 获取新武器
166+
167+
很明显,现在无法拿到新武器,因为目前它没有任何获取途径。
168+
169+
可以通过以下的代码创造新武器对应的物品:
170+
171+
```csharp
172+
//生成物品
173+
private void SpawnWeapon(Hero hero)
174+
{
175+
InventItem testItem = new InventItem(new InventItemKind.Weapon("OtherDashSword".AsHaxeString()));
176+
bool test_boolean = false;
177+
ItemDrop itemDrop = new ItemDrop(hero._level, hero.cx, hero.cy, testItem, true, new HaxeProxy.Runtime.Ref<bool>(ref test_boolean));
178+
// 生成掉落物后必须调用init方法,否则游戏会崩溃
179+
itemDrop.init();
180+
itemDrop.onDropAsLoot();
181+
itemDrop.dx = hero.dx; // 不知道为什么要有这一步,但是原版代码这么写的
182+
}
183+
```
184+
185+
为了简单起见,使用以下代码使得在**游戏中**可以通过按下**反斜杠**来获取**新武器**
186+
187+
```csharp
188+
//实现IOnHeroUpdate接口
189+
void IOnHeroUpdate.OnHeroUpdate(double dt)
190+
{
191+
if(Key.Class.isPressed(0xDC /**反斜杠键码**/))
192+
{
193+
SpawnWeapon(Game.Instance.HeroInstance!);
194+
}
195+
}
196+
```
197+
198+
## 效果演示
199+
200+
[视频](https://github.com/dead-cells-core-modding/docs-zh/blob/main/docs/dev/videos/Dead%20Cells%20with%20Core%20Modding%202025-07-21%2015-30-36.mp4)
Binary file not shown.

0 commit comments

Comments
 (0)