From d4382742a87e6b1588538983ebd6e7f57bcb019a Mon Sep 17 00:00:00 2001 From: ClearZer0 <534310154@qq.com> Date: Thu, 16 Jan 2025 23:57:48 +0800 Subject: [PATCH 01/26] =?UTF-8?q?=E8=A1=A5=E5=85=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/advanced/cross_mod_interactions.md | 4 ++-- docs/coding_setup/basic_env.md | 2 +- docs/misc/change_log.md | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/advanced/cross_mod_interactions.md b/docs/advanced/cross_mod_interactions.md index d0cfd0b..c23fb8f 100644 --- a/docs/advanced/cross_mod_interactions.md +++ b/docs/advanced/cross_mod_interactions.md @@ -139,8 +139,8 @@ public static class MyCelesteModAPI // 如果没有返回值, 也就是返回值是 void 则使用 Action public static Action LogStuff; - // 如果导出的方法参数中有 out 或 ref 需要定义自定义委托类型以进行导入 - // Func 并不支持参数中带有 out 或 ref 的情况 + // 如果导出的方法参数中有 in, out 或 ref 需要定义自定义委托类型以进行导入 + // Func 并不支持参数中带有 in, out 或 ref 的情况 public static TryDoubleIfEvenDelegate TryDoubleIfEven; public delegate bool TryDoubleIfEvenDelegate(int number, out int? doubledNumber); } diff --git a/docs/coding_setup/basic_env.md b/docs/coding_setup/basic_env.md index 420d42c..f74d388 100644 --- a/docs/coding_setup/basic_env.md +++ b/docs/coding_setup/basic_env.md @@ -218,7 +218,7 @@ ok, 我们前面几乎巴拉巴拉讲了几乎三千多个字, 但是依然没 最后是最底下的那个依赖, 这里我们只依赖最基础的 Everest, 版本填上你目前使用的 Everest 版本, 这里我就填写 3971 了. 如果你的 mod 依赖 Everest Core, 你需要在这里将 `Everest` 更改为 `EverestCore`, 并将版本号填写大于 4465 的值. -## 最后一步 +## 热重载以及结语 为了方便我们的调试, 我们需要让蔚蓝打开的同时打开控制台, 这一步很简单: diff --git a/docs/misc/change_log.md b/docs/misc/change_log.md index 7192ec5..6f3456c 100644 --- a/docs/misc/change_log.md +++ b/docs/misc/change_log.md @@ -29,6 +29,6 @@ * 添加[测试地图](../coding_challenges/test_map.md) * 完善[跨 Mod 交互](../advanced/cross_mod_interactions.md) -### 2025.1. +### 2025.1.16 * 完善[调试](../coding_setup/debug.md) - 完善[跨 Mod 交互 - ModInterop](../advanced/cross_mod_interactions.md) From 31aa5c534810597e1a2474c6b3622dd0a5399670 Mon Sep 17 00:00:00 2001 From: ClearZer0 <534310154@qq.com> Date: Fri, 17 Jan 2025 13:12:56 +0800 Subject: [PATCH 02/26] =?UTF-8?q?=E5=90=88=E5=B9=B6CMCC=20LuaCutscene=20XM?= =?UTF-8?q?L=E7=AE=80=E5=8D=95=E4=BB=8B=E7=BB=8D=E8=87=B3=E6=96=B0?= =?UTF-8?q?=E7=9A=84=E9=A2=9D=E5=A4=96=E7=AB=A0=E8=8A=82=E4=BB=A5=E4=BC=98?= =?UTF-8?q?=E5=8C=96=E6=8E=92=E7=89=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/coding_setup/preference.md | 2 +- .../lua_cutscene}/begin.md | 2 +- .../lua_cutscene}/cs_access.md | 0 .../lua_cutscene}/examples.md | 2 +- .../lua_cutscene}/lua-in-vscode.png | Bin .../lua_cutscene}/reference.md | 0 docs/{other => extra/xml}/xml-speedrun.md | 0 docs/extra_cmcc/cmcc | 1 - docs/extra_cmcc/index.md | 5 ---- docs/misc/change_log.md | 20 +++++++-------- docs/misc/to_do_list.md | 12 +++++---- mkdocs.yml | 24 +++++++++--------- 12 files changed, 32 insertions(+), 36 deletions(-) rename docs/{extra_luacs => extra/lua_cutscene}/begin.md (99%) rename docs/{extra_luacs => extra/lua_cutscene}/cs_access.md (100%) rename docs/{extra_luacs => extra/lua_cutscene}/examples.md (98%) rename docs/{extra_luacs => extra/lua_cutscene}/lua-in-vscode.png (100%) rename docs/{extra_luacs => extra/lua_cutscene}/reference.md (100%) rename docs/{other => extra/xml}/xml-speedrun.md (100%) delete mode 160000 docs/extra_cmcc/cmcc delete mode 100644 docs/extra_cmcc/index.md diff --git a/docs/coding_setup/preference.md b/docs/coding_setup/preference.md index ac6551d..4b53d0b 100644 --- a/docs/coding_setup/preference.md +++ b/docs/coding_setup/preference.md @@ -34,7 +34,7 @@ ``` !!! note - 这个文件是 XML 格式的, 如果你不熟悉 XML 的话你可以到[这里](../other/xml-speedrun.md)简单看一下, 免得你不知道我们讨论的东西都是什么 + 这个文件是 XML 格式的, 如果你不熟悉 XML 的话你可以到[这里](../extra/xml/xml-speedrun.md)简单看一下, 免得你不知道我们讨论的东西都是什么 其中我们只需要关注里面的 `PropertyGroup` 以及 `ItemGroup` 节点 `PropertyGroup` 节点定义了这个项目有哪些属性, 比如项目框架版本, 语言版本, 程序集昵称等 diff --git a/docs/extra_luacs/begin.md b/docs/extra/lua_cutscene/begin.md similarity index 99% rename from docs/extra_luacs/begin.md rename to docs/extra/lua_cutscene/begin.md index 7f574e4..bfd2bc3 100644 --- a/docs/extra_luacs/begin.md +++ b/docs/extra/lua_cutscene/begin.md @@ -1,4 +1,4 @@ -# 额外 - LuaCutscene +# LuaCutscene ## 前言 diff --git a/docs/extra_luacs/cs_access.md b/docs/extra/lua_cutscene/cs_access.md similarity index 100% rename from docs/extra_luacs/cs_access.md rename to docs/extra/lua_cutscene/cs_access.md diff --git a/docs/extra_luacs/examples.md b/docs/extra/lua_cutscene/examples.md similarity index 98% rename from docs/extra_luacs/examples.md rename to docs/extra/lua_cutscene/examples.md index 4ee710b..7811f09 100644 --- a/docs/extra_luacs/examples.md +++ b/docs/extra/lua_cutscene/examples.md @@ -51,7 +51,7 @@ Cursor @ 以防你还不知道, 游戏的坐标系与常规的数学坐标系不同, 其 y 坐标经过了竖直翻转: -![game-coord](../coding_challenges/images/simple_entity/game_coord.png) +![game-coord](../../coding_challenges/images/simple_entity/game_coord.png) ## 片段 diff --git a/docs/extra_luacs/lua-in-vscode.png b/docs/extra/lua_cutscene/lua-in-vscode.png similarity index 100% rename from docs/extra_luacs/lua-in-vscode.png rename to docs/extra/lua_cutscene/lua-in-vscode.png diff --git a/docs/extra_luacs/reference.md b/docs/extra/lua_cutscene/reference.md similarity index 100% rename from docs/extra_luacs/reference.md rename to docs/extra/lua_cutscene/reference.md diff --git a/docs/other/xml-speedrun.md b/docs/extra/xml/xml-speedrun.md similarity index 100% rename from docs/other/xml-speedrun.md rename to docs/extra/xml/xml-speedrun.md diff --git a/docs/extra_cmcc/cmcc b/docs/extra_cmcc/cmcc deleted file mode 160000 index bd18d76..0000000 --- a/docs/extra_cmcc/cmcc +++ /dev/null @@ -1 +0,0 @@ -Subproject commit bd18d76948bfaa85154b5d1ca1a161582ab1fb4a diff --git a/docs/extra_cmcc/index.md b/docs/extra_cmcc/index.md deleted file mode 100644 index d52a025..0000000 --- a/docs/extra_cmcc/index.md +++ /dev/null @@ -1,5 +0,0 @@ -# 额外 - CMCC - -欢迎来到又一个额外章节, 不过这里不是一个新主题, 只是一个由 [ForkKILLET](https://github.com/ForkKILLET) 建立的仓库 [CelesteMapperCooperationInChina](https://github.com/ForkKILLET/CelesteMapperCooperationInChina) (CMCC) 的一个网页呈现. - -源 github 仓库: [https://github.com/ForkKILLET/CelesteMapperCooperationInChina](https://github.com/ForkKILLET/CelesteMapperCooperationInChina) \ No newline at end of file diff --git a/docs/misc/change_log.md b/docs/misc/change_log.md index 6f3456c..f6d3dcd 100644 --- a/docs/misc/change_log.md +++ b/docs/misc/change_log.md @@ -2,10 +2,9 @@ ## 前言 -总之, 这里是更改日志 虽然说翻 github 也能翻到就是了, 不过还是写出来更方便(? +总之, 这里是更改日志 虽然说翻 Github 也能翻到就是了, 不过还是写出来更方便(? 一些比较大的改动和纠错会记录在这, 至于一些重写了的页面会扔进历史归档中 -因为时间比较久远, 更改日志从 AppleSheep 重构整个教程开始 ## ChangeLog @@ -17,18 +16,19 @@ ### 2024.12.11 * 添加夜间模式 -* 分离[阅读代码](../coding_setup/code_reading.md) -* 分离 [StateMachine](../components/statemachine.md) +* 分离[一些准备 - 阅读代码](../coding_setup/code_reading.md) +* 分离 [组件 - StateMachine](../components/statemachine.md) ### 2024.12.16 -* 添加[跨 Mod 交互](../advanced/cross_mod_interactions.md) +* 添加[进阶 - 跨 Mod 交互](../advanced/cross_mod_interactions.md) ### 2024.12.21 * 更新项目模板 -* 归档并重写[基础环境配置 - 通过模板创建项目](../coding_setup/basic_env.md) -* 添加[测试地图](../coding_challenges/test_map.md) -* 完善[跨 Mod 交互](../advanced/cross_mod_interactions.md) +* 归档并重写[一些准备 - 基础环境配置 - #通过模板创建项目](../coding_setup/basic_env.md) +* 添加[实战 - 测试地图](../coding_challenges/test_map.md) +* 完善[进阶 - 跨 Mod 交互](../advanced/cross_mod_interactions.md) ### 2025.1.16 -* 完善[调试](../coding_setup/debug.md) -- 完善[跨 Mod 交互 - ModInterop](../advanced/cross_mod_interactions.md) +* 重构[一些准备 - 调试](../coding_setup/debug.md) +- 完善[进阶 - 跨 Mod 交互 - #ModInterop](../advanced/cross_mod_interactions.md) +- 合并[额外 - CMCC](../extra/cmcc/index.md), [额外 - LuaCutscene](../extra/lua_cutscene/begin.md) 以及[其他 - XML 简单介绍](../extra/xml/xml-speedrun.md) 至额外章节以优化排版 diff --git a/docs/misc/to_do_list.md b/docs/misc/to_do_list.md index d30de67..ec4f8cb 100644 --- a/docs/misc/to_do_list.md +++ b/docs/misc/to_do_list.md @@ -4,7 +4,8 @@ 这里是 AppleSheep, 本教程后续的维护应该都由我负责 -这里列出了自己的一些代办事项, 如果有什么想法或建议可以QQ私聊我(可以在二群 962344157 或是 coder 群 550358997 找到我) +这里列出了自己的一些代办事项, 以优先级进行排序. 如果有什么想法或建议可以 QQ 私聊我(可以在二群 962344157 或是 coder 群 550358997 找到我) +唔 似乎直接把自己的 QQ 534310154 发出来更合适, 虽然还是不太敢就是了(草 ## ToDoList @@ -12,12 +13,13 @@ | ----------------------------- | ------ | | 分离 Loenn 节及补充 | 进行中 | | 重写 EC 架构相关 | 准备中 | -| everest 自带事件 | 计划中 | +| 添加 碰撞检测 | 计划中 | +| 添加 输入获取 | 计划中 | +| 添加 资产管理 | 计划中 | +| 添加 everest 自带事件 | 计划中 | | 分离已有的组件进行重写 | 计划中 | -| 完善 VisualStudio C# 调试 | 计划中 | | 重构 Hook 节 | 计划中 | | 分离 DynamicData 相关 | 计划中 | -| 完善 StateMachine | 计划中 | | 添加 Effect 相关 | 计划中 | -| 添加 Collider 相关 | 计划中 | + diff --git a/mkdocs.yml b/mkdocs.yml index a1d3e4c..a571904 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -92,18 +92,18 @@ nav: - Sprite, Image: "components/sprite_image.md" - Alarm, Tween, Coroutine: "components/alarm_tween_coroutine.md" - StateMachine: "components/statemachine.md" - - 其他: - - XML简单介绍: "other/xml-speedrun.md" - - 额外 - LuaCutscene: - - 开始: "extra_luacs/begin.md" - - 参考: "extra_luacs/reference.md" - - C# 交互: "extra_luacs/cs_access.md" - - 例子: "extra_luacs/examples.md" - # - 高级对话: "extra_luacs/advanced_dialog.md" - - 额外 - CMCC: - - 首页: "extra_cmcc/index.md" - - readme: "extra_cmcc/cmcc/ReadMe.md" - - FAQ: "extra_cmcc/cmcc/todo.md" + - 额外: + - CMCC: + - 首页: "extra/cmcc/index.md" + - readme: "extra/cmcc/ReadMe.md" + - FAQ: "extra/cmcc/todo.md" + - LuaCutscene: + - 开始: "extra/lua_cutscene/begin.md" + - 参考: "extra/lua_cutscene/reference.md" + - C# 交互: "extra/lua_cutscene/cs_access.md" + - 例子: "extra/lua_cutscene/examples.md" + - XML: + - XML 简单介绍: "extra/xml/xml-speedrun.md" - 历史归档: - 基础环境配置: "arc/basic_env.md" - 通过模板创建项目: "arc/project_template.md" From 7d8a16cb62cfb34bbb0388c78a898259961a2238 Mon Sep 17 00:00:00 2001 From: ClearZer0 <534310154@qq.com> Date: Fri, 17 Jan 2025 13:15:40 +0800 Subject: [PATCH 03/26] =?UTF-8?q?=E9=87=8D=E5=AE=9A=E5=90=91CMCC=E5=AD=90?= =?UTF-8?q?=E4=BB=93=E5=BA=93?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitmodules | 6 +++--- docs/extra/cmcc/index.md | 5 +++++ docs/extra/cmcc/remote | 1 + mkdocs.yml | 4 ++-- 4 files changed, 11 insertions(+), 5 deletions(-) create mode 100644 docs/extra/cmcc/index.md create mode 160000 docs/extra/cmcc/remote diff --git a/.gitmodules b/.gitmodules index 52b095b..e6c3d98 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,3 @@ -[submodule "docs/extra_cmcc/cmcc"] - path = docs/extra_cmcc/cmcc - url = https://github.com/ForkKILLET/CelesteMapperCooperationInChina +[submodule "docs/extra/cmcc/remote"] + path = docs/extra/cmcc/remote + url = https://github.com/ForkKILLET/CelesteMapperCooperationInChina.git diff --git a/docs/extra/cmcc/index.md b/docs/extra/cmcc/index.md new file mode 100644 index 0000000..efcfd2e --- /dev/null +++ b/docs/extra/cmcc/index.md @@ -0,0 +1,5 @@ +# CMCC + +欢迎来到这个额外章节, 不过这里不是一个新主题, 只是一个由 [ForkKILLET](https://github.com/ForkKILLET) 建立的仓库 [CelesteMapperCooperationInChina](https://github.com/ForkKILLET/CelesteMapperCooperationInChina) (CMCC) 的一个网页呈现. + +源 github 仓库: [https://github.com/ForkKILLET/CelesteMapperCooperationInChina](https://github.com/ForkKILLET/CelesteMapperCooperationInChina) \ No newline at end of file diff --git a/docs/extra/cmcc/remote b/docs/extra/cmcc/remote new file mode 160000 index 0000000..5a96c28 --- /dev/null +++ b/docs/extra/cmcc/remote @@ -0,0 +1 @@ +Subproject commit 5a96c2831a86f9103e6af7b1b9f706d00bc5c565 diff --git a/mkdocs.yml b/mkdocs.yml index a571904..8115874 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -95,8 +95,8 @@ nav: - 额外: - CMCC: - 首页: "extra/cmcc/index.md" - - readme: "extra/cmcc/ReadMe.md" - - FAQ: "extra/cmcc/todo.md" + - readme: "extra/cmcc/remote/ReadMe.md" + - FAQ: "extra/cmcc/remote/todo.md" - LuaCutscene: - 开始: "extra/lua_cutscene/begin.md" - 参考: "extra/lua_cutscene/reference.md" From 54cc22bf7d66f407c1f085572f67327df6898482 Mon Sep 17 00:00:00 2001 From: ClearZer0 <534310154@qq.com> Date: Fri, 17 Jan 2025 16:59:18 +0800 Subject: [PATCH 04/26] Update change_log.md --- docs/misc/change_log.md | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/docs/misc/change_log.md b/docs/misc/change_log.md index f6d3dcd..2306b4e 100644 --- a/docs/misc/change_log.md +++ b/docs/misc/change_log.md @@ -30,5 +30,8 @@ ### 2025.1.16 * 重构[一些准备 - 调试](../coding_setup/debug.md) -- 完善[进阶 - 跨 Mod 交互 - #ModInterop](../advanced/cross_mod_interactions.md) -- 合并[额外 - CMCC](../extra/cmcc/index.md), [额外 - LuaCutscene](../extra/lua_cutscene/begin.md) 以及[其他 - XML 简单介绍](../extra/xml/xml-speedrun.md) 至额外章节以优化排版 +* 完善[进阶 - 跨 Mod 交互 - #ModInterop](../advanced/cross_mod_interactions.md) +* 合并[额外 - CMCC](../extra/cmcc/index.md), [额外 - LuaCutscene](../extra/lua_cutscene/begin.md) 以及[其他 - XML 简单介绍](../extra/xml/xml-speedrun.md) 至额外章节以优化排版 + +### 2025.1.17 +* Loenn stuff 先在更新日志占个位(草草 \ No newline at end of file From 475947e1499e62fb362c6b820dc34851a71482cc Mon Sep 17 00:00:00 2001 From: ClearZer0 <534310154@qq.com> Date: Sun, 19 Jan 2025 15:50:24 +0800 Subject: [PATCH 05/26] =?UTF-8?q?=E9=87=8D=E6=9E=84=E8=B0=83=E8=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/coding_setup/basic_env.md | 64 +----------------- docs/coding_setup/debug.md | 101 ++++++++++++++++++++++++++++- docs/extra/cmcc/remote | 2 +- docs/extra/lua/simple_introduce.md | 0 docs/misc/change_log.md | 2 +- mkdocs.yml | 7 +- 6 files changed, 110 insertions(+), 66 deletions(-) create mode 100644 docs/extra/lua/simple_introduce.md diff --git a/docs/coding_setup/basic_env.md b/docs/coding_setup/basic_env.md index f74d388..951d2b9 100644 --- a/docs/coding_setup/basic_env.md +++ b/docs/coding_setup/basic_env.md @@ -169,38 +169,13 @@ public class MyCelesteModModule : EverestModule - `Unload` 方法在你的 mod 被卸载时调用. 通常我们会在 `Load` 方法里加载我们需要的资源, 进行适当的初始化, 在 `Unload` 方法里释放我们的资源. -在这里为了明显可见, 我们在 `Load` 方法里通过一个蔚蓝中的类 `Logger` 打印出了一句 "Hello World". - -??? note "如果你好奇 `Logger.Log` 这个方法你可以展开来了解" - `Logger` 是一个蔚蓝底层引擎 `Monocle` 的一个工具类, 它帮助你打印输出一些调试信息, - 通常这些信息会被打印进控制台的同时写入游戏的 `log.txt` 文件中, - 这也就解释了为什么你遇到各种问题时别人总要求你发送你的 `log.txt`. - `Logger.Log` 有两个重载, 其中一个的签名是: - ```cs - public static void Log(LogLevel logLevel, string tag, string str) - ``` - 它会以 `logLevel` 的日志等级打印一个标签为 `tag` 的消息 `str`, - 另一个重载不要求你传入 `logLevel` 但会默认你的 `logLevel` 为 `LogLevel.Verbose`. - `LogLevel` 枚举包含 `Verbose, Debug, Info, Warn, Error`. - 通常对于普通日志我们会选择 `Info`, 对于较多的调试信息选择 `Debug`, - 对于冗余的信息选择 `Verbose`, 对于一些错误但不影响游戏进行的信息选择 `Warn`, 对于一些致命性错误我们会选择 `Error`. - 一般地, 游戏只会打印 `Info` 等级及以上的日志, 你可以通过在蔚蓝启动的命令行中加入`--loglevel {等级}`来指定过滤等级. ## everest.yaml ok, 我们前面几乎巴拉巴拉讲了几乎三千多个字, 但是依然没有让蔚蓝加载到我们的mod, 不过别急, 这是倒数第二步了. 实际上有关 code mod 的所有代码相关的东西我们都已经做完了, 剩余的其实只是一个普通 mod 要做的 ---- 写 `everest.yaml`. -在这里我们需要在 `ModFolder` 这个文件夹里做这件事, 那么, 在你的这个文件夹下创建 `everest.yaml` 空文件, 你的目录结构可能像是: - -!!! note - `.dll` 文件和 `.pdb` 文件仅会在你构建过项目后出现, 有时候甚至 ModFolder 目录也会在构建过后出现 - -- ModFolder - - everest.yaml - - MyCelesteMod.dll - - MyCelesteMod.pdb -好的, 现在我们打开 `everest.yaml`, 然后像一个普通的 mapper 一样填写信息: +好的, 现在我们找到模板自动生成的 `everest.yaml` 并打开 , 然后像一个普通的 mapper 一样填写信息: ```yml - Name: MyCelesteMod Version: 0.1.0 @@ -215,43 +190,10 @@ ok, 我们前面几乎巴拉巴拉讲了几乎三千多个字, 但是依然没 - `Version`: 你的 mod 的版本 - `DLL`: 如果你是 code mod 的话, 这里填入你的 code (也就是 dll 文件) 的位置, 这里我们是直接把 .dll 文件放到这个 yaml 的旁边了, 所以直接写名字就好 -最后是最底下的那个依赖, 这里我们只依赖最基础的 Everest, 版本填上你目前使用的 Everest 版本, 这里我就填写 3971 了. +最后是最底下的那个依赖, 这里我们只依赖最基础的 Everest, 版本填上你目前使用的 Everest 版本. 如果你的 mod 依赖 Everest Core, 你需要在这里将 `Everest` 更改为 `EverestCore`, 并将版本号填写大于 4465 的值. -## 热重载以及结语 - -为了方便我们的调试, 我们需要让蔚蓝打开的同时打开控制台, 这一步很简单: - -- 找到蔚蓝根目录下的 `everest-launch.txt`, 没有的话新建一个空的就行了 -- 向里面写入 `--console` -- 搞定, 走你! - -现在, 重新编译项目, 让 `msbuild` 带着你的 `ModFolder` 的内容前往蔚蓝 Mods 文件夹下, 启动蔚蓝. -在同时启动的黑乎乎的命令行窗口上你应该能在这附近看到那句熟悉的 Hello world: -```log hl_lines="7" -(07/08/2023 21:18:59) [Everest] [Info] [core] Module DialogCutscene 1.0.0 registered. -(07/08/2023 21:18:59) [Everest] [Info] [core] Module UpdateChecker 1.0.2 registered. -(07/08/2023 21:18:59) [Everest] [Info] [core] Module InfiniteSaves 1.0.0 registered. -(07/08/2023 21:18:59) [Everest] [Info] [core] Module DebugRebind 1.0.0 registered. -(07/08/2023 21:18:59) [Everest] [Info] [core] Module RebindPeriod 1.0.0 registered. -(07/08/2023 21:19:00) [Everest] [Info] [Everest.LuaBoot] Lua ready. -(07/08/2023 21:19:00) [Everest] [Info] [MyCelesteMod] Hello World! -(07/08/2023 21:19:00) [Everest] [Info] [core] Module MyAwesomeMod 0.1.0 registered. -(07/08/2023 21:19:00) [Everest] [Info] [loader] Loading mods with unsatisfied optional dependencies (if any) -FNA3D Driver: D3D11 -D3D11 Adapter: Intel(R) UHD Graphics 630 -``` - - -在经过如上的配置后, 你会发现在蔚蓝启动的时候, 进行编译并复制资源时会报错, -这是因为 Everest 锁定占用了它们, 导致你不得不让这一切在蔚蓝关闭时进行, -同时由于蔚蓝的重启速度不是很理想, 这大大的拉低了 mod 开发效率. -不过好在 Everest 提供了一个技术叫做 `code hot reload`, -即热重载, 它允许你在游戏运行期间替换你的代码并重载资源, 它目前还在 wip 状态. -要开启这项功能, 首先到你的蔚蓝根目录下的 Saves 目录, 找到并打开 `modsettings-Everest.celeste` 这个文件, -翻到大概中间的位置, 找到属性 `CodeReload_WIP`, 将其更改为 `true`, 此时重新编译你的项目, -你应该就不会再得到任何错误, 并且 Everest 也正确地热重载了你的 mod 和你的 mod 资源. - +## 结语 这一节完成后你的目录结构大概会像是 外部模板: diff --git a/docs/coding_setup/debug.md b/docs/coding_setup/debug.md index be4a52b..9374c02 100644 --- a/docs/coding_setup/debug.md +++ b/docs/coding_setup/debug.md @@ -1,9 +1,108 @@ # Debug 调试 -只要写程序就免不了 bug, 所以我们需要强有力的 debug 手段 +只要写程序就免不了 bug, 所以我们需要强有力的 debug 手段. ![code_joke](images/debug/code_joke.jpg) +## 热重载 + +为了方便我们的调试, 我们需要让蔚蓝打开的同时打开控制台, 这一步很简单: + +- 找到蔚蓝根目录下的 `everest-launch.txt`, 没有的话新建一个空的就行了 +- 向里面写入 `--console` + +```txt title="everest-launch.txt" hl_lines="7" +# Add any Everest launch flags here. +# Lines starting with # are ignored. +# All options here are disabled by default. +# Full list: https://github.com/EverestAPI/Resources/wiki/Command-Line-Arguments + +# Windows only: open a separate log console window. +--console + +# FNA only: force OpenGL (might be necessary to bypass a load crash on some PCs). +#--graphics OpenGL + +# Change default log level (verbose will print all logs). +#--loglevel verbose +``` + +现在, 重新编译项目, 启动蔚蓝, 你应该能看到同时启动的命令行窗口. + +在经过如上的配置后, 你会发现在蔚蓝启动的时候, 进行编译并复制资源时会报错, +这是因为 Everest 锁定占用了它们, 导致你不得不让这一切在蔚蓝关闭时进行, +同时由于蔚蓝的重启速度不是很理想, 这大大的拉低了 mod 开发效率. +不过好在 Everest 提供了一个技术叫做 `code hot reload`, +即热重载, 它允许你在游戏运行期间替换你的代码并重载资源, 它目前还在 wip 状态. +要开启这项功能, 首先到你的蔚蓝根目录下的 Saves 目录, 找到并打开 `modsettings-Everest.celeste` 这个文件, +翻到大概中间的位置, 找到属性 `CodeReload_WIP`, 将其更改为 `true`. + +``` title="modsettings-Everest.celeste" hl_lines="11" +// 其他设置 + +PhotosensitiveMode: false +PhotosensitivityDistortOverride: false +PhotosensitivityGlitchOverride: false +PhotosensitivityLightningOverride: false +PhotosensitivityScreenFlashOverride: false +PhotosensitivityTextHighlightOverride: false +QuickRestart: +ShowManualTextOnDebugMap: true +CodeReload_WIP: true +UseInGameCrashHandler: true +CrashHandlerAlwaysTeabag: false +CurrentVersion: 1.4465.0 +CurrentBranch: updater_src_stable +LogLevels: {} + +// 其他设置 +``` + +完成设置后重新编译项目, 你应该就不会再得到任何错误, 并且 Everest 也正确地热重载了你的 mod 和你的 mod 资源. + +## Logger + +`Logger` 是一个蔚蓝底层引擎 `Monocle` 的一个工具类, 它帮助你打印输出一些调试信息, +通常这些信息会被打印进控制台的同时写入游戏的 `log.txt` 文件中, +这也就解释了为什么你遇到各种问题时别人总要求你发送你的 `log.txt`. + +`Logger.Log` 有两个重载, 其中一个的签名是: +```cs +public static void Log(LogLevel logLevel, string tag, string str) +``` +它会以 `logLevel` 的日志等级打印一个标签为 `tag` 的消息 `str`, +另一个重载不要求你传入 `logLevel` 但会默认你的 `logLevel` 为 `LogLevel.Verbose`. + +`LogLevel` 包含以下枚举, 以优先级从低到高排序: + +- `Verbose`: 一般用于输出冗余的日志信息. +- `Debug`: 一般用于输出较多的调试信息. +- `info`: 一般用于输出普通日志. +- `Warn`: 一般用于输出一些错误但不影响游戏进行的信息. +- `Error`: 一般用于输出一些致命性错误. + +一般地, 游戏只会打印 `Info` 等级及以上的日志, 你可以通过在 `everest-launch.txt` 中加入`--loglevel {等级}`来指定过滤等级. + +下面是一些使用示例: + +```cs +Logger.Log(LogLevel.Info, "MyCelesteMod", "Hello my Celeste!"); +Logger.Log(LogLevel.Info, "YourCelesteMod", "Hello your Celeste!"); +Logger.Log(LogLevel.Warn, "MyCelesteMod", "This is a warn!"); +Logger.Log(LogLevel.Error, "MyCelesteMod", "Fatal error!"); +``` + +这会在控制台输出: + +```log +(01/19/2025 15:19:00) [Everest] [Info] [MyCelesteMod] Hello my Celeste! +(01/19/2025 15:19:00) [Everest] [Info] [YourCelesteMod] Hello your Celeste! +(01/19/2025 15:19:00) [Everest] [warn] [MyCelesteMod] This is a warn! +(01/19/2025 15:19:00) [Everest] [Error] [MyCelesteMod] Fatal error! +``` + +## 附加到进程 + 最常见的 debug 手段是通过 `Logger.Log()`, 能解决大部分问题, 但当项目做大, 嵌套变多, `Logger` 输出的信息已经满足不了我们的时候(甚至我们都不知道这个 bug 哪儿来的), 我们一般就要使用断点来调试, 步骤如下: * 打开蔚蓝 diff --git a/docs/extra/cmcc/remote b/docs/extra/cmcc/remote index 5a96c28..bb773b2 160000 --- a/docs/extra/cmcc/remote +++ b/docs/extra/cmcc/remote @@ -1 +1 @@ -Subproject commit 5a96c2831a86f9103e6af7b1b9f706d00bc5c565 +Subproject commit bb773b2d21a819cf68aee269df07d250ba062f4b diff --git a/docs/extra/lua/simple_introduce.md b/docs/extra/lua/simple_introduce.md new file mode 100644 index 0000000..e69de29 diff --git a/docs/misc/change_log.md b/docs/misc/change_log.md index 2306b4e..46517b5 100644 --- a/docs/misc/change_log.md +++ b/docs/misc/change_log.md @@ -31,7 +31,7 @@ ### 2025.1.16 * 重构[一些准备 - 调试](../coding_setup/debug.md) * 完善[进阶 - 跨 Mod 交互 - #ModInterop](../advanced/cross_mod_interactions.md) -* 合并[额外 - CMCC](../extra/cmcc/index.md), [额外 - LuaCutscene](../extra/lua_cutscene/begin.md) 以及[其他 - XML 简单介绍](../extra/xml/xml-speedrun.md) 至额外章节以优化排版 +* 移动[额外 - CMCC](../extra/cmcc/index.md), [额外 - LuaCutscene](../extra/lua_cutscene/begin.md) 以及[其他 - XML 简单介绍](../extra/xml/xml-speedrun.md) 至额外章节以优化排版 ### 2025.1.17 * Loenn stuff 先在更新日志占个位(草草 \ No newline at end of file diff --git a/mkdocs.yml b/mkdocs.yml index 8115874..0facb27 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -97,13 +97,16 @@ nav: - 首页: "extra/cmcc/index.md" - readme: "extra/cmcc/remote/ReadMe.md" - FAQ: "extra/cmcc/remote/todo.md" + - XML: + - XML 简单介绍: "extra/xml/xml-speedrun.md" + - Lua: + - Lua 简单介绍: "extra/lua/simple_introduce.md" - LuaCutscene: - 开始: "extra/lua_cutscene/begin.md" - 参考: "extra/lua_cutscene/reference.md" - C# 交互: "extra/lua_cutscene/cs_access.md" - 例子: "extra/lua_cutscene/examples.md" - - XML: - - XML 简单介绍: "extra/xml/xml-speedrun.md" + - 历史归档: - 基础环境配置: "arc/basic_env.md" - 通过模板创建项目: "arc/project_template.md" From e37cf71caea5e39f102e34e8483c328d6be7d8bc Mon Sep 17 00:00:00 2001 From: ClearZer0 <534310154@qq.com> Date: Sun, 19 Jan 2025 15:53:35 +0800 Subject: [PATCH 06/26] Update debug.md --- docs/coding_setup/debug.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/coding_setup/debug.md b/docs/coding_setup/debug.md index 9374c02..db126f4 100644 --- a/docs/coding_setup/debug.md +++ b/docs/coding_setup/debug.md @@ -77,7 +77,7 @@ public static void Log(LogLevel logLevel, string tag, string str) - `Verbose`: 一般用于输出冗余的日志信息. - `Debug`: 一般用于输出较多的调试信息. -- `info`: 一般用于输出普通日志. +- `Info`: 一般用于输出普通日志. - `Warn`: 一般用于输出一些错误但不影响游戏进行的信息. - `Error`: 一般用于输出一些致命性错误. From 820c801251dc8673c1123aef73b22188fd0e8596 Mon Sep 17 00:00:00 2001 From: ClearZer0 <534310154@qq.com> Date: Sun, 19 Jan 2025 19:03:41 +0800 Subject: [PATCH 07/26] requested --- docs/advanced/cross_mod_interactions.md | 2 +- docs/coding_setup/debug.md | 17 ++++++++++------- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/docs/advanced/cross_mod_interactions.md b/docs/advanced/cross_mod_interactions.md index c23fb8f..d6785e5 100644 --- a/docs/advanced/cross_mod_interactions.md +++ b/docs/advanced/cross_mod_interactions.md @@ -141,8 +141,8 @@ public static class MyCelesteModAPI // 如果导出的方法参数中有 in, out 或 ref 需要定义自定义委托类型以进行导入 // Func 并不支持参数中带有 in, out 或 ref 的情况 - public static TryDoubleIfEvenDelegate TryDoubleIfEven; public delegate bool TryDoubleIfEvenDelegate(int number, out int? doubledNumber); + public static TryDoubleIfEvenDelegate TryDoubleIfEven; } ``` diff --git a/docs/coding_setup/debug.md b/docs/coding_setup/debug.md index db126f4..dacb16d 100644 --- a/docs/coding_setup/debug.md +++ b/docs/coding_setup/debug.md @@ -8,8 +8,11 @@ 为了方便我们的调试, 我们需要让蔚蓝打开的同时打开控制台, 这一步很简单: -- 找到蔚蓝根目录下的 `everest-launch.txt`, 没有的话新建一个空的就行了 -- 向里面写入 `--console` +- 找到蔚蓝根目录下的 `everest-launch.txt`, 没有的话新建一个空的就行了. +- 向里面写入 `--console`. + +!!!info + `--console` 项只在 `Windows` 系统上有用. ```txt title="everest-launch.txt" hl_lines="7" # Add any Everest launch flags here. @@ -33,12 +36,12 @@ 这是因为 Everest 锁定占用了它们, 导致你不得不让这一切在蔚蓝关闭时进行, 同时由于蔚蓝的重启速度不是很理想, 这大大的拉低了 mod 开发效率. 不过好在 Everest 提供了一个技术叫做 `code hot reload`, -即热重载, 它允许你在游戏运行期间替换你的代码并重载资源, 它目前还在 wip 状态. +即热重载, 它允许你在游戏运行期间替换你的代码并重载资源. 要开启这项功能, 首先到你的蔚蓝根目录下的 Saves 目录, 找到并打开 `modsettings-Everest.celeste` 这个文件, 翻到大概中间的位置, 找到属性 `CodeReload_WIP`, 将其更改为 `true`. -``` title="modsettings-Everest.celeste" hl_lines="11" -// 其他设置 +```yaml title="modsettings-Everest.celeste" hl_lines="11" +# 其他设置 PhotosensitiveMode: false PhotosensitivityDistortOverride: false @@ -55,14 +58,14 @@ CurrentVersion: 1.4465.0 CurrentBranch: updater_src_stable LogLevels: {} -// 其他设置 +# 其他设置 ``` 完成设置后重新编译项目, 你应该就不会再得到任何错误, 并且 Everest 也正确地热重载了你的 mod 和你的 mod 资源. ## Logger -`Logger` 是一个蔚蓝底层引擎 `Monocle` 的一个工具类, 它帮助你打印输出一些调试信息, +`Logger` 是一个蔚蓝底层引擎 `Everest` 的一个工具类, 它帮助你打印输出一些调试信息, 通常这些信息会被打印进控制台的同时写入游戏的 `log.txt` 文件中, 这也就解释了为什么你遇到各种问题时别人总要求你发送你的 `log.txt`. From 492b67a7382ffe03f29f0756bb9ee55786dbc5e4 Mon Sep 17 00:00:00 2001 From: ClearZer0 <534310154@qq.com> Date: Sun, 19 Jan 2025 19:26:59 +0800 Subject: [PATCH 08/26] =?UTF-8?q?=E7=BA=A0=E9=94=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/coding_setup/debug.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/coding_setup/debug.md b/docs/coding_setup/debug.md index dacb16d..4f01cdd 100644 --- a/docs/coding_setup/debug.md +++ b/docs/coding_setup/debug.md @@ -65,7 +65,7 @@ LogLevels: {} ## Logger -`Logger` 是一个蔚蓝底层引擎 `Everest` 的一个工具类, 它帮助你打印输出一些调试信息, +`Logger` 是一个蔚蓝 `Everest` 的一个工具类, 它帮助你打印输出一些调试信息, 通常这些信息会被打印进控制台的同时写入游戏的 `log.txt` 文件中, 这也就解释了为什么你遇到各种问题时别人总要求你发送你的 `log.txt`. From 44da7124eab602f1388ac345d78ff005ad6d6c9a Mon Sep 17 00:00:00 2001 From: ClearZer0 <534310154@qq.com> Date: Mon, 20 Jan 2025 00:07:53 +0800 Subject: [PATCH 09/26] =?UTF-8?q?Lua=E9=80=9F=E9=80=9Apart=201?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../lua/{simple_introduce.md => Sample.lua} | 0 docs/extra/lua/begin.md | 18 ++++++ docs/extra/lua/control_flow.md | 0 docs/extra/lua/data_structure.md | 0 docs/extra/lua/function.md | 0 docs/extra/lua/images/begin/lua_in_vscode.png | Bin 0 -> 24305 bytes docs/extra/lua/iterator.md | 0 docs/extra/lua/package.md | 0 docs/extra/lua/syntax.md | 53 ++++++++++++++++++ docs/extra/lua_cutscene/begin.md | 11 ---- docs/extra/lua_cutscene/lua-in-vscode.png | Bin 52743 -> 0 bytes mkdocs.yml | 8 ++- 12 files changed, 78 insertions(+), 12 deletions(-) rename docs/extra/lua/{simple_introduce.md => Sample.lua} (100%) create mode 100644 docs/extra/lua/begin.md create mode 100644 docs/extra/lua/control_flow.md create mode 100644 docs/extra/lua/data_structure.md create mode 100644 docs/extra/lua/function.md create mode 100644 docs/extra/lua/images/begin/lua_in_vscode.png create mode 100644 docs/extra/lua/iterator.md create mode 100644 docs/extra/lua/package.md create mode 100644 docs/extra/lua/syntax.md delete mode 100644 docs/extra/lua_cutscene/lua-in-vscode.png diff --git a/docs/extra/lua/simple_introduce.md b/docs/extra/lua/Sample.lua similarity index 100% rename from docs/extra/lua/simple_introduce.md rename to docs/extra/lua/Sample.lua diff --git a/docs/extra/lua/begin.md b/docs/extra/lua/begin.md new file mode 100644 index 0000000..08a924f --- /dev/null +++ b/docs/extra/lua/begin.md @@ -0,0 +1,18 @@ +# Lua + +## 前言 + +制图软件 `Loenn` 使用 `Lua` 作为开发语言. 相应的, 我们想要 `Loenn` 能加载到自定义实体也需要编写 `Lua` 脚本. + +这个额外章节将会介绍如何速通 Lua 一些编写 `Loenn` 侧自定义实体的加载脚本所必需的 `Lua` 知识. + +## 开发环境 + +这一步实际上是可选的, 不过为了更愉快的 `Lua` 脚本的编写, +个人还是觉得挺有必要的. +在这里我会推荐使用 [VSCode](https://code.visualstudio.com/Download) 配上 [Lua (sumneko.lua)](https://marketplace.visualstudio.com/items?itemName=sumneko.lua) +插件: +![lua-in-vscode](images/begin/lua_in_vscode.png) + +!!! note + 我个人不太会配置这种 lua 环境, 所以如果你遇到了大量的未定义警告你可以选择在设置中搜索 `Lua.diagnostics.enable` 并将其关闭. \ No newline at end of file diff --git a/docs/extra/lua/control_flow.md b/docs/extra/lua/control_flow.md new file mode 100644 index 0000000..e69de29 diff --git a/docs/extra/lua/data_structure.md b/docs/extra/lua/data_structure.md new file mode 100644 index 0000000..e69de29 diff --git a/docs/extra/lua/function.md b/docs/extra/lua/function.md new file mode 100644 index 0000000..e69de29 diff --git a/docs/extra/lua/images/begin/lua_in_vscode.png b/docs/extra/lua/images/begin/lua_in_vscode.png new file mode 100644 index 0000000000000000000000000000000000000000..571d5fbe640e68b465cfa63e06edf72dfa0524a0 GIT binary patch literal 24305 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 Date: Tue, 21 Jan 2025 01:02:34 +0800 Subject: [PATCH 10/26] =?UTF-8?q?=E8=BF=81=E7=A7=BB=E6=B5=8B=E8=AF=95?= =?UTF-8?q?=E5=9C=B0=E5=9B=BE=E8=87=B3=E6=96=B0=E7=9A=84=E6=A8=A1=E6=9D=BF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/{coding_setup => arc}/preference.md | 0 docs/extra/lua/syntax.md | 20 ++++++---- docs/index.md | 2 +- docs/misc/change_log.md | 20 +++++----- docs/misc/to_do_list.md | 13 ++++--- docs/resources/CelesteModTutorial.zip | Bin 13536 -> 9475 bytes mkdocs.yml | 4 +- .../Loenn/triggers/SampleTrigger.lua | 12 ++++++ .../Maps/CelesteModTutorial/Test.bin | Bin 790 -> 1017 bytes .../Source/CelesteMod.props | 8 +++- .../Source/CelesteMod.targets | 8 +--- .../Source/CelesteModTutorialModule.cs | 35 +++++++++--------- .../Source/CelesteModTutorialSaveData.cs | 7 ++-- .../Source/CelesteModTutorialSession.cs | 7 ++-- .../Source/CelesteModTutorialSettings.cs | 7 ++-- 15 files changed, 81 insertions(+), 62 deletions(-) rename docs/{coding_setup => arc}/preference.md (100%) create mode 100644 src/CelesteModTutorial/Loenn/triggers/SampleTrigger.lua diff --git a/docs/coding_setup/preference.md b/docs/arc/preference.md similarity index 100% rename from docs/coding_setup/preference.md rename to docs/arc/preference.md diff --git a/docs/extra/lua/syntax.md b/docs/extra/lua/syntax.md index d0f98a9..152e633 100644 --- a/docs/extra/lua/syntax.md +++ b/docs/extra/lua/syntax.md @@ -11,7 +11,7 @@ -- 这是单行注释 --[[ -这是多行注释的开始 +这是多行注释 多行注释可以跨越多行 --]] ``` @@ -20,8 +20,8 @@ `Lua` 中的标识符是用于定义一个变量, 函数, 表, 模块等名称的符号. 标识符的命名遵循以下规则: -- 标识符必须以字母(`a `到 `z`,`A `到 `Z`)或下划线 `_` 开头后加上0个或多个字母,下划线,数字(`0` 到 `9`) -- `Lua` 是大小写敏感的,所以 `variable` 和 `Variable` 是不同的标识符 +- 标识符必须以字母 (`a `到 `z`,`A `到 `Z`), 或下划线 `_` 开头后加上0个或多个字母,下划线,数字 (`0` 到 `9`). +- `Lua` 是大小写敏感的,所以 `variable` 和 `Variable` 是不同的标识符. - 标识符不能包含特殊字符例如 `@`, `$`, 与 `%` 等. - 标识符不能包含 `Lua` 中的保留关键字. @@ -43,11 +43,17 @@ -- 合法的标识符 x = 10 -- 以字母 x 开头 _var = "Hello" -- 以下划线开头 -var_1 = 3.14 -- 包含数字,但不能以数字开头 +var_1 = 3.14 -- 包含数字, 但不能以数字开头 myVariable = 5 -- 包含多个字母 function_name = "Lua" -- 包含下划线 -- 不合法的标识符 -0var = 20 -- 错误:不能以数字开头 -true = 5 -- 错误:`true` 是一个保留字 -``` \ No newline at end of file +0var = 20 -- 不能以数字开头 +true = 5 -- `true` 是一个保留关键字 +``` + +## 作用域 + +`Lua` 中默认情况下定义的变量与函数都是全局的, 与 `C#` 中的 `public` 访问修饰符相同, 全局变量与全局函数在整个程序中的任何位置都可以被访问与修改. + +直接定义的变量默认是全局的 \ No newline at end of file diff --git a/docs/index.md b/docs/index.md index 95cfadf..74a4d95 100644 --- a/docs/index.md +++ b/docs/index.md @@ -12,7 +12,7 @@ 顺便感谢一些为本教程贡献的人: -- AppleSheep - 在写作初期提供了大量修改建议 目前正在重构整个教程([Bilibili](https://space.bilibili.com/227488539)) +- AppleSheep - 在写作初期提供了大量修改建议 目前正在维护整个教程([Bilibili](https://space.bilibili.com/227488539)) - 夜谷紫幽 - 为配置环境节提供了使用模板的建议 ([Bilibili](https://space.bilibili.com/346379712)) - 电箱 - 制作了包含基础 Loenn 使用教程的作图教程 ([Bilibili](https://space.bilibili.com/240308518)) - Lucky boy - [Session, Settings, SaveData](basics/session_settings_savedata.md) 节的一些补充, 以及钩取 Helper 方法, debug, tracker, flag, tag 节的作者 ([GitHub](https://github.com/LuckyBoy-7)) diff --git a/docs/misc/change_log.md b/docs/misc/change_log.md index 46517b5..65380e1 100644 --- a/docs/misc/change_log.md +++ b/docs/misc/change_log.md @@ -16,22 +16,24 @@ ### 2024.12.11 * 添加夜间模式 -* 分离[一些准备 - 阅读代码](../coding_setup/code_reading.md) +* 分离 [一些准备 - 阅读代码](../coding_setup/code_reading.md) * 分离 [组件 - StateMachine](../components/statemachine.md) ### 2024.12.16 -* 添加[进阶 - 跨 Mod 交互](../advanced/cross_mod_interactions.md) +* 编写 [进阶 - 跨 Mod 交互](../advanced/cross_mod_interactions.md) ### 2024.12.21 * 更新项目模板 -* 归档并重写[一些准备 - 基础环境配置 - #通过模板创建项目](../coding_setup/basic_env.md) -* 添加[实战 - 测试地图](../coding_challenges/test_map.md) -* 完善[进阶 - 跨 Mod 交互](../advanced/cross_mod_interactions.md) +* 归档并重写 [一些准备 - 基础环境配置 - #通过模板创建项目](../coding_setup/basic_env.md) +* 编写 [实战 - 测试地图](../coding_challenges/test_map.md) +* 完善 [进阶 - 跨 Mod 交互](../advanced/cross_mod_interactions.md) ### 2025.1.16 -* 重构[一些准备 - 调试](../coding_setup/debug.md) -* 完善[进阶 - 跨 Mod 交互 - #ModInterop](../advanced/cross_mod_interactions.md) -* 移动[额外 - CMCC](../extra/cmcc/index.md), [额外 - LuaCutscene](../extra/lua_cutscene/begin.md) 以及[其他 - XML 简单介绍](../extra/xml/xml-speedrun.md) 至额外章节以优化排版 +* 归档 [一些准备 - 偏好](../arc/preference.md) +* 重构 [一些准备 - 调试](../coding_setup/debug.md) +* 完善 [进阶 - 跨 Mod 交互 - #ModInterop](../advanced/cross_mod_interactions.md) +* 移动 [额外 - CMCC](../extra/cmcc/index.md), [额外 - LuaCutscene](../extra/lua_cutscene/begin.md) 以及[其他 - XML 简单介绍](../extra/xml/xml-speedrun.md) 至额外章节以优化排版 ### 2025.1.17 -* Loenn stuff 先在更新日志占个位(草草 \ No newline at end of file +* 更新项目模板 +* 编写 [额外 - Lua](../extra/lua/begin.md) \ No newline at end of file diff --git a/docs/misc/to_do_list.md b/docs/misc/to_do_list.md index ec4f8cb..02aad84 100644 --- a/docs/misc/to_do_list.md +++ b/docs/misc/to_do_list.md @@ -11,15 +11,16 @@ | 计划 | 状态 | | ----------------------------- | ------ | +| 编写 Lua 简易教程 | 进行中 | | 分离 Loenn 节及补充 | 进行中 | -| 重写 EC 架构相关 | 准备中 | -| 添加 碰撞检测 | 计划中 | -| 添加 输入获取 | 计划中 | -| 添加 资产管理 | 计划中 | -| 添加 everest 自带事件 | 计划中 | +| 重构 EC 架构相关 | 准备中 | +| 编写 碰撞检测 | 计划中 | +| 编写 输入获取 | 计划中 | +| 编写 资产管理 | 计划中 | +| 编写 Everest 自带事件 | 计划中 | | 分离已有的组件进行重写 | 计划中 | | 重构 Hook 节 | 计划中 | | 分离 DynamicData 相关 | 计划中 | -| 添加 Effect 相关 | 计划中 | +| 编写 Effect 相关 | 计划中 | diff --git a/docs/resources/CelesteModTutorial.zip b/docs/resources/CelesteModTutorial.zip index 08d1e839e9bc6d6118b20ede33e975393fcfdb39..cba8c972332099f351af0cd6f6ae52e1be572e73 100644 GIT binary patch literal 9475 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 AwEzGB literal 790 zcmZuu+fv&w5M4R8twE79l2Vhu>0>{k zpVZIj%7tl|;bEoKo^zzLt9ZYA*c~L@_15# z$TS+$oT(Ib$t}HAX)l4G6sgU_97UE}KS5*JJhED38EVtu(w;X@4Z675$#9ommGh1lE<#wMNvp4^SV1K4!sc$` zGmX*ZP_O*faa;LrAjnchNe>}cJ6;I6h^=T2mm~Y0T?u4^(}3; zDcY`l7Xa?jVU@tTD?Fg&F~t)IZoxVwHA0sh@{Fjj>A+~;bcHvRY)~vyY(el2Zn|m< zyf178*l!MWbD7}Ri&sAcued+4g_ep0X%e0p1S2P`18pZ diff --git a/src/CelesteModTutorial/Source/CelesteMod.props b/src/CelesteModTutorial/Source/CelesteMod.props index 7fc2704..99a33e1 100644 --- a/src/CelesteModTutorial/Source/CelesteMod.props +++ b/src/CelesteModTutorial/Source/CelesteMod.props @@ -22,7 +22,7 @@ - + @@ -32,7 +32,7 @@ $(CelesteRootPath)/MonoMod.RuntimeDetour.dll False + + $(CelesteRootPath)/MonoMod.Patcher.dll + False + \ No newline at end of file diff --git a/src/CelesteModTutorial/Source/CelesteMod.targets b/src/CelesteModTutorial/Source/CelesteMod.targets index 1e9a245..4140f99 100644 --- a/src/CelesteModTutorial/Source/CelesteMod.targets +++ b/src/CelesteModTutorial/Source/CelesteMod.targets @@ -17,14 +17,10 @@ Code="SMT03" Text="Legacy versions of Everest are not supported. Please update your Everest to 4465+."/> - - - - - $(CelesteRootPath)/Mods/Cache/%(Identity).%(Identity).dll - $(CelesteRootPath)/Mods/Cache/%(Identity).%(AssemblyName).dll + $(CelesteRootPath)/Mods/Cache/%(Identity).%(Identity).dll + $(CelesteRootPath)/Mods/Cache/%(Identity).%(AssemblyName).dll false diff --git a/src/CelesteModTutorial/Source/CelesteModTutorialModule.cs b/src/CelesteModTutorial/Source/CelesteModTutorialModule.cs index c49d11a..a5cc6b6 100644 --- a/src/CelesteModTutorial/Source/CelesteModTutorialModule.cs +++ b/src/CelesteModTutorial/Source/CelesteModTutorialModule.cs @@ -1,25 +1,26 @@ -namespace Celeste.Mod.CelesteModTutorial +namespace Celeste.Mod.CelesteModTutorial; + +public sealed class CelesteModTutorialModule : EverestModule { - public class CelesteModTutorialModule : EverestModule - { - public static CelesteModTutorialModule Instance { get; private set; } + public static CelesteModTutorialModule Instance { get; private set; } + + public override Type SettingsType => typeof(CelesteModTutorialSettings); + public static CelesteModTutorialSettings Settings => (CelesteModTutorialSettings)Instance._Settings; - public override Type SettingsType => typeof(CelesteModTutorialSettings); - public static CelesteModTutorialSettings Settings => (CelesteModTutorialSettings)Instance._Settings; + public override Type SessionType => typeof(CelesteModTutorialSession); + public static CelesteModTutorialSession Session => (CelesteModTutorialSession)Instance._Session; - public override Type SessionType => typeof(CelesteModTutorialSession); - public static CelesteModTutorialSession Session => (CelesteModTutorialSession)Instance._Session; + public override Type SaveDataType => typeof(CelesteModTutorialSaveData); + public static CelesteModTutorialSaveData SaveData => (CelesteModTutorialSaveData)Instance._SaveData; - public override Type SaveDataType => typeof(CelesteModTutorialSaveData); - public static CelesteModTutorialSaveData SaveData => (CelesteModTutorialSaveData)Instance._SaveData; + public override void Load() + { + Instance = this; - public override void Load() - { - Instance = this; - } + Logger.Log(LogLevel.Info, "CelesteModTutorial", "Hello, Celeste!"); + } - public override void Unload() - { - } + public override void Unload() + { } } \ No newline at end of file diff --git a/src/CelesteModTutorial/Source/CelesteModTutorialSaveData.cs b/src/CelesteModTutorial/Source/CelesteModTutorialSaveData.cs index 6c4985b..df88cfc 100644 --- a/src/CelesteModTutorial/Source/CelesteModTutorialSaveData.cs +++ b/src/CelesteModTutorial/Source/CelesteModTutorialSaveData.cs @@ -1,6 +1,5 @@ -namespace Celeste.Mod.CelesteModTutorial +namespace Celeste.Mod.CelesteModTutorial; + +public sealed class CelesteModTutorialSaveData : EverestModuleSaveData { - public class CelesteModTutorialSaveData : EverestModuleSaveData - { - } } \ No newline at end of file diff --git a/src/CelesteModTutorial/Source/CelesteModTutorialSession.cs b/src/CelesteModTutorial/Source/CelesteModTutorialSession.cs index 4bbecbf..aa8001a 100644 --- a/src/CelesteModTutorial/Source/CelesteModTutorialSession.cs +++ b/src/CelesteModTutorial/Source/CelesteModTutorialSession.cs @@ -1,6 +1,5 @@ -namespace Celeste.Mod.CelesteModTutorial +namespace Celeste.Mod.CelesteModTutorial; + +public sealed class CelesteModTutorialSession : EverestModuleSession { - public class CelesteModTutorialSession : EverestModuleSession - { - } } \ No newline at end of file diff --git a/src/CelesteModTutorial/Source/CelesteModTutorialSettings.cs b/src/CelesteModTutorial/Source/CelesteModTutorialSettings.cs index ee33861..09a3220 100644 --- a/src/CelesteModTutorial/Source/CelesteModTutorialSettings.cs +++ b/src/CelesteModTutorial/Source/CelesteModTutorialSettings.cs @@ -1,6 +1,5 @@ -namespace Celeste.Mod.CelesteModTutorial +namespace Celeste.Mod.CelesteModTutorial; + +public sealed class CelesteModTutorialSettings : EverestModuleSettings { - public class CelesteModTutorialSettings : EverestModuleSettings - { - } } \ No newline at end of file From f0990c2032ade134a98adc4012194291034f401a Mon Sep 17 00:00:00 2001 From: ClearZer0 <534310154@qq.com> Date: Tue, 21 Jan 2025 01:12:29 +0800 Subject: [PATCH 11/26] =?UTF-8?q?=E7=A7=BB=E9=99=A4SampleTrigger.lua?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/resources/CelesteModTutorial.zip | Bin 9475 -> 9211 bytes .../Loenn/triggers/SampleTrigger.lua | 12 ------------ 2 files changed, 12 deletions(-) delete mode 100644 src/CelesteModTutorial/Loenn/triggers/SampleTrigger.lua diff --git a/docs/resources/CelesteModTutorial.zip b/docs/resources/CelesteModTutorial.zip index cba8c972332099f351af0cd6f6ae52e1be572e73..429f6c3b827dd9b81550c13b612f34806d0322fb 100644 GIT binary patch delta 158 zcmZqn`t82qImhOOoWI2;zfzE!yh}l3vW%i9(?ib5>54u~Av}|}DmpT?^GuHAm7FZ7 zq{ZaVKiO8vmFb+|i delta 414 zcmezE-t4vEIY<4nN`ol2ds35X7#J8%0kHxQ`{bwQ<;9c~Wu~X678SuN$->bj7--Pai#P`tFut>yfhNh7Gha%oCIogUTMobjQm6>d&WWuxs#FU-fsbs|D zF9u|)O@6GT#rSqIpRy0rY{|*~VsevX*m)+mDeExh%S^r~Z73Gt&B_LHm?#id0$C+; GARYk6XNmFv diff --git a/src/CelesteModTutorial/Loenn/triggers/SampleTrigger.lua b/src/CelesteModTutorial/Loenn/triggers/SampleTrigger.lua deleted file mode 100644 index 2dc9984..0000000 --- a/src/CelesteModTutorial/Loenn/triggers/SampleTrigger.lua +++ /dev/null @@ -1,12 +0,0 @@ -local trigger = {} - -trigger.name = "MyCelesteMod/SampleTrigger" -trigger.placements = { - name = "SampleTrigger", - data = { - width = 16, - height = 16 - } -} - -return trigger \ No newline at end of file From a99c98a9989ae8cbc19d897efdd5a4c82960732b Mon Sep 17 00:00:00 2001 From: ClearZer0 <534310154@qq.com> Date: Tue, 21 Jan 2025 20:00:30 +0800 Subject: [PATCH 12/26] =?UTF-8?q?Lua=E9=80=9F=E9=80=9Apart1=E8=A1=A5?= =?UTF-8?q?=E5=85=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/advanced/cross_mod_interactions.md | 7 +- docs/extra/lua/Sample.lua | 12 ++++ docs/extra/lua/begin.md | 54 +++++++++++++++- .../extra/lua/images/begin/vs_code_runner.png | Bin 0 -> 53071 bytes docs/extra/lua/images/begin/vs_lua_output.png | Bin 0 -> 19961 bytes docs/extra/lua/syntax.md | 61 +++++++++++++++--- 6 files changed, 121 insertions(+), 13 deletions(-) create mode 100644 docs/extra/lua/images/begin/vs_code_runner.png create mode 100644 docs/extra/lua/images/begin/vs_lua_output.png diff --git a/docs/advanced/cross_mod_interactions.md b/docs/advanced/cross_mod_interactions.md index d6785e5..b650058 100644 --- a/docs/advanced/cross_mod_interactions.md +++ b/docs/advanced/cross_mod_interactions.md @@ -81,6 +81,8 @@ public static class MyCelesteModExports // 添加于 1.0.0 版本 public static void LogStuff() => Logger.Log(LogLevel.Info, "MyCelesteMod", "Someone is calling this method!"); // 添加于 1.0.0 版本 + public static void LogNumber(int number) => Logger.Log(LogLevel.Info, "MyCelesteMod", $"Number is {number}!"); + // 添加于 1.0.0 版本 public static bool TryDoubleIfEven(int number, out int? doubledNumber) { if (number % 2 == 0) @@ -138,6 +140,7 @@ public static class MyCelesteModAPI // 如果没有返回值, 也就是返回值是 void 则使用 Action public static Action LogStuff; + public static Action LogNumber; // 如果导出的方法参数中有 in, out 或 ref 需要定义自定义委托类型以进行导入 // Func 并不支持参数中带有 in, out 或 ref 的情况 @@ -166,11 +169,9 @@ if (MyCelesteModAPI.MultiplyByTwo(myNumber) > 400) MyCelesteModAPI.LogStuff(); } -int myDoubledNumber; - if (MyCelesteModAPI.TryDoubleIfEven(myNumber, out int? doubledNumber)) { - myDoubledNumber = doubledNumber; + MyCelesteModAPI.LogNumber(doubledNumber); } ``` diff --git a/docs/extra/lua/Sample.lua b/docs/extra/lua/Sample.lua index e69de29..f00f485 100644 --- a/docs/extra/lua/Sample.lua +++ b/docs/extra/lua/Sample.lua @@ -0,0 +1,12 @@ +number = 10 -- 全局变量 +local number = 20 -- 局部变量 + +print(number) -- 输出 20 (局部变量优先) + +do + local number = 30 -- 新的局部变量 + print(number) -- 输出 30 +end + +print(number) -- 输出 20 (回到外层的局部变量) + diff --git a/docs/extra/lua/begin.md b/docs/extra/lua/begin.md index 08a924f..c022381 100644 --- a/docs/extra/lua/begin.md +++ b/docs/extra/lua/begin.md @@ -8,11 +8,61 @@ ## 开发环境 +### Lua 安装 +!!!info + `Everest` 集成了 `Lua` 环境, 因此实际开发时无需再次安装 `Lua`. 以下步骤仅用于学习或自定义开发时的 `Lua` 环境安装. + +!!!info + 这部分介绍的是 Windows 系统下的 `Lua` 安装, Linux 系统用户请直接访问 [Lua Download](https://www.lua.org/download.html) 下载并安装. + +我们可以通过命令行工具 `winget` 安装 `Lua`: +```bat +winget install DEVCOM.Lua +``` +安装完成后, 我们可以通过以下命令检查 `Lua` 是否安装成功: +```bat +lua -v +``` + +如果命令行输出以下错误信息我们需要手动添加 `Lua` 的安装目录至环境变量: +```bat +lua : 无法将“lua”项识别为 cmdlet、函数、脚本文件或可运行程序的名称。请检查名称的拼写,如果包括路径,请确保路径正确, +然后再试一次。 +``` + +默认情况下, `winget` 会将 `Lua` 安装至 `C:\Users\你的用户名\AppData\Local\Programs\Lua\bin`, 这里需要根据你的用户名更改路径, 例如 `C:\Users\AppleSheep\AppData\Local\Programs\Lua\bin`. + +随后在命令行输入以下命令将 `Lua` 安装目录添加至系统环境变量中: +```bat +setx PATH "$env:PATH;C:\Users\AppleSheep\AppData\Local\Programs\Lua\bin" +``` + +完成后我们可以再次检查 `Lua` 是否安装成功: +```bat +lua -v +``` + +安装成功会输出: +```bat +Lua 5.4.6 Copyright (C) 1994-2023 Lua.org, PUC-Rio +``` + +### Visual Studio Code 配置 这一步实际上是可选的, 不过为了更愉快的 `Lua` 脚本的编写, 个人还是觉得挺有必要的. -在这里我会推荐使用 [VSCode](https://code.visualstudio.com/Download) 配上 [Lua (sumneko.lua)](https://marketplace.visualstudio.com/items?itemName=sumneko.lua) +在这里我会推荐使用 [Visual Studio Code](https://code.visualstudio.com/Download) 配上 [Lua (sumneko.lua)](https://marketplace.visualstudio.com/items?itemName=sumneko.lua) 插件: ![lua-in-vscode](images/begin/lua_in_vscode.png) !!! note - 我个人不太会配置这种 lua 环境, 所以如果你遇到了大量的未定义警告你可以选择在设置中搜索 `Lua.diagnostics.enable` 并将其关闭. \ No newline at end of file + 个人不太会配置这种 lua 环境, 所以如果你遇到了大量的未定义警告你可以选择在设置中搜索 `Lua.diagnostics.enable` 并将其关闭. + +此外, Lua (sumneko.lua) 插件并不支持 `Lua` 的调试. 个人推荐安装 [Code Runner](https://marketplace.visualstudio.com/items?itemName=formulahendry.code-runner) 插件. + +安装完成后我们在右键菜单内点击 `Run Code` 即可运行 `Lua` 脚本: + +![vs_code_runner](images/begin/vs_code_runner.png) + +运行结果将显示在输出窗口: + +![vs_lua_output](images/begin/vs_lua_output.png) \ No newline at end of file diff --git a/docs/extra/lua/images/begin/vs_code_runner.png b/docs/extra/lua/images/begin/vs_code_runner.png new file mode 100644 index 0000000000000000000000000000000000000000..5f3db427a4047c9a83a69df30bccc53af5321993 GIT binary patch literal 53071 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%0DPzu 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 literal 0 HcmV?d00001 diff --git a/docs/extra/lua/images/begin/vs_lua_output.png b/docs/extra/lua/images/begin/vs_lua_output.png new file mode 100644 index 0000000000000000000000000000000000000000..de2cbad1be9a4c5d2e55697e300e952b5a697a08 GIT binary patch literal 19961 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 Date: Tue, 21 Jan 2025 21:15:33 +0800 Subject: [PATCH 13/26] =?UTF-8?q?=E7=BA=A0=E9=94=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/coding_setup/basic_env.md | 12 ++++++------ docs/extra/lua/data_structure.md | 1 + docs/extra/xml/{xml-speedrun.md => xml_speedrun.md} | 0 docs/misc/to_do_list.md | 4 +++- mkdocs.yml | 2 +- 5 files changed, 11 insertions(+), 8 deletions(-) rename docs/extra/xml/{xml-speedrun.md => xml_speedrun.md} (100%) diff --git a/docs/coding_setup/basic_env.md b/docs/coding_setup/basic_env.md index 951d2b9..6264e0a 100644 --- a/docs/coding_setup/basic_env.md +++ b/docs/coding_setup/basic_env.md @@ -176,10 +176,10 @@ ok, 我们前面几乎巴拉巴拉讲了几乎三千多个字, 但是依然没 实际上有关 code mod 的所有代码相关的东西我们都已经做完了, 剩余的其实只是一个普通 mod 要做的 ---- 写 `everest.yaml`. 好的, 现在我们找到模板自动生成的 `everest.yaml` 并打开 , 然后像一个普通的 mapper 一样填写信息: -```yml +```yaml - Name: MyCelesteMod Version: 0.1.0 - DLL: MyCelesteMod.dll + DLL: Code/MyCelesteMod.dll Dependencies: - Name: EverestCore Version: 1.4465.0 @@ -188,9 +188,9 @@ ok, 我们前面几乎巴拉巴拉讲了几乎三千多个字, 但是依然没 - `Name`: 你的 mod 名字 - `Version`: 你的 mod 的版本 -- `DLL`: 如果你是 code mod 的话, 这里填入你的 code (也就是 dll 文件) 的位置, 这里我们是直接把 .dll 文件放到这个 yaml 的旁边了, 所以直接写名字就好 +- `DLL`: 如果你是 code mod 的话, 这里填入你的 code (也就是 dll 文件) 的位置 -最后是最底下的那个依赖, 这里我们只依赖最基础的 Everest, 版本填上你目前使用的 Everest 版本. +最后是最底下的那个 `Dependencies`, 即依赖. 这里我们只依赖最基础的 Everest, 版本填上你目前使用的 Everest 版本. 如果你的 mod 依赖 Everest Core, 你需要在这里将 `Everest` 更改为 `EverestCore`, 并将版本号填写大于 4465 的值. ## 结语 @@ -201,8 +201,8 @@ ok, 我们前面几乎巴拉巴拉讲了几乎三千多个字, 但是依然没 - MyCelesteMod (你的根目录) - ModFolder - Code - - MyCelesteMod.dll - - MyCelesteMod.pdb + - MyCelesteMod.dll + - MyCelesteMod.pdb - everest.yaml - CelesteMod.props - CelesteMod.targets diff --git a/docs/extra/lua/data_structure.md b/docs/extra/lua/data_structure.md index e69de29..5d52e71 100644 --- a/docs/extra/lua/data_structure.md +++ b/docs/extra/lua/data_structure.md @@ -0,0 +1 @@ +# Lua 数据类型 diff --git a/docs/extra/xml/xml-speedrun.md b/docs/extra/xml/xml_speedrun.md similarity index 100% rename from docs/extra/xml/xml-speedrun.md rename to docs/extra/xml/xml_speedrun.md diff --git a/docs/misc/to_do_list.md b/docs/misc/to_do_list.md index 02aad84..a477102 100644 --- a/docs/misc/to_do_list.md +++ b/docs/misc/to_do_list.md @@ -5,7 +5,9 @@ 这里是 AppleSheep, 本教程后续的维护应该都由我负责 这里列出了自己的一些代办事项, 以优先级进行排序. 如果有什么想法或建议可以 QQ 私聊我(可以在二群 962344157 或是 coder 群 550358997 找到我) -唔 似乎直接把自己的 QQ 534310154 发出来更合适, 虽然还是不太敢就是了(草 +唔 似乎直接把自己的 QQ 534310154 发出来更合适, 虽然还是不太敢就是了(草 + +草草 计划似乎排的有点多了(??? 总之就是 写不完了啦qwq ## ToDoList diff --git a/mkdocs.yml b/mkdocs.yml index 0c6dce8..d671d1a 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -97,7 +97,7 @@ nav: - readme: "extra/cmcc/remote/ReadMe.md" - FAQ: "extra/cmcc/remote/todo.md" - XML: - - XML 简单介绍: "extra/xml/xml-speedrun.md" + - XML 简单介绍: "extra/xml/xml_speedrun.md" - Lua: - 开始: "extra/lua/begin.md" - 基本语法: "extra/lua/syntax.md" From c280f77343a54a8cd4c8a0249d9ab60d0afb7fe1 Mon Sep 17 00:00:00 2001 From: ClearZer0 <534310154@qq.com> Date: Wed, 22 Jan 2025 00:15:03 +0800 Subject: [PATCH 14/26] requested --- docs/advanced/cross_mod_interactions.md | 2 +- docs/arc/preference.md | 2 +- docs/extra/lua/begin.md | 17 ++++++++++------- docs/extra/lua/syntax.md | 2 +- docs/misc/change_log.md | 2 +- 5 files changed, 14 insertions(+), 11 deletions(-) diff --git a/docs/advanced/cross_mod_interactions.md b/docs/advanced/cross_mod_interactions.md index b650058..6668992 100644 --- a/docs/advanced/cross_mod_interactions.md +++ b/docs/advanced/cross_mod_interactions.md @@ -140,7 +140,7 @@ public static class MyCelesteModAPI // 如果没有返回值, 也就是返回值是 void 则使用 Action public static Action LogStuff; - public static Action LogNumber; + public static Action LogNumber; // 如果导出的方法参数中有 in, out 或 ref 需要定义自定义委托类型以进行导入 // Func 并不支持参数中带有 in, out 或 ref 的情况 diff --git a/docs/arc/preference.md b/docs/arc/preference.md index 4b53d0b..731c99d 100644 --- a/docs/arc/preference.md +++ b/docs/arc/preference.md @@ -34,7 +34,7 @@ ``` !!! note - 这个文件是 XML 格式的, 如果你不熟悉 XML 的话你可以到[这里](../extra/xml/xml-speedrun.md)简单看一下, 免得你不知道我们讨论的东西都是什么 + 这个文件是 XML 格式的, 如果你不熟悉 XML 的话你可以到[这里](../extra/xml/xml_speedrun.md)简单看一下, 免得你不知道我们讨论的东西都是什么 其中我们只需要关注里面的 `PropertyGroup` 以及 `ItemGroup` 节点 `PropertyGroup` 节点定义了这个项目有哪些属性, 比如项目框架版本, 语言版本, 程序集昵称等 diff --git a/docs/extra/lua/begin.md b/docs/extra/lua/begin.md index c022381..b2f2db4 100644 --- a/docs/extra/lua/begin.md +++ b/docs/extra/lua/begin.md @@ -10,15 +10,20 @@ ### Lua 安装 !!!info - `Everest` 集成了 `Lua` 环境, 因此实际开发时无需再次安装 `Lua`. 以下步骤仅用于学习或自定义开发时的 `Lua` 环境安装. + `Everest` 集成了 `Lua` 环境, 因此实际写蔚蓝 Mod 时可以直接使用其提供的 `Lua` API. 以下步骤仅用于学习或自定义开发时的 `Lua` 环境安装. !!!info - 这部分介绍的是 Windows 系统下的 `Lua` 安装, Linux 系统用户请直接访问 [Lua Download](https://www.lua.org/download.html) 下载并安装. + 这部分介绍的是 Windows 系统下的 `Lua` 安装, Linux 用户可直接通过包管理器安装 `Lua`. 我们可以通过命令行工具 `winget` 安装 `Lua`: + +!!!info + 下面使用的是 `Windows PowerShell` 而不是 `cmd`. 某些命令行语法是 `Windows PowerShell` 独有的, 使用 `cmd` 可能会导致问题. + ```bat winget install DEVCOM.Lua ``` + 安装完成后, 我们可以通过以下命令检查 `Lua` 是否安装成功: ```bat lua -v @@ -28,13 +33,11 @@ lua -v ```bat lua : 无法将“lua”项识别为 cmdlet、函数、脚本文件或可运行程序的名称。请检查名称的拼写,如果包括路径,请确保路径正确, 然后再试一次。 -``` - -默认情况下, `winget` 会将 `Lua` 安装至 `C:\Users\你的用户名\AppData\Local\Programs\Lua\bin`, 这里需要根据你的用户名更改路径, 例如 `C:\Users\AppleSheep\AppData\Local\Programs\Lua\bin`. +``` -随后在命令行输入以下命令将 `Lua` 安装目录添加至系统环境变量中: +默认情况下, `winget` 会将 `Lua` 安装至 `%LocalAppdata%\Programs\Lua\bin`. 我们在命令行输入以下命令将 `Lua` 安装目录添加至系统环境变量中: ```bat -setx PATH "$env:PATH;C:\Users\AppleSheep\AppData\Local\Programs\Lua\bin" +setx PATH "$env:PATH;%LocalAppdata%\Programs\Lua\bin\Programs\Lua\bin" ``` 完成后我们可以再次检查 `Lua` 是否安装成功: diff --git a/docs/extra/lua/syntax.md b/docs/extra/lua/syntax.md index 2d6faec..a3195fe 100644 --- a/docs/extra/lua/syntax.md +++ b/docs/extra/lua/syntax.md @@ -55,7 +55,7 @@ my-var = 10 -- 不能包含特殊字符 ## 作用域 -`Lua` 中默认情况下定义的变量与函数都是全局的, 与 `C#` 中的 `public` 访问修饰符相同, 全局变量与全局函数在整个程序中的任何位置都可以被访问与修改. +`Lua` 中默认情况下定义的变量与函数都是全局的. 全局变量与全局函数在整个程序中的任何位置都可以被访问与修改. !!!info 变量与函数的作用域遵循相同的规则, 以下将以变量为例进行说明. diff --git a/docs/misc/change_log.md b/docs/misc/change_log.md index 65380e1..c1913e9 100644 --- a/docs/misc/change_log.md +++ b/docs/misc/change_log.md @@ -32,7 +32,7 @@ * 归档 [一些准备 - 偏好](../arc/preference.md) * 重构 [一些准备 - 调试](../coding_setup/debug.md) * 完善 [进阶 - 跨 Mod 交互 - #ModInterop](../advanced/cross_mod_interactions.md) -* 移动 [额外 - CMCC](../extra/cmcc/index.md), [额外 - LuaCutscene](../extra/lua_cutscene/begin.md) 以及[其他 - XML 简单介绍](../extra/xml/xml-speedrun.md) 至额外章节以优化排版 +* 移动 [额外 - CMCC](../extra/cmcc/index.md), [额外 - LuaCutscene](../extra/lua_cutscene/begin.md) 以及[其他 - XML 简单介绍](../extra/xml/xml_speedrun.md) 至额外章节以优化排版 ### 2025.1.17 * 更新项目模板 From 118778091974ac82dcbd4216bd44f9b0fd183122 Mon Sep 17 00:00:00 2001 From: ClearZer0 <534310154@qq.com> Date: Sat, 25 Jan 2025 13:21:12 +0800 Subject: [PATCH 15/26] =?UTF-8?q?Lua=E9=80=9F=E9=80=9Apart2-1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/coding_setup/code_reading.md | 2 +- docs/coding_setup/debug.md | 2 +- docs/extra/lua/BinaryDecode.lua | 32 ++++ docs/extra/lua/Sample.lua | 26 ++- docs/extra/lua/begin.md | 2 +- docs/extra/lua/data_structure.md | 302 ++++++++++++++++++++++++++++++ docs/extra/lua/operator.md | 18 ++ docs/extra/lua/syntax.md | 6 +- mkdocs.yml | 1 + 9 files changed, 378 insertions(+), 13 deletions(-) create mode 100644 docs/extra/lua/BinaryDecode.lua create mode 100644 docs/extra/lua/operator.md diff --git a/docs/coding_setup/code_reading.md b/docs/coding_setup/code_reading.md index 6d76cb8..b882221 100644 --- a/docs/coding_setup/code_reading.md +++ b/docs/coding_setup/code_reading.md @@ -18,7 +18,7 @@ - 打开它 - 点击左上角的`文件`, `打开` -- 选择 `Celeste.exe` (如果你使用 core 版本的 everest, 你需要选择 `Celeste.dll`) +- 选择 `Celeste.exe` (如果你使用 Core 版本的 Everest, 你需要选择 `Celeste.dll`) - 展开蔚蓝的程序集 - 你现在可以看到蔚蓝都有哪些类了 - 你现在也可以看到蔚蓝都有哪些函数了 diff --git a/docs/coding_setup/debug.md b/docs/coding_setup/debug.md index 4f01cdd..db31887 100644 --- a/docs/coding_setup/debug.md +++ b/docs/coding_setup/debug.md @@ -67,7 +67,7 @@ LogLevels: {} `Logger` 是一个蔚蓝 `Everest` 的一个工具类, 它帮助你打印输出一些调试信息, 通常这些信息会被打印进控制台的同时写入游戏的 `log.txt` 文件中, -这也就解释了为什么你遇到各种问题时别人总要求你发送你的 `log.txt`. +这也解释了为什么你遇到各种问题时别人总要求你发送你的 `log.txt`. `Logger.Log` 有两个重载, 其中一个的签名是: ```cs diff --git a/docs/extra/lua/BinaryDecode.lua b/docs/extra/lua/BinaryDecode.lua new file mode 100644 index 0000000..2d6c77b --- /dev/null +++ b/docs/extra/lua/BinaryDecode.lua @@ -0,0 +1,32 @@ +local function splitBinary(binary) + local groups = {} + for group in binary:gmatch("%d+") do + table.insert(groups, group) + end + return groups +end + +local function binaryToDecimal(binary) + return tonumber(binary, 2) +end + +local function decimalToLetter(decimal) + return string.char(decimal + 64) +end + +local function decodeBinaryMessage(binaryString) + local groups = splitBinary(binaryString) + local message = "" + + for _, group in ipairs(groups) do + local decimal = binaryToDecimal(group) + local letter = decimalToLetter(decimal) + message = message .. letter + end + + return message +end + +local binary = "00101 01110 10010" + +print(decodeBinaryMessage(binary)) \ No newline at end of file diff --git a/docs/extra/lua/Sample.lua b/docs/extra/lua/Sample.lua index f00f485..9142436 100644 --- a/docs/extra/lua/Sample.lua +++ b/docs/extra/lua/Sample.lua @@ -1,12 +1,24 @@ -number = 10 -- 全局变量 -local number = 20 -- 局部变量 +local add = function (a, b) + return a + b +end + +print(add(1, 2)) -print(number) -- 输出 20 (局部变量优先) +local function apply(func, x, y) + return func(x, y) +end -do - local number = 30 -- 新的局部变量 - print(number) -- 输出 30 +local function sub(a, b) + return a - b end -print(number) -- 输出 20 (回到外层的局部变量) +print(apply(sub, 10, 3)) + +local function multiplyBy(factor) + return function(x) + return x * factor + end +end +local double = multiplyBy(2) +print(double(10)) \ No newline at end of file diff --git a/docs/extra/lua/begin.md b/docs/extra/lua/begin.md index b2f2db4..9555fb6 100644 --- a/docs/extra/lua/begin.md +++ b/docs/extra/lua/begin.md @@ -29,7 +29,7 @@ winget install DEVCOM.Lua lua -v ``` -如果命令行输出以下错误信息我们需要手动添加 `Lua` 的安装目录至环境变量: +如果命令行输出以下错误信息我们需要手动添加 `Lua` 的安装目录至系统环境变量: ```bat lua : 无法将“lua”项识别为 cmdlet、函数、脚本文件或可运行程序的名称。请检查名称的拼写,如果包括路径,请确保路径正确, 然后再试一次。 diff --git a/docs/extra/lua/data_structure.md b/docs/extra/lua/data_structure.md index 5d52e71..5991035 100644 --- a/docs/extra/lua/data_structure.md +++ b/docs/extra/lua/data_structure.md @@ -1 +1,303 @@ # Lua 数据类型 + +## 基本数据类型 +`Lua` 是动态类型语言, 其变量在运行时根据赋值的内容自动决定数据类型. + +`Lua` 有以下 8 种基本数据类型: + +- `nil`: 表示一个空值或无效值 +- `number`: 表示双精度类型的浮点数 +- `string`: 表示字符串 +- `boolean`: 表示布尔值 +- `table`: 表示表类型 +- `function`: 表示函数类型 +- `userdata`: 表示用户自定义的数据类型 +- `thread`: 表示线程类型 + +!!!info + `Loenn` 侧的 `Lua` 脚本编写并不会涉及 `userdata` 与 `thread`, 下面不做介绍. + 实际上是自己也不清楚(草草 + +我们可以使用 `type()` 函数查看变量的类型: +```lua +-- nil +print(type(nil)) -- 输出 nil + +-- number +print(type(202)) -- 输出 number +print(type(3.14)) -- 输出 number + +-- string +print(type("Celeste")) -- 输出 string +print(type("mb6fbhsphdrcb")) -- 输出 string + +-- boolean +print(type(true)) -- 输出 boolean +print(type(false)) -- 输出 boolean + +-- table +local numbers = {1, 2, 3} +print(type(numbers)) -- 输出 table + +-- function +local function add(a, b) + return a + b +end +print(type(add)) -- 输出 function +``` + +### nil + +`nil` 是一种特殊的类型, 只包含一个值 `nil`. 所有未初始化的变量都被视为 `nil`, 把变量赋值为 `nil` 即可删除这个变量: +```lua +print(a) -- 输出 nil +local a = 10 -- 初始化变量 a +print(a) -- 输出 10 +a = nil -- 删除变量 a +print(a) -- 输出 nil +``` + +`nil` 在逻辑判断中被视为"假", 但其与布尔值 `false` 是不同的值: +```lua +local value = nil +if value then + print("Value is valid") +else + print("Value is nil") -- 输出 Value is nil +end + +print(nil == false) -- 输出 false +print(type(nil)) -- 输出 nil +print(type(false)) -- 输出 boolean +``` + +### number + +`Lua` 默认只有一种数字类型, 即双精度浮点数 `double`. 以下写法都可以表示 `number` 类型: +```lua +-- 输出结果都为 number +print(type(0)) +print(type(2)) +print(type(2.2)) +print(type(0.2)) +print(type(2e+1)) +print(type(0.2e-1)) +print(type(7.8263692594256e-06)) +``` + +`number` 在进行浮点数运算时会出现数值精度误差, 这导致在进行计算时可能会出现预期外的结果: +```lua +print(0.1 + 0.2) -- 输出 0.3, 但实际计算结果可能是 0.30000000000000004 +print(0.1 + 0.2 == 0.3) -- 输出 false + +-- 浮点数精度比较函数的可能实现 +-- 添加参数 precision 判断两个浮点数的误差是否小到可以忽略 +local function almost_equal(a, b, precision) + precision = precision or 1e-10 + return math.abs(a - b) < precision +end + +print(almost_equal(0.1 + 0.2, 0.3)) -- 输出 true, 忽略了微小误差 +``` + +`number` 类型存在三种特殊值: `infinite`, `-infinite` 以及 `NaN`. 其中, `NaN` 是唯一不等于自身的值: +```lua +print(type(1 / 0)) -- 输出 number +print(type(-1 / 0)) -- 输出 number +print(type(0 / 0)) -- 输出 number + +print(1 / 0) -- 输出 inf +print(math.huge) -- 输出 inf +print(-1 / 0) -- 输出 -inf +print(-math.huge) -- 输出 -inf +print(0 / 0) -- 输出 -nan(ind) + +print((0 / 0) == (0 / 0)) -- 输出 false, NaN 不等于自身 +``` + +!!!note + `-nan(ind)` 表示未定义结果, `nan` 表示这不是一个数字, 即 `Not a Number`. 其中 `ind` 是 `indeterminate` 的缩写, 即"不确定". + 进行未定义行为的运算都会得到这个值, 例如 `0 / 0`, `0 ^ 0` 以及 `math.sqrt(-1)` 等. + +### string + +`Lua` 中 `string` 类型用于表示文本数据或字符序列. 可以使用 `' '`, `" "` 以及 `[[ ]]` 声明字符串: +```lua +local str1 = "Celeste" -- 使用 "" 声明 +local str2 = 'Everest' -- 使用 '' 声明, "" 与 '' 并没有区别 + +-- 使用 [[]] 声明多行字符串, 这种声明方式会保留字符串中的换行与格式 +-- print(str3) 的输出会是: +-- +-- some stuff i guess +-- another stuff +local str3 = [[ +some stuff i guess +another stuff +]] + +print(type(str1)) -- 输出 string +print(type(str2)) -- 输出 string +print(type(str3)) -- 输出 string +``` + +可以在字符串中使用转义字符 `\` 表示一些无法直接输入或有特殊含义的字符: +```lua +print("\"wow\"") -- 输出 "wow" +print("IVXL \\\\ ECOM") -- 输出 IVXL \\ ECOM +print("a line\nnew line") -- 输出 a line + -- new line +``` + +需要连接字符串使用 `..` 运算符, 需要计算字符串的长度使用 `#` 运算符: +```lua +local str1 = "speed" +local str2 = "run" + +print(str1 .. str2) -- 输出 speedrun +print(str1 .. " " .. str2) -- 输出 speed run + +print(#str1) -- 输出 5 +print(#str2) -- 输出 3 +``` + +`string` 类型是不可变的, 所有修改字符串的操作本质上都是生成并返回修改后的字符串: +```lua +local str1 = "hi there" +print(str1) -- 输出 hi there + +-- 直接修改 string 的值会报错 +-- str1[1] = "H" 报错 attempt to index a string value (local 'str1') + +local str2 = "H" .. str1:sub(2) -- 使用 .. 运算符与 sub 方法生成新的字符串 str2 +print(str2) -- 输出 Hi there +print(str1) -- 输出 hi there, str1 的值并没有被改变 +``` + +### boolean + +`boolean` 类型有两个取值: `true` 和 `false`, 通常用于条件判断, 循环控制等. 可以直接声明 `boolean` 类型的变量为 `true` 或 `false`: +```lua +local var1 = true +local var2 = false + +print(var1) -- 输出 boolean +print(var2) -- 输出 boolean +``` + +`nil` 和 `false` 是唯一被认为是"假"的值, 其他的值都被认为是"真": +```lua +-- nil 被认为是假 +if nil then + print("nil is true") +else + print("nil is false") -- 输出 nil is false +end + +-- false 被认为是假 +if false then + print("false is true") +else + print("false is false") -- 输出 false is false +end + +-- 0 被认为是真 +if 0 then + print("0 is true") -- 输出 0 is true +else + print("0 is false") +end + +-- 空字符串 "" 被认为是真 +if "" then + print("\"\" is true") -- 输出 "" is true +else + print("\"\" is false") +end + +-- 空表 {} 被认为是真 +if {} then + print("{} is true") -- 输出 {} is true +else + print("{} is false") +end +``` + +### table + +### function + +!!!info + 这里只做简单的引入, 详细的说明与解释请阅读 [Lua - 函数](function.md). + +`Lua` 中的函数使用关键字 `function` 声明. `Lua` 支持函数式编程, 函数可以作为变量赋值, 参数传递以及结果返回: + +```lua +-- 函数可以作为变量赋值 +-- 使用匿名函数定义加法操作 +local add = function (a, b) + return a + b +end + +print(add(1, 2)) -- 输出 3 + +-- 函数可以作为参数传递 +-- 定义一个接受函数作为参数的高阶函数 +local function apply(func, x, y) + return func(x, y) +end + +local function sub(a, b) + return a - b +end + +-- 将 sub 函数作为参数传递给 apply 函数 +print(apply(sub, 10, 3)) -- 输出 7 + +-- 函数可以作为返回结果 +-- 定义 createMultiplier 函数, 返回一个新的函数, 该函数会将其参数与给定的 factor 相乘 +local function createMultiplier(factor) + -- 返回一个捕获 factor 的匿名函数 + return function(x) + return x * factor + end +end + +-- 定义 double 函数, 该函数会将其参数乘2返回 +local double = createMultiplier(2) +print(double(10)) -- 输出 20 +``` + +上面的 `Lua` 代码等同于下面的 `C#` 代码: +```cs +// 函数可以作为变量赋值 +// 使用委托定义加法操作 +Func Add = (a, b) => a + b; +Console.WriteLine(Add(1, 2)); // 输出 3 + +// 函数可以作为参数传递 +// 定义一个接受函数作为参数的高阶函数 +int Apply(Func func, int x, int y) +{ + return func(x, y); +} + +Func Sub = (a, b) => a - b; + +// 将 sub 函数作为参数传递给 apply 函数 +Console.WriteLine(Apply(Sub, 10, 3)); // 输出 7 + +// 函数可以作为返回结果 +// 定义 createMultiplier 函数, 返回一个新的函数, 该函数会将其参数与给定的 factor 相乘 +Func CreateMultiplier(int factor) +{ + // 返回一个捕获 factor 的匿名函数 + return x => x * factor; +} + +// 定义 double 函数, 该函数会将其参数乘2返回 +var DoubleFunc = CreateMultiplier(2); +Console.WriteLine(DoubleFunc(10)); // 输出 20 +``` + +## 类型转换 \ No newline at end of file diff --git a/docs/extra/lua/operator.md b/docs/extra/lua/operator.md new file mode 100644 index 0000000..2511d8d --- /dev/null +++ b/docs/extra/lua/operator.md @@ -0,0 +1,18 @@ +# 运算符 + +运算符是一种特殊的符号, 用于告诉解释器执行特定的数学或逻辑运算. `Lua` 提供以下运算符类型: + +- 算数运算符: 执行数学运算 +- 关系运算符: 执行比较运算 +- 逻辑运算符: 执行逻辑运算 +- 其他运算符: 执行其他特定的运算 + +## 算术运算符 + +## 关系运算符 + +## 逻辑运算符 + +## 其他运算符 + +## 运算符优先级 \ No newline at end of file diff --git a/docs/extra/lua/syntax.md b/docs/extra/lua/syntax.md index a3195fe..96e39ae 100644 --- a/docs/extra/lua/syntax.md +++ b/docs/extra/lua/syntax.md @@ -21,9 +21,9 @@ `Lua` 中的标识符是用于定义一个变量, 函数, 表, 模块等名称的符号. 标识符的命名遵循以下规则: - 标识符必须以字母 (`a `到 `z`,`A `到 `Z`), 或下划线 `_` 开头后加上0个或多个字母,下划线,数字 (`0` 到 `9`). -- `Lua` 是大小写敏感的,所以 `variable` 和 `Variable` 是不同的标识符. +- `Lua` 是大小写敏感的, `variable` 和 `Variable` 是不同的标识符. - 标识符不能包含特殊字符例如 `@`, `$`, 与 `%` 等. -- 标识符不能包含 `Lua` 中的保留关键字. +- 标识符不能以 `Lua` 中的保留关键字开头. ???note "Lua中的关键字" `Lua` 包含以下关键字, 不能用于作为标识符: @@ -49,7 +49,7 @@ function_name = "Lua" -- 下划线命名 -- 不合法的标识符 0var = 20 -- 不能以数字开头 -true = 5 -- 不能包含保留关键字 +true = 5 -- 不能以保留关键字开头 my-var = 10 -- 不能包含特殊字符 ``` diff --git a/mkdocs.yml b/mkdocs.yml index d671d1a..c5a8ab0 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -103,6 +103,7 @@ nav: - 基本语法: "extra/lua/syntax.md" - 数据类型: "extra/lua/data_structure.md" - 流程控制: "extra/lua/control_flow.md" + - 运算符: "extra/lua/operator.md" - 函数: "extra/lua/function.md" - 迭代器: "extra/lua/iterator.md" - 模块与包: "extra/lua/package.md" From eb1eed76e0cba9b0378dbb5ba53d95aa232298d4 Mon Sep 17 00:00:00 2001 From: ClearZer0 <534310154@qq.com> Date: Sun, 26 Jan 2025 06:30:24 +0800 Subject: [PATCH 16/26] =?UTF-8?q?Lua=E9=80=9F=E9=80=9Apart2=20(=E7=BB=88?= =?UTF-8?q?=E4=BA=8E...?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/extra/lua/BinaryDecode.lua | 32 -- docs/extra/lua/Sample.lua | 50 ++- docs/extra/lua/begin.md | 2 +- docs/extra/lua/control_flow.md | 1 + docs/extra/lua/data_structure.md | 303 --------------- docs/extra/lua/data_type.md | 538 +++++++++++++++++++++++++++ docs/extra/lua/exception_handling.md | 1 + docs/extra/lua/function.md | 0 docs/extra/lua/iterator.md | 1 + docs/extra/lua/metatable.md | 1 + docs/extra/lua/oop.md | 1 + docs/extra/lua/operator.md | 2 +- docs/extra/lua/package.md | 1 + docs/extra/lua/syntax.md | 29 +- mkdocs.yml | 6 +- 15 files changed, 611 insertions(+), 357 deletions(-) delete mode 100644 docs/extra/lua/BinaryDecode.lua delete mode 100644 docs/extra/lua/data_structure.md create mode 100644 docs/extra/lua/data_type.md create mode 100644 docs/extra/lua/exception_handling.md delete mode 100644 docs/extra/lua/function.md create mode 100644 docs/extra/lua/metatable.md create mode 100644 docs/extra/lua/oop.md diff --git a/docs/extra/lua/BinaryDecode.lua b/docs/extra/lua/BinaryDecode.lua deleted file mode 100644 index 2d6c77b..0000000 --- a/docs/extra/lua/BinaryDecode.lua +++ /dev/null @@ -1,32 +0,0 @@ -local function splitBinary(binary) - local groups = {} - for group in binary:gmatch("%d+") do - table.insert(groups, group) - end - return groups -end - -local function binaryToDecimal(binary) - return tonumber(binary, 2) -end - -local function decimalToLetter(decimal) - return string.char(decimal + 64) -end - -local function decodeBinaryMessage(binaryString) - local groups = splitBinary(binaryString) - local message = "" - - for _, group in ipairs(groups) do - local decimal = binaryToDecimal(group) - local letter = decimalToLetter(decimal) - message = message .. letter - end - - return message -end - -local binary = "00101 01110 10010" - -print(decodeBinaryMessage(binary)) \ No newline at end of file diff --git a/docs/extra/lua/Sample.lua b/docs/extra/lua/Sample.lua index 9142436..9e3c139 100644 --- a/docs/extra/lua/Sample.lua +++ b/docs/extra/lua/Sample.lua @@ -1,24 +1,40 @@ -local add = function (a, b) - return a + b +local function printToNumber(e, base) + local castedInput = tonumber(e) + + if base then + castedInput = tonumber(e, base) + end + + if type(castedInput) == "nil" then + print("type: nil, cast failed") + else + print("type: " .. type(castedInput) .. " value: " .. castedInput) + end end -print(add(1, 2)) +printToNumber("123") -- 输出 type: number value: 123 +printToNumber("123.45") -- 输出 type: number value: 123.45 +printToNumber("-123") -- 输出 type: number value: -123 +printToNumber("0") -- 输出 type: number value: 0 -local function apply(func, x, y) - return func(x, y) -end +printToNumber("FF", 16) -- 输出 type: number value: 255 +printToNumber("1010", 2) -- 输出 type: number value: 10 +printToNumber("1010", 3) -- 输出 type: number value: 30 +printToNumber("3", 2) -- 输出 type: nil, cast failed -local function sub(a, b) - return a - b -end +printToNumber("abc") -- 输出 type: nil, cast failed +printToNumber("") -- 输出 type: nil, cast failed +printToNumber(true) -- 输出 type: nil, cast failed +printToNumber(nil) -- 输出 type: nil, cast failed -print(apply(sub, 10, 3)) +print(tostring(123)) -- 输出 123 +print(tostring(123.45)) -- 输出 123.45 +print(tostring(-123)) -- 输出 -123 +print(tostring(0)) -- 输出 0 -local function multiplyBy(factor) - return function(x) - return x * factor - end -end +print(tostring(nil)) -- 输出 nil +print(tostring(true)) -- 输出 true +print(tostring(false)) -- 输出 false -local double = multiplyBy(2) -print(double(10)) \ No newline at end of file +print(tostring(function() end)) -- 输出 function: 000002B0EBF58730, 内存地址可能不同 +print(tostring({"some stuff"})) -- 输出 table: 000002B0EBF563C0, 内存地址可能不同 diff --git a/docs/extra/lua/begin.md b/docs/extra/lua/begin.md index 9555fb6..889d10d 100644 --- a/docs/extra/lua/begin.md +++ b/docs/extra/lua/begin.md @@ -60,7 +60,7 @@ Lua 5.4.6 Copyright (C) 1994-2023 Lua.org, PUC-Rio !!! note 个人不太会配置这种 lua 环境, 所以如果你遇到了大量的未定义警告你可以选择在设置中搜索 `Lua.diagnostics.enable` 并将其关闭. -此外, Lua (sumneko.lua) 插件并不支持 `Lua` 的调试. 个人推荐安装 [Code Runner](https://marketplace.visualstudio.com/items?itemName=formulahendry.code-runner) 插件. +此外, Lua (sumneko.lua) 插件并不支持 `Lua` 的运行. 个人推荐安装 [Code Runner](https://marketplace.visualstudio.com/items?itemName=formulahendry.code-runner) 插件. 安装完成后我们在右键菜单内点击 `Run Code` 即可运行 `Lua` 脚本: diff --git a/docs/extra/lua/control_flow.md b/docs/extra/lua/control_flow.md index e69de29..fc97d27 100644 --- a/docs/extra/lua/control_flow.md +++ b/docs/extra/lua/control_flow.md @@ -0,0 +1 @@ +# Lua 流程控制 \ No newline at end of file diff --git a/docs/extra/lua/data_structure.md b/docs/extra/lua/data_structure.md deleted file mode 100644 index 5991035..0000000 --- a/docs/extra/lua/data_structure.md +++ /dev/null @@ -1,303 +0,0 @@ -# Lua 数据类型 - -## 基本数据类型 -`Lua` 是动态类型语言, 其变量在运行时根据赋值的内容自动决定数据类型. - -`Lua` 有以下 8 种基本数据类型: - -- `nil`: 表示一个空值或无效值 -- `number`: 表示双精度类型的浮点数 -- `string`: 表示字符串 -- `boolean`: 表示布尔值 -- `table`: 表示表类型 -- `function`: 表示函数类型 -- `userdata`: 表示用户自定义的数据类型 -- `thread`: 表示线程类型 - -!!!info - `Loenn` 侧的 `Lua` 脚本编写并不会涉及 `userdata` 与 `thread`, 下面不做介绍. - 实际上是自己也不清楚(草草 - -我们可以使用 `type()` 函数查看变量的类型: -```lua --- nil -print(type(nil)) -- 输出 nil - --- number -print(type(202)) -- 输出 number -print(type(3.14)) -- 输出 number - --- string -print(type("Celeste")) -- 输出 string -print(type("mb6fbhsphdrcb")) -- 输出 string - --- boolean -print(type(true)) -- 输出 boolean -print(type(false)) -- 输出 boolean - --- table -local numbers = {1, 2, 3} -print(type(numbers)) -- 输出 table - --- function -local function add(a, b) - return a + b -end -print(type(add)) -- 输出 function -``` - -### nil - -`nil` 是一种特殊的类型, 只包含一个值 `nil`. 所有未初始化的变量都被视为 `nil`, 把变量赋值为 `nil` 即可删除这个变量: -```lua -print(a) -- 输出 nil -local a = 10 -- 初始化变量 a -print(a) -- 输出 10 -a = nil -- 删除变量 a -print(a) -- 输出 nil -``` - -`nil` 在逻辑判断中被视为"假", 但其与布尔值 `false` 是不同的值: -```lua -local value = nil -if value then - print("Value is valid") -else - print("Value is nil") -- 输出 Value is nil -end - -print(nil == false) -- 输出 false -print(type(nil)) -- 输出 nil -print(type(false)) -- 输出 boolean -``` - -### number - -`Lua` 默认只有一种数字类型, 即双精度浮点数 `double`. 以下写法都可以表示 `number` 类型: -```lua --- 输出结果都为 number -print(type(0)) -print(type(2)) -print(type(2.2)) -print(type(0.2)) -print(type(2e+1)) -print(type(0.2e-1)) -print(type(7.8263692594256e-06)) -``` - -`number` 在进行浮点数运算时会出现数值精度误差, 这导致在进行计算时可能会出现预期外的结果: -```lua -print(0.1 + 0.2) -- 输出 0.3, 但实际计算结果可能是 0.30000000000000004 -print(0.1 + 0.2 == 0.3) -- 输出 false - --- 浮点数精度比较函数的可能实现 --- 添加参数 precision 判断两个浮点数的误差是否小到可以忽略 -local function almost_equal(a, b, precision) - precision = precision or 1e-10 - return math.abs(a - b) < precision -end - -print(almost_equal(0.1 + 0.2, 0.3)) -- 输出 true, 忽略了微小误差 -``` - -`number` 类型存在三种特殊值: `infinite`, `-infinite` 以及 `NaN`. 其中, `NaN` 是唯一不等于自身的值: -```lua -print(type(1 / 0)) -- 输出 number -print(type(-1 / 0)) -- 输出 number -print(type(0 / 0)) -- 输出 number - -print(1 / 0) -- 输出 inf -print(math.huge) -- 输出 inf -print(-1 / 0) -- 输出 -inf -print(-math.huge) -- 输出 -inf -print(0 / 0) -- 输出 -nan(ind) - -print((0 / 0) == (0 / 0)) -- 输出 false, NaN 不等于自身 -``` - -!!!note - `-nan(ind)` 表示未定义结果, `nan` 表示这不是一个数字, 即 `Not a Number`. 其中 `ind` 是 `indeterminate` 的缩写, 即"不确定". - 进行未定义行为的运算都会得到这个值, 例如 `0 / 0`, `0 ^ 0` 以及 `math.sqrt(-1)` 等. - -### string - -`Lua` 中 `string` 类型用于表示文本数据或字符序列. 可以使用 `' '`, `" "` 以及 `[[ ]]` 声明字符串: -```lua -local str1 = "Celeste" -- 使用 "" 声明 -local str2 = 'Everest' -- 使用 '' 声明, "" 与 '' 并没有区别 - --- 使用 [[]] 声明多行字符串, 这种声明方式会保留字符串中的换行与格式 --- print(str3) 的输出会是: --- --- some stuff i guess --- another stuff -local str3 = [[ -some stuff i guess -another stuff -]] - -print(type(str1)) -- 输出 string -print(type(str2)) -- 输出 string -print(type(str3)) -- 输出 string -``` - -可以在字符串中使用转义字符 `\` 表示一些无法直接输入或有特殊含义的字符: -```lua -print("\"wow\"") -- 输出 "wow" -print("IVXL \\\\ ECOM") -- 输出 IVXL \\ ECOM -print("a line\nnew line") -- 输出 a line - -- new line -``` - -需要连接字符串使用 `..` 运算符, 需要计算字符串的长度使用 `#` 运算符: -```lua -local str1 = "speed" -local str2 = "run" - -print(str1 .. str2) -- 输出 speedrun -print(str1 .. " " .. str2) -- 输出 speed run - -print(#str1) -- 输出 5 -print(#str2) -- 输出 3 -``` - -`string` 类型是不可变的, 所有修改字符串的操作本质上都是生成并返回修改后的字符串: -```lua -local str1 = "hi there" -print(str1) -- 输出 hi there - --- 直接修改 string 的值会报错 --- str1[1] = "H" 报错 attempt to index a string value (local 'str1') - -local str2 = "H" .. str1:sub(2) -- 使用 .. 运算符与 sub 方法生成新的字符串 str2 -print(str2) -- 输出 Hi there -print(str1) -- 输出 hi there, str1 的值并没有被改变 -``` - -### boolean - -`boolean` 类型有两个取值: `true` 和 `false`, 通常用于条件判断, 循环控制等. 可以直接声明 `boolean` 类型的变量为 `true` 或 `false`: -```lua -local var1 = true -local var2 = false - -print(var1) -- 输出 boolean -print(var2) -- 输出 boolean -``` - -`nil` 和 `false` 是唯一被认为是"假"的值, 其他的值都被认为是"真": -```lua --- nil 被认为是假 -if nil then - print("nil is true") -else - print("nil is false") -- 输出 nil is false -end - --- false 被认为是假 -if false then - print("false is true") -else - print("false is false") -- 输出 false is false -end - --- 0 被认为是真 -if 0 then - print("0 is true") -- 输出 0 is true -else - print("0 is false") -end - --- 空字符串 "" 被认为是真 -if "" then - print("\"\" is true") -- 输出 "" is true -else - print("\"\" is false") -end - --- 空表 {} 被认为是真 -if {} then - print("{} is true") -- 输出 {} is true -else - print("{} is false") -end -``` - -### table - -### function - -!!!info - 这里只做简单的引入, 详细的说明与解释请阅读 [Lua - 函数](function.md). - -`Lua` 中的函数使用关键字 `function` 声明. `Lua` 支持函数式编程, 函数可以作为变量赋值, 参数传递以及结果返回: - -```lua --- 函数可以作为变量赋值 --- 使用匿名函数定义加法操作 -local add = function (a, b) - return a + b -end - -print(add(1, 2)) -- 输出 3 - --- 函数可以作为参数传递 --- 定义一个接受函数作为参数的高阶函数 -local function apply(func, x, y) - return func(x, y) -end - -local function sub(a, b) - return a - b -end - --- 将 sub 函数作为参数传递给 apply 函数 -print(apply(sub, 10, 3)) -- 输出 7 - --- 函数可以作为返回结果 --- 定义 createMultiplier 函数, 返回一个新的函数, 该函数会将其参数与给定的 factor 相乘 -local function createMultiplier(factor) - -- 返回一个捕获 factor 的匿名函数 - return function(x) - return x * factor - end -end - --- 定义 double 函数, 该函数会将其参数乘2返回 -local double = createMultiplier(2) -print(double(10)) -- 输出 20 -``` - -上面的 `Lua` 代码等同于下面的 `C#` 代码: -```cs -// 函数可以作为变量赋值 -// 使用委托定义加法操作 -Func Add = (a, b) => a + b; -Console.WriteLine(Add(1, 2)); // 输出 3 - -// 函数可以作为参数传递 -// 定义一个接受函数作为参数的高阶函数 -int Apply(Func func, int x, int y) -{ - return func(x, y); -} - -Func Sub = (a, b) => a - b; - -// 将 sub 函数作为参数传递给 apply 函数 -Console.WriteLine(Apply(Sub, 10, 3)); // 输出 7 - -// 函数可以作为返回结果 -// 定义 createMultiplier 函数, 返回一个新的函数, 该函数会将其参数与给定的 factor 相乘 -Func CreateMultiplier(int factor) -{ - // 返回一个捕获 factor 的匿名函数 - return x => x * factor; -} - -// 定义 double 函数, 该函数会将其参数乘2返回 -var DoubleFunc = CreateMultiplier(2); -Console.WriteLine(DoubleFunc(10)); // 输出 20 -``` - -## 类型转换 \ No newline at end of file diff --git a/docs/extra/lua/data_type.md b/docs/extra/lua/data_type.md new file mode 100644 index 0000000..e011abf --- /dev/null +++ b/docs/extra/lua/data_type.md @@ -0,0 +1,538 @@ +# Lua 数据类型 + +## 基本数据类型 +`Lua` 是动态类型语言, 其变量在运行时根据赋值的内容自动决定数据类型. + +`Lua` 有以下 8 种基本数据类型: + +- `nil`: 表示一个空值或无效值 +- `number`: 表示双精度类型的浮点数 +- `string`: 表示字符串 +- `boolean`: 表示布尔值 +- `table`: 表示表类型 +- `function`: 表示函数类型 +- `userdata`: 表示用户自定义的数据类型 +- `thread`: 表示线程类型 + +!!!info + `Loenn` 侧的 `Lua` 脚本编写并不会涉及 `userdata` 与 `thread`, 下面不做介绍. + 实际上是自己也不清楚(草草 + +我们可以使用 `type()` 函数查看变量的类型: +```lua +-- nil +print(type(nil)) -- 输出 nil + +-- number +print(type(202)) -- 输出 number +print(type(3.14)) -- 输出 number + +-- string +print(type("Celeste")) -- 输出 string +print(type("mb6fbhsphdrcb")) -- 输出 string + +-- boolean +print(type(true)) -- 输出 boolean +print(type(false)) -- 输出 boolean + +-- table +local numbers = {1, 2, 3} +print(type(numbers)) -- 输出 table + +-- function +local function add(a, b) + return a + b +end +print(type(add)) -- 输出 function +``` + +对于类型比较, `type()` 函数返回的是一个 `string` 类型. +正确的比较方式是将 `type()` 的返回值与字符串进行比较, 并且需要使用 `""` 引用类型字符串: +```lua +print(type(nil) == nil) -- 输出 false, type(nil) 返回的是 "nil", "nil" 不等于 nil +print(type(nil) == "nil") -- 输出 true, type(nil) 返回的是 "nil", "nil" 等于 "nil" +``` + +### nil + +`nil` 是一种特殊的类型, 只包含一个值 `nil`. 所有未初始化的变量都被视为 `nil`, 把变量赋值为 `nil` 即可删除这个变量: +```lua +print(a) -- 输出 nil +local a = 10 -- 初始化变量 a +print(a) -- 输出 10 +a = nil -- 删除变量 a +print(a) -- 输出 nil +``` + +`nil` 在逻辑判断中被视为"假", 但其与布尔值 `false` 是不同的值: +```lua +local value = nil +if value then + print("Value is valid") +else + print("Value is nil") -- 输出 Value is nil +end + +print(nil == false) -- 输出 false +print(type(nil)) -- 输出 nil +print(type(false)) -- 输出 boolean +``` + +### number + +`Lua` 默认只有一种数字类型, 即双精度浮点数 `double`. 以下写法都可以表示 `number` 类型: +```lua +-- 输出结果都为 number +print(type(0)) +print(type(2)) +print(type(2.2)) +print(type(0.2)) +print(type(2e+1)) +print(type(0.2e-1)) +print(type(7.8263692594256e-06)) +``` + +`number` 在进行浮点数运算时会出现数值精度误差, 这导致在进行计算时可能会出现预期外的结果: +```lua +print(0.1 + 0.2) -- 输出 0.3, 但实际计算结果可能是 0.30000000000000004 +print(0.1 + 0.2 == 0.3) -- 输出 false + +-- 浮点数精度比较函数的可能实现 +-- 添加参数 precision 判断两个浮点数的误差是否小到可以忽略 +local function almostEqual(a, b, precision) + precision = precision or 1e-10 + return math.abs(a - b) < precision +end + +print(almostEqual(0.1 + 0.2, 0.3)) -- 输出 true, 忽略了微小误差 +``` + +`number` 类型存在三种特殊值: `infinite`, `-infinite` 以及 `NaN`. 其中, `NaN` 是唯一不等于自身的值: +```lua +print(type(1 / 0)) -- 输出 number +print(type(-1 / 0)) -- 输出 number +print(type(0 / 0)) -- 输出 number + +print(1 / 0) -- 输出 inf +print(math.huge) -- 输出 inf +print(-1 / 0) -- 输出 -inf +print(-math.huge) -- 输出 -inf +print(0 / 0) -- 输出 -nan(ind) + +print((0 / 0) == (0 / 0)) -- 输出 false, NaN 不等于自身 +``` + +!!!note + `-nan(ind)` 表示未定义结果, `nan` 表示这不是一个数字, 即 `Not a Number`. 其中 `ind` 是 `indeterminate` 的缩写, 即"不确定". + 进行未定义行为的运算都会得到这个值, 例如 `0 / 0`, `0 ^ 0` 以及 `math.sqrt(-1)` 等. + +### string + +`Lua` 中 `string` 类型用于表示文本数据或字符序列. 可以使用 `' '`, `" "` 以及 `[[ ]]` 声明字符串: +```lua +local str1 = "Celeste" -- 使用 "" 声明 +local str2 = 'Everest' -- 使用 '' 声明, "" 与 '' 并没有区别 + +-- 使用 [[]] 声明多行字符串, 这种声明方式会保留字符串中的换行与格式 +-- print(str3) 的输出会是: +-- +-- some stuff i guess +-- another stuff +local str3 = [[ +some stuff i guess +another stuff +]] + +print(type(str1)) -- 输出 string +print(type(str2)) -- 输出 string +print(type(str3)) -- 输出 string +``` + +可以在字符串中使用转义字符 `\` 表示一些无法直接输入或有特殊含义的字符: +```lua +print("\"wow\"") -- 输出 "wow" +print("IVXL \\\\ ECOM") -- 输出 IVXL \\ ECOM +print("a line\nnew line") -- 输出 a line + -- new line +``` + +需要连接字符串使用 `..` 运算符, 需要计算字符串的长度使用 `#` 运算符: +```lua +local str1 = "speed" +local str2 = "run" + +print(str1 .. str2) -- 输出 speedrun +print(str1 .. " " .. str2) -- 输出 speed run + +print(#str1) -- 输出 5 +print(#str2) -- 输出 3 +``` + +`string` 类型是不可变的, 所有修改字符串的操作本质上都是生成并返回修改后的字符串: +```lua +local str1 = "hi there" +print(str1) -- 输出 hi there + +-- 直接修改 string 的值会报错 +-- str1[1] = "H" 报错 attempt to index a string value (local 'str1') + +local str2 = "H" .. str1:sub(2) -- 使用 .. 运算符与 sub 方法生成新的字符串 str2 +print(str2) -- 输出 Hi there +print(str1) -- 输出 hi there, str1 的值并没有被改变 +``` + +### boolean + +`boolean` 类型有两个取值: `true` 和 `false`, 通常用于条件判断, 循环控制等. 可以直接声明 `boolean` 类型的变量为 `true` 或 `false`: +```lua +local var1 = true +local var2 = false + +print(var1) -- 输出 boolean +print(var2) -- 输出 boolean +``` + +`nil` 和 `false` 是唯一被认为是"假"的值, 其他的值都被认为是"真": +```lua +-- nil 被认为是假 +if nil then + print("nil is true") +else + print("nil is false") -- 输出 nil is false +end + +-- false 被认为是假 +if false then + print("false is true") +else + print("false is false") -- 输出 false is false +end + +-- 0 被认为是真 +if 0 then + print("0 is true") -- 输出 0 is true +else + print("0 is false") +end + +-- 空字符串 "" 被认为是真 +if "" then + print("\"\" is true") -- 输出 "" is true +else + print("\"\" is false") +end + +-- 空表 {} 被认为是真 +if {} then + print("{} is true") -- 输出 {} is true +else + print("{} is false") +end +``` + +### table + +`Lua` 只有 `table` 一种基本数据结构, 即"表". 其可以实现数组, 字典, 堆栈, 链表等复杂数据结构. `table` 是关联数组, 可以使用除 `nil` 外任何类型的值作为数组的索引. 索引对应的值可以是任何类型, 包括 `nil`. `table` 没有预定义的大小, 可以动态扩展. + +我们可以使用 `{}` 声明一个空表, 也可以向其填充数据以直接初始化表. 可以通过 `[]` 索引器访问对应的值: + +!!!info + `Lua` 还提供了一种遍历表中元素的访问方式, 你可以在 [Lua - 迭代器](iterator.md) 找到. + +```lua +-- 声明一个空表 +local emptyTable = {} + +-- 预先填充数据以直接初始化表, 其中每项元素使用 , 进行分隔 +-- 连续索引的表 +local fruitTable = {"apple", "orange", "strawberry"} + +-- 连续索引, 即数组类型的表其索引从 1 开始而不是 0 +-- 索引越界会返回 nil +print(fruitTable[1]) -- 输出 apple +print(fruitTable[0]) -- 输出 nil +print(fruitTable[4]) -- 输出 nil + +--------------------------------------------------------------------------------------------- + +local function someFunc() + return "hi there" +end + +local function noReturnValue() end + +-- 非连续索引的表可以有任意类型和不连续的键 +local mixedTable = { + [1] = nil, -- number 作为索引, nil 作为值 + ["count"] = 202, -- string 作为索引, number 作为值 + result = true, -- string 作为索引时可以省略 [""], boolean 作为值 + [true] = "a boolean value", -- boolean 作为索引, string 作为值 + sayHi = someFunc(), -- string 作为索引, function 作为值 + [someFunc()] = "use function as index" -- function 作为索引, string 作为值 + +-- 不能使用没有返回值的函数作为索引, 访问时会报错 table index is nil +-- 没有返回值的函数会返回 nil, nil 不能作为表的索引 +-- [noReturnValue()] = "error" +} + +-- 表内也可以嵌套表 +local nestedTable = { + [fruitTable] = "some fruit", -- table 作为索引, string 作为值 + inner = { -- string 作为索引, table 作为值 + innerIndex = "innerValue" + } +} + +-- 通过 [] 访问索引对应的值 +print(mixedTable[1]) -- 输出 nil +print(mixedTable["count"]) -- 输出 202 +print(mixedTable.result) -- 输出 true, string 作为索引可以通过 . 访问其对应的值 +print(mixedTable[true]) -- 输出 a boolean value + +-- 函数作为索引时会使用其返回值作为索引, 有多个返回值则使用第一个返回值作为索引 +-- 也可以直接通过函数名访问对应的值 +print(mixedTable["hi there"]) -- 输出 use function as index +print(mixedTable[someFunc()]) -- 输出 use function as index + +-- 函数作为值时访问会返回其返回值 +print(mixedTable.sayHi) -- 输出 hi there + +print(nestedTable[fruitTable]) -- 输出 some fruit +print(nestedTable.inner.innerIndex) -- 输出 innerValue + +-- 访问不存在的索引会返回 nil +print(nestedTable.notExistIndex) -- 输出 nil +``` + +我们也可以动态地向表中添加或删除元素: +```lua +local someTable = {} + +-- 动态添加元素 +someTable.player = "Madeline" +someTable[2] = "second element" +someTable.square = function(x) return x ^ 2 end + +--[[ +添加完成后的表会是 +someTable = { + player = "Madeline", + [2] = "second element", + square = function(x) return x ^ 2 end +} +--]] + +print(someTable.player) -- 输出 Madeline +print(someTable[2]) -- 输出 second element +print(someTable.square(5)) -- 输出 25.0 + +-- 向索引赋值 nil 即可删除键值对 +someTable.player = nil +someTable[2] = nil + +--[[ +删除完成后的表会是 +someTable = { + square = function(x) return x ^ 2 end +} +--]] + +print(someTable.player) -- 输出 nil +print(someTable[2]) -- 输出 nil +print(someTable.square(5)) -- 输出 25.0 +``` + +`Lua` 中的 `table` 是引用类型, 直接使用 `=` 操作符赋值并不会复制表, 而是创建对原表的引用. +直接比较两个表时,会比较它们的引用地址而不是表的内容. 在比较两个表是否相等时可能导致预期外的结果: +```lua +local emptyTable = {} +print(emptyTable == {}) -- 输出 false + +local table1 = {1, 2, 3} +local table2 = {1, 2, 3} +local table3 = table1 +print(table1 == table2) -- 输出 false +print(table1 == table3) -- 输出 true +``` + +`Lua` 并没有内建实现表的比较与复制的函数. 需要额外实现. + +### function + +`Lua` 中的函数使用 `function` 关键字声明.以 `end` 关键字结束. 函数的结构如下: +```lua +optionalFunctionScope function functionName(argument1, argument2..., argumentn) + functionBody + return result1, result2..., resultn +end +``` + +- `optionalFunctionScope`: 可选部分, 函数的作用域. 默认为全局函数, 使用 `local` 关键字声明局部函数. +- `functionName`: 函数名, 调用函数时所使用的标识符. +- `argument1, argument2..., argumentn`: 可选部分, 传递给函数的参数. 参数的数量可以是任意多. +- `functionBody`: 函数体, 函数需要执行的代码语句块. +- `result1, result2..., resultn`: 可选部分, 函数的返回值. 返回值的数量可以是任意多. + +例如: +```lua +-- 定义局部函数 calculate, 接受两个参数 a b, 计算其相加,相减以及相乘的值并返回 +local function calculate(a, b) + local add = a + b + local sub = a - b + local mul = a * b + return sum, sub, mul +end + +local addResult, subResult, mulResult = calculate(20, 5) +print(addResult, subResult, mulResult) -- 输出 25 15 100 +``` + +`Lua` 支持可变参数, 函数可以接受可变数量的参数, 在参数列表中使用 `...` 进行声明: + +!!!note + `...` 是可变参数表达式, 表示一个动态的参数列表. `...` 本身并不是一个表,而是一个特殊的语法结构. + 必须显式地把 `...` 转换成表才能访问这些参数. + +```lua +local function average(...) + local result = 0 + local args = {...} -- 显式转换可变参数 `...` 至表 args + + if #args == 0 then return 0 end -- #args 返回表的长度, 即参数数量. 判断是否有参数传入 + + for _, value in ipairs(args) do + result = result + value + end + + return result / #args +end + +print(average(1, 2, 3)) -- 输出 2.0 +print(average(1, 2, 3, 5, 10)) -- 输出 4.2 +print(average()) -- 输出 0 +``` + +`Lua` 支持函数式编程, 函数可以作为变量赋值, 参数传递以及结果返回: + +```lua +-- 函数可以作为变量赋值 +-- 使用匿名函数定义加法操作 +local add = function (a, b) + return a + b +end + +print(add(1, 2)) -- 输出 3 + +-- 函数可以作为参数传递 +-- 定义一个接受函数作为参数的高阶函数 +local function apply(func, x, y) + return func(x, y) +end + +local function sub(a, b) + return a - b +end + +-- 将 sub 函数作为参数传递给 apply 函数 +print(apply(sub, 10, 3)) -- 输出 7 + +-- 函数可以作为返回结果 +-- 定义 createMultiplier 函数, 返回一个新的函数, 该函数会将其参数与给定的 factor 相乘 +local function createMultiplier(factor) + -- 返回一个捕获 factor 的匿名函数 + return function(x) + return x * factor + end +end + +-- 定义 double 函数, 该函数会将其参数乘2返回 +local double = createMultiplier(2) +print(double(10)) -- 输出 20 +``` + +???note "上方 Lua 代码对应的 C# 代码" + + ```cs + // 函数可以作为变量赋值 + // 使用委托定义加法操作 + Func Add = (a, b) => a + b; + Console.WriteLine(Add(1, 2)); // 输出 3 + + // 函数可以作为参数传递 + // 定义一个接受函数作为参数的高阶函数 + double Apply(Func func, double x, double y) + { + return func(x, y); + } + + Func Sub = (a, b) => a - b; + + // 将 Sub 函数作为参数传递给 Apply 函数 + Console.WriteLine(Apply(Sub, 10, 3)); // 输出 7 + + // 函数可以作为返回结果 + // 定义 CreateMultiplier 函数, 返回一个新的函数, 该函数会将其参数与给定的 factor 相乘 + Func CreateMultiplier(double factor) + { + // 返回一个捕获 factor 的匿名函数 + return x => x * factor; + } + + // 定义 DoubleFunc 函数, 该函数会将其参数乘2返回 + var DoubleFunc = CreateMultiplier(2); + Console.WriteLine(DoubleFunc(10)); // 输出 20 + ``` + +## 类型转换 + +`Lua` 提供以下三种显式类型转换函数: + +- `tonumber(e)`: 将 `string` 类型的 `e` 转换为 `number`, 失败会返回 `nil`. +- `tonumber(e, base)`: 将 `string` 类型的 `e` 从指定进制 `base` 转换为十进制 的 `number`, 失败会返回 `nil`. +- `tostring(v)`: 将任何类型 `v` 转换为 `string`, 函数和表会返回其内存地址. + +以下是使用示例: +```lua +local function printToNumber(e, base) + local castedInput = tonumber(e) + + if base then + castedInput = tonumber(e, base) + end + + if type(castedInput) == "nil" then + print("type: nil, cast failed") + else + print("type: " .. type(castedInput) .. " value: " .. castedInput) + end +end + +printToNumber("123") -- 输出 type: number value: 123 +printToNumber("123.45") -- 输出 type: number value: 123.45 +printToNumber("-123") -- 输出 type: number value: -123 +printToNumber("0") -- 输出 type: number value: 0 + +printToNumber("FF", 16) -- 输出 type: number value: 255 +printToNumber("1010", 2) -- 输出 type: number value: 10 +printToNumber("1010", 3) -- 输出 type: number value: 30 +printToNumber("3", 2) -- 输出 type: nil, cast failed + +printToNumber("abc") -- 输出 type: nil, cast failed +printToNumber("") -- 输出 type: nil, cast failed +printToNumber(nil) -- 输出 type: nil, cast failed +printToNumber(true) -- 输出 type: nil, cast failed + +--------------------------------------------------------------------------------------------- + +print(tostring(123)) -- 输出 123 +print(tostring(123.45)) -- 输出 123.45 +print(tostring(-123)) -- 输出 -123 +print(tostring(0)) -- 输出 0 + +print(tostring(nil)) -- 输出 nil +print(tostring(true)) -- 输出 true +print(tostring(false)) -- 输出 false + +print(tostring(function() end)) -- 输出 function: 000002B0EBF58730, 内存地址可能不同 +print(tostring({"some stuff"})) -- 输出 table: 000002B0EBF563C0, 内存地址可能不同 +``` \ No newline at end of file diff --git a/docs/extra/lua/exception_handling.md b/docs/extra/lua/exception_handling.md new file mode 100644 index 0000000..cabb2b6 --- /dev/null +++ b/docs/extra/lua/exception_handling.md @@ -0,0 +1 @@ +# Lua 异常处理 \ No newline at end of file diff --git a/docs/extra/lua/function.md b/docs/extra/lua/function.md deleted file mode 100644 index e69de29..0000000 diff --git a/docs/extra/lua/iterator.md b/docs/extra/lua/iterator.md index e69de29..970aeff 100644 --- a/docs/extra/lua/iterator.md +++ b/docs/extra/lua/iterator.md @@ -0,0 +1 @@ +# Lua 迭代器 \ No newline at end of file diff --git a/docs/extra/lua/metatable.md b/docs/extra/lua/metatable.md new file mode 100644 index 0000000..5ac659c --- /dev/null +++ b/docs/extra/lua/metatable.md @@ -0,0 +1 @@ +# Lua 元表 \ No newline at end of file diff --git a/docs/extra/lua/oop.md b/docs/extra/lua/oop.md new file mode 100644 index 0000000..6912b30 --- /dev/null +++ b/docs/extra/lua/oop.md @@ -0,0 +1 @@ +# Lua 面向对象 \ No newline at end of file diff --git a/docs/extra/lua/operator.md b/docs/extra/lua/operator.md index 2511d8d..98630a1 100644 --- a/docs/extra/lua/operator.md +++ b/docs/extra/lua/operator.md @@ -1,4 +1,4 @@ -# 运算符 +# Lua 运算符 运算符是一种特殊的符号, 用于告诉解释器执行特定的数学或逻辑运算. `Lua` 提供以下运算符类型: diff --git a/docs/extra/lua/package.md b/docs/extra/lua/package.md index e69de29..d49b72f 100644 --- a/docs/extra/lua/package.md +++ b/docs/extra/lua/package.md @@ -0,0 +1 @@ +# Lua 模块与包 \ No newline at end of file diff --git a/docs/extra/lua/syntax.md b/docs/extra/lua/syntax.md index 96e39ae..d321fc0 100644 --- a/docs/extra/lua/syntax.md +++ b/docs/extra/lua/syntax.md @@ -25,7 +25,7 @@ - 标识符不能包含特殊字符例如 `@`, `$`, 与 `%` 等. - 标识符不能以 `Lua` 中的保留关键字开头. -???note "Lua中的关键字" +???note "Lua 中的关键字" `Lua` 包含以下关键字, 不能用于作为标识符: | | | | | @@ -53,6 +53,33 @@ true = 5 -- 不能以保留关键字开头 my-var = 10 -- 不能包含特殊字符 ``` +## 变量 + +`Lua` 支持在一行内声明多个变量与交换变量: +```lua +-- 一行内声明多个变量 +a, b, c = 1, 2, 3 +print(a, b, c) -- 输出 1 2 3 + +-- 交换变量 +x, y = 10, 20 +print(x, y) -- 输出 10 20 + +x, y = y, x +print(x, y) -- 输出 20 10 +``` + +当变量数量与值不匹配时, 缺少的值所对应的变量将会赋值为 `nil`, 多余的值将被忽略: +```lua +-- 左边变量的数量少于右边赋的值时,缺少的变量会被赋值为 nil +a, b, c, = 1, 2 +print(a, b, c) -- 输出 1 2 nil + +-- 右边赋的值多于左边变量的数量时, 多余的值将被忽略 +x, y, z = 10, 20, 30, 40 +print(x, y, z) -- 输出 10 20 30 +``` + ## 作用域 `Lua` 中默认情况下定义的变量与函数都是全局的. 全局变量与全局函数在整个程序中的任何位置都可以被访问与修改. diff --git a/mkdocs.yml b/mkdocs.yml index c5a8ab0..9ba3909 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -101,12 +101,14 @@ nav: - Lua: - 开始: "extra/lua/begin.md" - 基本语法: "extra/lua/syntax.md" - - 数据类型: "extra/lua/data_structure.md" + - 数据类型: "extra/lua/data_type.md" - 流程控制: "extra/lua/control_flow.md" - 运算符: "extra/lua/operator.md" - - 函数: "extra/lua/function.md" - 迭代器: "extra/lua/iterator.md" + - 元表: "extra/lua/metatable.md" + - 异常处理: "extra/lua/exception_handling.md" - 模块与包: "extra/lua/package.md" + - 面向对象: "extra/lua/oop.md" - LuaCutscene: - 开始: "extra/lua_cutscene/begin.md" - 参考: "extra/lua_cutscene/reference.md" From 40ea56f6f923110330dbfdf5d681506993bc1bd8 Mon Sep 17 00:00:00 2001 From: ClearZer0 <534310154@qq.com> Date: Wed, 29 Jan 2025 06:23:53 +0800 Subject: [PATCH 17/26] small change --- docs/coding_setup/debug.md | 10 +++++----- docs/extra/lua/begin.md | 4 ++-- docs/misc/change_log.md | 7 +++++-- 3 files changed, 12 insertions(+), 9 deletions(-) diff --git a/docs/coding_setup/debug.md b/docs/coding_setup/debug.md index db31887..7e8e7b1 100644 --- a/docs/coding_setup/debug.md +++ b/docs/coding_setup/debug.md @@ -34,10 +34,10 @@ 在经过如上的配置后, 你会发现在蔚蓝启动的时候, 进行编译并复制资源时会报错, 这是因为 Everest 锁定占用了它们, 导致你不得不让这一切在蔚蓝关闭时进行, -同时由于蔚蓝的重启速度不是很理想, 这大大的拉低了 mod 开发效率. +同时由于蔚蓝的重启速度不是很理想, 这大大的拉低了 Mod 开发效率. 不过好在 Everest 提供了一个技术叫做 `code hot reload`, -即热重载, 它允许你在游戏运行期间替换你的代码并重载资源. -要开启这项功能, 首先到你的蔚蓝根目录下的 Saves 目录, 找到并打开 `modsettings-Everest.celeste` 这个文件, +即热重载, 它允许在游戏运行期间替换你的代码并重载资源. +要开启这项功能, 首先到蔚蓝根目录下的 `Saves` 目录, 找到并打开 `modsettings-Everest.celeste` 这个文件, 翻到大概中间的位置, 找到属性 `CodeReload_WIP`, 将其更改为 `true`. ```yaml title="modsettings-Everest.celeste" hl_lines="11" @@ -61,7 +61,7 @@ LogLevels: {} # 其他设置 ``` -完成设置后重新编译项目, 你应该就不会再得到任何错误, 并且 Everest 也正确地热重载了你的 mod 和你的 mod 资源. +完成设置后重新编译项目, 你应该就不会再得到任何错误, 并且 Everest 也正确地热重载了你的 Mod 和你的 Mod 资源. ## Logger @@ -84,7 +84,7 @@ public static void Log(LogLevel logLevel, string tag, string str) - `Warn`: 一般用于输出一些错误但不影响游戏进行的信息. - `Error`: 一般用于输出一些致命性错误. -一般地, 游戏只会打印 `Info` 等级及以上的日志, 你可以通过在 `everest-launch.txt` 中加入`--loglevel {等级}`来指定过滤等级. +一般地, 游戏只会打印 `Info` 优先级及以上的日志, 你可以通过在 `everest-launch.txt` 中加入`--loglevel {等级}`来指定过滤等级. 下面是一些使用示例: diff --git a/docs/extra/lua/begin.md b/docs/extra/lua/begin.md index 889d10d..78dab78 100644 --- a/docs/extra/lua/begin.md +++ b/docs/extra/lua/begin.md @@ -53,12 +53,12 @@ Lua 5.4.6 Copyright (C) 1994-2023 Lua.org, PUC-Rio ### Visual Studio Code 配置 这一步实际上是可选的, 不过为了更愉快的 `Lua` 脚本的编写, 个人还是觉得挺有必要的. -在这里我会推荐使用 [Visual Studio Code](https://code.visualstudio.com/Download) 配上 [Lua (sumneko.lua)](https://marketplace.visualstudio.com/items?itemName=sumneko.lua) +在这里推荐使用 [Visual Studio Code](https://code.visualstudio.com/Download) 配上 [Lua (sumneko.lua)](https://marketplace.visualstudio.com/items?itemName=sumneko.lua) 插件: ![lua-in-vscode](images/begin/lua_in_vscode.png) !!! note - 个人不太会配置这种 lua 环境, 所以如果你遇到了大量的未定义警告你可以选择在设置中搜索 `Lua.diagnostics.enable` 并将其关闭. + 个人不太会配置这种 `Lua` 环境, 所以如果你遇到了大量的未定义警告你可以选择在设置中搜索 `Lua.diagnostics.enable` 并将其关闭. 此外, Lua (sumneko.lua) 插件并不支持 `Lua` 的运行. 个人推荐安装 [Code Runner](https://marketplace.visualstudio.com/items?itemName=formulahendry.code-runner) 插件. diff --git a/docs/misc/change_log.md b/docs/misc/change_log.md index c1913e9..1363ea5 100644 --- a/docs/misc/change_log.md +++ b/docs/misc/change_log.md @@ -28,12 +28,15 @@ * 编写 [实战 - 测试地图](../coding_challenges/test_map.md) * 完善 [进阶 - 跨 Mod 交互](../advanced/cross_mod_interactions.md) -### 2025.1.16 +### 2025.1.19 * 归档 [一些准备 - 偏好](../arc/preference.md) * 重构 [一些准备 - 调试](../coding_setup/debug.md) * 完善 [进阶 - 跨 Mod 交互 - #ModInterop](../advanced/cross_mod_interactions.md) * 移动 [额外 - CMCC](../extra/cmcc/index.md), [额外 - LuaCutscene](../extra/lua_cutscene/begin.md) 以及[其他 - XML 简单介绍](../extra/xml/xml_speedrun.md) 至额外章节以优化排版 -### 2025.1.17 +### 2025.1.28 +* 添加插件以显示页面的创建与最后修改时间 以及文档编写者 + +### 2025.2.7 * 更新项目模板 * 编写 [额外 - Lua](../extra/lua/begin.md) \ No newline at end of file From 4a77a343939864d148398e474931a6fc4645de85 Mon Sep 17 00:00:00 2001 From: ClearZer0 <534310154@qq.com> Date: Thu, 30 Jan 2025 17:36:42 +0800 Subject: [PATCH 18/26] =?UTF-8?q?Lua=E9=80=9F=E9=80=9Apart=203-1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/advanced/cross_mod_interactions.md | 3 +- docs/basics/session_settings_savedata.md | 40 ++----- docs/coding_challenges/simple_entity.md | 19 ++- docs/coding_challenges/simple_texturing.md | 12 +- docs/coding_challenges/simple_trigger.md | 4 - docs/coding_setup/basic_env.md | 2 +- docs/extra/lua/Sample.lua | 123 +++++++++++++------ docs/extra/lua/control_flow.md | 130 ++++++++++++++++++++- docs/extra/lua/data_type.md | 2 +- docs/misc/change_log.md | 3 +- docs/misc/to_do_list.md | 2 +- 11 files changed, 254 insertions(+), 86 deletions(-) diff --git a/docs/advanced/cross_mod_interactions.md b/docs/advanced/cross_mod_interactions.md index 6668992..4dfc28d 100644 --- a/docs/advanced/cross_mod_interactions.md +++ b/docs/advanced/cross_mod_interactions.md @@ -225,9 +225,8 @@ Everest 会将所有 Code Mod 的程序集使用 MonoMod 进行 patch 处理后 - GravityHelper.GravityHelper.dll - ExtendedVariantMode.ExtendedVariantMode.dll - ` FrostHelper.FrostTempleHelper.dll + - FrostHelper.FrostTempleHelper.dll - 我们填写目标 Mod 在 `Cache` 中名称的前半段就行. ### lib-stripped diff --git a/docs/basics/session_settings_savedata.md b/docs/basics/session_settings_savedata.md index 89ab24f..36f160b 100644 --- a/docs/basics/session_settings_savedata.md +++ b/docs/basics/session_settings_savedata.md @@ -15,7 +15,7 @@ Settings, 顾名思义就是选项的意思. Everest 为我们封装了一个非 在此之前, 我们先保存一下我们的 `EverestModule` 实例以方便我们访问它的实例(Everest 会确保它是单例的): ```cs -public class MyCelesteModModule : EverestModule +public sealed class MyCelesteModModule : EverestModule { public static MyCelesteModModule Instance { get; private set; } @@ -33,7 +33,7 @@ public class MyCelesteModModule : EverestModule 然后新建一个名字最好以 mod 开头, `Settings` 结尾的 `MyCelesteModSettings` 类并继承 `EverestModuleSettings`: ```cs -public class MyCelesteModSettings : EverestModuleSettings +public sealed class MyCelesteModSettings : EverestModuleSettings { } @@ -42,7 +42,7 @@ public class MyCelesteModSettings : EverestModuleSettings 然后在 module 类里这样注册这个类: ```cs hl_lines="5-6" -public class MyCelesteModModule : EverestModule +public sealed class MyCelesteModModule : EverestModule { public static MyCelesteModModule Instance { get; private set; } @@ -63,7 +63,7 @@ public class MyCelesteModModule : EverestModule 现在, 我们向选项中新加一条**公开**的 bool 类型的属性: ```cs -public class MyCelesteModSettings : EverestModuleSettings +public sealed class MyCelesteModSettings : EverestModuleSettings { public bool AnInterestingSwitch { get; set; } } @@ -78,7 +78,7 @@ public class MyCelesteModSettings : EverestModuleSettings 除此之外 Everest 还支持枚举, 字符串和数字, 它们分别会生成这样的选项: ```cs -public class MyCelesteModSettings : EverestModuleSettings +public sealed class MyCelesteModSettings : EverestModuleSettings { public bool AnInterestingSwitch { get; set; } @@ -126,7 +126,7 @@ public class MyCelesteModSettings : EverestModuleSettings 在这里, 我们需要的本地化键名是 `modoptions_{类名}_{属性名}`, 例如如下类: ```cs -public class MyCelesteModSettings : EverestModuleSettings +public sealed class MyCelesteModSettings : EverestModuleSettings { public bool EnableFunnyThing { get; set; } } @@ -201,17 +201,13 @@ Session 是一个蔚蓝中保存数据的概念, 它用于保存 "保存并退 与 Settings 相同, 我们需要先创建一个继承于 `EverestModuleSession` 的类, 然后在模块类中声明它: ```cs title="MyCelesteModSession.cs" -namespace Celeste.Mod.MyCelesteMod; - -public class MyCelesteModSession : EverestModuleSession +public sealed class MyCelesteModSession : EverestModuleSession { } ``` ```cs title="MyCelesteModModule.cs" -namespace Celeste.Mod.MyCelesteMod; - -public class MyCelesteModModule : EverestModule +public sealed class MyCelesteModModule : EverestModule { public static MyCelesteModModule Instance { get; private set; } @@ -239,19 +235,13 @@ public class MyCelesteModModule : EverestModule 退出了游戏, 再次进入时你会发现重生点是新的, 而 `PassByRefill` 的冲刺数又变回 `1` 了, 所以接下来我们尝试通过 `Session` 来修正这个错误. ```cs title="MyCelesteModSession.cs" -namespace Celeste.Mod.MyCelesteMod; - -public class MyCelesteModSession : EverestModuleSession +public sealed class MyCelesteModSession : EverestModuleSession { public Dictionary RoomIdToPassByRefillDashes = new(); // 我们将记录每个房间名对应的PassByRefill的冲刺数 } ``` ```cs title="SetPassByRefillDashesTrigger.cs" -using Celeste.Mod.Entities; - -namespace MyCelesteMod; - [CustomEntity("MyCelesteMod/SetPassByRefillDashesTrigger")] public class SetPassByRefillDashesTrigger : Trigger { @@ -272,10 +262,6 @@ public class SetPassByRefillDashesTrigger : Trigger ``` ```cs title="PassByRefill.cs" -using Celeste.Mod.Entities; - -namespace MyCelesteMod; - [CustomEntity("MyCelesteMod/PassByRefill")] public class PassByRefill : Entity { @@ -321,17 +307,13 @@ public class PassByRefill : Entity 使用它与使用 `Session` 极其相似: ```cs title="MyCelesteModSaveData.cs" -namespace Celeste.Mod.MyCelesteMod; - -public class MyCelesteModSaveData : EverestModuleSaveData +public sealed class MyCelesteModSaveData : EverestModuleSaveData { } ``` ```cs title="MyCelesteModModule.cs" -namespace Celeste.Mod.MyCelesteMod; - -public class MyCelesteModModule : EverestModule +public sealed class MyCelesteModModule : EverestModule { public static MyCelesteModModule Instance { get; private set; } diff --git a/docs/coding_challenges/simple_entity.md b/docs/coding_challenges/simple_entity.md index 345f961..0a9448c 100644 --- a/docs/coding_challenges/simple_entity.md +++ b/docs/coding_challenges/simple_entity.md @@ -31,8 +31,6 @@ 那么你应该会写出如下的代码: ```cs title="PassByRefill.cs" -namespace MyCelesteMod; - public class PassByRefill : Entity { @@ -60,8 +58,10 @@ public PassByRefill(Vector2 position, Vector2 size, int dashes) 接下来, 我们需要声明一个特殊的构造函数, 以让 Everest 反射调用并使得我们的实体可以正常获取地图的数据: ```cs title="PassByRefill.cs" public PassByRefill(EntityData data, Vector2 offset) - : this(data.Position + offset, new Vector2(data.Width, data.Height), data.Int("dashes")) - { } + : this(data.Position + offset, new Vector2(data.Width, data.Height), data.Int("dashes")) +{ + +} ``` 在这里, `EntityData data` 储存了作图软件保存的相关数据, 我们要提取它们很简单. 比如说我们要提取一个名为 `dashes` 的 `int` 类型的数据, 我们就简单地调用它的方法 `Int(string name)`, @@ -83,7 +83,8 @@ public PassByRefill(EntityData data, Vector2 offset) [CustomEntity("MyCelesteMod/PassByRefill")] public class PassByRefill : Entity { -...... + // ...... +} ``` 在这里 "名称 ID" 我们一般推荐以 "{Mod名}/该实体类名" 进行命名, 就像这里一样, Mod 名为 `MyCelesteMod`, 类名为 `PassByRefill`, 实体 "名称 ID" 就是 `MyCelesteMod/PassByRefill`. 这里我建议你记住它, 待会我们会在作图软件配置的时候用到. @@ -243,10 +244,6 @@ Draw.Rect(Position, Width, Height, c); 如果你遇到了困难, 你可以对比一下最终的代码: ```cs title="PassByRefill.cs" -using Celeste.Mod.Entities; - -namespace MyCelesteMod; - [CustomEntity("MyCelesteMod/PassByRefill")] public class PassByRefill : Entity { @@ -262,7 +259,9 @@ public class PassByRefill : Entity public PassByRefill(EntityData data, Vector2 offset) : this(data.Position + offset, new Vector2(data.Width, data.Height), data.Int("dashes")) - { } + { + + } public override void Update() { diff --git a/docs/coding_challenges/simple_texturing.md b/docs/coding_challenges/simple_texturing.md index d04952b..bc6321a 100644 --- a/docs/coding_challenges/simple_texturing.md +++ b/docs/coding_challenges/simple_texturing.md @@ -28,7 +28,9 @@ public PassByRefill(EntityData data, Vector2 offset) : this(data.Position + offset, data.Int("dashes")) - { } + { + + } ``` === "Before" ```cs title="PassByRefill.cs" @@ -42,7 +44,9 @@ public PassByRefill(EntityData data, Vector2 offset) : this(data.Position + offset, new Vector2(data.Width, data.Height), data.Int("dashes")) - { } + { + + } ``` !!! info @@ -108,7 +112,9 @@ public class PassByRefill : Entity public PassByRefill(EntityData data, Vector2 offset) : this(data.Position + offset, data.Int("dashes")) - { } + { + + } public override void Update() { diff --git a/docs/coding_challenges/simple_trigger.md b/docs/coding_challenges/simple_trigger.md index 6edc903..f025175 100644 --- a/docs/coding_challenges/simple_trigger.md +++ b/docs/coding_challenges/simple_trigger.md @@ -126,10 +126,6 @@ foreach(var refill in refills) 最后, 你的代码应该总体上是这个样子: ```cs title="SetPassByRefillDashesTrigger.cs" -using Celeste.Mod.Entities; - -namespace MyCelesteMod; - [CustomEntity("MyCelesteMod/SetPassByRefillDashesTrigger")] public class SetPassByRefillDashesTrigger : Trigger { diff --git a/docs/coding_setup/basic_env.md b/docs/coding_setup/basic_env.md index 6264e0a..0a67f3a 100644 --- a/docs/coding_setup/basic_env.md +++ b/docs/coding_setup/basic_env.md @@ -150,7 +150,7 @@ dotnet new install Saladim.CelesteModTemplate ```cs namespace MyCelesteMod; -public class MyCelesteModModule : EverestModule +public sealed class MyCelesteModModule : EverestModule { public override void Load() { diff --git a/docs/extra/lua/Sample.lua b/docs/extra/lua/Sample.lua index 9e3c139..0d6d01a 100644 --- a/docs/extra/lua/Sample.lua +++ b/docs/extra/lua/Sample.lua @@ -1,40 +1,97 @@ -local function printToNumber(e, base) - local castedInput = tonumber(e) - - if base then - castedInput = tonumber(e, base) - end - - if type(castedInput) == "nil" then - print("type: nil, cast failed") - else - print("type: " .. type(castedInput) .. " value: " .. castedInput) - end +-- 声明一个空表 +local emptyTable = {} + +-- 预先填充数据以直接初始化表, 其中每项元素使用 , 进行分隔 +-- 连续索引的表 +local fruitTable = {"apple", "orange", "strawberry"} + +-- 连续索引, 即数组类型的表其索引从 1 开始而不是 0 +-- 索引越界会返回 nil +print(fruitTable[1]) -- 输出 apple +print(fruitTable[0]) -- 输出 nil +print(fruitTable[4]) -- 输出 nil + +--------------------------------------------------------------------------------------------- + +local function someFunc() + return "hi there" end -printToNumber("123") -- 输出 type: number value: 123 -printToNumber("123.45") -- 输出 type: number value: 123.45 -printToNumber("-123") -- 输出 type: number value: -123 -printToNumber("0") -- 输出 type: number value: 0 +local function noReturnValue() end + +-- 非连续索引的表可以有任意类型和不连续的键 +local mixedTable = { + [1] = nil, -- number 作为索引, nil 作为值 + ["count"] = 202, -- string 作为索引, number 作为值 + result = true, -- string 作为索引时可以省略 [""], boolean 作为值 + [true] = "a boolean value", -- boolean 作为索引, string 作为值 + sayHi = someFunc(), -- string 作为索引, function 作为值 + [someFunc()] = "use function as index" -- function 作为索引, string 作为值 + +-- 不能使用没有返回值的函数作为索引, 访问时会报错 table index is nil +-- 没有返回值的函数会返回 nil, nil 不能作为表的索引 +-- [noReturnValue()] = "error" +} + +-- 表内也可以嵌套表 +local nestedTable = { + [fruitTable] = "some fruit", -- table 作为索引, string 作为值 + inner = { -- string 作为索引, table 作为值 + innerIndex = "innerValue" + } +} + +-- 通过 [] 访问索引对应的值 +print(mixedTable[1]) -- 输出 nil +print(mixedTable["count"]) -- 输出 202 +print(mixedTable.result) -- 输出 true, string 作为索引可以通过 . 访问其对应的值 +print(mixedTable[true]) -- 输出 a boolean value + +-- 函数作为索引时会使用其返回值作为索引, 有多个返回值则使用第一个返回值作为索引 +-- 也可以直接通过函数名访问对应的值 +print(mixedTable["hi there"]) -- 输出 use function as index +print(mixedTable[someFunc()]) -- 输出 use function as index + +-- 函数作为值时访问会返回其返回值 +print(mixedTable.sayHi) -- 输出 hi there + +print(nestedTable[fruitTable]) -- 输出 some fruit +print(nestedTable.inner.innerIndex) -- 输出 innerValue + +-- 访问不存在的索引会返回 nil +print(nestedTable.notExistIndex) -- 输出 nil + +local someTable = {} + +-- 动态添加元素 +someTable.player = "Madeline" +someTable[2] = "second element" +someTable.square = function(x) return x ^ 2 end -printToNumber("FF", 16) -- 输出 type: number value: 255 -printToNumber("1010", 2) -- 输出 type: number value: 10 -printToNumber("1010", 3) -- 输出 type: number value: 30 -printToNumber("3", 2) -- 输出 type: nil, cast failed +--[[ +添加完成后的表会是 +someTable = { + player = "Madeline", + [2] = "second element", + square = function(x) return x ^ 2 end +} +--]] -printToNumber("abc") -- 输出 type: nil, cast failed -printToNumber("") -- 输出 type: nil, cast failed -printToNumber(true) -- 输出 type: nil, cast failed -printToNumber(nil) -- 输出 type: nil, cast failed +print(someTable.player) -- 输出 Madeline +print(someTable[2]) -- 输出 second element +print(someTable.square(5)) -- 输出 25.0 -print(tostring(123)) -- 输出 123 -print(tostring(123.45)) -- 输出 123.45 -print(tostring(-123)) -- 输出 -123 -print(tostring(0)) -- 输出 0 +-- 向索引赋值 nil 即可删除键值对 +someTable.player = nil +someTable[2] = nil -print(tostring(nil)) -- 输出 nil -print(tostring(true)) -- 输出 true -print(tostring(false)) -- 输出 false +--[[ +删除完成后的表会是 +someTable = { + square = function(x) return x ^ 2 end +} +--]] -print(tostring(function() end)) -- 输出 function: 000002B0EBF58730, 内存地址可能不同 -print(tostring({"some stuff"})) -- 输出 table: 000002B0EBF563C0, 内存地址可能不同 +print(someTable.player) -- 输出 nil +print(someTable[2]) -- 输出 nil +print(someTable.square(5)) -- 输出 25.0 \ No newline at end of file diff --git a/docs/extra/lua/control_flow.md b/docs/extra/lua/control_flow.md index fc97d27..89900ed 100644 --- a/docs/extra/lua/control_flow.md +++ b/docs/extra/lua/control_flow.md @@ -1 +1,129 @@ -# Lua 流程控制 \ No newline at end of file +# Lua 流程控制 + +## 条件判断 + +与其他编程语言相同, `Lua` 提供 `if` 语句以实现条件判断. + +### if + +`if` 语句用于执行条件判断, 其语法结构如下: +```lua +if condition then + statement +end +``` + +`condition` 是需要判断的表达式, `if` 语句会根据其真假值以决定是否执行 `statement` 中的代码. +如果 `condition` 为真, 则执行 `statement` 代码块, 如果为假, 则跳过该部分代码块. + +!!!info + 表达式可使用逻辑运算符进行连接, 参考 [Lua - 运算符](operator.md). + +例如: +```lua +local num = 10 + +-- 判断 num 是否大于5 +if num > 5 then + print("num is greater than 5!") -- 输出 num is greater than 5! +end +``` + +### elseif + +`elseif` 是 `if` 语句的可选语句, 用于执行多个条件的判断. 其语法结构如下: +```lua +if condition1 then + statement1 +elseif condition2 then + statement2 +... +elseif conditionN then + statementN +end +``` + +`elseif` 后面可以跟任意多个 `condition` 表达式, `condition` 为真时会执行对应的 `statement` 代码块. +如果 `condition` 为假, 则依次检查后续的 `elseif`, 直到找到为真且匹配的表达式. + +例如: +```lua +local num = 50 + +-- 判断 num 是否小于/等于/大于 50 +if num < 50 then + print("num is less than 50") +elseif num == 50 then + print("num is eqaul to 50") -- 输出 num is eqaul to 50 +elseif num > 50 then + "num is greater than 50" +end +``` + +### else + +`else` 是 `if` 语句的可选语句, 用于表达式为假时执行的默认代码块. 其语法结构如下: +```lua +if condition then + statement +else + defaultStatement +end +``` + +如果 `condition` 为假, 则执行 `else` 后的 `defaultStatement` 代码块. + +例如: +```lua +local isRaining = false + +-- 判断 isRaining 是否为真 +if isRaining then + print("take umbrella") +else + -- 上面的表达式为假, 执行 else 语句块 + print("no need umbrella") -- 输出 no need umbrella +end +``` + +`else` 可以与 `elseif` 一起使用, `else` 会在所有条件都为假时执行. + +例如: +```lua +local num = 30 + +-- 判断 num 是否大于等于 50 +if num > 20 then + print("num is greater than 30") +elseif num == 30 then + print("num is equal to 30") +else + -- 上面的表达式都为假, 执行 else 语句块 + print("num is less than 30") -- 输出 num is less than 30 +end +``` + +### 嵌套 if 语句 + +`if` 语句可以嵌套使用以实现更复杂的逻辑判断. + +例如: +```lua +local num = 10 + +-- 判断 num 是否大于 5 +if num > 5 then + -- 判断 num 是否小于 15 + if num < 15 then + print("num is between 5 and 15") -- 输出 num is between 5 and 15 + end +end +``` + +## 循环 + +### for + +### while + +### repeat ... until \ No newline at end of file diff --git a/docs/extra/lua/data_type.md b/docs/extra/lua/data_type.md index e011abf..3746b0c 100644 --- a/docs/extra/lua/data_type.md +++ b/docs/extra/lua/data_type.md @@ -380,7 +380,7 @@ local function calculate(a, b) local add = a + b local sub = a - b local mul = a * b - return sum, sub, mul + return add, sub, mul end local addResult, subResult, mulResult = calculate(20, 5) diff --git a/docs/misc/change_log.md b/docs/misc/change_log.md index 1363ea5..9dff0a8 100644 --- a/docs/misc/change_log.md +++ b/docs/misc/change_log.md @@ -39,4 +39,5 @@ ### 2025.2.7 * 更新项目模板 -* 编写 [额外 - Lua](../extra/lua/begin.md) \ No newline at end of file +* 编写 [额外 - Lua](../extra/lua/begin.md) + diff --git a/docs/misc/to_do_list.md b/docs/misc/to_do_list.md index a477102..b606466 100644 --- a/docs/misc/to_do_list.md +++ b/docs/misc/to_do_list.md @@ -7,7 +7,7 @@ 这里列出了自己的一些代办事项, 以优先级进行排序. 如果有什么想法或建议可以 QQ 私聊我(可以在二群 962344157 或是 coder 群 550358997 找到我) 唔 似乎直接把自己的 QQ 534310154 发出来更合适, 虽然还是不太敢就是了(草 -草草 计划似乎排的有点多了(??? 总之就是 写不完了啦qwq +计划似乎排的有点多了(??? 总之就是 写不完了啦(草草 ## ToDoList From 564247ba842840edca997ffa6a922a3c50a02614 Mon Sep 17 00:00:00 2001 From: ClearZer0 <534310154@qq.com> Date: Fri, 7 Feb 2025 18:14:12 +0800 Subject: [PATCH 19/26] =?UTF-8?q?Lua=E9=80=9F=E9=80=9Apart3(=3F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/extra/lua/Sample.lua | 122 +++++++-------------------- docs/extra/lua/control_flow.md | 149 ++++++++++++++++++++++++++++++--- docs/misc/change_log.md | 2 +- docs/misc/to_do_list.md | 4 +- 4 files changed, 168 insertions(+), 109 deletions(-) diff --git a/docs/extra/lua/Sample.lua b/docs/extra/lua/Sample.lua index 0d6d01a..fc644c0 100644 --- a/docs/extra/lua/Sample.lua +++ b/docs/extra/lua/Sample.lua @@ -1,97 +1,33 @@ --- 声明一个空表 -local emptyTable = {} - --- 预先填充数据以直接初始化表, 其中每项元素使用 , 进行分隔 --- 连续索引的表 -local fruitTable = {"apple", "orange", "strawberry"} - --- 连续索引, 即数组类型的表其索引从 1 开始而不是 0 --- 索引越界会返回 nil -print(fruitTable[1]) -- 输出 apple -print(fruitTable[0]) -- 输出 nil -print(fruitTable[4]) -- 输出 nil - ---------------------------------------------------------------------------------------------- - -local function someFunc() - return "hi there" +-- if 嵌套 if +-- 判断 5 < num < 15 +local num = 10 +if num > 5 then + if num < 15 then + print("num is between 5 and 15") -- 输出 num is between 5 and 15 + end end -local function noReturnValue() end - --- 非连续索引的表可以有任意类型和不连续的键 -local mixedTable = { - [1] = nil, -- number 作为索引, nil 作为值 - ["count"] = 202, -- string 作为索引, number 作为值 - result = true, -- string 作为索引时可以省略 [""], boolean 作为值 - [true] = "a boolean value", -- boolean 作为索引, string 作为值 - sayHi = someFunc(), -- string 作为索引, function 作为值 - [someFunc()] = "use function as index" -- function 作为索引, string 作为值 - --- 不能使用没有返回值的函数作为索引, 访问时会报错 table index is nil --- 没有返回值的函数会返回 nil, nil 不能作为表的索引 --- [noReturnValue()] = "error" -} - --- 表内也可以嵌套表 -local nestedTable = { - [fruitTable] = "some fruit", -- table 作为索引, string 作为值 - inner = { -- string 作为索引, table 作为值 - innerIndex = "innerValue" - } -} - --- 通过 [] 访问索引对应的值 -print(mixedTable[1]) -- 输出 nil -print(mixedTable["count"]) -- 输出 202 -print(mixedTable.result) -- 输出 true, string 作为索引可以通过 . 访问其对应的值 -print(mixedTable[true]) -- 输出 a boolean value - --- 函数作为索引时会使用其返回值作为索引, 有多个返回值则使用第一个返回值作为索引 --- 也可以直接通过函数名访问对应的值 -print(mixedTable["hi there"]) -- 输出 use function as index -print(mixedTable[someFunc()]) -- 输出 use function as index - --- 函数作为值时访问会返回其返回值 -print(mixedTable.sayHi) -- 输出 hi there - -print(nestedTable[fruitTable]) -- 输出 some fruit -print(nestedTable.inner.innerIndex) -- 输出 innerValue - --- 访问不存在的索引会返回 nil -print(nestedTable.notExistIndex) -- 输出 nil - -local someTable = {} - --- 动态添加元素 -someTable.player = "Madeline" -someTable[2] = "second element" -someTable.square = function(x) return x ^ 2 end - ---[[ -添加完成后的表会是 -someTable = { - player = "Madeline", - [2] = "second element", - square = function(x) return x ^ 2 end -} ---]] - -print(someTable.player) -- 输出 Madeline -print(someTable[2]) -- 输出 second element -print(someTable.square(5)) -- 输出 25.0 - --- 向索引赋值 nil 即可删除键值对 -someTable.player = nil -someTable[2] = nil +-- for 嵌套 for +-- 输出 3 x 3 矩阵坐标 +for x = 1, 3 do + for y = 1, 3 do + print(x .. "," .. y) -- 输出 1,1 1,2 ... 3,2 3,3 + end +end ---[[ -删除完成后的表会是 -someTable = { - square = function(x) return x ^ 2 end -} ---]] +-- if 嵌套 for +-- 如果 num2 小于 10, 输出 num2 到 10 的所有整数 +local num2 = 5 +if num2 < 10 then + for i = num2, 10 do + print(i) -- 输出 5, 6, 7, 8, 9, 10 + end +end -print(someTable.player) -- 输出 nil -print(someTable[2]) -- 输出 nil -print(someTable.square(5)) -- 输出 25.0 \ No newline at end of file +-- for 嵌套 if +-- 输出偶数 +for i = 1, 5 do + if i % 2 == 0 then + print(i) -- 输出 2, 4 + end +end \ No newline at end of file diff --git a/docs/extra/lua/control_flow.md b/docs/extra/lua/control_flow.md index 89900ed..550891d 100644 --- a/docs/extra/lua/control_flow.md +++ b/docs/extra/lua/control_flow.md @@ -13,7 +13,7 @@ if condition then end ``` -`condition` 是需要判断的表达式, `if` 语句会根据其真假值以决定是否执行 `statement` 中的代码. +`condition` 是需要判断的表达式, `if` 语句会根据其真假值以决定是否执行 `statement` 代码块. 如果 `condition` 为真, 则执行 `statement` 代码块, 如果为假, 则跳过该部分代码块. !!!info @@ -103,27 +103,152 @@ else end ``` -### 嵌套 if 语句 +## 循环 + +`Lua` 提供以下三种循环语句, 分别用于在特定情况下重复执行代码块中的内容. + +### for + +`Lua` 支持两种 `for` 循环: 数值型 `for` 循环以及泛型 `for` 循环. + +!!!info + 这里仅介绍数值型 `for` 循环, 泛型 `for` 循环请阅读 [Lua 迭代器](iterator.md). + +数值型 `for` 循环的语法结构如下: +```lua +for var = start, stop, step do + statement +end +``` + +- `var`: 循环变量, 自动声明为局部变量. 其值在每次循环时自动更新. +- `start`: 循环变量的起始值. +- `stop`: 循环变量的结束值. +- `step`: 可选部分, 步长, 每次循环时循环变量的增量, 默认为 1. +- `statement`: 循环语句中需要反复执行的代码块. + +循环开始时`var` 会被设定为起始值 `start`, 每次循环都会执行 `statement` 中的代码. +每次循环结束时会更新 `var` 的值, 即 `var = var + step`. 当满足以下条件时循环结束: -`if` 语句可以嵌套使用以实现更复杂的逻辑判断. +- `step` 为正, 则 `var` 大于结束值 `stop` 时结束循环. +- `step` 为负, 则 `var` 小于结束值 `stop` 时结束循环. 例如: ```lua -local num = 10 +-- 从 1 循环到 5, 步长为 1 +for i = 1, 5 do + print(i) -- 依次输出 1, 2, 3, 4, 5 +end + +-- 从 10 循环到 1, 步长为 -2 +for i = 10, 1, -2 do + print(i) -- 依次输出 10, 8, 6, 4, 2 +end +``` + +### while + +`while` 循环在给定表达式为真时重复执行代码块. 其语法结构如下: +```lua +while condition do + statment +end +``` + +`while` 循环会反复执行, 直到 `condition` 表达式的值为假. +如果 `condition` 表达式在某次循环后为假,则循环结束. + +!!!info + `while` 循环在开始时会先检查 `condition` 的值, 如果为假则不执行循环. + +例如: +```lua +local num = 0 + +-- 当 num 小于 5 时,持续执行循环 +while num < 5 do + print(num) -- 输出 0, 1, 2, 3, 4 + num = num + 1 -- 更新 num 的值以避免死循环 +end +``` + +### repeat ... until --- 判断 num 是否大于 5 +`repeat ... until` 循环与 `while` 循环类似, 用于在条件满足时重复执行代码块. 其语法结构如下: +```lua +repeat + statements +until condition +``` + +`repeat ... until` 循环的结束条件与 `while` 循环相同. +不同的是其会先执行一次 `statement` 中的代码再判断 `condition` 表达式, 因此其至少会执行一次循环. + +例如: +```lua +local num = 0 + +-- 当 num 小于等于 5 时,持续执行循环 +repeat + print(num) -- 输出 0, 1, 2, 3, 4, 5 + num = num + 1 -- 更新 num 的值以避免死循环 +until num > 5 +``` + +### break + +`break` 语句用于跳出循环. 循环体中的代码执行 `break` 会立刻退出当前循环并执行循环语句之后的代码. + +例如: +```lua +-- 从 1 循环到 10, 步长为 1 +for i = 1, 10 do + if i == 5 then + break -- 当 i 等于 5 时跳出循环 + end + print(i) -- 输出 1 2 3 4 +end +``` + +对于多层嵌套循环, `break` 只能跳出当前正在进行的循环语句, 并不能直接跳出外层循环. + +## 嵌套语句 + +流程控制语句也可以嵌套使用以实现更为复杂的逻辑. + +例如: +```lua +-- if 嵌套 if +-- 判断 5 < num < 15 +local num = 10 if num > 5 then - -- 判断 num 是否小于 15 if num < 15 then print("num is between 5 and 15") -- 输出 num is between 5 and 15 end end -``` - -## 循环 -### for +-- for 嵌套 for +-- 输出 3 x 3 矩阵坐标 +for x = 1, 3 do + for y = 1, 3 do + print(x .. "," .. y) -- 输出 1,1 1,2 ... 3,2 3,3 + end +end -### while +-- if 嵌套 for +-- 如果 num2 小于 10, 输出 num2 到 10 的所有整数 +local num2 = 5 +if num2 > 10 then + for i = num2, 10 do + print(i) -- 输出 5, 6, 7, 8, 9, 10 + end +end -### repeat ... until \ No newline at end of file +-- for 嵌套 if +-- 输出偶数 +for i = 1, 5 do + if i % 2 == 0 then + print(i) -- 输出 2, 4 + end +end +``` \ No newline at end of file diff --git a/docs/misc/change_log.md b/docs/misc/change_log.md index 9dff0a8..c39e019 100644 --- a/docs/misc/change_log.md +++ b/docs/misc/change_log.md @@ -32,7 +32,7 @@ * 归档 [一些准备 - 偏好](../arc/preference.md) * 重构 [一些准备 - 调试](../coding_setup/debug.md) * 完善 [进阶 - 跨 Mod 交互 - #ModInterop](../advanced/cross_mod_interactions.md) -* 移动 [额外 - CMCC](../extra/cmcc/index.md), [额外 - LuaCutscene](../extra/lua_cutscene/begin.md) 以及[其他 - XML 简单介绍](../extra/xml/xml_speedrun.md) 至额外章节以优化排版 +* 移动 [额外 - CMCC](../extra/cmcc/index.md), [额外 - LuaCutscene](../extra/lua_cutscene/begin.md) 以及 [其他 - XML 简单介绍](../extra/xml/xml_speedrun.md) 至额外章节以优化排版 ### 2025.1.28 * 添加插件以显示页面的创建与最后修改时间 以及文档编写者 diff --git a/docs/misc/to_do_list.md b/docs/misc/to_do_list.md index b606466..01ac6b4 100644 --- a/docs/misc/to_do_list.md +++ b/docs/misc/to_do_list.md @@ -19,10 +19,8 @@ | 编写 碰撞检测 | 计划中 | | 编写 输入获取 | 计划中 | | 编写 资产管理 | 计划中 | -| 编写 Everest 自带事件 | 计划中 | -| 分离已有的组件进行重写 | 计划中 | | 重构 Hook 节 | 计划中 | -| 分离 DynamicData 相关 | 计划中 | +| 编写 Everest 自带事件 | 计划中 | | 编写 Effect 相关 | 计划中 | From 03e287727606560f9ff3be9624c55194af20ab43 Mon Sep 17 00:00:00 2001 From: ClearZer0 <534310154@qq.com> Date: Tue, 11 Feb 2025 02:59:22 +0800 Subject: [PATCH 20/26] =?UTF-8?q?Lua=E9=80=9F=E9=80=9Apart4...=3F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/extra/lua/Sample.lua | 35 +---- docs/extra/lua/begin.md | 5 + docs/extra/lua/control_flow.md | 2 +- docs/extra/lua/data_type.md | 40 +---- docs/extra/lua/operator.md | 265 ++++++++++++++++++++++++++++++++- 5 files changed, 276 insertions(+), 71 deletions(-) diff --git a/docs/extra/lua/Sample.lua b/docs/extra/lua/Sample.lua index fc644c0..30566dd 100644 --- a/docs/extra/lua/Sample.lua +++ b/docs/extra/lua/Sample.lua @@ -1,33 +1,6 @@ --- if 嵌套 if --- 判断 5 < num < 15 -local num = 10 -if num > 5 then - if num < 15 then - print("num is between 5 and 15") -- 输出 num is between 5 and 15 - end +local function divide(a, b) + return b ~= 0 and a/b or error("division by zero") end --- for 嵌套 for --- 输出 3 x 3 矩阵坐标 -for x = 1, 3 do - for y = 1, 3 do - print(x .. "," .. y) -- 输出 1,1 1,2 ... 3,2 3,3 - end -end - --- if 嵌套 for --- 如果 num2 小于 10, 输出 num2 到 10 的所有整数 -local num2 = 5 -if num2 < 10 then - for i = num2, 10 do - print(i) -- 输出 5, 6, 7, 8, 9, 10 - end -end - --- for 嵌套 if --- 输出偶数 -for i = 1, 5 do - if i % 2 == 0 then - print(i) -- 输出 2, 4 - end -end \ No newline at end of file +print(divide(10, 2)) -- 输出 5 +print(divide(10, 0)) -- 输出 "division by zero" \ No newline at end of file diff --git a/docs/extra/lua/begin.md b/docs/extra/lua/begin.md index 78dab78..d98a26c 100644 --- a/docs/extra/lua/begin.md +++ b/docs/extra/lua/begin.md @@ -6,6 +6,11 @@ 这个额外章节将会介绍如何速通 Lua 一些编写 `Loenn` 侧自定义实体的加载脚本所必需的 `Lua` 知识. +!!!info + 本教程的内容基于 `LuaJIT 2.1`, 即 `Loenn` 底层引擎 `LOVE2D` 所使用的 `Lua` 版本. + 因此, 高版本与 `Loenn` 开发中不涉及的特性在此教程不会提及. + 如果对高版本 `Lua` 感兴趣可以阅读[官方文档](https://www.lua.org/manual/5.4). + ## 开发环境 ### Lua 安装 diff --git a/docs/extra/lua/control_flow.md b/docs/extra/lua/control_flow.md index 550891d..4708d38 100644 --- a/docs/extra/lua/control_flow.md +++ b/docs/extra/lua/control_flow.md @@ -158,7 +158,7 @@ end `while` 循环会反复执行, 直到 `condition` 表达式的值为假. 如果 `condition` 表达式在某次循环后为假,则循环结束. -!!!info +!!!note `while` 循环在开始时会先检查 `condition` 的值, 如果为假则不执行循环. 例如: diff --git a/docs/extra/lua/data_type.md b/docs/extra/lua/data_type.md index 3746b0c..b1d0369 100644 --- a/docs/extra/lua/data_type.md +++ b/docs/extra/lua/data_type.md @@ -46,13 +46,6 @@ end print(type(add)) -- 输出 function ``` -对于类型比较, `type()` 函数返回的是一个 `string` 类型. -正确的比较方式是将 `type()` 的返回值与字符串进行比较, 并且需要使用 `""` 引用类型字符串: -```lua -print(type(nil) == nil) -- 输出 false, type(nil) 返回的是 "nil", "nil" 不等于 nil -print(type(nil) == "nil") -- 输出 true, type(nil) 返回的是 "nil", "nil" 等于 "nil" -``` - ### nil `nil` 是一种特殊的类型, 只包含一个值 `nil`. 所有未初始化的变量都被视为 `nil`, 把变量赋值为 `nil` 即可删除这个变量: @@ -156,18 +149,6 @@ print("a line\nnew line") -- 输出 a line -- new line ``` -需要连接字符串使用 `..` 运算符, 需要计算字符串的长度使用 `#` 运算符: -```lua -local str1 = "speed" -local str2 = "run" - -print(str1 .. str2) -- 输出 speedrun -print(str1 .. " " .. str2) -- 输出 speed run - -print(#str1) -- 输出 5 -print(#str2) -- 输出 3 -``` - `string` 类型是不可变的, 所有修改字符串的操作本质上都是生成并返回修改后的字符串: ```lua local str1 = "hi there" @@ -217,14 +198,14 @@ end -- 空字符串 "" 被认为是真 if "" then - print("\"\" is true") -- 输出 "" is true + print("\"\" is true") -- 输出 "" is true else print("\"\" is false") end -- 空表 {} 被认为是真 if {} then - print("{} is true") -- 输出 {} is true + print("{} is true") -- 输出 {} is true else print("{} is false") end @@ -270,7 +251,7 @@ local mixedTable = { sayHi = someFunc(), -- string 作为索引, function 作为值 [someFunc()] = "use function as index" -- function 作为索引, string 作为值 --- 不能使用没有返回值的函数作为索引, 访问时会报错 table index is nil +-- 不能使用没有返回值的函数作为索引, 访问时会报错 "table index is nil" -- 没有返回值的函数会返回 nil, nil 不能作为表的索引 -- [noReturnValue()] = "error" } @@ -342,21 +323,6 @@ print(someTable[2]) -- 输出 nil print(someTable.square(5)) -- 输出 25.0 ``` -`Lua` 中的 `table` 是引用类型, 直接使用 `=` 操作符赋值并不会复制表, 而是创建对原表的引用. -直接比较两个表时,会比较它们的引用地址而不是表的内容. 在比较两个表是否相等时可能导致预期外的结果: -```lua -local emptyTable = {} -print(emptyTable == {}) -- 输出 false - -local table1 = {1, 2, 3} -local table2 = {1, 2, 3} -local table3 = table1 -print(table1 == table2) -- 输出 false -print(table1 == table3) -- 输出 true -``` - -`Lua` 并没有内建实现表的比较与复制的函数. 需要额外实现. - ### function `Lua` 中的函数使用 `function` 关键字声明.以 `end` 关键字结束. 函数的结构如下: diff --git a/docs/extra/lua/operator.md b/docs/extra/lua/operator.md index 98630a1..e941534 100644 --- a/docs/extra/lua/operator.md +++ b/docs/extra/lua/operator.md @@ -1,6 +1,6 @@ # Lua 运算符 -运算符是一种特殊的符号, 用于告诉解释器执行特定的数学或逻辑运算. `Lua` 提供以下运算符类型: +运算符是一种特殊的符号, 用于让解释器执行特定的数学或逻辑运算. `Lua` 提供以下运算符类型: - 算数运算符: 执行数学运算 - 关系运算符: 执行比较运算 @@ -9,10 +9,271 @@ ## 算术运算符 +算术运算符用于执行数学运算, `Lua` 支持以下算数运算符: + +- `+`: 加法, 用于两个数值的相加 +- `-`: 减法, 用于两个数值的相减 +- `*`: 乘法, 用于两个数值的相乘 +- `/`: 除法, 用于两个数值的相除, 返回浮点数 +- `^`: 乘方, 即幂运算, 返回浮点数 +- `%`: 取模, 用于计算除法的余数 +- `-`: 取相反数, 用于返回数值的相反数 + +例如: +```lua +-- 加减乘除 +local a = 20 +local b = 10 + +print(a + b) -- 输出 30 +print(a - b) -- 输出 10 +print(a * b) -- 输出 200 +print(a / b) -- 输出 2.0 + +-- 乘方 取模 +local x = 7 +local y = 3 + +print(x ^ y) -- 输出 343.0 +print(x % y) -- 输出 1 + +-- 取相反数 +local i = 25 +local j = -30 + +print(-i) -- 输出 -25 +print(-j) -- 输出 30 +``` + ## 关系运算符 +关系运算符用于比较两个值,返回 `true` 或 `false`. `Lua` 支持以下关系运算符: + +- `==`: 等于 +- `~=`: 不等于 +- `<`: 小于 +- `<=`: 小于等于 +- `>`: 大于 +- `>=`: 大于等于 + +对于数值比较, `Lua` 会进行标准的数学比较: +```lua +print(1 == 1) -- 输出 true +print(2 ~= 3) -- 输出 true +print(2 < 3) -- 输出 true +print(2 <= 2) -- 输出 true +print(3 > 2) -- 输出 true +print(3 >= 3) -- 输出 true +``` + +对于字符串比较, `Lua` 会使用字典序进行比较, 即按字符的 `Unicode` 编码顺序进行大小比较: +```lua +print("apple" == "apple") -- 输出 true +print("apple" == "Apple") -- 输出 false + +print("apple" < "apples") -- 输出 true +print("apple" > "apples") -- 输出 false + +print("apple" < "banana") -- 输出 true +print("apple" > "banana") -- 输出 false +``` + +对于表的比较,`Lua` 中的 `table` 是引用类型, 直接使用 `=` 操作符赋值并不会复制表, 而是创建对原表的引用. +直接比较两个表时,会比较它们的引用地址而不是表的内容. 在比较两个表是否相等时可能导致预期外的结果: +```lua +local emptyTable = {} +print(emptyTable == {}) -- 输出 false + +local table1 = {1, 2, 3} +local table2 = {1, 2, 3} +local table3 = table1 +print(table1 == table2) -- 输出 false +print(table1 == table3) -- 输出 true + +-- table 是引用类型, 只能进行相等比较, 进行大小比较会报错 "attempt to compare two table values" +-- print(table1 < table3) +``` + +!!!info + `Lua` 并没有内建实现表的比较与复制的函数. 需要额外实现. + +对于类型比较, `type()` 函数返回的是 `string` 类型. +正确的比较方式是将 `type()` 的返回值与字符串进行比较, 并且需要使用 `""` 引用类型字符串: +```lua +print(type(nil) == nil) -- 输出 false, type(nil) 返回的是 "nil", "nil" 不等于 nil +print(type(nil) == "nil") -- 输出 true, type(nil) 返回的是 "nil", "nil" 等于 "nil" +``` + ## 逻辑运算符 +逻辑运算符用于条件判断, `Lua` 支持以下逻辑运算符: + +- `not`: 逻辑非 +- `and`: 逻辑与 +- `or`: 逻辑或 + +操作数可以是任何类型与表达式. + +对于 `not`, 将其操作数取反, `true` 输出 `false`. `false` 或 `nil` 输出 `true`: +```lua +print(not true) -- 输出 false +print(not false) -- 输出 true +print(not nil) -- 输出 true + +print(not "um") -- 输出 false +print(not 123) -- 输出 false + +print(not (5 < 2)) -- 输出 true, 5 < 2 为 false, not 取反为 true +print(not ("str1" ~= "str2")) -- 输出 false, "str1" ~= "str2" 为 true, not 取反为 false +``` + +对于 `and`, 若第一个操作数为假, 返回第一个操作数, 否则返回第二个操作数: +```lua +print(false and false) -- 输出 false +print(true and false) -- 输出 false +print(false and true) -- 输出 false +print(true and true) -- 输出 true + +print(0 and 1) -- 输出 1 +print("hi" and "there") -- 输出 there +print(nil and "stuff") -- 输出 nil + +print(1 and 2 and 3) -- 输出 3 +print(1 and nil and 3) -- 输出 nil +print(1 and false and 3) -- 输出 false +``` + +对于 `or`, 若第一个操作数为真, 返回第一个操作数, 否则返回第二个操作数: +```lua +print(false or false) -- 输出 false +print(true or false) -- 输出 true +print(false or true) -- 输出 true +print(true or true) -- 输出 true + +print(0 or 1) -- 输出 0 +print("hi" or "there") -- 输出 hi +print(nil or "stuff") -- 输出 stuff + +print(1 or 2 or 3) -- 输出 1 +print(1 or nil or 3) -- 输出 1 +print(1 or false or 3) -- 输出 1 +``` + +???note "Lua 模拟三元运算符" + `and` 与 `or` 都使用短路运算, 如果返回第一个操作数则不会计算第二个操作数的值. 因此可以模拟 `C#` 中的三元运算符: + ```lua + result = condition and "trueValue" or "falseValue" + ``` + + 其对应的 `C#` 代码如下: + ```cs + result = condition ? "trueValue" : "falseValue"; + ``` + + 需要注意的是, 在 `condition` 为真并且 `trueValue` 为假的情况下会输出预期外的 `falseValue`. + 因此在 `Lua` 中模拟三元运算符时应确保 `trueValue` 的值不为假, 或是添加额外的条件判断: + ```lua + result = condition and "trueValue" or (condition == false and "falseValue" or "fallback") + ``` + + 下面是一个示例: + ```lua + local function safeDivide(a, b) + return b ~= 0 and a/b or error("Attempted to divide by zero.") + end + + print(safeDivide(10, 2)) -- 输出 5.0 + print(safeDivide(10, 0)) -- 报错 "Attempted to divide by zero." + ``` + + 其对应的 `C#` 代码如下: + ```cs + double safeDivide(double a, double b) + { + return b != 0 ? a/b : throw new DivideByZeroException(); + } + + Console.WriteLine(safeDivide(10, 2)); // 输出 5 + Console.WriteLine(safeDivide(10, 0)); // 报错 "Attempted to divide by zero." + ``` + ## 其他运算符 -## 运算符优先级 \ No newline at end of file +`#` 长度运算符用于计算字符串或表的长度: +```lua +-- 计算字符串长度 +local tas = "Tool-Assisted Speedrun" + +print(#"") -- 输出 0 +print(#"Celeste") -- 输出 7 +print(#tas) -- 输出 22 + +-- 计算表长度 +local emptyTable = {} +local letters = {"a", "b", "c"} + +print(#{}) -- 输出 0 +print(#letters) -- 输出 3 +``` +对于非连续索引类型的表, 即字典类型以及包含 `nil` 的连续索引的表, 即数组类型, +`#` 的输出可能不准确: +```lua +-- 包含 nil 的连续索引类型的表 +local letters = {"a", "b", "c", nil} +print(#letters) -- 输出 3, 实际应该是 4. # 在遇到 nil 时会停止计数 + +-- 非连续索引的表 +local colors = { + white = "FFFFFF", + black = "000000" +} +print(#colors) -- 输出 0, 实际应该是 2 +``` + +`..` 连接运算符用于连接多个字符串: +```lua +print("Hello" .. " " .. "World") -- 输出 Hello World + +local str1 = "speed" +local str2 = "run" + +print(str1 .. str2) -- 输出 speedrun +print(str1 .. " " .. str2) -- 输出 speed run + +-- 数字会被转换为字符串 +print(1 .. 2) -- 输出 12 +print("Number: " .. 123) -- 输出 Number: 123 +``` + +## 运算符优先级 + +运算符优先级如下: + +| 优先级组 | 运算符 | +|-------------------------|--------------------------------| +| 最高 | `^` | +| | `not` `#` `-` (取相反数) | +| | `*` `/` `%` | +| | `+` `-` (减法) | +| | `..` | +| | `<` `>` `<=` `>=` `~=` `==` | +| | `and` | +| 最低 | `or` | + +除 `^`和 `..` 外所有的二元运算符都是左连接的: +```lua +a + i < b / 2 + 1 -- (a + i) < ((b / 2)+1) +5 + x ^ 2 * 8 -- 5 + ((x ^ 2) * 8) +a < y and y <= z -- (a < y) and (y <= z) +-x ^ 2 -- -(x ^ 2) +x ^ y ^ z -- x ^ (y ^ z) +``` + +可以使用 `()` 改变运算优先级: +```lua +print(2 + 3 * 4) -- 输出 14 +print((2 + 3) * 4) -- 输出 20 + +print(not false and true) -- 输出 true +print(not (false and true)) -- 输出 true +``` \ No newline at end of file From 08547a1d572198b94e5014723c85a6abefa533f2 Mon Sep 17 00:00:00 2001 From: ClearZer0 <534310154@qq.com> Date: Tue, 11 Feb 2025 23:16:36 +0800 Subject: [PATCH 21/26] requested --- docs/extra/lua/operator.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/extra/lua/operator.md b/docs/extra/lua/operator.md index e941534..a896728 100644 --- a/docs/extra/lua/operator.md +++ b/docs/extra/lua/operator.md @@ -162,18 +162,18 @@ print(1 or false or 3) -- 输出 1 ???note "Lua 模拟三元运算符" `and` 与 `or` 都使用短路运算, 如果返回第一个操作数则不会计算第二个操作数的值. 因此可以模拟 `C#` 中的三元运算符: ```lua - result = condition and "trueValue" or "falseValue" + result = condition and trueValue or falseValue ``` 其对应的 `C#` 代码如下: ```cs - result = condition ? "trueValue" : "falseValue"; + result = condition ? trueValue : falseValue; ``` 需要注意的是, 在 `condition` 为真并且 `trueValue` 为假的情况下会输出预期外的 `falseValue`. 因此在 `Lua` 中模拟三元运算符时应确保 `trueValue` 的值不为假, 或是添加额外的条件判断: ```lua - result = condition and "trueValue" or (condition == false and "falseValue" or "fallback") + result = condition and trueValue or (condition == false and falseValue or fallback) ``` 下面是一个示例: @@ -188,13 +188,13 @@ print(1 or false or 3) -- 输出 1 其对应的 `C#` 代码如下: ```cs - double safeDivide(double a, double b) + double SafeDivide(double a, double b) { return b != 0 ? a/b : throw new DivideByZeroException(); } - Console.WriteLine(safeDivide(10, 2)); // 输出 5 - Console.WriteLine(safeDivide(10, 0)); // 报错 "Attempted to divide by zero." + Console.WriteLine(SafeDivide(10, 2)); // 输出 5 + Console.WriteLine(SafeDivide(10, 0)); // 报错 "Attempted to divide by zero." ``` ## 其他运算符 From 8bdac57923d061b9ccd76d599e3eb3de5e5845b4 Mon Sep 17 00:00:00 2001 From: ClearZer0 <534310154@qq.com> Date: Mon, 10 Mar 2025 03:18:21 +0800 Subject: [PATCH 22/26] part5 ig idk --- docs/extra/lua/Sample.lua | 17 ++- docs/extra/lua/begin.md | 2 +- docs/extra/lua/control_flow.md | 32 ++--- docs/extra/lua/exception_handling.md | 1 - docs/extra/lua/iterator.md | 206 ++++++++++++++++++++++++++- docs/extra/lua/metatable.md | 1 - docs/extra/lua/module.md | 1 + docs/extra/lua/package.md | 1 - mkdocs.yml | 4 +- 9 files changed, 236 insertions(+), 29 deletions(-) delete mode 100644 docs/extra/lua/exception_handling.md delete mode 100644 docs/extra/lua/metatable.md create mode 100644 docs/extra/lua/module.md delete mode 100644 docs/extra/lua/package.md diff --git a/docs/extra/lua/Sample.lua b/docs/extra/lua/Sample.lua index 30566dd..0be0460 100644 --- a/docs/extra/lua/Sample.lua +++ b/docs/extra/lua/Sample.lua @@ -1,6 +1,13 @@ -local function divide(a, b) - return b ~= 0 and a/b or error("division by zero") -end +local someTable = { + [1] = 1, + strawberries = 202, + result = true, + [true] = "a boolean value" +} -print(divide(10, 2)) -- 输出 5 -print(divide(10, 0)) -- 输出 "division by zero" \ No newline at end of file +-- pairs 迭代器适用于需要遍历表中所有元素的场景, 遍历顺序不确定. 其返回两个值 +-- index: 当前索引 +-- value: 当前索引对应的值 +for index, value in pairs(someTable) do + print(index, value) -- 输出 strawberries 202, true a boolean value, result true +end \ No newline at end of file diff --git a/docs/extra/lua/begin.md b/docs/extra/lua/begin.md index d98a26c..e091c9a 100644 --- a/docs/extra/lua/begin.md +++ b/docs/extra/lua/begin.md @@ -8,7 +8,7 @@ !!!info 本教程的内容基于 `LuaJIT 2.1`, 即 `Loenn` 底层引擎 `LOVE2D` 所使用的 `Lua` 版本. - 因此, 高版本与 `Loenn` 开发中不涉及的特性在此教程不会提及. + 因此, 高版本与 `Loenn` 开发中不涉及的特性(元表 异常处理等)在此教程不会提及. 如果对高版本 `Lua` 感兴趣可以阅读[官方文档](https://www.lua.org/manual/5.4). ## 开发环境 diff --git a/docs/extra/lua/control_flow.md b/docs/extra/lua/control_flow.md index 4708d38..0f3bbb8 100644 --- a/docs/extra/lua/control_flow.md +++ b/docs/extra/lua/control_flow.md @@ -9,12 +9,12 @@ `if` 语句用于执行条件判断, 其语法结构如下: ```lua if condition then - statement + statements end ``` -`condition` 是需要判断的表达式, `if` 语句会根据其真假值以决定是否执行 `statement` 代码块. -如果 `condition` 为真, 则执行 `statement` 代码块, 如果为假, 则跳过该部分代码块. +`condition` 是需要判断的表达式, `if` 语句会根据其真假值以决定是否执行 `statements` 代码块. +如果 `condition` 为真, 则执行 `statements` 代码块, 如果为假, 则跳过该部分代码块. !!!info 表达式可使用逻辑运算符进行连接, 参考 [Lua - 运算符](operator.md). @@ -34,16 +34,16 @@ end `elseif` 是 `if` 语句的可选语句, 用于执行多个条件的判断. 其语法结构如下: ```lua if condition1 then - statement1 + statements1 elseif condition2 then - statement2 + statements2 ... elseif conditionN then - statementN + statementsN end ``` -`elseif` 后面可以跟任意多个 `condition` 表达式, `condition` 为真时会执行对应的 `statement` 代码块. +`elseif` 后面可以跟任意多个 `condition` 表达式, `condition` 为真时会执行对应的 `statements` 代码块. 如果 `condition` 为假, 则依次检查后续的 `elseif`, 直到找到为真且匹配的表达式. 例如: @@ -56,7 +56,7 @@ if num < 50 then elseif num == 50 then print("num is eqaul to 50") -- 输出 num is eqaul to 50 elseif num > 50 then - "num is greater than 50" + print("num is greater than 50") end ``` @@ -65,13 +65,13 @@ end `else` 是 `if` 语句的可选语句, 用于表达式为假时执行的默认代码块. 其语法结构如下: ```lua if condition then - statement + statements else - defaultStatement + defaultStatements end ``` -如果 `condition` 为假, 则执行 `else` 后的 `defaultStatement` 代码块. +如果 `condition` 为假, 则执行 `else` 后的 `defaultStatements` 代码块. 例如: ```lua @@ -117,7 +117,7 @@ end 数值型 `for` 循环的语法结构如下: ```lua for var = start, stop, step do - statement + statements end ``` @@ -125,9 +125,9 @@ end - `start`: 循环变量的起始值. - `stop`: 循环变量的结束值. - `step`: 可选部分, 步长, 每次循环时循环变量的增量, 默认为 1. -- `statement`: 循环语句中需要反复执行的代码块. +- `statements`: 循环语句中需要反复执行的代码块. -循环开始时`var` 会被设定为起始值 `start`, 每次循环都会执行 `statement` 中的代码. +循环开始时`var` 会被设定为起始值 `start`, 每次循环都会执行 `statements` 中的代码. 每次循环结束时会更新 `var` 的值, 即 `var = var + step`. 当满足以下条件时循环结束: - `step` 为正, 则 `var` 大于结束值 `stop` 时结束循环. @@ -151,7 +151,7 @@ end `while` 循环在给定表达式为真时重复执行代码块. 其语法结构如下: ```lua while condition do - statment + statements end ``` @@ -182,7 +182,7 @@ until condition ``` `repeat ... until` 循环的结束条件与 `while` 循环相同. -不同的是其会先执行一次 `statement` 中的代码再判断 `condition` 表达式, 因此其至少会执行一次循环. +不同的是其会先执行一次 `statements` 中的代码再判断 `condition` 表达式, 因此其至少会执行一次循环. 例如: ```lua diff --git a/docs/extra/lua/exception_handling.md b/docs/extra/lua/exception_handling.md deleted file mode 100644 index cabb2b6..0000000 --- a/docs/extra/lua/exception_handling.md +++ /dev/null @@ -1 +0,0 @@ -# Lua 异常处理 \ No newline at end of file diff --git a/docs/extra/lua/iterator.md b/docs/extra/lua/iterator.md index 970aeff..e19ee61 100644 --- a/docs/extra/lua/iterator.md +++ b/docs/extra/lua/iterator.md @@ -1 +1,205 @@ -# Lua 迭代器 \ No newline at end of file +# Lua 迭代器 +迭代器是一种用于遍历集合所有元素的机制, 其可以隐藏集合的内部结构. +`Lua` 中, 迭代器是一个函数, 每次调用都会返回集合中的下一个元素, 直到遍历完所有元素. + +## 泛型 for 循环 + +泛型 `for` 是 `Lua` 中用于遍历迭代器的专用语法结构. 它通过调用迭代器函数来遍历集合中的所有元素, 直到迭代器返回 `nil`. + +`Lua` 中的迭代器分为以下两种: + +- 无状态迭代器 +- 多状态迭代器 + +### 无状态迭代器 + +无状态迭代器不保存任何状态信息, 而是依赖于外部传入的参数来维持迭代状态. +无状态迭代器与迭代器函数的通用语法格式如下: +```lua +-- 迭代器函数 +-- invariant: 状态常量, 在迭代过程中不变的值. 例如表 +-- control: 用于控制迭代进度的变量, 每次迭代都会更新. 例如当前索引 +function iteratorFunction(invariant, control) + + -- limit: 用于判断迭代是否结束的边界值, 通常是集合的大小或长度 + -- nextControl: 计算下一次迭代的控制变量, 通常是索引加1或其他递增/递减逻辑 + local limit = getLimit(invariant) + local nextControl = control + 1 + + -- 判断迭代是否结束, 返回 nil 代表迭代结束 + if nextControl > limit then + return nil + end + + -- values: 根据状态常量和控制变量计算或处理后的返回值 + local values = computeValues(invariant, nextControl) + + -- 返回值 + -- nextControl: 下一次迭代所使用的控制变量的值 + -- value1, value2, ..., valueN: 当前迭代返回给泛型 for 循环的值 + return nextControl, value1, value2, ..., valueN +end + +-- 使用无状态迭代器的泛型 for 循环 +for var1, var2, ..., varN in iteratorFunction, invariant, control do + statements +end +``` + +无状态迭代器适用于迭代逻辑简单, 规律性强的集合, 需要内存占用最小化等场景. +例如: +```lua +-- 计算从 current 到 maxRange 范围内数字的平方的函数 +-- maxRange: 范围的最大值 +-- current: 范围的起始值 +local function square(maxRange, current) + + -- 递增当前数字, 计算下一个控制变量 + current = current + 1 + + -- 判断当前数字是否超出范围 + if current > maxRange then + return nil + end + + -- 返回下一个控制变量与计算结果 + return current, current * current +end + +-- 计算从 0 到 5 内数字的平方 +for num, square in square, 5, 0 do + print(num, square) -- 输出 1 1 2 4 3 9 4 16 5 25 +end +``` + +### 多状态迭代器 + +多状态迭代器使用闭包来保存状态, 它将所有的迭代状态都封装在迭代器函数内部. +多状态迭代器与迭代器函数的通用语法格式如下: +```lua +-- 迭代器工厂函数 +-- collection: 需要遍历的集合, 可以是表, 字符串或其他数据结构 +function iteratorFactory(collection) + + -- 初始化内部状态变量 + -- control: 用于控制迭代进度的变量, 每次迭代都会更新, 例如当前索引 + -- limit: 用于判断迭代是否结束的边界值, 通常是集合的大小或长度 + local control = 0 + local limit = getLimit(collection) + + -- 闭包返回迭代器函数 + return function() + -- 计算下一次迭代的控制变量, 通常是索引加1或其他递增/递减逻辑 + control = control + 1 + + -- 判断迭代是否结束, 返回 nil 代表迭代结束 + if control > limit then + return nil + end + + -- 计算当前迭代要返回的值 + -- element: 从集合中获取的当前元素 + -- values: 对元素进行计算或处理后的返回值 + local element = collection[control] + local values = computeValues(element) + + -- 返回值 + -- value1, value2, ..., valueN: 当前迭代返回给泛型 for 循环的值 + return value1, value2, ..., valueN + end +end + +-- 使用多状态迭代器的泛型 for 循环 +for var1, var2, ..., varN in iteratorFactory(collection) do + statements +end +``` + +多状态迭代器适用于需要复杂迭代逻辑, 不规则的集合等场景. 因为闭包的使用其性能开销略大. +例如: +```lua +-- C# LINQ 中 Where 方法的简略实现, 从指定表中过滤出符合条件的元素 +-- table: 需要进行过滤的表 +-- predicate: 谓词函数, 即过滤条件 +local function where(table, predicate) + + -- 初始化内部状态变量 + local index = 0 + local size = #table + + -- 闭包返回迭代器函数 + return function() + -- 查找下一个符合条件的元素 + while index < size do + index = index + 1 + + -- 返回符合谓词函数过滤条件的元素 + if predicate(table[index]) then + return table[index] + end + end + + -- 没有更多符合条件的元素则结束迭代 + return nil + end +end + +local nums = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10} + +-- 过滤偶数 +for value in where(nums, function(x) return x % 2 == 0 end) do + print(value) -- 输出 2 4 6 8 10 +end + +-- 过滤大于 3 小于 7 的数 +for value in where(nums, function(x) return x > 3 and x < 7 end) do + print(value) -- 输出 4 5 6 +end +``` + +## 内置迭代器 + +### ipairs(table) +`ipairs` 是一个无状态迭代器,用于按数字索引顺序遍历表中的元素,从索引 `1` 开始,遇到 `nil` 时停止. 适用于数组类型的表. +例如: +```lua +local letters = {"a", "b", "c", "d", nil, "f"} + +-- ipairs 迭代器适用于数字类型的表, 遇到 nil 会停止迭代. 其返回两个值: +-- index: 当前索引 +-- value: 当前索引对应的值 +for index, value in ipairs(letters) do + print(index, value) -- 输出 1 a 2 b 3 c 4 d +end +``` + +!!!note + 可以使用 `_` 进行弃元以丢弃不需要的返回值. + 例如: + ```lua + local letters = {"a", "b", "c", "d", "e"} + + -- 使用 _ 以丢弃不需要的索引返回值 + for _, value in ipairs(letters) do + print(value) -- 输出 a b c d e + end + ``` + +### pairs(table) +`pairs` 是一个无状态迭代器,用于遍历表中的所有键值对,包括数字索引和非数字索引,遍历顺序不确定. 适用于需要遍历表中所有元素的场景. +例如: +```lua +local someTable = { + [1] = 1, + strawberries = 202, + result = true, + [true] = "a boolean value" +} + +-- pairs 迭代器适用于需要遍历表中所有元素的场景, 遍历顺序不确定. 其返回两个值: +-- key: 当前键 +-- value: 当前键对应的值 +for key, value in pairs(someTable) do + print(key, value) -- 输出 strawberries 202, true a boolean value, result true, 1 1 +end +``` \ No newline at end of file diff --git a/docs/extra/lua/metatable.md b/docs/extra/lua/metatable.md deleted file mode 100644 index 5ac659c..0000000 --- a/docs/extra/lua/metatable.md +++ /dev/null @@ -1 +0,0 @@ -# Lua 元表 \ No newline at end of file diff --git a/docs/extra/lua/module.md b/docs/extra/lua/module.md new file mode 100644 index 0000000..3659094 --- /dev/null +++ b/docs/extra/lua/module.md @@ -0,0 +1 @@ +# Lua 模块 \ No newline at end of file diff --git a/docs/extra/lua/package.md b/docs/extra/lua/package.md deleted file mode 100644 index d49b72f..0000000 --- a/docs/extra/lua/package.md +++ /dev/null @@ -1 +0,0 @@ -# Lua 模块与包 \ No newline at end of file diff --git a/mkdocs.yml b/mkdocs.yml index 9ba3909..0f2dca1 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -105,9 +105,7 @@ nav: - 流程控制: "extra/lua/control_flow.md" - 运算符: "extra/lua/operator.md" - 迭代器: "extra/lua/iterator.md" - - 元表: "extra/lua/metatable.md" - - 异常处理: "extra/lua/exception_handling.md" - - 模块与包: "extra/lua/package.md" + - 模块: "extra/lua/module.md" - 面向对象: "extra/lua/oop.md" - LuaCutscene: - 开始: "extra/lua_cutscene/begin.md" From 9b87c2db3fb2b77ca3da237781efc254d296c0ed Mon Sep 17 00:00:00 2001 From: ClearZer0 <534310154@qq.com> Date: Fri, 2 May 2025 09:36:25 +0800 Subject: [PATCH 23/26] test --- docs/advanced/cross_mod_interactions.md | 8 ++-- docs/css/content.css | 3 +- docs/extra/lua/Sample.lua | 53 ++++++++++++++++++------ docs/extra/lua/linq.lua | 25 +++++++++++ docs/extra/lua/oop.md | 1 - docs/misc/GhostLand.gif | Bin 0 -> 153240 bytes docs/misc/change_log.md | 4 +- docs/misc/what.md | 17 ++++++++ mkdocs.yml | 20 ++++----- 9 files changed, 100 insertions(+), 31 deletions(-) create mode 100644 docs/extra/lua/linq.lua delete mode 100644 docs/extra/lua/oop.md create mode 100644 docs/misc/GhostLand.gif create mode 100644 docs/misc/what.md diff --git a/docs/advanced/cross_mod_interactions.md b/docs/advanced/cross_mod_interactions.md index 4dfc28d..7a77f90 100644 --- a/docs/advanced/cross_mod_interactions.md +++ b/docs/advanced/cross_mod_interactions.md @@ -56,7 +56,7 @@ public override void Load() 一个 Mod 可以通过 `ModExportName` 特性导出一组方法, 而其他的 Mod 可以通过 `ModImportName` 特性导入这些方法作为委托以调用. -!!! info +!!! note 如果被依赖的 Mod 被禁用, 其通过 `ModExportName` 导出的委托将会是 `null`, 调用它们将导致游戏崩溃. 我们应该检查被依赖的 Mod 是否启用以决定是否调用. @@ -99,7 +99,7 @@ public static class MyCelesteModExports } ``` -!!! info +!!! note 请记住, API 是一种**契约**. 使用你的 API 的 Mod 作者会期望它至少能在你的 API 下一个主要版本前保持稳定. 因此, 我们**强烈**建议你记录每个版本 API 的修改, 至少包括每个方法的添加版本. 这样可以帮助其他 Mod 作者了解哪些 API 是新增的, 哪些是更改过的, 尽可能避免因接口变动而导致的问题. @@ -123,7 +123,7 @@ public override void Load() 下面我们新建另一个 Mod `AnotherCelesteMod` 导入 `MyCelesteMod` 提供的 API: -!!! info +!!! note 在导入前记得在 `everest.yaml` 中添加 `MyCelesteMod` 的可选依赖. ```cs title="MyCelesteModAPI.cs" @@ -220,7 +220,7 @@ Everest 会将所有 Code Mod 的程序集使用 MonoMod 进行 patch 处理后 ``` -!!! info +!!! note 在引用之前我们需要确认目标 Mod 在 `Cache` 中的是否存在, 以上面引用的 Mod 为例. `Cache` 中应该存在: - GravityHelper.GravityHelper.dll diff --git a/docs/css/content.css b/docs/css/content.css index 60b3d9a..620cc3b 100644 --- a/docs/css/content.css +++ b/docs/css/content.css @@ -5,4 +5,5 @@ --md-primary-fg-color: #04040c; --md-default-bg-color: #13131a; --md-hue: 225; - } \ No newline at end of file +} + diff --git a/docs/extra/lua/Sample.lua b/docs/extra/lua/Sample.lua index 0be0460..416762c 100644 --- a/docs/extra/lua/Sample.lua +++ b/docs/extra/lua/Sample.lua @@ -1,13 +1,40 @@ -local someTable = { - [1] = 1, - strawberries = 202, - result = true, - [true] = "a boolean value" -} - --- pairs 迭代器适用于需要遍历表中所有元素的场景, 遍历顺序不确定. 其返回两个值 --- index: 当前索引 --- value: 当前索引对应的值 -for index, value in pairs(someTable) do - print(index, value) -- 输出 strawberries 202, true a boolean value, result true -end \ No newline at end of file +local function updateList(list, index, value) + -- split list + local elements = {} + for element in string.gmatch(list, "[^,]+") do + table.insert(elements, element) + end + + -- update list + if (index > #elements) then + if value == nil then + return list + end + + -- fill elements + for i = #elements + 1, index, 1 do + table.insert(elements, i, value) + end + else + -- remove element + if value == nil then + table.remove(elements, index) + + -- insert element after index + else + table.insert(elements, index + 1, value) + end + end + + -- convert to string + local updatedList = table.concat(elements, ",") + return updatedList +end + +local list = "a,b,c" + +--print(updateList(list, 1, "hi")) +--print(updateList(list, 5, "nothi")) +print(updateList(list, 3, "hi")) +print(updateList(list, 5, "hi")) +print(updateList(list, 2, nil)) \ No newline at end of file diff --git a/docs/extra/lua/linq.lua b/docs/extra/lua/linq.lua new file mode 100644 index 0000000..d3e84ad --- /dev/null +++ b/docs/extra/lua/linq.lua @@ -0,0 +1,25 @@ +local linq = {} + +local linqmt = { + +} + +setmetatable(linq, linqmt) + +function linq:From(colletion) + +end + +function linq:Where(predicate) + +end + +function linq:Select(predicate) + +end + +function linq.ToTable() + +end + +return linq \ No newline at end of file diff --git a/docs/extra/lua/oop.md b/docs/extra/lua/oop.md deleted file mode 100644 index 6912b30..0000000 --- a/docs/extra/lua/oop.md +++ /dev/null @@ -1 +0,0 @@ -# Lua 面向对象 \ No newline at end of file diff --git a/docs/misc/GhostLand.gif b/docs/misc/GhostLand.gif new file mode 100644 index 0000000000000000000000000000000000000000..92ed567c708f501eb966ba7bd2605893a14f244e GIT binary patch literal 153240 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 literal 0 HcmV?d00001 diff --git a/docs/misc/change_log.md b/docs/misc/change_log.md index c39e019..42553bf 100644 --- a/docs/misc/change_log.md +++ b/docs/misc/change_log.md @@ -24,14 +24,14 @@ ### 2024.12.21 * 更新项目模板 -* 归档并重写 [一些准备 - 基础环境配置 - #通过模板创建项目](../coding_setup/basic_env.md) +* 归档并重写 [一些准备 - 基础环境配置 - #通过模板创建项目](../coding_setup/basic_env.md#_2) * 编写 [实战 - 测试地图](../coding_challenges/test_map.md) * 完善 [进阶 - 跨 Mod 交互](../advanced/cross_mod_interactions.md) ### 2025.1.19 * 归档 [一些准备 - 偏好](../arc/preference.md) * 重构 [一些准备 - 调试](../coding_setup/debug.md) -* 完善 [进阶 - 跨 Mod 交互 - #ModInterop](../advanced/cross_mod_interactions.md) +* 完善 [进阶 - 跨 Mod 交互 - #ModInterop](../advanced/cross_mod_interactions.md#modinterop) * 移动 [额外 - CMCC](../extra/cmcc/index.md), [额外 - LuaCutscene](../extra/lua_cutscene/begin.md) 以及 [其他 - XML 简单介绍](../extra/xml/xml_speedrun.md) 至额外章节以优化排版 ### 2025.1.28 diff --git a/docs/misc/what.md b/docs/misc/what.md new file mode 100644 index 0000000..e81cda9 --- /dev/null +++ b/docs/misc/what.md @@ -0,0 +1,17 @@ +# ig idk + +[中文标签跳转测试](#_1) + +## someGIF and scaling + +我超自己怎么画的这么好看(草草 +![GIF](GhostLand.gif) +![GIF](GhostLand.gif){: width="25%"} + +## 标签(? + +## Copy and Paste(?? +``` +很方便的分割线(草草 +--------------------------------------------------------------------------------------------- +``` diff --git a/mkdocs.yml b/mkdocs.yml index 0f2dca1..5f19dee 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -69,14 +69,14 @@ nav: - Session, Settings, SaveData: "basics/session_settings_savedata.md" - 进阶: - 跨 Mod 交互: "advanced/cross_mod_interactions.md" - - Loenn: - - Loenn 目录结构: "loenn/folder_structure.md" - - Loenn 基础配置: "loenn/basic_configurations.md" - - Entity 结构: "loenn/entity_structs.md" - - Trigger 结构: "loenn/trigger_structs.md" - - Loenn 绘制: "loenn/rendering.md" - - Loenn 节点: "loenn/nodes.md" - - Effect 结构: "loenn/effect_structs.md" + # - Loenn: + # - Loenn 目录结构: "loenn/folder_structure.md" + # - Loenn 基础配置: "loenn/basic_configurations.md" + # - Entity 结构: "loenn/entity_structs.md" + # - Trigger 结构: "loenn/trigger_structs.md" + # - Loenn 绘制: "loenn/rendering.md" + # - Loenn 节点: "loenn/nodes.md" + # - Effect 结构: "loenn/effect_structs.md" - 实战: - 测试地图: "coding_challenges/test_map.md" - 简单自定义实体: "coding_challenges/simple_entity.md" @@ -106,7 +106,6 @@ nav: - 运算符: "extra/lua/operator.md" - 迭代器: "extra/lua/iterator.md" - 模块: "extra/lua/module.md" - - 面向对象: "extra/lua/oop.md" - LuaCutscene: - 开始: "extra/lua_cutscene/begin.md" - 参考: "extra/lua_cutscene/reference.md" @@ -120,4 +119,5 @@ nav: - 偏好-sdk-styled-proj: "arc/sdk-styled-proj.md" - 杂项: - ChangeLog: "misc/change_log.md" - - ToDoList: "misc/to_do_list.md" \ No newline at end of file + - ToDoList: "misc/to_do_list.md" + - What: "misc/what.md" \ No newline at end of file From a21e5c739567d00706ee9a0a7c5ed5ef860ec2af Mon Sep 17 00:00:00 2001 From: ClearZer0 <534310154@qq.com> Date: Tue, 20 May 2025 07:12:44 +0800 Subject: [PATCH 24/26] final part(??? --- docs/extra/lua/Sample.lua | 40 ----- docs/extra/lua/begin.md | 4 +- docs/extra/lua/data_type.md | 10 +- docs/extra/lua/iterator.md | 2 +- docs/extra/lua/linq.lua | 25 ---- docs/extra/lua/module.md | 50 ++++++- docs/extra/lua/operator.md | 131 ++++++++++++++++- docs/extra/lua/standard_library.md | 225 +++++++++++++++++++++++++++++ docs/extra/lua/syntax.md | 2 +- docs/misc/change_log.md | 2 +- docs/misc/to_do_list.md | 1 - mkdocs.yml | 1 + 12 files changed, 412 insertions(+), 81 deletions(-) delete mode 100644 docs/extra/lua/Sample.lua delete mode 100644 docs/extra/lua/linq.lua create mode 100644 docs/extra/lua/standard_library.md diff --git a/docs/extra/lua/Sample.lua b/docs/extra/lua/Sample.lua deleted file mode 100644 index 416762c..0000000 --- a/docs/extra/lua/Sample.lua +++ /dev/null @@ -1,40 +0,0 @@ -local function updateList(list, index, value) - -- split list - local elements = {} - for element in string.gmatch(list, "[^,]+") do - table.insert(elements, element) - end - - -- update list - if (index > #elements) then - if value == nil then - return list - end - - -- fill elements - for i = #elements + 1, index, 1 do - table.insert(elements, i, value) - end - else - -- remove element - if value == nil then - table.remove(elements, index) - - -- insert element after index - else - table.insert(elements, index + 1, value) - end - end - - -- convert to string - local updatedList = table.concat(elements, ",") - return updatedList -end - -local list = "a,b,c" - ---print(updateList(list, 1, "hi")) ---print(updateList(list, 5, "nothi")) -print(updateList(list, 3, "hi")) -print(updateList(list, 5, "hi")) -print(updateList(list, 2, nil)) \ No newline at end of file diff --git a/docs/extra/lua/begin.md b/docs/extra/lua/begin.md index e091c9a..09e3185 100644 --- a/docs/extra/lua/begin.md +++ b/docs/extra/lua/begin.md @@ -8,7 +8,7 @@ !!!info 本教程的内容基于 `LuaJIT 2.1`, 即 `Loenn` 底层引擎 `LOVE2D` 所使用的 `Lua` 版本. - 因此, 高版本与 `Loenn` 开发中不涉及的特性(元表 异常处理等)在此教程不会提及. + 因此, 高版本与 `Loenn` 开发中不涉及的特性(元表 面向对象 异常处理等)在此教程不会提及. 如果对高版本 `Lua` 感兴趣可以阅读[官方文档](https://www.lua.org/manual/5.4). ## 开发环境 @@ -42,7 +42,7 @@ lua : 无法将“lua”项识别为 cmdlet、函数、脚本文件或可运行 默认情况下, `winget` 会将 `Lua` 安装至 `%LocalAppdata%\Programs\Lua\bin`. 我们在命令行输入以下命令将 `Lua` 安装目录添加至系统环境变量中: ```bat -setx PATH "$env:PATH;%LocalAppdata%\Programs\Lua\bin\Programs\Lua\bin" +setx PATH "$env:PATH;%LocalAppdata%\Programs\Lua\bin" ``` 完成后我们可以再次检查 `Lua` 是否安装成功: diff --git a/docs/extra/lua/data_type.md b/docs/extra/lua/data_type.md index b1d0369..648701c 100644 --- a/docs/extra/lua/data_type.md +++ b/docs/extra/lua/data_type.md @@ -383,7 +383,7 @@ print(average()) -- 输出 0 ```lua -- 函数可以作为变量赋值 -- 使用匿名函数定义加法操作 -local add = function (a, b) +local function add(a, b) return a + b end @@ -460,16 +460,16 @@ print(double(10)) -- 输出 20 以下是使用示例: ```lua local function printToNumber(e, base) - local castedInput = tonumber(e) + local castedResult = tonumber(e) if base then - castedInput = tonumber(e, base) + castedResult = tonumber(e, base) end - if type(castedInput) == "nil" then + if type(castedResult) == "nil" then print("type: nil, cast failed") else - print("type: " .. type(castedInput) .. " value: " .. castedInput) + print("type: " .. type(castedResult) .. " value: " .. castedResult) end end diff --git a/docs/extra/lua/iterator.md b/docs/extra/lua/iterator.md index e19ee61..e5b749b 100644 --- a/docs/extra/lua/iterator.md +++ b/docs/extra/lua/iterator.md @@ -165,7 +165,7 @@ end ```lua local letters = {"a", "b", "c", "d", nil, "f"} --- ipairs 迭代器适用于数字类型的表, 遇到 nil 会停止迭代. 其返回两个值: +-- ipairs 迭代器适用于数组类型的表, 遇到 nil 会停止迭代. 其返回两个值: -- index: 当前索引 -- value: 当前索引对应的值 for index, value in ipairs(letters) do diff --git a/docs/extra/lua/linq.lua b/docs/extra/lua/linq.lua deleted file mode 100644 index d3e84ad..0000000 --- a/docs/extra/lua/linq.lua +++ /dev/null @@ -1,25 +0,0 @@ -local linq = {} - -local linqmt = { - -} - -setmetatable(linq, linqmt) - -function linq:From(colletion) - -end - -function linq:Where(predicate) - -end - -function linq:Select(predicate) - -end - -function linq.ToTable() - -end - -return linq \ No newline at end of file diff --git a/docs/extra/lua/module.md b/docs/extra/lua/module.md index 3659094..a63b460 100644 --- a/docs/extra/lua/module.md +++ b/docs/extra/lua/module.md @@ -1 +1,49 @@ -# Lua 模块 \ No newline at end of file +# Lua 模块 +## 编写模块 + +`Lua` 中的模块类似于封装库, 可以把重用的代码放入同一个文件中, 以 API 接口的形式供外部调用. +`Lua` 中的模块是由变量/函数组成的表, 创建一个模块即把要导出的内容放入表中, 最后返回这个表: +```lua title="someModule.lua" +-- 创建一个模块, 即定义一个空表 +local someModule = {} + +-- Lua 中的元素默认是公开的 +-- 使用 "local" 限定为私有 + +-- 所有公开的内容需要添加到模块表内 +local privateTable = {"a", "b", "c"} -- 私有变量 +someModule.PublicTable = {1, 2, 3} -- 公开变量 + +-- 私有函数 +local function GetTwo() + return 2 +end + +-- 公开函数 +function someModule.DoubleNumber(num) + local two = GetTwo() + return num * two +end + +-- 最后返回这个模块 +return someModule +``` + +这样我们就导出了编写完成的模块. + +## 导入模块 + +`Lua` 提供 `require()` 函数以导入编写完成的模块: +```lua +-- 使用 require(moduleFileName) 导入需要的模块 不需要添加 .lua 后缀 +-- 模块应该只导入一次 使用变量进行缓存 +local myModule = require("someModule") + +-- 访问公开元素 +print(myModule.PublicTable[1]) -- 输出 1 +print(myModule.DoubleNumber(5)) -- 输出 10 + +-- 私有元素不存在于模块表中 访问会返回 nil +-- myModule.GetTwo() +-- print(privateTable) +``` \ No newline at end of file diff --git a/docs/extra/lua/operator.md b/docs/extra/lua/operator.md index a896728..2f2331f 100644 --- a/docs/extra/lua/operator.md +++ b/docs/extra/lua/operator.md @@ -5,6 +5,7 @@ - 算数运算符: 执行数学运算 - 关系运算符: 执行比较运算 - 逻辑运算符: 执行逻辑运算 +- 访问运算符: 执行访问与函数调用运算 - 其他运算符: 执行其他特定的运算 ## 算术运算符 @@ -197,6 +198,128 @@ print(1 or false or 3) -- 输出 1 Console.WriteLine(SafeDivide(10, 0)); // 报错 "Attempted to divide by zero." ``` +## 访问运算符 + +访问运算符用于访问表中的元素或函数调用, `Lua` 支持以下访问运算符: + +- `.`: 点运算符 +- `:`: 冒号运算符 + +两者在处理函数调用时的参数传递行为不同, 其余相同: + +### self 参数 + +`Lua` 中 `self` 不是一个关键字, 而是一种编程约定, 其通常作为函数的第一个参数进行传递. +`self` 参数能够让函数访问调用者, 通常是表的内部数据. 其与 `C#` 的 `this` 类似, 本质上是指向调用者的引用. + +### 点运算符 + +`.` 运算符可以用于访问表中的元素: + +```lua +local table = { + num = 0 +} + +-- 使用 . 运算符访问表中的元素 +print(table.num) -- 输出 0 +table.num = 10 -- 修改表中 num 的值 +print(table.num) -- 输出 10 + +table.num2 = 202 -- 定义表中 num2 的值 +print(table.num2) -- 输出 202 +``` + +`.` 运算符也可以用于函数调用: +```lua +local calculator = {} + +-- 定义 calculator 表中的函数 +function calculator.add(a, b) + return a + b +end + +function calculator.sub(a, b) + return a - b +end + +-- 使用 . 运算符调用 calculator 表中的函数 +print(calculator.add(1, 2)) -- 输出 3 +print(calculator.sub(7, 3)) -- 输出 4 +``` + +使用 `.` 运算符定义或调用函数时, 如果函数设计需要访问调用者状态则需要传递 `self` 参数: +```lua +local calculator = { + -- 计算器的初始值 + value = 0 +} + +-- 通过 self 参数显式传递指向 calculator 表自身的引用 +function calculator.reset(self) + -- 通过 self 参数修改 calculator 表中的数据 + self.value = 0 +end + +function calculator.add (self, num) + self.value = self.value + num +end + +function calculator.sub(self, num) + self.value = self.value - num +end + +-- 调用函数时需要显式传递 calculator 表的引用 +calculator.add(calculator, 20) +print(calculator.value) -- 输出 20 + +calculator.sub(calculator, 15) +print(calculator.value) -- 输出 5 + +calculator.reset(calculator) +print(calculator.value) -- 输出 0 + +calculator.add(calculator, 202) +print(calculator.value) -- 输出 202 +``` + +### 冒号运算符 + +`:` 运算符会自动隐式传递 `self` 参数, 上面的代码等价于: +```lua +local calculator = { + -- 计算器的初始值 + value = 0 +} + +-- 使用 : 运算符定义函数时会自动隐式传递 self 参数 +function calculator:reset() + -- 通过 self 参数修改 calculator 表中的数据 + self.value = 0 +end + +function calculator:add(num) + self.value = self.value + num +end + +function calculator:sub(num) + self.value = self.value - num +end + +-- 使用 : 运算符调用函数时会自动隐式传递 self 参数 +calculator:add(20) +print(calculator.value) -- 输出 20 + +calculator:sub(15) +print(calculator.value) -- 输出 5 + +calculator:reset() +print(calculator.value) -- 输出 0 + +calculator:add(202) +print(calculator.value) -- 输出 202 +``` + ## 其他运算符 `#` 长度运算符用于计算字符串或表的长度: @@ -212,11 +335,10 @@ print(#tas) -- 输出 22 local emptyTable = {} local letters = {"a", "b", "c"} -print(#{}) -- 输出 0 +print(#emptyTable) -- 输出 0 print(#letters) -- 输出 3 ``` -对于非连续索引类型的表, 即字典类型以及包含 `nil` 的连续索引的表, 即数组类型, -`#` 的输出可能不准确: +对于非连续索引类型的表, 即字典类型以及包含 `nil` 的连续索引的表, 即数组类型, `#` 的输出可能不准确: ```lua -- 包含 nil 的连续索引类型的表 local letters = {"a", "b", "c", nil} @@ -251,7 +373,8 @@ print("Number: " .. 123) -- 输出 Number: 123 | 优先级组 | 运算符 | |-------------------------|--------------------------------| -| 最高 | `^` | +| 最高 | `.` `:` | +| | `^` | | | `not` `#` `-` (取相反数) | | | `*` `/` `%` | | | `+` `-` (减法) | diff --git a/docs/extra/lua/standard_library.md b/docs/extra/lua/standard_library.md new file mode 100644 index 0000000..53e5a73 --- /dev/null +++ b/docs/extra/lua/standard_library.md @@ -0,0 +1,225 @@ +# Lua 标准库 +这篇文档列出了常用的 `Lua` 标准库函数, 可以根据需求进行查阅. + +## stringilb +`stringlib` 用于执行字符串相关操作, 通过 `string.(functionName)` 进行访问. + +### string.upper(s) +将字符串 `s` 中的所有小写字母转为大写字母 +```lua +local str = "Celeste" +print(string.upper(str)) -- 输出 CELESTE +``` + +### string.lower(s) +将字符串 `s` 中的所有大写字母转为小写字母 +```lua +local str = "Celeste" +print(string.lower(str)) -- 输出 celeste +``` + +### string.sub(s, i [,j]) +返回字符串 `s` 从第 `i` 个字符到第 `j` 个字符之间的子串. 如果不指定 `j`,则默认到字符串的末尾. 索引可以是负数, 表示从字符串末尾开始计算 +```lua +local str = "Hello, Lua!" +print(string.sub(str, 1, 5)) -- 输出 Hello +print(string.sub(str, 8)) -- 输出 Lua! +print(string.sub(str, -4)) -- 输出 Lua! +``` + +### string.find(s, pattern [, init [, plain]]) +在字符串 `s` 中查找 `pattern` 第一次出现的位置. 如果找到, 则返回匹配的起始和结束位置, 否则返回 `nil`.可选参数 `init` 指定开始搜索的位置. `plain` 为 `true` 时关闭[模式匹配](https://www.lua.org/manual/5.4/manual.html#6.4.1)功能. +```lua +local str = "Hello, Lua! Welcome to Lua world!" +print(string.find(str, "Lua")) -- 输出 8 11 +print(string.find(str, "Lua", 12)) -- 输出 23 26 +print(string.find(str, "LUA")) -- 输出 nil +print(string.find(str, "LUA", 1, true)) -- 输出 nil +``` +### string.gsub(s, pattern, repl [, n]) +将字符串 `s` 中所有的 `pattern` 替换为 `repl`. 可选参数 `n` 限制替换次数. 返回替换后的字符串和实际替换的次数. +```lua +local str = "Hello, Lua! Welcome to Lua world!" +local result, count = string.gsub(str, "Lua", "C#") +print(result) -- 输出 Hello, C#! Welcome to C# world! +print(count) -- 输出 2 + +local result, count = string.gsub(str, "Lua", "C#", 1) +print(result) -- 输出 Hello, C#! Welcome to Lua world! +print(count) -- 输出 1 +``` + +### string.match(s, pattern [, init]) +在字符串 `s` 中搜索第一个与 `pattern` [模式匹配](https://www.lua.org/manual/5.4/manual.html#6.4.1)的子串. 如果找到, 则返回匹配的子串, 否则返回 `nil`. 可选参数 `init` 指定开始搜索的位置. +```lua +local str = "Hello, Lua! Lua version: 5.4" +print(string.match(str, "Lua")) -- 输出 Lua +print(string.match(str, "Lua version: (%d+%.%d+)")) -- 输出 5.4 +``` + +### string.rep(s, n [, sep]) +返回重复 `n` 次字符串 `s` 的结果.可选参数 `sep` 指定每次重复之间的分隔符. +```lua +print(string.rep("HA", 3)) -- 输出 HAHAHA +print(string.rep("HA", 3, "-")) -- 输出 HA-HA-HA +``` + +## tablelib +`tablelib` 用于执行表相关操作, 通过 `table.(functionName)` 进行访问. + +### table.concat(list [, sep [, i [, j]]]) +将表 `list` 中的元素连接成一个字符串. `i` 和 `j` 指定连接的起始和结束位置. 可选参数 `sep` 指定分隔符, 默认为空字符串. +```lua +local fruits = {"apple", "banana", "orange", "grape"} +print(table.concat(fruits)) -- 输出 applebananaorangegrape +print(table.concat(fruits, ", ")) -- 输出 apple, banana, orange, grape +print(table.concat(fruits, "-", 2, 3)) -- 输出 banana-orange +``` + +### table.insert(list, [pos,] value) +在表 `list` 的指定位置 `pos` 插入元素 `value`. 如果不指定 `pos`, 则在表的末尾插入. +```lua +local fruits = {"apple", "banana"} +table.insert(fruits, "orange") +print(table.concat(fruits, ", ")) -- 输出 apple, banana, orange + +table.insert(fruits, 2, "grape") +print(table.concat(fruits, ", ")) -- 输出 apple, grape, banana, orange +``` + +### table.remove(list [, pos]) +删除表 `list` 中指定位置 `pos` 的元素, 并返回该元素. 如果不指定 `pos`, 则删除表的最后一个元素. +```lua +local fruits = {"apple", "grape", "banana", "orange"} +local removed = table.remove(fruits, 2) +print(removed) -- 输出 grape +print(table.concat(fruits, ", ")) -- 输出 apple, banana, orange + +local last = table.remove(fruits) +print(last) -- 输出 orange +print(table.concat(fruits, ", ")) -- 输出 apple, banana +``` + +### table.sort(list [, comp]) +对表 `list` 中的元素进行排序. 可选参数 `comp` 是使用的比较函数. 用于确定元素的排序顺序. +```lua +local numbers = {3, 1, 4, 1, 5, 9, 2, 6} +table.sort(numbers) +print(table.concat(numbers, ", ")) -- 输出 1, 1, 2, 3, 4, 5, 6, 9 + +local fruits = {"orange", "apple", "banana"} +table.sort(fruits) +print(table.concat(fruits, ", ")) -- 输出 apple, banana, orange + +-- 使用自定义 comp 进行降序排序 +table.sort(numbers, function(a, b) return a > b end) +print(table.concat(numbers, ", ")) -- 输出 9, 6, 5, 4, 3, 2, 1, 1 +``` + +### table.unpack(list [, i [, j]]) +返回表 `list` 中从索引 `i` 到 `j` 的所有元素. 如果不指定 `i` 和 `j`, 则默认为整个表. +```lua +local values = {10, 20, 30, 40, 50} +print(table.unpack(values)) -- 输出 10 20 30 40 50 +print(table.unpack(values, 2, 4)) -- 输出 20 30 40 + +local index2, index3 = table.unpack(values, 2, 3) +print(index2, index3) -- 输出 20 30 + +local function sum(...) + local result = 0 + for _, v in ipairs({...}) do + result = result + v + end + return result +end + +print(sum(table.unpack(values))) -- 输出 150 +``` + +## mathlib +`mathlib` 用于执行数学运算相关操作, 通过 `math.(functionName)` 进行访问. + +### math.abs(x) +返回 `x` 的绝对值. +```lua +print(math.abs(-10)) -- 输出 10 +print(math.abs(10)) -- 输出 10 +print(math.abs(-3.5)) -- 输出 3.5 +``` + +### math.sqrt(x) +返回 `x` 的平方根. +```lua +print(math.sqrt(16)) -- 输出 4.0 +print(math.sqrt(2)) -- 输出 1.4142135623731 +``` + +### math.pow(x, y) +返回 `x` 的 `y` 次方. +```lua +print(math.pow(2, 3)) -- 输出 8.0 +print(math.pow(5, 2)) -- 输出 25.0 +print(math.pow(2, 0.5)) -- 输出 1.4142135623731 +``` + +### math.max(x, ...) / math.min(x, ...) +`math.max(x, ...)` 返回参数中最大的值. `math.min(x, ...)` 返回参数中最小的值. +```lua +print(math.max(1, 2, 3, 4, 5)) -- 输出 5 +print(math.max(-10, -5, 0, 5, 10)) -- 输出 10 + +print(math.min(1, 2, 3, 4, 5)) -- 输出 1 +print(math.min(-10, -5, 0, 5, 10)) -- 输出 -10 +``` + +### math.ceil(x) / math.floor(x) +`math.ceil(x) `返回不小于 `x` 的最小整数. `math.floor(x)` 返回不大于 `x` 的最大整数. +```lua +print(math.ceil(3.1)) -- 输出 4 +print(math.ceil(3.9)) -- 输出 4 +print(math.ceil(-3.1)) -- 输出 -3 + +print(math.floor(3.1)) -- 输出 3 +print(math.floor(3.9)) -- 输出 3 +print(math.floor(-3.1)) -- 输出 -4 +``` + +### math.pi +数学常量 `π` 的值. +```lua +print(math.pi) -- 输出 3.1415926535898 +``` + +### math.rad(x) / math.deg(x) +`math.rad(x)` 将角度 `x` 转换为弧度, `math.deg(x)` 将弧度 `x` 转换为角度. +```lua +print(math.rad(180)) -- 输出: 3.1415926535898, 即 π +print(math.rad(90)) -- 输出: 1.5707963267949, 即 π/2 +print(math.deg(math.pi)) -- 输出 180.0 +print(math.deg(math.pi/2)) -- 输出 90.0 +``` + +### math.sin(x) / math.cos(x) / math.tan(x) +返回 `x` 的正弦/余弦/正切值. `x` 以弧度制为单位. +```lua +print(math.sin(0)) -- 输出 0.0 +print(math.sin(math.pi / 2)) -- 输出 1.0 +print(math.sin(math.rad(90))) -- 输出 1.0 + +print(math.cos(0)) -- 输出 1.0 +print(math.cos(math.pi)) -- 输出 -1.0 +print(math.cos(math.rad(0))) -- 输出 1.0 + +print(math.tan(math.pi / 4)) -- 输出 1.0 +print(math.tan(math.rad(45))) -- 输出 1.0 +``` + +### math.random([m [, n]]) +生成随机数, 不带参数返回 `[0, 1)` 区间内的随机浮点数, 指定单个参数 `m` 返回 `[1, m]` 区间内的随机整数, 指定两个参数 `m, n` 返回 `[m, n]` 区间内的随机整数. +```lua +print(math.random()) -- 输出 0 到 1 之间的随机浮点数, 例如 0.12345678 +print(math.random(10)) -- 输出 1 到 10 之间的随机整数, 例如 3 +print(math.random(5, 10)) -- 输出 5 到 10 之间的随机整数, 例如 8 +``` + diff --git a/docs/extra/lua/syntax.md b/docs/extra/lua/syntax.md index d321fc0..ff60cb0 100644 --- a/docs/extra/lua/syntax.md +++ b/docs/extra/lua/syntax.md @@ -87,7 +87,7 @@ print(x, y, z) -- 输出 10 20 30 !!!info 变量与函数的作用域遵循相同的规则, 以下将以变量为例进行说明. -默认情况下, 变量总是被认为是全局的. 全局变量不需要显示声明, 给一个变量赋值后即创建了这个全局变量. 访问一个未初始化的全局变量并不会报错, 其得到的结果将会是 `nil`.如果需要删除一个全局变量, 只需要将这个全局变量赋值为 `nil`: +默认情况下, 变量总是被认为是全局的. 全局变量不需要显式声明, 给一个变量赋值后即创建了这个全局变量. 访问一个未初始化的全局变量并不会报错, 其得到的结果将会是 `nil`.如果需要删除一个全局变量, 只需要将这个全局变量赋值为 `nil`: ```lua print(varible) -- 输出 nil diff --git a/docs/misc/change_log.md b/docs/misc/change_log.md index 42553bf..a4967de 100644 --- a/docs/misc/change_log.md +++ b/docs/misc/change_log.md @@ -37,7 +37,7 @@ ### 2025.1.28 * 添加插件以显示页面的创建与最后修改时间 以及文档编写者 -### 2025.2.7 +### 2025.5.20 * 更新项目模板 * 编写 [额外 - Lua](../extra/lua/begin.md) diff --git a/docs/misc/to_do_list.md b/docs/misc/to_do_list.md index 01ac6b4..a000c76 100644 --- a/docs/misc/to_do_list.md +++ b/docs/misc/to_do_list.md @@ -13,7 +13,6 @@ | 计划 | 状态 | | ----------------------------- | ------ | -| 编写 Lua 简易教程 | 进行中 | | 分离 Loenn 节及补充 | 进行中 | | 重构 EC 架构相关 | 准备中 | | 编写 碰撞检测 | 计划中 | diff --git a/mkdocs.yml b/mkdocs.yml index 5f19dee..a0d3925 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -106,6 +106,7 @@ nav: - 运算符: "extra/lua/operator.md" - 迭代器: "extra/lua/iterator.md" - 模块: "extra/lua/module.md" + - 标准库: "extra/lua/standard_library.md" - LuaCutscene: - 开始: "extra/lua_cutscene/begin.md" - 参考: "extra/lua_cutscene/reference.md" From d3ebc63fde4a198c6b13e96dd74d9cf9c85cc554 Mon Sep 17 00:00:00 2001 From: ClearZer0 <534310154@qq.com> Date: Tue, 20 May 2025 12:37:42 +0800 Subject: [PATCH 25/26] =?UTF-8?q?=E7=A7=BB=E9=99=A4=E6=B5=8B=E8=AF=95?= =?UTF-8?q?=E6=96=87=E4=BB=B6(=3F=3F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- mkdocs.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mkdocs.yml b/mkdocs.yml index a0d3925..b30e4b9 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -121,4 +121,4 @@ nav: - 杂项: - ChangeLog: "misc/change_log.md" - ToDoList: "misc/to_do_list.md" - - What: "misc/what.md" \ No newline at end of file +# - What: "misc/what.md" \ No newline at end of file From cd056c0a58cc819ab2f935c4ed132c2c933a23d2 Mon Sep 17 00:00:00 2001 From: ClearZer0 <534310154@qq.com> Date: Sun, 8 Jun 2025 22:14:13 +0800 Subject: [PATCH 26/26] =?UTF-8?q?=E9=87=8D=E6=9E=84=E9=A1=B9=E7=9B=AE?= =?UTF-8?q?=E7=BB=93=E6=9E=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitmodules | 3 - .../advanced/cross_mod_interactions.md | 0 docs/{ => Coding}/arc/basic_env.md | 0 docs/{ => Coding}/arc/preference.md | 0 docs/{ => Coding}/arc/project_template.md | 0 docs/{ => Coding}/arc/rename_proj.png | Bin docs/{ => Coding}/arc/sdk-styled-proj.md | 0 docs/{ => Coding}/arc/vsprojnew.png | Bin docs/{ => Coding}/arc/vsprojtfw.png | Bin .../basics/celeste_everest_monomod.md | 0 docs/{ => Coding}/basics/ec_common.md | 0 docs/{ => Coding}/basics/flag_tag_tracker.md | 0 .../session_settings_savedata/dialog.png | Bin .../interesting-switch.png | Bin .../more-options.png | Bin .../basics/session_settings_savedata.md | 0 .../images/simple_entity/entity_result.png | Bin .../images/simple_entity/game_coord.png | Bin .../simple_entity/our_loenn_entity_name.png | Bin .../simple_entity/room_entity_coord.png | Bin .../simple_texturing/fucking_ugly_texture.png | Bin .../images/simple_trigger/9_triggers.png | Bin .../images/simple_trigger/af_enter.png | Bin .../images/simple_trigger/b4_enter.png | Bin .../simple_trigger/loenn_result_trigger.png | Bin .../coding_challenges/simple_entity.md | 0 .../coding_challenges/simple_texturing.md | 0 .../coding_challenges/simple_trigger.md | 0 .../coding_challenges/test_map.md | 0 docs/{ => Coding}/coding_setup/basic_env.md | 0 .../{ => Coding}/coding_setup/code_reading.md | 0 docs/{ => Coding}/coding_setup/debug.md | 0 .../images/base_env/external_template.png | Bin .../images/base_env/inplace_template.png | Bin .../coding_setup/images/base_env/runnob-1.png | Bin .../coding_setup/images/base_env/runnob-2.png | Bin .../coding_setup/images/base_env/runnob-3.png | Bin .../images/base_env/vs_template.png | Bin .../images/code_reading/ILSpy_ana.png | Bin .../images/code_reading/ILSpy_track.png | Bin .../images/code_reading/dnspy_ana.png | Bin .../images/code_reading/dnspy_track.png | Bin .../coding_setup/images/debug/code_joke.jpg | Bin .../coding_setup/images/debug/debug_p1_1.png | Bin .../images/debug/vs_breakpoint.png | Bin .../images/debug/vs_local_varible.png | Bin .../components/alarm_tween_coroutine.md | 0 .../components/images/sprite_image/img00.png | Bin .../components/images/sprite_image/img01.png | Bin docs/{ => Coding}/components/sprite_image.md | 0 docs/{ => Coding}/components/statemachine.md | 0 docs/{ => Coding}/extra/lua/begin.md | 0 docs/{ => Coding}/extra/lua/control_flow.md | 0 docs/{ => Coding}/extra/lua/data_type.md | 0 .../extra/lua/images/begin/lua_in_vscode.png | Bin .../extra/lua/images/begin/vs_code_runner.png | Bin .../extra/lua/images/begin/vs_lua_output.png | Bin docs/{ => Coding}/extra/lua/iterator.md | 0 docs/{ => Coding}/extra/lua/module.md | 0 docs/{ => Coding}/extra/lua/operator.md | 0 .../extra/lua/standard_library.md | 0 docs/{ => Coding}/extra/lua/syntax.md | 0 docs/{ => Coding}/extra/lua_cutscene/begin.md | 0 .../extra/lua_cutscene/cs_access.md | 0 .../extra/lua_cutscene/examples.md | 0 .../extra/lua_cutscene/reference.md | 0 docs/{ => Coding}/extra/xml/xml_speedrun.md | 0 docs/{ => Coding}/hooks/adv_hooks.md | 0 docs/{ => Coding}/hooks/adv_hooks2.md | 0 docs/{ => Coding}/hooks/hook.md | 0 docs/{ => Coding}/hooks/il.md | 0 .../images/adv_hooks/code_dependency.jpg | Bin .../hook_reading_1/auto_complete_af.png | Bin .../hook_reading_1/auto_complete_b4.png | Bin .../hooks/images/il/dnspy-check-IL.png | Bin docs/Coding/index.md | 54 ++++++++ .../loenn/basic_configurations.md | 0 docs/{ => Coding}/loenn/effect_structs.md | 0 docs/{ => Coding}/loenn/entity_structs.md | 0 docs/{ => Coding}/loenn/folder_structure.md | 0 docs/{ => Coding}/loenn/nodes.md | 0 docs/{ => Coding}/loenn/rendering.md | 0 docs/{ => Coding}/loenn/trigger_structs.md | 0 docs/{ => Coding}/misc/GhostLand.gif | Bin docs/{ => Coding}/misc/change_log.md | 0 docs/{ => Coding}/misc/to_do_list.md | 0 docs/{ => Coding}/misc/what.md | 0 .../resources/CelesteModTutorial.zip | Bin .../CelesteModTutorial/Dialog/English.txt | 0 .../Dialog/Simplified Chinese.txt | 0 .../objects/PassByRefill/pass_by_refill.png | Bin .../Loenn/entities/PassByRefill.lua | 0 .../entities/PassByRefillWithTexture.lua | 0 .../CelesteModTutorial/Loenn/lang/en_gb.lang | 0 .../triggers/SetPassByRefillDashesTrigger.lua | 0 .../Maps/CelesteModTutorial/Test.bin | Bin .../CelesteModTutorial/Source/.everestignore | 0 .../Source/CelesteMod.props | 0 .../Source/CelesteMod.targets | 0 .../Source/CelesteModTutorial.csproj | 0 .../Source/CelesteModTutorialModule.cs | 0 .../Source/CelesteModTutorialSaveData.cs | 0 .../Source/CelesteModTutorialSession.cs | 0 .../Source/CelesteModTutorialSettings.cs | 0 .../Source/Entities/PassByRefill.cs | 0 .../Entities/PassByRefillWithTexture.cs | 0 .../Triggers/SetPassByRefillDashesTrigger.cs | 0 .../src}/CelesteModTutorial/everest.yaml | 0 docs/CustomMusic/index.md | 1 + docs/Mapping/index.md | 1 + docs/extra/cmcc/index.md | 5 - docs/extra/cmcc/remote | 1 - docs/index.md | 53 +------ mkdocs.yml | 129 +++++++++--------- 114 files changed, 122 insertions(+), 125 deletions(-) delete mode 100644 .gitmodules rename docs/{ => Coding}/advanced/cross_mod_interactions.md (100%) rename docs/{ => Coding}/arc/basic_env.md (100%) rename docs/{ => Coding}/arc/preference.md (100%) rename docs/{ => Coding}/arc/project_template.md (100%) rename docs/{ => Coding}/arc/rename_proj.png (100%) rename docs/{ => Coding}/arc/sdk-styled-proj.md (100%) rename docs/{ => Coding}/arc/vsprojnew.png (100%) rename docs/{ => Coding}/arc/vsprojtfw.png (100%) rename docs/{ => Coding}/basics/celeste_everest_monomod.md (100%) rename docs/{ => Coding}/basics/ec_common.md (100%) rename docs/{ => Coding}/basics/flag_tag_tracker.md (100%) rename docs/{ => Coding}/basics/images/session_settings_savedata/dialog.png (100%) rename docs/{ => Coding}/basics/images/session_settings_savedata/interesting-switch.png (100%) rename docs/{ => Coding}/basics/images/session_settings_savedata/more-options.png (100%) rename docs/{ => Coding}/basics/session_settings_savedata.md (100%) rename docs/{ => Coding}/coding_challenges/images/simple_entity/entity_result.png (100%) rename docs/{ => Coding}/coding_challenges/images/simple_entity/game_coord.png (100%) rename docs/{ => Coding}/coding_challenges/images/simple_entity/our_loenn_entity_name.png (100%) rename docs/{ => Coding}/coding_challenges/images/simple_entity/room_entity_coord.png (100%) rename docs/{ => Coding}/coding_challenges/images/simple_texturing/fucking_ugly_texture.png (100%) rename docs/{ => Coding}/coding_challenges/images/simple_trigger/9_triggers.png (100%) rename docs/{ => Coding}/coding_challenges/images/simple_trigger/af_enter.png (100%) rename docs/{ => Coding}/coding_challenges/images/simple_trigger/b4_enter.png (100%) rename docs/{ => Coding}/coding_challenges/images/simple_trigger/loenn_result_trigger.png (100%) rename docs/{ => Coding}/coding_challenges/simple_entity.md (100%) rename docs/{ => Coding}/coding_challenges/simple_texturing.md (100%) rename docs/{ => Coding}/coding_challenges/simple_trigger.md (100%) rename docs/{ => Coding}/coding_challenges/test_map.md (100%) rename docs/{ => Coding}/coding_setup/basic_env.md (100%) rename docs/{ => Coding}/coding_setup/code_reading.md (100%) rename docs/{ => Coding}/coding_setup/debug.md (100%) rename docs/{ => Coding}/coding_setup/images/base_env/external_template.png (100%) rename docs/{ => Coding}/coding_setup/images/base_env/inplace_template.png (100%) rename docs/{ => Coding}/coding_setup/images/base_env/runnob-1.png (100%) rename docs/{ => Coding}/coding_setup/images/base_env/runnob-2.png (100%) rename docs/{ => Coding}/coding_setup/images/base_env/runnob-3.png (100%) rename docs/{ => Coding}/coding_setup/images/base_env/vs_template.png (100%) rename docs/{ => Coding}/coding_setup/images/code_reading/ILSpy_ana.png (100%) rename docs/{ => Coding}/coding_setup/images/code_reading/ILSpy_track.png (100%) rename docs/{ => Coding}/coding_setup/images/code_reading/dnspy_ana.png (100%) rename docs/{ => Coding}/coding_setup/images/code_reading/dnspy_track.png (100%) rename docs/{ => Coding}/coding_setup/images/debug/code_joke.jpg (100%) rename docs/{ => Coding}/coding_setup/images/debug/debug_p1_1.png (100%) rename docs/{ => Coding}/coding_setup/images/debug/vs_breakpoint.png (100%) rename docs/{ => Coding}/coding_setup/images/debug/vs_local_varible.png (100%) rename docs/{ => Coding}/components/alarm_tween_coroutine.md (100%) rename docs/{ => Coding}/components/images/sprite_image/img00.png (100%) rename docs/{ => Coding}/components/images/sprite_image/img01.png (100%) rename docs/{ => Coding}/components/sprite_image.md (100%) rename docs/{ => Coding}/components/statemachine.md (100%) rename docs/{ => Coding}/extra/lua/begin.md (100%) rename docs/{ => Coding}/extra/lua/control_flow.md (100%) rename docs/{ => Coding}/extra/lua/data_type.md (100%) rename docs/{ => Coding}/extra/lua/images/begin/lua_in_vscode.png (100%) rename docs/{ => Coding}/extra/lua/images/begin/vs_code_runner.png (100%) rename docs/{ => Coding}/extra/lua/images/begin/vs_lua_output.png (100%) rename docs/{ => Coding}/extra/lua/iterator.md (100%) rename docs/{ => Coding}/extra/lua/module.md (100%) rename docs/{ => Coding}/extra/lua/operator.md (100%) rename docs/{ => Coding}/extra/lua/standard_library.md (100%) rename docs/{ => Coding}/extra/lua/syntax.md (100%) rename docs/{ => Coding}/extra/lua_cutscene/begin.md (100%) rename docs/{ => Coding}/extra/lua_cutscene/cs_access.md (100%) rename docs/{ => Coding}/extra/lua_cutscene/examples.md (100%) rename docs/{ => Coding}/extra/lua_cutscene/reference.md (100%) rename docs/{ => Coding}/extra/xml/xml_speedrun.md (100%) rename docs/{ => Coding}/hooks/adv_hooks.md (100%) rename docs/{ => Coding}/hooks/adv_hooks2.md (100%) rename docs/{ => Coding}/hooks/hook.md (100%) rename docs/{ => Coding}/hooks/il.md (100%) rename docs/{ => Coding}/hooks/images/adv_hooks/code_dependency.jpg (100%) rename docs/{ => Coding}/hooks/images/hook_reading_1/auto_complete_af.png (100%) rename docs/{ => Coding}/hooks/images/hook_reading_1/auto_complete_b4.png (100%) rename docs/{ => Coding}/hooks/images/il/dnspy-check-IL.png (100%) create mode 100644 docs/Coding/index.md rename docs/{ => Coding}/loenn/basic_configurations.md (100%) rename docs/{ => Coding}/loenn/effect_structs.md (100%) rename docs/{ => Coding}/loenn/entity_structs.md (100%) rename docs/{ => Coding}/loenn/folder_structure.md (100%) rename docs/{ => Coding}/loenn/nodes.md (100%) rename docs/{ => Coding}/loenn/rendering.md (100%) rename docs/{ => Coding}/loenn/trigger_structs.md (100%) rename docs/{ => Coding}/misc/GhostLand.gif (100%) rename docs/{ => Coding}/misc/change_log.md (100%) rename docs/{ => Coding}/misc/to_do_list.md (100%) rename docs/{ => Coding}/misc/what.md (100%) rename docs/{ => Coding}/resources/CelesteModTutorial.zip (100%) rename {src => docs/Coding/src}/CelesteModTutorial/Dialog/English.txt (100%) rename {src => docs/Coding/src}/CelesteModTutorial/Dialog/Simplified Chinese.txt (100%) rename {src => docs/Coding/src}/CelesteModTutorial/Graphics/Atlases/Gameplay/objects/PassByRefill/pass_by_refill.png (100%) rename {src => docs/Coding/src}/CelesteModTutorial/Loenn/entities/PassByRefill.lua (100%) rename {src => docs/Coding/src}/CelesteModTutorial/Loenn/entities/PassByRefillWithTexture.lua (100%) rename {src => docs/Coding/src}/CelesteModTutorial/Loenn/lang/en_gb.lang (100%) rename {src => docs/Coding/src}/CelesteModTutorial/Loenn/triggers/SetPassByRefillDashesTrigger.lua (100%) rename {src => docs/Coding/src}/CelesteModTutorial/Maps/CelesteModTutorial/Test.bin (100%) rename {src => docs/Coding/src}/CelesteModTutorial/Source/.everestignore (100%) rename {src => docs/Coding/src}/CelesteModTutorial/Source/CelesteMod.props (100%) rename {src => docs/Coding/src}/CelesteModTutorial/Source/CelesteMod.targets (100%) rename {src => docs/Coding/src}/CelesteModTutorial/Source/CelesteModTutorial.csproj (100%) rename {src => docs/Coding/src}/CelesteModTutorial/Source/CelesteModTutorialModule.cs (100%) rename {src => docs/Coding/src}/CelesteModTutorial/Source/CelesteModTutorialSaveData.cs (100%) rename {src => docs/Coding/src}/CelesteModTutorial/Source/CelesteModTutorialSession.cs (100%) rename {src => docs/Coding/src}/CelesteModTutorial/Source/CelesteModTutorialSettings.cs (100%) rename {src => docs/Coding/src}/CelesteModTutorial/Source/Entities/PassByRefill.cs (100%) rename {src => docs/Coding/src}/CelesteModTutorial/Source/Entities/PassByRefillWithTexture.cs (100%) rename {src => docs/Coding/src}/CelesteModTutorial/Source/Triggers/SetPassByRefillDashesTrigger.cs (100%) rename {src => docs/Coding/src}/CelesteModTutorial/everest.yaml (100%) create mode 100644 docs/CustomMusic/index.md create mode 100644 docs/Mapping/index.md delete mode 100644 docs/extra/cmcc/index.md delete mode 160000 docs/extra/cmcc/remote diff --git a/.gitmodules b/.gitmodules deleted file mode 100644 index e6c3d98..0000000 --- a/.gitmodules +++ /dev/null @@ -1,3 +0,0 @@ -[submodule "docs/extra/cmcc/remote"] - path = docs/extra/cmcc/remote - url = https://github.com/ForkKILLET/CelesteMapperCooperationInChina.git diff --git a/docs/advanced/cross_mod_interactions.md b/docs/Coding/advanced/cross_mod_interactions.md similarity index 100% rename from docs/advanced/cross_mod_interactions.md rename to docs/Coding/advanced/cross_mod_interactions.md diff --git a/docs/arc/basic_env.md b/docs/Coding/arc/basic_env.md similarity index 100% rename from docs/arc/basic_env.md rename to docs/Coding/arc/basic_env.md diff --git a/docs/arc/preference.md b/docs/Coding/arc/preference.md similarity index 100% rename from docs/arc/preference.md rename to docs/Coding/arc/preference.md diff --git a/docs/arc/project_template.md b/docs/Coding/arc/project_template.md similarity index 100% rename from docs/arc/project_template.md rename to docs/Coding/arc/project_template.md diff --git a/docs/arc/rename_proj.png b/docs/Coding/arc/rename_proj.png similarity index 100% rename from docs/arc/rename_proj.png rename to docs/Coding/arc/rename_proj.png diff --git a/docs/arc/sdk-styled-proj.md b/docs/Coding/arc/sdk-styled-proj.md similarity index 100% rename from docs/arc/sdk-styled-proj.md rename to docs/Coding/arc/sdk-styled-proj.md diff --git a/docs/arc/vsprojnew.png b/docs/Coding/arc/vsprojnew.png similarity index 100% rename from docs/arc/vsprojnew.png rename to docs/Coding/arc/vsprojnew.png diff --git a/docs/arc/vsprojtfw.png b/docs/Coding/arc/vsprojtfw.png similarity index 100% rename from docs/arc/vsprojtfw.png rename to docs/Coding/arc/vsprojtfw.png diff --git a/docs/basics/celeste_everest_monomod.md b/docs/Coding/basics/celeste_everest_monomod.md similarity index 100% rename from docs/basics/celeste_everest_monomod.md rename to docs/Coding/basics/celeste_everest_monomod.md diff --git a/docs/basics/ec_common.md b/docs/Coding/basics/ec_common.md similarity index 100% rename from docs/basics/ec_common.md rename to docs/Coding/basics/ec_common.md diff --git a/docs/basics/flag_tag_tracker.md b/docs/Coding/basics/flag_tag_tracker.md similarity index 100% rename from docs/basics/flag_tag_tracker.md rename to docs/Coding/basics/flag_tag_tracker.md diff --git a/docs/basics/images/session_settings_savedata/dialog.png b/docs/Coding/basics/images/session_settings_savedata/dialog.png similarity index 100% rename from docs/basics/images/session_settings_savedata/dialog.png rename to docs/Coding/basics/images/session_settings_savedata/dialog.png diff --git a/docs/basics/images/session_settings_savedata/interesting-switch.png b/docs/Coding/basics/images/session_settings_savedata/interesting-switch.png similarity index 100% rename from docs/basics/images/session_settings_savedata/interesting-switch.png rename to docs/Coding/basics/images/session_settings_savedata/interesting-switch.png diff --git a/docs/basics/images/session_settings_savedata/more-options.png b/docs/Coding/basics/images/session_settings_savedata/more-options.png similarity index 100% rename from docs/basics/images/session_settings_savedata/more-options.png rename to docs/Coding/basics/images/session_settings_savedata/more-options.png diff --git a/docs/basics/session_settings_savedata.md b/docs/Coding/basics/session_settings_savedata.md similarity index 100% rename from docs/basics/session_settings_savedata.md rename to docs/Coding/basics/session_settings_savedata.md diff --git a/docs/coding_challenges/images/simple_entity/entity_result.png b/docs/Coding/coding_challenges/images/simple_entity/entity_result.png similarity index 100% rename from docs/coding_challenges/images/simple_entity/entity_result.png rename to docs/Coding/coding_challenges/images/simple_entity/entity_result.png diff --git a/docs/coding_challenges/images/simple_entity/game_coord.png b/docs/Coding/coding_challenges/images/simple_entity/game_coord.png similarity index 100% rename from docs/coding_challenges/images/simple_entity/game_coord.png rename to docs/Coding/coding_challenges/images/simple_entity/game_coord.png diff --git a/docs/coding_challenges/images/simple_entity/our_loenn_entity_name.png b/docs/Coding/coding_challenges/images/simple_entity/our_loenn_entity_name.png similarity index 100% rename from docs/coding_challenges/images/simple_entity/our_loenn_entity_name.png rename to docs/Coding/coding_challenges/images/simple_entity/our_loenn_entity_name.png diff --git a/docs/coding_challenges/images/simple_entity/room_entity_coord.png b/docs/Coding/coding_challenges/images/simple_entity/room_entity_coord.png similarity index 100% rename from docs/coding_challenges/images/simple_entity/room_entity_coord.png rename to docs/Coding/coding_challenges/images/simple_entity/room_entity_coord.png diff --git a/docs/coding_challenges/images/simple_texturing/fucking_ugly_texture.png b/docs/Coding/coding_challenges/images/simple_texturing/fucking_ugly_texture.png similarity index 100% rename from docs/coding_challenges/images/simple_texturing/fucking_ugly_texture.png rename to docs/Coding/coding_challenges/images/simple_texturing/fucking_ugly_texture.png diff --git a/docs/coding_challenges/images/simple_trigger/9_triggers.png b/docs/Coding/coding_challenges/images/simple_trigger/9_triggers.png similarity index 100% rename from docs/coding_challenges/images/simple_trigger/9_triggers.png rename to docs/Coding/coding_challenges/images/simple_trigger/9_triggers.png diff --git a/docs/coding_challenges/images/simple_trigger/af_enter.png b/docs/Coding/coding_challenges/images/simple_trigger/af_enter.png similarity index 100% rename from docs/coding_challenges/images/simple_trigger/af_enter.png rename to docs/Coding/coding_challenges/images/simple_trigger/af_enter.png diff --git a/docs/coding_challenges/images/simple_trigger/b4_enter.png b/docs/Coding/coding_challenges/images/simple_trigger/b4_enter.png similarity index 100% rename from docs/coding_challenges/images/simple_trigger/b4_enter.png rename to docs/Coding/coding_challenges/images/simple_trigger/b4_enter.png diff --git a/docs/coding_challenges/images/simple_trigger/loenn_result_trigger.png b/docs/Coding/coding_challenges/images/simple_trigger/loenn_result_trigger.png similarity index 100% rename from docs/coding_challenges/images/simple_trigger/loenn_result_trigger.png rename to docs/Coding/coding_challenges/images/simple_trigger/loenn_result_trigger.png diff --git a/docs/coding_challenges/simple_entity.md b/docs/Coding/coding_challenges/simple_entity.md similarity index 100% rename from docs/coding_challenges/simple_entity.md rename to docs/Coding/coding_challenges/simple_entity.md diff --git a/docs/coding_challenges/simple_texturing.md b/docs/Coding/coding_challenges/simple_texturing.md similarity index 100% rename from docs/coding_challenges/simple_texturing.md rename to docs/Coding/coding_challenges/simple_texturing.md diff --git a/docs/coding_challenges/simple_trigger.md b/docs/Coding/coding_challenges/simple_trigger.md similarity index 100% rename from docs/coding_challenges/simple_trigger.md rename to docs/Coding/coding_challenges/simple_trigger.md diff --git a/docs/coding_challenges/test_map.md b/docs/Coding/coding_challenges/test_map.md similarity index 100% rename from docs/coding_challenges/test_map.md rename to docs/Coding/coding_challenges/test_map.md diff --git a/docs/coding_setup/basic_env.md b/docs/Coding/coding_setup/basic_env.md similarity index 100% rename from docs/coding_setup/basic_env.md rename to docs/Coding/coding_setup/basic_env.md diff --git a/docs/coding_setup/code_reading.md b/docs/Coding/coding_setup/code_reading.md similarity index 100% rename from docs/coding_setup/code_reading.md rename to docs/Coding/coding_setup/code_reading.md diff --git a/docs/coding_setup/debug.md b/docs/Coding/coding_setup/debug.md similarity index 100% rename from docs/coding_setup/debug.md rename to docs/Coding/coding_setup/debug.md diff --git a/docs/coding_setup/images/base_env/external_template.png b/docs/Coding/coding_setup/images/base_env/external_template.png similarity index 100% rename from docs/coding_setup/images/base_env/external_template.png rename to docs/Coding/coding_setup/images/base_env/external_template.png diff --git a/docs/coding_setup/images/base_env/inplace_template.png b/docs/Coding/coding_setup/images/base_env/inplace_template.png similarity index 100% rename from docs/coding_setup/images/base_env/inplace_template.png rename to docs/Coding/coding_setup/images/base_env/inplace_template.png diff --git a/docs/coding_setup/images/base_env/runnob-1.png b/docs/Coding/coding_setup/images/base_env/runnob-1.png similarity index 100% rename from docs/coding_setup/images/base_env/runnob-1.png rename to docs/Coding/coding_setup/images/base_env/runnob-1.png diff --git a/docs/coding_setup/images/base_env/runnob-2.png b/docs/Coding/coding_setup/images/base_env/runnob-2.png similarity index 100% rename from docs/coding_setup/images/base_env/runnob-2.png rename to docs/Coding/coding_setup/images/base_env/runnob-2.png diff --git a/docs/coding_setup/images/base_env/runnob-3.png b/docs/Coding/coding_setup/images/base_env/runnob-3.png similarity index 100% rename from docs/coding_setup/images/base_env/runnob-3.png rename to docs/Coding/coding_setup/images/base_env/runnob-3.png diff --git a/docs/coding_setup/images/base_env/vs_template.png b/docs/Coding/coding_setup/images/base_env/vs_template.png similarity index 100% rename from docs/coding_setup/images/base_env/vs_template.png rename to docs/Coding/coding_setup/images/base_env/vs_template.png diff --git a/docs/coding_setup/images/code_reading/ILSpy_ana.png b/docs/Coding/coding_setup/images/code_reading/ILSpy_ana.png similarity index 100% rename from docs/coding_setup/images/code_reading/ILSpy_ana.png rename to docs/Coding/coding_setup/images/code_reading/ILSpy_ana.png diff --git a/docs/coding_setup/images/code_reading/ILSpy_track.png b/docs/Coding/coding_setup/images/code_reading/ILSpy_track.png similarity index 100% rename from docs/coding_setup/images/code_reading/ILSpy_track.png rename to docs/Coding/coding_setup/images/code_reading/ILSpy_track.png diff --git a/docs/coding_setup/images/code_reading/dnspy_ana.png b/docs/Coding/coding_setup/images/code_reading/dnspy_ana.png similarity index 100% rename from docs/coding_setup/images/code_reading/dnspy_ana.png rename to docs/Coding/coding_setup/images/code_reading/dnspy_ana.png diff --git a/docs/coding_setup/images/code_reading/dnspy_track.png b/docs/Coding/coding_setup/images/code_reading/dnspy_track.png similarity index 100% rename from docs/coding_setup/images/code_reading/dnspy_track.png rename to docs/Coding/coding_setup/images/code_reading/dnspy_track.png diff --git a/docs/coding_setup/images/debug/code_joke.jpg b/docs/Coding/coding_setup/images/debug/code_joke.jpg similarity index 100% rename from docs/coding_setup/images/debug/code_joke.jpg rename to docs/Coding/coding_setup/images/debug/code_joke.jpg diff --git a/docs/coding_setup/images/debug/debug_p1_1.png b/docs/Coding/coding_setup/images/debug/debug_p1_1.png similarity index 100% rename from docs/coding_setup/images/debug/debug_p1_1.png rename to docs/Coding/coding_setup/images/debug/debug_p1_1.png diff --git a/docs/coding_setup/images/debug/vs_breakpoint.png b/docs/Coding/coding_setup/images/debug/vs_breakpoint.png similarity index 100% rename from docs/coding_setup/images/debug/vs_breakpoint.png rename to docs/Coding/coding_setup/images/debug/vs_breakpoint.png diff --git a/docs/coding_setup/images/debug/vs_local_varible.png b/docs/Coding/coding_setup/images/debug/vs_local_varible.png similarity index 100% rename from docs/coding_setup/images/debug/vs_local_varible.png rename to docs/Coding/coding_setup/images/debug/vs_local_varible.png diff --git a/docs/components/alarm_tween_coroutine.md b/docs/Coding/components/alarm_tween_coroutine.md similarity index 100% rename from docs/components/alarm_tween_coroutine.md rename to docs/Coding/components/alarm_tween_coroutine.md diff --git a/docs/components/images/sprite_image/img00.png b/docs/Coding/components/images/sprite_image/img00.png similarity index 100% rename from docs/components/images/sprite_image/img00.png rename to docs/Coding/components/images/sprite_image/img00.png diff --git a/docs/components/images/sprite_image/img01.png b/docs/Coding/components/images/sprite_image/img01.png similarity index 100% rename from docs/components/images/sprite_image/img01.png rename to docs/Coding/components/images/sprite_image/img01.png diff --git a/docs/components/sprite_image.md b/docs/Coding/components/sprite_image.md similarity index 100% rename from docs/components/sprite_image.md rename to docs/Coding/components/sprite_image.md diff --git a/docs/components/statemachine.md b/docs/Coding/components/statemachine.md similarity index 100% rename from docs/components/statemachine.md rename to docs/Coding/components/statemachine.md diff --git a/docs/extra/lua/begin.md b/docs/Coding/extra/lua/begin.md similarity index 100% rename from docs/extra/lua/begin.md rename to docs/Coding/extra/lua/begin.md diff --git a/docs/extra/lua/control_flow.md b/docs/Coding/extra/lua/control_flow.md similarity index 100% rename from docs/extra/lua/control_flow.md rename to docs/Coding/extra/lua/control_flow.md diff --git a/docs/extra/lua/data_type.md b/docs/Coding/extra/lua/data_type.md similarity index 100% rename from docs/extra/lua/data_type.md rename to docs/Coding/extra/lua/data_type.md diff --git a/docs/extra/lua/images/begin/lua_in_vscode.png b/docs/Coding/extra/lua/images/begin/lua_in_vscode.png similarity index 100% rename from docs/extra/lua/images/begin/lua_in_vscode.png rename to docs/Coding/extra/lua/images/begin/lua_in_vscode.png diff --git a/docs/extra/lua/images/begin/vs_code_runner.png b/docs/Coding/extra/lua/images/begin/vs_code_runner.png similarity index 100% rename from docs/extra/lua/images/begin/vs_code_runner.png rename to docs/Coding/extra/lua/images/begin/vs_code_runner.png diff --git a/docs/extra/lua/images/begin/vs_lua_output.png b/docs/Coding/extra/lua/images/begin/vs_lua_output.png similarity index 100% rename from docs/extra/lua/images/begin/vs_lua_output.png rename to docs/Coding/extra/lua/images/begin/vs_lua_output.png diff --git a/docs/extra/lua/iterator.md b/docs/Coding/extra/lua/iterator.md similarity index 100% rename from docs/extra/lua/iterator.md rename to docs/Coding/extra/lua/iterator.md diff --git a/docs/extra/lua/module.md b/docs/Coding/extra/lua/module.md similarity index 100% rename from docs/extra/lua/module.md rename to docs/Coding/extra/lua/module.md diff --git a/docs/extra/lua/operator.md b/docs/Coding/extra/lua/operator.md similarity index 100% rename from docs/extra/lua/operator.md rename to docs/Coding/extra/lua/operator.md diff --git a/docs/extra/lua/standard_library.md b/docs/Coding/extra/lua/standard_library.md similarity index 100% rename from docs/extra/lua/standard_library.md rename to docs/Coding/extra/lua/standard_library.md diff --git a/docs/extra/lua/syntax.md b/docs/Coding/extra/lua/syntax.md similarity index 100% rename from docs/extra/lua/syntax.md rename to docs/Coding/extra/lua/syntax.md diff --git a/docs/extra/lua_cutscene/begin.md b/docs/Coding/extra/lua_cutscene/begin.md similarity index 100% rename from docs/extra/lua_cutscene/begin.md rename to docs/Coding/extra/lua_cutscene/begin.md diff --git a/docs/extra/lua_cutscene/cs_access.md b/docs/Coding/extra/lua_cutscene/cs_access.md similarity index 100% rename from docs/extra/lua_cutscene/cs_access.md rename to docs/Coding/extra/lua_cutscene/cs_access.md diff --git a/docs/extra/lua_cutscene/examples.md b/docs/Coding/extra/lua_cutscene/examples.md similarity index 100% rename from docs/extra/lua_cutscene/examples.md rename to docs/Coding/extra/lua_cutscene/examples.md diff --git a/docs/extra/lua_cutscene/reference.md b/docs/Coding/extra/lua_cutscene/reference.md similarity index 100% rename from docs/extra/lua_cutscene/reference.md rename to docs/Coding/extra/lua_cutscene/reference.md diff --git a/docs/extra/xml/xml_speedrun.md b/docs/Coding/extra/xml/xml_speedrun.md similarity index 100% rename from docs/extra/xml/xml_speedrun.md rename to docs/Coding/extra/xml/xml_speedrun.md diff --git a/docs/hooks/adv_hooks.md b/docs/Coding/hooks/adv_hooks.md similarity index 100% rename from docs/hooks/adv_hooks.md rename to docs/Coding/hooks/adv_hooks.md diff --git a/docs/hooks/adv_hooks2.md b/docs/Coding/hooks/adv_hooks2.md similarity index 100% rename from docs/hooks/adv_hooks2.md rename to docs/Coding/hooks/adv_hooks2.md diff --git a/docs/hooks/hook.md b/docs/Coding/hooks/hook.md similarity index 100% rename from docs/hooks/hook.md rename to docs/Coding/hooks/hook.md diff --git a/docs/hooks/il.md b/docs/Coding/hooks/il.md similarity index 100% rename from docs/hooks/il.md rename to docs/Coding/hooks/il.md diff --git a/docs/hooks/images/adv_hooks/code_dependency.jpg b/docs/Coding/hooks/images/adv_hooks/code_dependency.jpg similarity index 100% rename from docs/hooks/images/adv_hooks/code_dependency.jpg rename to docs/Coding/hooks/images/adv_hooks/code_dependency.jpg diff --git a/docs/hooks/images/hook_reading_1/auto_complete_af.png b/docs/Coding/hooks/images/hook_reading_1/auto_complete_af.png similarity index 100% rename from docs/hooks/images/hook_reading_1/auto_complete_af.png rename to docs/Coding/hooks/images/hook_reading_1/auto_complete_af.png diff --git a/docs/hooks/images/hook_reading_1/auto_complete_b4.png b/docs/Coding/hooks/images/hook_reading_1/auto_complete_b4.png similarity index 100% rename from docs/hooks/images/hook_reading_1/auto_complete_b4.png rename to docs/Coding/hooks/images/hook_reading_1/auto_complete_b4.png diff --git a/docs/hooks/images/il/dnspy-check-IL.png b/docs/Coding/hooks/images/il/dnspy-check-IL.png similarity index 100% rename from docs/hooks/images/il/dnspy-check-IL.png rename to docs/Coding/hooks/images/il/dnspy-check-IL.png diff --git a/docs/Coding/index.md b/docs/Coding/index.md new file mode 100644 index 0000000..a5581ac --- /dev/null +++ b/docs/Coding/index.md @@ -0,0 +1,54 @@ +# 首页 + +本系列教程主要写自于个人在制作蔚蓝 CodeMod 的一些经验 +本网站内容开源在: [github.com/Saplonily/CelesteModTutorial](https://github.com/Saplonily/CelesteModTutorial) +十分欢迎来提 pr 和 issue 以修复各种语法错误, 用词错误和内容错误以及建议_(:з」∠)_ + +大部分文章可能会写的不明不白以至于需要频繁修改, 如果你有更好的修改建议的话欢迎来提 issue. + +那么一切就绪, 可以开始阅读 入门-第一节 了: + +[开始 - Celeste Everest MonoMod](basics/celeste_everest_monomod.md) + +顺便感谢一些为本教程贡献的人: + +- AppleSheep - 在写作初期提供了大量修改建议 目前正在维护整个教程([Bilibili](https://space.bilibili.com/227488539)) +- 夜谷紫幽 - 为配置环境节提供了使用模板的建议 ([Bilibili](https://space.bilibili.com/346379712)) +- 电箱 - 制作了包含基础 Loenn 使用教程的作图教程 ([Bilibili](https://space.bilibili.com/240308518)) +- Lucky boy - [Session, Settings, SaveData](basics/session_settings_savedata.md) 节的一些补充, 以及钩取 Helper 方法, debug, tracker, flag, tag 节的作者 ([GitHub](https://github.com/LuckyBoy-7)) + +以及我自己 :D + +- Saplonily ([Bilibili](https://space.bilibili.com/39046375), [Outlook](mailto:Saplonily@outlook.com)) + +以及教程大部分内容的来源: + +- [Everest Wiki](https://github.com/EverestAPI/Resources/wiki/Code-Mod-Setup) + +和一切的基础: + +- [Celeste](https://www.celestegame.com/) +- [Everest API](https://github.com/EverestAPI) + +---- + +在网站中的代码块中的一些高亮在横向滚动时会发生截断, 即高亮并没有覆盖整行, 这个是 `mkdocs-material` 自身的 bug, 而且看上去说是修复起来很困难, +issue 链接: [mkdocs-material issue #452](https://github.com/squidfunk/mkdocs-material/issues/452). + +bug 于下: +``` hl_lines="1 2 3 4" +t11ntpj808mbc1gu4lx7n9d8tj5q3ck3t1c0aclc Liquorice oat cake carrot cake. Halvah lemon drops bear claw fruitcake. Marshmallow danish jelly-o toffee. +jqlksiohper0brg9x2ajcm7ajjf8ptjxprqstvda Apple pie cake jelly-o sugar plum. +x3mjly0wn48wy7lgf2bfymbykommv8dbyp7an1n8 Toffee candy brownie carrot cake jujubes sweet roll chocolate gingerbread. +q0b5pj6eacuwj3t1i4jv7yxf00mi6osc0h5etcfz Cupcake tiramisu danish brownie danish jujubes gingerbread toffee gummi bears. +u25qzla31ahqxd2x6b2wgpbxvw88h5w6mujoqtuq Fruitcake jelly beans candy canes icing pastry liquorice. Bear claw tart chocolate sweet soufflé sweet roll marshmallow ice cream liquorice. +9xcjy4nvh1jinka64lkdr1nhagm8odp0frr56nks Bear claw tootsie roll toffee biscuit cotton candy macaroon. +5rmcwguz3jzws8w1hh2jbfdau74jip3f8rbu10oy Pudding caramels carrot cake sweet roll danish oat cake. +s50wqctf9059ets5ezp4oeq7p6pfr24ntww2d15v Oat cake macaroon pastry cheesecake. Dessert topping chocolate bar. +vue3y73jcwsg5um4pw8aqhuv3njgtg9iq0ortx5p Sesame snaps candy canes muffin lollipop wafer. +1o6edje4xcb7vtcvct4ghawafdvmvgkx4r0scny5 Macaroon pudding gingerbread. +``` + +----- + +本系列内容依据[CC BY-SA 4.0](https://creativecommons.org/licenses/by-sa/4.0/)许可证进行授权 \ No newline at end of file diff --git a/docs/loenn/basic_configurations.md b/docs/Coding/loenn/basic_configurations.md similarity index 100% rename from docs/loenn/basic_configurations.md rename to docs/Coding/loenn/basic_configurations.md diff --git a/docs/loenn/effect_structs.md b/docs/Coding/loenn/effect_structs.md similarity index 100% rename from docs/loenn/effect_structs.md rename to docs/Coding/loenn/effect_structs.md diff --git a/docs/loenn/entity_structs.md b/docs/Coding/loenn/entity_structs.md similarity index 100% rename from docs/loenn/entity_structs.md rename to docs/Coding/loenn/entity_structs.md diff --git a/docs/loenn/folder_structure.md b/docs/Coding/loenn/folder_structure.md similarity index 100% rename from docs/loenn/folder_structure.md rename to docs/Coding/loenn/folder_structure.md diff --git a/docs/loenn/nodes.md b/docs/Coding/loenn/nodes.md similarity index 100% rename from docs/loenn/nodes.md rename to docs/Coding/loenn/nodes.md diff --git a/docs/loenn/rendering.md b/docs/Coding/loenn/rendering.md similarity index 100% rename from docs/loenn/rendering.md rename to docs/Coding/loenn/rendering.md diff --git a/docs/loenn/trigger_structs.md b/docs/Coding/loenn/trigger_structs.md similarity index 100% rename from docs/loenn/trigger_structs.md rename to docs/Coding/loenn/trigger_structs.md diff --git a/docs/misc/GhostLand.gif b/docs/Coding/misc/GhostLand.gif similarity index 100% rename from docs/misc/GhostLand.gif rename to docs/Coding/misc/GhostLand.gif diff --git a/docs/misc/change_log.md b/docs/Coding/misc/change_log.md similarity index 100% rename from docs/misc/change_log.md rename to docs/Coding/misc/change_log.md diff --git a/docs/misc/to_do_list.md b/docs/Coding/misc/to_do_list.md similarity index 100% rename from docs/misc/to_do_list.md rename to docs/Coding/misc/to_do_list.md diff --git a/docs/misc/what.md b/docs/Coding/misc/what.md similarity index 100% rename from docs/misc/what.md rename to docs/Coding/misc/what.md diff --git a/docs/resources/CelesteModTutorial.zip b/docs/Coding/resources/CelesteModTutorial.zip similarity index 100% rename from docs/resources/CelesteModTutorial.zip rename to docs/Coding/resources/CelesteModTutorial.zip diff --git a/src/CelesteModTutorial/Dialog/English.txt b/docs/Coding/src/CelesteModTutorial/Dialog/English.txt similarity index 100% rename from src/CelesteModTutorial/Dialog/English.txt rename to docs/Coding/src/CelesteModTutorial/Dialog/English.txt diff --git a/src/CelesteModTutorial/Dialog/Simplified Chinese.txt b/docs/Coding/src/CelesteModTutorial/Dialog/Simplified Chinese.txt similarity index 100% rename from src/CelesteModTutorial/Dialog/Simplified Chinese.txt rename to docs/Coding/src/CelesteModTutorial/Dialog/Simplified Chinese.txt diff --git a/src/CelesteModTutorial/Graphics/Atlases/Gameplay/objects/PassByRefill/pass_by_refill.png b/docs/Coding/src/CelesteModTutorial/Graphics/Atlases/Gameplay/objects/PassByRefill/pass_by_refill.png similarity index 100% rename from src/CelesteModTutorial/Graphics/Atlases/Gameplay/objects/PassByRefill/pass_by_refill.png rename to docs/Coding/src/CelesteModTutorial/Graphics/Atlases/Gameplay/objects/PassByRefill/pass_by_refill.png diff --git a/src/CelesteModTutorial/Loenn/entities/PassByRefill.lua b/docs/Coding/src/CelesteModTutorial/Loenn/entities/PassByRefill.lua similarity index 100% rename from src/CelesteModTutorial/Loenn/entities/PassByRefill.lua rename to docs/Coding/src/CelesteModTutorial/Loenn/entities/PassByRefill.lua diff --git a/src/CelesteModTutorial/Loenn/entities/PassByRefillWithTexture.lua b/docs/Coding/src/CelesteModTutorial/Loenn/entities/PassByRefillWithTexture.lua similarity index 100% rename from src/CelesteModTutorial/Loenn/entities/PassByRefillWithTexture.lua rename to docs/Coding/src/CelesteModTutorial/Loenn/entities/PassByRefillWithTexture.lua diff --git a/src/CelesteModTutorial/Loenn/lang/en_gb.lang b/docs/Coding/src/CelesteModTutorial/Loenn/lang/en_gb.lang similarity index 100% rename from src/CelesteModTutorial/Loenn/lang/en_gb.lang rename to docs/Coding/src/CelesteModTutorial/Loenn/lang/en_gb.lang diff --git a/src/CelesteModTutorial/Loenn/triggers/SetPassByRefillDashesTrigger.lua b/docs/Coding/src/CelesteModTutorial/Loenn/triggers/SetPassByRefillDashesTrigger.lua similarity index 100% rename from src/CelesteModTutorial/Loenn/triggers/SetPassByRefillDashesTrigger.lua rename to docs/Coding/src/CelesteModTutorial/Loenn/triggers/SetPassByRefillDashesTrigger.lua diff --git a/src/CelesteModTutorial/Maps/CelesteModTutorial/Test.bin b/docs/Coding/src/CelesteModTutorial/Maps/CelesteModTutorial/Test.bin similarity index 100% rename from src/CelesteModTutorial/Maps/CelesteModTutorial/Test.bin rename to docs/Coding/src/CelesteModTutorial/Maps/CelesteModTutorial/Test.bin diff --git a/src/CelesteModTutorial/Source/.everestignore b/docs/Coding/src/CelesteModTutorial/Source/.everestignore similarity index 100% rename from src/CelesteModTutorial/Source/.everestignore rename to docs/Coding/src/CelesteModTutorial/Source/.everestignore diff --git a/src/CelesteModTutorial/Source/CelesteMod.props b/docs/Coding/src/CelesteModTutorial/Source/CelesteMod.props similarity index 100% rename from src/CelesteModTutorial/Source/CelesteMod.props rename to docs/Coding/src/CelesteModTutorial/Source/CelesteMod.props diff --git a/src/CelesteModTutorial/Source/CelesteMod.targets b/docs/Coding/src/CelesteModTutorial/Source/CelesteMod.targets similarity index 100% rename from src/CelesteModTutorial/Source/CelesteMod.targets rename to docs/Coding/src/CelesteModTutorial/Source/CelesteMod.targets diff --git a/src/CelesteModTutorial/Source/CelesteModTutorial.csproj b/docs/Coding/src/CelesteModTutorial/Source/CelesteModTutorial.csproj similarity index 100% rename from src/CelesteModTutorial/Source/CelesteModTutorial.csproj rename to docs/Coding/src/CelesteModTutorial/Source/CelesteModTutorial.csproj diff --git a/src/CelesteModTutorial/Source/CelesteModTutorialModule.cs b/docs/Coding/src/CelesteModTutorial/Source/CelesteModTutorialModule.cs similarity index 100% rename from src/CelesteModTutorial/Source/CelesteModTutorialModule.cs rename to docs/Coding/src/CelesteModTutorial/Source/CelesteModTutorialModule.cs diff --git a/src/CelesteModTutorial/Source/CelesteModTutorialSaveData.cs b/docs/Coding/src/CelesteModTutorial/Source/CelesteModTutorialSaveData.cs similarity index 100% rename from src/CelesteModTutorial/Source/CelesteModTutorialSaveData.cs rename to docs/Coding/src/CelesteModTutorial/Source/CelesteModTutorialSaveData.cs diff --git a/src/CelesteModTutorial/Source/CelesteModTutorialSession.cs b/docs/Coding/src/CelesteModTutorial/Source/CelesteModTutorialSession.cs similarity index 100% rename from src/CelesteModTutorial/Source/CelesteModTutorialSession.cs rename to docs/Coding/src/CelesteModTutorial/Source/CelesteModTutorialSession.cs diff --git a/src/CelesteModTutorial/Source/CelesteModTutorialSettings.cs b/docs/Coding/src/CelesteModTutorial/Source/CelesteModTutorialSettings.cs similarity index 100% rename from src/CelesteModTutorial/Source/CelesteModTutorialSettings.cs rename to docs/Coding/src/CelesteModTutorial/Source/CelesteModTutorialSettings.cs diff --git a/src/CelesteModTutorial/Source/Entities/PassByRefill.cs b/docs/Coding/src/CelesteModTutorial/Source/Entities/PassByRefill.cs similarity index 100% rename from src/CelesteModTutorial/Source/Entities/PassByRefill.cs rename to docs/Coding/src/CelesteModTutorial/Source/Entities/PassByRefill.cs diff --git a/src/CelesteModTutorial/Source/Entities/PassByRefillWithTexture.cs b/docs/Coding/src/CelesteModTutorial/Source/Entities/PassByRefillWithTexture.cs similarity index 100% rename from src/CelesteModTutorial/Source/Entities/PassByRefillWithTexture.cs rename to docs/Coding/src/CelesteModTutorial/Source/Entities/PassByRefillWithTexture.cs diff --git a/src/CelesteModTutorial/Source/Triggers/SetPassByRefillDashesTrigger.cs b/docs/Coding/src/CelesteModTutorial/Source/Triggers/SetPassByRefillDashesTrigger.cs similarity index 100% rename from src/CelesteModTutorial/Source/Triggers/SetPassByRefillDashesTrigger.cs rename to docs/Coding/src/CelesteModTutorial/Source/Triggers/SetPassByRefillDashesTrigger.cs diff --git a/src/CelesteModTutorial/everest.yaml b/docs/Coding/src/CelesteModTutorial/everest.yaml similarity index 100% rename from src/CelesteModTutorial/everest.yaml rename to docs/Coding/src/CelesteModTutorial/everest.yaml diff --git a/docs/CustomMusic/index.md b/docs/CustomMusic/index.md new file mode 100644 index 0000000..8c72c96 --- /dev/null +++ b/docs/CustomMusic/index.md @@ -0,0 +1 @@ +filler \ No newline at end of file diff --git a/docs/Mapping/index.md b/docs/Mapping/index.md new file mode 100644 index 0000000..8c72c96 --- /dev/null +++ b/docs/Mapping/index.md @@ -0,0 +1 @@ +filler \ No newline at end of file diff --git a/docs/extra/cmcc/index.md b/docs/extra/cmcc/index.md deleted file mode 100644 index efcfd2e..0000000 --- a/docs/extra/cmcc/index.md +++ /dev/null @@ -1,5 +0,0 @@ -# CMCC - -欢迎来到这个额外章节, 不过这里不是一个新主题, 只是一个由 [ForkKILLET](https://github.com/ForkKILLET) 建立的仓库 [CelesteMapperCooperationInChina](https://github.com/ForkKILLET/CelesteMapperCooperationInChina) (CMCC) 的一个网页呈现. - -源 github 仓库: [https://github.com/ForkKILLET/CelesteMapperCooperationInChina](https://github.com/ForkKILLET/CelesteMapperCooperationInChina) \ No newline at end of file diff --git a/docs/extra/cmcc/remote b/docs/extra/cmcc/remote deleted file mode 160000 index bb773b2..0000000 --- a/docs/extra/cmcc/remote +++ /dev/null @@ -1 +0,0 @@ -Subproject commit bb773b2d21a819cf68aee269df07d250ba062f4b diff --git a/docs/index.md b/docs/index.md index 74a4d95..4a8b7df 100644 --- a/docs/index.md +++ b/docs/index.md @@ -1,54 +1,3 @@ # 首页 -本系列教程主要写自于个人在制作蔚蓝 CodeMod 的一些经验 -本网站内容开源在: [github.com/Saplonily/CelesteModTutorial](https://github.com/Saplonily/CelesteModTutorial) -十分欢迎来提 pr 和 issue 以修复各种语法错误, 用词错误和内容错误以及建议_(:з」∠)_ - -大部分文章可能会写的不明不白以至于需要频繁修改, 如果你有更好的修改建议的话欢迎来提 issue. - -那么一切就绪, 可以开始阅读 入门-第一节 了: - -[开始 - Celeste Everest MonoMod](basics/celeste_everest_monomod.md) - -顺便感谢一些为本教程贡献的人: - -- AppleSheep - 在写作初期提供了大量修改建议 目前正在维护整个教程([Bilibili](https://space.bilibili.com/227488539)) -- 夜谷紫幽 - 为配置环境节提供了使用模板的建议 ([Bilibili](https://space.bilibili.com/346379712)) -- 电箱 - 制作了包含基础 Loenn 使用教程的作图教程 ([Bilibili](https://space.bilibili.com/240308518)) -- Lucky boy - [Session, Settings, SaveData](basics/session_settings_savedata.md) 节的一些补充, 以及钩取 Helper 方法, debug, tracker, flag, tag 节的作者 ([GitHub](https://github.com/LuckyBoy-7)) - -以及我自己 :D - -- Saplonily ([Bilibili](https://space.bilibili.com/39046375), [Outlook](mailto:Saplonily@outlook.com)) - -以及教程大部分内容的来源: - -- [Everest Wiki](https://github.com/EverestAPI/Resources/wiki/Code-Mod-Setup) - -和一切的基础: - -- [Celeste](https://www.celestegame.com/) -- [Everest API](https://github.com/EverestAPI) - ----- - -在网站中的代码块中的一些高亮在横向滚动时会发生截断, 即高亮并没有覆盖整行, 这个是 `mkdocs-material` 自身的 bug, 而且看上去说是修复起来很困难, -issue 链接: [mkdocs-material issue #452](https://github.com/squidfunk/mkdocs-material/issues/452). - -bug 于下: -``` hl_lines="1 2 3 4" -t11ntpj808mbc1gu4lx7n9d8tj5q3ck3t1c0aclc Liquorice oat cake carrot cake. Halvah lemon drops bear claw fruitcake. Marshmallow danish jelly-o toffee. -jqlksiohper0brg9x2ajcm7ajjf8ptjxprqstvda Apple pie cake jelly-o sugar plum. -x3mjly0wn48wy7lgf2bfymbykommv8dbyp7an1n8 Toffee candy brownie carrot cake jujubes sweet roll chocolate gingerbread. -q0b5pj6eacuwj3t1i4jv7yxf00mi6osc0h5etcfz Cupcake tiramisu danish brownie danish jujubes gingerbread toffee gummi bears. -u25qzla31ahqxd2x6b2wgpbxvw88h5w6mujoqtuq Fruitcake jelly beans candy canes icing pastry liquorice. Bear claw tart chocolate sweet soufflé sweet roll marshmallow ice cream liquorice. -9xcjy4nvh1jinka64lkdr1nhagm8odp0frr56nks Bear claw tootsie roll toffee biscuit cotton candy macaroon. -5rmcwguz3jzws8w1hh2jbfdau74jip3f8rbu10oy Pudding caramels carrot cake sweet roll danish oat cake. -s50wqctf9059ets5ezp4oeq7p6pfr24ntww2d15v Oat cake macaroon pastry cheesecake. Dessert topping chocolate bar. -vue3y73jcwsg5um4pw8aqhuv3njgtg9iq0ortx5p Sesame snaps candy canes muffin lollipop wafer. -1o6edje4xcb7vtcvct4ghawafdvmvgkx4r0scny5 Macaroon pudding gingerbread. -``` - ------ - -本系列内容依据[CC BY-SA 4.0](https://creativecommons.org/licenses/by-sa/4.0/)许可证进行授权 \ No newline at end of file +filler \ No newline at end of file diff --git a/mkdocs.yml b/mkdocs.yml index b30e4b9..076173f 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -58,67 +58,68 @@ markdown_extensions: nav: - 首页: "index.md" - - 一些准备: - - 基础环境配置: "coding_setup/basic_env.md" - - 调试: "coding_setup/debug.md" - - 阅读代码: "coding_setup/code_reading.md" - - 基础: - - Celeste, Everest, MonoMod: "basics/celeste_everest_monomod.md" - - 更多EC: "basics/ec_common.md" - - Flag, Tag, Tracker: "basics/flag_tag_tracker.md" - - Session, Settings, SaveData: "basics/session_settings_savedata.md" - - 进阶: - - 跨 Mod 交互: "advanced/cross_mod_interactions.md" - # - Loenn: - # - Loenn 目录结构: "loenn/folder_structure.md" - # - Loenn 基础配置: "loenn/basic_configurations.md" - # - Entity 结构: "loenn/entity_structs.md" - # - Trigger 结构: "loenn/trigger_structs.md" - # - Loenn 绘制: "loenn/rendering.md" - # - Loenn 节点: "loenn/nodes.md" - # - Effect 结构: "loenn/effect_structs.md" - - 实战: - - 测试地图: "coding_challenges/test_map.md" - - 简单自定义实体: "coding_challenges/simple_entity.md" - - 简单自定义Trigger: "coding_challenges/simple_trigger.md" - - 简单贴图: "coding_challenges/simple_texturing.md" - - 钩子: - - 钩子: "hooks/hook.md" - - IL: "hooks/il.md" - - IL 钩子与随意钩取: "hooks/adv_hooks.md" - - 协程的钩取与私有成员访问: "hooks/adv_hooks2.md" - - 组件: - - Sprite, Image: "components/sprite_image.md" - - Alarm, Tween, Coroutine: "components/alarm_tween_coroutine.md" - - StateMachine: "components/statemachine.md" - - 额外: - - CMCC: - - 首页: "extra/cmcc/index.md" - - readme: "extra/cmcc/remote/ReadMe.md" - - FAQ: "extra/cmcc/remote/todo.md" - - XML: - - XML 简单介绍: "extra/xml/xml_speedrun.md" - - Lua: - - 开始: "extra/lua/begin.md" - - 基本语法: "extra/lua/syntax.md" - - 数据类型: "extra/lua/data_type.md" - - 流程控制: "extra/lua/control_flow.md" - - 运算符: "extra/lua/operator.md" - - 迭代器: "extra/lua/iterator.md" - - 模块: "extra/lua/module.md" - - 标准库: "extra/lua/standard_library.md" - - LuaCutscene: - - 开始: "extra/lua_cutscene/begin.md" - - 参考: "extra/lua_cutscene/reference.md" - - C# 交互: "extra/lua_cutscene/cs_access.md" - - 例子: "extra/lua_cutscene/examples.md" - - - 历史归档: - - 基础环境配置: "arc/basic_env.md" - - 通过模板创建项目: "arc/project_template.md" - - 偏好: "arc/preference.md" - - 偏好-sdk-styled-proj: "arc/sdk-styled-proj.md" - - 杂项: - - ChangeLog: "misc/change_log.md" - - ToDoList: "misc/to_do_list.md" -# - What: "misc/what.md" \ No newline at end of file + - Mapping: + - 首页: "Mapping/index.md" + - Codeing: + - 首页: "Coding/index.md" + - 一些准备: + - 基础环境配置: "Coding/coding_setup/basic_env.md" + - 调试: "Coding/coding_setup/debug.md" + - 阅读代码: "Coding/coding_setup/code_reading.md" + - 基础: + - Celeste, Everest, MonoMod: "Coding/basics/celeste_everest_monomod.md" + - 更多EC: "Coding/basics/ec_common.md" + - Flag, Tag, Tracker: "Coding/basics/flag_tag_tracker.md" + - Session, Settings, SaveData: "Coding/basics/session_settings_savedata.md" + - 进阶: + - 跨 Mod 交互: "Coding/advanced/cross_mod_interactions.md" + # - Loenn: + # - Loenn 目录结构: "loenn/folder_structure.md" + # - Loenn 基础配置: "loenn/basic_configurations.md" + # - Entity 结构: "loenn/entity_structs.md" + # - Trigger 结构: "loenn/trigger_structs.md" + # - Loenn 绘制: "loenn/rendering.md" + # - Loenn 节点: "loenn/nodes.md" + # - Effect 结构: "loenn/effect_structs.md" + - 实战: + - 测试地图: "Coding/coding_challenges/test_map.md" + - 简单自定义实体: "Coding/coding_challenges/simple_entity.md" + - 简单自定义Trigger: "Coding/coding_challenges/simple_trigger.md" + - 简单贴图: "Coding/coding_challenges/simple_texturing.md" + - 钩子: + - 钩子: "Coding/hooks/hook.md" + - IL: "Coding/hooks/il.md" + - IL 钩子与随意钩取: "Coding/hooks/adv_hooks.md" + - 协程的钩取与私有成员访问: "Coding/hooks/adv_hooks2.md" + - 组件: + - Sprite, Image: "Coding/components/sprite_image.md" + - Alarm, Tween, Coroutine: "Coding/components/alarm_tween_coroutine.md" + - StateMachine: "Coding/components/statemachine.md" + - 额外: + - XML: + - XML 简单介绍: "Coding/extra/xml/xml_speedrun.md" + - Lua: + - 开始: "Coding/extra/lua/begin.md" + - 基本语法: "Coding/extra/lua/syntax.md" + - 数据类型: "Coding/extra/lua/data_type.md" + - 流程控制: "Coding/extra/lua/control_flow.md" + - 运算符: "Coding/extra/lua/operator.md" + - 迭代器: "Coding/extra/lua/iterator.md" + - 模块: "Coding/extra/lua/module.md" + - 标准库: "Coding/extra/lua/standard_library.md" + - LuaCutscene: + - 开始: "Coding/extra/lua_cutscene/begin.md" + - 参考: "Coding/extra/lua_cutscene/reference.md" + - C# 交互: "Coding/extra/lua_cutscene/cs_access.md" + - 例子: "Coding/extra/lua_cutscene/examples.md" + - 历史归档: + - 基础环境配置: "Coding/arc/basic_env.md" + - 通过模板创建项目: "Coding/arc/project_template.md" + - 偏好: "Coding/arc/preference.md" + - 偏好-sdk-styled-proj: "Coding/arc/sdk-styled-proj.md" + - 杂项: + - ChangeLog: "Coding/misc/change_log.md" + - ToDoList: "Coding/misc/to_do_list.md" + # - What: "Coding/misc/what.md" + - CustomMusic: + - 首页: "CustomMusic/index.md" \ No newline at end of file