1
0
mirror of https://github.com/minetest/minetest.git synced 2025-07-02 08:00:22 +02:00

Add paramtype2s for 4 horizontal rotations and 64 colors (#11431)

4dir is like facedir, but only for 4 horizontal directions: NESW. It is identical in behavior to facedir otherwise. The reason why game makers would want to use this over facedir is 1) simplicity and 2) you get 6 free bits.
It can be used for things like chests and furnaces and you don't need or want them to "flip them on the side" (like you could with facedir).

color4dir is like colorfacedir, but you get 64 colors instead of only 8.
This commit is contained in:
Wuzzy
2022-09-16 13:18:55 +02:00
committed by GitHub
parent b5e7280708
commit 1d04903c19
15 changed files with 299 additions and 28 deletions

View File

@ -1510,7 +1510,9 @@ void MapblockMeshGenerator::drawMeshNode()
int degrotate = 0;
if (f->param_type_2 == CPT2_FACEDIR ||
f->param_type_2 == CPT2_COLORED_FACEDIR) {
f->param_type_2 == CPT2_COLORED_FACEDIR ||
f->param_type_2 == CPT2_4DIR ||
f->param_type_2 == CPT2_COLORED_4DIR) {
facedir = n.getFaceDir(nodedef);
} else if (f->param_type_2 == CPT2_WALLMOUNTED ||
f->param_type_2 == CPT2_COLORED_WALLMOUNTED) {

View File

@ -3462,7 +3462,9 @@ bool Game::nodePlacement(const ItemDefinition &selected_def,
param2 = dir.Z < 0 ? 5 : 4;
}
} else if (predicted_f.param_type_2 == CPT2_FACEDIR ||
predicted_f.param_type_2 == CPT2_COLORED_FACEDIR) {
predicted_f.param_type_2 == CPT2_COLORED_FACEDIR ||
predicted_f.param_type_2 == CPT2_4DIR ||
predicted_f.param_type_2 == CPT2_COLORED_4DIR) {
v3s16 dir = nodepos - floatToInt(client->getEnv().getLocalPlayer()->getPosition(), BS);
if (abs(dir.X) > abs(dir.Z)) {
@ -3501,6 +3503,7 @@ bool Game::nodePlacement(const ItemDefinition &selected_def,
// Apply color
if (!place_param2 && (predicted_f.param_type_2 == CPT2_COLOR
|| predicted_f.param_type_2 == CPT2_COLORED_FACEDIR
|| predicted_f.param_type_2 == CPT2_COLORED_4DIR
|| predicted_f.param_type_2 == CPT2_COLORED_WALLMOUNTED)) {
const auto &indexstr = selected_item.metadata.
getString("palette_index", 0);
@ -3514,6 +3517,9 @@ bool Game::nodePlacement(const ItemDefinition &selected_def,
} else if (predicted_f.param_type_2 == CPT2_COLORED_FACEDIR) {
// param2 = pure palette index + other
param2 = (index & 0xe0) | (param2 & 0x1f);
} else if (predicted_f.param_type_2 == CPT2_COLORED_4DIR) {
// param2 = pure palette index + other
param2 = (index & 0xfc) | (param2 & 0x03);
}
}
}

View File

@ -149,6 +149,9 @@ u8 MapNode::getFaceDir(const NodeDefManager *nodemgr,
if (f.param_type_2 == CPT2_FACEDIR ||
f.param_type_2 == CPT2_COLORED_FACEDIR)
return (getParam2() & 0x1F) % 24;
if (f.param_type_2 == CPT2_4DIR ||
f.param_type_2 == CPT2_COLORED_4DIR)
return getParam2() & 0x03;
if (allow_wallmounted && (f.param_type_2 == CPT2_WALLMOUNTED ||
f.param_type_2 == CPT2_COLORED_WALLMOUNTED))
return wallmounted_to_facedir[getParam2() & 0x07];
@ -196,7 +199,8 @@ void MapNode::rotateAlongYAxis(const NodeDefManager *nodemgr, Rotation rot)
{
ContentParamType2 cpt2 = nodemgr->get(*this).param_type_2;
if (cpt2 == CPT2_FACEDIR || cpt2 == CPT2_COLORED_FACEDIR) {
if (cpt2 == CPT2_FACEDIR || cpt2 == CPT2_COLORED_FACEDIR ||
cpt2 == CPT2_4DIR || cpt2 == CPT2_COLORED_4DIR) {
static const u8 rotate_facedir[24 * 4] = {
// Table value = rotated facedir
// Columns: 0, 90, 180, 270 degrees rotation around vertical axis
@ -232,10 +236,17 @@ void MapNode::rotateAlongYAxis(const NodeDefManager *nodemgr, Rotation rot)
22, 21, 20, 23,
23, 22, 21, 20
};
u8 facedir = (param2 & 31) % 24;
u8 index = facedir * 4 + rot;
param2 &= ~31;
param2 |= rotate_facedir[index];
if (cpt2 == CPT2_FACEDIR || cpt2 == CPT2_COLORED_FACEDIR) {
u8 facedir = (param2 & 31) % 24;
u8 index = facedir * 4 + rot;
param2 &= ~31;
param2 |= rotate_facedir[index];
} else if (cpt2 == CPT2_4DIR || cpt2 == CPT2_COLORED_4DIR) {
u8 fourdir = param2 & 3;
u8 index = fourdir + rot;
param2 &= ~3;
param2 |= rotate_facedir[index];
}
} else if (cpt2 == CPT2_WALLMOUNTED ||
cpt2 == CPT2_COLORED_WALLMOUNTED) {
u8 wmountface = (param2 & 7);

View File

@ -992,6 +992,7 @@ void ContentFeatures::updateTextures(ITextureSource *tsrc, IShaderSource *shdsrc
if (param_type_2 == CPT2_COLOR ||
param_type_2 == CPT2_COLORED_FACEDIR ||
param_type_2 == CPT2_COLORED_4DIR ||
param_type_2 == CPT2_COLORED_WALLMOUNTED ||
param_type_2 == CPT2_COLORED_DEGROTATE)
palette = tsrc->getPalette(palette_name);
@ -1018,6 +1019,15 @@ void ContentFeatures::updateTextures(ITextureSource *tsrc, IShaderSource *shdsrc
recalculateBoundingBox(mesh_ptr[j]);
meshmanip->recalculateNormals(mesh_ptr[j], true, false);
}
} else if (tsettings.enable_mesh_cache && mesh_ptr[0] &&
(param_type_2 == CPT2_4DIR
|| param_type_2 == CPT2_COLORED_4DIR)) {
for (u16 j = 1; j < 4; j++) {
mesh_ptr[j] = cloneMesh(mesh_ptr[0]);
rotateMeshBy6dFacedir(mesh_ptr[j], j);
recalculateBoundingBox(mesh_ptr[j]);
meshmanip->recalculateNormals(mesh_ptr[j], true, false);
}
} else if (tsettings.enable_mesh_cache && mesh_ptr[0]
&& (param_type_2 == CPT2_WALLMOUNTED ||
param_type_2 == CPT2_COLORED_WALLMOUNTED)) {
@ -1241,7 +1251,9 @@ void getNodeBoxUnion(const NodeBox &nodebox, const ContentFeatures &features,
half_processed.MaxEdge.Y = +BS / 2;
}
if (features.param_type_2 == CPT2_FACEDIR ||
features.param_type_2 == CPT2_COLORED_FACEDIR) {
features.param_type_2 == CPT2_COLORED_FACEDIR ||
features.param_type_2 == CPT2_4DIR ||
features.param_type_2 == CPT2_COLORED_4DIR) {
// Get maximal coordinate
f32 coords[] = {
fabsf(half_processed.MinEdge.X),
@ -1705,7 +1717,9 @@ bool NodeDefManager::nodeboxConnects(MapNode from, MapNode to,
// does to node declare usable faces?
if (f2.connect_sides > 0) {
if ((f2.param_type_2 == CPT2_FACEDIR ||
f2.param_type_2 == CPT2_COLORED_FACEDIR)
f2.param_type_2 == CPT2_COLORED_FACEDIR ||
f2.param_type_2 == CPT2_4DIR ||
f2.param_type_2 == CPT2_COLORED_4DIR)
&& (connect_face >= 4)) {
static const u8 rot[33 * 4] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 4, 32, 16, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
@ -1719,8 +1733,15 @@ bool NodeDefManager::nodeboxConnects(MapNode from, MapNode to,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 32, 16, 8, 4 // 32 - left
};
return (f2.connect_sides
& rot[(connect_face * 4) + (to.param2 & 0x1F)]);
if (f2.param_type_2 == CPT2_FACEDIR ||
f2.param_type_2 == CPT2_COLORED_FACEDIR) {
return (f2.connect_sides
& rot[(connect_face * 4) + (to.param2 & 0x1F)]);
} else if (f2.param_type_2 == CPT2_4DIR ||
f2.param_type_2 == CPT2_COLORED_4DIR) {
return (f2.connect_sides
& rot[(connect_face * 4) + (to.param2 & 0x03)]);
}
}
return (f2.connect_sides & connect_face);
}

View File

@ -58,7 +58,7 @@ enum ContentParamType2
CPT2_FULL,
// Flowing liquid properties
CPT2_FLOWINGLIQUID,
// Direction for chests and furnaces and such
// Direction for chests and furnaces and such (with axis rotation)
CPT2_FACEDIR,
// Direction for signs, torches and such
CPT2_WALLMOUNTED,
@ -78,6 +78,10 @@ enum ContentParamType2
CPT2_GLASSLIKE_LIQUID_LEVEL,
// 3 bits of palette index, then degrotate
CPT2_COLORED_DEGROTATE,
// Simplified direction for chests and furnaces and such (4 directions)
CPT2_4DIR,
// 6 bits of palette index, then 4dir
CPT2_COLORED_4DIR,
};
enum LiquidType

View File

@ -673,7 +673,8 @@ void read_content_features(lua_State *L, ContentFeatures &f, int index)
!(f.param_type_2 == CPT2_COLOR ||
f.param_type_2 == CPT2_COLORED_FACEDIR ||
f.param_type_2 == CPT2_COLORED_WALLMOUNTED ||
f.param_type_2 == CPT2_COLORED_DEGROTATE))
f.param_type_2 == CPT2_COLORED_DEGROTATE ||
f.param_type_2 == CPT2_COLORED_4DIR))
warningstream << "Node " << f.name.c_str()
<< " has a palette, but not a suitable paramtype2." << std::endl;

View File

@ -66,6 +66,8 @@ struct EnumString ScriptApiNode::es_ContentParamType2[] =
{CPT2_COLORED_WALLMOUNTED, "colorwallmounted"},
{CPT2_GLASSLIKE_LIQUID_LEVEL, "glasslikeliquidlevel"},
{CPT2_COLORED_DEGROTATE, "colordegrotate"},
{CPT2_4DIR, "4dir"},
{CPT2_COLORED_4DIR, "color4dir"},
{0, NULL},
};