diff --git a/doc/en/scripting/ui.md b/doc/en/scripting/ui.md
index 1ddafdba..2da6843c 100644
--- a/doc/en/scripting/ui.md
+++ b/doc/en/scripting/ui.md
@@ -75,6 +75,7 @@ Common methods:
| ------------------------------- | -------------------------------------------------------------------------------------------- |
| clear() | clears content |
| add(xml) | adds an element, creating it using xml code. Example: `container:add("")` |
+| add(xml, data) | overload with table, which in events declared in xml will be available as DATA |
| setInterval(interval, callback) | assigns a function to be executed repeatedly at an interval specified in milliseconds |
## Textbox
diff --git a/doc/ru/main-page.md b/doc/ru/main-page.md
index e4a9dc61..eda864e8 100644
--- a/doc/ru/main-page.md
+++ b/doc/ru/main-page.md
@@ -20,3 +20,4 @@
- [Скриптинг](scripting.md)
- [Стили текста](text-styles.md)
- [Частицы](particles.md)
+- [Формат моделей VCM](vcm.md)
diff --git a/doc/ru/scripting/ui.md b/doc/ru/scripting/ui.md
index d61d2af3..19f1f8ab 100644
--- a/doc/ru/scripting/ui.md
+++ b/doc/ru/scripting/ui.md
@@ -71,11 +71,12 @@ document["worlds-panel"]:clear()
Методы:
-| Метод | Описание |
-| ------------------------------- | ------------------------------------------------------------------------------------------- |
-| clear() | очищает контент |
-| add(xml) | добавляет элемент, создавая его по xml коду. Пример: `container:add("")` |
-| setInterval(interval, callback) | назначает функцию на повторяющееся выполнение с заданным в миллисекундах интервалом |
+| Метод | Описание |
+| ------------------------------- | --------------------------------------------------------------------------------------------- |
+| clear() | очищает контент |
+| add(xml) | добавляет элемент, создавая его по xml коду. Пример: `container:add("")` |
+| add(xml, data) | перегрузка с передачей таблицы, которая в событиях, объявленных в xml будет доступна как DATA |
+| setInterval(interval, callback) | назначает функцию на повторяющееся выполнение с заданным в миллисекундах интервалом |
## Текстовое поле (textbox)
diff --git a/doc/ru/vcm.md b/doc/ru/vcm.md
new file mode 100644
index 00000000..9e52ca49
--- /dev/null
+++ b/doc/ru/vcm.md
@@ -0,0 +1,49 @@
+## VCM
+
+Текстовый формат описания 3D моделей, являющийся заменой устаревшего свойства `model-primitives`.
+
+Синтаксис:
+
+```
+@примитив атрибут (значение1,значение2,...) атрибут2 "значение3" {
+ @внутренний_примитив ...
+}
+```
+
+Аналогичная структура в XML:
+
+```xml
+<примитив атрибут="значение1,значение2,..." атрибут2="значение3">
+ <внутренний_примитив .../>
+примитив>
+```
+
+В отличие от XML в корне может находиться несколько элементов.
+
+На данный момент существует два вида примитивов: box и rect, а также, part (описывает часть примитива, такую как, например, сторона куба).
+
+### Свойства `rect`
+
+- `from` - точка начала примитива. Пример: `from (0,0.5,0.125)`
+- `right` - вектор X, также определяющий ширину примитива. Пример: `right (1,0,0)`
+- `up` - вектор Y, также определяющий высоту примитива. Пример: `up (0,1,0)`
+- `texture` - отображаемая текстура. По-умолчанию: `$0`. Пример: `texture "blocks:sand"`
+- `region` - UV регион в границах выбранной текстуры, определяется позициями противоположных углов. Пример: `region (0,0,1,1)`
+- `region-scale` вектор-множитель для автоматически выбранного UV региона. Пример: `region-scale (0.5,1)`
+- `shading` определяет возможность затенения на примитиве. Пример: `shading off`
+- `flip` отражает UV регион по горизонтали или вертикали. Пример: `flip v`
+
+### Свойства `box`
+
+- `from` - точка начала примитива. Пример: `from (0,0,0)`
+- `to` - противоположная от начала точка. Пример: `to (1,1,1)`
+- `texture` - отображаемая текстура для всех сторон по-умолчанию.
+- `shading` определяет возможность затенения на примитиве. Пример: `shading off`
+- `delete` удаляет стороны по именам (top, bottom, east, west, north, south)
+
+### Свойства `part` (в `box`)
+
+- `tags` - определяет то, на какаие из сторон будут применены свойства. Пример: `tags (top,bottom)`
+- `texture` - отображаемая текстура. По-умолчанию: `$индекс_стороны`.
+- `region` - UV регион в границах выбранной текстуры, определяется позициями противоположных углов. Пример: `region (0,0,1,1)`
+- `region-scale` вектор-множитель для автоматически выбранного UV региона. Пример: `region-scale (0.5,1)`
diff --git a/res/devtools/syntax/vcm.toml b/res/devtools/syntax/vcm.toml
index 524fdc80..96f1e095 100644
--- a/res/devtools/syntax/vcm.toml
+++ b/res/devtools/syntax/vcm.toml
@@ -1,6 +1,6 @@
language = "VCM"
extensions = ["vcm"]
-line-comment-start = "#"
+line-comment = "#"
keywords = [
"on", "off"
]
diff --git a/src/coders/syntax_parser.cpp b/src/coders/syntax_parser.cpp
index 4b56b607..871cd314 100644
--- a/src/coders/syntax_parser.cpp
+++ b/src/coders/syntax_parser.cpp
@@ -151,6 +151,12 @@ public:
return std::wstring(source.substr(start, pos - start));
}
+ void emitLineComment(devtools::Location start) {
+ auto string = readUntilEOL();
+ emitToken(TokenTag::COMMENT, std::wstring(string), start);
+ skipLine();
+ }
+
std::vector tokenize() {
skipWhitespace();
while (hasNext()) {
@@ -229,16 +235,18 @@ public:
}
if (is_lua_operator_start(c)) {
auto text = parseOperator();
- if (text == L"--") {
- auto string = readUntilEOL();
- emitToken(TokenTag::COMMENT, std::wstring(string), start);
- skipLine();
+ if (text == syntax.lineComment) {
+ emitLineComment(start);
continue;
}
emitToken(TokenTag::OPERATOR, std::move(text), start);
continue;
}
auto text = readUntilWhitespace();
+ if (text.find(syntax.lineComment) == 0) {
+ emitLineComment(start);
+ continue;
+ }
emitToken(TokenTag::UNEXPECTED, std::wstring(text), start);
}
return std::move(tokens);
diff --git a/src/frontend/ContentGfxCache.cpp b/src/frontend/ContentGfxCache.cpp
index 18645259..71492626 100644
--- a/src/frontend/ContentGfxCache.cpp
+++ b/src/frontend/ContentGfxCache.cpp
@@ -67,7 +67,7 @@ void ContentGfxCache::refresh(const Block& def, const Atlas& atlas) {
if (def.variants) {
const auto& variants = def.variants->variants;
for (int i = 1; i < variants.size() - 1; i++) {
- refresh_variant(assets, def, variants[i], i + 1, sideregions, atlas, settings, models);
+ refresh_variant(assets, def, variants[i], i, sideregions, atlas, settings, models);
}
def.variants->variants.at(0) = def.defaults;
}