This commit is contained in:
2025-10-21 20:09:31 +08:00
commit 2a79a885eb
21 changed files with 1309 additions and 0 deletions

5
.gitignore vendored Normal file
View File

@@ -0,0 +1,5 @@
.**/idea/
**/.vscode/
decompile/

108
README.md Normal file
View File

@@ -0,0 +1,108 @@
# Duckov Modding 示例 (Duckov Modding Example)
## 文件夹结构
- decompile (反编译后的代码文件夹 / Decompiled code folder)
- full_decompile (完整解包后的代码文件夹 / Fully decompiled code folder)
- history (历史版本文件夹 / History folder)
- test (测试项目用文件夹 / Test folder)
## DLL解包方法 / DLL Decompile Method
### 使用ILSpy命令行工具一次性解包所有代码
1. 安装ILSpy命令行工具只需安装一次
```
dotnet tool install --global ilspycmd
```
2. 创建解包目录:
```
mkdir full_decompile
```
3. 使用ILSpy解包DLL文件
```
ilspycmd "E:\Steam\steamapps\common\Escape from Duckov\Duckov_Data\Managed\TeamSoda.Duckov.Core.dll" -o decompile -p
```
参数说明:
- `-o decompile`:指定输出目录
- `-p`生成项目文件便于在IDE中打开
4. 解包完成后,可以在`decompile`目录中查看所有解包后的源代码并使用IDE打开`TeamSoda.Duckov.Core.csproj`项目文件。
### 解包其他DLL文件
如需解包其他DLL文件使用相同的命令格式
```
ilspycmd "DLL文件路径" -o 目标目录 -p
```
## 工作原理概述
[official](official/README.md)
## 使用dotnet编译Debug和Release版本
### 编译命令
使用dotnet命令行工具可以轻松区分编译Debug和Release版本
1. **编译Debug版本**(默认配置):
```
dotnet build
```
或明确指定:
```
dotnet build -c Debug
```
2. **编译Release版本**
```
dotnet build -c Release
```
3. **发布Release版本**(优化后的可发布版本):
```
dotnet publish -c Release
```
### Debug和Release版本的区别
- **Debug版本**
- 包含调试信息
- 未进行代码优化
- 文件大小较大
- 适合开发和调试阶段
- **Release版本**
- 不包含调试信息(默认情况下)
- 进行了代码优化
- 文件大小较小
- 运行性能更好
- 适合发布和分发
### 输出位置
编译后的DLL文件通常位于以下位置
- Debug版本`bin/Debug/netstandard2.1/YourModName.dll`
- Release版本`bin/Release/netstandard2.1/YourModName.dll`
### 推荐做法
1. 开发阶段使用Debug版本便于调试
2. 发布Mod前使用Release版本确保性能最优
3. 发布时只需将Release版本的DLL文件、info.ini和preview.png打包
### 示例:完整编译流程
```bash
# 清理之前的构建
dotnet clean
# 编译Release版本
dotnet build -c Release
# 或者直接发布到指定目录
dotnet publish -c Release -o ./publish
```

107
history/HealthBarPatch.cs Normal file
View File

@@ -0,0 +1,107 @@
using HarmonyLib;
using System.Collections.Generic;
using TMPro;
using UnityEngine;
namespace test
{
/// <summary>
/// Harmony补丁类用于修改HealthBar的行为
/// 添加血量数值显示功能
/// </summary>
[HarmonyPatch]
public class HealthBarPatch
{
// 使用字典来存储每个HealthBar实例对应的血量文本
private static readonly Dictionary<Duckov.UI.HealthBar, TextMeshProUGUI> healthTexts = new Dictionary<Duckov.UI.HealthBar, TextMeshProUGUI>();
/// <summary>
/// 补丁HealthBar的Setup方法初始化血量文本
/// </summary>
[HarmonyPostfix]
[HarmonyPatch(typeof(Duckov.UI.HealthBar), "Setup")]
static void SetupPostfix(Duckov.UI.HealthBar __instance)
{
// 如果这个HealthBar已经有对应的文本先清理
if (healthTexts.ContainsKey(__instance))
{
CleanupHealthText(__instance);
}
// 创建血量文本对象
GameObject textObj = new GameObject("HealthText");
textObj.transform.SetParent(__instance.transform);
// 设置文本组件
TextMeshProUGUI healthText = textObj.AddComponent<TextMeshProUGUI>();
healthText.fontSize = 12;
healthText.color = Color.white;
healthText.alignment = TextAlignmentOptions.Center;
// 设置文本位置
RectTransform rectTransform = textObj.GetComponent<RectTransform>();
rectTransform.anchorMin = new Vector2(0, 0);
rectTransform.anchorMax = new Vector2(1, 1);
rectTransform.offsetMin = new Vector2(0, 0);
rectTransform.offsetMax = new Vector2(0, 0);
// 将文本对象存储到字典中
healthTexts[__instance] = healthText;
// 更新血量文本
UpdateHealthText(__instance);
}
/// <summary>
/// 补丁HealthBar的Refresh方法更新血量文本
/// </summary>
[HarmonyPostfix]
[HarmonyPatch(typeof(Duckov.UI.HealthBar), "Refresh")]
static void RefreshPostfix(Duckov.UI.HealthBar __instance)
{
UpdateHealthText(__instance);
}
/// <summary>
/// 补丁HealthBar的Release方法清理血量文本
/// </summary>
[HarmonyPostfix]
[HarmonyPatch(typeof(Duckov.UI.HealthBar), "Release")]
static void ReleasePostfix(Duckov.UI.HealthBar __instance)
{
CleanupHealthText(__instance);
}
/// <summary>
/// 清理与HealthBar关联的血量文本
/// </summary>
static void CleanupHealthText(Duckov.UI.HealthBar healthBar)
{
if (healthTexts.TryGetValue(healthBar, out TextMeshProUGUI textComponent))
{
if (textComponent != null && textComponent.gameObject != null)
{
Object.DestroyImmediate(textComponent.gameObject);
}
healthTexts.Remove(healthBar);
}
}
/// <summary>
/// 更新血量文本显示
/// </summary>
static void UpdateHealthText(Duckov.UI.HealthBar healthBar)
{
if (!healthTexts.TryGetValue(healthBar, out TextMeshProUGUI textComponent) ||
textComponent == null ||
healthBar.target == null)
return;
float currentHealth = healthBar.target.CurrentHealth;
float maxHealth = healthBar.target.MaxHealth;
// 显示当前血量和最大血量
textComponent.text = $"{currentHealth:F0}/{maxHealth:F0}";
}
}
}

View File

@@ -0,0 +1,88 @@
using Duckov.UI;
using Duckov.Utilities;
using ItemStatsSystem;
using TMPro;
using UnityEngine;
// 物品价值显示类
// 用于在物品悬停UI中显示物品的价值
namespace test
{
/// <summary>
/// test模组的主要行为类
/// 继承自Duckov.Modding.ModBehaviour用于在游戏UI中显示物品价值
/// </summary>
public class ModBehaviour : Duckov.Modding.ModBehaviour
{
private TextMeshProUGUI? _text = null;
private TextMeshProUGUI Text
{
get
{
// 如果文本组件尚未创建,则实例化一个新的
if (_text == null)
{
// 使用游戏UI样式模板创建文本组件
_text = Instantiate(GameplayDataSettings.UIStyle.TemplateTextUGUI);
}
return _text;
}
}
/// <summary>
/// 模组初始化时调用,类似于构造函数
/// 在此记录模组加载日志
/// </summary>
void Awake()
{
// 在控制台输出模组加载成功的日志信息
Debug.Log("DisplayItemValue Loaded!!!");
}
/// <summary>
/// 模组销毁时调用,用于清理资源
/// 确保创建的文本组件被正确销毁,避免内存泄漏
/// </summary>
void OnDestroy()
{
// 检查文本组件是否存在
if (_text != null)
// 销毁文本组件以释放资源
Destroy(_text);
}
void OnEnable()
{
// 注册物品悬停UI设置事件的监听器
ItemHoveringUI.onSetupItem += OnSetupItemHoveringUI;
}
/// <summary>
/// 模组禁用时调用,取消事件监听器
/// 取消订阅事件,防止在模组禁用后仍然响应事件
/// </summary>
void OnDisable()
{
// 取消注册物品悬停UI设置事件的监听器
ItemHoveringUI.onSetupItem -= OnSetupItemHoveringUI;
}
private void OnSetupItemHoveringUI(ItemHoveringUI uiInstance, Item item)
{
if (item == null)
{
Text.gameObject.SetActive(false);
return;
}
Text.gameObject.SetActive(true);
Text.transform.SetParent(uiInstance.LayoutParent);
Text.transform.localScale = Vector3.one;
Text.transform.SetSiblingIndex(1);
Text.text = $"${item.GetTotalRawValue() / 2}";
Text.fontSize = 20f;
Text.color = Color.green;
}
}
}

37
history/ModBehaviour.cs Normal file
View File

@@ -0,0 +1,37 @@
namespace test
{
/// <summary>
/// 基础模板
/// 继承自Duckov.Modding.ModBehaviour
/// </summary>
public class ModBehaviour : Duckov.Modding.ModBehaviour
{
/// <summary>
/// 模组初始化时调用,类似于构造函数
/// </summary>
void Awake()
{
}
/// <summary>
/// 模组销毁时调用,用于清理资源
/// </summary>
void OnDestroy()
{
}
void OnEnable()
{
}
/// <summary>
/// 模组禁用时调用,取消事件监听器
/// 取消订阅事件,防止在模组禁用后仍然响应事件
/// </summary>
void OnDisable()
{
}
}
}

View File

@@ -0,0 +1,60 @@
using HarmonyLib;
namespace test
{
/// <summary>
/// test模组的主要行为类
/// 继承自Duckov.Modding.ModBehaviour用于在游戏UI中显示物品价值
/// </summary>
public class ModBehaviour : Duckov.Modding.ModBehaviour
{
private static Harmony? harmony;
private static bool patched = false;
/// <summary>
/// 模组初始化时调用,类似于构造函数
/// </summary>
void Awake()
{
// 只在第一次初始化时创建Harmony实例
if (harmony == null)
{
harmony = new Harmony("com.test.healthdisplay");
}
// 只在未打补丁时应用补丁
if (!patched)
{
harmony.PatchAll();
patched = true;
}
}
/// <summary>
/// 模组销毁时调用,用于清理资源
/// </summary>
void OnDestroy()
{
// 只在已打补丁时取消补丁
if (patched && harmony != null)
{
harmony.UnpatchAll("com.test.healthdisplay");
patched = false;
}
}
void OnEnable()
{
}
/// <summary>
/// 模组禁用时调用,取消事件监听器
/// 取消订阅事件,防止在模组禁用后仍然响应事件
/// </summary>
void OnDisable()
{
}
}
}

226
official/.gitignore vendored Normal file
View File

@@ -0,0 +1,226 @@
# The following command works for downloading when using Git for Windows:
# curl -LOf http://gist.githubusercontent.com/kmorcinek/2710267/raw/.gitignore
#
# Download this file using PowerShell v3 under Windows with the following comand:
# Invoke-WebRequest https://gist.githubusercontent.com/kmorcinek/2710267/raw/ -OutFile .gitignore
#
# or wget:
# wget --no-check-certificate http://gist.githubusercontent.com/kmorcinek/2710267/raw/.gitignore
# User-specific files
*.suo
*.user
*.sln.docstates
# Build results
[Dd]ebug/
[Rr]elease/
x64/
[Bb]in/
[Oo]bj/
# build folder is nowadays used for build scripts and should not be ignored
#build/
# NuGet Packages
*.nupkg
# The packages folder can be ignored because of Package Restore
**/packages/*
# except build/, which is used as an MSBuild target.
!**/packages/build/
# Uncomment if necessary however generally it will be regenerated when needed
#!**/packages/repositories.config
# MSTest test Results
[Tt]est[Rr]esult*/
[Bb]uild[Ll]og.*
*_i.c
*_p.c
*.ilk
*.meta
*.obj
*.pch
*.pdb
*.pgc
*.pgd
*.rsp
*.sbr
*.tlb
*.tli
*.tlh
*.tmp
*.tmp_proj
*.log
*.vspscc
*.vssscc
.builds
*.pidb
*.scc
# Visual C++ cache files
ipch/
*.aps
*.ncb
*.opensdf
*.sdf
*.cachefile
# Visual Studio profiler
*.psess
*.vsp
*.vspx
# Guidance Automation Toolkit
*.gpState
# ReSharper is a .NET coding add-in
_ReSharper*/
*.[Rr]e[Ss]harper
# TeamCity is a build add-in
_TeamCity*
# DotCover is a Code Coverage Tool
*.dotCover
# NCrunch
*.ncrunch*
.*crunch*.local.xml
# Installshield output folder
[Ee]xpress/
# DocProject is a documentation generator add-in
DocProject/buildhelp/
DocProject/Help/*.HxT
DocProject/Help/*.HxC
DocProject/Help/*.hhc
DocProject/Help/*.hhk
DocProject/Help/*.hhp
DocProject/Help/Html2
DocProject/Help/html
# Click-Once directory
publish/
# Publish Web Output
*.Publish.xml
# Windows Azure Build Output
csx
*.build.csdef
# Windows Store app package directory
AppPackages/
# Others
*.Cache
ClientBin/
[Ss]tyle[Cc]op.*
~$*
*~
*.dbmdl
*.[Pp]ublish.xml
*.pfx
*.publishsettings
modulesbin/
tempbin/
# EPiServer Site file (VPP)
AppData/
# RIA/Silverlight projects
Generated_Code/
# Backup & report files from converting an old project file to a newer
# Visual Studio version. Backup files are not needed, because we have git ;-)
_UpgradeReport_Files/
Backup*/
UpgradeLog*.XML
UpgradeLog*.htm
# vim
*.txt~
*.swp
*.swo
# Temp files when opening LibreOffice on ubuntu
.~lock.*
# svn
.svn
# CVS - Source Control
**/CVS/
# Remainings from resolving conflicts in Source Control
*.orig
# SQL Server files
**/App_Data/*.mdf
**/App_Data/*.ldf
**/App_Data/*.sdf
#LightSwitch generated files
GeneratedArtifacts/
_Pvt_Extensions/
ModelManifest.xml
# =========================
# Windows detritus
# =========================
# Windows image file caches
Thumbs.db
ehthumbs.db
# Folder config file
Desktop.ini
# Recycle Bin used on file shares
$RECYCLE.BIN/
# OS generated files #
Icon?
# Mac desktop service store files
.DS_Store
# SASS Compiler cache
.sass-cache
# Visual Studio 2014 CTP
**/*.sln.ide
# Visual Studio temp something
.vs/
# dotnet stuff
project.lock.json
# VS 2015+
*.vc.vc.opendb
*.vc.db
# Rider
.idea/
# Visual Studio Code
.vscode/
# Output folder used by Webpack or other FE stuff
**/node_modules/*
**/wwwroot/*
# SpecFlow specific
*.feature.cs
*.feature.xlsx.*
*.Specs_*.html
# UWP Projects
AppPackages/
#####
# End of core ignore list, below put you custom 'per project' settings (patterns or path)
#####

View File

@@ -0,0 +1,34 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.0.31903.59
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DisplayItemValue", "DisplayItemValue\DisplayItemValue.csproj", "{2AF6EE80-2BF2-45F4-A8B6-22EE93FF7CC1}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Debug|x64 = Debug|x64
Debug|x86 = Debug|x86
Release|Any CPU = Release|Any CPU
Release|x64 = Release|x64
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{2AF6EE80-2BF2-45F4-A8B6-22EE93FF7CC1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{2AF6EE80-2BF2-45F4-A8B6-22EE93FF7CC1}.Debug|Any CPU.Build.0 = Debug|Any CPU
{2AF6EE80-2BF2-45F4-A8B6-22EE93FF7CC1}.Debug|x64.ActiveCfg = Debug|Any CPU
{2AF6EE80-2BF2-45F4-A8B6-22EE93FF7CC1}.Debug|x64.Build.0 = Debug|Any CPU
{2AF6EE80-2BF2-45F4-A8B6-22EE93FF7CC1}.Debug|x86.ActiveCfg = Debug|Any CPU
{2AF6EE80-2BF2-45F4-A8B6-22EE93FF7CC1}.Debug|x86.Build.0 = Debug|Any CPU
{2AF6EE80-2BF2-45F4-A8B6-22EE93FF7CC1}.Release|Any CPU.ActiveCfg = Release|Any CPU
{2AF6EE80-2BF2-45F4-A8B6-22EE93FF7CC1}.Release|Any CPU.Build.0 = Release|Any CPU
{2AF6EE80-2BF2-45F4-A8B6-22EE93FF7CC1}.Release|x64.ActiveCfg = Release|Any CPU
{2AF6EE80-2BF2-45F4-A8B6-22EE93FF7CC1}.Release|x64.Build.0 = Release|Any CPU
{2AF6EE80-2BF2-45F4-A8B6-22EE93FF7CC1}.Release|x86.ActiveCfg = Release|Any CPU
{2AF6EE80-2BF2-45F4-A8B6-22EE93FF7CC1}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

View File

@@ -0,0 +1,14 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.1</TargetFramework>
<Nullable>enable</Nullable>
<!-- This should be the folder that contains Duckov.exe -->
<!-- 下面这行里填写你的鸭科夫安装路径这样编译器就能找到相关的dll文件 -->
<DuckovPath>Path/To/Your/Duckov/</DuckovPath>
</PropertyGroup>
<ItemGroup>
<Reference Include="$(DuckovPath)\Duckov_Data\Managed\TeamSoda.*" />
<Reference Include="$(DuckovPath)\Duckov_Data\Managed\ItemStatsSystem.dll" />
<Reference Include="$(DuckovPath)\Duckov_Data\Managed\Unity*" />
</ItemGroup>
</Project>

View File

@@ -0,0 +1,24 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.5.2.0
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DisplayItemValue", "DisplayItemValue.csproj", "{784BCDB1-58EF-470D-56B7-EE39393A307C}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{784BCDB1-58EF-470D-56B7-EE39393A307C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{784BCDB1-58EF-470D-56B7-EE39393A307C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{784BCDB1-58EF-470D-56B7-EE39393A307C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{784BCDB1-58EF-470D-56B7-EE39393A307C}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {5C5F3569-CECB-482D-B101-BA6C0384A647}
EndGlobalSection
EndGlobal

View File

@@ -0,0 +1,58 @@
using Duckov.UI;
using Duckov.Utilities;
using ItemStatsSystem;
using TMPro;
using UnityEngine;
using UnityEngine.UI;
namespace DisplayItemValue
{
public class ModBehaviour : Duckov.Modding.ModBehaviour
{
TextMeshProUGUI _text = null;
TextMeshProUGUI Text
{
get
{
if (_text == null)
{
_text = Instantiate(GameplayDataSettings.UIStyle.TemplateTextUGUI);
}
return _text;
}
}
void Awake()
{
Debug.Log("DisplayItemValue Loaded!!!");
}
void OnDestroy()
{
if (_text != null)
Destroy(_text);
}
void OnEnable()
{
ItemHoveringUI.onSetupItem += OnSetupItemHoveringUI;
}
void OnDisable()
{
ItemHoveringUI.onSetupItem -= OnSetupItemHoveringUI;
}
private void OnSetupItemHoveringUI(ItemHoveringUI uiInstance, Item item)
{
if (item == null)
{
Text.gameObject.SetActive(false);
return;
}
Text.gameObject.SetActive(true);
Text.transform.SetParent(uiInstance.LayoutParent);
Text.transform.localScale = Vector3.one;
Text.text = $"${item.GetTotalRawValue() / 2}";
Text.fontSize = 20f;
}
}
}

View File

@@ -0,0 +1,5 @@
name = DisplayItemValue
displayName = 显示物品价值
description = 能够显示物品的价值by xvrsl
publishedFileId = 3532400883

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

152
official/README.md Normal file
View File

@@ -0,0 +1,152 @@
# Duckov Modding 示例 (Duckov Modding Example)
_This is an example project for modding Escape From Duckov._
## 工作原理概述 / Overview
《逃离鸭科夫》的 Mod 模块会扫描并读取 Duckov_Data/Mods 文件夹中的各个子文件夹,以及 Steam 创意工坊已订阅物品的各个文件夹。通过文件夹中包含的 dll 文件info.ini 和 preview.png 在游戏中展示、加载 mod。
The modding system of Escape From Duckov scans and reads the subfolders in the Duckov_Data/Mods folder, as well as the folders of subscribed items in the Steam Workshop. Mods are displayed and loaded in the game through the `dll` files, `info.ini`, and `preview.png` contained in these folders.
《逃离鸭科夫》会读取 info.ini 中的 name 参数,并以此作为 namespace 尝试加载名为 ModBehaviour 的类。例如info.ini 中如果记载`name=MyMod`,则会加载`MyMod.dll`文件中的`MyMod.ModBehaviour`
Escape From Duckov reads the name parameter in info.ini and uses it as a namespace to load a class named ModBehaviour. For example, if info.ini contains `name=MyMod`, it will load `MyMod.ModBehaviour` from the `MyMod.dll` file.
ModBehaviour 应继承自 Duckov.Modding.ModBehaviour。Duckov.Modding.ModBehaviour 是一个继承自 MonoBehaivour 的类。其中还包含了一些 mod 系统中需要使用的额外功能。在加载 mod 时,《逃离鸭科夫》会创建一个该 mod 的 GameObject 并通过调用 GameObject.AddComponent(Type) 的方式创建一个 ModBehaviour 的实例。Mod 作者可以通过编写 ModBehaviour 的 Start\Update 等 Unity 事件实现功能,也可以通过注册《逃离鸭科夫》中的其他事件实现功能。
ModBehaviour should inherit from `Duckov.Modding.ModBehaviour`. `Duckov.Modding.ModBehaviour` is a class that inherits from MonoBehaviour and includes some additional features needed in the mod system. When loading a mod, Escape From Duckov creates a GameObject for that mod and creates an instance of ModBehaviour by calling GameObject.AddComponent(Type). Mod authors can implement functionality by writing Unity events such as Start\Update in ModBehaviour, or by registering other events in Escape From Duckov.
## Mod 文件结构 / File Structure
将准备好的 Mod 文件夹放到《逃离鸭科夫》本体的 Duckov_Data/Mods 中,即可在游戏主界面的 Mods 界面加载该 Mod。
假设 Mod 的名字为"MyMod"。发布的文件结构应该如下:
Place the prepared Mod folder in `Duckov_Data/Mods` within the Escape From Duckov installation directory, and the Mod can be loaded in the Mods interface on the game's main menu.
Assuming the Mod's name is "MyMod", the published file structure should be as follows:
- MyMod (文件夹 / Folder)
- MyMod.dll
- info.ini
- preview.png (正方形的预览图,建议使用 256*256 分辨率 / Square preview image, recommended resolution 256*256)
[Mod 文件夹示例 / Mod Folder Example](DisplayItemValue/ReleaseExample/DisplayItemValue/)
### info.ini
info.ini 应包含以下参数:
- name (mod 名称,主要用于加载 dll 文件)
- displayName (显示的名称)
- description显示的描述
info.ini should contain the following parameters:
- name (mod name, primarily used for loading the dll file)
- displayName (display name)
- description (display description)
info.ini 还可能包含以下参数:
- publishedFileId (记录本 Mod 在 steam 创意工坊的 id
info.ini may also contain the following parameters:
- publishedFileId (records this Mod's ID in the Steam Workshop)
**注意:在上传 Steam Workshop 的时候,会复写 info.ini。info.ini 中原有的信息可能会因此丢失。所以不建议在 info.ini 中存储除以上项目之外的其他信息。**
**Note: When uploading to Steam Workshop, info.ini will be overwritten. Original information in info.ini may be lost as a result. Therefore, it is not recommended to store any information other than the above items in info.ini.**
## 配置 C# 工程 / Configuring C# Project
1. 在电脑上准备好《逃离鸭科夫》本体。
2. 创建一个 .Net Class Library 工程。
3. 配置工程参数。
1. Target Framework
- **TargetFramework 建议设置为 netstandard2.1。**
- 注意删除 TargetFramework 不支持的功能,比如`<ImplicitUsings>`
2. Reference Include
- 将《逃离鸭科夫》的`\Duckov_Data\Managed\*.dll`添加到引用中。
- 例:
```
<ItemGroup>
<Reference Include="$(DuckovPath)\Duckov_Data\Managed\TeamSoda.*" />
<Reference Include="$(DuckovPath)\Duckov_Data\Managed\ItemStatsSystem.dll" />
<Reference Include="$(DuckovPath)\Duckov_Data\Managed\Unity*" />
</ItemGroup>
```
4. 完成!现在在你 Mod 的 Namespace 中编写一个 ModBehaivour 的类。构建工程,即可得到你的 mod 的主要 dll。
### English Translation:
1. Have Escape From Duckov installed on your computer.
2. Create a .NET Class Library project.
3. Configure project parameters.
1. Target Framework
- **It is recommended to set TargetFramework to netstandard2.1.**
- Note: Remove features not supported by TargetFramework, such as `<ImplicitUsings>`
2. Reference Include
- Add `\Duckov_Data\Managed\*.dll` from Escape From Duckov to the references.
- Example:
```
<ItemGroup>
<Reference Include="$(DuckovPath)\Duckov_Data\Managed\TeamSoda.*" />
<Reference Include="$(DuckovPath)\Duckov_Data\Managed\ItemStatsSystem.dll" />
<Reference Include="$(DuckovPath)\Duckov_Data\Managed\Unity*" />
</ItemGroup>
```
4. Done! Now write a ModBehaviour class in your Mod's Namespace. Build the project to get your mod's main dll.
csproj 文件示例 / csproj File Example: [DisplayItemValue.csproj](DisplayItemValue/DisplayItemValue.csproj)
## 其他 / Other
### Unity Package
使用 Unity 进行开发时,可以参考本仓库附带的 [manifest.json 文件](UnityFiles/manifest.json) 来选择 package。
When developing with Unity, you can refer to the [manifest.json file](UnityFiles/manifest.json) included in this repository to select packages.
### 自定义游戏物品 / Custom Game Items
- 可调用 `ItemStatsSystem.ItemAssetsCollection.AddDynamicEntry(Item prefab)` 添加自定义物品
- 可调用`ItemStatsSystem.ItemAssetsCollection.RemoveDynamicEntry(Item prefab)`将该 mod 物品移除
- 自定义物品的 prefab 上需要配置好 TypeID。避免与游戏本体和其他 MOD 冲突。
- 进入游戏时如果未加载对应 MOD存档中的自定义物品会直接消失。
- Call `ItemStatsSystem.ItemAssetsCollection.AddDynamicEntry(Item prefab)` to add custom items
- Call `ItemStatsSystem.ItemAssetsCollection.RemoveDynamicEntry(Item prefab)` to remove the mod item
- Custom item prefabs need to have TypeID configured properly. Avoid conflicts with the base game and other MODs.
- If the corresponding MOD is not loaded when entering the game, custom items in the save file will disappear directly.
### 本地化 / Localization
- 可调用 `SodaCraft.Localizations.LocalizationManager.SetOverrideText(string key, string value)` 来覆盖显示本地化文本。
- 可借助 `SodaCraft.Localizations.LocalizationManager.OnSetLanguage:System.Action<SystemLanguage>` 事件来处理语言切换时的逻辑
- Call `SodaCraft.Localizations.LocalizationManager.SetOverrideText(string key, string value)` to override displayed localization text.
- Use the `SodaCraft.Localizations.LocalizationManager.OnSetLanguage:System.Action<SystemLanguage>` event to handle logic when switching languages
## 鸭科夫社区准则 / Duckov Community Rules
为了鸭科夫社区的长期健康与和谐发展,我们需要共同维护良好的创作环境。 因此,我们希望大家遵守以下规则:
1.禁止违反开发组以及 Steam 平台所在地区法律的内容,包括但不限于涉及政治、儿童色情、宣扬暴力恐怖等内容。
2.禁止严重侮辱角色或者扭曲剧情、意图在玩家社群内容引起反感和制造对立的内容,或者涉及到热门时事与现实人物等容易引发现实争议的内容。
3.禁止未经授权,使用受版权保护的游戏资源或其他第三方素材的内容。
4.禁止利用 Mod 引导至广告、募捐等商业或非官方性质的外部链接,或引导他人付费的行为。
5.使用AI内容的 Mod 需要标注。
对于在Steam创意工坊发布的 Mod如果违反上述规则我们可能会在不事先通知的情况下直接删除并可能封禁相关创作者的权限。
To aid the long-term development of the Duckov community, we ask everyone to contribute to a positive creative environment. Please adhere to the following rules:
1.Content that violates the laws of the regions where the developer team and the Steam platform operate is strictly prohibited, including but not limited to content involving politics, child sexual exploitation, or the promotion of violence or terrorism.
2.Content that severely insults characters, distorts the story, or aims to cause discomfort, conflict, or controversy in the player community is prohibited. This also includes content related to current events or real-life individuals that may trigger real-world disputes.
3.Unauthorized use of copyrighted game assets or other third-party materials is prohibited.
4.Mods must not be used to direct players to advertisements, fundraising, payment requests, or other commercial or unofficial external links.
5.Mods containing AI-generated content must be clearly labeled.
For mods published on Steam Workshop, any violations of the above rules may result in removal without prior notice and may lead to suspension of the creators permissions.

View File

@@ -0,0 +1,64 @@
{
"dependencies": {
"com.eflatun.scenereference": "git+https://github.com/starikcetin/Eflatun.SceneReference.git#3.2.1",
"com.febucci.custom-hierarchy": "https://github.com/febucci/unitypackage-custom-hierarchy.git",
"com.unity.2d.sprite": "1.0.0",
"com.unity.2d.tilemap": "1.0.0",
"com.unity.2d.tilemap.extras": "3.1.3",
"com.unity.addressables": "2.2.2",
"com.unity.burst": "1.8.22",
"com.unity.cinemachine": "2.10.1",
"com.unity.collab-proxy": "2.5.2",
"com.unity.collections": "2.5.1",
"com.unity.device-simulator.devices": "1.0.0",
"com.unity.ide.rider": "3.0.31",
"com.unity.ide.visualstudio": "2.0.22",
"com.unity.inputsystem": "1.11.1",
"com.unity.mathematics": "1.3.2",
"com.unity.memoryprofiler": "1.1.1",
"com.unity.polybrush": "1.1.8",
"com.unity.probuilder": "5.2.3",
"com.unity.profiling.core": "1.0.2",
"com.unity.recorder": "4.0.3",
"com.unity.render-pipelines.universal": "17.0.3",
"com.unity.scriptablebuildpipeline": "2.1.4",
"com.unity.splines": "2.6.1",
"com.unity.test-framework": "1.4.5",
"com.unity.textmeshpro": "3.0.9",
"com.unity.timeline": "1.8.7",
"com.unity.toolchain.win-x86_64-linux-x86_64": "2.0.10",
"com.unity.ugui": "2.0.0",
"com.unity.visualscripting": "1.9.4",
"com.unity.modules.ai": "1.0.0",
"com.unity.modules.androidjni": "1.0.0",
"com.unity.modules.animation": "1.0.0",
"com.unity.modules.assetbundle": "1.0.0",
"com.unity.modules.audio": "1.0.0",
"com.unity.modules.cloth": "1.0.0",
"com.unity.modules.director": "1.0.0",
"com.unity.modules.imageconversion": "1.0.0",
"com.unity.modules.imgui": "1.0.0",
"com.unity.modules.jsonserialize": "1.0.0",
"com.unity.modules.particlesystem": "1.0.0",
"com.unity.modules.physics": "1.0.0",
"com.unity.modules.physics2d": "1.0.0",
"com.unity.modules.screencapture": "1.0.0",
"com.unity.modules.terrain": "1.0.0",
"com.unity.modules.terrainphysics": "1.0.0",
"com.unity.modules.tilemap": "1.0.0",
"com.unity.modules.ui": "1.0.0",
"com.unity.modules.uielements": "1.0.0",
"com.unity.modules.umbra": "1.0.0",
"com.unity.modules.unityanalytics": "1.0.0",
"com.unity.modules.unitywebrequest": "1.0.0",
"com.unity.modules.unitywebrequestassetbundle": "1.0.0",
"com.unity.modules.unitywebrequestaudio": "1.0.0",
"com.unity.modules.unitywebrequesttexture": "1.0.0",
"com.unity.modules.unitywebrequestwww": "1.0.0",
"com.unity.modules.vehicles": "1.0.0",
"com.unity.modules.video": "1.0.0",
"com.unity.modules.vr": "1.0.0",
"com.unity.modules.wind": "1.0.0",
"com.unity.modules.xr": "1.0.0"
}
}

226
test/.gitignore vendored Normal file
View File

@@ -0,0 +1,226 @@
# The following command works for downloading when using Git for Windows:
# curl -LOf http://gist.githubusercontent.com/kmorcinek/2710267/raw/.gitignore
#
# Download this file using PowerShell v3 under Windows with the following comand:
# Invoke-WebRequest https://gist.githubusercontent.com/kmorcinek/2710267/raw/ -OutFile .gitignore
#
# or wget:
# wget --no-check-certificate http://gist.githubusercontent.com/kmorcinek/2710267/raw/.gitignore
# User-specific files
*.suo
*.user
*.sln.docstates
# Build results
[Dd]ebug/
[Rr]elease/
x64/
[Bb]in/
[Oo]bj/
# build folder is nowadays used for build scripts and should not be ignored
#build/
# NuGet Packages
*.nupkg
# The packages folder can be ignored because of Package Restore
**/packages/*
# except build/, which is used as an MSBuild target.
!**/packages/build/
# Uncomment if necessary however generally it will be regenerated when needed
#!**/packages/repositories.config
# MSTest test Results
[Tt]est[Rr]esult*/
[Bb]uild[Ll]og.*
*_i.c
*_p.c
*.ilk
*.meta
*.obj
*.pch
*.pdb
*.pgc
*.pgd
*.rsp
*.sbr
*.tlb
*.tli
*.tlh
*.tmp
*.tmp_proj
*.log
*.vspscc
*.vssscc
.builds
*.pidb
*.scc
# Visual C++ cache files
ipch/
*.aps
*.ncb
*.opensdf
*.sdf
*.cachefile
# Visual Studio profiler
*.psess
*.vsp
*.vspx
# Guidance Automation Toolkit
*.gpState
# ReSharper is a .NET coding add-in
_ReSharper*/
*.[Rr]e[Ss]harper
# TeamCity is a build add-in
_TeamCity*
# DotCover is a Code Coverage Tool
*.dotCover
# NCrunch
*.ncrunch*
.*crunch*.local.xml
# Installshield output folder
[Ee]xpress/
# DocProject is a documentation generator add-in
DocProject/buildhelp/
DocProject/Help/*.HxT
DocProject/Help/*.HxC
DocProject/Help/*.hhc
DocProject/Help/*.hhk
DocProject/Help/*.hhp
DocProject/Help/Html2
DocProject/Help/html
# Click-Once directory
publish/
# Publish Web Output
*.Publish.xml
# Windows Azure Build Output
csx
*.build.csdef
# Windows Store app package directory
AppPackages/
# Others
*.Cache
ClientBin/
[Ss]tyle[Cc]op.*
~$*
*~
*.dbmdl
*.[Pp]ublish.xml
*.pfx
*.publishsettings
modulesbin/
tempbin/
# EPiServer Site file (VPP)
AppData/
# RIA/Silverlight projects
Generated_Code/
# Backup & report files from converting an old project file to a newer
# Visual Studio version. Backup files are not needed, because we have git ;-)
_UpgradeReport_Files/
Backup*/
UpgradeLog*.XML
UpgradeLog*.htm
# vim
*.txt~
*.swp
*.swo
# Temp files when opening LibreOffice on ubuntu
.~lock.*
# svn
.svn
# CVS - Source Control
**/CVS/
# Remainings from resolving conflicts in Source Control
*.orig
# SQL Server files
**/App_Data/*.mdf
**/App_Data/*.ldf
**/App_Data/*.sdf
#LightSwitch generated files
GeneratedArtifacts/
_Pvt_Extensions/
ModelManifest.xml
# =========================
# Windows detritus
# =========================
# Windows image file caches
Thumbs.db
ehthumbs.db
# Folder config file
Desktop.ini
# Recycle Bin used on file shares
$RECYCLE.BIN/
# OS generated files #
Icon?
# Mac desktop service store files
.DS_Store
# SASS Compiler cache
.sass-cache
# Visual Studio 2014 CTP
**/*.sln.ide
# Visual Studio temp something
.vs/
# dotnet stuff
project.lock.json
# VS 2015+
*.vc.vc.opendb
*.vc.db
# Rider
.idea/
# Visual Studio Code
.vscode/
# Output folder used by Webpack or other FE stuff
**/node_modules/*
**/wwwroot/*
# SpecFlow specific
*.feature.cs
*.feature.xlsx.*
*.Specs_*.html
# UWP Projects
AppPackages/
#####
# End of core ignore list, below put you custom 'per project' settings (patterns or path)
#####

42
test/ModBehaviour.cs Normal file
View File

@@ -0,0 +1,42 @@

namespace test
{
/// <summary>
/// test模组的主要行为类
/// 继承自Duckov.Modding.ModBehaviour用于在游戏UI中显示物品价值
/// </summary>
public class ModBehaviour : Duckov.Modding.ModBehaviour
{
/// <summary>
/// 模组初始化时调用,类似于构造函数
/// </summary>
void Awake()
{
}
/// <summary>
/// 模组销毁时调用,用于清理资源
/// </summary>
void OnDestroy()
{
}
void OnEnable()
{
}
/// <summary>
/// 模组禁用时调用,取消事件监听器
/// 取消订阅事件,防止在模组禁用后仍然响应事件
/// </summary>
void OnDisable()
{
}
}
}

BIN
test/libs/0Harmony.dll Normal file

Binary file not shown.

35
test/test.csproj Normal file
View File

@@ -0,0 +1,35 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.1</TargetFramework>
<Nullable>enable</Nullable>
<!-- 下面这行里填写你的鸭科夫安装路径这样编译器就能找到相关的dll文件 -->
<DuckovPath>E:\Steam\steamapps\common\Escape from Duckov</DuckovPath>
<AssemblyName>test</AssemblyName>
<RootNamespace>test</RootNamespace>
<!-- 自动生成绑定重定向来解决程序集版本冲突 -->
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
<!-- 抑制程序集版本冲突警告 -->
<NoWarn>$(NoWarn);MSB3277</NoWarn>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
<PlatformTarget>x64</PlatformTarget>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)' == 'Release' ">
<PlatformTarget>x64</PlatformTarget>
</PropertyGroup>
<ItemGroup>
<Reference Include="$(DuckovPath)\Duckov_Data\Managed\TeamSoda.*" />
<Reference Include="$(DuckovPath)\Duckov_Data\Managed\ItemStatsSystem.dll" />
<Reference Include="$(DuckovPath)\Duckov_Data\Managed\Unity*" />
<Reference Include="0Harmony">
<HintPath>libs\0Harmony.dll</HintPath>
</Reference>
</ItemGroup>
<!-- 解决System.Text.Encoding.Extensions版本冲突 -->
<Target Name="AddBindingRedirects" AfterTargets="ResolveAssemblyReferences">
<ItemGroup>
<BindingRedirects Include="System.Text.Encoding.Extensions" OldVersion="0.0.0.0-8.0.0.0" NewVersion="4.0.11.0" />
</ItemGroup>
</Target>
</Project>

24
test/test.sln Normal file
View File

@@ -0,0 +1,24 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.5.2.0
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "test", "test.csproj", "{784BCDB1-58EF-470D-56B7-EE39393A307C}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{784BCDB1-58EF-470D-56B7-EE39393A307C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{784BCDB1-58EF-470D-56B7-EE39393A307C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{784BCDB1-58EF-470D-56B7-EE39393A307C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{784BCDB1-58EF-470D-56B7-EE39393A307C}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {5C5F3569-CECB-482D-B101-BA6C0384A647}
EndGlobalSection
EndGlobal