mirror of
https://github.com/MihailRis/voxelcore.git
synced 2026-10-04 18:41:51 +00:00
Merge branch 'main' into fix-assets-pipeline
This commit is contained in:
commit
f30b5f84d0
24 changed files with 339 additions and 66 deletions
BIN
dev/tests/attachments/line_clipping_test.png
Normal file
BIN
dev/tests/attachments/line_clipping_test.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.5 KiB |
51
dev/tests/canvas_lines.lua
Normal file
51
dev/tests/canvas_lines.lua
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
local W, H = 128, 128
|
||||
|
||||
local canvas = Canvas({W, H})
|
||||
canvas:clear(0xff202020)
|
||||
|
||||
local WHITE = 0xffffffff
|
||||
local RED = 0xffff4040
|
||||
local GREEN = 0xff40ff40
|
||||
local BLUE = 0xff4080ff
|
||||
local YELLOW = 0xffffff40
|
||||
|
||||
-- border
|
||||
canvas:line(0, 0, W - 1, 0, WHITE)
|
||||
canvas:line(W - 1, 0, W - 1, H - 1, WHITE)
|
||||
canvas:line(W - 1, H - 1, 0, H - 1, WHITE)
|
||||
canvas:line(0, H - 1, 0, 0, WHITE)
|
||||
|
||||
-- horizontal
|
||||
canvas:line(-40, 16, W + 40, 16, RED)
|
||||
canvas:line(-40, H / 2, W + 40, H / 2, RED)
|
||||
canvas:line(-40, H - 17, W + 40, H - 17, RED)
|
||||
|
||||
-- vertical
|
||||
canvas:line(16, -40, 16, H + 40, GREEN)
|
||||
canvas:line(W / 2, -40, W / 2, H + 40, GREEN)
|
||||
canvas:line(W - 17, -40, W - 17, H + 40, GREEN)
|
||||
|
||||
-- diagonals
|
||||
canvas:line(-40, -40, W + 40, H + 40, BLUE)
|
||||
canvas:line(-40, H + 40, W + 40, -40, BLUE)
|
||||
|
||||
canvas:line(W / 2, -40, W + 40, H / 2, BLUE)
|
||||
canvas:line(-40, H / 2, W / 2, H + 40, BLUE)
|
||||
|
||||
-- outer
|
||||
canvas:line(-30, -30, 20, 20, YELLOW)
|
||||
canvas:line(W - 20, H - 20, W + 30, H + 30, YELLOW)
|
||||
|
||||
canvas:line(W + 30, -30, W - 20, 20, YELLOW)
|
||||
canvas:line(-30, H + 30, 20, H - 20, YELLOW)
|
||||
|
||||
-- completely outside
|
||||
canvas:line(-50, -20, -10, H + 20, 0xffff00ff)
|
||||
canvas:line(W + 10, -20, W + 50, H + 20, 0xffff00ff)
|
||||
canvas:line(-20, -20, W + 20, -10, 0xffff00ff)
|
||||
canvas:line(-20, H + 10, W + 20, H + 30, 0xffff00ff)
|
||||
|
||||
local expected = Canvas.decode(
|
||||
file.read_bytes("script:attachments/line_clipping_test.png"), "png"
|
||||
)
|
||||
asserts.equals(expected, canvas)
|
||||
|
|
@ -162,7 +162,19 @@ inventory.get_all_data(
|
|||
invid: int,
|
||||
-- slot index
|
||||
slot: int,
|
||||
) -> table
|
||||
) -> table | nil
|
||||
|
||||
-- Sets the values of all local item properties.
|
||||
inventory.set_all_data(
|
||||
-- inventory id
|
||||
invid: int,
|
||||
-- slot index
|
||||
slot: int,
|
||||
-- property:value table
|
||||
fields: table,
|
||||
-- clear other property values
|
||||
[optional] clear: boolean = false
|
||||
)
|
||||
```
|
||||
|
||||
```lua
|
||||
|
|
|
|||
|
|
@ -264,3 +264,9 @@ function on_used(playerid: int)
|
|||
```
|
||||
|
||||
Called when an entity is used (RMB by entity). The player ID is passed as an argument.
|
||||
|
||||
```lua
|
||||
function on_player_set(playerid: int)
|
||||
```
|
||||
|
||||
Called when an entity is attached to a player.
|
||||
|
|
|
|||
|
|
@ -170,7 +170,19 @@ inventory.get_all_data(
|
|||
invid: int,
|
||||
-- индекс слота
|
||||
slot: int,
|
||||
) -> table
|
||||
) -> table | nil
|
||||
|
||||
-- Устанавливает значения локальных cвойств предмета.
|
||||
inventory.set_all_data(
|
||||
-- id инвентаря
|
||||
invid: int,
|
||||
-- индекс слота
|
||||
slot: int,
|
||||
-- таблица cвойство:значение
|
||||
fields: table,
|
||||
-- удалить остальные значения свойств
|
||||
[опционально] clear: boolean = false
|
||||
)
|
||||
```
|
||||
|
||||
```lua
|
||||
|
|
@ -222,4 +234,4 @@ inventory.use(
|
|||
-- индекс слота
|
||||
slot: int
|
||||
)
|
||||
```
|
||||
```
|
||||
|
|
|
|||
|
|
@ -265,3 +265,8 @@ function on_used(playerid: int)
|
|||
|
||||
Вызывается при использовании сущности (ПКМ по сущности). ID игрока передается в качестве аргумента.
|
||||
|
||||
```lua
|
||||
function on_player_set(playerid: int)
|
||||
```
|
||||
|
||||
Вызывается при прикреплении сущности к игроку.
|
||||
|
|
|
|||
|
|
@ -1,8 +1,77 @@
|
|||
local this = {}
|
||||
local app = __vc_app
|
||||
|
||||
function this.equals(expected, fact)
|
||||
local function diff_canvas(expected, fact)
|
||||
this.equals(expected.width, fact.width, "image width")
|
||||
this.equals(expected.width, fact.width, "image height")
|
||||
|
||||
local diff = Canvas({expected.width, expected.height})
|
||||
|
||||
local mismatches = 0
|
||||
|
||||
for y = 0, expected.height - 1 do
|
||||
for x = 0, expected.width - 1 do
|
||||
local ca = expected:at(x, y)
|
||||
local cb = fact:at(x, y)
|
||||
|
||||
if ca == cb then
|
||||
diff:set(x, y, ca)
|
||||
else
|
||||
diff:set(x, y, 0xff0000ff)
|
||||
mismatches = mismatches + 1
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return diff, mismatches
|
||||
end
|
||||
|
||||
local TEST_ARTIFACTS_PATH = "export:test-results"
|
||||
|
||||
local function get_test_artifact_path(name)
|
||||
local path = TEST_ARTIFACTS_PATH
|
||||
if not file.isdir(path) then
|
||||
file.mkdirs(path)
|
||||
end
|
||||
return file.join(path, name)
|
||||
end
|
||||
|
||||
function this.equals(expected, fact, prefix)
|
||||
local mt = getmetatable(expected)
|
||||
if mt == Canvas then
|
||||
local diff, mismatches = diff_canvas(expected, fact)
|
||||
if mismatches > 0 then
|
||||
prefix = prefix or app.script or base64.encode_urlsafe(random.bytes(6))
|
||||
local path_diff = get_test_artifact_path(
|
||||
string.format("%s.diff.png", prefix)
|
||||
)
|
||||
local path_fact = get_test_artifact_path(
|
||||
string.format("%s.fact.png", prefix)
|
||||
)
|
||||
local path_expected = get_test_artifact_path(
|
||||
string.format("%s.expected.png", prefix)
|
||||
)
|
||||
file.write_bytes(path_diff, diff:encode('png'))
|
||||
file.write_bytes(path_fact, fact:encode('png'))
|
||||
file.write_bytes(path_expected, expected:encode('png'))
|
||||
local total_pixels = expected.width * expected.height
|
||||
assert(mismatches == 0, string.format(
|
||||
"%s pixels of %s (%s%%) are different, diff saved as %s",
|
||||
mismatches,
|
||||
total_pixels,
|
||||
math.round(mismatches / total_pixels * 100, 2),
|
||||
string.escape(path_diff))
|
||||
)
|
||||
end
|
||||
return
|
||||
end
|
||||
if prefix then
|
||||
prefix = prefix .. " "
|
||||
else
|
||||
prefix = ""
|
||||
end
|
||||
assert(fact == expected, string.format(
|
||||
"(fact == expected) assertion failed\n Expected: %s\n Fact: %s",
|
||||
prefix .. "(fact == expected) assertion failed\n Expected: %s\n Fact: %s",
|
||||
expected, fact
|
||||
))
|
||||
end
|
||||
|
|
|
|||
|
|
@ -12,11 +12,30 @@ FFI.cdef[[
|
|||
} bytearray_t;
|
||||
]]
|
||||
|
||||
local malloc = FFI.C.malloc
|
||||
local free = FFI.C.free
|
||||
|
||||
local FFIBytearray
|
||||
local bytearray_type
|
||||
|
||||
local allocated_bytes = 0
|
||||
local GC_THRESHOLD = 50 * 1024 * 1024
|
||||
|
||||
local function malloc(size)
|
||||
local raw = FFI.C.malloc(size)
|
||||
if raw == nil then
|
||||
return nil
|
||||
end
|
||||
|
||||
allocated_bytes = allocated_bytes + size
|
||||
|
||||
if allocated_bytes >= GC_THRESHOLD then
|
||||
collectgarbage("step", 200)
|
||||
allocated_bytes = 0
|
||||
end
|
||||
|
||||
return raw
|
||||
end
|
||||
|
||||
local function grow_buffer(self, elems)
|
||||
local new_capacity = math.ceil(self.capacity / 0.75 + elems)
|
||||
local prev = self.bytes
|
||||
|
|
|
|||
|
|
@ -142,14 +142,16 @@ end
|
|||
|
||||
function is_flight() return flight end
|
||||
|
||||
function set_flight(flag) flight = flag end
|
||||
function set_flight(flag)
|
||||
flight = flag
|
||||
body:set_gravity_scale(flight and 0.0 or props.gravity_scale)
|
||||
end
|
||||
|
||||
local prev_angle = (vec2.angle({dir[3], dir[1]})) % 360
|
||||
|
||||
function on_physics_update(delta)
|
||||
local grounded = body:is_grounded()
|
||||
body:set_vdamping(flight)
|
||||
body:set_gravity_scale(flight and 0.0 or props.gravity_scale)
|
||||
body:set_linear_damping(
|
||||
(flight or not grounded) and props.air_damping or props.ground_damping
|
||||
)
|
||||
|
|
|
|||
|
|
@ -58,16 +58,12 @@ local function process_player_inputs(pid, rot, delta)
|
|||
end
|
||||
end
|
||||
|
||||
local prepared = false
|
||||
body:set_enabled(false)
|
||||
mob.set_flight(true)
|
||||
function on_player_set(pid)
|
||||
mob.set_flight(player.is_flight(pid))
|
||||
body:set_body_type(player.is_noclip(pid) and "kinematic" or "dynamic")
|
||||
end
|
||||
|
||||
function on_physics_update(delta)
|
||||
if not prepared then
|
||||
prepared = true
|
||||
body:set_enabled(true)
|
||||
end
|
||||
|
||||
local pid = entity:get_player()
|
||||
if pid == -1 then
|
||||
return
|
||||
|
|
|
|||
|
|
@ -49,9 +49,9 @@ static util::Buffer<ubyte> write_to_memory(uint width, uint height, const ubyte*
|
|||
png_write_info(png_ptr, info_ptr);
|
||||
|
||||
auto row = std::make_unique<png_byte[]>(pixsize * width);
|
||||
for (uint y = 0; y < height; y++) {
|
||||
for (uint x = 0; x < width; x++) {
|
||||
for (uint i = 0; i < pixsize; i++) {
|
||||
for (int y = height-1; y >= 0; y--) {
|
||||
for (int x = 0; x < width; x++) {
|
||||
for (int i = 0; i < pixsize; i++) {
|
||||
row[x * pixsize + i] =
|
||||
(png_byte)data[(y * width + x) * pixsize + i];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
#include "ImageData.hpp"
|
||||
|
||||
#include "debug/Logger.hpp"
|
||||
|
||||
#include <glm/glm.hpp>
|
||||
#include <assert.h>
|
||||
#include <stdexcept>
|
||||
|
|
@ -7,6 +9,8 @@
|
|||
#include <cmath>
|
||||
#include <algorithm>
|
||||
|
||||
static debug::Logger logger("image-data");
|
||||
|
||||
ImageData::ImageData(ImageFormat format, uint width, uint height)
|
||||
: format(format), width(width), height(height) {
|
||||
size_t pixsize;
|
||||
|
|
@ -106,47 +110,83 @@ std::unique_ptr<ImageData> ImageData::cropped(int x, int y, int width, int heigh
|
|||
return subImage;
|
||||
}
|
||||
|
||||
static bool clip_line(int& x1, int& y1, int& x2, int& y2, int width, int height) {
|
||||
const int left = 0;
|
||||
const int right = width;
|
||||
const int bottom = 0;
|
||||
const int top = height;
|
||||
static bool clip_line(
|
||||
int& x0, int& y0, int& x1, int& y1, int width, int height
|
||||
) {
|
||||
if (width <= 0 || height <= 0) {
|
||||
return false;
|
||||
}
|
||||
constexpr int INSIDE = 0;
|
||||
constexpr int LEFT = 1;
|
||||
constexpr int RIGHT = 2;
|
||||
constexpr int BOTTOM = 4;
|
||||
constexpr int TOP = 8;
|
||||
|
||||
int dx = x2 - x1;
|
||||
int dy = y2 - y1;
|
||||
const int xmin = 0;
|
||||
const int ymin = 0;
|
||||
const int xmax = width - 1;
|
||||
const int ymax = height - 1;
|
||||
|
||||
float t0 = 0.0f;
|
||||
float t1 = 1.0f;
|
||||
auto outcode = [&](int x, int y) {
|
||||
int code = INSIDE;
|
||||
|
||||
auto clip = [](int p, int q, float& t0, float& t1) {
|
||||
if (p == 0) {
|
||||
return q >= 0;
|
||||
}
|
||||
float t = static_cast<float>(q) / p;
|
||||
if (p < 0) {
|
||||
if (t > t1) return false;
|
||||
if (t > t0) t0 = t;
|
||||
} else {
|
||||
if (t < t0) return false;
|
||||
if (t < t1) t1 = t;
|
||||
}
|
||||
return true;
|
||||
if (x < xmin)
|
||||
code |= LEFT;
|
||||
else if (x > xmax)
|
||||
code |= RIGHT;
|
||||
|
||||
if (y < ymin)
|
||||
code |= BOTTOM;
|
||||
else if (y > ymax)
|
||||
code |= TOP;
|
||||
|
||||
return code;
|
||||
};
|
||||
|
||||
if (!clip(-dx, x1 - left, t0, t1)) return false;
|
||||
if (!clip( dx, right - x1, t0, t1)) return false;
|
||||
if (!clip(-dy, y1 - bottom, t0, t1)) return false;
|
||||
if (!clip( dy, top - y1, t0, t1)) return false;
|
||||
int c0 = outcode(x0, y0);
|
||||
int c1 = outcode(x1, y1);
|
||||
|
||||
if (t1 < 1.0f) {
|
||||
x2 = x1 + static_cast<int>(std::round(t1 * dx));
|
||||
y2 = y1 + static_cast<int>(std::round(t1 * dy));
|
||||
while (true) {
|
||||
if (!(c0 | c1)) {
|
||||
return true;
|
||||
}
|
||||
if (c0 & c1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const int out = c0 ? c0 : c1;
|
||||
|
||||
double x = 0.0;
|
||||
double y = 0.0;
|
||||
|
||||
if (out & TOP) {
|
||||
y = ymax;
|
||||
x = x0 + (x1 - x0) * static_cast<double>(ymax - y0) / (y1 - y0);
|
||||
} else if (out & BOTTOM) {
|
||||
y = ymin;
|
||||
x = x0 + (x1 - x0) * static_cast<double>(ymin - y0) / (y1 - y0);
|
||||
} else if (out & RIGHT) {
|
||||
x = xmax;
|
||||
y = y0 + (y1 - y0) * static_cast<double>(xmax - x0) / (x1 - x0);
|
||||
} else { // LEFT
|
||||
x = xmin;
|
||||
y = y0 + (y1 - y0) * static_cast<double>(xmin - x0) / (x1 - x0);
|
||||
}
|
||||
|
||||
if (out == c0) {
|
||||
x0 = std::clamp(static_cast<int>(std::lround(x)), xmin, xmax);
|
||||
y0 = std::clamp(static_cast<int>(std::lround(y)), ymin, ymax);
|
||||
c0 = outcode(x0, y0);
|
||||
} else {
|
||||
x1 = std::clamp(static_cast<int>(std::lround(x)), xmin, xmax);
|
||||
y1 = std::clamp(static_cast<int>(std::lround(y)), ymin, ymax);
|
||||
c1 = outcode(x1, y1);
|
||||
}
|
||||
}
|
||||
if (t0 > 0.0f) {
|
||||
x1 = x1 + static_cast<int>(std::round(t0 * dx));
|
||||
y1 = y1 + static_cast<int>(std::round(t0 * dy));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool is_point_outside(int x, int y, int width, int height) {
|
||||
return x < 0 || y < 0 || x >= width || y >= height;
|
||||
}
|
||||
|
||||
template<uint channels>
|
||||
|
|
@ -155,11 +195,24 @@ static void draw_line(ImageData& image, int x1, int y1, int x2, int y2, const gl
|
|||
uint width = image.getWidth();
|
||||
uint height = image.getHeight();
|
||||
|
||||
glm::ivec4 init {x1, y1, x2, y2};
|
||||
|
||||
if ((x1 < 0 || x1 >= width || x2 < 0 || x2 >= width ||
|
||||
y1 < 0 || y1 >= height || y2 < 0 || y2 >= height) &&
|
||||
!clip_line(x1, y1, x2, y2, width, height)) {
|
||||
return;
|
||||
}
|
||||
// spam info for bug report
|
||||
if (is_point_outside(x1, y1, width, height) || is_point_outside(x2, y2, width, height)) {
|
||||
logger.warning() << "clip_line fault: [" << init.x << ", " << init.y
|
||||
<< "] - [" << init.z << ", " << init.w << "] --> ["
|
||||
<< x1 << ", " << y1 << "] - [" << x2 << ", " << y2
|
||||
<< "]";
|
||||
x1 = glm::clamp(x1, 0, static_cast<int>(width) - 1);
|
||||
y1 = glm::clamp(y1, 0, static_cast<int>(height) - 1);
|
||||
x2 = glm::clamp(x2, 0, static_cast<int>(width) - 1);
|
||||
y2 = glm::clamp(y2, 0, static_cast<int>(height) - 1);
|
||||
}
|
||||
|
||||
int dx = std::abs(x2 - x1);
|
||||
int dy = -std::abs(y2 - y1);
|
||||
|
|
|
|||
|
|
@ -55,6 +55,16 @@ public:
|
|||
return fields;
|
||||
}
|
||||
|
||||
void setFields(dv::value&& table, bool clear) {
|
||||
if (clear) {
|
||||
fields = std::move(table);
|
||||
return;
|
||||
}
|
||||
for (auto&& [key, value] : table.asObject()) {
|
||||
fields[std::move(key)] = std::move(value);
|
||||
}
|
||||
}
|
||||
|
||||
bool hasFields() const {
|
||||
return fields != nullptr;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -82,7 +82,6 @@ void LevelController::update(float delta, bool pause) {
|
|||
continue;
|
||||
}
|
||||
player->rotationInterpolation.updateTimer(delta);
|
||||
player->updateEntity();
|
||||
glm::vec3 position = player->getPosition();
|
||||
player->chunks->configure(
|
||||
glm::floor(position.x),
|
||||
|
|
@ -96,9 +95,9 @@ void LevelController::update(float delta, bool pause) {
|
|||
*player,
|
||||
player.get() == clientPlayer
|
||||
);
|
||||
player->updateEntity();
|
||||
}
|
||||
if (!pause) {
|
||||
// update all objects that needed
|
||||
blocks->update(delta, settings.chunks.padding.get());
|
||||
level->entities->update(delta);
|
||||
for (const auto& [_, player] : *level->players) {
|
||||
|
|
|
|||
|
|
@ -237,6 +237,14 @@ static int l_get_all_data(lua::State* L, ItemStack& stack) {
|
|||
return lua::pushvalue(L, stack.getFields());
|
||||
}
|
||||
|
||||
static int l_set_all_data(lua::State* L, ItemStack& stack) {
|
||||
if (!lua::istable(L, 3)) {
|
||||
throw std::runtime_error("table expected as argument 1");
|
||||
}
|
||||
stack.setFields(lua::tovalue(L, 3), lua::toboolean(L, 4));
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int l_has_data(lua::State* L, ItemStack& stack) {
|
||||
auto key = lua::tostring(L, 3);
|
||||
if (key == nullptr) {
|
||||
|
|
@ -267,6 +275,7 @@ const luaL_Reg inventorylib[] = {
|
|||
{"get_data", lua::wrap<wrap_slot<l_get_data>>},
|
||||
{"set_data", lua::wrap<wrap_slot<l_set_data>>},
|
||||
{"get_all_data", lua::wrap<wrap_slot<l_get_all_data>>},
|
||||
{"set_all_data", lua::wrap<wrap_slot<l_set_all_data>>},
|
||||
{"has_data", lua::wrap<wrap_slot<l_has_data>>},
|
||||
{"create", lua::wrap<l_create>},
|
||||
{"remove", lua::wrap<l_remove>},
|
||||
|
|
|
|||
|
|
@ -81,16 +81,17 @@ union RGBA {
|
|||
uint8_t arr[4];
|
||||
uint32_t rgba;
|
||||
};
|
||||
static_assert(sizeof(RGBA) == 4);
|
||||
|
||||
static RGBA* get_at(const ImageData& data, uint index) {
|
||||
if (index >= data.getWidth() * data.getHeight()) {
|
||||
return nullptr;
|
||||
}
|
||||
static RGBA* get_at(const ImageData& data, size_t index) {
|
||||
return reinterpret_cast<RGBA*>(data.getData() + index * sizeof(RGBA));
|
||||
}
|
||||
|
||||
static RGBA* get_at(const ImageData& data, uint x, uint y) {
|
||||
return get_at(data, y * data.getWidth() + x);
|
||||
if (x >= data.getWidth() || y >= data.getHeight()) {
|
||||
return nullptr;
|
||||
}
|
||||
return get_at(data, static_cast<size_t>(y) * data.getWidth() + x);
|
||||
}
|
||||
|
||||
static RGBA* get_at(State* L, uint x, uint y) {
|
||||
|
|
|
|||
|
|
@ -142,6 +142,7 @@ namespace scripting {
|
|||
void on_entity_grounded(const Entity& entity, float force);
|
||||
void on_entity_fall(const Entity& entity);
|
||||
void on_entity_save(const Entity& entity);
|
||||
void on_entity_player_set(const Entity& entity, int64_t pid);
|
||||
void on_entities_update(int tps, int parts, int part);
|
||||
void on_entities_physics_update(float delta);
|
||||
void on_entities_render(float delta);
|
||||
|
|
|
|||
|
|
@ -71,6 +71,7 @@ static void init_component_events(
|
|||
funcsset.on_aim_off = lua::hasfield(L, "on_aim_off");
|
||||
funcsset.on_attacked = lua::hasfield(L, "on_attacked");
|
||||
funcsset.on_used = lua::hasfield(L, "on_used");
|
||||
funcsset.on_player_set = lua::hasfield(L, "on_player_set");
|
||||
lua::pop(L);
|
||||
}
|
||||
|
||||
|
|
@ -238,6 +239,15 @@ void scripting::on_entity_save(const Entity& entity) {
|
|||
);
|
||||
}
|
||||
|
||||
void scripting::on_entity_player_set(const Entity& entity, int64_t pid) {
|
||||
process_entity_callback(
|
||||
entity,
|
||||
"on_player_set",
|
||||
&EntityFuncsSet::on_player_set,
|
||||
[pid](auto L) { return lua::pushinteger(L, pid); }
|
||||
);
|
||||
}
|
||||
|
||||
void scripting::on_sensor_enter(
|
||||
const Entity& entity, size_t index, entityid_t oid
|
||||
) {
|
||||
|
|
|
|||
|
|
@ -113,6 +113,11 @@ int64_t Entity::getPlayer() const {
|
|||
}
|
||||
|
||||
void Entity::setPlayer(int64_t id) {
|
||||
registry.get<EntityId>(entity).player = id;
|
||||
auto& eid = registry.get<EntityId>(entity);
|
||||
if (eid.player == id) {
|
||||
return;
|
||||
}
|
||||
eid.player = id;
|
||||
scripting::on_entity_player_set(*this, id);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -81,7 +81,7 @@ void Player::updateEntity() {
|
|||
}
|
||||
}
|
||||
|
||||
Hitbox* Player::getHitbox() {
|
||||
Hitbox* Player::getHitbox() const {
|
||||
if (auto entity = level.entities->get(eid)) {
|
||||
return &entity->getRigidbody().hitbox;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -135,7 +135,7 @@ public:
|
|||
|
||||
bool isCurrentCameraBuiltin() const;
|
||||
|
||||
Hitbox* getHitbox();
|
||||
Hitbox* getHitbox() const;
|
||||
|
||||
void setSpawnPoint(glm::vec3 point);
|
||||
glm::vec3 getSpawnPoint() const;
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ struct EntityFuncsSet {
|
|||
bool on_aim_off;
|
||||
bool on_attacked;
|
||||
bool on_used;
|
||||
bool on_player_set;
|
||||
};
|
||||
|
||||
struct UserComponent {
|
||||
|
|
|
|||
|
|
@ -88,12 +88,22 @@ void Skeleton::deserialize(const dv::value& root) {
|
|||
|
||||
void Skeleton::setConfig(std::shared_ptr<const SkeletonConfig> rigConfig) {
|
||||
config = std::move(rigConfig);
|
||||
|
||||
const auto& bones = config->getBones();
|
||||
|
||||
pose.matrices.resize(
|
||||
config->getBones().size(), glm::mat4(1.0f)
|
||||
bones.size(), glm::mat4(1.0f)
|
||||
);
|
||||
calculated.matrices.resize(
|
||||
config->getBones().size(), glm::mat4(1.0f)
|
||||
bones.size(), glm::mat4(1.0f)
|
||||
);
|
||||
|
||||
modelOverrides.resize(bones.size());
|
||||
flags.resize(bones.size());
|
||||
|
||||
for (size_t i = 0; i < bones.size(); i++) {
|
||||
flags[i].visible = true;
|
||||
}
|
||||
}
|
||||
|
||||
static void get_all_nodes(std::vector<Bone*>& nodes, Bone* node) {
|
||||
|
|
|
|||
|
|
@ -309,7 +309,9 @@ static inline voxel* raycast_blocks(
|
|||
} else {
|
||||
iend = {ix, iy, iz};
|
||||
norm = {0, 0, 0};
|
||||
norm[steppedIndex] = -step[steppedIndex];
|
||||
if (steppedIndex != -1) {
|
||||
norm[steppedIndex] = -step[steppedIndex];
|
||||
}
|
||||
return voxel;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue