1
0
Fork 0
mirror of https://github.com/luanti-org/luanti.git synced 2025-06-27 16:36:03 +00:00

Tool specific pointing and blocking pointable type (#13992)

This commit is contained in:
cx384 2024-01-22 18:27:08 +01:00 committed by GitHub
parent fb461d21a5
commit 5958714309
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
39 changed files with 676 additions and 67 deletions

View file

@ -83,6 +83,12 @@ void read_item_definition(lua_State* L, int index,
getboolfield(L, index, "liquids_pointable", def.liquids_pointable);
lua_getfield(L, index, "pointabilities");
if(lua_istable(L, -1)){
def.pointabilities = std::make_optional<Pointabilities>(
read_pointabilities(L, -1));
}
lua_getfield(L, index, "tool_capabilities");
if(lua_istable(L, -1)){
def.tool_capabilities = new ToolCapabilities(
@ -199,6 +205,10 @@ void push_item_definition_full(lua_State *L, const ItemDefinition &i)
lua_setfield(L, -2, "usable");
lua_pushboolean(L, i.liquids_pointable);
lua_setfield(L, -2, "liquids_pointable");
if (i.pointabilities) {
push_pointabilities(L, *i.pointabilities);
lua_setfield(L, -2, "pointabilities");
}
if (i.tool_capabilities) {
push_tool_capabilities(L, *i.tool_capabilities);
lua_setfield(L, -2, "tool_capabilities");
@ -311,7 +321,12 @@ void read_object_properties(lua_State *L, int index,
}
lua_pop(L, 1);
getboolfield(L, -1, "pointable", prop->pointable);
lua_getfield(L, -1, "pointable");
if(!lua_isnil(L, -1)){
prop->pointable = read_pointability_type(L, -1);
}
lua_pop(L, 1);
getstringfield(L, -1, "visual", prop->visual);
getstringfield(L, -1, "mesh", prop->mesh);
@ -452,7 +467,7 @@ void push_object_properties(lua_State *L, ObjectProperties *prop)
lua_pushboolean(L, prop->rotate_selectionbox);
lua_setfield(L, -2, "rotate");
lua_setfield(L, -2, "selectionbox");
lua_pushboolean(L, prop->pointable);
push_pointability_type(L, prop->pointable);
lua_setfield(L, -2, "pointable");
lua_pushlstring(L, prop->visual.c_str(), prop->visual.size());
lua_setfield(L, -2, "visual");
@ -781,8 +796,14 @@ void read_content_features(lua_State *L, ContentFeatures &f, int index)
// This is used for collision detection.
// Also for general solidness queries.
getboolfield(L, index, "walkable", f.walkable);
// Player can point to these
getboolfield(L, index, "pointable", f.pointable);
// Player can point to these, point through or it is blocking
lua_getfield(L, index, "pointable");
if(!lua_isnil(L, -1)){
f.pointable = read_pointability_type(L, -1);
}
lua_pop(L, 1);
// Player can dig these
getboolfield(L, index, "diggable", f.diggable);
// Player can climb these
@ -1005,7 +1026,7 @@ void push_content_features(lua_State *L, const ContentFeatures &c)
lua_setfield(L, -2, "is_ground_content");
lua_pushboolean(L, c.walkable);
lua_setfield(L, -2, "walkable");
lua_pushboolean(L, c.pointable);
push_pointability_type(L, c.pointable);
lua_setfield(L, -2, "pointable");
lua_pushboolean(L, c.diggable);
lua_setfield(L, -2, "diggable");
@ -1592,6 +1613,125 @@ ToolCapabilities read_tool_capabilities(
return toolcap;
}
/******************************************************************************/
PointabilityType read_pointability_type(lua_State *L, int index)
{
if (lua_isboolean(L, index)) {
if (lua_toboolean(L, index))
return PointabilityType::POINTABLE;
else
return PointabilityType::POINTABLE_NOT;
} else {
const char* s = luaL_checkstring(L, index);
if (s && !strcmp(s, "blocking")) {
return PointabilityType::POINTABLE_BLOCKING;
}
}
throw LuaError("Invalid pointable type.");
}
/******************************************************************************/
Pointabilities read_pointabilities(lua_State *L, int index)
{
Pointabilities pointabilities;
lua_getfield(L, index, "nodes");
if(lua_istable(L, -1)){
int ti = lua_gettop(L);
lua_pushnil(L);
while(lua_next(L, ti) != 0) {
// key at index -2 and value at index -1
std::string name = luaL_checkstring(L, -2);
// handle groups
if(std::string_view(name).substr(0,6)=="group:") {
pointabilities.node_groups[name.substr(6)] = read_pointability_type(L, -1);
} else {
pointabilities.nodes[name] = read_pointability_type(L, -1);
}
// removes value, keeps key for next iteration
lua_pop(L, 1);
}
}
lua_pop(L, 1);
lua_getfield(L, index, "objects");
if(lua_istable(L, -1)){
int ti = lua_gettop(L);
lua_pushnil(L);
while(lua_next(L, ti) != 0) {
// key at index -2 and value at index -1
std::string name = luaL_checkstring(L, -2);
// handle groups
if(std::string_view(name).substr(0,6)=="group:") {
pointabilities.object_groups[name.substr(6)] = read_pointability_type(L, -1);
} else {
pointabilities.objects[name] = read_pointability_type(L, -1);
}
// removes value, keeps key for next iteration
lua_pop(L, 1);
}
}
lua_pop(L, 1);
return pointabilities;
}
/******************************************************************************/
void push_pointability_type(lua_State *L, PointabilityType pointable)
{
switch(pointable)
{
case PointabilityType::POINTABLE:
lua_pushboolean(L, true);
break;
case PointabilityType::POINTABLE_NOT:
lua_pushboolean(L, false);
break;
case PointabilityType::POINTABLE_BLOCKING:
lua_pushliteral(L, "blocking");
break;
}
}
/******************************************************************************/
void push_pointabilities(lua_State *L, const Pointabilities &pointabilities)
{
// pointabilities table
lua_newtable(L);
if (!pointabilities.nodes.empty() || !pointabilities.node_groups.empty()) {
// Create and fill table
lua_newtable(L);
for (const auto &entry : pointabilities.nodes) {
push_pointability_type(L, entry.second);
lua_setfield(L, -2, entry.first.c_str());
}
for (const auto &entry : pointabilities.node_groups) {
push_pointability_type(L, entry.second);
lua_setfield(L, -2, ("group:" + entry.first).c_str());
}
lua_setfield(L, -2, "nodes");
}
if (!pointabilities.objects.empty() || !pointabilities.object_groups.empty()) {
// Create and fill table
lua_newtable(L);
for (const auto &entry : pointabilities.objects) {
push_pointability_type(L, entry.second);
lua_setfield(L, -2, entry.first.c_str());
}
for (const auto &entry : pointabilities.object_groups) {
push_pointability_type(L, entry.second);
lua_setfield(L, -2, ("group:" + entry.first).c_str());
}
lua_setfield(L, -2, "objects");
}
}
/******************************************************************************/
void push_dig_params(lua_State *L,const DigParams &params)
{