Починаючи з версії 1.21, спеціальні зачарування в Minecraft використовують підхід, керований даними. Це полегшує додавання простих зачарувань, як-от збільшення шкоди від атаки, але ускладнює створення складних. Процес передбачає розбиття чар на компоненти ефекту.
Компонент ефекту містить код, який визначає спеціальні ефекти зачарування. Minecraft підтримує різні стандартні ефекти, такі як пошкодження предметів, відкидання та досвід.
TIP
Обов’язково перевірте, чи стандартні ефекти Minecraft задовольняють ваші потреби, відвідавши сторінку компонентів ефектів зачарування Вікі Minecraft. У цьому посібнику передбачається, що ви розумієте, як налаштувати «прості» зачарування, керовані даними, і зосереджено на створенні спеціальних ефектів зачарування, які не підтримуються усталено.
Власні ефекти зачарування
Почніть зі створення теки enchantment, а в ній створіть теку effect. У цьому випадку ми створимо запис LightningEnchantmentEffect.
Далі ми можемо створити конструктор і перевизначити методи інтерфейсу EnchantmentEntityEffect. Ми також створимо змінну CODEC для кодування та декодування нашого ефекту; ви можете прочитати більше про кодеки тут.
Основна частина нашого коду буде передана в подію apply(), яка викликається, коли виконується критерій для роботи вашого зачарування. Пізніше ми налаштуємо цей Effect, щоб він викликався, коли сутність уражена, а поки що напишімо простий код, щоб вразити ціль блискавкою.
java
public record LightningEnchantmentEffect(LevelBasedValue amount) implements EnchantmentEntityEffect {
public static final MapCodec<LightningEnchantmentEffect> CODEC = RecordCodecBuilder.mapCodec(instance ->
instance.group(
LevelBasedValue.CODEC.fieldOf("amount").forGetter(LightningEnchantmentEffect::amount)
).apply(instance, LightningEnchantmentEffect::new)
);
@Override
public void apply(ServerLevel serverLevel, int level, EnchantedItemInUse context, Entity target, Vec3 pos) {
if (target instanceof LivingEntity victim) {
if (context.owner() != null && context.owner() instanceof Player player) {
float numStrikes = this.amount.calculate(level);
for (float i = 0; i < numStrikes; i++) {
BlockPos position = victim.blockPosition();
EntityType.LIGHTNING_BOLT.spawn(serverLevel, position, EntitySpawnReason.TRIGGERED);
}
}
}
}
@Override
public MapCodec<? extends EnchantmentEntityEffect> codec() {
return CODEC;
}
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
Тут змінна amount вказує на значення, масштабоване до рівня зачарування. Ми можемо використовувати це, щоб змінити ефективність зачарування залежно від рівня. У коді вище ми використовуємо рівень зачарування, щоб визначити, скільки ударів блискавки породжується.
Реєстрація ефекту зачарування
Як і будь-який інший компонент вашого мода, нам доведеться додати цей EnchantmentEffect до реєстру Minecraft. Для цього додайте клас ModEnchantmentEffects (або будь-яку іншу назву) і допоміжний метод для реєстрації зачарування. Обов’язково викликайте registerModEnchantmentEffects() у вашому головному класі, який містить метод onInitialize().
java
public class ModEnchantmentEffects {
public static final ResourceKey<Enchantment> THUNDERING = of("thundering");
public static MapCodec<LightningEnchantmentEffect> LIGHTNING_EFFECT = register("lightning_effect", LightningEnchantmentEffect.CODEC);
private static ResourceKey<Enchantment> of(String path) {
Identifier id = Identifier.fromNamespaceAndPath(ExampleMod.MOD_ID, path);
return ResourceKey.create(Registries.ENCHANTMENT, id);
}
private static <T extends EnchantmentEntityEffect> MapCodec<T> register(String id, MapCodec<T> codec) {
return Registry.register(BuiltInRegistries.ENCHANTMENT_ENTITY_EFFECT_TYPE, Identifier.fromNamespaceAndPath(ExampleMod.MOD_ID, id), codec);
}
public static void registerModEnchantmentEffects() {
ExampleMod.LOGGER.info("Registering EnchantmentEffects for" + ExampleMod.MOD_ID);
}
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
Створення зачарування
Тепер у нас є ефект зачарування! Останнім кроком є створення зачарування, яке застосовує наш спеціальний ефект. Хоча це можна зробити, створивши файл JSON, подібний до файлів у пакетах даних, цей посібник покаже вам, як динамічно генерувати JSON за допомогою інструментів генерації даних Fabric. Для початку створіть клас ExampleModEnchantmentGenerator.
У цьому класі ми спочатку зареєструємо нове зачарування, а потім використаємо метод configure() для програмного створення JSON.
java
public class ExampleModEnchantmentGenerator extends FabricDynamicRegistryProvider {
public ExampleModEnchantmentGenerator(FabricDataOutput output, CompletableFuture<HolderLookup.Provider> registriesFuture) {
super(output, registriesFuture);
System.out.println("REGISTERING ENCHANTS");
}
@Override
protected void configure(HolderLookup.Provider registries, Entries entries) {
// Our new enchantment, "Thundering."
register(entries, ModEnchantmentEffects.THUNDERING, Enchantment.enchantment(
Enchantment.definition(
registries.lookupOrThrow(Registries.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.dynamicCost(1, 10),
// same fields as above but for max cost
Enchantment.dynamicCost(1, 15),
// anvil cost
5,
// valid slots
EquipmentSlotGroup.HAND
)
)
.withEffect(
// enchantment occurs POST_ATTACK
EnchantmentEffectComponents.POST_ATTACK,
EnchantmentTarget.ATTACKER,
EnchantmentTarget.VICTIM,
new LightningEnchantmentEffect(LevelBasedValue.perLevel(0.4f, 0.2f)) // scale the enchantment linearly.
)
);
}
private void register(Entries entries, ResourceKey<Enchantment> key, Enchantment.Builder builder, ResourceCondition... resourceConditions) {
entries.add(key, builder.build(key.identifier()), resourceConditions);
}
@Override
public String getName() {
return "ExampleModEnchantmentGenerator";
}
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
Перш ніж продовжити, ви повинні переконатися, що ваш проєкт налаштовано для створення даних; якщо ви не впевнені, перегляньте відповідну сторінку документів.
Нарешті, ми повинні сказати нашому моду додати наш EnchantmentGenerator до списку завдань генерації даних. Для цього просто додайте EnchantmentGenerator до цього всередині методу onInitializeDataGenerator.
java
pack.addProvider(ExampleModEnchantmentGenerator::new);1
Тепер, коли ви запускаєте завдання генерації даних вашого мода, у теці generated будуть створені JSON-файли зачарувань. Приклад можна побачити нижче:
json
{
"anvil_cost": 5,
"description": {
"translate": "enchantment.example-mod.thundering"
},
"effects": {
"minecraft:post_attack": [
{
"affected": "victim",
"effect": {
"type": "example-mod: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
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
Ви також повинні додати переклади до свого файлу en_us.json (для української створіть uk_ua.json), щоб надати своєму зачаруванню читабельну назву:
json
"enchantment.example-mod.thundering": "Thundering",1
Тепер у вас повинен бути робочий спеціальний ефект зачарування! Перевірте це, зачарувавши зброю за допомогою чар і вдаривши моба. Приклад наведено в наступному відео:


