🇷🇺 Русский (Russian)
🇷🇺 Русский (Russian)
Внешний вид
🇷🇺 Русский (Russian)
🇷🇺 Русский (Russian)
Внешний вид
Страница написана для версии игры:
1.21.4
Страница написана для версии игры:
1.21.4
Начиная с версии 1.21, пользовательские чары в Minecraft используют подход, "управляемый данными". Это упрощает добавление простых чар, таких как увеличение урона от атаки, но усложняет создание сложных. Этот процесс включает в себя разбиение чар на компоненты эффекта.
Компонент эффекта содержит код, определяющий специальные эффекты чар. Minecraft поддерживает различные эффекты по умолчанию, такие как повреждение предметов, отбрасывание и опыт.
TIP
Обязательно проверьте, удовлетворяют ли эффекты Minecraft по умолчанию вашим потребностям, посетив страницу компонентов эффектов зачарования Minecraft Wiki. В этом руководстве предполагается, что вы понимаете, как настраивать «простые» чары, управляемые данными, и основное внимание уделяется созданию пользовательских эффектов чар, которые не поддерживаются по умолчанию.
Начните с создания папки enchantment
, а внутри неё создайте папку effect
. Внутри этого мы создадим запись LightningEnchantmentEffect
.
Далее мы можем создать конструктор и переопределить методы интерфейса EnchantmentEntityEffect
. Мы также создадим переменную CODEC
для кодирования и декодирования нашего эффекта; вы можете прочитать больше о кодеках здесь.
Большая часть нашего кода будет передана в событие apply()
, которое вызывается, когда выполняются критерии для работы вашего зачарования. Позже мы настроим этот Эффект
, чтобы он вызывался при ударе по объекту, а сейчас давайте напишем простой код для поражения цели молнией.
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);
}
}
Теперь у нас есть эффект зачарования! Последний шаг — создать чары, которые будут применять наш собственный эффект. Хотя это можно сделать, создав файл JSON, аналогичный файлам в пакетах данных, в этом руководстве показано, как динамически генерировать JSON с помощью инструментов генерации данных Fabric. Для начала создайте класс 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
.
Теперь, когда вы запускаете задачу генерации данных вашего мода, 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
}
Вам также следует добавить переводы в файл en_us.json
, чтобы дать вашему зачарованию читаемое имя:
"enchantment.FabricDocsReference.thundering": "Thundering",
Теперь у вас должен быть рабочий эффект зачарования! Проверьте это, зачаровав оружие чарами и ударив моба. Пример приведен в следующем видео: