532 lines
17 KiB
Markdown
532 lines
17 KiB
Markdown
# Скриптинг
|
||
|
||
В качестве языка сценариев используется LuaJIT
|
||
|
||
## Функции, доступные в скриптах
|
||
|
||
```lua
|
||
load_script("контентпак:scripts/имя_скрипта.lua") -- загружает скрипт, если ещё не загружен
|
||
load_script("контентпак:scripts/имя_скрипта.lua", true) -- перезагружает скрипт
|
||
require "контентпак:имя_модуля" -- загружает lua модуль из папки modules (расширение не указывается)
|
||
```
|
||
|
||
## Библиотека player
|
||
```python
|
||
player.get_pos(playerid: int) -> number, number, number
|
||
```
|
||
Возвращает x, y, z координаты игрока
|
||
|
||
```python
|
||
player.set_pos(playerid: int, x: number, y: number, z: number)
|
||
```
|
||
|
||
Устанавливает x, y, z координаты игрока
|
||
|
||
```python
|
||
player.get_rot(playerid: int) -> number, number
|
||
```
|
||
|
||
Возвращает x, y вращения камеры (в радианах)
|
||
|
||
```python
|
||
player.set_rot(playerid: int, x: number, y: number, z: number)
|
||
```
|
||
|
||
Устанавливает x, y вращения камеры (в радианах)
|
||
|
||
```python
|
||
player.get_inventory(playerid: int) -> int, int
|
||
```
|
||
|
||
Возвращает id инвентаря игрока и индекс выбранного слота (от 0 до 9)
|
||
|
||
## Библиотека world
|
||
|
||
```python
|
||
world.get_day_time() -> number
|
||
```
|
||
|
||
Возвращает текущее игровое время от 0.0 до 1.0, где 0.0 и 1.0 - полночь, 0.5 - полдень.
|
||
|
||
```python
|
||
world.set_day_time(time: number)
|
||
```
|
||
|
||
Устанавливает указанное игровое время.
|
||
|
||
```python
|
||
world.get_total_time() -> number
|
||
```
|
||
|
||
Возвращает общее суммарное время, прошедшее в мире
|
||
|
||
```python
|
||
world.get_seed() -> int
|
||
```
|
||
|
||
Возвращает зерно мира.
|
||
|
||
## Библиотека gui
|
||
|
||
Библиотека содержит функции для доступа к свойствам UI элементов. Вместо gui следует использовать объектную обертку, предоставляющую доступ к свойствам через мета-методы __index, __newindex:
|
||
```lua
|
||
local inventory_doc = Document.new("id-макета")
|
||
print(inventory_doc.some_button.text)
|
||
indentory_doc.some_button.text = "new text"
|
||
```
|
||
|
||
В скрипте макета `layouts/файл_макета.xml` - `layouts/файл_макета.xml.lua` уже доступна переменная **document** содержащая объект класса Document
|
||
|
||
## Библиотека inventory
|
||
|
||
Библиотека функций для работы с инвентарем.
|
||
|
||
```python
|
||
inventory.get(invid: int, slot: int) -> int, int
|
||
```
|
||
|
||
Принимает id инвентаря и индекс слота. Возвращает id предмета и его количество. id = 0 (core:empty) обозначает, что слот пуст.
|
||
|
||
```python
|
||
inventory.set(invid: int, slot: int, itemid: int, count: int)
|
||
```
|
||
|
||
Устанавливает содержимое слота.
|
||
|
||
```python
|
||
inventory.size(invid: int) -> int
|
||
```
|
||
|
||
Возращает размер инвентаря (число слотов). Если указанного инвентаря не существует, бросает исключение.
|
||
|
||
```python
|
||
inventory.add(invid: int, itemid: int, count: int) -> int
|
||
```
|
||
|
||
Добавляет предмет в инвентарь. Если не удалось вместить все количество, возвращает остаток.
|
||
|
||
```python
|
||
inventory.get_block(x: int, y: int, z: int) -> int
|
||
```
|
||
|
||
Функция возвращает id инвентаря указанного блока. Если блок не может иметь инвентарь - возвращает 0.
|
||
|
||
```python
|
||
inventory.bind_block(invid: int, x: int, y: int, z: int)
|
||
```
|
||
|
||
Привязывает указанный инвентарь к блоку.
|
||
|
||
```python
|
||
inventory.unbind_block(x: int, y: int, z: int)
|
||
```
|
||
|
||
Отвязывает инвентарь от блока.
|
||
|
||
> [!WARNING]
|
||
> Инвентари, не привязанные ни к одному из блоков, удаляются при выходе из мира.
|
||
|
||
```python
|
||
inventory.clone(invid: int) -> int
|
||
```
|
||
|
||
Создает копию инвентаря и возвращает id копии. Если копируемого инвентаря не существует, возвращает 0.
|
||
|
||
## Библиотека block
|
||
|
||
```python
|
||
block.name(blockid: int) -> str
|
||
```
|
||
|
||
Возвращает строковый id блока по его числовому id
|
||
|
||
```python
|
||
block.index(name: str) -> int
|
||
```
|
||
|
||
Возвращает числовой id блока, принимая в качестве агрумента строковый
|
||
|
||
```python
|
||
block.get(x: int, y: int, z: int) -> int
|
||
```
|
||
|
||
Возвращает числовой id блока на указанных координатах. Если чанк на указанных координатах не загружен, возвращает -1.
|
||
|
||
```python
|
||
block.get_states(x: int, y: int, z: int) -> int
|
||
```
|
||
|
||
Возвращает состояние (поворот + доп. информация) в виде целого числа
|
||
|
||
```python
|
||
block.set(x: int, y: int, z: int, id: int, states: int)
|
||
```
|
||
|
||
Устанавливает блок с заданным числовым id и состоянием (0 - по-умолчанию) на заданных координатах.
|
||
|
||
> [!WARNING]
|
||
> `block.set` не вызывает событие on_placed.
|
||
|
||
```python
|
||
block.is_solid_at(x: int, y: int, z: int) -> bool
|
||
```
|
||
|
||
Проверяет, является ли блок на указанных координатах полным
|
||
|
||
```python
|
||
block.is_replaceable_at(x: int, y: int, z: int) -> bool
|
||
```
|
||
Проверяет, можно ли на заданных координатах поставить блок (примеры: воздух, трава, цветы, вода)
|
||
|
||
```python
|
||
block.defs_count() -> int
|
||
```
|
||
|
||
Возвращает количество id доступных в движке блоков
|
||
|
||
Следующие три функции используется для учёта вращения блока при обращении к соседним блокам или других целей, где направление блока имеет решающее значение.
|
||
|
||
|
||
```python
|
||
block.get_X(x: int, y: int, z: int) -> int, int, int
|
||
```
|
||
|
||
Возвращает целочисленный единичный вектор X блока на указанных координатах с учётом его вращения (три целых числа).
|
||
Если поворот отсутствует, возвращает 1, 0, 0
|
||
|
||
```python
|
||
block.get_Y(x: int, y: int, z: int) -> int, int, int
|
||
```
|
||
|
||
Возвращает целочисленный единичный вектор Y блока на указанных координатах с учётом его вращения (три целых числа).
|
||
Если поворот отсутствует, возвращает 0, 1, 0
|
||
|
||
```python
|
||
block.get_Z(x: int, y: int, z: int) -> int, int, int
|
||
```
|
||
|
||
Возвращает целочисленный единичный вектор Z блока на указанных координатах с учётом его вращения (три целых числа).
|
||
Если поворот отсутствует, возвращает 0, 0, 1
|
||
|
||
```python
|
||
block.get_rotation(x: int, y: int, z: int) -> int
|
||
```
|
||
|
||
Возвращает индекс поворота блока в его профиле вращения.
|
||
|
||
```python
|
||
block.set_rotation(x: int, y: int, z: int, rotation: int)
|
||
```
|
||
|
||
Устанавливает вращение блока по индексу в его профиле вращения.
|
||
|
||
### Пользовательские биты
|
||
|
||
Выделенная под использования в скриптах часть поля `voxel.states` хранящего доп-информацию о вокселе, такую как вращение блока. На данный момент выделенная часть составляет 8 бит.
|
||
|
||
```python
|
||
block.get_user_bits(x: int, y: int, z: int, offset: int, bits: int) -> int
|
||
```
|
||
|
||
Возвращает выбранное число бит с указанного смещения в виде целого беззнакового числа
|
||
|
||
```python
|
||
block.set_user_bits(x: int, y: int, z: int, offset: int, bits: int, value: int) -> int
|
||
```
|
||
Записывает указанное число бит значения value в user bits по выбранному смещению
|
||
|
||
## Библиотека item
|
||
|
||
```python
|
||
item.name(itemid: int) -> str
|
||
```
|
||
|
||
Возвращает строковый id предмета по его числовому id (как block.name)
|
||
|
||
```python
|
||
item.index(name: str) -> int
|
||
```
|
||
|
||
Возвращает числовой id предмета по строковому id (как block_index)
|
||
|
||
```python
|
||
item.stack_size(itemid: int) -> int
|
||
```
|
||
|
||
Возвращает максимальный размер стопки для предмета.
|
||
|
||
```python
|
||
item.defs_count() -> int
|
||
```
|
||
|
||
Возвращает общее число доступных предметов (включая сгенерированные)
|
||
|
||
## Библиотека hud
|
||
|
||
```python
|
||
hud.open_inventory()
|
||
```
|
||
|
||
Открывает инвентарь
|
||
|
||
```python
|
||
hud.close_inventory()
|
||
```
|
||
|
||
Закрывает инвентарь
|
||
|
||
```python
|
||
hud.open_block(x: int, y: int, z: int) -> int, str
|
||
```
|
||
|
||
Открывает инвентарь и UI блока. Если блок не имеет макета UI - бросается исключение.
|
||
|
||
Возвращает id инвентаря блока (при *"inventory-size"=0* создаётся виртуальный инвентарь, который удаляется после закрытия), и id макета UI.
|
||
|
||
```python
|
||
hud.show_overlay(layoutid: str, playerinv: bool)
|
||
```
|
||
|
||
Показывает элемент в режиме оверлея. Также показывает инвентарь игрока, если playerinv - **true**
|
||
|
||
> [!NOTE]
|
||
> Одновременно может быть открыт только один блок
|
||
|
||
```python
|
||
hud.open_permanent(layoutid: str)
|
||
```
|
||
|
||
Добавляет постоянный элемент на экран. Элемент не удаляется при закрытии инвентаря. Чтобы не перекрывать затенение в режиме инвентаря нужно установить z-index элемента меньшим чем -1. В случае тега inventory, произойдет привязка слотов к инвентарю игрока.
|
||
|
||
```python
|
||
hud.close(layoutid: str)
|
||
```
|
||
|
||
Удаляет элемент с экрана
|
||
## События блоков
|
||
|
||
```lua
|
||
function on_placed(x, y, z, playerid)
|
||
```
|
||
|
||
Вызывается после установки блока игроком
|
||
|
||
```lua
|
||
function on_broken(x, y, z, playerid)
|
||
```
|
||
|
||
Вызывается после разрушения блока игроком
|
||
|
||
```lua
|
||
function on_interact(x, y, z, playerid) -> bool
|
||
```
|
||
|
||
Вызывается при нажатии на блок ПКМ. Предотвращает установку блоков, если возвращает `true`
|
||
|
||
```lua
|
||
function on_update(x, y, z)
|
||
```
|
||
|
||
Вызывается при обновлении блока (если изменился соседний блок)
|
||
|
||
```lua
|
||
function on_random_update(x, y, z)
|
||
```
|
||
|
||
Вызывается в случайные моменты времени (рост травы на блоках земли)
|
||
|
||
```lua
|
||
function on_blocks_tick(tps: int)
|
||
```
|
||
|
||
Вызывается tps (20) раз в секунду
|
||
|
||
## События предметов
|
||
|
||
```lua
|
||
function on_use(playerid: int)
|
||
```
|
||
|
||
Вызывается при нажатии ПКМ не на блок.
|
||
|
||
```lua
|
||
function on_use_on_block(x: int, y: int, z: int, playerid: int)
|
||
```
|
||
|
||
Вызывается при нажатии ПКМ на блок. Предотвращает установку блока, прописанного в `placing-block` если возвращает `true`
|
||
|
||
```lua
|
||
function on_block_break_by(x: int, y: int, z: int, playerid: int)
|
||
```
|
||
|
||
Вызывается при нажатии ЛКМ на блок (в т.ч неразрушимый). Предотвращает разрушение блока, если возвращает `true`
|
||
|
||
## События мира
|
||
|
||
События мира для контент-пака прописываются в `scripts/world.lua`
|
||
|
||
```lua
|
||
function on_world_open()
|
||
```
|
||
|
||
Вызывается при загрузке мира
|
||
|
||
```lua
|
||
function on_world_save()
|
||
```
|
||
|
||
Вызывается перед сохранением мира
|
||
|
||
```lua
|
||
function on_world_tick()
|
||
```
|
||
|
||
Вызывается 20 раз в секунду
|
||
|
||
```lua
|
||
function on_world_quit()
|
||
```
|
||
|
||
Вызывается при выходе из мира (после сохранения)
|
||
|
||
## События макета
|
||
|
||
События прописываются в файле `layouts/имя_макета.xml.lua`.
|
||
|
||
```lua
|
||
function on_open(invid: int, x: int, y: int, z: int)
|
||
```
|
||
|
||
Вызывается при добавлении элемента на экран.
|
||
При отсутствии привязки к инвентарю invid будет равен 0.
|
||
При отсутствии привязки к блоку x, y, z так же будут равны 0.
|
||
|
||
```lua
|
||
function on_close(invid: int)
|
||
```
|
||
|
||
Вызывается при удалении элемента с экрана.
|
||
|
||
## События HUD
|
||
|
||
События связанные с игровым интерфейсом прописываются в файле `scripts/hud.lua`
|
||
|
||
```lua
|
||
function on_hud_open(playerid: int)
|
||
```
|
||
|
||
Вызывается после входа в мир, когда становится доступна библиотека hud. Здесь на экран добавляются постоянные элементы.
|
||
|
||
```lua
|
||
function on_hud_close(playerid: int)
|
||
```
|
||
|
||
Вызывается при выходе из мира, перед его сохранением.
|
||
|
||
## Библиотеки движка
|
||
|
||
### file
|
||
|
||
Библиотека функций для работы с файлами
|
||
|
||
```python
|
||
file.resolve(путь: str) -> str
|
||
```
|
||
|
||
Функция приводит запись `точка_входа:путь` (например `user:worlds/house1`) к обычному пути. (например `C://Users/user/.voxeng/worlds/house1`)
|
||
|
||
> [!NOTE]
|
||
> Функцию не нужно использовать в сочетании с другими функциями из библиотеки, так как они делают это автоматически
|
||
|
||
Возвращаемый путь не является каноническим и может быть как абсолютным, так и относительным.
|
||
|
||
```python
|
||
file.read(путь: str) -> str
|
||
```
|
||
|
||
Читает весь текстовый файл и возвращает в виде строки
|
||
|
||
```python
|
||
file.read_bytes(путь: str) -> array of integers
|
||
```
|
||
|
||
Читает файл в массив байт.
|
||
|
||
```python
|
||
file.write(путь: str, текст: str) -> nil
|
||
```
|
||
|
||
Записывает текст в файл (с перезаписью)
|
||
|
||
```python
|
||
file.write_bytes(путь: str, data: array of integers)
|
||
```
|
||
|
||
Записывает массив байт в файл (с перезаписью)
|
||
|
||
```python
|
||
file.length(путь: str) -> int
|
||
```
|
||
|
||
Возвращает размер файла в байтах, либо -1, если файл не найден
|
||
|
||
```python
|
||
file.exists(путь: str) -> bool
|
||
```
|
||
|
||
Проверяет, существует ли по данному пути файл или директория
|
||
|
||
```python
|
||
file.isfile(путь: str) -> bool
|
||
```
|
||
|
||
Проверяет, существует ли по данному пути файл
|
||
|
||
```python
|
||
file.isdir(путь: str) -> bool
|
||
```
|
||
|
||
Проверяет, существует ли по данному пути директория
|
||
|
||
```python
|
||
file.mkdir(путь: str) -> bool
|
||
```
|
||
|
||
Создает директорию. Возвращает true если была создана новая директория
|
||
|
||
```python
|
||
file.mkdirs(путь: str) -> bool
|
||
```
|
||
|
||
Создает всю цепочку директорий. Возвращает true если были созданы директории.
|
||
|
||
### time
|
||
|
||
```python
|
||
time.uptime() -> float
|
||
```
|
||
|
||
Возвращает время с момента запуска движка в секундах
|
||
|
||
## Доступные модули
|
||
|
||
### TOML сериализация/десериализация
|
||
|
||
```lua
|
||
local toml = require "core:toml"
|
||
|
||
local t = {a=53, b=42, s="test", sub={x=1, y=6}}
|
||
local s = toml.serialize(t)
|
||
print(s)
|
||
local t2 = toml.deserialize(s)
|
||
```
|
||
вывод:
|
||
```toml
|
||
b = 42
|
||
s = "test"
|
||
a = 53
|
||
[sub]
|
||
y = 6
|
||
x = 1
|
||
```
|