Привет, Хабр! В этой статье я хочу затронуть тему аддонов. Многим чего-то не хватало в игре, и они скачивали аддоны с интернета. Когда вы понимаете, что скачанный аддон настолько безполезный, удаляете его. Я, допустим, хочу сделать аддон в minecraft bedrock. Если я сделаю достойный аддон, он может попасть на рынок. Заманчиво? Давайте попробуем сделать что-нибудь своё. Пригодится базовое знание json и в некоторых случаях javascript.
Первым делом, создадим папку myaddon по пути android/data/com.mojang.../files//games/com.mojang/behaivor_packs
если у вас другое сохранение файлов, используйте games/com.mojang.../...
Название папки, которую вы создали, никак не влияет на название аддона. За это отвечает manifest.json, который находится в нашей папке. Отредакиируем его
{
"format_version": 1,
"header": {
"description": "Описание вашего аддона"
"name": "Название вашего аддона",
"uuid": "вставьте сюда уникальный id",
"version": [ 1, 0, 5 ],
"min_engine_version": [ 1, 17, 10 ]
},
"modules": [
{
"description": "",
"type": "data",
"uuid": "вставьте сюда второй уникальный id",
"version": [1, 0, 0]
}
]
}
Если что, uuid это уникальный id, который используется для сохранения аддона. Уникальный айди можно сгенерировать, например, на сайте uuidgener*tor.net, я не хочу оставлять точную ссылку поэтому вместо «а» поставил «*». Чтобы создать иконку нашему аддону, создайте в папке аддона файл pack_icon.jpg или pack_icon.png. Теперь сохраняем наши файлы, заходим в майнкрафт и проверям — теперь во вкладке создание мира в «наборы параметров» есть пустой аддон, который ещё бесполезный.
Function — так называется функция аддона, которая может выполнять несколько команд одновременно. Например, если вы в чат введёте команду /function myfunction, вам дадут и яблоко, и дерево. Так можно создавать на function даже нормальные античиты, но для этого требуется знание команд minecraft bedrock. Чтобы сделать функции в аддона, создайте в папке аддона папку functions. В ней создадите myfunction.mcfunction, ваша функция будет называться myfunction. Отредактируйте код.
#выдать всём яблоко
give @a apple
#выдать всем дерево
give @a log
#создать скорборд
scoreboard objectives add my score dummy
Функция может не отображаться при вводе /function ****. Теперь, если вы введёте /function myfunction, всем игрокам в мире дадут яблоко и дерево, а ещё создадится новый скорборд. Чтобы функция работала каждый тик непрерывно, не вводя её в чат или командный блок, создадим в папке function файл tick.json. Он будет отвечать за автоматическое выполнение функций каждый тик. Введём небольшой json код
{
"values": [
"myfunction"
]
}
теперь функция myfunction будет выполняться каждый тик. Если что, одна секунда это 20 тиков.
Идём всё дальше — чат. Вы, наверное, давно хотели оптимизировать чат, сделать ранги, антиспам. Тут всё в одном аддона — антиспам, ранги в чате и тд. Для начала нам придётся изменить manifest.json, чтобы указать в нём содержание javascript.
{
"format_version": 2,
"header": {
"name": "Название аддона",
"description": "Описание аддона",
"uuid": "Уникальный id",
"version": [ 1, 0, 3 ],
"min_engine_version": [ 1, 14, 0 ]
},
"modules": [
{
"description": "made by habr @DinoZavr2",
"type": "data",
"uuid": "Второй уникальный id",
"version": [ 1, 0, 0 ]
},
{
"description": "",
"language": "javascript",
"type": "script",
"uuid": "Третий уникальный id",
"version": [0, 0, 1],
"entry": "scripts/main/index.js"
}
],
"dependencies": [
{
"uuid": "Четвёртый уникальный id",
"version": [ 0, 1, 0 ]
},
{
"uuid": "Пятый уникальный id",
"version": [ 0, 1, 0 ]
}
]
}
Если хотите, пробелы можете убрать. Вы наверное заметили, что здесь используется 5 уникальных айди. Это может быть для кого-то странно. Также мы указали путь к индексу. Вы уже наверное понимаете структуру.
В папке аддона создадим папку scripts, в ней хранятся скрипты (тоже очевидно). Создадим в папке scripts папку main. В ней файл index.js, языка javascript. Это наш индекс. Введите туда этот код
import { chatrank } from './misc/chat.js'
import { world } from 'mojang-minecraft'
import { timer } from './misc/second.js'
let tick = 0, worldLoaded = false, loadTime = 0;
world.events.beforeChat.subscribe((data) => {
chatrank(data)
})
world.events.tick.subscribe((ticks) => {
tick++
if (!world.getDimension("overworld").runCommand('testfor @a').error && !worldLoaded) {
loadTime = tick
worldLoaded = true;
world.getDimension("overworld").runCommand(`execute @r ~~~ say §l§aМир был загружен в ${ticks} тиках. Добро пожаловать! `)
world.getDimension("overworld").runCommand(`scoreboard objectives add chatsSent dummy`)
}
if(tick >= 20){
tick = 0
timer()
}
})
Думаю, вы поняли, что это отображение того, сколько тиках загружался мир. Ну, базовых знаний js достаточно, чтобы тут не объяснять. Далее в папке main создадим папку misc, а в ней файл chat.js, это будет отвечать за спам и ранги.
import { world } from "mojang-minecraft"
let messages = new Map()
function chatrank(data){
const tags = data.sender.getTags()
data.sender.runCommand(`scoreboard players add @s chatsSent 0`)
let score = parseInt(data.sender.runCommand(`scoreboard players test @s chatsSent *`).statusMessage.match(/-?\d+/)[0])
let ranks = [];
for(const tag of tags){
if(tag.startsWith('rank:')){
ranks.push(tag.replace('rank:', ''))
}
}
if(ranks.length == 0)ranks = ["§l§aPlayer"]
if(data.message.startsWith("!*")){
data.cancel = true
return
}
if(score >= 3){
data.cancel = true
return world.getDimension("overworld").runCommand(`ability "${data.sender.nameTag}" mute true`)
}
if(!messages.get(data.sender.name)){
messages.set(data.sender.name, data.message)
}else {
const oldMsg = messages.get(data.sender.name)
if(oldMsg == data.message){
data.cancel = true
return world.getDimension("overworld").runCommand(`tellraw "${data.sender.nameTag}" {"rawtext":[{"text":"§l§cНе пишите похожие сообщения"}]}`)
}
}
let text = `§f[${ranks}§r§f] §7${data.sender.nameTag}: §f${data.message}`
world.getDimension('overworld').runCommand(`tellraw @a {"rawtext":[{"translate":"§l§eM§r - ${JSON.stringify(text)}}]}`)
messages.set(data.sender.name, data.message)
data.sender.runCommand(`scoreboard players add @s chatsSent 1`)
data.cancel = true
}
export { chatrank }
Чтобы создать себе ранг, нужно вписать tag @s add rank:ВАШ_РАНГ. Например, rank:§l§cADMIN, это будет красным ADMIN, а по умолчанию ранг зелёным Player. Но пока что всё равно ранги и анти-спам не будут работать, нужно в misc создать ещё один файл second.js, по названию всё понятно.
import { world } from 'mojang-minecraft'
let seconds = 0
export function timer(){
seconds++
if(seconds >= 4){
world.getDimension("overworld").runCommand(`scoreboard players reset * chatsSent`)
world.getDimension("overworld").runCommand(`scoreboard players set "dummy" chatsSent 1`)
seconds = 0
return seconds
}
}
Это тоже небольшой js код, который импортирует секунды.Теперь заходим в майнкрафт, создаём мир с этим аддоном, в настройках мира включаем gametest и education edition. Внимание: поддерживаемая версия рангов и антиспама — 1.19.11 и выше. На других, более старых версиях, есть небольшой баг с командой tellraw.