Merge branch 'main' into release-0.26
This commit is contained in:
commit
b37c71059a
2
.github/workflows/appimage.yml
vendored
2
.github/workflows/appimage.yml
vendored
@ -32,7 +32,7 @@ jobs:
|
||||
# install EnTT
|
||||
git clone https://github.com/skypjack/entt.git
|
||||
cd entt/build
|
||||
cmake -DCMAKE_BUILD_TYPE=Release ..
|
||||
cmake -DCMAKE_BUILD_TYPE=Release -DENTT_INSTALL=on ..
|
||||
sudo make install
|
||||
cd ../..
|
||||
- name: Configure
|
||||
|
||||
2
.github/workflows/cmake.yml
vendored
2
.github/workflows/cmake.yml
vendored
@ -46,7 +46,7 @@ jobs:
|
||||
# install EnTT
|
||||
git clone https://github.com/skypjack/entt.git
|
||||
cd entt/build
|
||||
cmake -DCMAKE_BUILD_TYPE=Release ..
|
||||
cmake -DCMAKE_BUILD_TYPE=Release -DENTT_INSTALL=on ..
|
||||
sudo make install
|
||||
cd ../..
|
||||
|
||||
|
||||
@ -14,7 +14,7 @@
|
||||
```sh
|
||||
git clone https://github.com/skypjack/entt.git
|
||||
cd entt/build
|
||||
cmake -DCMAKE_BUILD_TYPE=Release ..
|
||||
cmake -DCMAKE_BUILD_TYPE=Release -DENTT_INSTALL=on ..
|
||||
sudo make install
|
||||
```
|
||||
|
||||
|
||||
@ -26,6 +26,9 @@ entity:get_uid() -> int
|
||||
entity:get_component(name: str) -> component or nil
|
||||
-- Checks for the presence of a component by name
|
||||
entity:has_component(name: str) -> bool
|
||||
|
||||
-- Enables/disables the component
|
||||
entity:set_enabled(name: str, enable: bool)
|
||||
```
|
||||
|
||||
## Built-in components
|
||||
|
||||
@ -26,6 +26,9 @@ entity:get_uid() -> int
|
||||
entity:get_component(name: str) -> компонент или nil
|
||||
-- Проверяет наличие компонента по имени
|
||||
entity:has_component(name: str) -> bool
|
||||
|
||||
-- Включает/выключает компонент по имени
|
||||
entity:set_enabled(name: str, enable: bool)
|
||||
```
|
||||
|
||||
## Встроенные компоненты
|
||||
|
||||
@ -2,5 +2,6 @@
|
||||
"texture": "lamp",
|
||||
"emission": [15, 14, 13],
|
||||
"shadeless": true,
|
||||
"material": "base:glass",
|
||||
"base:durability": 0.3
|
||||
}
|
||||
|
||||
@ -12,7 +12,7 @@
|
||||
</container>
|
||||
|
||||
<container id="logContainer" pos="0,60"
|
||||
size-func="unpack(vec2.add(gui.get_viewport(), {0,-100}))">
|
||||
size-func="unpack(vec2.add(gui.get_viewport(), {-350,-100}))">
|
||||
<textbox
|
||||
id='log'
|
||||
color='0'
|
||||
@ -20,7 +20,7 @@
|
||||
margin='0'
|
||||
editable='false'
|
||||
multiline='true'
|
||||
size-func="gui.get_viewport()[1],40"
|
||||
size-func="gui.get_viewport()[1]-350,40"
|
||||
gravity="bottom-left"
|
||||
markup="md"
|
||||
></textbox>
|
||||
|
||||
@ -7,18 +7,11 @@ local initialized = false
|
||||
local max_lines = 15
|
||||
local animation_fps = 30
|
||||
|
||||
local function remove_line(line)
|
||||
document[line[1]]:destruct()
|
||||
time.post_runnable(function()
|
||||
if world.is_open() then document.root:reposition() end
|
||||
end)
|
||||
end
|
||||
|
||||
local function update_line(line, uptime)
|
||||
local diff = uptime - line[2]
|
||||
if diff > timeout then
|
||||
remove_line(line)
|
||||
table.insert(dead_lines, i)
|
||||
document[line[1]]:destruct()
|
||||
table.insert(dead_lines, table.index(lines, line))
|
||||
elseif diff > timeout-fadeout then
|
||||
local opacity = (timeout - diff) / fadeout
|
||||
document[line[1]].color = {0, 0, 0, opacity * 80}
|
||||
@ -27,16 +20,16 @@ local function update_line(line, uptime)
|
||||
end
|
||||
|
||||
events.on("core:chat", function(message)
|
||||
while #lines >= max_lines do
|
||||
document[lines[1][1]]:destruct()
|
||||
table.remove(lines, 1)
|
||||
end
|
||||
local current_time = time.uptime()
|
||||
local id = 'l'..tostring(nextid)
|
||||
document.root:add(gui.template("chat_line", {id=id}))
|
||||
document.root:reposition()
|
||||
document[id.."L"].text = message
|
||||
nextid = nextid + 1
|
||||
if #lines == max_lines then
|
||||
remove_line(lines[1])
|
||||
table.remove(lines, 1)
|
||||
end
|
||||
table.insert(lines, {id, current_time})
|
||||
end)
|
||||
|
||||
|
||||
@ -313,8 +313,8 @@ function bit_converter.bytes_to_uint16(bytes, order)
|
||||
|
||||
return
|
||||
bit.bor(
|
||||
bit.lshift(bytes[1], 8),
|
||||
bytes[2], 0)
|
||||
bit.lshift(bytes[2], 8),
|
||||
bytes[1], 0)
|
||||
end
|
||||
|
||||
function bit_converter.bytes_to_int64(bytes, order)
|
||||
|
||||
@ -144,31 +144,31 @@ function data_buffer:put_number(num)
|
||||
|
||||
if math.floor(num) ~= num then
|
||||
type = TYPE_FLOAT64
|
||||
bytes = bit_converter.float64_to_bytes(num)
|
||||
bytes = bit_converter.float64_to_bytes(num, self.order)
|
||||
elseif num == 0 then
|
||||
type = TYPE_ZERO
|
||||
bytes = { }
|
||||
elseif num > 0 then
|
||||
if num <= MAX_UINT16 then
|
||||
type = TYPE_UINT16
|
||||
bytes = bit_converter.uint16_to_bytes(num)
|
||||
bytes = bit_converter.uint16_to_bytes(num, self.order)
|
||||
elseif num <= MAX_UINT32 then
|
||||
type = TYPE_UINT32
|
||||
bytes = bit_converter.uint32_to_bytes(num)
|
||||
bytes = bit_converter.uint32_to_bytes(num, self.order)
|
||||
elseif num <= MAX_INT64 then
|
||||
type = TYPE_INT64
|
||||
bytes = bit_converter.int64_to_bytes(num)
|
||||
bytes = bit_converter.int64_to_bytes(num, self.order)
|
||||
end
|
||||
elseif num < 0 then
|
||||
if num >= MIN_INT16 then
|
||||
type = TYPE_SINT16
|
||||
bytes = bit_converter.sint16_to_bytes(num)
|
||||
bytes = bit_converter.sint16_to_bytes(num, self.order)
|
||||
elseif num >= MIN_INT32 then
|
||||
type = TYPE_SINT32
|
||||
bytes = bit_converter.sint32_to_bytes(num)
|
||||
bytes = bit_converter.sint32_to_bytes(num, self.order)
|
||||
elseif num >= MIN_INT64 then
|
||||
type = TYPE_INT64
|
||||
bytes = bit_converter.int64_to_bytes(num)
|
||||
bytes = bit_converter.int64_to_bytes(num, self.order)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@ -68,6 +68,22 @@ local Entity = {__index={
|
||||
def_index=function(self) return entities.get_def(self.eid) end,
|
||||
def_name=function(self) return entities.def_name(entities.get_def(self.eid)) end,
|
||||
get_player=function(self) return entities.get_player(self.eid) end,
|
||||
set_enabled=function(self, name, flag)
|
||||
local comp = self.components[name]
|
||||
if comp then
|
||||
if flag then
|
||||
if comp.__disabled and comp.on_enable then
|
||||
comp.on_enable()
|
||||
end
|
||||
comp.__disabled = nil
|
||||
else
|
||||
if not comp.__disabled and comp.on_disable then
|
||||
comp.on_disable()
|
||||
end
|
||||
comp.__disabled = true
|
||||
end
|
||||
end
|
||||
end,
|
||||
}}
|
||||
|
||||
local entities = {}
|
||||
@ -99,7 +115,7 @@ return {
|
||||
end
|
||||
for _, component in pairs(entity.components) do
|
||||
local callback = component.on_update
|
||||
if callback then
|
||||
if not component.__disabled and callback then
|
||||
local result, err = pcall(callback, tps)
|
||||
if err then
|
||||
debug.error(err)
|
||||
@ -113,7 +129,7 @@ return {
|
||||
for _,entity in pairs(entities) do
|
||||
for _, component in pairs(entity.components) do
|
||||
local callback = component.on_render
|
||||
if callback then
|
||||
if not component.__disabled and callback then
|
||||
local result, err = pcall(callback, delta)
|
||||
if err then
|
||||
debug.error(err)
|
||||
|
||||
@ -37,7 +37,10 @@ local function complete_app_lib(app)
|
||||
app.tick = coroutine.yield
|
||||
app.get_version = core.get_version
|
||||
app.get_setting_info = core.get_setting_info
|
||||
app.load_content = core.load_content
|
||||
app.load_content = function()
|
||||
core.load_content()
|
||||
app.tick()
|
||||
end
|
||||
app.reset_content = core.reset_content
|
||||
app.is_content_loaded = core.is_content_loaded
|
||||
|
||||
@ -416,7 +419,18 @@ end
|
||||
|
||||
function start_coroutine(chunk, name)
|
||||
local co = coroutine.create(function()
|
||||
local status, error = xpcall(chunk, __vc__error)
|
||||
local status, error = xpcall(chunk, function(...)
|
||||
gui.alert(debug.traceback(), function()
|
||||
if world.is_open() then
|
||||
__vc_app.close_world()
|
||||
else
|
||||
__vc_app.reset_content()
|
||||
menu:reset()
|
||||
menu.page = "main"
|
||||
end
|
||||
end)
|
||||
return ...
|
||||
end)
|
||||
if not status then
|
||||
debug.error(error)
|
||||
end
|
||||
|
||||
@ -27,6 +27,7 @@ inline constexpr blockid_t BLOCK_OBSTACLE = 1;
|
||||
inline constexpr blockid_t BLOCK_STRUCT_AIR = 2;
|
||||
inline constexpr itemid_t ITEM_EMPTY = 0;
|
||||
inline constexpr entityid_t ENTITY_NONE = 0;
|
||||
inline constexpr entityid_t ENTITY_AUTO = std::numeric_limits<entityid_t>::max();
|
||||
|
||||
inline constexpr int CHUNK_W = 16;
|
||||
inline constexpr int CHUNK_H = 256;
|
||||
|
||||
@ -104,6 +104,9 @@ namespace dv {
|
||||
}
|
||||
|
||||
boolean_t value::asBoolean() const {
|
||||
if (type == value_type::none) {
|
||||
return false;
|
||||
}
|
||||
check_type(type, value_type::boolean);
|
||||
return val.boolean;
|
||||
}
|
||||
|
||||
@ -199,6 +199,7 @@ void Engine::updateFrontend() {
|
||||
audio::update(delta);
|
||||
gui->act(delta, Viewport(Window::width, Window::height));
|
||||
screen->update(delta);
|
||||
gui->postAct();
|
||||
}
|
||||
|
||||
void Engine::nextFrame() {
|
||||
@ -217,7 +218,6 @@ void Engine::renderFrame() {
|
||||
Viewport viewport(Window::width, Window::height);
|
||||
DrawContext ctx(nullptr, viewport, nullptr);
|
||||
gui->draw(ctx, *assets);
|
||||
gui->postAct();
|
||||
}
|
||||
|
||||
void Engine::saveSettings() {
|
||||
|
||||
@ -202,7 +202,7 @@ void GUI::act(float delta, const Viewport& vp) {
|
||||
|
||||
void GUI::postAct() {
|
||||
while (!postRunnables.empty()) {
|
||||
runnable callback = postRunnables.back();
|
||||
runnable callback = postRunnables.front();
|
||||
postRunnables.pop();
|
||||
callback();
|
||||
}
|
||||
|
||||
@ -53,6 +53,7 @@ void Panel::cropToContent() {
|
||||
void Panel::fullRefresh() {
|
||||
refresh();
|
||||
cropToContent();
|
||||
reposition();
|
||||
Container::fullRefresh();
|
||||
}
|
||||
|
||||
|
||||
@ -826,7 +826,7 @@ void TextBox::setCaret(size_t position) {
|
||||
scrolled(-glm::ceil(offset/static_cast<double>(scrollStep)+0.5f));
|
||||
}
|
||||
uint lcaret = caret - label->getTextLineOffset(line);
|
||||
int realoffset = font->calcWidth(input, lcaret)-int(textOffset)+2;
|
||||
int realoffset = font->calcWidth(input, lcaret)-int(textOffset) - padding.x;
|
||||
if (realoffset-width > 0) {
|
||||
setTextOffset(textOffset + realoffset-width);
|
||||
} else if (realoffset < 0) {
|
||||
|
||||
@ -34,13 +34,14 @@ void guiutil::alert(
|
||||
auto panel = std::make_shared<Panel>(glm::vec2(500, 300), glm::vec4(4.0f), 4.0f);
|
||||
panel->setColor(glm::vec4(0.0f, 0.0f, 0.0f, 0.5f));
|
||||
|
||||
auto menu = engine.getGUI()->getMenu();
|
||||
runnable on_hidden_final = [on_hidden, menu, &engine]() {
|
||||
menu->removePage("<alert>");
|
||||
auto menuPtr = engine.getGUI()->getMenu();
|
||||
auto& menu = *menuPtr;
|
||||
runnable on_hidden_final = [on_hidden, &menu, &engine]() {
|
||||
menu.removePage("<alert>");
|
||||
if (on_hidden) {
|
||||
on_hidden();
|
||||
} else {
|
||||
menu->back();
|
||||
menu.back();
|
||||
}
|
||||
};
|
||||
|
||||
@ -50,21 +51,21 @@ void guiutil::alert(
|
||||
panel->add(label);
|
||||
panel->add(std::make_shared<Button>(
|
||||
langs::get(L"Ok"), glm::vec4(10.f),
|
||||
[=](GUI*) {
|
||||
[on_hidden_final](GUI*) {
|
||||
on_hidden_final();
|
||||
}
|
||||
));
|
||||
panel->refresh();
|
||||
panel->keepAlive(Events::keyCallbacks[keycode::ENTER].add([=](){
|
||||
panel->keepAlive(Events::keyCallbacks[keycode::ENTER].add([on_hidden_final](){
|
||||
on_hidden_final();
|
||||
return true;
|
||||
}));
|
||||
panel->keepAlive(Events::keyCallbacks[keycode::ESCAPE].add([=](){
|
||||
panel->keepAlive(Events::keyCallbacks[keycode::ESCAPE].add([on_hidden_final](){
|
||||
on_hidden_final();
|
||||
return true;
|
||||
}));
|
||||
menu->addPage("<alert>", panel, true);
|
||||
menu->setPage("<alert>");
|
||||
menu.addPage("<alert>", panel, true);
|
||||
menu.setPage("<alert>");
|
||||
}
|
||||
|
||||
void guiutil::confirm(
|
||||
|
||||
@ -4,6 +4,7 @@
|
||||
#include "typedefs.hpp"
|
||||
|
||||
#include <memory>
|
||||
#include <cstring>
|
||||
|
||||
inline constexpr int LIGHTMAP_DATA_LEN = CHUNK_VOL/2;
|
||||
|
||||
@ -17,6 +18,10 @@ public:
|
||||
|
||||
void set(const light_t* map);
|
||||
|
||||
void clear() {
|
||||
std::memset(map, 0, sizeof(map));
|
||||
}
|
||||
|
||||
inline unsigned short get(int x, int y, int z) const {
|
||||
return (map[y*CHUNK_D*CHUNK_W+z*CHUNK_W+x]);
|
||||
}
|
||||
|
||||
@ -229,7 +229,9 @@ static int l_set_entity(lua::State* L) {
|
||||
if (player == nullptr) {
|
||||
return 0;
|
||||
}
|
||||
if (auto entity = get_entity(L, 2)) {
|
||||
if (lua::isnumber(L, 2)) {
|
||||
player->setEntity(lua::tointeger(L, 2));
|
||||
} else if (auto entity = get_entity(L, 2)) {
|
||||
player->setEntity(entity->getUID());
|
||||
}
|
||||
return 0;
|
||||
|
||||
@ -148,12 +148,12 @@ static void integrate_chunk_client(Chunk& chunk) {
|
||||
int x = chunk.x;
|
||||
int z = chunk.z;
|
||||
auto chunksController = controller->getChunksController();
|
||||
|
||||
Lighting& lighting = *chunksController->lighting;
|
||||
chunk.flags.loadedLights = false;
|
||||
chunk.flags.lighted = false;
|
||||
|
||||
chunk.lightmap.clear();
|
||||
Lighting::prebuildSkyLight(chunk, *indices);
|
||||
lighting.onChunkLoaded(x, z, true);
|
||||
|
||||
for (int lz = -1; lz <= 1; lz++) {
|
||||
for (int lx = -1; lx <= 1; lx++) {
|
||||
@ -162,7 +162,6 @@ static void integrate_chunk_client(Chunk& chunk) {
|
||||
}
|
||||
if (auto other = level->chunks->getChunk(x + lx, z + lz)) {
|
||||
other->flags.modified = true;
|
||||
lighting.onChunkLoaded(x - 1, z, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -22,6 +22,9 @@ namespace lua {
|
||||
|
||||
inline void pop(lua::State* L, int n = 1) {
|
||||
#ifndef NDEBUG
|
||||
if (n < 0) {
|
||||
abort();
|
||||
}
|
||||
if (lua_gettop(L) < n) {
|
||||
abort();
|
||||
}
|
||||
|
||||
@ -86,7 +86,10 @@ public:
|
||||
}
|
||||
|
||||
void update() override {
|
||||
if (lua::getglobal(L, "__vc_resume_coroutine")) {
|
||||
if (id == 0) {
|
||||
return;
|
||||
}
|
||||
if (lua::requireglobal(L, "__vc_resume_coroutine")) {
|
||||
lua::pushinteger(L, id);
|
||||
if (lua::call(L, 1)) {
|
||||
alive = lua::toboolean(L, -1);
|
||||
@ -102,10 +105,10 @@ public:
|
||||
}
|
||||
|
||||
void terminate() override {
|
||||
if (lua::getglobal(L, "__vc_stop_coroutine")) {
|
||||
lua::requireglobal(L, "__vc_stop_coroutine");
|
||||
lua::pushinteger(L, id);
|
||||
lua::pop(L, lua::call(L, 1));
|
||||
}
|
||||
id = 0;
|
||||
}
|
||||
};
|
||||
|
||||
@ -614,6 +617,10 @@ static void process_entity_callback(
|
||||
) {
|
||||
auto L = lua::get_main_state();
|
||||
lua::pushenv(L, *env);
|
||||
if (lua::hasfield(L, "__disabled")) {
|
||||
lua::pop(L);
|
||||
return;
|
||||
}
|
||||
if (lua::getfield(L, name)) {
|
||||
if (args) {
|
||||
lua::call_nothrow(L, args(L), 0);
|
||||
|
||||
@ -62,7 +62,7 @@ Player::Player(
|
||||
Player::~Player() = default;
|
||||
|
||||
void Player::updateEntity() {
|
||||
if (eid == 0) {
|
||||
if (eid == ENTITY_AUTO) {
|
||||
auto& def = level.content.entities.require("base:player");
|
||||
eid = level.entities->spawn(def, getPosition());
|
||||
if (auto entity = level.entities->get(eid)) {
|
||||
@ -73,10 +73,10 @@ void Player::updateEntity() {
|
||||
if (auto entity = level.entities->get(eid)) {
|
||||
entity->setPlayer(id);
|
||||
}
|
||||
} else if (chunks->getChunkByVoxel(position)) {
|
||||
} else if (chunks->getChunkByVoxel(position) && eid != ENTITY_NONE) {
|
||||
logger.error() << "player entity despawned or deleted; "
|
||||
"will be respawned";
|
||||
eid = 0;
|
||||
eid = ENTITY_AUTO;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -54,7 +54,7 @@ class Player : public Serializable {
|
||||
bool infiniteItems = true;
|
||||
bool instantDestruction = true;
|
||||
bool loadingChunks = true;
|
||||
entityid_t eid;
|
||||
entityid_t eid = ENTITY_AUTO;
|
||||
entityid_t selectedEid = 0;
|
||||
|
||||
glm::vec3 rotation {};
|
||||
|
||||
@ -37,7 +37,7 @@ Player* Players::create(int64_t id) {
|
||||
glm::vec3(0, DEF_PLAYER_Y, 0),
|
||||
DEF_PLAYER_SPEED,
|
||||
level.inventories->create(DEF_PLAYER_INVENTORY_SIZE),
|
||||
0
|
||||
ENTITY_AUTO
|
||||
);
|
||||
auto player = playerPtr.get();
|
||||
add(std::move(playerPtr));
|
||||
@ -92,7 +92,7 @@ void Players::deserialize(const dv::value& src) {
|
||||
glm::vec3(0, DEF_PLAYER_Y, 0),
|
||||
DEF_PLAYER_SPEED,
|
||||
level.inventories->create(DEF_PLAYER_INVENTORY_SIZE),
|
||||
0
|
||||
ENTITY_AUTO
|
||||
);
|
||||
auto player = playerPtr.get();
|
||||
player->deserialize(playerMap);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user