Merge branch 'MihailRis:main' into main

This commit is contained in:
Alex Zebra 2025-01-30 01:53:02 +03:00 committed by GitHub
commit 4c4a6e08b8
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
38 changed files with 283 additions and 130 deletions

View File

@ -1,96 +1,153 @@
# 0.25 - 2024.12.01 # 0.26 - 2025.01.27
[Documentation](https://github.com/MihailRis/VoxelEngine-Cpp/tree/release-0.25/doc/en/main-page.md) for 0.25 [Documentation](https://github.com/MihailRis/VoxelEngine-Cpp/tree/release-0.26/doc/en/main-page.md) for 0.26
Table of contents: Table of contents:
- [Added](#added) - [Added](#added)
- [Changes](#changes)
- [Functions](#functions) - [Functions](#functions)
- [Fixes](#fixes) - [Fixes](#fixes)
## Added ## Added
- 3dtext - headless mode `--headless`
- blockwraps - script execution mode `--headless --script filename`
- network (http requests and sockets) - test execution mode `--headless --test filename`
- vctest console application
- libraries: - libraries:
- base64 - app
- gfx.text3d - byteutil
- gfx.blockwraps - in-game chat
- network - text markup: Markdown
- syntax-highlighting: Lua
- http post requests
- `Scripts` menu page for app scripts
- binding `hud.chat`
- user-defined console.submit
- events: - events:
- on_replaced - on_chunk_present
- on_block_replaced - on_chunk_remove
- on_player_tick - on_inventory_open
- structures 'lowering' property - on_inventory_closed
- add 'hint' property to textbox - [canvas](https://github.com/MihailRis/VoxelEngine-Cpp/pull/444) ui node
- add 'taking' and 'placing' properties to slot and slotsgrid - settings:
- add 'scroll-step' property to container - `graphics.dense-render`
- add 'line-numbers' and 'text-color' to textbox - block properties:
- modules: - `culling`
- base:util - particles properties:
- uinode property 'id' - `angle_spread`
- block.materials table - `min_angular_vel`, `max_angular_vel`
- block.properties table - bytearray support in serializers
- item.properties table - ui properties:
- add version to world info table - uinode: `cursor`
- add 'sizeSpread' particles property - textbox: `markup`, `syntax`, `text-color`
- add user properties - label: `markup`
- base pack:
- add transparent leaves render mode
- add falling leaves particles
- 'states' parameter in base:falling_block
- added/updated sounds
- nameless worlds
- SIGTERM handler
- project:
- clang Windows workflow
- engine tests
### Changes
- moved `devtools.console` binding handler to Lua
- move `key:escape` binding handler to Lua
- upgrade dead emitters garbage collection
- reserved player entity ids: `0` - none (example: dead), `-1` - auto (spawns new one)
- input.add_callback("key:name") support and add optional `owner` argument
### Functions ### Functions
- player.is_infinite_items - app.tick
- player.set_infinite_items - app.sleep
- player.is_instant_destruction - app.sleep_until
- player.set_instant_destruction - app.new_world
- player.get_name - app.open_world
- player.set_name - app.save_world
- hud.open - app.close_world
- base64.encode - app.reopen_world
- base64.decode - app.delete_world
- utf8.escape - app.config_packs
- string.escape - app.reconfig_packs
- textbox:lineAt - app.get_setting
- textbox:linePos - app.set_setting
- network.get - app.get_version
- network.get_binary - app.get_setting_info
- network.tcp_connect - app.load_content
- network.tcp_open - app.reset_content
- network.get_total_upload - app.is_content_loaded
- network.get_total_download - app.quit
- gfx.text3d.show - entity:get_player
- gfx.text3d.hide - start_coroutine
- gfx.text3d.get_text - gui.clear_markup
- gfx.text3d.set_text - gui.escape_markup
- gfx.text3d.get_pos - gui.alert
- gfx.text3d.set_pos - gui.confirm
- gfx.text3d.get_axis_x - gui.load_document
- gfx.text3d.set_axis_x - console.get
- gfx.text3d.get_axis_y - world.get_chunk_data
- gfx.text3d.set_axis_y - world.set_chunk_data
- gfx.text3d.set_rotation - world.save_chunk_data
- gfx.text3d.update_settings - world.count_chunks
- player.create
- player.delete
- player.is_suspended
- player.set_suspended
- player.is_loaded_chunks
- player.set_loading_chunks
- network.post
- table.shuffle
- table.deep_copy
- math.normalize
- math.round
- byteutil.pack
- byteutil.unpack
- file.name
- file.stem
- file.ext
- file.prefix
- hud.set_allow_pause
Methods:
- uinode:reposition
- socket:available
New overloads:
- block.get_X, block.get_Y, block.get_Z
- player.get_rot
- Bytearray:append
## Fixes ## Fixes
- [fix on_block_interact & fix segfault after engine finished](https://github.com/MihailRis/VoxelEngine-Cpp/commit/d1f92c21d0bbdf2df0eb3b31c5637bdf7110444c)
- [fix translucent blocks render](https://github.com/MihailRis/VoxelEngine-Cpp/pull/370) - [fix item.properties](https://github.com/MihailRis/VoxelEngine-Cpp/commit/92fb19ba5e2307fdbcbf5d0e55f9c0712be45f72)
- [fix blocks selection with semi-transparent blocks](https://github.com/MihailRis/VoxelEngine-Cpp/commit/171cbb48d099032d7e78c51a46c374104f96f0d1) - [fix base:bazalt durability](https://github.com/MihailRis/VoxelEngine-Cpp/commit/a036c5e383135dc0f9b086e244188d1ceb3f0bf2)
- [fix: commands repository not reset before world open](https://github.com/MihailRis/VoxelEngine-Cpp/commit/1a00a91b604399f3108aa995422d371e573e650b) - [fix camera-related bugs](https://github.com/MihailRis/VoxelEngine-Cpp/commit/0d071ab0141edbf087f3ec03505792740023c01e)
- [mip-mapping related fixes](https://github.com/MihailRis/VoxelEngine-Cpp/commit/d9277e1b31714632bd7f5f601b8362a9e7cb8819) - [fix: grabbed item is deleted on inventory close](https://github.com/MihailRis/VoxelEngine-Cpp/commit/2787f2fc5495004f6029644ed5221f3abfc0c68f)
- [fix disabled slots display](https://github.com/MihailRis/VoxelEngine-Cpp/commit/e8ee3e04b1398a3ada8445591267525304410571) - [fix block overriding](https://github.com/MihailRis/VoxelEngine-Cpp/commit/cda34e3975a42696ea31a1b0018731e746cd13bb)
- [fix attack](https://github.com/MihailRis/VoxelEngine-Cpp/commit/bc17abc8b3ee7ff9027f7e3c375ca0330bb8e7bc) - [fix faces culling when 'light-passing' is false](https://github.com/MihailRis/VoxelEngine-Cpp/commit/954724c8378da525fc7349c018e9351c5bdfdf8f)
- [fix: commands repository not reset before world open](https://github.com/MihailRis/VoxelEngine-Cpp/commit/1a00a91b604399f3108aa995422d371e573e650b) - [fix particles lighting](https://github.com/MihailRis/VoxelEngine-Cpp/commit/6be640458d6b4ae46866b342ca0f26e561ead125)
- [fix stdlib.lua](https://github.com/MihailRis/VoxelEngine-Cpp/commit/6ec33ab98c78523eaececf40f113f2323d25a33a) - [fix non-skipping particles](https://github.com/MihailRis/VoxelEngine-Cpp/pull/421/commits/f1c7317c5ab2a148e5188e091cd1aa3490dc8b4d)
- [fix file.write_bytes](https://github.com/MihailRis/VoxelEngine-Cpp/commit/0fec17a8b69ac81255b77022f3af5addf8fcc8f8) - [fix content stats](https://github.com/MihailRis/VoxelEngine-Cpp/commit/97eef3ef1900157a9648bade8e06b203b99ee6f6)
- [fix World::nextInventoryId](https://github.com/MihailRis/VoxelEngine-Cpp/commit/371fdaedcef2c163edd226160f388068b2bf5e83) - [fix byte manipulation functions](https://github.com/MihailRis/VoxelEngine-Cpp/commit/9490d1f7eacb00f56112dfdd1ea12bb9c3ca528d)
- [fix block inventory unbinding](https://github.com/MihailRis/VoxelEngine-Cpp/commit/6f6c2a916afd6b9b79221111fc72b1a86109be13) - [fix error handling in events and runnables](https://github.com/MihailRis/VoxelEngine-Cpp/commit/03a3062940ebfc4e8f0b3efc5930c71f8d07b604)
- [fix xml text escapes handling](https://github.com/MihailRis/VoxelEngine-Cpp/commit/53c54dc91d132c221ff5fea2f7e9fb4568db9a0f) - [fix small dumb legacy memory leak](https://github.com/MihailRis/VoxelEngine-Cpp/commit/4d0b9f049b79322959e4aefd95eedc665e87d087)
- [fix `\'` escape parsing](https://github.com/MihailRis/VoxelEngine-Cpp/commit/2bc6cbda2e809b14fa6cffe09161b53c1636675f) - [fix grass lighting](https://github.com/MihailRis/VoxelEngine-Cpp/commit/9d7816a286fb3a7269b5220502354720e4d2726b)
- [fix crosshair look](https://github.com/MihailRis/VoxelEngine-Cpp/commit/e034bda477c35efe96548e78ecc722966a7a2197) - [small fixes in translation.](https://github.com/MihailRis/VoxelEngine-Cpp/commit/d25452784d68be19821dc917ad15bc0a92d81bd9)
- [fix: actual block inventory size not updating on inventory-size property update](https://github.com/MihailRis/VoxelEngine-Cpp/commit/1ba5b0ce33103e539ccb199ee1cd52095e286a1f) - [fix errors handling in event handlers](https://github.com/MihailRis/VoxelEngine-Cpp/commit/f62fc5a039dca70219fb2b38f61fc53a2542adf7)
- [fix falling block hitbox](https://github.com/MihailRis/VoxelEngine-Cpp/commit/352ef6485a4b796d1cdc8dd0e00ab1a1d72a2c0a) - [fix lua stack manipulations](https://github.com/MihailRis/VoxelEngine-Cpp/commit/e7555448cf0df86995b40d67fa58de1ca78f8105)
- [fix console position](https://github.com/MihailRis/VoxelEngine-Cpp/commit/3ea213e8d3cee7be55ec39ffb18dc557dec7557b) - [fix lua::create_lambda](https://github.com/MihailRis/VoxelEngine-Cpp/commit/40cdebb175014736e35bc31ecc93ae72fb00a6e9)
- [fix: fatal error on pack removal when no world open](https://github.com/MihailRis/VoxelEngine-Cpp/commit/78d5ab02c2ba8a3d05cf5639eb10a49c9ca14ec3) - [fix some UB](https://github.com/MihailRis/VoxelEngine-Cpp/commit/b5999fe36420d116674abc353ed3dad739ac5f70)
- [fix custom model lighting](https://github.com/MihailRis/VoxelEngine-Cpp/commit/a333cadfcaeb485a30833343d55faf01b28a5c5f) - [fix rigidbody:is_enabled](https://github.com/MihailRis/VoxelEngine-Cpp/commit/2adfbdb19226b2685848131073a56b354706433d)
- [fix: emitter does not skip particles](https://github.com/MihailRis/VoxelEngine-Cpp/commit/983e516fb4ebc1f2def592f2b7f3195d968deed2) - [fix panel elements removal](https://github.com/MihailRis/VoxelEngine-Cpp/commit/c6951e09651149463528bdffbc2cba4ea41de4a4)
- [fix old custom models render](https://github.com/MihailRis/VoxelEngine-Cpp/commit/82733d38011b52a426cb74560521949c1cd43cc1) - [fix infinite block fields conversion requests](https://github.com/MihailRis/VoxelEngine-Cpp/commit/0494db91872abff500cfc153a32035ee3f2745ae)
- [fix data_buffer:put_number](https://github.com/MihailRis/VoxelEngine-Cpp/commit/e247902cc6ffdaa6beab391fcfdaea7f021ab063)
- [fix textbox horizontal scroll & fix console log width](https://github.com/MihailRis/VoxelEngine-Cpp/commit/13fde2116d095b9393c4f5804ba23071e5f56ad6)
- [fix is_array](https://github.com/MihailRis/VoxelEngine-Cpp/pull/420)
- [fix neighbour chunk update](https://github.com/MihailRis/VoxelEngine-Cpp/pull/404)
- [fix lamp material](https://github.com/MihailRis/VoxelEngine-Cpp/commit/57356e1d64d6d9d7e8d59b078543b290e998ad00)

View File

@ -29,7 +29,7 @@ RUN apt-get update && apt-get install --no-install-recommends -y \
# Install EnTT # Install EnTT
RUN git clone https://github.com/skypjack/entt.git && \ RUN git clone https://github.com/skypjack/entt.git && \
cd entt/build && \ cd entt/build && \
cmake -DCMAKE_BUILD_TYPE=Release .. && \ cmake -DCMAKE_BUILD_TYPE=Release -DENTT_INSTALL=on .. && \
make install && \ make install && \
cd ../.. && rm -rf entt cd ../.. && rm -rf entt

View File

@ -3,7 +3,7 @@
## Latest release ## Latest release
- [Download](https://github.com/MihailRis/VoxelEngine-Cpp/releases/latest) | [Скачать](https://github.com/MihailRis/VoxelEngine-Cpp/releases/latest) - [Download](https://github.com/MihailRis/VoxelEngine-Cpp/releases/latest) | [Скачать](https://github.com/MihailRis/VoxelEngine-Cpp/releases/latest)
- [Documentation](https://github.com/MihailRis/VoxelEngine-Cpp/blob/release-0.25/doc/en/main-page.md) | [Документация](https://github.com/MihailRis/VoxelEngine-Cpp/blob/release-0.25/doc/ru/main-page.md) - [Documentation](https://github.com/MihailRis/VoxelEngine-Cpp/blob/release-0.26/doc/en/main-page.md) | [Документация](https://github.com/MihailRis/VoxelEngine-Cpp/blob/release-0.26/doc/ru/main-page.md)
## Build project in Linux ## Build project in Linux

View File

@ -1,8 +1,6 @@
# Documentation # Documentation
Documentation for in-development version 0.26. Documentation for release 0.26.
[Documentation for stable release 0.25.x.](https://github.com/MihailRis/VoxelEngine-Cpp/blob/release-0.25/doc/en/main-page.md)
## Sections ## Sections

View File

@ -62,6 +62,17 @@ gui.escape_markup(
Escapes markup in text. Escapes markup in text.
```lua
gui.alert(
-- message (not automatically translated, use gui.str(...))
message: str,
-- function called on close
on_ok: function() -> nil
)
```
Displays a message box. **Non-blocking**.
```lua ```lua
gui.confirm( gui.confirm(
-- message (does not translate automatically, use gui.str(...)) -- message (does not translate automatically, use gui.str(...))
@ -78,7 +89,7 @@ gui.confirm(
) )
``` ```
Requests confirmation from the user for an action. **Does not** stop code execution. Requests confirmation from the user for an action. **Non-blocking**.
```lua ```lua
gui.load_document( gui.load_document(

View File

@ -96,6 +96,15 @@ player.get_spawnpoint(playerid: int) -> number, number, number
Spawn point setter and getter Spawn point setter and getter
```lua
player.is_suspended(pid: int) -> bool
player.set_suspended(pid: int, suspended: bool)
```
Setter and getter for the player's suspended status.
When suspended, the entity is deleted and the player is disabled from the world simulation.
```lua ```lua
player.set_name(playerid: int, name: str) player.set_name(playerid: int, name: str)
player.get_name(playerid: int) -> str player.get_name(playerid: int) -> str

View File

@ -1,8 +1,6 @@
# Документация # Документация
Документация разрабатываемой версии 0.26. Документация версии 0.26.
[Документация стабильной версии 0.25.x.](https://github.com/MihailRis/VoxelEngine-Cpp/blob/release-0.25/doc/ru/main-page.md)
## Разделы ## Разделы

View File

@ -59,6 +59,17 @@ gui.escape_markup(
Экранирует разметку в тексте. Экранирует разметку в тексте.
```lua
gui.alert(
-- сообщение (не переводится автоматически, используйте gui.str(...))
message: str,
-- функция, вызываемая при закрытии
on_ok: function() -> nil
)
```
Выводит окно с сообщением. **Не** останавливает выполнение кода.
```lua ```lua
gui.confirm( gui.confirm(
-- сообщение (не переводится автоматически, используйте gui.str(...)) -- сообщение (не переводится автоматически, используйте gui.str(...))

View File

@ -96,6 +96,15 @@ player.get_spawnpoint(playerid: int) -> number, number, number
Сеттер и геттер точки спавна игрока Сеттер и геттер точки спавна игрока
```lua
player.is_suspended(pid: int) -> bool
player.set_suspended(pid: int, suspended: bool)
```
Сеттер и геттер статуса "заморозки" игрока.
При "заморозке" удаляется сущность, а игрок выключается из симуляции мира.
```lua ```lua
player.set_name(playerid: int, name: str) player.set_name(playerid: int, name: str)
player.get_name(playerid: int) -> str player.get_name(playerid: int) -> str

View File

@ -0,0 +1,5 @@
{
"steps-sound": "steps/snow",
"place-sound": "blocks/snow_place",
"break-sound": "blocks/snow_break"
}

View File

@ -19,7 +19,7 @@ function on_render()
return return
end end
local rx, ry, rz = player.get_rot(pid, true) local rx, ry, rz = player.get_rot(pid, pid ~= hud.get_player())
rig:set_matrix(headIndex, mat4.rotate({1, 0, 0}, ry)) rig:set_matrix(headIndex, mat4.rotate({1, 0, 0}, ry))
rig:set_matrix(bodyIndex, mat4.rotate({0, 1, 0}, rx)) rig:set_matrix(bodyIndex, mat4.rotate({0, 1, 0}, rx))

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -194,8 +194,8 @@ function gui.template(name, params)
text = text:gsub("if%s*=%s*'%%{%w+}'", "if=''") text = text:gsub("if%s*=%s*'%%{%w+}'", "if=''")
text = text:gsub("if%s*=%s*\"%%{%w+}\"", "if=\"\"") text = text:gsub("if%s*=%s*\"%%{%w+}\"", "if=\"\"")
-- remove unsolved properties: attr='%{var}' -- remove unsolved properties: attr='%{var}'
text = text:gsub("%w+%s*=%s*'%%{%w+}'%s?", "") text = text:gsub("%s*%S+='%%{[^}]+}'%s*", " ")
text = text:gsub("%w+%s*=%s*\"%%{%w+}\"%s?", "") text = text:gsub('%s*%S+="%%{[^}]+}"%s*', " ")
return text return text
end end

View File

@ -9,7 +9,7 @@
#include "lighting/Lightmap.hpp" #include "lighting/Lightmap.hpp"
#include "frontend/ContentGfxCache.hpp" #include "frontend/ContentGfxCache.hpp"
const glm::vec3 BlocksRenderer::SUN_VECTOR (0.411934f, 0.863868f, -0.279161f); const glm::vec3 BlocksRenderer::SUN_VECTOR (0.2275f,0.9388f,-0.1005f);
BlocksRenderer::BlocksRenderer( BlocksRenderer::BlocksRenderer(
size_t capacity, size_t capacity,
@ -129,7 +129,7 @@ void BlocksRenderer::faceAO(
float s = 0.5f; float s = 0.5f;
if (lights) { if (lights) {
float d = glm::dot(glm::normalize(Z), SUN_VECTOR); float d = glm::dot(glm::normalize(Z), SUN_VECTOR);
d = 0.8f + d * 0.2f; d = 0.7f + d * 0.3f;
auto axisX = glm::normalize(X); auto axisX = glm::normalize(X);
auto axisY = glm::normalize(Y); auto axisY = glm::normalize(Y);
@ -167,7 +167,7 @@ void BlocksRenderer::face(
float s = 0.5f; float s = 0.5f;
if (lights) { if (lights) {
float d = glm::dot(glm::normalize(Z), SUN_VECTOR); float d = glm::dot(glm::normalize(Z), SUN_VECTOR);
d = 0.8f + d * 0.2f; d = 0.7f + d * 0.3f;
tint *= d; tint *= d;
} }
vertex(coord + (-X - Y + Z) * s, region.u1, region.v1, tint); vertex(coord + (-X - Y + Z) * s, region.u1, region.v1, tint);

View File

@ -5,6 +5,7 @@
#include "elements/UINode.hpp" #include "elements/UINode.hpp"
#include "elements/Label.hpp" #include "elements/Label.hpp"
#include "elements/Menu.hpp" #include "elements/Menu.hpp"
#include "elements/Panel.hpp"
#include "assets/Assets.hpp" #include "assets/Assets.hpp"
#include "frontend/UiDocument.hpp" #include "frontend/UiDocument.hpp"
@ -23,8 +24,10 @@
using namespace gui; using namespace gui;
GUI::GUI() : batch2D(std::make_unique<Batch2D>(1024)) { GUI::GUI()
container = std::make_shared<Container>(glm::vec2(1000)); : batch2D(std::make_unique<Batch2D>(1024)),
container(std::make_shared<Container>(glm::vec2(1000))) {
container->setId("root");
uicamera = std::make_unique<Camera>(glm::vec3(), Window::height); uicamera = std::make_unique<Camera>(glm::vec3(), Window::height);
uicamera->perspective = false; uicamera->perspective = false;
uicamera->flipped = true; uicamera->flipped = true;
@ -214,6 +217,14 @@ void GUI::draw(const DrawContext& pctx, const Assets& assets) {
auto& viewport = ctx.getViewport(); auto& viewport = ctx.getViewport();
glm::vec2 wsize = viewport.size(); glm::vec2 wsize = viewport.size();
auto& page = menu->getCurrent();
if (page.panel) {
menu->setSize(page.panel->getSize());
page.panel->refresh();
if (auto panel = std::dynamic_pointer_cast<gui::Panel>(page.panel)) {
panel->cropToContent();
}
}
menu->setPos((wsize - menu->getSize()) / 2.0f); menu->setPos((wsize - menu->getSize()) / 2.0f);
uicamera->setFov(wsize.y); uicamera->setFov(wsize.y);

View File

@ -65,9 +65,10 @@ void Menu::setPage(Page page, bool history) {
setSize(current.panel->getSize()); setSize(current.panel->getSize());
} }
void Menu::back() { bool Menu::back() {
if (pageStack.empty()) if (pageStack.empty()) {
return; return false;
}
Page page = pageStack.top(); Page page = pageStack.top();
pageStack.pop(); pageStack.pop();
@ -77,6 +78,7 @@ void Menu::back() {
} }
setPage(page, false); setPage(page, false);
return true;
} }
void Menu::setPageLoader(PageLoaderFunc loader) { void Menu::setPageLoader(PageLoaderFunc loader) {

View File

@ -54,7 +54,7 @@ namespace gui {
PageLoaderFunc getPageLoader(); PageLoaderFunc getPageLoader();
/// @brief Set page to previous saved in history /// @brief Set page to previous saved in history
void back(); bool back();
/// @brief Clear pages history /// @brief Clear pages history
void clearHistory(); void clearHistory();

View File

@ -70,9 +70,6 @@ void Panel::remove(const std::shared_ptr<UINode> &node) {
void Panel::refresh() { void Panel::refresh() {
UINode::refresh(); UINode::refresh();
std::stable_sort(nodes.begin(), nodes.end(), [](auto a, auto b) {
return a->getZIndex() < b->getZIndex();
});
float x = padding.x; float x = padding.x;
float y = padding.y; float y = padding.y;
@ -80,20 +77,21 @@ void Panel::refresh() {
if (orientation == Orientation::vertical) { if (orientation == Orientation::vertical) {
float maxw = size.x; float maxw = size.x;
for (auto& node : nodes) { for (auto& node : nodes) {
glm::vec2 nodesize = node->getSize();
const glm::vec4 margin = node->getMargin(); const glm::vec4 margin = node->getMargin();
y += margin.y; y += margin.y;
float ex = x + margin.x; float ex = x + margin.x;
node->setPos(glm::vec2(ex, y)); node->setPos(glm::vec2(ex, y));
y += nodesize.y + margin.w + interval;
float width = size.x - padding.x - padding.z - margin.x - margin.z; float width = size.x - padding.x - padding.z - margin.x - margin.z;
if (node->isResizing()) { if (node->isResizing()) {
node->setSize(glm::vec2(width, nodesize.y)); node->setMaxSize({width, node->getMaxSize().y});
node->setSize(glm::vec2(width, node->getSize().y));
} }
node->refresh(); node->refresh();
maxw = fmax(maxw, ex+node->getSize().x+margin.z+padding.z); glm::vec2 nodeSize = node->getSize();
y += nodeSize.y + margin.w + interval;
maxw = fmax(maxw, ex+nodeSize.x+margin.z+padding.z);
} }
actualLength = y + padding.w; actualLength = y + padding.w;
} else { } else {

View File

@ -195,7 +195,8 @@ glm::vec2 UINode::getSize() const {
void UINode::setSize(glm::vec2 size) { void UINode::setSize(glm::vec2 size) {
this->size = glm::vec2( this->size = glm::vec2(
glm::max(minSize.x, size.x), glm::max(minSize.y, size.y) glm::max(minSize.x, glm::min(maxSize.x, size.x)),
glm::max(minSize.y, glm::min(maxSize.y, size.y))
); );
} }
@ -208,6 +209,15 @@ void UINode::setMinSize(glm::vec2 minSize) {
setSize(getSize()); setSize(getSize());
} }
glm::vec2 UINode::getMaxSize() const {
return maxSize;
}
void UINode::setMaxSize(glm::vec2 maxSize) {
this->maxSize = maxSize;
setSize(getSize());
}
void UINode::setColor(glm::vec4 color) { void UINode::setColor(glm::vec4 color) {
this->color = color; this->color = color;
this->hoverColor = color; this->hoverColor = color;

View File

@ -75,6 +75,8 @@ namespace gui {
glm::vec2 size; glm::vec2 size;
/// @brief minimal element size /// @brief minimal element size
glm::vec2 minSize {1.0f}; glm::vec2 minSize {1.0f};
/// @brief maximal element size
glm::vec2 maxSize {1e6f};
/// @brief element primary color (background-color or text-color if label) /// @brief element primary color (background-color or text-color if label)
glm::vec4 color {1.0f}; glm::vec4 color {1.0f};
/// @brief element color when mouse is over it /// @brief element color when mouse is over it
@ -224,6 +226,8 @@ namespace gui {
virtual void setSize(glm::vec2 size); virtual void setSize(glm::vec2 size);
virtual glm::vec2 getMinSize() const; virtual glm::vec2 getMinSize() const;
virtual void setMinSize(glm::vec2 size); virtual void setMinSize(glm::vec2 size);
virtual glm::vec2 getMaxSize() const;
virtual void setMaxSize(glm::vec2 size);
/// @brief Called in containers when new element added /// @brief Called in containers when new element added
virtual void refresh() {}; virtual void refresh() {};
virtual void fullRefresh() { virtual void fullRefresh() {

View File

@ -31,7 +31,17 @@ void guiutil::alert(
const std::wstring& text, const std::wstring& text,
const runnable& on_hidden const runnable& on_hidden
) { ) {
auto panel = std::make_shared<Panel>(glm::vec2(500, 300), glm::vec4(4.0f), 4.0f); auto panel = std::make_shared<Panel>(
glm::vec2(
glm::min(
static_cast<size_t>(650),
glm::max(text.length() * 10, static_cast<size_t>(200))
),
300
),
glm::vec4(4.0f),
4.0f
);
panel->setColor(glm::vec4(0.0f, 0.0f, 0.0f, 0.5f)); panel->setColor(glm::vec4(0.0f, 0.0f, 0.0f, 0.5f));
auto menuPtr = engine.getGUI()->getMenu(); auto menuPtr = engine.getGUI()->getMenu();
@ -40,14 +50,15 @@ void guiutil::alert(
menu.removePage("<alert>"); menu.removePage("<alert>");
if (on_hidden) { if (on_hidden) {
on_hidden(); on_hidden();
} else { } else if (!menu.back()) {
menu.back(); menu.reset();
} }
}; };
auto label = std::make_shared<Label>(text); auto label = std::make_shared<Label>(text);
label->setMultiline(true); label->setMultiline(true);
label->setSize(glm::vec2(1, 24)); label->setSize(glm::vec2(1, 24));
label->setAutoResize(true);
panel->add(label); panel->add(label);
panel->add(std::make_shared<Button>( panel->add(std::make_shared<Button>(
langs::get(L"Ok"), glm::vec4(10.f), langs::get(L"Ok"), glm::vec4(10.f),
@ -56,6 +67,7 @@ void guiutil::alert(
} }
)); ));
panel->refresh(); panel->refresh();
panel->keepAlive(Events::keyCallbacks[keycode::ENTER].add([on_hidden_final](){ panel->keepAlive(Events::keyCallbacks[keycode::ENTER].add([on_hidden_final](){
on_hidden_final(); on_hidden_final();
return true; return true;

View File

@ -148,7 +148,13 @@ static int l_reconfig_packs(lua::State* L) {
lua::pop(L); lua::pop(L);
} }
auto engineController = engine->getController(); auto engineController = engine->getController();
try {
engineController->reconfigPacks(controller, addPacks, remPacks); engineController->reconfigPacks(controller, addPacks, remPacks);
} catch (const contentpack_error& err) {
throw std::runtime_error(
std::string(err.what()) + " [" + err.getPackId() + " ]"
);
}
return 0; return 0;
} }

View File

@ -231,7 +231,13 @@ static int l_pack_assemble(lua::State* L) {
} }
auto manager = engine->createPacksManager(worldFolder); auto manager = engine->createPacksManager(worldFolder);
manager.scan(); manager.scan();
try {
ids = std::move(manager.assemble(ids)); ids = std::move(manager.assemble(ids));
} catch (const contentpack_error& err) {
throw std::runtime_error(
std::string(err.what()) + " [" + err.getPackId() + "]"
);
}
lua::createtable(L, ids.size(), 0); lua::createtable(L, ids.size(), 0);
for (size_t i = 0; i < ids.size(); i++) { for (size_t i = 0; i < ids.size(); i++) {

View File

@ -55,7 +55,7 @@ static int l_get_list(lua::State* L) {
auto assets = engine->getAssets(); auto assets = engine->getAssets();
std::string icon = "world#" + name + ".icon"; std::string icon = "world#" + name + ".icon";
if (!AssetsLoader::loadExternalTexture( if (!engine->isHeadless() && !AssetsLoader::loadExternalTexture(
assets, assets,
icon, icon,
{worlds[i] / fs::path("icon.png"), {worlds[i] / fs::path("icon.png"),

View File

@ -23,6 +23,7 @@ namespace lua {
public: public:
LuaBytearray(size_t capacity); LuaBytearray(size_t capacity);
LuaBytearray(std::vector<ubyte> buffer); LuaBytearray(std::vector<ubyte> buffer);
LuaBytearray(const ubyte* data, size_t size);
virtual ~LuaBytearray(); virtual ~LuaBytearray();
const std::string& getTypeName() const override { const std::string& getTypeName() const override {

View File

@ -1,4 +1,5 @@
#include "lua_util.hpp" #include "lua_util.hpp"
#include "lua_engine.hpp"
#include <iomanip> #include <iomanip>
#include <iostream> #include <iostream>
@ -60,13 +61,7 @@ int lua::pushvalue(State* L, const dv::value& value) {
break; break;
case value_type::bytes: { case value_type::bytes: {
const auto& bytes = value.asBytes(); const auto& bytes = value.asBytes();
createtable(L, 0, bytes.size()); newuserdata<LuaBytearray>(L, bytes.data(), bytes.size());
size_t size = bytes.size();
for (size_t i = 0; i < size;) {
pushinteger(L, bytes[i]);
i++;
rawseti(L, i);
}
break; break;
} }
} }
@ -234,6 +229,7 @@ static std::shared_ptr<std::string> create_lambda_handler(State* L) {
return std::shared_ptr<std::string>( return std::shared_ptr<std::string>(
new std::string(name), new std::string(name),
[=](std::string* name) { [=](std::string* name) {
auto L = lua::get_main_state();
requireglobal(L, LAMBDAS_TABLE); requireglobal(L, LAMBDAS_TABLE);
pushnil(L); pushnil(L);
setfield(L, *name); setfield(L, *name);
@ -246,6 +242,7 @@ static std::shared_ptr<std::string> create_lambda_handler(State* L) {
runnable lua::create_runnable(State* L) { runnable lua::create_runnable(State* L) {
auto funcptr = create_lambda_handler(L); auto funcptr = create_lambda_handler(L);
return [=]() { return [=]() {
auto L = lua::get_main_state();
if (!get_from(L, LAMBDAS_TABLE, *funcptr, false)) if (!get_from(L, LAMBDAS_TABLE, *funcptr, false))
return; return;
call_nothrow(L, 0, 0); call_nothrow(L, 0, 0);

View File

@ -14,6 +14,9 @@ LuaBytearray::LuaBytearray(size_t capacity) : buffer(capacity) {
LuaBytearray::LuaBytearray(std::vector<ubyte> buffer) : buffer(std::move(buffer)) { LuaBytearray::LuaBytearray(std::vector<ubyte> buffer) : buffer(std::move(buffer)) {
} }
LuaBytearray::LuaBytearray(const ubyte* data, size_t size) : buffer(data, data + size) {
}
LuaBytearray::~LuaBytearray() { LuaBytearray::~LuaBytearray() {
} }

View File

@ -319,7 +319,6 @@ public:
~SocketConnection() { ~SocketConnection() {
if (state != ConnectionState::CLOSED) { if (state != ConnectionState::CLOSED) {
shutdown(descriptor, 2); shutdown(descriptor, 2);
closesocket(descriptor);
} }
if (thread) { if (thread) {
thread->join(); thread->join();
@ -382,6 +381,9 @@ public:
} }
int send(const char* buffer, size_t length) override { int send(const char* buffer, size_t length) override {
if (state == ConnectionState::CLOSED) {
return 0;
}
int len = sendsocket(descriptor, buffer, length, 0); int len = sendsocket(descriptor, buffer, length, 0);
if (len == -1) { if (len == -1) {
int err = errno; int err = errno;
@ -444,7 +446,7 @@ public:
hints.ai_family = AF_INET; hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM; hints.ai_socktype = SOCK_STREAM;
addrinfo* addrinfo; addrinfo* addrinfo = nullptr;
if (int res = getaddrinfo( if (int res = getaddrinfo(
address.c_str(), nullptr, &hints, &addrinfo address.c_str(), nullptr, &hints, &addrinfo
)) { )) {
@ -452,12 +454,11 @@ public:
} }
sockaddr_in serverAddress = *(sockaddr_in*)addrinfo->ai_addr; sockaddr_in serverAddress = *(sockaddr_in*)addrinfo->ai_addr;
freeaddrinfo(addrinfo);
serverAddress.sin_port = htons(port); serverAddress.sin_port = htons(port);
freeaddrinfo(addrinfo);
SOCKET descriptor = socket(AF_INET, SOCK_STREAM, 0); SOCKET descriptor = socket(AF_INET, SOCK_STREAM, 0);
if (descriptor == -1) { if (descriptor == -1) {
freeaddrinfo(addrinfo);
throw std::runtime_error("Could not create socket"); throw std::runtime_error("Could not create socket");
} }
auto socket = std::make_shared<SocketConnection>(descriptor, std::move(serverAddress)); auto socket = std::make_shared<SocketConnection>(descriptor, std::move(serverAddress));

View File

@ -65,17 +65,21 @@ int platform::get_process_id() {
#else // _WIN32 #else // _WIN32
#include <unistd.h> #include <unistd.h>
#include "frontend/locale.hpp"
void platform::configure_encoding() { void platform::configure_encoding() {
} }
std::string platform::detect_locale() { std::string platform::detect_locale() {
std::string programLocaleName = setlocale(LC_ALL, nullptr); const char* const programLocaleName = setlocale(LC_ALL, nullptr);
std::string preferredLocaleName = const char* const preferredLocaleName =
setlocale(LC_ALL, ""); // locale name format: ll_CC.encoding setlocale(LC_ALL, ""); // locale name format: ll_CC.encoding
setlocale(LC_ALL, programLocaleName.c_str()); if (programLocaleName && preferredLocaleName) {
setlocale(LC_ALL, programLocaleName);
return preferredLocaleName.substr(0, 5); return std::string(preferredLocaleName, 5);
}
return langs::FALLBACK_DEFAULT;
} }
void platform::sleep(size_t millis) { void platform::sleep(size_t millis) {