Генерация зачарований 26.1.2
Руководство по созданию зачарований с помощью datagen.
ТРЕБОВАНИЯ
Сначала убедитесь, что вы установили datagen.
Установка
Перед реализацией генератора данных создайте пакет enchantment в основном наборе исходных кодов (main source set) и добавьте в него класс 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
Теперь все готово к добавлению генератора данных. В пакете datagen создайте класс, который расширяет (extends) FabricDynamicRegistryProvider. В созданном классе добавьте конструктор, соответствующий суперклассу (super), а также реализуйте методы configure и getName.
java
public class ExampleModEnchantmentGenerator extends FabricDynamicRegistryProvider {
public ExampleModEnchantmentGenerator(FabricPackOutput 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 переопределите (override) метод 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
Теперь просто запустите генерацию данных, и ваше новое зачарование появится в игре!
Условия эффектов
Большинство типов эффектов зачарований являются условными эффектами (conditional effects). При добавлении таких эффектов можно передавать условия в вызов метода 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 можно объединять в цепочку (chain), чтобы добавить несколько эффектов к одному зачарованию. Однако при таком подходе вам придется указывать условия эффекта для каждого вызова отдельно.
Чтобы использовать общие условия и цели для нескольких эффектов, можно объединить их в один эффект с помощью 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 FabricTagsProvider<Enchantment> {
public ExampleModEnchantmentTagProvider(FabricPackOutput 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
Теперь мы можем добавить наше зачарование в тег EnchantmentTags.NON_TREASURE, вызвав строитель (builder) внутри метода addTags.
java
builder(EnchantmentTags.NON_TREASURE).add(ModEnchantments.THUNDERING);1
Проклятия
Проклятия также реализуются с помощью тегов. Мы можем использовать тот же провайдер тегов из предыдущего раздела "Стол зачарования".
В методе addTags просто добавьте ваше зачарование в тег CURSE, чтобы пометить его как проклятие.
java
builder(EnchantmentTags.CURSE).add(ModEnchantments.REPULSION_CURSE);1

