-
Notifications
You must be signed in to change notification settings - Fork 3
JavaScript API
Моды пишутся на JavaScript. По умолчанию JavaScript не предоставляет ни методов для работы с Terraria, ни методов для работы с модами. Но все эти методы нужны, иначе толку от JavaScript никакого. В связи с этим TL предоставляет API (набор функций), который позволяет работать с игрой и модами.
Набор доступных функций зависит от версии структуры пака (её можно увидеть и изменить в TL Packer или вручную в поле packStructureVersion
в Settings.json
пака). Мы стараемся делать так, чтобы новые версии TL поддерживали работу со всеми версиями структур, чтобы не нужно было переписывать моды после того, как мы изменили часть функций. В идеале, стоит создавать моды под последнюю версию структуры пака на момент создания мода, чтобы получить доступ к наибольшему количеству функций.
Преобразования типов:
В C# есть понятия упаковки и распаковки (boxing и unboxing соответственно). Упаковка происходит, когда экземпляр структуры (или примитива) приводится к типу объекта. Пример: object number = 3
- примитив 3
упаковывается в объект. В C# упаковка производится автоматически, а для распаковки нужно указать конкретный тип в скобках (Пример: object boxedNumber = 3; int unboxedNumber = (int) boxedNumber
).
TL Mod API при работе с объектами C# автоматически выполняет приведение примитивных типов к аналогам в JavaScript для удобства работы с ними. К примеру поле Terraria.ID.ItemID.SummonerEmblem
имеет тип short
, поэтому код new NativeClass('Terraria.ID', 'ItemID').SummonerEmblem
автоматически преобразует возвращённое значение к типу Number
в JavaScript.
Данные приведения в большинстве случаев не вызывают проблем, но иногда всё же вызывают.
К примеру, может потребоваться передать объект в качестве аргумента в функцию при создании и заполнении массива int
:
const Array = new NativeClass('System', 'Array');
const CreateInstance = Array['Array CreateInstance(Type elementType, int length)'];
const GetValue = Array['object GetValue(long index)'];
const SetValue = Array['void SetValue(object value, long index)'];
const Type = new NativeClass('System', 'Type');
const GetType = Type['Type GetType(string typeName)'];
const Int32Type = GetType('System.Int32');
const newArray = CreateInstance(Int32Type, 1);
SetValue(newArray, 20, 0n) // Выбросит ошибку из-за несоотвествия типов - нужен объект, а передаётся примитив
SetValue(newArray, NativeObject.wrap(20, 'int'), 0n); // Всё хорошо
const arrayBoxedValue = GetValue(newArray, 0n); // Тип `arrayBoxedValue` - NativeObject, другими словами, упакованное примитивное значение
const arrayUnboxedValue = NativeObject.unwrap(arrayBoxedValue); // Тип `arrayUnboxedValue` - `Number`
В примере выше метод Array.SetValue
согласно сигнатуре принимает первым аргументом значение типа object
. Если вместо NativeObject
передать JavaScript Number
(20
), то Mod API не сможет понять, к какому типу примитива это число нужно преобразовать (нужно ли передать int
, или short
, или byte
и т.п.). Поэтому перед передачей значения его нужно упаковать с помощью NativeObject.wrap
.
Метод же Array.GetValue
согласно сигнатуре возвращает объект, поэтому arrayBoxedValue
не будет автоматически преобразован в JavaScript Number
. Для его преобразования и вычислений с помощью стандартных JavaScript операций нужно использовать функцию NativeObject.unwrap
.
NativeObject.wrap/unwrap
также используется для преобразования других C# объектов в их аналоги в JavaScript. К примеру, вызов NativeObject.wrap('hello', 'string')
вернёт упакованный экземпляр типа string
, а NativeObject.unwrap(<some string object>)
вернёт JavaScript строку.
Информацию по методам NativeObject.wrap/unwrap
смотри ниже.
- import.meta.currentDirectory (v22+)
- NativeClass.constructor (v22+)
- NativeClass.makeGeneric (v22+)
- NativeClass.new (v22+)
- NativeObject.unwrap (v27+)
- NativeObject.wrap (v27+)
- tl.info.terrariaVersionName (v22+)
- tl.info.terrariaVersionCode (v22+)
- tl.mod.dataDirectory (v27+)
- tl.mod.name (v22+)
- tl.mod.path (v22+)
- tl.mod.uuid (v22+)
- tl.mod.packUuid (v22+)
- tl.mod.packStructureVersion (v22+)
- tl.translation.add (v22+)
- tl.file.delete (v27+)
- tl.file.exists (v22+)
- tl.file.read (v22+)
- tl.file.write (v27+)
- tl.item.registerNew (v22+)
- tl.texture.load (v22+)
- tl.texture.loadAnimation (v22+)
- tl.cheatMenu.getItemCategories (v22+)
- tl.cheatMenu.addItemCategory (v22+)
- tl.cheatMenu.addItemToCategory (v22+)
- tl.directory.create (v27+)
- tl.directory.delete (v27+)
- tl.directory.exists (v27+)
- tl.directory.listDirectories (v27+)
- tl.directory.listFiles (v27+)
- tl.log (v22+)
import.meta.currentDirectory String
Описание: возвращает путь к папке текущего скрипта.
Версия: 22 и выше
Пример:
main.js
:
import { callScript } from 'inner/script.js'
callScript();
inner/script.js
:
export function callScript() {
tl.log(import.meta.currentDirectory)
}
Содержимое лога: "inner"
new NativeClass(String namespace, String name)
Описание: создаёт новый экземпляр класса NativeClass
. Этот класс позволяет работать с методами из C#
Версия: 22 и выше
Пример:
main.js
const ItemID = new NativeClass('Terraria.ID', 'ItemID');
tl.log(ItemID.SummonerEmblem);
Содержимое лога: 2998
NativeClass.makeGeneric(NativeClass[] types) -> NativeClass
Описание: позволяет работать с generic C# классами
Версия: 22 и выше
Пример:
main.js
const List = new NativeClass('System.Collections.Generic', 'List`1');
const Int32Type = new NativeClass('System', 'Int32');
const IntList = List.makeGeneric(Int32Type);
const list = IntList.new();
list['void .ctor()']();
list.Add(5);
list.Add(10);
list.Add(15);
const lastItem = list['int get_Item(int index)'](2);
tl.log(lastItem);
Содержимое лога: 15
NativeClass.new() -> NativeObject
Описание: позволяет создавать экземпляры объектов
Важно: после создания объекта необходимо вызвать один из конструкторов класса на созданном экземпляре. Если этого не сделать, то поля объекта будут неинициализированы, что может привести к неожиданным проблемам при работе с объектом
Версия: 22 и выше
Пример:
main.js
const Viewport = new NativeClass('Microsoft.Xna.Framework.Graphics', 'Viewport');
const instance = Viewport.new();
instance['void .ctor(int x, int y, int width, int height)'](1, 2, 3, 4);
tl.log(instance.Y);
Содержимое лога: 2
NativeClass.property или NativeClass["property"]
Описание: позволяет работать с методами/свойствами/полями C# класса
Версия: 22 и выше
Пример 1 - статическое поле:
main.js
const ItemID = new NativeClass('Terraria.ID', 'ItemID');
tl.log(ItemID.SummonerEmblem);
tl.log(ItemID["SummonerEmblem"]);
Содержимое лога:
2998
2998
Пример 2 - статический метод:
main.js
const Path = new NativeClass('System.IO', 'Path');
const method1 = Path.GetExtension; // работает, т.к. у Path есть только один метод с именем GetExtension
const method2 = Path['string GetExtension(string path)'];
tl.log(method1('file.txt'));
tl.log(method2('file.txt'));
Содержимое лога:
.txt
.txt
static NativeClass.unwrap(NativeObject wrappedValue) -> Any
Описание: преобразовывает объекты C# в JavaScript объекты
Версия: 27 и выше
Пример:
main.js
const Array = new NativeClass('System', 'Array');
const GetValue = Array['object GetValue(long index)'];
const someArray = ... // Тип `someArray` - NativeObject c массивом `int` внутри
const arrayBoxedValue = GetValue(newArray, 0n); // Тип `arrayBoxedValue` - NativeObject
const arrayUnboxedValue = NativeObject.unwrap(arrayBoxedValue); // Тип `arrayUnboxedValue` - `Number`
static NativeClass.wrap(Any value, String type) -> NativeObject
type - byte | sbyte | short | ushort | int | uint | long | ulong | float | double | bool | char | string
Описание: преобразовывает JavaScript объекты в C# объекты
Версия: 27 и выше
Пример:
main.js
const Array = new NativeClass('System', 'Array');
const SetValue = Array['void SetValue(object value, long index)'];
const someArray = ... // Тип someArray - NativeObject c массивом int внутри
const valueToSetUnboxed = 20; // Тип valueToSetUnboxed - Number
const valueToSetBoxed = NativeObject.wrap(valueToSetUnboxed, 'int'); // Тип valueToSetBoxed - NativeObject
SetValue(someArray, valueToSetBoxed, 0n);
tl.info.terrariaVersionName String
Описание: возвращает строковую версию террарии
Версия: 22 и выше
Пример:
main.js
:
tl.log(tl.info.terrariaVersionName)
Содержимое лога: "1.4.0.5.2.1"
tl.info.terrariaVersionCode Integer
Описание: возвращает целочисленную версию террарии
Версия: 22 и выше
Пример:
main.js
:
tl.log(tl.info.terrariaVersionCode)
Содержимое лога: 300543
tl.mod.name String
Описание: возвращает название пака, взятое из поля title
файла Settings.json
Версия: 22 и выше
Пример:
Settings.json
:
{
"title": "Интересный пак"
}
tl.log(tl.mod.name);
Содержимое лога: "Интересный пак"
tl.mod.path String
Описание: возвращает путь к директории мода на устройстве пользователя. Функции TL, работающие с файлами, считают этот путь корневой директорией, в которой ищется необходимый путь к файлу. К примеру, tl.file.read("some_file.txt")
прочитает файл из папки tl.mod.path + '/some_file.txt'
, это происходит неявно
Версия: 22 и выше
Пример:
main.js
tl.log(tl.mod.path);
Содержимое лога: "/storage/emulated/0/Android/data/com.pixelcurves.terlauncher/tl_files/packs/7634960c-2c5a-4509-b586-c26a35fa5546/Modified/1.mod"
tl.mod.uuid String
Описание: возвращает id
мода - поле id
внутри файла <mod_dir>.json
Версия: 22 и выше
Пример:
<mod_dir>.json
:
{
"id": "ae7d54e7-c8db-4d66-bb50-713c76b76d59"
}
tl.log(tl.mod.uuid)
Содержимое лога: ae7d54e7-c8db-4d66-bb50-713c76b76d59
tl.mod.packUuid String
Описание: возвращает id
пака с модом - поле guid
внутри файла Settings.json
Версия: 22 и выше
Пример:
Settings.json
:
{
"packStructureVersion": 17,
"title": "Bosses stop spawn mobs",
"guid": "7634960c-2c5a-4509-b586-c26a35fa5546"
}
tl.log(tl.mod.packUuid)
Содержимое лога: 7634960c-2c5a-4509-b586-c26a35fa5546
tl.mod.packStructureVersion Integer
Описание: возвращает версию структуры пака с модом - поле packStructureVersion
внутри файла Settings.json
Версия: 22 и выше
Пример:
Settings.json
:
{
"packStructureVersion": 17,
"title": "Bosses stop spawn mobs",
"guid": "7634960c-2c5a-4509-b586-c26a35fa5546"
}
tl.log(tl.mod.packStructureVersion)
Содержимое лога: "17"
tl.mod.dataDirectory String
Описание: возвращает директорию, файлы в которой сохраняются при обновлении пака. Используйте данную папку для хранения данных мода
Версия: 27 и выше
Пример 1 (вывод пути):
main.js
tl.log(tl.mod.dataDirectory)
Содержимое лога: "data"
Пример 2 (сохранение и чтение данных):
main.js
function saveData(dataString) {
tl.directory.create(tl.mod.dataDirectory);
tl.file.write(tl.mod.dataDirectory + "/some_data.json", dataString);
}
function restoreData() {
tl.directory.create(tl.mod.dataDirectory);
return tl.file.read(tl.mod.dataDirectory + "/some_data.json");
}
saveData("Hello everyone");
tl.log(restoreData());
Содержимое лога: "data"
tl.translation.add(String languageCode, String jsonContents)
Описание: добавляет перевод для указанного языка
Версия: 22 и выше
Пример: TBD
tl.file.delete(String filePath) -> Boolean
Описание: удаляет файл по указанному пути и возвращает true
, если удаление успешно
Версия: 27 и выше
Пример:
main.js
:
tl.file.write("test.txt", "Hello");
tl.log(tl.file.delete("test.txt"));
Содержимое лога: "true"
tl.file.exists(String filePath) -> Boolean
Описание: проверяет наличие файла по указанному пути
Версия: 22 и выше
Пример:
main.js
:
tl.file.write("test.txt", "Hello");
tl.log(tl.file.exists("test.txt"));
Содержимое лога: "true"
tl.file.read(String filePath) -> String
Описание: читает текст из файла в кодировке utf-8 и возвращает в виде строки
Версия: 27 и выше
Пример:
main.js
:
tl.file.write("test.txt", "Привет");
tl.log(tl.file.read("test.txt"));
Содержимое лога: "Привет"
tl.file.write(String filePath, String data)
Описание: записывает текст в файл в кодировке utf-8
Версия: 27 и выше
Пример:
main.js
:
tl.file.write("test.txt", "Привет");
tl.log(tl.file.read("test.txt"));
Содержимое лога: "Привет"
tl.item.registerNew(String itemName) -> Integer
Описание: добавляет новый предмет с именем itemName
в игру и возвращает его ID
Версия: 22 и выше
Пример:
let itemId = tl.item.registerNew("Some cool item");
tl.log(itemId);
Содержимое лога: "6000"
tl.texture.load(String filePath) -> NativeObject (Xna Texture2D)
Описание: загружает из файла картинку формата .png
, преобразует её в Xna Texture2D и возвращает её
Версия: 22 и выше
Пример:
let myTexture = tl.texture.load("textures/myLovelyTexture.png");
tl.texture.loadAnimation(String filePath, Integer horizontalFramesCount, Integer millisPerFrame) -> NativeObject (Xna Texture2D)
Описание: TBD
Версия: 22 и выше
Пример: TBD
tl.cheatMenu.getItemCategories() -> String[]
Описание: возвращает текущий список категорий предметов в чит меню
Версия: 22 и выше
Пример:
main.js
:
tl.log(tl.cheatMenu.getItemCategories())
Содержимое лога: "all,tile,wall,pick,axe,hammer,armor,melee,summon,magic,ranged,thrown,accessory,wings,shield,mount,expert,potion,fishingPole,questItem,helmet,breastplate,boots,painting,mod,redirected,redirectedAnimated"
tl.cheatMenu.addItemCategory(String categoryName, String iconPath) -> String
Описание: добавляет в список категорий предметов в чит меню новую категорию и возвращает её имя ("<mod id>: <category name>") в списке категорий
Версия: 22 и выше
Пример:
main.js
:
tl.log(tl.cheatMenu.addItemCategory("animated category", "textures/animated.gif"));
tl.log(tl.cheatMenu.addItemCategory("static category", "textures/static.webp"));
Содержимое лога:
00000000-0000-0001-0000-000000000001: animated category
00000000-0000-0001-0000-000000000001: static category
tl.cheatMenu.addItemToCategory(String categoryName, int id) -> Boolean
Описание: добавляет предмет в заданную категорию предметов в чит меню и возвращает, успешно ли добавление (неуспешно, если категория с заданным именем не найдена)
Версия: 22 и выше
Пример:
main.js
:
let categoryName = tl.cheatMenu.addItemCategory("static category", "textures/static.webp");
tl.cheatMenu.addItemToCategory(categoryName, 10);
tl.cheatMenu.addItemToCategory(categoryName, 201);
tl.directory.create(String directoryPath) -> Boolean
Описание: создаёт директорию с поддиректориями по указанному пути и возвращает true
, если создание успешно
Версия: 27 и выше
Пример:
main.js
:
tl.directory.create("files/textures");
tl.log(tl.directory.exists("files/textures"));
Содержимое лога: "true"
tl.directory.delete(String directoryPath) -> Boolean
Описание: удаляет директорию по указанному пути и возвращает true
, если удаление успешно
Версия: 27 и выше
Пример:
main.js
:
tl.directory.create("files/textures");
tl.log(tl.directory.delete("files/textures"));
Содержимое лога: "true"
tl.directory.exists(String directoryPath) -> Boolean
Описание: проверяет наличие директории по указанному пути
Версия: 27 и выше
Пример:
main.js
:
tl.directory.create("files/textures");
tl.log(tl.directory.exists("files/textures"));
Содержимое лога: "true"
tl.directory.listDirectories(String directoryPath) -> String[]
Описание: возвращает список директорий по указанному пути
Версия: 27 и выше
Пример:
main.js
:
tl.directory.create("files/textures/custom");
tl.directory.create("files/sounds");
tl.file.write("files/file.txt", "Hello");
tl.log(tl.directory.listDirectories("files"));
Содержимое лога: "files/textures","files/sounds"
tl.directory.listFiles(String directoryPath) -> String[]
Описание: возвращает список файлов по указанному пути
Версия: 27 и выше
Пример:
main.js
:
tl.directory.create("files/textures/custom");
tl.directory.create("files/sounds");
tl.file.write("files/file.txt", "Hello");
tl.log(tl.directory.listFiles("files"));
Содержимое лога: "files/file.txt"
tl.log(Object data)
Описание: выводит переданный объект в лог
Версия: 22 и выше
Пример:
main.js
:
tl.log("Привет мир!")
Содержимое лога: "Привет мир!"