diff --git a/src/content_mapnode.cpp b/src/content_mapnode.cpp index a365f2ae9..0ba59fcbb 100644 --- a/src/content_mapnode.cpp +++ b/src/content_mapnode.cpp @@ -335,6 +335,7 @@ void content_mapnode_init() f->solidness = 0; // drawn separately, makes no faces f->air_equivalent = true; // grass grows underneath f->walkable = false; + f->selection_box.type = NODEBOX_FIXED; setDirtLikeDiggingProperties(f->digging_properties, 0.75); i = CONTENT_LADDER; @@ -350,6 +351,7 @@ void content_mapnode_init() f->air_equivalent = true; f->walkable = false; f->climbable = true; + f->selection_box.type = NODEBOX_WALLMOUNTED; setWoodLikeDiggingProperties(f->digging_properties, 0.5); // Deprecated @@ -606,6 +608,13 @@ void content_mapnode_init() f->air_equivalent = true; f->dug_item = std::string("MaterialItem2 ")+itos(i)+" 1"; f->light_source = LIGHT_MAX-1; + f->selection_box.type = NODEBOX_WALLMOUNTED; + f->selection_box.wall_top = core::aabbox3d( + -BS/10, BS/2-BS/3.333*2, -BS/10, BS/10, BS/2, BS/10); + f->selection_box.wall_bottom = core::aabbox3d( + -BS/10, -BS/2, -BS/10, BS/10, -BS/2+BS/3.333*2, BS/10); + f->selection_box.wall_side = core::aabbox3d( + -BS/2, -BS/3.333, -BS/10, -BS/2+BS/3.333, BS/3.333, BS/10); f->digging_properties.set("", DiggingProperties(true, 0.0, 0)); i = CONTENT_SIGN_WALL; @@ -623,6 +632,7 @@ void content_mapnode_init() if(f->initial_metadata == NULL) f->initial_metadata = new SignNodeMetadata("Some sign"); f->digging_properties.set("", DiggingProperties(true, 0.5, 0)); + f->selection_box.type = NODEBOX_WALLMOUNTED; i = CONTENT_CHEST; f = &content_features(i); diff --git a/src/game.cpp b/src/game.cpp index d7efbeae9..30bd1bcf7 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -43,7 +43,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "gettext.h" #include "log.h" #include "filesys.h" -// Needed for some special cases for CONTENT_TORCH and CONTENT_SIGN_WALL +// Needed for writing to signs (CONTENT_SIGN_WALL) // TODO: A generic way for handling such should be created #include "content_mapnode.h" // Needed for sign text input @@ -343,10 +343,29 @@ void getPointedNode(Client *client, v3f player_position, v3s16(-1,0,0), // left }; - /* - Meta-objects - */ - if(n.getContent() == CONTENT_TORCH) + ContentFeatures &f = content_features(n); + + if(f.selection_box.type == NODEBOX_FIXED) + { + f32 distance = (npf - camera_position).getLength(); + + core::aabbox3d box = f.selection_box.fixed; + box.MinEdge += npf; + box.MaxEdge += npf; + + if(distance < mindistance) + { + if(box.intersectsWithLine(shootline)) + { + nodefound = true; + nodepos = np; + neighbourpos = np; + mindistance = distance; + nodehilightbox = box; + } + } + } + else if(f.selection_box.type == NODEBOX_WALLMOUNTED) { v3s16 dir = unpackDir(n.param2); v3f dir_f = v3f(dir.X, dir.Y, dir.Z); @@ -356,31 +375,41 @@ void getPointedNode(Client *client, v3f player_position, core::aabbox3d box; - // bottom - if(dir == v3s16(0,-1,0)) - { - box = core::aabbox3d( - npf - v3f(BS/6, BS/2, BS/6), - npf + v3f(BS/6, -BS/2+BS/3*2, BS/6) - ); - } // top - else if(dir == v3s16(0,1,0)) - { - box = core::aabbox3d( - npf - v3f(BS/6, -BS/2+BS/3*2, BS/6), - npf + v3f(BS/6, BS/2, BS/6) - ); + if(dir == v3s16(0,1,0)){ + box = f.selection_box.wall_top; + } + // bottom + else if(dir == v3s16(0,-1,0)){ + box = f.selection_box.wall_bottom; } // side - else - { - box = core::aabbox3d( - cpf - v3f(BS/6, BS/3, BS/6), - cpf + v3f(BS/6, BS/3, BS/6) - ); + else{ + v3f vertices[2] = + { + f.selection_box.wall_side.MinEdge, + f.selection_box.wall_side.MaxEdge + }; + + for(s32 i=0; i<2; i++) + { + if(dir == v3s16(-1,0,0)) + vertices[i].rotateXZBy(0); + if(dir == v3s16(1,0,0)) + vertices[i].rotateXZBy(180); + if(dir == v3s16(0,0,-1)) + vertices[i].rotateXZBy(90); + if(dir == v3s16(0,0,1)) + vertices[i].rotateXZBy(-90); + } + + box = core::aabbox3d(vertices[0]); + box.addInternalPoint(vertices[1]); } + box.MinEdge += npf; + box.MaxEdge += npf; + if(distance < mindistance) { if(box.intersectsWithLine(shootline)) @@ -393,146 +422,7 @@ void getPointedNode(Client *client, v3f player_position, } } } - else if(n.getContent() == CONTENT_SIGN_WALL) - { - v3s16 dir = unpackDir(n.param2); - v3f dir_f = v3f(dir.X, dir.Y, dir.Z); - dir_f *= BS/2 - BS/6 - BS/20; - v3f cpf = npf + dir_f; - f32 distance = (cpf - camera_position).getLength(); - - v3f vertices[4] = - { - v3f(BS*0.42,-BS*0.35,-BS*0.4), - v3f(BS*0.49, BS*0.35, BS*0.4), - }; - - for(s32 i=0; i<2; i++) - { - if(dir == v3s16(1,0,0)) - vertices[i].rotateXZBy(0); - if(dir == v3s16(-1,0,0)) - vertices[i].rotateXZBy(180); - if(dir == v3s16(0,0,1)) - vertices[i].rotateXZBy(90); - if(dir == v3s16(0,0,-1)) - vertices[i].rotateXZBy(-90); - if(dir == v3s16(0,-1,0)) - vertices[i].rotateXYBy(-90); - if(dir == v3s16(0,1,0)) - vertices[i].rotateXYBy(90); - - vertices[i] += npf; - } - - core::aabbox3d box; - - box = core::aabbox3d(vertices[0]); - box.addInternalPoint(vertices[1]); - - if(distance < mindistance) - { - if(box.intersectsWithLine(shootline)) - { - nodefound = true; - nodepos = np; - neighbourpos = np; - mindistance = distance; - nodehilightbox = box; - } - } - } - - else if(n.getContent() == CONTENT_LADDER) - { - v3s16 dir = unpackDir(n.param2); - v3f dir_f = v3f(dir.X, dir.Y, dir.Z); - dir_f *= BS/2 - BS/6 - BS/20; - v3f cpf = npf + dir_f; - f32 distance = (cpf - camera_position).getLength(); - - v3f vertices[4] = - { - v3f(BS*0.42,-BS/2,-BS/2), - v3f(BS*0.49, BS/2, BS/2), - }; - - for(s32 i=0; i<2; i++) - { - if(dir == v3s16(1,0,0)) - vertices[i].rotateXZBy(0); - if(dir == v3s16(-1,0,0)) - vertices[i].rotateXZBy(180); - if(dir == v3s16(0,0,1)) - vertices[i].rotateXZBy(90); - if(dir == v3s16(0,0,-1)) - vertices[i].rotateXZBy(-90); - if(dir == v3s16(0,-1,0)) - vertices[i].rotateXYBy(-90); - if(dir == v3s16(0,1,0)) - vertices[i].rotateXYBy(90); - - vertices[i] += npf; - } - - core::aabbox3d box; - - box = core::aabbox3d(vertices[0]); - box.addInternalPoint(vertices[1]); - - if(distance < mindistance) - { - if(box.intersectsWithLine(shootline)) - { - nodefound = true; - nodepos = np; - neighbourpos = np; - mindistance = distance; - nodehilightbox = box; - } - } - } - else if(n.getContent() == CONTENT_RAIL) - { - v3s16 dir = unpackDir(n.param0); - v3f dir_f = v3f(dir.X, dir.Y, dir.Z); - dir_f *= BS/2 - BS/6 - BS/20; - v3f cpf = npf + dir_f; - f32 distance = (cpf - camera_position).getLength(); - - float d = (float)BS/16; - v3f vertices[4] = - { - v3f(BS/2, -BS/2+d, -BS/2), - v3f(-BS/2, -BS/2, BS/2), - }; - - for(s32 i=0; i<2; i++) - { - vertices[i] += npf; - } - - core::aabbox3d box; - - box = core::aabbox3d(vertices[0]); - box.addInternalPoint(vertices[1]); - - if(distance < mindistance) - { - if(box.intersectsWithLine(shootline)) - { - nodefound = true; - nodepos = np; - neighbourpos = np; - mindistance = distance; - nodehilightbox = box; - } - } - } - /* - Regular blocks - */ - else + else // NODEBOX_REGULAR { for(u16 i=0; i<6; i++) { diff --git a/src/mapnode_contentfeatures.h b/src/mapnode_contentfeatures.h index b60fc8d8b..7dd9df13b 100644 --- a/src/mapnode_contentfeatures.h +++ b/src/mapnode_contentfeatures.h @@ -57,6 +57,35 @@ enum LiquidType LIQUID_SOURCE }; +enum NodeBoxType +{ + NODEBOX_REGULAR, // Regular block; allows buildable_to + NODEBOX_FIXED, // Static separately defined box + NODEBOX_WALLMOUNTED, // Box for wall_mounted nodes; (top, bottom, side) +}; + +struct NodeBox +{ + enum NodeBoxType type; + // NODEBOX_REGULAR (no parameters) + // NODEBOX_FIXED + core::aabbox3d fixed; + // NODEBOX_WALLMOUNTED + core::aabbox3d wall_top; + core::aabbox3d wall_bottom; + core::aabbox3d wall_side; // being at the -X side + + NodeBox(): + type(NODEBOX_REGULAR), + // default is rail-like + fixed(-BS/2, -BS/2, -BS/2, BS/2, -BS/2+BS/16., BS/2), + // default is sign/ladder-like + wall_top(-BS/2, BS/2-BS/16., -BS/2, BS/2, BS/2, BS/2), + wall_bottom(-BS/2, -BS/2, -BS/2, BS/2, -BS/2+BS/16., BS/2), + wall_side(-BS/2, -BS/2, -BS/2, -BS/2+BS/16., BS/2, BS/2) + {} +}; + struct MapNode; class NodeMetadata; @@ -149,6 +178,8 @@ struct ContentFeatures DiggingPropertiesList digging_properties; u32 damage_per_second; + + NodeBox selection_box; // NOTE: Move relevant properties to here from elsewhere @@ -186,6 +217,7 @@ struct ContentFeatures light_source = 0; digging_properties.clear(); damage_per_second = 0; + selection_box = NodeBox(); } ContentFeatures()