优秀

优秀

砍树也要有范儿

杂项

Axecellent

砍掉树干的底部,然后看着它散开——先从枝梢开始,一路拆回到你手中的方块。

哪把工具能使用它——以及砍树时树如何倒下——由物品标签决定,而非附魔。这些标签默认为空,因此整合包可以随心所欲地将链锯能力授予任何工具,并能让树的倒下方式成为玩家可以升级的内容。

Minecraft 1.21.1 · NeoForge


功能简介

使用链锯工具破坏一根原木,整棵相连的树都会倒下——但不是瞬间完成。砍伐从通过树木自身树枝最远的原木开始,沿着树枝一路切回,最后才落到你击中的那个方块上。每根原木都会带走它的树叶,因此树冠会随着支撑它的树枝一起瓦解。

这种渐进过程正是关键所在。大多数伐木模组让树瞬间消失;这个模组让你看着它倒下,并提供一种由你掌控的模式。

单独安装时它什么都不做。在授予标签之前,没有工具拥有链锯能力——参见 授予链锯能力。本模组是机制本身;由整合包决定哪种工具获得该能力。

砍伐模式

渐进

一次破坏即可在接下来的一两秒内让整棵树倒下,每游戏刻砍掉几根原木。一棵大云杉需要几秒钟;白桦几乎瞬间就能砍完。

手动

只有在你持续砍伐时,树才会散架。每次完成的砍伐会额外移除一根原木——而在两次砍伐之间,什么都不会发生。停止挥动,树就停在原处不再倒下。你的工具决定了节奏:石斧缓慢地磨过,而下界合金斧则能快速撕裂。

潜行可反转顺序。正常情况下,远端先被砍掉,砍伐方向朝你推进;潜行时,原木会从你面前的方块开始剥落——因此一次砍伐只移除你前方的原木,继续砍则会从那里逐步深入树木。需要精确控制时可以精确控制,不需要时则带给你壮观场面。

耐久度会按倒下的每个方块扣除,所以提前停止只会消耗你实际砍掉部分的耐久。

瞬间

整棵树在同一游戏刻内消失。适合不希望有华丽动画的服务器,或实现自动化树场的整合包。

选择模式

模式是工具的属性。将工具放入 #axecellent:chainsaw_held、#axecellent:chainsaw_progressive 或 #axecellent:chainsaw_instant 标签中,它将始终以该方式砍伐;放入普通的 #axecellent:chainsaw 标签则遵循 chainsaw.mode 设置。

这使得三种模式可以在一个整合包中共存。一把木斧需要你为每一根原木挥砍,一把铁斧一次挥击就能砍倒一棵树,一把下界合金斧在你松开按钮之前就已完工——同一棵树,三种不同体验,作为一种进度体系而非无人能见的服务器级开关。

渐进 和 手动 模式各自有独立的节奏配置——参见 配置。

前置要求

Minecraft 1.21.1
加载器 NeoForge 21.1.181 或更新版本
安装端 服务端——单人游戏视作服务端

所有操作均在服务端进行,因此客户端无需安装本模组。安装了本模组的客户端会在任何带有链锯标签的工具提示上显示其能力名称——拉绳启动链锯、强力链锯、涡轮链锯——以便玩家分辨哪把工具是特别的,以及他们拥有哪种类型。这些措辞可由你自行更改。

安装

  1. 为 1.21.1 安装 NeoForge。
  2. 将 jar 文件放入 mods/ 文件夹。
  3. 在多人服务器上,服务端需要安装本模组。客户端不需要。
  4. 将链锯能力授予一把工具——在此之前,什么都不会发生。

授予链锯能力

Axecellent 只问物品一个问题:它在四个工具标签中的哪一个?它如何到达那里由你决定。任何能向物品标签添加内容的方式都可以——数据包、KubeJS、其他模组、整合包生成脚本。

标签 效果
axecellent:chainsaw 能砍树,使用 chainsaw.mode 选择的模式
axecellent:chainsaw_progressive 始终以 渐进 模式砍伐
axecellent:chainsaw_held 始终以 手动 模式砍伐
axecellent:chainsaw_instant 始终以 瞬间 模式砍伐

模式标签本身已足够——放入其中一个模式标签的工具不需要同时放入普通标签。两种常见填充方式:

KubeJS 服务端脚本

位于 kubejs/server_scripts/ 中,使用 /reload 应用:

ServerEvents.tags('item', event => {
    event.add('axecellent:chainsaw', 'minecraft:iron_axe')
    event.add('axecellent:chainsaw_held', 'minecraft:wooden_axe')
    event.add('axecellent:chainsaw_instant', 'minecraft:netherite_axe')
})

数据包

位于 data/axecellent/tags/item/chainsaw.json(或 chainsaw_held.json 等):

{
  "values": [
    "minecraft:iron_axe"
  ]
}

使用 /kubejs list-tag item axecellent:chainsaw 检查是否生效,或者直接查看工具的提示。在纯原版中,/clear @s #axecellent:chainsaw 0 可以计算匹配物品数量而不移除任何东西。

三个常见的坑

  • 标签适用于物品类型,而非单个物品堆叠。给 minecraft:iron_axe 打上标签意味着所有铁斧都获得链锯能力,而非某一把特定的。
  • 不要将工具放入两个模式标签。如果发生了,最需要手动操作的模式优先——手动,然后渐进,然后瞬间——但这是决胜规则,不应依赖。
  • 移除条目仅在它是作为条目被添加时有效。如果某物是通过嵌套标签引用加入的——例如另一个包添加了 #minecraft:axes——你必须移除引用,而不是移除物品:event.remove('axecellent:chainsaw', '#minecraft:axes')。在这种情况下移除 minecraft:wooden_axe 会静默失败。

什么算作一棵树

两个方块标签,与工具标签不同,这些标签确实有默认值,因此模组树木通常无需任何配置即可正常工作。

标签 类型 默认值 控制
axecellent:chainsaw_logs 方块 #minecraft:logs 什么算作树干
axecellent:chainsaw_leaves 方块 #minecraft:leaves 哪些树叶会被清除

#minecraft:logs 也包含绯红和诡异菌柄,因此下界的“树木”也能被砍伐。如果你不希望如此,可以将它们从 axecellent:chainsaw_logs 中移除。

只有自然生长的树叶会被清除。玩家放置的树叶具有 persistent 属性,始终存活,这确保了无限制的树叶清除在建筑周围是安全的。

重命名工具提示

工具提示行是翻译键,而非内置文本,因此整合包可以随意措辞——包括使用其他语言,或者完全不显示。在资源包的 assets/axecellent/lang/en_us.json 中覆盖以下四个键:

键 默认文本 用于
axecellent.tooltip.chainsaw Chainsaw 普通标签,其模式由服务端决定
axecellent.tooltip.chainsaw.held Pull-Start Chainsaw #axecellent:chainsaw_held
axecellent.tooltip.chainsaw.progressive Power Chainsaw #axecellent:chainsaw_progressive
axecellent.tooltip.chainsaw.instant Turbo Chainsaw #axecellent:chainsaw_instant

它们是名称而非描述,并且等级递增:先是你持续拉动的启动款,然后是强力款,最后是涡轮款。这样玩家升级斧头时,会看到能力随之升级,就像它所取代的附魔一样。渐进 和 手动 永远不会出现——那些是配置值,玩家没有必要知道。

examples/resourcepack/ 中有一个现成的资源包——将其放入 resourcepacks/ 文件夹,或者将 lang 文件合并到你已有的包中。将键设置为 "" 可完全移除该行。

工具提示是客户端侧的,因此这是一个资源包而非服务端设置:它改变你的玩家看到的内容,而没有该资源包的客户端仍会显示默认文本。灰色样式和位置(最后一行)由模组决定;文字内容由你决定。

配置

config/axecellent-server.toml。这是一个服务端配置,因此在多人游戏中由服务端的副本决定,客户端无需任何配置。

只有当设置属于特定模式时,才会放在该模式的分区中。无论树以何种方式倒下都含义相同的所有设置都是全局的——一个 maxLogs,一个耐久度消耗值。

选项 默认值 含义
chainsaw.mode PROGRESSIVE 用于普通 #axecellent:chainsaw 标签中工具的模式。模式标签中的工具会忽略此选项
chainsaw.maxConcurrentCuts 32 服务器范围内同时进行中的砍树数量。超过此数量后,后续的树将立即砍完而不是排队
chainsaw.maxLogs 64 单次破坏最多能移除的原木数量
chainsaw.clearLeaves true 是否同时清除树叶
chainsaw.maxLeaves 0 树叶数量限制;0 表示无限制
chainsaw.requireLeaves false 仅砍伐附有树叶的原木群——开启以保护原木建筑
chainsaw.dropsAtBreakPosition true 掉落物出现在你的脚下,还是每个方块原位置
chainsaw.sneakToDisable true 潜行可打断单根原木的砍伐(手动模式覆盖此选项)
chainsaw.enabledInCreative false 在创造模式下使用链锯
chainsaw.respectBlockProtection true 允许领地或保护模组否决单个方块
durability.perLog 1 每额外砍掉一根原木消耗的耐久度;0 为免费
durability.chargeForLeaves false 是否也计算清除树叶的耐久度消耗
durability.stopBeforeBreak true 在工具于砍树中途损坏前停止

然后每个模式都有自己专门的分区,用于仅在该模式下有意义的设置——例如节奏,以及潜行的作用:

选项 默认值 含义
progressive.logsPerTick 2 每游戏刻砍伐的原木数量。树叶免费附带;2 值可使一棵 64 原木的树在约 1.6 秒内倒下
held.logsPerChop 1 每次完整挥砍移除的原木数量
held.resumeWindow 10 一棵部分砍伐的树等待你下一次挥砍的秒数
held.sneakStartsAtYou true 潜行反转砍伐顺序而非禁用链锯

瞬间 模式没有自己的分区:没有需要设定节奏的内容正是其“瞬间”的原因。

如果工具在砍树途中耐久耗尽,砍伐会停止,剩余部分保持原样。

在游戏中更改设置

需要管理员权限。更改会立即写入配置文件,因此重启后依然生效。

/axecellent config                       列出所有选项及其值
/axecellent config <option>              显示单个选项:值、默认值、范围、描述
/axecellent config <option> <value>     更改它
/axecellent config reset                 将所有设置恢复为默认值

选项名称是文件中的点分路径,例如 /axecellent config held.logsPerChop 2。超出选项范围的值会在写入前被拒绝,任何与默认值不同的项都会被高亮显示。更改会立即应用到进行中的砍伐,因此你可以一边观察砍伐过程一边调整设置。

面向整合包作者

将你的设置放入 defaultconfigs/axecellent-server.toml。两件值得知道的事:

  • 只列出你想更改的键。未列出的内容会从模组的默认值、注释等填充,这样你的文件保持简短,并且不会在新选项添加时过时。
  • 它只用于初始化新安装。当 config/ 中不存在该文件时,NeoForge 会将其复制过去。因此,它本身不会将更改后的值推送到已经运行过的服务器。要让整合包更新生效,你的更新程序必须替换 config/axecellent-server.toml。

多人游戏

砍伐操作由服务端权威处理,每个被移除的方块都经过普通玩家破坏的相同路径——包括每个方块的方块破坏事件,因此领地或保护模组可以单独否决它们。

每棵树同时只能有一个链锯砍伐进程。如果其他人正在砍你挥动的树,你的破坏将视为普通破坏,而他们的砍伐进程不受干扰地继续。

AI 声明

我使用我能力范围内最好的工具,这包括 AI 编码助手。但我不会袖手旁观,让它产出垃圾代码。每一行代码在发布前都经过我的阅读、检查和游玩测试。

我是一名专业程序员。我运营过许多公共 Minecraft 服务器,我理解 Minecraft 的实际工作原理,并且在这些工具出现之前我就已编写模组。助手不决定模组是什么、它应该如何运作、或哪些内容超出范围——那些由我决定。它做的是提升周围工作的标准:文档得以妥善编写,棘手情况得以覆盖,不会有半成品发布。

如果这里有什么损坏了,那由我来修复。提交 issue,我会处理的。

许可证

MIT。