Extended block selecting

master
jachoo 2011-12-04 15:32:50 +01:00
parent d4bf0b6e99
commit da398e01e6
5 changed files with 97 additions and 19 deletions

View File

@ -105,6 +105,8 @@
#screenshot_path = .
# Amount of view bobbing (0 = no view bobbing, 1.0 = normal, 2.0 = double)
#view_bobbing_amount = 1.0
# Enables extended block selecting feature (you con now build everything without sneaking)
#extended_block_selecting = false
#
# Server stuff

View File

@ -81,6 +81,7 @@ void set_default_settings(Settings *settings)
settings->setDefault("view_bobbing_amount", "1.0");
settings->setDefault("enable_3d_clouds", "false");
settings->setDefault("opaque_water", "false");
settings->setDefault("extended_block_selecting", "false");
// Server stuff
// "map-dir" doesn't exist by default.

View File

@ -346,9 +346,18 @@ PointedThing getPointedThing(Client *client, v3f player_position,
// That didn't work, try to find a pointed at node
f32 mindistance = BS * 1001;
static const bool extBlockSel = g_settings->getBool("extended_block_selecting");
bool onlyFreeFound = false;
bool freeNodeFound = false;
f32 mindistance = BS * 1001; //used for regular blocks
f32 maxdistance = -BS * 1001; //used for free blocks
v3s16 pos_i = floatToInt(player_position, BS);
v3s16 cam_i = floatToInt(camera_position, BS);
v3s16 camdir_i(camera_direction.X>=0?1:-1,
camera_direction.Y>=0?1:-1,
camera_direction.Z>=0?1:-1);
/*infostream<<"pos_i=("<<pos_i.X<<","<<pos_i.Y<<","<<pos_i.Z<<")"
<<std::endl;*/
@ -374,8 +383,8 @@ PointedThing getPointedThing(Client *client, v3f player_position,
{
continue;
}
if(!isPointableNode(n, client, liquids_pointable))
continue;
/*if(!isPointableNode(n, client, liquids_pointable))
continue;*/
v3s16 np(x,y,z);
v3f npf = intToFloat(np, BS);
@ -548,27 +557,90 @@ PointedThing getPointedThing(Client *client, v3f player_position,
if(facebox.intersectsWithLine(shootline))
{
result.type = POINTEDTHING_NODE;
result.node_undersurface = np;
result.node_abovesurface = np + dirs[i];
mindistance = distance;
if(isPointableNode(n, client, liquids_pointable))
{
result.type = POINTEDTHING_NODE;
result.node_undersurface = np;
result.node_abovesurface = np + dirs[i];
mindistance = distance;
//hilightbox = facebox;
//hilightbox = facebox;
const float d = 0.502;
core::aabbox3d<f32> nodebox
(-BS*d, -BS*d, -BS*d, BS*d, BS*d, BS*d);
v3f nodepos_f = intToFloat(np, BS);
nodebox.MinEdge += nodepos_f;
nodebox.MaxEdge += nodepos_f;
hilightbox = nodebox;
should_show_hilightbox = true;
const float d = 0.502;
core::aabbox3d<f32> nodebox
(-BS*d, -BS*d, -BS*d, BS*d, BS*d, BS*d);
v3f nodepos_f = intToFloat(np, BS);
nodebox.MinEdge += nodepos_f;
nodebox.MaxEdge += nodepos_f;
hilightbox = nodebox;
should_show_hilightbox = true;
//if no node has been found - we try to find 'fake' pointed node
}else if(extBlockSel
&& result.type == POINTEDTHING_NOTHING
&& distance < (BS*6) //is this OK?
&& np != pos_i
&& np != v3s16(pos_i.X,pos_i.Y+1,pos_i.Z)
&& client->getNodeDefManager()->get(n).buildable_to)
{
bool can_build = false;
v3s16 neigh_pos;
for(int i=0; i<6; i++)
{
const v3s16& npos = dirs[i];
v3s16 ap = np + npos;
try{
MapNode an = client->getNode(ap);
//check if we can build onto this node
//FIXME: when it will be possible to build on torches, rails etc. then change .walkable to .pointable
if(!client->getNodeDefManager()->get(an).walkable)
continue;
if( npos.X==camdir_i.X //is it same direction as camera?
|| npos.Y==camdir_i.Y
|| npos.Z==camdir_i.Z
|| (npos.X != 0 && cam_i.X == np.X) //is it the same axis as camera?
|| (npos.Y != 0 && cam_i.Y == np.Y)
|| (npos.Z != 0 && cam_i.Z == np.Z) )
{
can_build = false;
break;
}
can_build = true;
neigh_pos = ap;
}catch(InvalidPositionException&){}
}
if(can_build && distance > maxdistance){
maxdistance = distance;
//nodefound = true; //we can't do this here!
freeNodeFound = true; //instead, we set this and check at the end
result.node_undersurface = neigh_pos; //yes, these are swaped!
result.node_abovesurface = np;
const float d = 0.502;
core::aabbox3d<f32> nodebox
(-BS*d, -BS*d, -BS*d, BS*d, BS*d, BS*d);
v3f nodepos_f = intToFloat(np, BS);
nodebox.MinEdge += nodepos_f;
nodebox.MaxEdge += nodepos_f;
hilightbox = nodebox;
//should_show_hilightbox = true;
}
}
}
} // if distance < mindistance
} // for dirs
} // regular block
} // for coords
if(extBlockSel && result.type == POINTEDTHING_NOTHING && freeNodeFound){
result.is_fake = true;
result.type = POINTEDTHING_NODE;
should_show_hilightbox = true;
}
return result;
}
@ -1830,7 +1902,7 @@ void the_game(
*/
if(nodig_delay_timer <= 0.0 && input->getLeftState())
if(!pointed.is_fake && nodig_delay_timer <= 0.0 && input->getLeftState())
{
if(!digging)
{

View File

@ -259,7 +259,8 @@ PointedThing::PointedThing():
type(POINTEDTHING_NOTHING),
node_undersurface(0,0,0),
node_abovesurface(0,0,0),
object_id(-1)
object_id(-1),
is_fake(false)
{}
std::string PointedThing::dump() const
@ -274,7 +275,8 @@ std::string PointedThing::dump() const
const v3s16 &u = node_undersurface;
const v3s16 &a = node_abovesurface;
os<<"[node under="<<u.X<<","<<u.Y<<","<<u.Z
<< " above="<<a.X<<","<<a.Y<<","<<a.Z<<"]";
<< " above="<<a.X<<","<<a.Y<<","<<a.Z
<< (is_fake?" fake]":"]");
}
else if(type == POINTEDTHING_OBJECT)
{

View File

@ -1766,6 +1766,7 @@ struct PointedThing
v3s16 node_undersurface;
v3s16 node_abovesurface;
s16 object_id;
bool is_fake; //if true, then disallow digging! [not serialized!]
PointedThing();
std::string dump() const;