Атрибуты сущности 26.1.2
Узнайте, как добавлять пользовательские атрибуты сущностям.
Атрибуты определяют свойства, которыми может обладать ваша сущность из мода. Используя Fabric, вы можете создавать собственные которые улучшают игровые механики и также используют ванильные.
Создание пользовательского атрибута
Давайте создадим пользовательский атрибут и назовем его AGGRO_RANGE. Этот атрибут будет управлять дистанцией, на которой сущность может обнаруживать потенциальные угрозы и реагировать на них.
Определение класса атрибута
Начните с создания Java-класса для управления определением и регистрацией ваших атрибутов в структуре кода вашего мода. В данном примере будут созданы следующие функции в классе с именем ModAttributes:
Сначала создайте базовый вспомогательный метод для регистрации атрибутов вашего мода. Этот метод будет принимать следующие параметры и регистрировать атрибут:
String– имя вашего атрибутаdouble– значение по умолчаниюdouble– минимальное возможное значениеdouble– максимальное возможное значениеboolean– значение, определяющее, будет ли атрибут синхронизироваться с клиентами
java
private static Holder<Attribute> register(
String name, double defaultValue, double minValue, double maxValue, boolean syncedWithClient
) {
Identifier identifier = Identifier.fromNamespaceAndPath(ExampleMod.MOD_ID, name);
Attribute entityAttribute = new RangedAttribute(
identifier.toLanguageKey(),
defaultValue,
minValue,
maxValue
).setSyncable(syncedWithClient);
return Registry.registerForHolder(BuiltInRegistries.ATTRIBUTE, identifier, entityAttribute);
}1
2
3
4
5
6
7
8
9
10
11
12
13
2
3
4
5
6
7
8
9
10
11
12
13
Затем мы зарегистрируем атрибут с именем AGGRO_RANGE и идентификатором aggro_range, значением по умолчанию 8.0, минимальным значением 0 и максимальным значением, установленным на предел типа double. Этот атрибут не будет синхронизироваться с игроками.
java
public static final Holder<Attribute> AGGRO_RANGE = register(
"aggro_range",
8.0,
0.0,
Double.MAX_VALUE,
false
);1
2
3
4
5
6
7
2
3
4
5
6
7
Перевод пользовательских атрибутов
Чтобы отобразить название атрибута в удобном для чтения формате, необходимо внести следующие изменения в файл assets/example-mod/lang/en_us.json:
json
{
"attribute.name.example-mod.aggro_range": "Aggro Range"
}1
2
3
2
3
Инициализация
Чтобы убедиться в правильной регистрации атрибута, вам необходимо инициализировать его при запуске мода. Для этого добавьте публичный статический метод инициализации в ваш класс и вызовите его из главного класса инициализатора вашего мода. На данный момент этот метод может оставаться пустым.
java
public static void initialize() {
}1
2
2
java
public class ExampleModAttributes implements ModInitializer {
@Override
public void onInitialize() {
ModAttributes.initialize();
}
}1
2
3
4
5
6
2
3
4
5
6
Статический вызов метода класса инициализирует его, если он не был загружен ранее — это означает, что все статические поля будут вычислены. Именно для этого и нужен пустой метод initialize.
Применение атрибутов
Чтобы атрибуты начали действовать, их необходимо прикрепить к сущности. Обычно это делается в методе, где создаются или изменяются атрибуты сущности.
Ванильная игра также предоставляет атрибуты, включая максимальное здоровье, скорость передвижения и урон от атаки. Полный список можно найти в ванильном классе Attributes и на Minecraft Wiki.
В качестве демонстрации мы добавим максимальное здоровье, скорость передвижения, урон от атаки и созданный ранее атрибут дальности агрессии.
java
public static AttributeSupplier.Builder createEntityAttributes() {
return Mob.createMobAttributes()
.add(Attributes.MAX_HEALTH, 25.0)
.add(Attributes.MOVEMENT_SPEED, 0.22)
.add(Attributes.ATTACK_DAMAGE, 3.0)
.add(ModAttributes.AGGRO_RANGE, 8.0);
}1
2
3
4
5
6
7
2
3
4
5
6
7
Чтение и изменение атрибутов
Атрибут сам по себе — это просто данные, привязанные к сущности. Чтобы он приносил пользу, нам нужно уметь читать и записывать его значения. Для этого есть два основных способа: получение экземпляра атрибута (AttributeInstance) сущности или получение значения напрямую.
java
entity.getAttribute(ModAttributes.AGGRO_RANGE) // returns an `AttributeInstance`
entity.getAttributeValue(ModAttributes.AGGRO_RANGE) // returns a double with the current value
entity.getAttributeBaseValue(ModAttributes.AGGRO_RANGE) // returns a double with the base value1
2
3
2
3
Экземпляр атрибута (AttributeInstance) дает больше гибкости. Например, он позволяет установить модификатор атрибута (AttributeModifier), используя одну из трех ванильных операций модификации. Модификаторы могут быть постоянными (сохраняются в NBT) или временными (не сохраняются в NBT) и добавляются через методы добавления модификаторов – addPermanentModifier и addTransitiveModifier соответственно.
java
attribute.addPermanentModifier(
new AttributeModifier(
Identifier.fromNamespaceAndPath(ExampleMod.MOD_ID, "increased_range"), // the ID of your modifier, should be static so it can be removed
8, // how much to modify it
AttributeModifier.Operation.ADD_VALUE // what operator to use, see the wiki page linked above
));1
2
3
4
5
6
2
3
4
5
6
Как только вы получите доступ к значению атрибута, вы сможете использовать его в ИИ (искусственном интеллекте) вашей сущности.


