mirror of
https://github.com/MihailRis/voxelcore.git
synced 2026-10-06 11:31:49 +00:00
Merge branch 'MihailRis:main' into main
This commit is contained in:
commit
e049f4ae0c
61 changed files with 1209 additions and 534 deletions
|
|
@ -150,6 +150,48 @@ static int l_set_linear_damping(lua::State* L) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int l_set_material(lua::State* L) {
|
||||
if (auto entity = get_entity(L, 1)) {
|
||||
entity->getRigidbody().hitbox.material = lua::require_string(L, 2);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int l_get_material(lua::State* L) {
|
||||
if (auto entity = get_entity(L, 1)) {
|
||||
return lua::pushstring(L, entity->getRigidbody().hitbox.material);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int l_get_mass(lua::State* L) {
|
||||
if (auto entity = get_entity(L, 1)) {
|
||||
return lua::pushnumber(L, entity->getRigidbody().mass);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int l_set_mass(lua::State* L) {
|
||||
if (auto entity = get_entity(L, 1)) {
|
||||
entity->getRigidbody().mass = lua::tonumber(L, 2);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int l_get_elasticity(lua::State* L) {
|
||||
if (auto entity = get_entity(L, 1)) {
|
||||
return lua::pushnumber(L, entity->getRigidbody().elasticity);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int l_set_elasticity(lua::State* L) {
|
||||
if (auto entity = get_entity(L, 1)) {
|
||||
entity->getRigidbody().elasticity = lua::tonumber(L, 2);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
const luaL_Reg rigidbodylib[] = {
|
||||
{"is_enabled", lua::wrap<l_is_enabled>},
|
||||
{"set_enabled", lua::wrap<l_set_enabled>},
|
||||
|
|
@ -169,5 +211,11 @@ const luaL_Reg rigidbodylib[] = {
|
|||
{"set_crouching", lua::wrap<l_set_crouching>},
|
||||
{"get_body_type", lua::wrap<l_get_body_type>},
|
||||
{"set_body_type", lua::wrap<l_set_body_type>},
|
||||
{"set_material", lua::wrap<l_set_material>},
|
||||
{"get_material", lua::wrap<l_get_material>},
|
||||
{"get_mass", lua::wrap<l_get_mass>},
|
||||
{"set_mass", lua::wrap<l_set_mass>},
|
||||
{"get_elasticity", lua::wrap<l_get_elasticity>},
|
||||
{"set_elasticity", lua::wrap<l_set_elasticity>},
|
||||
{nullptr, nullptr}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ static int l_set_pos(lua::State* L) {
|
|||
auto vec = lua::tovec3(L, 2);
|
||||
check_valid(vec);
|
||||
entity->getTransform().setPos(vec);
|
||||
entity->getRigidbody().hitbox.position = vec;
|
||||
entity->getRigidbody().hitbox.setPos(vec);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,8 +20,22 @@
|
|||
|
||||
using namespace scripting;
|
||||
|
||||
static inline const Block* get_block_def(lua::State* L) {
|
||||
auto indices = content->getIndices();
|
||||
static const Content& require_content() {
|
||||
if (content == nullptr) {
|
||||
throw std::runtime_error("content is not initialized");
|
||||
}
|
||||
return *content;
|
||||
}
|
||||
|
||||
static Level& require_level() {
|
||||
if (level == nullptr) {
|
||||
throw std::runtime_error("level is not initialized");
|
||||
}
|
||||
return *level;
|
||||
}
|
||||
|
||||
static const Block* get_block_def(lua::State* L) {
|
||||
auto indices = require_content().getIndices();
|
||||
auto id = lua::tointeger(L, 1);
|
||||
return indices->blocks.get(id);
|
||||
}
|
||||
|
|
@ -45,7 +59,7 @@ static int l_is_solid_at(lua::State* L) {
|
|||
auto y = lua::tointeger(L, 2);
|
||||
auto z = lua::tointeger(L, 3);
|
||||
return lua::pushboolean(
|
||||
L, blocks_agent::is_solid_at(*level->chunks, x, y, z)
|
||||
L, blocks_agent::is_solid_at(*require_level().chunks, x, y, z)
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -55,7 +69,7 @@ static int l_count(lua::State* L) {
|
|||
|
||||
static int l_index(lua::State* L) {
|
||||
auto name = lua::require_string(L, 1);
|
||||
return lua::pushinteger(L, content->blocks.require(name).rt.id);
|
||||
return lua::pushinteger(L, require_content().blocks.require(name).rt.id);
|
||||
}
|
||||
|
||||
static int l_is_extended(lua::State* L) {
|
||||
|
|
@ -76,7 +90,7 @@ static int l_is_segment(lua::State* L) {
|
|||
auto x = lua::tointeger(L, 1);
|
||||
auto y = lua::tointeger(L, 2);
|
||||
auto z = lua::tointeger(L, 3);
|
||||
const auto& vox = blocks_agent::require(*level->chunks, x, y, z);
|
||||
const auto& vox = blocks_agent::require(*require_level().chunks, x, y, z);
|
||||
return lua::pushboolean(L, vox.state.segment);
|
||||
}
|
||||
|
||||
|
|
@ -84,10 +98,11 @@ static int l_seek_origin(lua::State* L) {
|
|||
auto x = lua::tointeger(L, 1);
|
||||
auto y = lua::tointeger(L, 2);
|
||||
auto z = lua::tointeger(L, 3);
|
||||
const auto& vox = blocks_agent::require(*level->chunks, x, y, z);
|
||||
const auto& level = require_level();
|
||||
const auto& vox = blocks_agent::require(*level.chunks, x, y, z);
|
||||
auto& def = indices->blocks.require(vox.id);
|
||||
return lua::pushivec_stack(
|
||||
L, blocks_agent::seek_origin(*level->chunks, {x, y, z}, def, vox.state)
|
||||
L, blocks_agent::seek_origin(*level.chunks, {x, y, z}, def, vox.state)
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -98,10 +113,12 @@ static int l_set(lua::State* L) {
|
|||
auto id = lua::tointeger(L, 4);
|
||||
auto state = lua::tointeger(L, 5);
|
||||
bool noupdate = lua::toboolean(L, 6);
|
||||
if (static_cast<size_t>(id) >= indices->blocks.count()) {
|
||||
auto& level = require_level();
|
||||
auto& indices = require_content().getIndices()->blocks;
|
||||
if (static_cast<size_t>(id) >= indices.count()) {
|
||||
return 0;
|
||||
}
|
||||
if (!blocks_agent::set(*level->chunks, x, y, z, id, int2blockstate(state))) {
|
||||
if (!blocks_agent::set(*level.chunks, x, y, z, id, int2blockstate(state))) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -123,7 +140,7 @@ static int l_get(lua::State* L) {
|
|||
auto x = lua::tointeger(L, 1);
|
||||
auto y = lua::tointeger(L, 2);
|
||||
auto z = lua::tointeger(L, 3);
|
||||
auto vox = blocks_agent::get(*level->chunks, x, y, z);
|
||||
auto vox = blocks_agent::get(*require_level().chunks, x, y, z);
|
||||
int id = vox == nullptr ? -1 : vox->id;
|
||||
return lua::pushinteger(L, id);
|
||||
}
|
||||
|
|
@ -138,8 +155,9 @@ template<int n>
|
|||
static int get_axis(lua::State* L) {
|
||||
auto x = lua::tointeger(L, 1);
|
||||
auto y = lua::tointeger(L, 2);
|
||||
auto& level = require_level();
|
||||
if (lua::gettop(L) == 2) {
|
||||
const auto& def = level->content.getIndices()->blocks.require(x);
|
||||
const auto& def = level.content.getIndices()->blocks.require(x);
|
||||
return get_axis<n>(L, def, y);
|
||||
}
|
||||
auto z = lua::tointeger(L, 3);
|
||||
|
|
@ -147,11 +165,11 @@ static int get_axis(lua::State* L) {
|
|||
glm::ivec3 defAxis {};
|
||||
defAxis[n] = 1;
|
||||
|
||||
auto vox = blocks_agent::get(*level->chunks, x, y, z);
|
||||
auto vox = blocks_agent::get(*level.chunks, x, y, z);
|
||||
if (vox == nullptr) {
|
||||
return lua::pushivec_stack(L, defAxis);
|
||||
}
|
||||
const auto& def = level->content.getIndices()->blocks.require(vox->id);
|
||||
const auto& def = level.content.getIndices()->blocks.require(vox->id);
|
||||
if (!def.rotatable) {
|
||||
return lua::pushivec_stack(L, defAxis);
|
||||
} else {
|
||||
|
|
@ -175,7 +193,7 @@ static int l_get_rotation(lua::State* L) {
|
|||
auto x = lua::tointeger(L, 1);
|
||||
auto y = lua::tointeger(L, 2);
|
||||
auto z = lua::tointeger(L, 3);
|
||||
auto vox = blocks_agent::get(*level->chunks, x, y, z);
|
||||
auto vox = blocks_agent::get(*require_level().chunks, x, y, z);
|
||||
int rotation = vox == nullptr ? 0 : vox->state.rotation;
|
||||
return lua::pushinteger(L, rotation);
|
||||
}
|
||||
|
|
@ -185,7 +203,7 @@ static int l_set_rotation(lua::State* L) {
|
|||
auto y = lua::tointeger(L, 2);
|
||||
auto z = lua::tointeger(L, 3);
|
||||
auto value = lua::tointeger(L, 4);
|
||||
blocks_agent::set_rotation(*level->chunks, x, y, z, value);
|
||||
blocks_agent::set_rotation(*require_level().chunks, x, y, z, value);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -193,7 +211,7 @@ static int l_get_states(lua::State* L) {
|
|||
auto x = lua::tointeger(L, 1);
|
||||
auto y = lua::tointeger(L, 2);
|
||||
auto z = lua::tointeger(L, 3);
|
||||
auto vox = blocks_agent::get(*level->chunks, x, y, z);
|
||||
auto vox = blocks_agent::get(*require_level().chunks, x, y, z);
|
||||
int states = vox == nullptr ? 0 : blockstate2int(vox->state);
|
||||
return lua::pushinteger(L, states);
|
||||
}
|
||||
|
|
@ -208,7 +226,7 @@ static int l_set_states(lua::State* L) {
|
|||
}
|
||||
int cx = floordiv<CHUNK_W>(x);
|
||||
int cz = floordiv<CHUNK_D>(z);
|
||||
auto chunk = blocks_agent::get_chunk(*level->chunks, cx, cz);
|
||||
auto chunk = blocks_agent::get_chunk(*require_level().chunks, cx, cz);
|
||||
if (chunk == nullptr) {
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -227,16 +245,17 @@ static int l_get_user_bits(lua::State* L) {
|
|||
auto offset = lua::tointeger(L, 4) + VOXEL_USER_BITS_OFFSET;
|
||||
auto bits = lua::tointeger(L, 5);
|
||||
|
||||
auto vox = blocks_agent::get(*level->chunks, x, y, z);
|
||||
auto& level = require_level();
|
||||
auto vox = blocks_agent::get(*level.chunks, x, y, z);
|
||||
if (vox == nullptr) {
|
||||
return lua::pushinteger(L, 0);
|
||||
}
|
||||
const auto& def = content->getIndices()->blocks.require(vox->id);
|
||||
const auto& def = level.content.getIndices()->blocks.require(vox->id);
|
||||
if (def.rt.extended) {
|
||||
auto origin = blocks_agent::seek_origin(
|
||||
*level->chunks, {x, y, z}, def, vox->state
|
||||
*level.chunks, {x, y, z}, def, vox->state
|
||||
);
|
||||
vox = blocks_agent::get(*level->chunks, origin.x, origin.y, origin.z);
|
||||
vox = blocks_agent::get(*level.chunks, origin.x, origin.y, origin.z);
|
||||
if (vox == nullptr) {
|
||||
return lua::pushinteger(L, 0);
|
||||
}
|
||||
|
|
@ -246,7 +265,9 @@ static int l_get_user_bits(lua::State* L) {
|
|||
}
|
||||
|
||||
static int l_get_variant(lua::State* L) {
|
||||
auto& chunks = *level->chunks;
|
||||
auto& level = require_level();
|
||||
auto& chunks = *level.chunks;
|
||||
|
||||
auto x = lua::tointeger(L, 1);
|
||||
auto y = lua::tointeger(L, 2);
|
||||
auto z = lua::tointeger(L, 3);
|
||||
|
|
@ -255,7 +276,7 @@ static int l_get_variant(lua::State* L) {
|
|||
if (vox == nullptr) {
|
||||
return lua::pushinteger(L, 0);
|
||||
}
|
||||
const auto& def = content->getIndices()->blocks.require(vox->id);
|
||||
const auto& def = level.content.getIndices()->blocks.require(vox->id);
|
||||
if (def.variants == nullptr) {
|
||||
return lua::pushinteger(L, 0);
|
||||
}
|
||||
|
|
@ -272,7 +293,9 @@ static int l_get_variant(lua::State* L) {
|
|||
}
|
||||
|
||||
static int l_set_user_bits(lua::State* L) {
|
||||
auto& chunks = *level->chunks;
|
||||
auto& level = require_level();
|
||||
auto& chunks = *level.chunks;
|
||||
|
||||
auto x = lua::tointeger(L, 1);
|
||||
auto y = lua::tointeger(L, 2);
|
||||
auto z = lua::tointeger(L, 3);
|
||||
|
|
@ -291,7 +314,7 @@ static int l_set_user_bits(lua::State* L) {
|
|||
int lx = x - cx * CHUNK_W;
|
||||
int lz = z - cz * CHUNK_D;
|
||||
auto vox = &chunk->voxels[vox_index(lx, y, lz)];
|
||||
const auto& def = content->getIndices()->blocks.require(vox->id);
|
||||
const auto& def = level.content.getIndices()->blocks.require(vox->id);
|
||||
if (def.rt.extended) {
|
||||
auto origin = blocks_agent::seek_origin(chunks, {x, y, z}, def, vox->state);
|
||||
vox = blocks_agent::get(chunks, origin.x, origin.y, origin.z);
|
||||
|
|
@ -313,7 +336,9 @@ static int l_set_user_bits(lua::State* L) {
|
|||
}
|
||||
|
||||
static int l_set_variant(lua::State* L) {
|
||||
auto& chunks = *level->chunks;
|
||||
auto& level = require_level();
|
||||
auto& chunks = *level.chunks;
|
||||
|
||||
auto x = lua::tointeger(L, 1);
|
||||
auto y = lua::tointeger(L, 2);
|
||||
auto z = lua::tointeger(L, 3);
|
||||
|
|
@ -327,7 +352,7 @@ static int l_set_variant(lua::State* L) {
|
|||
int lx = x - cx * CHUNK_W;
|
||||
int lz = z - cz * CHUNK_D;
|
||||
auto vox = &chunk->voxels[vox_index(lx, y, lz)];
|
||||
const auto& def = content->getIndices()->blocks.require(vox->id);
|
||||
const auto& def = level.content.getIndices()->blocks.require(vox->id);
|
||||
|
||||
if (def.variants == nullptr) {
|
||||
return 0;
|
||||
|
|
@ -358,11 +383,12 @@ static int l_set_variant(lua::State* L) {
|
|||
}
|
||||
|
||||
static int l_is_replaceable_at(lua::State* L) {
|
||||
auto& level = require_level();
|
||||
auto x = lua::tointeger(L, 1);
|
||||
auto y = lua::tointeger(L, 2);
|
||||
auto z = lua::tointeger(L, 3);
|
||||
return lua::pushboolean(
|
||||
L, blocks_agent::is_replaceable_at(*level->chunks, x, y, z)
|
||||
L, blocks_agent::is_replaceable_at(*level.chunks, x, y, z)
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -373,20 +399,28 @@ static int l_caption(lua::State* L) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
static lua::Integer get_variant_index(lua::State* L, const Block* const block, int argumentIndex) {
|
||||
const auto variantIndex = lua::gettop(L) >= argumentIndex ? lua::tointeger(L, argumentIndex) : 0;
|
||||
const size_t variantsSize = block->variants->variants.size();
|
||||
static lua::Integer get_variant_index(
|
||||
lua::State* L, const Block& block, int argumentIndex
|
||||
) {
|
||||
const auto variantIndex =
|
||||
lua::isnumber(L, argumentIndex) ? lua::tointeger(L, argumentIndex) : 0;
|
||||
const size_t variantsSize = block.variants->variants.size();
|
||||
if (variantIndex < 0 || variantIndex >= variantsSize) {
|
||||
throw std::out_of_range(
|
||||
"variant index out of bounds [0, " + std::to_string(variantsSize - 1) + "]");
|
||||
"variant index out of bounds [0, " +
|
||||
std::to_string(variantsSize - 1) + "]"
|
||||
);
|
||||
}
|
||||
return variantIndex;
|
||||
}
|
||||
|
||||
static int l_get_textures(lua::State* L) {
|
||||
if (auto def = get_block_def(L)) {
|
||||
const auto& textureFaces = (def->variants ? def->variants->variants[get_variant_index(L, def, 2)].textureFaces :
|
||||
def->defaults.textureFaces);
|
||||
const auto& textureFaces =
|
||||
(def->variants
|
||||
? def->variants->variants[get_variant_index(L, *def, 2)]
|
||||
.textureFaces
|
||||
: def->defaults.textureFaces);
|
||||
lua::createtable(L, 6, 0);
|
||||
for (size_t i = 0; i < 6; i++) {
|
||||
lua::pushstring(L, textureFaces[i]);
|
||||
|
|
@ -397,11 +431,13 @@ static int l_get_textures(lua::State* L) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int l_model_name(lua::State* L) {
|
||||
if (auto def = get_block_def(L)) {
|
||||
const auto& modelName = (def->variants ? def->variants->variants[get_variant_index(L, def, 2)].model.name :
|
||||
def->defaults.model.name);
|
||||
const auto& modelName =
|
||||
(def->variants
|
||||
? def->variants->variants[get_variant_index(L, *def, 2)]
|
||||
.model.name
|
||||
: def->defaults.model.name);
|
||||
if (modelName.empty()) {
|
||||
return lua::pushlstring(L, def->name + ".model");
|
||||
}
|
||||
|
|
@ -412,8 +448,11 @@ static int l_model_name(lua::State* L) {
|
|||
|
||||
static int l_get_model(lua::State* L) {
|
||||
if (auto def = get_block_def(L)) {
|
||||
const BlockModelType modelType = (def->variants ? def->variants->variants[get_variant_index(L, def, 2)].model.type :
|
||||
def->defaults.model.type);
|
||||
const BlockModelType modelType =
|
||||
(def->variants
|
||||
? def->variants->variants[get_variant_index(L, *def, 2)]
|
||||
.model.type
|
||||
: def->defaults.model.type);
|
||||
return lua::pushlstring(L, BlockModelTypeMeta.getName(modelType));
|
||||
}
|
||||
return 0;
|
||||
|
|
@ -422,7 +461,8 @@ static int l_get_model(lua::State* L) {
|
|||
static int l_get_hitbox(lua::State* L) {
|
||||
if (auto def = get_block_def(L)) {
|
||||
size_t rotation = lua::tointeger(L, 2);
|
||||
const size_t hitboxIndex = static_cast<size_t>(lua::gettop(L) >= 3 ? lua::tointeger(L, 3) : 0);
|
||||
const size_t hitboxIndex =
|
||||
static_cast<size_t>(lua::isnumber(L, 3) ? lua::tointeger(L, 3) : 0);
|
||||
if (def->rotatable) {
|
||||
rotation %= def->rotations.MAX_COUNT;
|
||||
} else {
|
||||
|
|
@ -456,25 +496,28 @@ static int l_get_picking_item(lua::State* L) {
|
|||
}
|
||||
|
||||
static int l_place(lua::State* L) {
|
||||
auto& level = require_level();
|
||||
auto& indices = *level.content.getIndices();
|
||||
|
||||
auto x = lua::tointeger(L, 1);
|
||||
auto y = lua::tointeger(L, 2);
|
||||
auto z = lua::tointeger(L, 3);
|
||||
auto id = lua::tointeger(L, 4);
|
||||
auto state = lua::tointeger(L, 5);
|
||||
auto playerid = lua::gettop(L) >= 6 ? lua::tointeger(L, 6) : -1;
|
||||
if (static_cast<size_t>(id) >= indices->blocks.count()) {
|
||||
if (static_cast<size_t>(id) >= indices.blocks.count()) {
|
||||
return 0;
|
||||
}
|
||||
if (!blocks_agent::get(*level->chunks, x, y, z)) {
|
||||
if (!blocks_agent::get(*level.chunks, x, y, z)) {
|
||||
return 0;
|
||||
}
|
||||
const auto def = level->content.getIndices()->blocks.get(id);
|
||||
const auto def = indices.blocks.get(id);
|
||||
if (def == nullptr) {
|
||||
throw std::runtime_error(
|
||||
"there is no block with index " + std::to_string(id)
|
||||
);
|
||||
}
|
||||
auto player = level->players->get(playerid);
|
||||
auto player = level.players->get(playerid);
|
||||
controller->getBlocksController()->placeBlock(
|
||||
player, *def, int2blockstate(state), x, y, z
|
||||
);
|
||||
|
|
@ -482,21 +525,26 @@ static int l_place(lua::State* L) {
|
|||
}
|
||||
|
||||
static int l_destruct(lua::State* L) {
|
||||
auto& level = require_level();
|
||||
|
||||
auto x = lua::tointeger(L, 1);
|
||||
auto y = lua::tointeger(L, 2);
|
||||
auto z = lua::tointeger(L, 3);
|
||||
auto playerid = lua::gettop(L) >= 4 ? lua::tointeger(L, 4) : -1;
|
||||
auto vox = blocks_agent::get(*level->chunks, x, y, z);
|
||||
auto playerid = lua::isnumber(L, 4) ? lua::tointeger(L, 4) : -1;
|
||||
|
||||
auto vox = blocks_agent::get(*level.chunks, x, y, z);
|
||||
if (vox == nullptr) {
|
||||
return 0;
|
||||
}
|
||||
auto& def = level->content.getIndices()->blocks.require(vox->id);
|
||||
auto player = level->players->get(playerid);
|
||||
auto& def = level.content.getIndices()->blocks.require(vox->id);
|
||||
auto player = level.players->get(playerid);
|
||||
controller->getBlocksController()->breakBlock(player, def, x, y, z);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int l_raycast(lua::State* L) {
|
||||
auto& level = require_level();
|
||||
|
||||
auto start = lua::tovec<3>(L, 1);
|
||||
auto dir = lua::tovec<3>(L, 2);
|
||||
auto maxDistance = lua::tonumber(L, 3);
|
||||
|
|
@ -526,7 +574,7 @@ static int l_raycast(lua::State* L) {
|
|||
glm::ivec3 normal;
|
||||
glm::ivec3 iend;
|
||||
if (auto voxel = blocks_agent::raycast(
|
||||
*level->chunks,
|
||||
*level.chunks,
|
||||
start,
|
||||
dir,
|
||||
maxDistance,
|
||||
|
|
@ -620,6 +668,8 @@ static int get_field(
|
|||
}
|
||||
|
||||
static int l_get_field(lua::State* L) {
|
||||
auto& level = require_level();
|
||||
|
||||
auto x = lua::tointeger(L, 1);
|
||||
auto y = lua::tointeger(L, 2);
|
||||
auto z = lua::tointeger(L, 3);
|
||||
|
|
@ -628,9 +678,10 @@ static int l_get_field(lua::State* L) {
|
|||
if (lua::gettop(L) >= 5) {
|
||||
index = lua::tointeger(L, 5);
|
||||
}
|
||||
|
||||
auto cx = floordiv(x, CHUNK_W);
|
||||
auto cz = floordiv(z, CHUNK_D);
|
||||
auto chunk = blocks_agent::get_chunk(*level->chunks, cx, cz);
|
||||
auto chunk = blocks_agent::get_chunk(*level.chunks, cx, cz);
|
||||
if (chunk == nullptr || y < 0 || y >= CHUNK_H) {
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -689,6 +740,8 @@ static int set_field(
|
|||
}
|
||||
|
||||
static int l_set_field(lua::State* L) {
|
||||
auto& level = require_level();
|
||||
|
||||
auto x = lua::tointeger(L, 1);
|
||||
auto y = lua::tointeger(L, 2);
|
||||
auto z = lua::tointeger(L, 3);
|
||||
|
|
@ -698,11 +751,12 @@ static int l_set_field(lua::State* L) {
|
|||
if (lua::gettop(L) >= 6) {
|
||||
index = lua::tointeger(L, 6);
|
||||
}
|
||||
|
||||
auto cx = floordiv(x, CHUNK_W);
|
||||
auto cz = floordiv(z, CHUNK_D);
|
||||
auto lx = x - cx * CHUNK_W;
|
||||
auto lz = z - cz * CHUNK_W;
|
||||
auto chunk = blocks_agent::get_chunk(*level->chunks, cx, cz);
|
||||
auto chunk = blocks_agent::get_chunk(*level.chunks, cx, cz);
|
||||
if (chunk == nullptr || y < 0 || y >= CHUNK_H) {
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,28 +7,42 @@
|
|||
|
||||
using namespace scripting;
|
||||
|
||||
static Level& require_level() {
|
||||
if (level == nullptr) {
|
||||
throw std::runtime_error("level is not initialized");
|
||||
}
|
||||
return *level;
|
||||
}
|
||||
|
||||
static const Content& require_content() {
|
||||
if (content == nullptr) {
|
||||
throw std::runtime_error("content is not initialized");
|
||||
}
|
||||
return *content;
|
||||
}
|
||||
|
||||
template <int (*getterfunc)(lua::State*, const Camera&)>
|
||||
static int l_camera_getter(lua::State* L) {
|
||||
size_t index = static_cast<size_t>(lua::tointeger(L, 1));
|
||||
return getterfunc(L, *level->cameras.at(index));
|
||||
return getterfunc(L, *require_level().cameras.at(index));
|
||||
}
|
||||
|
||||
template <void (*setterfunc)(lua::State*, Camera&, int)>
|
||||
static int l_camera_setter(lua::State* L) {
|
||||
size_t index = static_cast<size_t>(lua::tointeger(L, 1));
|
||||
setterfunc(L, *level->cameras.at(index), 2);
|
||||
setterfunc(L, *require_level().cameras.at(index), 2);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int l_index(lua::State* L) {
|
||||
auto name = lua::require_string(L, 1);
|
||||
auto& indices = content->getIndices(ResourceType::CAMERA);
|
||||
auto& indices = require_content().getIndices(ResourceType::CAMERA);
|
||||
return lua::pushinteger(L, indices.indexOf(name));
|
||||
}
|
||||
|
||||
static int l_name(lua::State* L) {
|
||||
size_t index = static_cast<size_t>(lua::tointeger(L, 1));
|
||||
auto& indices = content->getIndices(ResourceType::CAMERA);
|
||||
auto& indices = require_content().getIndices(ResourceType::CAMERA);
|
||||
return lua::pushstring(L, indices.getName(index));
|
||||
}
|
||||
|
||||
|
|
@ -89,7 +103,7 @@ static int getter_up(lua::State* L, const Camera& camera) {
|
|||
|
||||
static int l_look_at(lua::State* L) {
|
||||
size_t index = static_cast<size_t>(lua::tointeger(L, 1));
|
||||
auto& camera = *level->cameras.at(index);
|
||||
auto& camera = *require_level().cameras.at(index);
|
||||
auto center = lua::tovec<3>(L, 2);
|
||||
auto matrix = glm::inverse(
|
||||
glm::lookAt(glm::vec3(), center - camera.position, glm::vec3(0, 1, 0))
|
||||
|
|
|
|||
|
|
@ -347,6 +347,41 @@ static int l_write_descriptor(lua::State* L) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int l_seek_descriptor(lua::State* L) {
|
||||
int descriptor = lua::tointeger(L, 1);
|
||||
|
||||
if (!scripting::descriptors_manager::has_descriptor(descriptor)) {
|
||||
throw std::runtime_error("unknown descriptor");
|
||||
}
|
||||
|
||||
std::string mode = lua::require_string(L, 2);
|
||||
std::ios_base::seekdir dir;
|
||||
|
||||
switch (mode[0]) {
|
||||
case 'b':
|
||||
dir = std::ios_base::beg;
|
||||
break;
|
||||
case 'c':
|
||||
dir = std::ios_base::cur;
|
||||
break;
|
||||
case 'e':
|
||||
dir = std::ios_base::end;
|
||||
break;
|
||||
default:
|
||||
throw std::runtime_error("invalid seek mode");
|
||||
}
|
||||
|
||||
auto* stream = scripting::descriptors_manager::get_output(descriptor);
|
||||
|
||||
stream->seekp(lua::tointeger(L, 3), dir);
|
||||
|
||||
if (!stream->good()) {
|
||||
throw std::runtime_error("failed to seek stream");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int l_flush_descriptor(lua::State* L) {
|
||||
int descriptor = lua::tointeger(L, 1);
|
||||
|
||||
|
|
@ -406,9 +441,9 @@ const luaL_Reg filelib[] = {
|
|||
{"__has_descriptor", lua::wrap<l_has_descriptor>},
|
||||
{"__read_descriptor", lua::wrap<l_read_descriptor>},
|
||||
{"__write_descriptor", lua::wrap<l_write_descriptor>},
|
||||
{"__seek_descriptor", lua::wrap<l_seek_descriptor>},
|
||||
{"__flush_descriptor", lua::wrap<l_flush_descriptor>},
|
||||
{"__close_descriptor", lua::wrap<l_close_descriptor>},
|
||||
{"__close_all_descriptors", lua::wrap<l_close_all_descriptors>},
|
||||
{nullptr, nullptr}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -8,14 +8,28 @@
|
|||
using namespace scripting;
|
||||
|
||||
namespace {
|
||||
Level& require_level() {
|
||||
if (level == nullptr) {
|
||||
throw std::runtime_error("world is not open");
|
||||
}
|
||||
return *level;
|
||||
}
|
||||
|
||||
const Content& require_content() {
|
||||
if (content == nullptr) {
|
||||
throw std::runtime_error("content is not initialized");
|
||||
}
|
||||
return *content;
|
||||
}
|
||||
|
||||
void validate_itemid(itemid_t id) {
|
||||
if (id >= indices->items.count()) {
|
||||
if (id >= require_content().getIndices()->items.count()) {
|
||||
throw std::runtime_error("invalid item id");
|
||||
}
|
||||
}
|
||||
|
||||
Inventory& get_inventory(int64_t id) {
|
||||
auto inv = level->inventories->get(id);
|
||||
auto inv = require_level().inventories->get(id);
|
||||
if (inv == nullptr) {
|
||||
throw std::runtime_error("inventory not found: " + std::to_string(id));
|
||||
}
|
||||
|
|
@ -23,7 +37,7 @@ namespace {
|
|||
}
|
||||
|
||||
Inventory& get_inventory(int64_t id, int arg) {
|
||||
auto inv = level->inventories->get(id);
|
||||
auto inv = require_level().inventories->get(id);
|
||||
if (inv == nullptr) {
|
||||
throw std::runtime_error(
|
||||
"inventory not found: " + std::to_string(id) + " argument " +
|
||||
|
|
@ -137,7 +151,7 @@ static int l_unbind_block(lua::State* L) {
|
|||
|
||||
static int l_create(lua::State* L) {
|
||||
auto invsize = lua::tointeger(L, 1);
|
||||
auto inv = level->inventories->create(invsize);
|
||||
auto inv = require_level().inventories->create(invsize);
|
||||
if (inv == nullptr) {
|
||||
return lua::pushinteger(L, 0);
|
||||
}
|
||||
|
|
@ -146,13 +160,13 @@ static int l_create(lua::State* L) {
|
|||
|
||||
static int l_remove(lua::State* L) {
|
||||
auto invid = lua::tointeger(L, 1);
|
||||
level->inventories->remove(invid);
|
||||
require_level().inventories->remove(invid);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int l_clone(lua::State* L) {
|
||||
auto id = lua::tointeger(L, 1);
|
||||
auto clone = level->inventories->clone(id);
|
||||
auto clone = require_level().inventories->clone(id);
|
||||
if (clone == nullptr) {
|
||||
return lua::pushinteger(L, 0);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,6 +8,9 @@
|
|||
using namespace scripting;
|
||||
|
||||
static const ItemDef* get_item_def(lua::State* L, int idx) {
|
||||
if (content == nullptr) {
|
||||
throw std::runtime_error("content is not initialized");
|
||||
}
|
||||
auto indices = content->getIndices();
|
||||
auto id = lua::tointeger(L, idx);
|
||||
return indices->items.get(id);
|
||||
|
|
|
|||
|
|
@ -229,6 +229,20 @@ static int l_look_at(lua::State* L) {
|
|||
}
|
||||
}
|
||||
|
||||
static int l_perspective(lua::State *L) {
|
||||
uint argc = lua::check_argc(L, 4, 5);
|
||||
|
||||
double fov = glm::radians(lua::tonumber(L, 1));
|
||||
double ratio = lua::tonumber(L, 2);
|
||||
double near = lua::tonumber(L, 3);
|
||||
double far = lua::tonumber(L, 4);
|
||||
|
||||
glm::mat4 mat = glm::perspective(fov, ratio, near, far);
|
||||
|
||||
if (argc == 5) return lua::setmat4(L, 5, mat);
|
||||
else return lua::pushmat4(L, mat);
|
||||
}
|
||||
|
||||
static int l_from_quat(lua::State* L) {
|
||||
uint argc = lua::check_argc(L, 1, 2);
|
||||
auto quat = lua::toquat(L, 1);
|
||||
|
|
@ -280,6 +294,7 @@ const luaL_Reg mat4lib[] = {
|
|||
{"determinant", lua::wrap<l_determinant>},
|
||||
{"decompose", lua::wrap<l_decompose>},
|
||||
{"look_at", lua::wrap<l_look_at>},
|
||||
{"perspective", lua::wrap<l_perspective>},
|
||||
{"from_quat", lua::wrap<l_from_quat>},
|
||||
{"tostring", lua::wrap<l_tostring>},
|
||||
{nullptr, nullptr}
|
||||
|
|
|
|||
|
|
@ -14,6 +14,13 @@
|
|||
|
||||
using namespace scripting;
|
||||
|
||||
static Level& require_level() {
|
||||
if (level == nullptr) {
|
||||
throw std::runtime_error("world is not loaded");
|
||||
}
|
||||
return *level;
|
||||
}
|
||||
|
||||
inline Player* get_player(lua::State* L, int idx) {
|
||||
if (!lua::isnumber(L, idx)) {
|
||||
if (engine->isHeadless()) {
|
||||
|
|
@ -22,7 +29,7 @@ inline Player* get_player(lua::State* L, int idx) {
|
|||
);
|
||||
}
|
||||
}
|
||||
return level->players->get(lua::tointeger(L, idx));
|
||||
return require_level().players->get(lua::tointeger(L, idx));
|
||||
}
|
||||
|
||||
static int l_get_pos(lua::State* L) {
|
||||
|
|
@ -304,15 +311,18 @@ static int l_create(lua::State* L) {
|
|||
if (lua::gettop(L) >= 2) {
|
||||
playerId = lua::tointeger(L, 2);
|
||||
}
|
||||
auto player = level->players->create(playerId);
|
||||
auto& level = require_level();
|
||||
auto player = level.players->create(playerId);
|
||||
player->setName(lua::require_string(L, 1));
|
||||
return lua::pushinteger(L, player->getId());
|
||||
}
|
||||
|
||||
static int l_delete(lua::State* L) {
|
||||
auto id = lua::tointeger(L, 1);
|
||||
level->players->suspend(id);
|
||||
level->players->remove(id);
|
||||
|
||||
auto& level = require_level();
|
||||
level.players->suspend(id);
|
||||
level.players->remove(id);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -324,19 +334,21 @@ static int l_is_suspended(lua::State* L) {
|
|||
}
|
||||
|
||||
static int l_set_suspended(lua::State* L) {
|
||||
auto& level = require_level();
|
||||
if (lua::toboolean(L, 2)) {
|
||||
level->players->suspend(lua::tointeger(L, 1));
|
||||
level.players->suspend(lua::tointeger(L, 1));
|
||||
} else {
|
||||
level->players->resume(lua::tointeger(L, 1));
|
||||
level.players->resume(lua::tointeger(L, 1));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int l_get_all_in_radius(lua::State* L) {
|
||||
auto& level = require_level();
|
||||
auto center = lua::tovec3(L, 1);
|
||||
auto radius = static_cast<float>(lua::tonumber(L, 2));
|
||||
|
||||
auto players = level->players->getAllInRadius(center, radius);
|
||||
auto players = level.players->getAllInRadius(center, radius);
|
||||
lua::createtable(L, players.size(), 0);
|
||||
for (size_t i = 0; i < players.size(); i++) {
|
||||
lua::pushinteger(L, players[i]->getId());
|
||||
|
|
@ -346,7 +358,7 @@ static int l_get_all_in_radius(lua::State* L) {
|
|||
}
|
||||
|
||||
static int l_get_all(lua::State* L) {
|
||||
auto players = level->players->getAll();
|
||||
auto players = require_level().players->getAll();
|
||||
lua::createtable(L, players.size(), 0);
|
||||
for (size_t i = 0; i < players.size(); i++) {
|
||||
lua::pushinteger(L, players[i]->getId());
|
||||
|
|
@ -356,8 +368,9 @@ static int l_get_all(lua::State* L) {
|
|||
}
|
||||
|
||||
static int l_get_nearest(lua::State* L) {
|
||||
auto& level = require_level();
|
||||
auto position = lua::tovec3(L, 1);
|
||||
if (auto player = level->players->getNearest(position)) {
|
||||
if (auto player = level.players->getNearest(position)) {
|
||||
lua::pushinteger(L, player->getId());
|
||||
return 1;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -44,8 +44,17 @@ static int l_tostring(lua::State* L) {
|
|||
return lua::pushstring(L, ss.str());
|
||||
}
|
||||
|
||||
static int l_from_euler(lua::State *L) {
|
||||
uint argc = lua::check_argc(L, 1, 2);
|
||||
glm::vec3 euler = glm::radians(lua::tovec3(L, 1));
|
||||
|
||||
if (argc == 2) return lua::setquat(L, 2, glm::quat(euler));
|
||||
return lua::pushquat(L, glm::quat(euler));
|
||||
}
|
||||
|
||||
const luaL_Reg quatlib[] = {
|
||||
{"from_mat4", lua::wrap<l_from_mat4>},
|
||||
{"from_euler", lua::wrap<l_from_euler>},
|
||||
{"slerp", lua::wrap<l_slerp>},
|
||||
{"tostring", lua::wrap<l_tostring>},
|
||||
{nullptr, nullptr}
|
||||
|
|
|
|||
|
|
@ -25,11 +25,15 @@
|
|||
using namespace scripting;
|
||||
namespace fs = std::filesystem;
|
||||
|
||||
static WorldInfo& require_world_info() {
|
||||
static Level& require_level() {
|
||||
if (level == nullptr) {
|
||||
throw std::runtime_error("no world open");
|
||||
throw std::runtime_error("world is not open");
|
||||
}
|
||||
return level->getWorld()->getInfo();
|
||||
return *level;
|
||||
}
|
||||
|
||||
static WorldInfo& require_world_info() {
|
||||
return require_level().getWorld()->getInfo();
|
||||
}
|
||||
|
||||
static int l_is_open(lua::State* L) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue