
智能食谱
一个扩展配方格式并加入条件的Fabric模组。

Smart Recipes
你觉得原版 Minecraft 的合成配方格式很无聊吗?或者你希望让游戏更偏向事件驱动,像 Terraria 那样?如果是这样,Smart Recipes 正是你需要的!用我们全新的条件配方格式,打造属于你自己的独特体验吧!
格式
如果你更喜欢看实际示例而不是解释,可以直接跳到 示例 部分。但别忘了之后回来查看 条件 和 重载条件 部分。
条件格式
Smart Recipes 模组扩展了原版配方格式。理解原版格式的工作方式至关重要,否则下面的说明可能难以理解。
此模组为配方格式引入了一个新的 smart_recipes:conditions 属性。它与战利品表中的条件有些类似。让我们仔细看看:
"smart_recipes:conditions": []
此属性决定配方加载所需的条件。如果指定了多个条件,则必须全部通过。
"smart_recipes:conditions": [
{
"condition": "conditionName0",
"args": [
// 传递给名为 `conditionName0` 的某个条件的参数。
4,
"2"
]
},
{
"condition": "conditionName1",
"args": [
// 传递给名为 `conditionName1` 的某个条件的参数。
"foo"
]
}
]
此示例与战利品表中条件的通常写法完全相同。但我觉得它们太冗长了。让我们看看如何改进我们的条件。
// 把这样的条件声明:
{
"condition": "conditionName1",
"args": [
"foo"
]
}
// 变成这样:
"conditionName1": ["foo"]
好多了,你不觉得吗?
"smart_recipes:conditions": [
{
"conditionName0": [4, "2"]
},
{
"conditionName1": ["foo"]
}
]
这比以前更好了,但仍有改进的空间。让我们把条件合并到单个对象中:
"smart_recipes:conditions": [
{
"conditionName0": [4, "2"],
"conditionName1": ["foo"]
}
]
最后,如果数组只包含一个对象,Smart Recipes 模组允许省略它的声明。以下是最终结果:
"smart_recipes:conditions": {
"conditionName0": [4, "2"],
"conditionName1": "foo"
}
我需要说明的是,Smart Recipes 可以解析上述每一个示例,所以你可以选择你喜欢的风格。
重载条件格式
重载条件允许在不同的时机重新评估配方条件。如果你的配方依赖于天气、时间或其他易变实体,这会很有用。
这个过程非常简单。你只需要提供配方所依赖的重载条件名称:
"smart_recipes:reload_conditions": [
"weather_changed",
"time_changed"
]
条件
false
不需要参数,始终返回 false。
"smart_recipes:conditions": [
"false"
]
true
不需要参数,始终返回 true。
"smart_recipes:conditions": [
"true"
]
or 和 any
如果指定的任一条件返回 true,则返回 true。
"smart_recipes:conditions": {
"or": [
{ "false": {} },
false,
"true"
]
}
and 和 all
如果指定的所有条件都返回 true,则返回 true。
"smart_recipes:conditions": {
"and": {
"true": {},
"false": null
}
}
not 和 none
如果指定的所有条件都不返回 true,则返回 true。
"smart_recipes:conditions": {
"not": {
"false": null
}
}
is_hardcore
不需要参数,如果服务器处于极限模式,则返回 true。
"smart_recipes:conditions": {
"not": "is_hardcore"
}
is_peaceful_difficulty
不需要参数,如果当前难度为和平,则返回 true。
"smart_recipes:conditions": {
"or": [
"is_peaceful_difficulty",
"is_hardcore"
]
}
is_easy_difficulty
不需要参数,如果当前难度为简单,则返回 true。
"smart_recipes:conditions": {
"not": ["is_easy_difficulty"]
}
is_normal_difficulty
不需要参数,如果当前难度为普通,则返回 true。
"smart_recipes:conditions": "is_normal_difficulty"
is_hard_difficulty
不需要参数,如果当前难度为困难,则返回 true。
"smart_recipes:conditions": {
"is_hard_difficulty": null
}
difficulty_check
如果指定的值之一与当前难度匹配,则返回 true。
"smart_recipes:conditions": {
"difficulty_check": [
0, // 和平难度的序号
1, // 简单难度的序号
2, // 普通难度的序号
3, // 困难难度的序号
"peaceful",
"easy",
"normal",
"HarD" // 大小写无关
]
}
is_survival
不需要参数,如果默认游戏模式为生存,则返回 true。
"smart_recipes:conditions": "is_survival"
is_creative
不需要参数,如果默认游戏模式为创造,则返回 true。
"smart_recipes:conditions": ["is_creative"]
is_adventure
不需要参数,如果默认游戏模式为冒险,则返回 true。
"smart_recipes:conditions": {
"is_adventure": {}
}
is_spectator
不需要参数,如果默认游戏模式为旁观,则返回 true。
"smart_recipes:conditions": {
"not": "is_spectator"
}
gamemode_check
如果指定的值之一与默认游戏模式匹配,则返回 true。
"smart_recipes:conditions": {
"gamemode_check": [
0, // 生存游戏模式的序号
1, // 创造游戏模式的序号
2, // 冒险游戏模式的序号
3, // 旁观游戏模式的序号
"survival",
"creative",
"adventure",
"SpEcTaToR" // 大小写无关
]
}
weather_check
如果指定的字符串之一与主世界维度中的当前天气匹配,则返回 true。
"smart_recipes:conditions": {
"weather_check": [
"clear", // 天气晴朗
"rain", // 正在下雨或雷暴
"thunder" // 正在雷暴
]
}
time_check
如果指定的字符串之一与主世界维度中的当前时间匹配,则返回 true。
"smart_recipes:conditions": {
"time_check": [
"day", // 从 1000 到 12999 tick
"noon", // 从 5000 到 6999 tick
"sunset", // 从 11000 到 12999 tick
"midnight", // 从 17000 到 18999 tick
"sunrise", // 从 22000 到 23999 tick
"night" // 从 13000 到 23999 tick,从 0 到 999 tick
]
}
players_online
如果所有指定的玩家都在线,则返回 true。
"smart_recipes:conditions": {
"players_online": [
"Notch",
"Dinnerbone",
"jeb_"
]
}
blocks_registered
如果所有指定的方块都已注册,则返回 true。
"smart_recipes:conditions": {
"blocks_registered": [
"stone",
"minecraft:dirt",
"aether:aether_dirt"
]
}
items_registered
如果所有指定的物品都已注册,则返回 true。
"smart_recipes:conditions": {
"items_registered": [
"stone",
"minecraft:dirt",
"aether:aether_dirt"
]
}
block_entities_registered
如果所有指定的方块实体都已注册,则返回 true。
"smart_recipes:conditions": {
"block_entities_registered": [
"furnance",
"minecraft:chest",
"aether:incubator"
]
}
entries_registered
如果所有指定的注册表项都已注册,则返回 true。
"smart_recipes:conditions": {
"entries_registered": [
{
"registry": "block",
"entry": "stone"
},
"minecraft:dirt", // `registry` 的默认值为 "block",
{
"registry": "item",
"entry": "aether:incubator"
},
{
"entry": "air" // `registry` 的默认值为 "block",
}
]
}
fabric:mods_loaded
如果所有指定的模组都已加载,则返回 true。
"smart_recipes:conditions": {
"fabric:mods_loaded": [
{
"id": "smart-recipes",
"version": "1.0"
},
"fabric-transfer-api-v1", // `version` 的默认值为 "*"
{
"id": "fabric-command-api-v1" // `version` 的默认值为 "*"
}
]
}
重载条件
player_joined 和 player_disconnected
当玩家加入或断开与服务器的连接时重载配方。
"smart_recipes:conditions": {
"not": {
"players_online": "Nickname"
}
},
"smart_recipes:reload_conditions": [
"player_joined",
"player_disconnected"
]
difficulty_changed
当当前难度改变时重载配方。
"smart_recipes:conditions": "is_easy_difficulty",
"smart_recipes:reload_conditions": "difficulty_changed"
gamemode_changed
当默认游戏模式改变时重载配方。
"smart_recipes:conditions": {
"gamemode_check": [
"survival",
"creative"
]
},
"smart_recipes:reload_conditions": ["gamemode_changed"]
weather_changed
当当前天气改变时重载配方。
"smart_recipes:conditions": {
"weather_check": "thunder"
},
"smart_recipes:reload_conditions": "weather_changed"
time_changed
当当前时间改变时重载配方。
"smart_recipes:conditions": {
"time_check": [
"noon",
"midnight"
]
},
"smart_recipes:reload_conditions": [
"time_changed"
]
示例
考虑一个场景:我们想添加一个简化的 TNT 配方:
{
"type": "minecraft:crafting_shaped",
"pattern": [
"# X",
" ",
"X #"
],
"key": {
"#": {
"item": "minecraft:sand"
},
"X": {
"item": "minecraft:gunpowder"
}
},
"result": {
"item": "minecraft:tnt"
}
}
现在,让我们添加一些条件。以下是我们的目标:
- 此配方应仅在
midnight(午夜)和sunrise(日出)时可用,因为没人在大白天制作炸药。 - 此配方应仅在
weather is clear(天气晴朗)时可用,以防止火药受潮。 - 当
Vladimir is online(Vladimir 在线)时,此配方应not(不)可用,因为我们不放心把致命武器交给 Vladimir。 - 此配方应仅在
hard(困难)难度下可用,因为……为什么不呢?
是时候将我们的计划付诸行动了:
{
// 与上面相同的部分,这里没什么有趣的
"type": "minecraft:crafting_shaped",
"pattern": [
"# X",
" ",
"X #"
],
"key": {
"#": {
"item": "minecraft:sand"
},
"X": {
"item": "minecraft:gunpowder"
}
},
"result": {
"item": "minecraft:tnt"
},
// 有趣的部分开始了。
// 我们需要在 `conditions` 部分描述加载此配方所需的条件。
// 如果指定了多个条件,则必须全部通过。
"smart_recipes:conditions": {
// #1
"time_check": [
"midnight",
"sunrise"
],
// #2
// 注意 `weather_check` 通常接收一个数组(就像 `time_check` 一样),
// 但由于我们只需要传递一个值,所以可以省略。
"weather_check": "clear",
// #3
"not": {
// 这里也可以省略数组声明,但
// 我保留它是为了说明这并非必须。
"players_online": ["Vladimir"]
},
// #4
// 可以替换为:
// - `"is_hard_difficulty": null`
// - `"is_hard_difficulty"`(在数组中)
// - `{ "condition": "is_hard_difficulty" }`(在数组中)
// - `{ "condition": "difficulty_check", "args": ["hard"] }`(在数组中)
"difficulty_check": "hard"
},
// 默认情况下,条件仅在服务器启动时评估。
// 所以,如果我们想让配方与游戏的实际状态保持同步,
// 就需要添加 `reload_conditions`。
"smart_recipes:reload_conditions": [
// #1
// 当时间改变时重载配方。
"time_changed",
// #2
// 当天气改变时重载配方。
"weather_changed",
// #3
// 这些会在玩家加入或断开与服务器的连接时重载配方。
// 我将来可能会把这两个合并为一个。
"player_joined",
"player_disconnected",
// #4
// 当难度改变时重载配方。
// 说实话,我觉得你并不真的需要它,
// 因为大多数服务器的难度是锁定的,
// 所以只在服务器启动时评估基于难度的条件也没问题。
"difficulty_changed"
]
}
安装
要求:
- Minecraft
>=1.17.x - Fabric Loader
>=0.11.3 - Fabric API
>=0.35.0
你可以从以下途径下载此模组:
- GitHub Releases
- Modrinth
- CurseForge
- GitHub Actions (这些构建可能不稳定,但它们代表了开发的实际状态)
用作依赖项
你可以将 Smart Recipes 包含在你的模组中,以使用新的条件格式,而无需玩家单独下载它。
build.gradle:
repositories {
maven {
name = "Modrinth"
url = "https://api.modrinth.com/maven"
content {
includeGroup "maven.modrinth"
}
}
}
dependencies {
modImplementation "maven.modrinth:smart-recipes:${project.smart_recipes_version}"
}
gradle.properties:
smart_recipes_version=/* 在此填入最新版本 */
从源码构建
要求:
- JDK
17
Linux/MacOS
git clone https://github.com/Kir-Antipov/smart-recipes.git
cd smart-recipes
chmod +x ./gradlew
./gradlew build
cd build/libs
Windows
git clone https://github.com/Kir-Antipov/smart-recipes.git
cd smart-recipes
gradlew build
cd build/libs
正在加载版本记录…
正在加载评论…
评论在新手盒子客户端中发表,这里同步展示。