Атрибути визначають властивості, якими може володіти ваша модифікована сутність. Використовуючи Fabric, ви можете створювати власні атрибути, які покращують ігрову механіку, а також застосовувати ванільні атрибути.
Створення власного атрибута
Створімо налаштовуваний атрибут під назвою AGGRO_RANGE. Цей атрибут контролюватиме відстань, на якій об’єкт може виявити потенційні загрози та реагувати на них.
Визначення класу атрибута
Почніть зі створення класу Java для керування визначенням і реєстрацією ваших атрибутів у структурі коду вашого мода. У цьому прикладі буде створено такі функції в класі під назвою ModAttributes.
Спочатку почніть з основного допоміжного методу, щоб зареєструвати атрибути мода. Цей метод прийматиме такі параметри та реєструватиме атрибут.
Stringбуде назвою вашого атрибутаdouble, яке буде усталеним значенням атрибутаdouble, що буде найменшим значенням, якого досягне ваш атрибутdouble, що буде найвищим значенням, якого досягне ваш атрибут- Логічне значення, яке визначає, чи буде атрибут синхронізовано з клієнтами
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 і максимальним значенням, встановленим якомога вищим. Цей атрибут не буде синхронізовано з гравцями.
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 (uk_ua.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
Виклик методу в класі статично ініціалізує його, якщо він не був попередньо завантажений — це означає, що всі статичні поля оцінюються. Ось для чого цей фіктивний метод ініціалізації.
Застосування атрибутів
Атрибути мають бути прикріплені до сутності, щоб набули чинності. Зазвичай це робиться в методі, де будуються або змінюються атрибути сутності.
Стандартна гра також надає атрибути, зокрема максимальне здоров’я, швидкість руху і шкода від атаки, як показано нижче. Щоб отримати повний список, дивіться стандартний клас Attributes і вікі Minecraft.
У якості демонстрації ми включимо максимальне здоров’я, швидкість руху, шкоду від атаки та атрибут агродальності, створений раніше.
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
Отримавши доступ до значення атрибута, ви можете використовувати його в ШІ вашої сутності.


