mirror of
https://github.com/MihailRis/voxelcore.git
synced 2026-10-04 18:41:51 +00:00
Merge branch 'main' into blocks-renderer-and-generator-update-review
This commit is contained in:
commit
4c2a85acbe
36 changed files with 386 additions and 130 deletions
|
|
@ -48,6 +48,12 @@ player.set_rot(playerid: int, x: number, y: number, z: number)
|
||||||
|
|
||||||
Set camera rotation (degrees)
|
Set camera rotation (degrees)
|
||||||
|
|
||||||
|
```lua
|
||||||
|
player.get_dir(playerid: int) -> vec3
|
||||||
|
```
|
||||||
|
|
||||||
|
Returns the player look direction vector
|
||||||
|
|
||||||
```lua
|
```lua
|
||||||
player.get_inventory(playerid: int) -> int, int
|
player.get_inventory(playerid: int) -> int, int
|
||||||
```
|
```
|
||||||
|
|
|
||||||
|
|
@ -30,4 +30,7 @@ utf8.lower(text: str) -> str
|
||||||
|
|
||||||
-- Escapes a string
|
-- Escapes a string
|
||||||
utf8.escape(text: str) -> str
|
utf8.escape(text: str) -> str
|
||||||
|
|
||||||
|
-- Escapes special XML characters
|
||||||
|
utf8.escape_xml(text: str) -> str
|
||||||
```
|
```
|
||||||
|
|
|
||||||
|
|
@ -48,6 +48,12 @@ player.set_rot(playerid: int, x: number, y: number, z: number)
|
||||||
|
|
||||||
Устанавливает x, y вращения камеры (в градусах)
|
Устанавливает x, y вращения камеры (в градусах)
|
||||||
|
|
||||||
|
```lua
|
||||||
|
player.get_dir(playerid: int) -> vec3
|
||||||
|
```
|
||||||
|
|
||||||
|
Возвращает вектор направления взгляда игрока
|
||||||
|
|
||||||
```lua
|
```lua
|
||||||
player.get_inventory(playerid: int) -> int, int
|
player.get_inventory(playerid: int) -> int, int
|
||||||
```
|
```
|
||||||
|
|
|
||||||
|
|
@ -30,4 +30,7 @@ utf8.lower(text: str) -> str
|
||||||
|
|
||||||
-- Экранирует строку
|
-- Экранирует строку
|
||||||
utf8.escape(text: str) -> str
|
utf8.escape(text: str) -> str
|
||||||
|
|
||||||
|
-- Экранирует спец-символы XML
|
||||||
|
utf8.escape_xml(text: str) -> str
|
||||||
```
|
```
|
||||||
|
|
|
||||||
|
|
@ -187,6 +187,12 @@ string.escape(str: string) -> string
|
||||||
|
|
||||||
Экранирует строку. Является псевдонимом `utf8.escape`.
|
Экранирует строку. Является псевдонимом `utf8.escape`.
|
||||||
|
|
||||||
|
```lua
|
||||||
|
string.escape_xml(text: str) -> str
|
||||||
|
```
|
||||||
|
|
||||||
|
Экранирует спец-символы XML. Является псевдонимом `utf8.escape_xml`.
|
||||||
|
|
||||||
```lua
|
```lua
|
||||||
string.pad(str: string, size: number, [опционально] char: string) -> string
|
string.pad(str: string, size: number, [опционально] char: string) -> string
|
||||||
```
|
```
|
||||||
|
|
|
||||||
19
res/devtools/default_syntax_scheme.toml
Normal file
19
res/devtools/default_syntax_scheme.toml
Normal file
|
|
@ -0,0 +1,19 @@
|
||||||
|
[default]
|
||||||
|
bold = false
|
||||||
|
italic = false
|
||||||
|
strikethrough = false
|
||||||
|
underline = false
|
||||||
|
color = [0.8, 0.8, 0.8, 1]
|
||||||
|
|
||||||
|
[keyword]
|
||||||
|
bold = true
|
||||||
|
color = [0.9, 0.6, 0.4, 1]
|
||||||
|
|
||||||
|
[literal]
|
||||||
|
color = [0.4, 0.8, 0.5, 1]
|
||||||
|
|
||||||
|
[comment]
|
||||||
|
color = [0.5, 0.7, 1.0, 1]
|
||||||
|
|
||||||
|
[error]
|
||||||
|
color = [1.0, 0.2, 0.1, 1]
|
||||||
|
|
@ -105,6 +105,7 @@ end
|
||||||
string.lower = utf8.lower
|
string.lower = utf8.lower
|
||||||
string.upper = utf8.upper
|
string.upper = utf8.upper
|
||||||
string.escape = utf8.escape
|
string.escape = utf8.escape
|
||||||
|
string.escape_xml = utf8.escape_xml
|
||||||
|
|
||||||
local meta = getmetatable("")
|
local meta = getmetatable("")
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,8 +3,8 @@ local gui_util = {
|
||||||
}
|
}
|
||||||
|
|
||||||
--- Parse `pagename?arg1=value1&arg2=value2` queries
|
--- Parse `pagename?arg1=value1&arg2=value2` queries
|
||||||
--- @param query page query string
|
--- @param query string page query string
|
||||||
--- @return page_name, args_table
|
--- @return string, string -> page_name, args_table
|
||||||
function gui_util.parse_query(query)
|
function gui_util.parse_query(query)
|
||||||
local args = {}
|
local args = {}
|
||||||
local name
|
local name
|
||||||
|
|
@ -23,8 +23,7 @@ function gui_util.parse_query(query)
|
||||||
return name, args
|
return name, args
|
||||||
end
|
end
|
||||||
|
|
||||||
--- @param query page query string
|
--- @param query string page query string
|
||||||
--- @return document_id
|
|
||||||
function gui_util.load_page(query)
|
function gui_util.load_page(query)
|
||||||
local name, args = gui_util.parse_query(query)
|
local name, args = gui_util.parse_query(query)
|
||||||
for i = #gui_util.local_dispatchers, 1, -1 do
|
for i = #gui_util.local_dispatchers, 1, -1 do
|
||||||
|
|
@ -116,4 +115,52 @@ gui_util.Document = Document
|
||||||
gui_util.Element = Element
|
gui_util.Element = Element
|
||||||
gui_util.RadioGroup = RadioGroup
|
gui_util.RadioGroup = RadioGroup
|
||||||
|
|
||||||
|
function gui.show_message(text, actual_callback)
|
||||||
|
local id = "dialog_"..random.uuid()
|
||||||
|
|
||||||
|
local callback = function()
|
||||||
|
gui.root[id]:destruct()
|
||||||
|
if actual_callback then
|
||||||
|
actual_callback()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
gui.root.root:add(string.format([[
|
||||||
|
<container id='%s' color='#00000080' size-func='-1,-1' z-index='10'>
|
||||||
|
<panel color='#507090E0' size='300' padding='16'
|
||||||
|
gravity='center-center' interval='4'>
|
||||||
|
<label>%s</label>
|
||||||
|
<button onclick='DATA.callback()'>@OK</button>
|
||||||
|
</panel>
|
||||||
|
</container>
|
||||||
|
]], id, string.escape_xml(text)), {callback=callback})
|
||||||
|
input.add_callback("key:escape", callback, gui.root[id])
|
||||||
|
end
|
||||||
|
|
||||||
|
function gui.ask(text, on_yes, on_no)
|
||||||
|
on_yes = on_yes or function() end
|
||||||
|
on_no = on_no or function() end
|
||||||
|
|
||||||
|
local id = "dialog_"..random.uuid()
|
||||||
|
|
||||||
|
local yes_callback = function()
|
||||||
|
gui.root[id]:destruct()
|
||||||
|
on_yes()
|
||||||
|
end
|
||||||
|
local no_callback = function()
|
||||||
|
gui.root[id]:destruct()
|
||||||
|
on_no()
|
||||||
|
end
|
||||||
|
gui.root.root:add(string.format([[
|
||||||
|
<container id='%s' color='#00000080' size-func='-1,-1' z-index='10'>
|
||||||
|
<panel color='#507090E0' size='300' padding='16'
|
||||||
|
gravity='center-center' interval='4'>
|
||||||
|
<label margin='4'>%s</label>
|
||||||
|
<button onclick='DATA.on_yes()'>@Yes</button>
|
||||||
|
<button onclick='DATA.on_no()'>@No</button>
|
||||||
|
</panel>
|
||||||
|
</container>
|
||||||
|
]], id, string.escape_xml(text)), {on_yes=yes_callback, on_no=no_callback})
|
||||||
|
input.add_callback("key:escape", no_callback, gui.root[id])
|
||||||
|
end
|
||||||
|
|
||||||
return gui_util
|
return gui_util
|
||||||
|
|
|
||||||
|
|
@ -150,6 +150,18 @@ _MENU = _GUI_ROOT.menu
|
||||||
menu = _MENU
|
menu = _MENU
|
||||||
gui.root = _GUI_ROOT
|
gui.root = _GUI_ROOT
|
||||||
|
|
||||||
|
do
|
||||||
|
local status, err = pcall(function()
|
||||||
|
local default_styles = toml.parse(file.read(
|
||||||
|
"res:devtools/default_syntax_scheme.toml"
|
||||||
|
))
|
||||||
|
gui.set_syntax_styles(default_styles)
|
||||||
|
end)
|
||||||
|
if not status then
|
||||||
|
debug.error("could not to load default syntax scheme: "..err)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
--- Console library extension ---
|
--- Console library extension ---
|
||||||
console.cheats = {}
|
console.cheats = {}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,7 @@ Error at line %{0}=Памылка ў радку %{0}
|
||||||
Run=Запусціць
|
Run=Запусціць
|
||||||
Filter=Фільтр
|
Filter=Фільтр
|
||||||
Are you sure you want to open the link: =Ці вы ўпэўненыя, што хочаце адкрыць спасылку:
|
Are you sure you want to open the link: =Ці вы ўпэўненыя, што хочаце адкрыць спасылку:
|
||||||
|
Grant '%{0}' pack audio recording permission?=Выдаць паку «%{0}» дазвол на запіс гуку?
|
||||||
|
|
||||||
editor.info.tooltip=CTRL+S - Захаваць\nCTRL+R - Запусціць\nCTRL+Z - Скасаваць\nCTRL+Y - Паўтарыць
|
editor.info.tooltip=CTRL+S - Захаваць\nCTRL+R - Запусціць\nCTRL+Z - Скасаваць\nCTRL+Y - Паўтарыць
|
||||||
devtools.traceback=Стэк выклікаў (ад апошняга)
|
devtools.traceback=Стэк выклікаў (ад апошняга)
|
||||||
|
|
@ -33,12 +34,14 @@ devtools.output=Вывод
|
||||||
|
|
||||||
error.pack-not-found=Не ўдалося знайсці пакет
|
error.pack-not-found=Не ўдалося знайсці пакет
|
||||||
error.dependency-not-found=Выкарыстоўваная залежнасць не знойдзена
|
error.dependency-not-found=Выкарыстоўваная залежнасць не знойдзена
|
||||||
|
error.dependency-version-not-met=Версія залежнасці не адпавядае неабходнай
|
||||||
pack.remove-confirm=Выдаліць увесь кантэнт, які пастаўляецца пакетам/пакетамі, са свету (беззваротна)?
|
pack.remove-confirm=Выдаліць увесь кантэнт, які пастаўляецца пакетам/пакетамі, са свету (беззваротна)?
|
||||||
|
|
||||||
# Падказкі
|
# Падказкі
|
||||||
graphics.gamma.tooltip=Крывая яркасці асвятлення
|
graphics.gamma.tooltip=Крывая яркасці асвятлення
|
||||||
graphics.backlight.tooltip=Падсветка, якая прадухіляе поўную цемру
|
graphics.backlight.tooltip=Падсветка, якая прадухіляе поўную цемру
|
||||||
graphics.dense-render.tooltip=Уключае празрыстасць блокаў, такіх як лісце.
|
graphics.dense-render.tooltip=Уключае празрыстасць блокаў, такіх як лісце.
|
||||||
|
graphics.soft-lighting.tooltip=Уключае мяккае асвятленне ў блоках
|
||||||
|
|
||||||
# Меню
|
# Меню
|
||||||
menu.Apply=Ужыць
|
menu.Apply=Ужыць
|
||||||
|
|
@ -60,7 +63,6 @@ menu.Quit=Выхад
|
||||||
menu.Save and Quit to Menu=Захаваць і Выйсці ў Меню
|
menu.Save and Quit to Menu=Захаваць і Выйсці ў Меню
|
||||||
menu.Settings=Налады
|
menu.Settings=Налады
|
||||||
menu.Reset settings=Скінуць налады
|
menu.Reset settings=Скінуць налады
|
||||||
menu.Contents Menu=Меню кантэнт-пакаў
|
|
||||||
menu.Open data folder=Адкрыць тэчку з дадзенымі
|
menu.Open data folder=Адкрыць тэчку з дадзенымі
|
||||||
menu.Open content folder=Адкрыць тэчку [content]
|
menu.Open content folder=Адкрыць тэчку [content]
|
||||||
|
|
||||||
|
|
@ -80,6 +82,7 @@ world.delete-confirm=Выдаліць свет беззваротна?
|
||||||
settings.Ambient=Фон
|
settings.Ambient=Фон
|
||||||
settings.Backlight=Падсветка
|
settings.Backlight=Падсветка
|
||||||
settings.Dense blocks render=Шчыльны рэндэр блокаў
|
settings.Dense blocks render=Шчыльны рэндэр блокаў
|
||||||
|
settings.Soft lighting=Мяккае асвятленне
|
||||||
settings.Camera Shaking=Труска камеры
|
settings.Camera Shaking=Труска камеры
|
||||||
settings.Camera Inertia=Інэрцыя камеры
|
settings.Camera Inertia=Інэрцыя камеры
|
||||||
settings.Camera FOV Effects=Эфекты поля зроку
|
settings.Camera FOV Effects=Эфекты поля зроку
|
||||||
|
|
@ -100,6 +103,13 @@ settings.V-Sync=Вертыкальная сінхранізацыя
|
||||||
settings.Key=Кнопка
|
settings.Key=Кнопка
|
||||||
settings.Controls Search Mode=Пошук па прывязанай кнопцы кіравання
|
settings.Controls Search Mode=Пошук па прывязанай кнопцы кіравання
|
||||||
settings.Limit Background FPS=Абмежаваць фонавую частату кадраў
|
settings.Limit Background FPS=Абмежаваць фонавую частату кадраў
|
||||||
|
settings.Advanced render=Прасунуты рэндэр
|
||||||
|
settings.Shadows quality=Якасць ценяў
|
||||||
|
settings.Conflict=Знойдзены магчымыя канфлікты
|
||||||
|
settings.Windowed=Ваконны
|
||||||
|
settings.Borderless=Безрамкавы
|
||||||
|
settings.Microphone=Мікрафон
|
||||||
|
settings.microphone.None=Няма
|
||||||
|
|
||||||
# Кіраванне
|
# Кіраванне
|
||||||
chunks.reload=Перазагрузіць чанкі
|
chunks.reload=Перазагрузіць чанкі
|
||||||
|
|
|
||||||
|
|
@ -7,19 +7,15 @@
|
||||||
using namespace devtools;
|
using namespace devtools;
|
||||||
|
|
||||||
static std::unique_ptr<FontStylesScheme> build_styles(
|
static std::unique_ptr<FontStylesScheme> build_styles(
|
||||||
|
const FontStylesScheme& colorScheme,
|
||||||
const std::vector<devtools::Token>& tokens
|
const std::vector<devtools::Token>& tokens
|
||||||
) {
|
) {
|
||||||
using devtools::TokenTag;
|
using devtools::TokenTag;
|
||||||
FontStylesScheme styles {
|
FontStylesScheme styles {colorScheme.palette, {}};
|
||||||
{
|
if (styles.palette.empty()) {
|
||||||
{false, false, false, false, glm::vec4(0.8f, 0.8f, 0.8f, 1)}, // default
|
styles.palette.push_back(FontStyle {
|
||||||
{true, false, false, false, glm::vec4(0.9, 0.6f, 0.4f, 1)}, // keyword
|
false, false, false, false, glm::vec4(0.8f, 0.8f, 0.8f, 1)});
|
||||||
{false, false, false, false, glm::vec4(0.4, 0.8f, 0.5f, 1)}, // string
|
}
|
||||||
{false, false, false, false, glm::vec4(0.3, 0.3f, 0.3f, 1)}, // comment
|
|
||||||
{true, false, false, false, glm::vec4(1.0f, 0.2f, 0.1f, 1)}, // unexpected
|
|
||||||
},
|
|
||||||
{}
|
|
||||||
};
|
|
||||||
size_t offset = 0;
|
size_t offset = 0;
|
||||||
for (int i = 0; i < tokens.size(); i++) {
|
for (int i = 0; i < tokens.size(); i++) {
|
||||||
const auto& token = tokens.at(i);
|
const auto& token = tokens.at(i);
|
||||||
|
|
@ -47,6 +43,9 @@ static std::unique_ptr<FontStylesScheme> build_styles(
|
||||||
styleIndex = 0;
|
styleIndex = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
if (styleIndex >= styles.palette.size()) {
|
||||||
|
styleIndex = 0;
|
||||||
|
}
|
||||||
styles.map.insert(
|
styles.map.insert(
|
||||||
styles.map.end(), token.end.pos - token.start.pos, styleIndex
|
styles.map.end(), token.end.pos - token.start.pos, styleIndex
|
||||||
);
|
);
|
||||||
|
|
@ -67,7 +66,9 @@ void SyntaxProcessor::addSyntax(
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<FontStylesScheme> SyntaxProcessor::highlight(
|
std::unique_ptr<FontStylesScheme> SyntaxProcessor::highlight(
|
||||||
const std::string& ext, std::wstring_view source
|
const FontStylesScheme& colorScheme,
|
||||||
|
const std::string& ext,
|
||||||
|
std::wstring_view source
|
||||||
) const {
|
) const {
|
||||||
const auto& found = langsExtensions.find(ext);
|
const auto& found = langsExtensions.find(ext);
|
||||||
if (found == langsExtensions.end()) {
|
if (found == langsExtensions.end()) {
|
||||||
|
|
@ -76,7 +77,7 @@ std::unique_ptr<FontStylesScheme> SyntaxProcessor::highlight(
|
||||||
const auto& syntax = *found->second;
|
const auto& syntax = *found->second;
|
||||||
try {
|
try {
|
||||||
auto tokens = tokenize(syntax, "<string>", source);
|
auto tokens = tokenize(syntax, "<string>", source);
|
||||||
return build_styles(tokens);
|
return build_styles(colorScheme, tokens);
|
||||||
} catch (const parsing_error& err) {
|
} catch (const parsing_error& err) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,9 @@ namespace devtools {
|
||||||
class SyntaxProcessor {
|
class SyntaxProcessor {
|
||||||
public:
|
public:
|
||||||
std::unique_ptr<FontStylesScheme> highlight(
|
std::unique_ptr<FontStylesScheme> highlight(
|
||||||
const std::string& ext, std::wstring_view source
|
const FontStylesScheme& colorScheme,
|
||||||
|
const std::string& ext,
|
||||||
|
std::wstring_view source
|
||||||
) const;
|
) const;
|
||||||
|
|
||||||
void addSyntax(std::unique_ptr<Syntax> syntax);
|
void addSyntax(std::unique_ptr<Syntax> syntax);
|
||||||
|
|
|
||||||
|
|
@ -23,11 +23,12 @@ void UiDocument::rebuildIndices() {
|
||||||
map["root"] = root;
|
map["root"] = root;
|
||||||
}
|
}
|
||||||
|
|
||||||
const UINodesMap& UiDocument::getMap() const {
|
void UiDocument::pushIndices(const std::shared_ptr<gui::UINode>& node) {
|
||||||
return map;
|
gui::UINode::getIndices(node, map);
|
||||||
|
map["root"] = root;
|
||||||
}
|
}
|
||||||
|
|
||||||
UINodesMap& UiDocument::getMapWriteable() {
|
const UINodesMap& UiDocument::getMap() const {
|
||||||
return map;
|
return map;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -36,10 +36,10 @@ public:
|
||||||
);
|
);
|
||||||
|
|
||||||
void rebuildIndices();
|
void rebuildIndices();
|
||||||
|
void pushIndices(const std::shared_ptr<gui::UINode>& node);
|
||||||
|
|
||||||
const std::string& getId() const;
|
const std::string& getId() const;
|
||||||
const UINodesMap& getMap() const;
|
const UINodesMap& getMap() const;
|
||||||
UINodesMap& getMapWriteable();
|
|
||||||
std::shared_ptr<gui::UINode> getRoot() const;
|
std::shared_ptr<gui::UINode> getRoot() const;
|
||||||
std::shared_ptr<gui::UINode> get(const std::string& id) const;
|
std::shared_ptr<gui::UINode> get(const std::string& id) const;
|
||||||
const uidocscript& getScript() const;
|
const uidocscript& getScript() const;
|
||||||
|
|
|
||||||
37
src/graphics/commons/FontStyle.cpp
Normal file
37
src/graphics/commons/FontStyle.cpp
Normal file
|
|
@ -0,0 +1,37 @@
|
||||||
|
#include "FontStyle.hpp"
|
||||||
|
|
||||||
|
#include "data/dv.hpp"
|
||||||
|
#include "data/dv_util.hpp"
|
||||||
|
#include "devtools/SyntaxProcessor.hpp"
|
||||||
|
|
||||||
|
FontStyle FontStyle::parse(const dv::value& src) {
|
||||||
|
FontStyle style {};
|
||||||
|
src.at("bold").get(style.bold);
|
||||||
|
src.at("italic").get(style.italic);
|
||||||
|
src.at("strikethrough").get(style.strikethrough);
|
||||||
|
src.at("underline").get(style.underline);
|
||||||
|
dv::get_vec(src, "color", style.color);
|
||||||
|
return style;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void parse_style(
|
||||||
|
const dv::value& src,
|
||||||
|
FontStylesScheme& scheme,
|
||||||
|
const std::string& name,
|
||||||
|
devtools::SyntaxStyles tag
|
||||||
|
) {
|
||||||
|
if (src.has(name)) {
|
||||||
|
scheme.palette[static_cast<int>(tag)] = FontStyle::parse(src[name]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FontStylesScheme FontStylesScheme::parse(const dv::value& src) {
|
||||||
|
FontStylesScheme scheme {};
|
||||||
|
scheme.palette.resize(8);
|
||||||
|
parse_style(src, scheme, "default", devtools::SyntaxStyles::DEFAULT);
|
||||||
|
parse_style(src, scheme, "keyword", devtools::SyntaxStyles::KEYWORD);
|
||||||
|
parse_style(src, scheme, "literal", devtools::SyntaxStyles::LITERAL);
|
||||||
|
parse_style(src, scheme, "comment", devtools::SyntaxStyles::COMMENT);
|
||||||
|
parse_style(src, scheme, "error", devtools::SyntaxStyles::ERROR);
|
||||||
|
return scheme;
|
||||||
|
}
|
||||||
39
src/graphics/commons/FontStyle.hpp
Normal file
39
src/graphics/commons/FontStyle.hpp
Normal file
|
|
@ -0,0 +1,39 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "data/dv_fwd.hpp"
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
#include <glm/glm.hpp>
|
||||||
|
|
||||||
|
struct FontStyle {
|
||||||
|
bool bold = false;
|
||||||
|
bool italic = false;
|
||||||
|
bool strikethrough = false;
|
||||||
|
bool underline = false;
|
||||||
|
glm::vec4 color {1, 1, 1, 1};
|
||||||
|
|
||||||
|
FontStyle() = default;
|
||||||
|
|
||||||
|
FontStyle(
|
||||||
|
bool bold,
|
||||||
|
bool italic,
|
||||||
|
bool strikethrough,
|
||||||
|
bool underline,
|
||||||
|
glm::vec4 color
|
||||||
|
)
|
||||||
|
: bold(bold),
|
||||||
|
italic(italic),
|
||||||
|
strikethrough(strikethrough),
|
||||||
|
underline(underline),
|
||||||
|
color(std::move(color)) {
|
||||||
|
}
|
||||||
|
|
||||||
|
static FontStyle parse(const dv::value& src);
|
||||||
|
};
|
||||||
|
|
||||||
|
struct FontStylesScheme {
|
||||||
|
std::vector<FontStyle> palette;
|
||||||
|
std::vector<unsigned char> map;
|
||||||
|
|
||||||
|
static FontStylesScheme parse(const dv::value& src);
|
||||||
|
};
|
||||||
|
|
@ -7,41 +7,14 @@
|
||||||
|
|
||||||
#include "typedefs.hpp"
|
#include "typedefs.hpp"
|
||||||
#include "FontMetics.hpp"
|
#include "FontMetics.hpp"
|
||||||
|
#include "data/dv_fwd.hpp"
|
||||||
|
#include "../commons/FontStyle.hpp"
|
||||||
|
|
||||||
class Texture;
|
class Texture;
|
||||||
class Batch2D;
|
class Batch2D;
|
||||||
class Batch3D;
|
class Batch3D;
|
||||||
class Camera;
|
class Camera;
|
||||||
|
|
||||||
struct FontStyle {
|
|
||||||
bool bold = false;
|
|
||||||
bool italic = false;
|
|
||||||
bool strikethrough = false;
|
|
||||||
bool underline = false;
|
|
||||||
glm::vec4 color {1, 1, 1, 1};
|
|
||||||
|
|
||||||
FontStyle() = default;
|
|
||||||
|
|
||||||
FontStyle(
|
|
||||||
bool bold,
|
|
||||||
bool italic,
|
|
||||||
bool strikethrough,
|
|
||||||
bool underline,
|
|
||||||
glm::vec4 color
|
|
||||||
)
|
|
||||||
: bold(bold),
|
|
||||||
italic(italic),
|
|
||||||
strikethrough(strikethrough),
|
|
||||||
underline(underline),
|
|
||||||
color(std::move(color)) {
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct FontStylesScheme {
|
|
||||||
std::vector<FontStyle> palette;
|
|
||||||
std::vector<ubyte> map;
|
|
||||||
};
|
|
||||||
|
|
||||||
class Font {
|
class Font {
|
||||||
int lineHeight;
|
int lineHeight;
|
||||||
int yoffset;
|
int yoffset;
|
||||||
|
|
|
||||||
|
|
@ -80,6 +80,14 @@ std::shared_ptr<Menu> GUI::getMenu() {
|
||||||
return menu;
|
return menu;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GUI::setSyntaxColorScheme(std::unique_ptr<FontStylesScheme> scheme) {
|
||||||
|
syntaxColorScheme = std::move(scheme);
|
||||||
|
}
|
||||||
|
|
||||||
|
FontStylesScheme* GUI::getSyntaxColorScheme() const {
|
||||||
|
return syntaxColorScheme.get();
|
||||||
|
}
|
||||||
|
|
||||||
void GUI::onAssetsLoad(Assets* assets) {
|
void GUI::onAssetsLoad(Assets* assets) {
|
||||||
rootDocument->rebuildIndices();
|
rootDocument->rebuildIndices();
|
||||||
assets->store(rootDocument, "core:root");
|
assets->store(rootDocument, "core:root");
|
||||||
|
|
@ -302,7 +310,7 @@ bool GUI::isFocusCaught() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
void GUI::add(std::shared_ptr<UINode> node) {
|
void GUI::add(std::shared_ptr<UINode> node) {
|
||||||
UINode::getIndices(node, rootDocument->getMapWriteable());
|
rootDocument->pushIndices(node);
|
||||||
container->add(std::move(node));
|
container->add(std::move(node));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,7 @@ struct CursorState;
|
||||||
class Engine;
|
class Engine;
|
||||||
class Input;
|
class Input;
|
||||||
class Window;
|
class Window;
|
||||||
|
struct FontStylesScheme;
|
||||||
|
|
||||||
namespace devtools {
|
namespace devtools {
|
||||||
class Editor;
|
class Editor;
|
||||||
|
|
@ -73,6 +74,7 @@ namespace gui {
|
||||||
std::shared_ptr<UINode> focus;
|
std::shared_ptr<UINode> focus;
|
||||||
std::shared_ptr<UINode> tooltip;
|
std::shared_ptr<UINode> tooltip;
|
||||||
std::shared_ptr<UiDocument> rootDocument;
|
std::shared_ptr<UiDocument> rootDocument;
|
||||||
|
std::unique_ptr<FontStylesScheme> syntaxColorScheme;
|
||||||
std::unordered_map<std::string, std::shared_ptr<UINode>> storage;
|
std::unordered_map<std::string, std::shared_ptr<UINode>> storage;
|
||||||
|
|
||||||
std::unique_ptr<Camera> uicamera;
|
std::unique_ptr<Camera> uicamera;
|
||||||
|
|
@ -157,6 +159,9 @@ namespace gui {
|
||||||
/// @deprecated
|
/// @deprecated
|
||||||
std::shared_ptr<Container> getContainer() const;
|
std::shared_ptr<Container> getContainer() const;
|
||||||
|
|
||||||
|
void setSyntaxColorScheme(std::unique_ptr<FontStylesScheme> scheme);
|
||||||
|
FontStylesScheme* getSyntaxColorScheme() const;
|
||||||
|
|
||||||
void onAssetsLoad(Assets* assets);
|
void onAssetsLoad(Assets* assets);
|
||||||
|
|
||||||
void postRunnable(const runnable& callback);
|
void postRunnable(const runnable& callback);
|
||||||
|
|
|
||||||
|
|
@ -918,7 +918,9 @@ void TextBox::onTab(bool shiftPressed) {
|
||||||
void TextBox::refreshSyntax() {
|
void TextBox::refreshSyntax() {
|
||||||
if (!syntax.empty()) {
|
if (!syntax.empty()) {
|
||||||
const auto& processor = gui.getEditor().getSyntaxProcessor();
|
const auto& processor = gui.getEditor().getSyntaxProcessor();
|
||||||
if (auto styles = processor.highlight(syntax, input)) {
|
auto scheme = gui.getSyntaxColorScheme();
|
||||||
|
if (auto styles =
|
||||||
|
processor.highlight(scheme ? *scheme : FontStylesScheme {}, syntax, input)) {
|
||||||
label->setStyles(std::move(styles));
|
label->setStyles(std::move(styles));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -16,18 +16,23 @@ LightSolver::LightSolver(const ContentIndices& contentIds, Chunks& chunks, int c
|
||||||
}
|
}
|
||||||
|
|
||||||
void LightSolver::add(int x, int y, int z, int emission) {
|
void LightSolver::add(int x, int y, int z, int emission) {
|
||||||
if (emission <= 1)
|
if (emission <= 1) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
Chunk* chunk = chunks.getChunkByVoxel(x, y, z);
|
Chunk* chunk = chunks.getChunkByVoxel(x, y, z);
|
||||||
if (chunk == nullptr)
|
if (chunk == nullptr) {
|
||||||
return;
|
return;
|
||||||
ubyte light = chunk->lightmap.get(x-chunk->x*CHUNK_W, y, z-chunk->z*CHUNK_D, channel);
|
}
|
||||||
|
assert(chunk->lightmap != nullptr);
|
||||||
|
auto& lightmap = *chunk->lightmap;
|
||||||
|
|
||||||
|
ubyte light = lightmap.get(x-chunk->x*CHUNK_W, y, z-chunk->z*CHUNK_D, channel);
|
||||||
if (emission < light) return;
|
if (emission < light) return;
|
||||||
|
|
||||||
addqueue.push(lightentry {x, y, z, ubyte(emission)});
|
addqueue.push(lightentry {x, y, z, ubyte(emission)});
|
||||||
|
|
||||||
chunk->flags.modified = true;
|
chunk->flags.modified = true;
|
||||||
chunk->lightmap.set(x-chunk->x*CHUNK_W, y, z-chunk->z*CHUNK_D, channel, emission);
|
lightmap.set(x-chunk->x*CHUNK_W, y, z-chunk->z*CHUNK_D, channel, emission);
|
||||||
}
|
}
|
||||||
|
|
||||||
void LightSolver::add(int x, int y, int z) {
|
void LightSolver::add(int x, int y, int z) {
|
||||||
|
|
@ -36,15 +41,18 @@ void LightSolver::add(int x, int y, int z) {
|
||||||
|
|
||||||
void LightSolver::remove(int x, int y, int z) {
|
void LightSolver::remove(int x, int y, int z) {
|
||||||
Chunk* chunk = chunks.getChunkByVoxel(x, y, z);
|
Chunk* chunk = chunks.getChunkByVoxel(x, y, z);
|
||||||
if (chunk == nullptr)
|
if (chunk == nullptr) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
assert(chunk->lightmap != nullptr);
|
||||||
|
auto& lightmap = *chunk->lightmap;
|
||||||
|
|
||||||
ubyte light = chunk->lightmap.get(x-chunk->x*CHUNK_W, y, z-chunk->z*CHUNK_D, channel);
|
ubyte light = lightmap.get(x-chunk->x*CHUNK_W, y, z-chunk->z*CHUNK_D, channel);
|
||||||
if (light == 0){
|
if (light == 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
remqueue.push(lightentry {x, y, z, light});
|
remqueue.push(lightentry {x, y, z, light});
|
||||||
chunk->lightmap.set(x-chunk->x*CHUNK_W, y, z-chunk->z*CHUNK_D, channel, 0);
|
lightmap.set(x-chunk->x*CHUNK_W, y, z-chunk->z*CHUNK_D, channel, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void LightSolver::solve(){
|
void LightSolver::solve(){
|
||||||
|
|
@ -73,18 +81,21 @@ void LightSolver::solve(){
|
||||||
int lz = z - chunk->z * CHUNK_D;
|
int lz = z - chunk->z * CHUNK_D;
|
||||||
chunk->flags.modified = true;
|
chunk->flags.modified = true;
|
||||||
|
|
||||||
ubyte light = chunk->lightmap.get(lx,y,lz, channel);
|
assert(chunk->lightmap != nullptr);
|
||||||
|
auto& lightmap = *chunk->lightmap;
|
||||||
|
|
||||||
|
ubyte light = lightmap.get(lx,y,lz, channel);
|
||||||
if (light != 0 && light == entry.light-1){
|
if (light != 0 && light == entry.light-1){
|
||||||
voxel* vox = chunks.get(x, y, z);
|
voxel* vox = chunks.get(x, y, z);
|
||||||
if (vox && vox->id != 0) {
|
if (vox && vox->id != 0) {
|
||||||
const Block* block = blockDefs[vox->id];
|
const Block* block = blockDefs[vox->id];
|
||||||
if (uint8_t emission = block->emission[channel]) {
|
if (uint8_t emission = block->emission[channel]) {
|
||||||
addqueue.push(lightentry {x, y, z, emission});
|
addqueue.push(lightentry {x, y, z, emission});
|
||||||
chunk->lightmap.set(lx, y, lz, channel, emission);
|
lightmap.set(lx, y, lz, channel, emission);
|
||||||
}
|
}
|
||||||
else chunk->lightmap.set(lx, y, lz, channel, 0);
|
else lightmap.set(lx, y, lz, channel, 0);
|
||||||
}
|
}
|
||||||
else chunk->lightmap.set(lx, y, lz, channel, 0);
|
else lightmap.set(lx, y, lz, channel, 0);
|
||||||
remqueue.push(lightentry {x, y, z, light});
|
remqueue.push(lightentry {x, y, z, light});
|
||||||
}
|
}
|
||||||
else if (light >= entry.light){
|
else if (light >= entry.light){
|
||||||
|
|
@ -105,21 +116,24 @@ void LightSolver::solve(){
|
||||||
int z = entry.z+coords[imul3+2];
|
int z = entry.z+coords[imul3+2];
|
||||||
|
|
||||||
Chunk* chunk = chunks.getChunkByVoxel(x,y,z);
|
Chunk* chunk = chunks.getChunkByVoxel(x,y,z);
|
||||||
if (chunk) {
|
if (chunk == nullptr) {
|
||||||
int lx = x - chunk->x * CHUNK_W;
|
continue;
|
||||||
int lz = z - chunk->z * CHUNK_D;
|
}
|
||||||
chunk->flags.modified = true;
|
assert(chunk->lightmap != nullptr);
|
||||||
|
auto& lightmap = *chunk->lightmap;
|
||||||
|
int lx = x - chunk->x * CHUNK_W;
|
||||||
|
int lz = z - chunk->z * CHUNK_D;
|
||||||
|
chunk->flags.modified = true;
|
||||||
|
|
||||||
ubyte light = chunk->lightmap.get(lx, y, lz, channel);
|
ubyte light = lightmap.get(lx, y, lz, channel);
|
||||||
voxel& v = chunk->voxels[vox_index(lx, y, lz)];
|
voxel& v = chunk->voxels[vox_index(lx, y, lz)];
|
||||||
const Block* block = blockDefs[v.id];
|
const Block* block = blockDefs[v.id];
|
||||||
if (block->lightPassing && light+2 <= entry.light){
|
if (block->lightPassing && light+2 <= entry.light){
|
||||||
chunk->lightmap.set(
|
lightmap.set(
|
||||||
x-chunk->x*CHUNK_W, y, z-chunk->z*CHUNK_D,
|
x-chunk->x*CHUNK_W, y, z-chunk->z*CHUNK_D,
|
||||||
channel,
|
channel,
|
||||||
entry.light-1);
|
entry.light-1);
|
||||||
addqueue.push(lightentry {x, y, z, ubyte(entry.light-1)});
|
addqueue.push(lightentry {x, y, z, ubyte(entry.light-1)});
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -29,16 +29,21 @@ void Lighting::clear(){
|
||||||
const auto& chunks = this->chunks.getChunks();
|
const auto& chunks = this->chunks.getChunks();
|
||||||
for (size_t index = 0; index < chunks.size(); index++){
|
for (size_t index = 0; index < chunks.size(); index++){
|
||||||
auto chunk = chunks[index];
|
auto chunk = chunks[index];
|
||||||
if (chunk == nullptr)
|
if (chunk == nullptr) {
|
||||||
continue;
|
continue;
|
||||||
Lightmap& lightmap = chunk->lightmap;
|
|
||||||
for (int i = 0; i < CHUNK_VOL; i++){
|
|
||||||
lightmap.map[i] = 0;
|
|
||||||
}
|
}
|
||||||
|
auto& lightmap = chunk->lightmap;
|
||||||
|
if (lightmap == nullptr) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
std::memset(lightmap->map, 0, sizeof(Lightmap::map));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Lighting::prebuildSkyLight(Chunk& chunk, const ContentIndices& indices){
|
void Lighting::prebuildSkyLight(Chunk& chunk, const ContentIndices& indices) {
|
||||||
|
assert(chunk.lightmap != nullptr);
|
||||||
|
auto& lightmap = *chunk.lightmap;
|
||||||
|
|
||||||
const auto* blockDefs = indices.blocks.getDefs();
|
const auto* blockDefs = indices.blocks.getDefs();
|
||||||
|
|
||||||
int highestPoint = 0;
|
int highestPoint = 0;
|
||||||
|
|
@ -49,17 +54,19 @@ void Lighting::prebuildSkyLight(Chunk& chunk, const ContentIndices& indices){
|
||||||
voxel& vox = chunk.voxels[index];
|
voxel& vox = chunk.voxels[index];
|
||||||
const Block* block = blockDefs[vox.id];
|
const Block* block = blockDefs[vox.id];
|
||||||
if (!block->skyLightPassing) {
|
if (!block->skyLightPassing) {
|
||||||
if (highestPoint < y)
|
if (highestPoint < y) {
|
||||||
highestPoint = y;
|
highestPoint = y;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
chunk.lightmap.setS(x,y,z, 15);
|
lightmap.setS(x, y, z, 15);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (highestPoint < CHUNK_H-1)
|
if (highestPoint < CHUNK_H-1) {
|
||||||
highestPoint++;
|
highestPoint++;
|
||||||
chunk.lightmap.highestPoint = highestPoint;
|
}
|
||||||
|
lightmap.highestPoint = highestPoint;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Lighting::buildSkyLight(int cx, int cz){
|
void Lighting::buildSkyLight(int cx, int cz){
|
||||||
|
|
@ -70,15 +77,18 @@ void Lighting::buildSkyLight(int cx, int cz){
|
||||||
logger.error() << "attempted to build sky lights to chunk missing in local matrix";
|
logger.error() << "attempted to build sky lights to chunk missing in local matrix";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
assert(chunk->lightmap != nullptr);
|
||||||
|
auto& lightmap = *chunk->lightmap;
|
||||||
|
|
||||||
for (int z = 0; z < CHUNK_D; z++){
|
for (int z = 0; z < CHUNK_D; z++){
|
||||||
for (int x = 0; x < CHUNK_W; x++){
|
for (int x = 0; x < CHUNK_W; x++){
|
||||||
int gx = x + cx * CHUNK_W;
|
int gx = x + cx * CHUNK_W;
|
||||||
int gz = z + cz * CHUNK_D;
|
int gz = z + cz * CHUNK_D;
|
||||||
for (int y = chunk->lightmap.highestPoint; y >= 0; y--){
|
for (int y = lightmap.highestPoint; y >= 0; y--){
|
||||||
while (y > 0 && !blockDefs[chunk->voxels[vox_index(x, y, z)].id]->lightPassing) {
|
while (y > 0 && !blockDefs[chunk->voxels[vox_index(x, y, z)].id]->lightPassing) {
|
||||||
y--;
|
y--;
|
||||||
}
|
}
|
||||||
if (chunk->lightmap.getS(x, y, z) != 15) {
|
if (lightmap.getS(x, y, z) != 15) {
|
||||||
solverS->add(gx,y+1,gz);
|
solverS->add(gx,y+1,gz);
|
||||||
for (; y >= 0; y--){
|
for (; y >= 0; y--){
|
||||||
solverS->add(gx+1,y,gz);
|
solverS->add(gx+1,y,gz);
|
||||||
|
|
@ -106,6 +116,9 @@ void Lighting::onChunkLoaded(int cx, int cz, bool expand) {
|
||||||
logger.error() << "attempted to build lights to chunk missing in local matrix";
|
logger.error() << "attempted to build lights to chunk missing in local matrix";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
assert(chunk->lightmap != nullptr);
|
||||||
|
auto& lightmap = *chunk->lightmap;
|
||||||
|
|
||||||
for (uint y = 0; y < CHUNK_H; y++){
|
for (uint y = 0; y < CHUNK_H; y++){
|
||||||
for (uint z = 0; z < CHUNK_D; z++){
|
for (uint z = 0; z < CHUNK_D; z++){
|
||||||
for (uint x = 0; x < CHUNK_W; x++){
|
for (uint x = 0; x < CHUNK_W; x++){
|
||||||
|
|
@ -128,7 +141,7 @@ void Lighting::onChunkLoaded(int cx, int cz, bool expand) {
|
||||||
for (int z = 0; z < CHUNK_D; z++) {
|
for (int z = 0; z < CHUNK_D; z++) {
|
||||||
int gx = x + cx * CHUNK_W;
|
int gx = x + cx * CHUNK_W;
|
||||||
int gz = z + cz * CHUNK_D;
|
int gz = z + cz * CHUNK_D;
|
||||||
int rgbs = chunk->lightmap.get(x, y, z);
|
int rgbs = lightmap.get(x, y, z);
|
||||||
if (rgbs){
|
if (rgbs){
|
||||||
solverR.add(gx,y,gz, Lightmap::extract(rgbs, 0));
|
solverR.add(gx,y,gz, Lightmap::extract(rgbs, 0));
|
||||||
solverG.add(gx,y,gz, Lightmap::extract(rgbs, 1));
|
solverG.add(gx,y,gz, Lightmap::extract(rgbs, 1));
|
||||||
|
|
@ -143,7 +156,7 @@ void Lighting::onChunkLoaded(int cx, int cz, bool expand) {
|
||||||
for (int x = 0; x < CHUNK_W; x++) {
|
for (int x = 0; x < CHUNK_W; x++) {
|
||||||
int gx = x + cx * CHUNK_W;
|
int gx = x + cx * CHUNK_W;
|
||||||
int gz = z + cz * CHUNK_D;
|
int gz = z + cz * CHUNK_D;
|
||||||
int rgbs = chunk->lightmap.get(x, y, z);
|
int rgbs = lightmap.get(x, y, z);
|
||||||
if (rgbs){
|
if (rgbs){
|
||||||
solverR.add(gx,y,gz, Lightmap::extract(rgbs, 0));
|
solverR.add(gx,y,gz, Lightmap::extract(rgbs, 0));
|
||||||
solverG.add(gx,y,gz, Lightmap::extract(rgbs, 1));
|
solverG.add(gx,y,gz, Lightmap::extract(rgbs, 1));
|
||||||
|
|
|
||||||
|
|
@ -89,4 +89,6 @@ public:
|
||||||
|
|
||||||
std::unique_ptr<ubyte[]> encode() const;
|
std::unique_ptr<ubyte[]> encode() const;
|
||||||
static std::unique_ptr<light_t[]> decode(const ubyte* buffer);
|
static std::unique_ptr<light_t[]> decode(const ubyte* buffer);
|
||||||
|
|
||||||
|
static inline light_t SUN_LIGHT_ONLY = combine(0U, 0U, 0U, 15U);
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -150,7 +150,7 @@ bool ChunksController::buildLights(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (surrounding == MIN_SURROUNDING) {
|
if (surrounding == MIN_SURROUNDING) {
|
||||||
if (lighting) {
|
if (lighting && chunk->lightmap) {
|
||||||
bool lightsCache = chunk->flags.loadedLights;
|
bool lightsCache = chunk->flags.loadedLights;
|
||||||
if (!lightsCache) {
|
if (!lightsCache) {
|
||||||
lighting->buildSkyLight(chunk->x, chunk->z);
|
lighting->buildSkyLight(chunk->x, chunk->z);
|
||||||
|
|
@ -170,7 +170,7 @@ void ChunksController::createChunk(const Player& player, int x, int z) const {
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
auto chunk = level.chunks->create(x, z);
|
auto chunk = level.chunks->create(x, z, lighting != nullptr);
|
||||||
player.chunks->putChunk(chunk);
|
player.chunks->putChunk(chunk);
|
||||||
auto& chunkFlags = chunk->flags;
|
auto& chunkFlags = chunk->flags;
|
||||||
if (!chunkFlags.loaded) {
|
if (!chunkFlags.loaded) {
|
||||||
|
|
@ -179,7 +179,7 @@ void ChunksController::createChunk(const Player& player, int x, int z) const {
|
||||||
}
|
}
|
||||||
chunk->updateHeights();
|
chunk->updateHeights();
|
||||||
level.events->trigger(LevelEventType::CHUNK_PRESENT, chunk.get());
|
level.events->trigger(LevelEventType::CHUNK_PRESENT, chunk.get());
|
||||||
if (!chunkFlags.loadedLights) {
|
if (!chunkFlags.loadedLights && chunk->lightmap) {
|
||||||
Lighting::prebuildSkyLight(*chunk, *level.content.getIndices());
|
Lighting::prebuildSkyLight(*chunk, *level.content.getIndices());
|
||||||
}
|
}
|
||||||
chunkFlags.loaded = true;
|
chunkFlags.loaded = true;
|
||||||
|
|
|
||||||
|
|
@ -105,7 +105,7 @@ static int l_container_add(lua::State* L) {
|
||||||
auto subnode = guiutil::create(
|
auto subnode = guiutil::create(
|
||||||
engine->getGUI(), xmlsrc, std::move(env)
|
engine->getGUI(), xmlsrc, std::move(env)
|
||||||
);
|
);
|
||||||
UINode::getIndices(subnode, docnode.document->getMapWriteable());
|
docnode.document->pushIndices(subnode);
|
||||||
node->add(std::move(subnode));
|
node->add(std::move(subnode));
|
||||||
} catch (const std::exception& err) {
|
} catch (const std::exception& err) {
|
||||||
throw std::runtime_error("container:add(...): " + std::string(err.what()));
|
throw std::runtime_error("container:add(...): " + std::string(err.what()));
|
||||||
|
|
@ -410,9 +410,7 @@ static const std::string& request_node_id(const DocumentNode& docnode) {
|
||||||
reinterpret_cast<std::ptrdiff_t>(docnode.node.get()));
|
reinterpret_cast<std::ptrdiff_t>(docnode.node.get()));
|
||||||
}
|
}
|
||||||
docnode.node->setId(std::move(id));
|
docnode.node->setId(std::move(id));
|
||||||
UINode::getIndices(
|
docnode.document->pushIndices(docnode.node);
|
||||||
docnode.node, docnode.document->getMapWriteable()
|
|
||||||
);
|
|
||||||
return docnode.node->getId();
|
return docnode.node->getId();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1089,6 +1087,16 @@ static int l_gui_load_document(lua::State* L) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int l_set_syntax_styles(lua::State* L) {
|
||||||
|
if (engine->isHeadless()) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
engine->getGUI().setSyntaxColorScheme(std::make_unique<FontStylesScheme>(
|
||||||
|
FontStylesScheme::parse(lua::tovalue(L, 1))
|
||||||
|
));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
const luaL_Reg guilib[] = {
|
const luaL_Reg guilib[] = {
|
||||||
{"get_viewport", lua::wrap<l_gui_getviewport>},
|
{"get_viewport", lua::wrap<l_gui_getviewport>},
|
||||||
{"getattr", lua::wrap<l_gui_getattr>},
|
{"getattr", lua::wrap<l_gui_getattr>},
|
||||||
|
|
@ -1101,6 +1109,7 @@ const luaL_Reg guilib[] = {
|
||||||
{"confirm", lua::wrap<l_gui_confirm>},
|
{"confirm", lua::wrap<l_gui_confirm>},
|
||||||
{"alert", lua::wrap<l_gui_alert>},
|
{"alert", lua::wrap<l_gui_alert>},
|
||||||
{"load_document", lua::wrap<l_gui_load_document>},
|
{"load_document", lua::wrap<l_gui_load_document>},
|
||||||
|
{"set_syntax_styles", lua::wrap<l_set_syntax_styles>},
|
||||||
{"__reindex", lua::wrap<l_gui_reindex>},
|
{"__reindex", lua::wrap<l_gui_reindex>},
|
||||||
{nullptr, nullptr}
|
{nullptr, nullptr}
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -88,6 +88,11 @@ static int l_escape(lua::State* L) {
|
||||||
return lua::pushstring(L, util::escape(string));
|
return lua::pushstring(L, util::escape(string));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int l_escape_xml(lua::State* L) {
|
||||||
|
auto string = lua::require_wstring(L, 1);
|
||||||
|
return lua::pushwstring(L, util::escape_xml(string));
|
||||||
|
}
|
||||||
|
|
||||||
const luaL_Reg utf8lib[] = {
|
const luaL_Reg utf8lib[] = {
|
||||||
{"tobytes", lua::wrap<l_tobytes>},
|
{"tobytes", lua::wrap<l_tobytes>},
|
||||||
{"tostring", lua::wrap<l_tostring>},
|
{"tostring", lua::wrap<l_tostring>},
|
||||||
|
|
@ -98,5 +103,6 @@ const luaL_Reg utf8lib[] = {
|
||||||
{"lower", lua::wrap<l_lower>},
|
{"lower", lua::wrap<l_lower>},
|
||||||
{"encode", lua::wrap<l_encode>},
|
{"encode", lua::wrap<l_encode>},
|
||||||
{"escape", lua::wrap<l_escape>},
|
{"escape", lua::wrap<l_escape>},
|
||||||
|
{"escape_xml", lua::wrap<l_escape_xml>},
|
||||||
{nullptr, nullptr}
|
{nullptr, nullptr}
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -153,8 +153,10 @@ static void integrate_chunk_client(Chunk& chunk) {
|
||||||
|
|
||||||
chunk.flags.loadedLights = false;
|
chunk.flags.loadedLights = false;
|
||||||
chunk.flags.lighted = false;
|
chunk.flags.lighted = false;
|
||||||
chunk.lightmap.clear();
|
if (chunk.lightmap) {
|
||||||
Lighting::prebuildSkyLight(chunk, *indices);
|
chunk.lightmap->clear();
|
||||||
|
Lighting::prebuildSkyLight(chunk, *indices);
|
||||||
|
}
|
||||||
|
|
||||||
for (int lz = -1; lz <= 1; lz++) {
|
for (int lz = -1; lz <= 1; lz++) {
|
||||||
for (int lx = -1; lx <= 1; lx++) {
|
for (int lx = -1; lx <= 1; lx++) {
|
||||||
|
|
|
||||||
|
|
@ -60,6 +60,33 @@ std::string util::escape(std::string_view s, bool escapeUnicode) {
|
||||||
return ss.str();
|
return ss.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::wstring util::escape_xml(std::wstring_view s) {
|
||||||
|
std::wstringstream ss;
|
||||||
|
for (wchar_t c : s) {
|
||||||
|
switch (c) {
|
||||||
|
case L'&':
|
||||||
|
ss << L"&";
|
||||||
|
break;
|
||||||
|
case L'<':
|
||||||
|
ss << L"<";
|
||||||
|
break;
|
||||||
|
case L'>':
|
||||||
|
ss << L">";
|
||||||
|
break;
|
||||||
|
case '"':
|
||||||
|
ss << L""";
|
||||||
|
break;
|
||||||
|
case '\'':
|
||||||
|
ss << L"'";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
ss << c;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ss.str();
|
||||||
|
}
|
||||||
|
|
||||||
std::string util::quote(const std::string& s) {
|
std::string util::quote(const std::string& s) {
|
||||||
return escape(s, false);
|
return escape(s, false);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,9 @@ namespace util {
|
||||||
/// @brief Function used for string serialization in text formats
|
/// @brief Function used for string serialization in text formats
|
||||||
std::string escape(std::string_view s, bool escapeUnicode=true);
|
std::string escape(std::string_view s, bool escapeUnicode=true);
|
||||||
|
|
||||||
|
/// @brief Escape all special XML characters
|
||||||
|
std::wstring escape_xml(std::wstring_view s);
|
||||||
|
|
||||||
/// @brief Function used for error messages
|
/// @brief Function used for error messages
|
||||||
std::string quote(const std::string& s);
|
std::string quote(const std::string& s);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,8 @@
|
||||||
#include "util/data_io.hpp"
|
#include "util/data_io.hpp"
|
||||||
#include "voxel.hpp"
|
#include "voxel.hpp"
|
||||||
|
|
||||||
Chunk::Chunk(int xpos, int zpos) : x(xpos), z(zpos) {
|
Chunk::Chunk(int xpos, int zpos, std::shared_ptr<Lightmap> lightmap)
|
||||||
|
: x(xpos), z(zpos), lightmap(std::move(lightmap)) {
|
||||||
bottom = 0;
|
bottom = 0;
|
||||||
top = CHUNK_H;
|
top = CHUNK_H;
|
||||||
}
|
}
|
||||||
|
|
@ -56,15 +57,6 @@ std::shared_ptr<Inventory> Chunk::getBlockInventory(uint x, uint y, uint z)
|
||||||
return found->second;
|
return found->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<Chunk> Chunk::clone() const {
|
|
||||||
auto other = std::make_unique<Chunk>(x, z);
|
|
||||||
for (uint i = 0; i < CHUNK_VOL; i++) {
|
|
||||||
other->voxels[i] = voxels[i];
|
|
||||||
}
|
|
||||||
other->lightmap.set(&lightmap);
|
|
||||||
return other;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Current chunk format:
|
Current chunk format:
|
||||||
- byte-order: little-endian
|
- byte-order: little-endian
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,7 @@ public:
|
||||||
int x, z;
|
int x, z;
|
||||||
int bottom, top;
|
int bottom, top;
|
||||||
voxel voxels[CHUNK_VOL] {};
|
voxel voxels[CHUNK_VOL] {};
|
||||||
Lightmap lightmap;
|
std::shared_ptr<Lightmap> lightmap;
|
||||||
struct {
|
struct {
|
||||||
bool modified : 1;
|
bool modified : 1;
|
||||||
bool ready : 1;
|
bool ready : 1;
|
||||||
|
|
@ -45,14 +45,11 @@ public:
|
||||||
/// @brief Blocks metadata heap
|
/// @brief Blocks metadata heap
|
||||||
BlocksMetadata blocksMetadata;
|
BlocksMetadata blocksMetadata;
|
||||||
|
|
||||||
Chunk(int x, int z);
|
Chunk(int x, int z, std::shared_ptr<Lightmap> lightmap=nullptr);
|
||||||
|
|
||||||
/// @brief Refresh `bottom` and `top` values
|
/// @brief Refresh `bottom` and `top` values
|
||||||
void updateHeights();
|
void updateHeights();
|
||||||
|
|
||||||
// unused
|
|
||||||
std::unique_ptr<Chunk> clone() const;
|
|
||||||
|
|
||||||
/// @brief Creates new block inventory given size
|
/// @brief Creates new block inventory given size
|
||||||
/// @return inventory id or 0 if block does not exists
|
/// @return inventory id or 0 if block does not exists
|
||||||
void addBlockInventory(
|
void addBlockInventory(
|
||||||
|
|
|
||||||
|
|
@ -115,9 +115,10 @@ ubyte Chunks::getLight(int32_t x, int32_t y, int32_t z, int channel) const {
|
||||||
if (chunk == nullptr) {
|
if (chunk == nullptr) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
assert(chunk->lightmap != nullptr);
|
||||||
int lx = x - cx * CHUNK_W;
|
int lx = x - cx * CHUNK_W;
|
||||||
int lz = z - cz * CHUNK_D;
|
int lz = z - cz * CHUNK_D;
|
||||||
return chunk->lightmap.get(lx, y, lz, channel);
|
return chunk->lightmap->get(lx, y, lz, channel);
|
||||||
}
|
}
|
||||||
|
|
||||||
light_t Chunks::getLight(int32_t x, int32_t y, int32_t z) const {
|
light_t Chunks::getLight(int32_t x, int32_t y, int32_t z) const {
|
||||||
|
|
@ -135,9 +136,10 @@ light_t Chunks::getLight(int32_t x, int32_t y, int32_t z) const {
|
||||||
if (chunk == nullptr) {
|
if (chunk == nullptr) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
assert(chunk->lightmap != nullptr);
|
||||||
int lx = x - cx * CHUNK_W;
|
int lx = x - cx * CHUNK_W;
|
||||||
int lz = z - cz * CHUNK_D;
|
int lz = z - cz * CHUNK_D;
|
||||||
return chunk->lightmap.get(lx, y, lz);
|
return chunk->lightmap->get(lx, y, lz);
|
||||||
}
|
}
|
||||||
|
|
||||||
Chunk* Chunks::getChunkByVoxel(int32_t x, int32_t y, int32_t z) const {
|
Chunk* Chunks::getChunkByVoxel(int32_t x, int32_t y, int32_t z) const {
|
||||||
|
|
@ -373,7 +375,8 @@ void Chunks::getVoxels(VoxelsVolume& volume, bool backlight) const {
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
const voxel* cvoxels = chunk->voxels;
|
const voxel* cvoxels = chunk->voxels;
|
||||||
const light_t* clights = chunk->lightmap.getLights();
|
const light_t* clights =
|
||||||
|
chunk->lightmap ? chunk->lightmap->getLights() : nullptr;
|
||||||
for (int ly = y; ly < y + h; ly++) {
|
for (int ly = y; ly < y + h; ly++) {
|
||||||
for (int lz = std::max(z, cz * CHUNK_D);
|
for (int lz = std::max(z, cz * CHUNK_D);
|
||||||
lz < std::min(z + d, (cz + 1) * CHUNK_D);
|
lz < std::min(z + d, (cz + 1) * CHUNK_D);
|
||||||
|
|
@ -390,7 +393,8 @@ void Chunks::getVoxels(VoxelsVolume& volume, bool backlight) const {
|
||||||
CHUNK_D
|
CHUNK_D
|
||||||
);
|
);
|
||||||
voxels[vidx] = cvoxels[cidx];
|
voxels[vidx] = cvoxels[cidx];
|
||||||
light_t light = clights[cidx];
|
light_t light = clights ? clights[cidx]
|
||||||
|
: Lightmap::SUN_LIGHT_ONLY;
|
||||||
if (backlight) {
|
if (backlight) {
|
||||||
const auto block =
|
const auto block =
|
||||||
indices.blocks.get(voxels[vidx].id);
|
indices.blocks.get(voxels[vidx].id);
|
||||||
|
|
|
||||||
|
|
@ -91,14 +91,16 @@ static inline auto load_inventories(
|
||||||
}
|
}
|
||||||
|
|
||||||
static util::ObjectsPool<Chunk> chunks_pool(1'024);
|
static util::ObjectsPool<Chunk> chunks_pool(1'024);
|
||||||
|
static util::ObjectsPool<Lightmap> lightmaps_pool;
|
||||||
|
|
||||||
std::shared_ptr<Chunk> GlobalChunks::create(int x, int z) {
|
std::shared_ptr<Chunk> GlobalChunks::create(int x, int z, bool lighting) {
|
||||||
const auto& found = chunksMap.find(keyfrom(x, z));
|
const auto& found = chunksMap.find(keyfrom(x, z));
|
||||||
if (found != chunksMap.end()) {
|
if (found != chunksMap.end()) {
|
||||||
return found->second;
|
return found->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto chunk = chunks_pool.create(x, z);
|
auto chunk =
|
||||||
|
chunks_pool.create(x, z, lighting ? lightmaps_pool.create() : nullptr);
|
||||||
chunksMap[keyfrom(x, z)] = chunk;
|
chunksMap[keyfrom(x, z)] = chunk;
|
||||||
|
|
||||||
World& world = *level.getWorld();
|
World& world = *level.getWorld();
|
||||||
|
|
@ -125,9 +127,11 @@ std::shared_ptr<Chunk> GlobalChunks::create(int x, int z) {
|
||||||
level.inventories->store(entry.second);
|
level.inventories->store(entry.second);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (auto lights = regions.getLights(chunk->x, chunk->z)) {
|
if (chunk->lightmap) {
|
||||||
chunk->lightmap.set(lights.get());
|
if (auto lights = regions.getLights(chunk->x, chunk->z)) {
|
||||||
chunk->flags.loadedLights = true;
|
chunk->lightmap->set(lights.get());
|
||||||
|
chunk->flags.loadedLights = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
chunk->blocksMetadata = regions.getBlocksData(chunk->x, chunk->z);
|
chunk->blocksMetadata = regions.getBlocksData(chunk->x, chunk->z);
|
||||||
return chunk;
|
return chunk;
|
||||||
|
|
|
||||||
|
|
@ -40,7 +40,7 @@ public:
|
||||||
void setOnUnload(consumer<Chunk&> onUnload);
|
void setOnUnload(consumer<Chunk&> onUnload);
|
||||||
|
|
||||||
std::shared_ptr<Chunk> fetch(int x, int z);
|
std::shared_ptr<Chunk> fetch(int x, int z);
|
||||||
std::shared_ptr<Chunk> create(int x, int z);
|
std::shared_ptr<Chunk> create(int x, int z, bool lighting);
|
||||||
|
|
||||||
void pinChunk(std::shared_ptr<Chunk> chunk);
|
void pinChunk(std::shared_ptr<Chunk> chunk);
|
||||||
void unpinChunk(int x, int z);
|
void unpinChunk(int x, int z);
|
||||||
|
|
|
||||||
|
|
@ -434,7 +434,8 @@ inline void get_voxels_impl(
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
const voxel* cvoxels = chunk->voxels;
|
const voxel* cvoxels = chunk->voxels;
|
||||||
const light_t* clights = chunk->lightmap.getLights();
|
const light_t* clights =
|
||||||
|
chunk->lightmap ? chunk->lightmap->getLights() : nullptr;
|
||||||
for (int ly = y; ly < y + h; ly++) {
|
for (int ly = y; ly < y + h; ly++) {
|
||||||
for (int lz = std::max(z, cz * CHUNK_D);
|
for (int lz = std::max(z, cz * CHUNK_D);
|
||||||
lz < std::min(z + d, (cz + 1) * CHUNK_D);
|
lz < std::min(z + d, (cz + 1) * CHUNK_D);
|
||||||
|
|
@ -451,7 +452,8 @@ inline void get_voxels_impl(
|
||||||
CHUNK_D
|
CHUNK_D
|
||||||
);
|
);
|
||||||
voxels[vidx] = cvoxels[cidx];
|
voxels[vidx] = cvoxels[cidx];
|
||||||
light_t light = clights[cidx];
|
light_t light = clights ? clights[cidx]
|
||||||
|
: Lightmap::SUN_LIGHT_ONLY;
|
||||||
if (backlight) {
|
if (backlight) {
|
||||||
const auto block = blocks.get(voxels[vidx].id);
|
const auto block = blocks.get(voxels[vidx].id);
|
||||||
if (block && block->lightPassing) {
|
if (block && block->lightPassing) {
|
||||||
|
|
|
||||||
|
|
@ -175,11 +175,11 @@ void WorldRegions::put(Chunk* chunk, std::vector<ubyte> entitiesData) {
|
||||||
CHUNK_DATA_LEN);
|
CHUNK_DATA_LEN);
|
||||||
|
|
||||||
// Writing lights cache
|
// Writing lights cache
|
||||||
if (doWriteLights && chunk->flags.lighted) {
|
if (doWriteLights && chunk->flags.lighted && chunk->lightmap) {
|
||||||
put(chunk->x,
|
put(chunk->x,
|
||||||
chunk->z,
|
chunk->z,
|
||||||
REGION_LAYER_LIGHTS,
|
REGION_LAYER_LIGHTS,
|
||||||
chunk->lightmap.encode(),
|
chunk->lightmap->encode(),
|
||||||
LIGHTMAP_DATA_LEN);
|
LIGHTMAP_DATA_LEN);
|
||||||
}
|
}
|
||||||
// Writing block inventories
|
// Writing block inventories
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue