🇨🇳 中文 (Chinese - China)
🇨🇳 中文 (Chinese - China)
外观
🇨🇳 中文 (Chinese - China)
🇨🇳 中文 (Chinese - China)
外观
本页面基于这个版本编写:
1.21.4
从 1.21 开始,Minecraft 中的自定义魔咒通过”数据驱动“的方式添加。 这让添加一些简单的魔咒(如增加攻击伤害)变得更容易,但创建复杂的魔咒则更具挑战性。 这个过程包括将魔咒分解成 效果组件。
效果组件包含定义魔咒特殊效果的代码。 Minecraft 原版已支持一些默认效果,例如物品损害值、击退和经验。
TIP
来看看 Minecraft Wiki 的附魔效果组件页面,检查 Minecraft 默认效果是否满足你的需求。 本指南假定你了解如何配置“简单”的数据驱动魔咒,并侧重于创建默认不支持的自定义魔咒效果。
先创建 enchanyments
文件夹,然后在里面创建 effect
文件夹。 在里面,创建记录类 LightningEnchantmentEffect
。
现在,创建构造器,并覆盖 EnchantmentEntityEffect
接口的方法。 还要创建 CODEC
变量以编码解码我们的效果,可以了解更多关于 codec 的信息。
我们的大部分代码都将进入 apply()
事件,当魔咒生效的条件得到满足时,该事件就会被调用。 我们稍后会配置这个 Effect
以在实体被击中时调用,但现在,让我们编写简单的代码来实现用闪电击中目标。
public record LightningEnchantmentEffect(EnchantmentLevelBasedValue amount) implements EnchantmentEntityEffect {
public static final MapCodec<LightningEnchantmentEffect> CODEC = RecordCodecBuilder.mapCodec(instance ->
instance.group(
EnchantmentLevelBasedValue.CODEC.fieldOf("amount").forGetter(LightningEnchantmentEffect::amount)
).apply(instance, LightningEnchantmentEffect::new)
);
@Override
public void apply(ServerWorld world, int level, EnchantmentEffectContext context, Entity target, Vec3d pos) {
if (target instanceof LivingEntity victim) {
if (context.owner() != null && context.owner() instanceof PlayerEntity player) {
float numStrikes = this.amount.getValue(level);
for (float i = 0; i < numStrikes; i++) {
BlockPos position = victim.getBlockPos();
EntityType.LIGHTNING_BOLT.spawn(world, position, SpawnReason.TRIGGERED);
}
}
}
}
@Override
public MapCodec<? extends EnchantmentEntityEffect> getCodec() {
return CODEC;
}
}
这里,变量 amount
表示与附魔等级成比例的数值。 我们可以根据等级来修改魔咒的效果。 在上面的代码中,我们使用附魔的等级来决定生成多少闪电。
就像我们的模组中的其他部分,我们将会把我们的 EnchantmentEffect
加入到 Minecraft 的注册表中。 为了实现这一点,添加一个叫做 ModEnchantmentEffects
(或者你想叫什么就叫什么)的类,和一个辅助方法来注册我们的魔咒。 确保在你的主类中调用 registerModEnchantmentEffects()
方法,这个主类应该包含 onInitialize()
方法。
public class ModEnchantmentEffects {
public static final RegistryKey<Enchantment> THUNDERING = of("thundering");
public static MapCodec<LightningEnchantmentEffect> LIGHTNING_EFFECT = register("lightning_effect", LightningEnchantmentEffect.CODEC);
private static RegistryKey<Enchantment> of(String path) {
Identifier id = Identifier.of(FabricDocsReference.MOD_ID, path);
return RegistryKey.of(RegistryKeys.ENCHANTMENT, id);
}
private static <T extends EnchantmentEntityEffect> MapCodec<T> register(String id, MapCodec<T> codec) {
return Registry.register(Registries.ENCHANTMENT_ENTITY_EFFECT_TYPE, Identifier.of(FabricDocsReference.MOD_ID, id), codec);
}
public static void registerModEnchantmentEffects() {
FabricDocsReference.LOGGER.info("Registering EnchantmentEffects for" + FabricDocsReference.MOD_ID);
}
}
现在我们有了一个魔咒效果! 最后一步是创建一个魔咒,应用我们自定义的效果。 这可以通过创建类似于 Minecraft 数据包中的 JSON 文件来实现,在这篇文档中,将向你展示如何使用 Fabric 的数据生成工具来动态生成 JSON。 要开始,请创建一个名为 EnchantmentGenerator
的类。
在这个类中,我们先注册我们的魔咒对象,并使用 configure()
方法来在程序中创建 JSON。
public class EnchantmentGenerator extends FabricDynamicRegistryProvider {
public EnchantmentGenerator(FabricDataOutput output, CompletableFuture<RegistryWrapper.WrapperLookup> registriesFuture) {
super(output, registriesFuture);
System.out.println("REGISTERING ENCHANTS");
}
@Override
protected void configure(RegistryWrapper.WrapperLookup registries, Entries entries) {
// Our new enchantment, "Thundering."
register(entries, ModEnchantmentEffects.THUNDERING, Enchantment.builder(
Enchantment.definition(
registries.getOrThrow(RegistryKeys.ITEM).getOrThrow(ItemTags.WEAPON_ENCHANTABLE),
// this is the "weight" or probability of our enchantment showing up in the table
10,
// the maximum level of the enchantment
3,
// base cost for level 1 of the enchantment, and min levels required for something higher
Enchantment.leveledCost(1, 10),
// same fields as above but for max cost
Enchantment.leveledCost(1, 15),
// anvil cost
5,
// valid slots
AttributeModifierSlot.HAND
)
)
.addEffect(
// enchantment occurs POST_ATTACK
EnchantmentEffectComponentTypes.POST_ATTACK,
EnchantmentEffectTarget.ATTACKER,
EnchantmentEffectTarget.VICTIM,
new LightningEnchantmentEffect(EnchantmentLevelBasedValue.linear(0.4f, 0.2f)) // scale the enchantment linearly.
)
);
}
private void register(Entries entries, RegistryKey<Enchantment> key, Enchantment.Builder builder, ResourceCondition... resourceConditions) {
entries.add(key, builder.build(key.getValue()), resourceConditions);
}
@Override
public String getName() {
return "ReferenceDocEnchantmentGenerator";
}
}
在继续之前,应确保你的项目已为数据生成进行了配置。如果您不确定,请 查看相关文档页面。
在最后,我们必须要告诉我们的模组去把 EnchantmentGenerator
加入到数据生成任务列表中。 为了实现这一点,只需要简单的把 EnchantmentGenerator
加入到 onInitializeDataGenerator
方法中。
pack.addProvider(EnchantmentGenerator::new);
现在,当你运行你的模组的数据生成任务,附魔表 JSON 将会生成在 generated
文件夹内。 下面是一个例子:
{
"anvil_cost": 5,
"description": {
"translate": "enchantment.fabric-docs-reference.thundering"
},
"effects": {
"minecraft:post_attack": [
{
"affected": "victim",
"effect": {
"type": "fabric-docs-reference:lightning_effect",
"amount": {
"type": "minecraft:linear",
"base": 0.4,
"per_level_above_first": 0.2
}
},
"enchanted": "attacker"
}
]
},
"max_cost": {
"base": 1,
"per_level_above_first": 15
},
"max_level": 3,
"min_cost": {
"base": 1,
"per_level_above_first": 10
},
"slots": [
"hand"
],
"supported_items": "#minecraft:enchantable/weapon",
"weight": 10
}
你需要在 zh_cn.json
中给你的自定义魔咒添加一个有意义的名字:
"enchantment.FabricDocsReference.thundering": "Thundering",
现在你应该有了一个可以正常工作的自定义附魔效果! 附魔一个武器,然后攻击一个生物试试吧。 下面的视频里有一个例子: