前置条件
请确保你已经完成数据生成器设置章节。
设置
在接入生成器之前,在主源码集内添加enchantment包,然后创建一个ModEnchantments类。 接着在这个新类中添加key方法。
java
private static ResourceKey<Enchantment> key(String path) {
Identifier id = Identifier.fromNamespaceAndPath(ExampleMod.MOD_ID, path);
return ResourceKey.create(Registries.ENCHANTMENT, id);
}1
2
3
4
2
3
4
使用此方法为你的魔咒创建一个ResourceKey。
java
public static final ResourceKey<Enchantment> THUNDERING = key("thundering");1
现在,我们已经准备好添加生成器了。 在数据生成器包里,创建一个继承FabricDynamicRegistryProvider的类。 在这个新创建的类里,添加一个匹配super的构造函数,并实现configure和getName方法。
java
public class ExampleModEnchantmentGenerator extends FabricDynamicRegistryProvider {
public ExampleModEnchantmentGenerator(FabricDataOutput output, CompletableFuture<HolderLookup.Provider> registriesFuture) {
super(output, registriesFuture);
}
@Override
protected void configure(HolderLookup.Provider registries, Entries entries) {
entries.addAll(registries.lookupOrThrow(Registries.ENCHANTMENT)); // Add all bootstrapped enchantments for the current mod id
}
@Override
public String getName() {
return "Enchantments";
}
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
接着,在新建的类中添加register辅助方法。
java
private static void register(BootstrapContext<Enchantment> context, ResourceKey<Enchantment> key, Enchantment.Builder builder) {
context.register(key, builder.build(key.identifier()));
}1
2
3
2
3
现在添加 bootstrap 方法。 在这里,我们将注册想要添加到游戏中的魔咒。
java
public static void bootstrap(BootstrapContext<Enchantment> context) {
// ...
}1
2
3
2
3
在你的 DataGeneratorEntrypoint 类中,重写 buildRegistry 方法并注册我们的 bootstrap 方法。
java
@Override
public void buildRegistry(RegistrySetBuilder registryBuilder) {
registryBuilder.add(Registries.ENCHANTMENT, ExampleModEnchantmentGenerator::bootstrap);
}1
2
3
4
2
3
4
最后,确保在 onInitializeDataGenerator 方法中注册了你的新生成器。
java
pack.addProvider(ExampleModEnchantmentGenerator::new);1
创建魔咒
为了创建自定义魔咒的定义,我们将使用生成器类中的 register 方法。
在生成器的 bootstrap 方法中注册你的魔咒,并调用 ModEnchantments 中已注册的魔咒。
在本例中,我们将使用自定义魔咒效果中创建的魔咒效果,但你也可以使用原版魔咒效果。
java
register(context, ModEnchantments.THUNDERING,
Enchantment.enchantment(
Enchantment.definition(
context.lookup(Registries.ITEM).getOrThrow(ItemTags.WEAPON_ENCHANTABLE), // The items this enchantment can be applied to
10, // The weight / probability of our enchantment being available in the enchanting table
3, // The max level of the enchantment
Enchantment.dynamicCost(1, 10), // The base minimum cost of the enchantment, and the additional cost for every level
Enchantment.dynamicCost(1, 15), // Same as the other dynamic cost, but for the maximum instead
5, // The cost to apply the enchantment in an anvil, in levels
EquipmentSlotGroup.HAND // The slot types in which this enchantment will be able to apply its effects
)
)
.withEffect(
EnchantmentEffectComponents.POST_ATTACK, // The type of effect to be applied
EnchantmentTarget.ATTACKER, // The target to be checked for the enchantment
EnchantmentTarget.VICTIM, // The target to apply the enchantment effect to
new LightningEnchantmentEffect(LevelBasedValue.perLevel(0.4f, 0.2f))
)
);1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
现在只需运行数据生成,你的新魔咒即可在游戏中使用!
效果条件
大多数魔咒效果类型都是条件性效果。 在添加这些效果时,可以向 withEffect 调用传递相应的条件。
INFO
若要概览可用的条件类型及其用法,请参阅Enchantments 类。
java
.withEffect(
// ...
LootItemEntityPropertyCondition.hasProperties(
LootContext.EntityTarget.ATTACKER,
EntityPredicate.Builder.entity().flags(
EntityFlagsPredicate.Builder.flags().setIsFlying(false)
)
)
)1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
多重效果
可以通过链式调用 withEffect 来为一个魔咒添加多种魔咒效果。 不过,这种方法要求你为每个效果单独指定效果条件。
若要在多个效果之间共享已定义的条件和目标,可使用AllOf将它们合并为单个效果。
java
AllOf.entityEffects(
new ApplyEntityImpulse(new Vec3(0, 0.2, -1), new Vec3(1, 1, 1), LevelBasedValue.perLevel(0.7f, 0.2f)),
new PlaySoundEffect(List.of(SoundEvents.LUNGE_1), ConstantFloat.of(5), ConstantFloat.of(1))
),1
2
3
4
2
3
4
注意,使用方法取决于所添加效果的类型。 例如,EnchantmentValueEffect需要使用AnyOf.valueEffects。 不同类型的效果仍需额外调用withEffect。
附魔台
虽然我们在魔咒定义中已指定了魔咒权重(或几率),但默认情况下它不会出现在附魔台中。 若要使该魔咒能被村民交易并出现在附魔台中,需将其添加至non_treasure标签。
为了实现这一点,我们可以创建一个标签提供者。 在datagen包中创建一个继承自 FabricTagProvider<Enchantment> 的类。 随后实现构造函数,将Registries.ENCHANTMENT作为registryKey参数传递给super,并创建addTags方法。
java
public class ExampleModEnchantmentTagProvider extends FabricTagProvider<Enchantment> {
public ExampleModEnchantmentTagProvider(FabricDataOutput output, CompletableFuture<HolderLookup.Provider> registriesFuture) {
super(output, Registries.ENCHANTMENT, registriesFuture);
}
@Override
protected void addTags(HolderLookup.Provider wrapperLookup) {
// ...
}1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
现在,我们可以通过在addTags方法内调用构建器,将我们的魔咒添加至 EnchantmentTags.NON_TREASURE。
java
builder(EnchantmentTags.NON_TREASURE).add(ModEnchantments.THUNDERING);1
诅咒
诅咒同样通过标签实现。 我们可以复用"附魔台"章节中的标签提供者。
在addTags方法中,只需将你的魔咒添加至CURSE标签,即可将其标记为诅咒。
java
builder(EnchantmentTags.CURSE).add(ModEnchantments.REPULSION_CURSE);1

