mirror of
https://github.com/MihailRis/voxelcore.git
synced 2026-10-12 06:21:50 +00:00
fix extended block grounding (new block property)
This commit is contained in:
parent
0cc8c70a17
commit
0b7dc14f55
7 changed files with 111 additions and 8 deletions
|
|
@ -241,6 +241,15 @@ Number of block inventory slots. Default - 0 (no inventory).
|
||||||
|
|
||||||
Array of three integers. Default value is `[1, 1, 1]`.
|
Array of three integers. Default value is `[1, 1, 1]`.
|
||||||
|
|
||||||
|
### *grounding-behaviour*
|
||||||
|
|
||||||
|
Defines the behavior of the extended grounded block. Available behavior options:
|
||||||
|
|
||||||
|
- "partial" - at least one segment must be grounded (default)
|
||||||
|
- "complete" - all segments must be grounded
|
||||||
|
- "origin" - origin segment must be grounded
|
||||||
|
|
||||||
|
|
||||||
## Block fields
|
## Block fields
|
||||||
|
|
||||||
Block fields allow you to write more data unique to a specified voxel than the user bits allow.
|
Block fields allow you to write more data unique to a specified voxel than the user bits allow.
|
||||||
|
|
|
||||||
|
|
@ -247,6 +247,14 @@
|
||||||
|
|
||||||
Массив из трех целых чисел. Значение по-умолчанию - `[1, 1, 1]`.
|
Массив из трех целых чисел. Значение по-умолчанию - `[1, 1, 1]`.
|
||||||
|
|
||||||
|
### Поведение приземленности - *grounding-behaviour*
|
||||||
|
|
||||||
|
Определяет поведение расширенного приземленного блока. Доступные варианты поведения:
|
||||||
|
|
||||||
|
- "partial" - как минимум один сегмент блока должен быть приземленным (по-умолчанию)
|
||||||
|
- "complete" - все сегменты блока должны быть приземленными
|
||||||
|
- "origin" - главный сегмент должен быть приземленным
|
||||||
|
|
||||||
## Поля блока
|
## Поля блока
|
||||||
|
|
||||||
Поля блоков позволяет записывать больше уникальных для конкретного блока данных, чем это позволяют пользовательские биты.
|
Поля блоков позволяет записывать больше уникальных для конкретного блока данных, чем это позволяют пользовательские биты.
|
||||||
|
|
|
||||||
|
|
@ -206,6 +206,15 @@ template<> void ContentUnitLoader<Block>::loadUnit(
|
||||||
def.defaults.model.type = BlockModelType::AABB;
|
def.defaults.model.type = BlockModelType::AABB;
|
||||||
def.hitboxes = {AABB(def.size)};
|
def.hitboxes = {AABB(def.size)};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// grounding behaviour
|
||||||
|
if (root.has("grounding-behaviour")) {
|
||||||
|
std::string groundingBehaviourName = GroundingBehaviourMeta.getNameString(def.groundingBehaviour);
|
||||||
|
root.at("grounding-behaviour").get(groundingBehaviourName);
|
||||||
|
if (!GroundingBehaviourMeta.getItem(groundingBehaviourName, def.groundingBehaviour)) {
|
||||||
|
logger.error() << "unknown grounding behaviour: " << groundingBehaviourName;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// primitive properties
|
// primitive properties
|
||||||
|
|
|
||||||
|
|
@ -106,10 +106,17 @@ void BlocksController::updateBlock(int x, int y, int z) {
|
||||||
if (vox == nullptr) return;
|
if (vox == nullptr) return;
|
||||||
const auto& def = level.content.getIndices()->blocks.require(vox->id);
|
const auto& def = level.content.getIndices()->blocks.require(vox->id);
|
||||||
if (def.grounded) {
|
if (def.grounded) {
|
||||||
const auto& vec = get_ground_direction(def, vox->state.rotation);
|
if (def.rt.extended) {
|
||||||
if (!blocks_agent::is_solid_at(chunks, x + vec.x, y + vec.y, z + vec.z)) {
|
auto origin = blocks_agent::seek_origin(chunks, {x, y, z}, def, vox->state);
|
||||||
breakBlock(nullptr, def, x, y, z);
|
if (!blocks_agent::check_grounding(chunks, def, vox->state.rotation, origin)) {
|
||||||
return;
|
breakBlock(nullptr, def, origin.x, origin.y, origin.z);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (!blocks_agent::check_grounding(chunks, def, vox->state.rotation, {x, y, z})) {
|
||||||
|
breakBlock(nullptr, def, x, y, z);
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (def.rt.funcsset.update) {
|
if (def.rt.funcsset.update) {
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,7 @@
|
||||||
#include "scripting/scripting.hpp"
|
#include "scripting/scripting.hpp"
|
||||||
#include "settings.hpp"
|
#include "settings.hpp"
|
||||||
#include "voxels/Block.hpp"
|
#include "voxels/Block.hpp"
|
||||||
|
#include "voxels/blocks_agent.hpp"
|
||||||
#include "voxels/Chunks.hpp"
|
#include "voxels/Chunks.hpp"
|
||||||
#include "voxels/voxel.hpp"
|
#include "voxels/voxel.hpp"
|
||||||
#include "window/Camera.hpp"
|
#include "window/Camera.hpp"
|
||||||
|
|
@ -448,10 +449,7 @@ void PlayerController::processRightClick(
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (def.grounded) {
|
if (def.grounded) {
|
||||||
const auto& vec = get_ground_direction(def, state.rotation);
|
if (!blocks_agent::check_grounding(chunks, def, state.rotation, coord)) {
|
||||||
if (!chunks.isSolidBlock(
|
|
||||||
coord.x + vec.x, coord.y + vec.y, coord.z + vec.z
|
|
||||||
)) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -140,6 +140,22 @@ VC_ENUM_METADATA(CullingMode)
|
||||||
{"disabled", CullingMode::DISABLED},
|
{"disabled", CullingMode::DISABLED},
|
||||||
VC_ENUM_END
|
VC_ENUM_END
|
||||||
|
|
||||||
|
/// @brief Grounding behaviour for extended blocks
|
||||||
|
enum class GroundingBehaviour : uint8_t {
|
||||||
|
/// @brief at least one segment must be grounded
|
||||||
|
PARTIAL,
|
||||||
|
/// @brief all segments must be grounded
|
||||||
|
COMPLETE,
|
||||||
|
/// @brief origin segment must be grounded
|
||||||
|
ORIGIN
|
||||||
|
};
|
||||||
|
|
||||||
|
VC_ENUM_METADATA(GroundingBehaviour)
|
||||||
|
{"partial", GroundingBehaviour::PARTIAL},
|
||||||
|
{"complete", GroundingBehaviour::COMPLETE},
|
||||||
|
{"origin", GroundingBehaviour::ORIGIN},
|
||||||
|
VC_ENUM_END
|
||||||
|
|
||||||
/// @brief Common kit of block properties applied to groups of blocks
|
/// @brief Common kit of block properties applied to groups of blocks
|
||||||
struct BlockMaterial : Serializable {
|
struct BlockMaterial : Serializable {
|
||||||
std::string name;
|
std::string name;
|
||||||
|
|
@ -239,6 +255,9 @@ public:
|
||||||
/// @brief Explicitly overriding 'solid' property if true assigned
|
/// @brief Explicitly overriding 'solid' property if true assigned
|
||||||
bool explictlySolid = false;
|
bool explictlySolid = false;
|
||||||
|
|
||||||
|
/// @brief Grounding behaviour
|
||||||
|
GroundingBehaviour groundingBehaviour = GroundingBehaviour::PARTIAL;
|
||||||
|
|
||||||
/// @brief Set of block physical hitboxes
|
/// @brief Set of block physical hitboxes
|
||||||
std::vector<AABB> hitboxes {AABB()};
|
std::vector<AABB> hitboxes {AABB()};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -494,4 +494,57 @@ inline const AABB* is_obstacle_at(const Storage& chunks, float x, float y, float
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// @brief Check block grounding
|
||||||
|
/// @tparam Storage chunks storage class
|
||||||
|
/// @param chunks chunks storage
|
||||||
|
/// @param def block definition
|
||||||
|
/// @param rotationIndex target block rotation index
|
||||||
|
/// @param origin target block origin
|
||||||
|
/// @return true if grounded
|
||||||
|
template <class Storage>
|
||||||
|
inline bool check_grounding(
|
||||||
|
const Storage& chunks,
|
||||||
|
const Block& def,
|
||||||
|
uint8_t rotationIndex,
|
||||||
|
const glm::ivec3& origin
|
||||||
|
) {
|
||||||
|
const auto& vec = get_ground_direction(def, rotationIndex);
|
||||||
|
|
||||||
|
if (def.rt.extended) {
|
||||||
|
const auto& rotation = def.rotations.variants[rotationIndex];
|
||||||
|
|
||||||
|
if (def.groundingBehaviour == GroundingBehaviour::PARTIAL) {
|
||||||
|
for (int sz = 0; sz < def.size.z; sz++) {
|
||||||
|
for (int sx = 0; sx < def.size.x; sx++) {
|
||||||
|
auto pos = origin;
|
||||||
|
pos += rotation.axes[0] * sx;
|
||||||
|
pos += rotation.axes[2] * sz;
|
||||||
|
if (blocks_agent::is_solid_at(chunks, pos.x + vec.x, pos.y + vec.y, pos.z + vec.z)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else if (def.groundingBehaviour == GroundingBehaviour::COMPLETE) {
|
||||||
|
for (int sz = 0; sz < def.size.z; sz++) {
|
||||||
|
for (int sx = 0; sx < def.size.x; sx++) {
|
||||||
|
auto pos = origin;
|
||||||
|
pos += rotation.axes[0] * sx;
|
||||||
|
pos += rotation.axes[2] * sz;
|
||||||
|
if (!blocks_agent::is_solid_at(chunks, pos.x + vec.x, pos.y + vec.y, pos.z + vec.z)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else if (def.groundingBehaviour == GroundingBehaviour::ORIGIN) {
|
||||||
|
return blocks_agent::is_solid_at(chunks, origin.x + vec.x, origin.y + vec.y, origin.z + vec.z);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return blocks_agent::is_solid_at(chunks, origin.x + vec.x, origin.y + vec.y, origin.z + vec.z);
|
||||||
|
}
|
||||||
|
|
||||||
} // blocks_agent
|
} // blocks_agent
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue