Merge pull request #891 from MihailRis/fixes

fixes
This commit is contained in:
MihailRis 2026-07-27 23:06:08 +03:00 • committed by GitHub
commit fae6b13367
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
13 changed files with 43 additions and 13 deletions

View file

@ -61,12 +61,16 @@ Determines how the physics engine will work with it.
### *blocking* ### *blocking*
Determines whether the entity blocks installation of blocks. If true - the entity blocks the placement of a block that intersects with the entity's hitbox.
*In the future will also block other entities movement.* *In the future will also block other entities movement.*
Default value: *true*. Default value: *true*.
### *selectable*
If set to `false` the cursor will ignore the entity, passing the ray.
### *sensors* ### *sensors*
A sensor is an area attached to a physical body that detects the entry of other bodies into it. A sensor is an area attached to a physical body that detects the entry of other bodies into it.

View file

@ -92,6 +92,8 @@ world.raycast(
-- exclusion filtering mode: -- exclusion filtering mode:
-- if true, filter_entities defines the list of ignored entity types -- if true, filter_entities defines the list of ignored entity types
entities_exclusion: bool = false, entities_exclusion: bool = false,
-- include entities with selectable=false
nonselect_entities: bool = false;
[==[ additional parameters (blocks) ]==] [==[ additional parameters (blocks) ]==]
-- id of the block types used for filtering -- id of the block types used for filtering

View file

@ -61,12 +61,16 @@
### Блокирование - *blocking* ### Блокирование - *blocking*
Определяет блокирует ли сущность установку блоков. Определяет, блокирует ли сущность установку блока, пересекающегося с хитбоксом сущности.
*В будущем будет также блокировать движение других сущностей.* *В будущем будет также блокировать движение других сущностей.*
Значение по-умолчанию: *true*. Значение по-умолчанию: *true*.
### Выделяемость - *selectable*
При значении в `false` курсор будет игнорировать cущность, пропуская луч далее.
### Список сенсоров - *sensors* ### Список сенсоров - *sensors*
Сенсор - область пространства, привязанная к физическому телу, детектирующее попадание в него других тел. Сенсор - область пространства, привязанная к физическому телу, детектирующее попадание в него других тел.

View file

@ -91,6 +91,8 @@ world.raycast(
-- исключающий режим фильтрации: -- исключающий режим фильтрации:
-- при значении (true) filter_entities определяет список игнорируемых -- при значении (true) filter_entities определяет список игнорируемых
entities_exclusion: bool = false, entities_exclusion: bool = false,
-- учитывать сущности с selectable=false
nonselect_entities: bool = false;
[==[ дополнительные параметры (блоки) ]==] [==[ дополнительные параметры (блоки) ]==]
-- id типов блоков используемых для фильтрации -- id типов блоков используемых для фильтрации

View file

@ -10,7 +10,7 @@ dropitem = ARGS
if dropitem.item then if dropitem.item then
dropitem.id = item.index(dropitem.item) dropitem.id = item.index(dropitem.item)
end end
if dropitem then if dropitem then
timer = dropitem.pickup_delay or timer timer = dropitem.pickup_delay or timer
end end
if SAVED_DATA.item then if SAVED_DATA.item then
@ -26,6 +26,7 @@ function on_save()
end end
if vc.is_client() then if vc.is_client() then
local SCALE = 0.3
local scale = {1, 1, 1} local scale = {1, 1, 1}
local rotation = mat4.rotate({ local rotation = mat4.rotate({
math.random(), math.random(), math.random() math.random(), math.random(), math.random()
@ -35,7 +36,7 @@ if vc.is_client() then
local matrix = mat4.idt() local matrix = mat4.idt()
rig:set_model(0, item.model_name(dropitem.id)) rig:set_model(0, item.model_name(dropitem.id))
local bodysize = math.min(scale[1], scale[2], scale[3]) local bodysize = math.min(scale[1], scale[2], scale[3])
body:set_size({scale[1], bodysize, scale[3]}) body:set_size(vec3.mul({scale[1], bodysize, scale[3]}, SCALE))
mat4.mul(matrix, rotation, matrix) mat4.mul(matrix, rotation, matrix)
mat4.scale(matrix, scale, matrix) mat4.scale(matrix, scale, matrix)
rig:set_matrix(0, matrix) rig:set_matrix(0, matrix)

View file

@ -26,17 +26,18 @@ std::unique_ptr<Content> ContentBuilder::build() {
def.rt.tags.insert(tags.add(tag)); def.rt.tags.insert(tags.add(tag));
} }
auto isSolid = [](const Variant& variant) {
return variant.model.type == BlockModelType::BLOCK ||
variant.culling == CullingMode::OPTIONAL;
};
if (def.variants) { if (def.variants) {
for (auto& variant : def.variants->variants) { for (auto& variant : def.variants->variants) {
variant.rt.solid = variant.rt.solid = isSolid(variant) || def.explictlySolid;
variant.model.type == BlockModelType::BLOCK ||
def.explictlySolid;
} }
def.defaults = def.variants->variants.at(0); def.defaults = def.variants->variants.at(0);
} else { } else {
def.defaults.rt.solid = def.defaults.rt.solid = isSolid(def.defaults) || def.explictlySolid;
def.defaults.model.type == BlockModelType::BLOCK ||
def.explictlySolid;
} }
const float EPSILON = 0.01f; const float EPSILON = 0.01f;

View file

@ -89,6 +89,7 @@ template<> void ContentUnitLoader<EntityDef>::loadUnit(
root.at("skeleton-name").get(def.skeletonName); root.at("skeleton-name").get(def.skeletonName);
root.at("material").get(def.material); root.at("material").get(def.material);
root.at("blocking").get(def.blocking); root.at("blocking").get(def.blocking);
root.at("selectable").get(def.selectable);
root.at("solid").get(def.solid); root.at("solid").get(def.solid);
root.at("mass").get(def.mass); root.at("mass").get(def.mass);
root.at("elasticity").get(def.elasticity); root.at("elasticity").get(def.elasticity);

View file

@ -30,6 +30,7 @@ void ContentGfxCache::refreshVariant(
uint8_t variantIndex, uint8_t variantIndex,
const Atlas& atlas const Atlas& atlas
) { ) {
std::unordered_map<std::string, std::string> optionalTextures;
bool denseRender = settings.denseRender.get(); bool denseRender = settings.denseRender.get();
for (uint side = 0; side < 6; side++) { for (uint side = 0; side < 6; side++) {
std::string tex = variant.textureFaces[side]; std::string tex = variant.textureFaces[side];
@ -43,6 +44,7 @@ void ContentGfxCache::refreshVariant(
texOpaque = tex; texOpaque = tex;
} else if (variant.culling == CullingMode::OPTIONAL && !denseRender) { } else if (variant.culling == CullingMode::OPTIONAL && !denseRender) {
tex = texOpaque; tex = texOpaque;
optionalTextures[variant.textureFaces[side]] = texOpaque;
} }
size_t index = getRegionIndex(def.rt.id, variantIndex, side, false); size_t index = getRegionIndex(def.rt.id, variantIndex, side, false);
sideregions[index] = atlas.get(tex); sideregions[index] = atlas.get(tex);
@ -56,7 +58,12 @@ void ContentGfxCache::refreshVariant(
if (pos == std::string::npos) { if (pos == std::string::npos) {
continue; continue;
} }
if (auto region = atlas.getIf(mesh.texture.substr(pos+1))) { std::string texture = mesh.texture.substr(pos+1);
const auto& found = optionalTextures.find(texture);
if (found != optionalTextures.end()) {
texture = found->second;
}
if (auto region = atlas.getIf(texture)) {
for (auto& vertex : mesh.vertices) { for (auto& vertex : mesh.vertices) {
vertex.uv = region->apply(vertex.uv); vertex.uv = region->apply(vertex.uv);
} }

View file

@ -538,7 +538,6 @@ void BlocksRenderer::render(
break; break;
} }
case BlockModelType::CUSTOM: { case BlockModelType::CUSTOM: {
if (!denseRender)
blockCustomModel( blockCustomModel(
{x, y, z}, {x, y, z},
def, def,

View file

@ -311,6 +311,10 @@ static int l_world_raycast(lua::State* L) {
entityRaycast.entityFilterExcludeMode = lua::toboolean(L, -1); entityRaycast.entityFilterExcludeMode = lua::toboolean(L, -1);
lua::pop(L); lua::pop(L);
} }
if (lua::getfield(L, "nonselect_entities", 1)) {
entityRaycast.includeNonSelectable = lua::toboolean(L, -1);
lua::pop(L);
}
if (lua::getfield(L, "filter_blocks", 1)) { if (lua::getfield(L, "filter_blocks", 1)) {
load_blocks_filter(L, -1, filteredBlocks); load_blocks_filter(L, -1, filteredBlocks);
blocksRaycast.filter = &filteredBlocks; blocksRaycast.filter = &filteredBlocks;

View file

@ -176,7 +176,8 @@ std::optional<Entities::RaycastResult> Entities::rayCast(
for (auto [entity, eid, transform, body] : view.each()) { for (auto [entity, eid, transform, body] : view.each()) {
if (eid.uid == settings.ignoredUid || !body.enabled || if (eid.uid == settings.ignoredUid || !body.enabled ||
(settings.solidEntitiesOnly && !eid.def.solid)) { (settings.solidEntitiesOnly && !eid.def.solid) ||
(!eid.def.selectable && !settings.includeNonSelectable)) {
continue; continue;
} }
if (settings.entitiesFilter) { if (settings.entitiesFilter) {

View file

@ -85,6 +85,7 @@ public:
bool solidEntitiesOnly = false; bool solidEntitiesOnly = false;
bool entityFilterExcludeMode = false; bool entityFilterExcludeMode = false;
const std::set<entitydefid_t>* entitiesFilter = nullptr; const std::set<entitydefid_t>* entitiesFilter = nullptr;
bool includeNonSelectable = false;
}; };
struct RaycastResult { struct RaycastResult {

View file

@ -42,6 +42,9 @@ struct EntityDef {
/// @brief Solid entity material material /// @brief Solid entity material material
std::string material; std::string material;
/// @brief Can the entity be interacted with cursor (on_attack, on_use)
bool selectable = true;
/// @brief Does entity prevent blocks setup /// @brief Does entity prevent blocks setup
bool blocking = true; bool blocking = true;