mirror of
https://github.com/minetest/minetest.git
synced 2024-11-30 03:23:45 +01:00
working nicely
This commit is contained in:
parent
47a593b519
commit
571fb14f94
@ -33,6 +33,12 @@ cp -r data/sign.png $PACKAGEPATH/data/
|
|||||||
cp -r data/sign_back.png $PACKAGEPATH/data/
|
cp -r data/sign_back.png $PACKAGEPATH/data/
|
||||||
cp -r data/rat.png $PACKAGEPATH/data/
|
cp -r data/rat.png $PACKAGEPATH/data/
|
||||||
cp -r data/mud.png $PACKAGEPATH/data/
|
cp -r data/mud.png $PACKAGEPATH/data/
|
||||||
|
cp -r data/torch.png $PACKAGEPATH/data/
|
||||||
|
cp -r data/torch_floor.png $PACKAGEPATH/data/
|
||||||
|
cp -r data/torch_ceiling.png $PACKAGEPATH/data/
|
||||||
|
cp -r data/skybox1.png $PACKAGEPATH/data/
|
||||||
|
cp -r data/skybox2.png $PACKAGEPATH/data/
|
||||||
|
cp -r data/skybox3.png $PACKAGEPATH/data/
|
||||||
|
|
||||||
cp -r doc/README.txt $PACKAGEPATH/doc/README.txt
|
cp -r doc/README.txt $PACKAGEPATH/doc/README.txt
|
||||||
|
|
||||||
|
@ -54,5 +54,8 @@
|
|||||||
#max_simultaneous_block_sends_server_total = 4
|
#max_simultaneous_block_sends_server_total = 4
|
||||||
|
|
||||||
#max_block_send_distance = 8
|
#max_block_send_distance = 8
|
||||||
#max_block_generate_distance = 5
|
#max_block_generate_distance = 6
|
||||||
|
|
||||||
|
#disable_water_climb = true
|
||||||
|
#endless_water = true
|
||||||
|
|
||||||
|
@ -1651,6 +1651,7 @@ MapBlockObject * Client::getSelectedObject(
|
|||||||
v3f from_pos_f_on_block = from_pos_f_on_map - block_pos_f_on_map;
|
v3f from_pos_f_on_block = from_pos_f_on_map - block_pos_f_on_map;
|
||||||
|
|
||||||
block->getObjects(from_pos_f_on_block, max_d, objects);
|
block->getObjects(from_pos_f_on_block, max_d, objects);
|
||||||
|
//block->getPseudoObjects(from_pos_f_on_block, max_d, objects);
|
||||||
}
|
}
|
||||||
|
|
||||||
//dstream<<"Collected "<<objects.size()<<" nearby objects"<<std::endl;
|
//dstream<<"Collected "<<objects.size()<<" nearby objects"<<std::endl;
|
||||||
|
@ -142,9 +142,9 @@ void Environment::step(float dtime)
|
|||||||
v3s16 bottompos = floatToInt(playerpos + v3f(0,-BS/4,0));
|
v3s16 bottompos = floatToInt(playerpos + v3f(0,-BS/4,0));
|
||||||
try{
|
try{
|
||||||
MapNode n = m_map->getNode(bottompos);
|
MapNode n = m_map->getNode(bottompos);
|
||||||
if(n.d == MATERIAL_GRASS)
|
if(n.d == CONTENT_GRASS)
|
||||||
{
|
{
|
||||||
n.d = MATERIAL_GRASS_FOOTSTEPS;
|
n.d = CONTENT_GRASS_FOOTSTEPS;
|
||||||
m_map->setNode(bottompos, n);
|
m_map->setNode(bottompos, n);
|
||||||
|
|
||||||
// Update mesh on client
|
// Update mesh on client
|
||||||
|
@ -101,4 +101,47 @@ u8 light_decode_table[LIGHT_MAX+1] =
|
|||||||
255,
|
255,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
#!/usr/bin/python
|
||||||
|
|
||||||
|
from math import *
|
||||||
|
from sys import stdout
|
||||||
|
|
||||||
|
# We want 0 at light=0 and 255 at light=LIGHT_MAX
|
||||||
|
LIGHT_MAX = 14
|
||||||
|
#FACTOR = 0.69
|
||||||
|
FACTOR = 0.75
|
||||||
|
|
||||||
|
maxlight = 255
|
||||||
|
minlight = 8
|
||||||
|
|
||||||
|
L = []
|
||||||
|
for i in range(1,LIGHT_MAX+1):
|
||||||
|
L.append(minlight+int(round((maxlight-minlight) * FACTOR ** (i-1))))
|
||||||
|
#L.append(int(round(255.0 * FACTOR ** (i-1))))
|
||||||
|
L.append(minlight)
|
||||||
|
|
||||||
|
L.reverse()
|
||||||
|
for i in L:
|
||||||
|
stdout.write(str(i)+",\n")
|
||||||
|
*/
|
||||||
|
/*u8 light_decode_table[LIGHT_MAX+1] =
|
||||||
|
{
|
||||||
|
8,
|
||||||
|
14,
|
||||||
|
16,
|
||||||
|
18,
|
||||||
|
22,
|
||||||
|
27,
|
||||||
|
33,
|
||||||
|
41,
|
||||||
|
52,
|
||||||
|
67,
|
||||||
|
86,
|
||||||
|
112,
|
||||||
|
147,
|
||||||
|
193,
|
||||||
|
255,
|
||||||
|
};*/
|
||||||
|
|
||||||
|
|
||||||
|
209
src/main.cpp
209
src/main.cpp
@ -186,13 +186,11 @@ SUGG: Implement a "Fast check queue" (a queue with a map for checking
|
|||||||
TODO: Proper looking torches.
|
TODO: Proper looking torches.
|
||||||
- Signs could be done in the same way?
|
- Signs could be done in the same way?
|
||||||
|
|
||||||
|
TODO: A mapper to map contents to tile names (for each side)
|
||||||
|
|
||||||
Doing now:
|
Doing now:
|
||||||
======================================================================
|
======================================================================
|
||||||
|
|
||||||
TODO: A system for showing some nodes in some other way than cubes
|
|
||||||
- Needed for torches
|
|
||||||
- Also for signs, stairs, etc
|
|
||||||
|
|
||||||
======================================================================
|
======================================================================
|
||||||
|
|
||||||
*/
|
*/
|
||||||
@ -257,22 +255,26 @@ TODO: A system for showing some nodes in some other way than cubes
|
|||||||
|
|
||||||
IrrlichtDevice *g_device = NULL;
|
IrrlichtDevice *g_device = NULL;
|
||||||
|
|
||||||
const char *g_material_filenames[MATERIALS_COUNT] =
|
const char *g_content_filenames[MATERIALS_COUNT] =
|
||||||
{
|
{
|
||||||
"../data/stone.png",
|
"../data/stone.png",
|
||||||
"../data/grass.png",
|
"../data/grass.png",
|
||||||
"../data/water.png",
|
"../data/water.png",
|
||||||
"../data/light.png",
|
"../data/torch_on_floor.png",
|
||||||
"../data/tree.png",
|
"../data/tree.png",
|
||||||
"../data/leaves.png",
|
"../data/leaves.png",
|
||||||
"../data/grass_footsteps.png",
|
"../data/grass_footsteps.png",
|
||||||
"../data/mese.png",
|
"../data/mese.png",
|
||||||
"../data/mud.png",
|
"../data/mud.png",
|
||||||
"../data/water.png", // ocean
|
"../data/water.png", // CONTENT_OCEAN
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Material cache
|
||||||
video::SMaterial g_materials[MATERIALS_COUNT];
|
video::SMaterial g_materials[MATERIALS_COUNT];
|
||||||
//video::SMaterial g_mesh_materials[3];
|
|
||||||
|
// Texture cache
|
||||||
|
TextureCache g_texturecache;
|
||||||
|
|
||||||
|
|
||||||
// All range-related stuff below is locked behind this
|
// All range-related stuff below is locked behind this
|
||||||
JMutex g_range_mutex;
|
JMutex g_range_mutex;
|
||||||
@ -320,20 +322,22 @@ void set_default_settings()
|
|||||||
g_settings.set("random_input", "false");
|
g_settings.set("random_input", "false");
|
||||||
g_settings.set("client_delete_unused_sectors_timeout", "1200");
|
g_settings.set("client_delete_unused_sectors_timeout", "1200");
|
||||||
g_settings.set("max_block_send_distance", "8");
|
g_settings.set("max_block_send_distance", "8");
|
||||||
g_settings.set("max_block_generate_distance", "5");
|
g_settings.set("max_block_generate_distance", "6");
|
||||||
|
|
||||||
// Server stuff
|
// Server stuff
|
||||||
g_settings.set("creative_mode", "false");
|
g_settings.set("creative_mode", "false");
|
||||||
g_settings.set("heightmap_blocksize", "128");
|
g_settings.set("heightmap_blocksize", "32");
|
||||||
g_settings.set("height_randmax", "constant 70.0");
|
g_settings.set("height_randmax", "constant 50.0");
|
||||||
g_settings.set("height_randfactor", "constant 0.6");
|
g_settings.set("height_randfactor", "constant 0.6");
|
||||||
g_settings.set("height_base", "linear 0 35 0");
|
g_settings.set("height_base", "linear 0 0 0");
|
||||||
g_settings.set("plants_amount", "1.0");
|
g_settings.set("plants_amount", "1.0");
|
||||||
g_settings.set("ravines_amount", "1.0");
|
g_settings.set("ravines_amount", "1.0");
|
||||||
g_settings.set("objectdata_interval", "0.2");
|
g_settings.set("objectdata_interval", "0.2");
|
||||||
g_settings.set("active_object_range", "2");
|
g_settings.set("active_object_range", "2");
|
||||||
g_settings.set("max_simultaneous_block_sends_per_client", "1");
|
g_settings.set("max_simultaneous_block_sends_per_client", "1");
|
||||||
g_settings.set("max_simultaneous_block_sends_server_total", "4");
|
g_settings.set("max_simultaneous_block_sends_server_total", "4");
|
||||||
|
g_settings.set("disable_water_climb", "true");
|
||||||
|
g_settings.set("endless_water", "true");
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -673,7 +677,7 @@ public:
|
|||||||
if(counter1 < 0.0)
|
if(counter1 < 0.0)
|
||||||
{
|
{
|
||||||
counter1 = 0.1*Rand(1,10);
|
counter1 = 0.1*Rand(1,10);
|
||||||
/*if(g_selected_material < USEFUL_MATERIAL_COUNT-1)
|
/*if(g_selected_material < USEFUL_CONTENT_COUNT-1)
|
||||||
g_selected_material++;
|
g_selected_material++;
|
||||||
else
|
else
|
||||||
g_selected_material = 0;*/
|
g_selected_material = 0;*/
|
||||||
@ -1297,7 +1301,7 @@ int main(int argc, char *argv[])
|
|||||||
g_materials[i].Lighting = false;
|
g_materials[i].Lighting = false;
|
||||||
g_materials[i].BackfaceCulling = false;
|
g_materials[i].BackfaceCulling = false;
|
||||||
|
|
||||||
const char *filename = g_material_filenames[i];
|
const char *filename = g_content_filenames[i];
|
||||||
if(filename != NULL){
|
if(filename != NULL){
|
||||||
video::ITexture *t = driver->getTexture(filename);
|
video::ITexture *t = driver->getTexture(filename);
|
||||||
if(t == NULL){
|
if(t == NULL){
|
||||||
@ -1313,9 +1317,9 @@ int main(int argc, char *argv[])
|
|||||||
//g_materials[i].setFlag(video::EMF_FOG_ENABLE, true);
|
//g_materials[i].setFlag(video::EMF_FOG_ENABLE, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
g_materials[MATERIAL_WATER].MaterialType = video::EMT_TRANSPARENT_VERTEX_ALPHA;
|
g_materials[CONTENT_WATER].MaterialType = video::EMT_TRANSPARENT_VERTEX_ALPHA;
|
||||||
//g_materials[MATERIAL_WATER].MaterialType = video::EMT_TRANSPARENT_ADD_COLOR;
|
//g_materials[CONTENT_WATER].MaterialType = video::EMT_TRANSPARENT_ADD_COLOR;
|
||||||
g_materials[MATERIAL_OCEAN].MaterialType = video::EMT_TRANSPARENT_VERTEX_ALPHA;
|
g_materials[CONTENT_OCEAN].MaterialType = video::EMT_TRANSPARENT_VERTEX_ALPHA;
|
||||||
|
|
||||||
/*g_mesh_materials[0].setTexture(0, driver->getTexture("../data/water.png"));
|
/*g_mesh_materials[0].setTexture(0, driver->getTexture("../data/water.png"));
|
||||||
g_mesh_materials[1].setTexture(0, driver->getTexture("../data/grass.png"));
|
g_mesh_materials[1].setTexture(0, driver->getTexture("../data/grass.png"));
|
||||||
@ -1328,8 +1332,18 @@ int main(int argc, char *argv[])
|
|||||||
g_mesh_materials[i].setFlag(video::EMF_FOG_ENABLE, true);
|
g_mesh_materials[i].setFlag(video::EMF_FOG_ENABLE, true);
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
// Make a scope here for the client so that it gets removed
|
/*
|
||||||
// before the irrlicht device
|
Preload some random textures that are used in threads
|
||||||
|
*/
|
||||||
|
|
||||||
|
g_texturecache.set("torch", driver->getTexture("../data/torch.png"));
|
||||||
|
g_texturecache.set("torch_on_floor", driver->getTexture("../data/torch_on_floor.png"));
|
||||||
|
g_texturecache.set("torch_on_ceiling", driver->getTexture("../data/torch_on_ceiling.png"));
|
||||||
|
|
||||||
|
/*
|
||||||
|
Make a scope here for the client so that it gets removed
|
||||||
|
before the irrlicht device
|
||||||
|
*/
|
||||||
{
|
{
|
||||||
|
|
||||||
std::cout<<DTIME<<"Creating server and client"<<std::endl;
|
std::cout<<DTIME<<"Creating server and client"<<std::endl;
|
||||||
@ -1381,6 +1395,23 @@ int main(int argc, char *argv[])
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Create skybox
|
||||||
|
*/
|
||||||
|
scene::ISceneNode* skybox = smgr->addSkyBoxSceneNode(
|
||||||
|
driver->getTexture("../data/skybox2.png"),
|
||||||
|
driver->getTexture("../data/skybox3.png"),
|
||||||
|
driver->getTexture("../data/skybox1.png"),
|
||||||
|
driver->getTexture("../data/skybox1.png"),
|
||||||
|
driver->getTexture("../data/skybox1.png"),
|
||||||
|
driver->getTexture("../data/skybox1.png"));
|
||||||
|
/* driver->getTexture("../data/irrlicht2_up.jpg"),
|
||||||
|
driver->getTexture("../data/irrlicht2_dn.jpg"),
|
||||||
|
driver->getTexture("../data/irrlicht2_lf.jpg"),
|
||||||
|
driver->getTexture("../data/irrlicht2_rt.jpg"),
|
||||||
|
driver->getTexture("../data/irrlicht2_ft.jpg"),
|
||||||
|
driver->getTexture("../data/irrlicht2_bk.jpg"));*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Create the camera node
|
Create the camera node
|
||||||
*/
|
*/
|
||||||
@ -1862,14 +1893,19 @@ int main(int argc, char *argv[])
|
|||||||
s16 zend = pos_i.Z + (camera_direction.Z>0 ? a : 1);
|
s16 zend = pos_i.Z + (camera_direction.Z>0 ? a : 1);
|
||||||
s16 xend = pos_i.X + (camera_direction.X>0 ? a : 1);
|
s16 xend = pos_i.X + (camera_direction.X>0 ? a : 1);
|
||||||
|
|
||||||
for(s16 y = ystart; y <= yend; y++){
|
for(s16 y = ystart; y <= yend; y++)
|
||||||
for(s16 z = zstart; z <= zend; z++){
|
for(s16 z = zstart; z <= zend; z++)
|
||||||
for(s16 x = xstart; x <= xend; x++)
|
for(s16 x = xstart; x <= xend; x++)
|
||||||
{
|
{
|
||||||
try{
|
MapNode n;
|
||||||
if(material_pointable(client.getNode(v3s16(x,y,z)).d) == false)
|
try
|
||||||
|
{
|
||||||
|
n = client.getNode(v3s16(x,y,z));
|
||||||
|
if(content_pointable(n.d) == false)
|
||||||
continue;
|
continue;
|
||||||
}catch(InvalidPositionException &e){
|
}
|
||||||
|
catch(InvalidPositionException &e)
|
||||||
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1878,55 +1914,110 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
f32 d = 0.01;
|
f32 d = 0.01;
|
||||||
|
|
||||||
v3s16 directions[6] = {
|
v3s16 dirs[6] = {
|
||||||
v3s16(0,0,1), // back
|
v3s16(0,0,1), // back
|
||||||
v3s16(0,1,0), // top
|
v3s16(0,1,0), // top
|
||||||
v3s16(1,0,0), // right
|
v3s16(1,0,0), // right
|
||||||
v3s16(0,0,-1),
|
v3s16(0,0,-1), // front
|
||||||
v3s16(0,-1,0),
|
v3s16(0,-1,0), // bottom
|
||||||
v3s16(-1,0,0),
|
v3s16(-1,0,0), // left
|
||||||
};
|
};
|
||||||
|
|
||||||
for(u16 i=0; i<6; i++){
|
/*
|
||||||
//{u16 i=3;
|
Meta-objects
|
||||||
v3f dir_f = v3f(directions[i].X,
|
*/
|
||||||
directions[i].Y, directions[i].Z);
|
if(n.d == CONTENT_LIGHT)
|
||||||
v3f centerpoint = npf + dir_f * BS/2;
|
{
|
||||||
f32 distance =
|
v3s16 dir = unpackDir(n.dir);
|
||||||
(centerpoint - camera_position).getLength();
|
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();
|
||||||
|
|
||||||
if(distance < mindistance){
|
core::aabbox3d<f32> box;
|
||||||
//std::cout<<DTIME<<"for centerpoint=("<<centerpoint.X<<","<<centerpoint.Y<<","<<centerpoint.Z<<"): distance < mindistance"<<std::endl;
|
|
||||||
//std::cout<<DTIME<<"npf=("<<npf.X<<","<<npf.Y<<","<<npf.Z<<")"<<std::endl;
|
|
||||||
core::CMatrix4<f32> m;
|
|
||||||
m.buildRotateFromTo(v3f(0,0,1), dir_f);
|
|
||||||
|
|
||||||
// This is the back face
|
// bottom
|
||||||
v3f corners[2] = {
|
if(dir == v3s16(0,-1,0))
|
||||||
v3f(BS/2, BS/2, BS/2),
|
{
|
||||||
v3f(-BS/2, -BS/2, BS/2+d)
|
box = core::aabbox3d<f32>(
|
||||||
};
|
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<f32>(
|
||||||
|
npf - v3f(BS/6, -BS/2+BS/3*2, BS/6),
|
||||||
|
npf + v3f(BS/6, BS/2, BS/6)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
// side
|
||||||
|
else
|
||||||
|
{
|
||||||
|
box = core::aabbox3d<f32>(
|
||||||
|
cpf - v3f(BS/6, BS/3, BS/6),
|
||||||
|
cpf + v3f(BS/6, BS/3, BS/6)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
for(u16 j=0; j<2; j++){
|
if(distance < mindistance)
|
||||||
m.rotateVect(corners[j]);
|
{
|
||||||
corners[j] += npf;
|
if(box.intersectsWithLine(shootline))
|
||||||
//std::cout<<DTIME<<"box corners["<<j<<"]: ("<<corners[j].X<<","<<corners[j].Y<<","<<corners[j].Z<<")"<<std::endl;
|
{
|
||||||
}
|
|
||||||
|
|
||||||
//core::aabbox3d<f32> facebox(corners[0],corners[1]);
|
|
||||||
core::aabbox3d<f32> facebox(corners[0]);
|
|
||||||
facebox.addInternalPoint(corners[1]);
|
|
||||||
|
|
||||||
if(facebox.intersectsWithLine(shootline)){
|
|
||||||
nodefound = true;
|
nodefound = true;
|
||||||
nodepos = np;
|
nodepos = np;
|
||||||
neighbourpos = np + directions[i];
|
neighbourpos = np;
|
||||||
mindistance = distance;
|
mindistance = distance;
|
||||||
nodefacebox = facebox;
|
nodefacebox = box;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}}}
|
/*
|
||||||
|
Regular blocks
|
||||||
|
*/
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for(u16 i=0; i<6; i++)
|
||||||
|
{
|
||||||
|
v3f dir_f = v3f(dirs[i].X,
|
||||||
|
dirs[i].Y, dirs[i].Z);
|
||||||
|
v3f centerpoint = npf + dir_f * BS/2;
|
||||||
|
f32 distance =
|
||||||
|
(centerpoint - camera_position).getLength();
|
||||||
|
|
||||||
|
if(distance < mindistance)
|
||||||
|
{
|
||||||
|
core::CMatrix4<f32> m;
|
||||||
|
m.buildRotateFromTo(v3f(0,0,1), dir_f);
|
||||||
|
|
||||||
|
// This is the back face
|
||||||
|
v3f corners[2] = {
|
||||||
|
v3f(BS/2, BS/2, BS/2),
|
||||||
|
v3f(-BS/2, -BS/2, BS/2+d)
|
||||||
|
};
|
||||||
|
|
||||||
|
for(u16 j=0; j<2; j++)
|
||||||
|
{
|
||||||
|
m.rotateVect(corners[j]);
|
||||||
|
corners[j] += npf;
|
||||||
|
}
|
||||||
|
|
||||||
|
core::aabbox3d<f32> facebox(corners[0]);
|
||||||
|
facebox.addInternalPoint(corners[1]);
|
||||||
|
|
||||||
|
if(facebox.intersectsWithLine(shootline))
|
||||||
|
{
|
||||||
|
nodefound = true;
|
||||||
|
nodepos = np;
|
||||||
|
neighbourpos = np + dirs[i];
|
||||||
|
mindistance = distance;
|
||||||
|
nodefacebox = facebox;
|
||||||
|
}
|
||||||
|
} // if distance < mindistance
|
||||||
|
} // for dirs
|
||||||
|
} // regular block
|
||||||
|
} // for coords
|
||||||
|
|
||||||
if(nodefound)
|
if(nodefound)
|
||||||
{
|
{
|
||||||
|
@ -55,7 +55,9 @@ extern std::ostream *derr_server_ptr;
|
|||||||
// This header is only for MATERIALS_COUNT
|
// This header is only for MATERIALS_COUNT
|
||||||
#include "mapnode.h"
|
#include "mapnode.h"
|
||||||
extern video::SMaterial g_materials[MATERIALS_COUNT];
|
extern video::SMaterial g_materials[MATERIALS_COUNT];
|
||||||
//extern video::SMaterial g_mesh_materials[3];
|
|
||||||
|
#include "utility.h"
|
||||||
|
extern TextureCache g_texturecache;
|
||||||
|
|
||||||
extern IrrlichtDevice *g_device;
|
extern IrrlichtDevice *g_device;
|
||||||
|
|
||||||
|
180
src/map.cpp
180
src/map.cpp
@ -510,6 +510,10 @@ void Map::unspreadLight(core::map<v3s16, u8> & from_nodes,
|
|||||||
light_sources.remove(n2pos);
|
light_sources.remove(n2pos);
|
||||||
}*/
|
}*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*// DEBUG
|
||||||
|
if(light_sources.find(n2pos) != NULL)
|
||||||
|
light_sources.remove(n2pos);*/
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
light_sources.insert(n2pos, true);
|
light_sources.insert(n2pos, true);
|
||||||
@ -850,8 +854,8 @@ void Map::updateLighting(core::map<v3s16, MapBlock*> & a_blocks,
|
|||||||
|
|
||||||
// Collect borders for unlighting
|
// Collect borders for unlighting
|
||||||
if(x==0 || x == MAP_BLOCKSIZE-1
|
if(x==0 || x == MAP_BLOCKSIZE-1
|
||||||
|| y==0 || y == MAP_BLOCKSIZE-1
|
|| y==0 || y == MAP_BLOCKSIZE-1
|
||||||
|| z==0 || z == MAP_BLOCKSIZE-1)
|
|| z==0 || z == MAP_BLOCKSIZE-1)
|
||||||
{
|
{
|
||||||
v3s16 p_map = p + v3s16(
|
v3s16 p_map = p + v3s16(
|
||||||
MAP_BLOCKSIZE*pos.X,
|
MAP_BLOCKSIZE*pos.X,
|
||||||
@ -912,6 +916,8 @@ void Map::updateLighting(core::map<v3s16, MapBlock*> & a_blocks,
|
|||||||
// Yes, add it to light_sources... somehow.
|
// Yes, add it to light_sources... somehow.
|
||||||
// It has to be added at somewhere above, in the loop.
|
// It has to be added at somewhere above, in the loop.
|
||||||
// TODO
|
// TODO
|
||||||
|
// NOTE: This actually works quite fine without it
|
||||||
|
// - Find out why it works
|
||||||
|
|
||||||
{
|
{
|
||||||
//TimeTaker timer("spreadLight", g_device);
|
//TimeTaker timer("spreadLight", g_device);
|
||||||
@ -1048,7 +1054,7 @@ void Map::removeNodeAndUpdate(v3s16 p,
|
|||||||
v3s16 toppos = p + v3s16(0,1,0);
|
v3s16 toppos = p + v3s16(0,1,0);
|
||||||
|
|
||||||
// Node will be replaced with this
|
// Node will be replaced with this
|
||||||
u8 replace_material = MATERIAL_AIR;
|
u8 replace_material = CONTENT_AIR;
|
||||||
|
|
||||||
// NOTE: Water is now managed elsewhere
|
// NOTE: Water is now managed elsewhere
|
||||||
#if 0
|
#if 0
|
||||||
@ -1099,7 +1105,7 @@ void Map::removeNodeAndUpdate(v3s16 p,
|
|||||||
if(
|
if(
|
||||||
c > highest_ranking ||
|
c > highest_ranking ||
|
||||||
// Prefer something else than air
|
// Prefer something else than air
|
||||||
(c >= highest_ranking && m != MATERIAL_AIR)
|
(c >= highest_ranking && m != CONTENT_AIR)
|
||||||
|
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
@ -1722,17 +1728,91 @@ MapBlock * ServerMap::emergeBlock(
|
|||||||
low_block_is_empty = true;*/
|
low_block_is_empty = true;*/
|
||||||
|
|
||||||
const s32 ued = 4;
|
const s32 ued = 4;
|
||||||
|
//const s32 ued = 8;
|
||||||
bool underground_emptiness[ued*ued*ued];
|
bool underground_emptiness[ued*ued*ued];
|
||||||
for(s32 i=0; i<ued*ued*ued; i++)
|
for(s32 i=0; i<ued*ued*ued; i++)
|
||||||
{
|
{
|
||||||
underground_emptiness[i] = ((rand() % 4) == 0);
|
underground_emptiness[i] = ((rand() % 5) == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
/*
|
||||||
|
This is a messy hack to sort the emptiness a bit
|
||||||
|
*/
|
||||||
|
for(s32 j=0; j<2; j++)
|
||||||
|
for(s32 y0=0; y0<ued; y0++)
|
||||||
|
for(s32 z0=0; z0<ued; z0++)
|
||||||
|
for(s32 x0=0; x0<ued; x0++)
|
||||||
|
{
|
||||||
|
v3s16 p0(x0,y0,z0);
|
||||||
|
bool &e0 = underground_emptiness[
|
||||||
|
ued*ued*(z0*ued/MAP_BLOCKSIZE)
|
||||||
|
+ued*(y0*ued/MAP_BLOCKSIZE)
|
||||||
|
+(x0*ued/MAP_BLOCKSIZE)];
|
||||||
|
|
||||||
|
v3s16 dirs[6] = {
|
||||||
|
v3s16(0,0,1), // back
|
||||||
|
v3s16(1,0,0), // right
|
||||||
|
v3s16(0,0,-1), // front
|
||||||
|
v3s16(-1,0,0), // left
|
||||||
|
/*v3s16(0,1,0), // top
|
||||||
|
v3s16(0,-1,0), // bottom*/
|
||||||
|
};
|
||||||
|
for(s32 i=0; i<4; i++)
|
||||||
|
{
|
||||||
|
v3s16 p1 = p0 + dirs[i];
|
||||||
|
if(isInArea(p1, ued) == false)
|
||||||
|
continue;
|
||||||
|
bool &e1 = underground_emptiness[
|
||||||
|
ued*ued*(p1.Z*ued/MAP_BLOCKSIZE)
|
||||||
|
+ued*(p1.Y*ued/MAP_BLOCKSIZE)
|
||||||
|
+(p1.X*ued/MAP_BLOCKSIZE)];
|
||||||
|
if(e0 == e1)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
v3s16 dirs[6] = {
|
||||||
|
v3s16(0,1,0), // top
|
||||||
|
v3s16(0,-1,0), // bottom
|
||||||
|
/*v3s16(0,0,1), // back
|
||||||
|
v3s16(1,0,0), // right
|
||||||
|
v3s16(0,0,-1), // front
|
||||||
|
v3s16(-1,0,0), // left*/
|
||||||
|
};
|
||||||
|
for(s32 i=0; i<2; i++)
|
||||||
|
{
|
||||||
|
v3s16 p2 = p1 + dirs[i];
|
||||||
|
if(p2 == p0)
|
||||||
|
continue;
|
||||||
|
if(isInArea(p2, ued) == false)
|
||||||
|
continue;
|
||||||
|
bool &e2 = underground_emptiness[
|
||||||
|
ued*ued*(p2.Z*ued/MAP_BLOCKSIZE)
|
||||||
|
+ued*(p2.Y*ued/MAP_BLOCKSIZE)
|
||||||
|
+(p2.X*ued/MAP_BLOCKSIZE)];
|
||||||
|
if(e2 != e0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
bool t = e1;
|
||||||
|
e1 = e2;
|
||||||
|
e2 = t;
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
//break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// This is the basic material of what the visible flat ground
|
// This is the basic material of what the visible flat ground
|
||||||
// will consist of
|
// will consist of
|
||||||
u8 material = MATERIAL_GRASS;
|
u8 material = CONTENT_GRASS;
|
||||||
|
|
||||||
|
u8 water_material = CONTENT_WATER;
|
||||||
|
if(g_settings.getBool("endless_water"))
|
||||||
|
water_material = CONTENT_OCEAN;
|
||||||
|
|
||||||
s32 lowest_ground_y = 32767;
|
s32 lowest_ground_y = 32767;
|
||||||
|
s32 highest_ground_y = -32768;
|
||||||
|
|
||||||
// DEBUG
|
// DEBUG
|
||||||
//sector->printHeightmaps();
|
//sector->printHeightmaps();
|
||||||
@ -1755,14 +1835,19 @@ MapBlock * ServerMap::emergeBlock(
|
|||||||
//avg_ground_y += surface_y;
|
//avg_ground_y += surface_y;
|
||||||
if(surface_y < lowest_ground_y)
|
if(surface_y < lowest_ground_y)
|
||||||
lowest_ground_y = surface_y;
|
lowest_ground_y = surface_y;
|
||||||
|
if(surface_y > highest_ground_y)
|
||||||
|
highest_ground_y = surface_y;
|
||||||
|
|
||||||
s32 surface_depth = 0;
|
s32 surface_depth = 0;
|
||||||
|
|
||||||
float slope = sector->getSlope(v2s16(x0,z0)).getLength();
|
float slope = sector->getSlope(v2s16(x0,z0)).getLength();
|
||||||
|
|
||||||
float min_slope = 0.45;
|
//float min_slope = 0.45;
|
||||||
float max_slope = 0.85;
|
//float max_slope = 0.85;
|
||||||
float min_slope_depth = 5.0;
|
float min_slope = 0.70;
|
||||||
|
float max_slope = 1.20;
|
||||||
|
float min_slope_depth = 4.0;
|
||||||
|
//float min_slope_depth = 5.0;
|
||||||
float max_slope_depth = 0;
|
float max_slope_depth = 0;
|
||||||
if(slope < min_slope)
|
if(slope < min_slope)
|
||||||
surface_depth = min_slope_depth;
|
surface_depth = min_slope_depth;
|
||||||
@ -1783,33 +1868,55 @@ MapBlock * ServerMap::emergeBlock(
|
|||||||
*/
|
*/
|
||||||
if(real_y > surface_y)
|
if(real_y > surface_y)
|
||||||
n.setLight(LIGHT_SUN);
|
n.setLight(LIGHT_SUN);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Calculate material
|
Calculate material
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// If node is very low
|
// If node is very low
|
||||||
if(real_y <= surface_y - 7){
|
/*if(real_y <= surface_y - 7)
|
||||||
|
{
|
||||||
// Create dungeons
|
// Create dungeons
|
||||||
if(underground_emptiness[
|
if(underground_emptiness[
|
||||||
ued*ued*(z0*ued/MAP_BLOCKSIZE)
|
ued*ued*(z0*ued/MAP_BLOCKSIZE)
|
||||||
+ued*(y0*ued/MAP_BLOCKSIZE)
|
+ued*(y0*ued/MAP_BLOCKSIZE)
|
||||||
+(x0*ued/MAP_BLOCKSIZE)])
|
+(x0*ued/MAP_BLOCKSIZE)])
|
||||||
{
|
{
|
||||||
n.d = MATERIAL_AIR;
|
n.d = CONTENT_AIR;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
n.d = MATERIAL_STONE;
|
n.d = CONTENT_STONE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// If node is under surface level
|
// If node is under surface level
|
||||||
else if(real_y <= surface_y - surface_depth)
|
else if(real_y <= surface_y - surface_depth)
|
||||||
n.d = MATERIAL_STONE;
|
n.d = CONTENT_STONE;
|
||||||
|
*/
|
||||||
|
if(real_y <= surface_y - surface_depth)
|
||||||
|
{
|
||||||
|
// Create dungeons
|
||||||
|
if(underground_emptiness[
|
||||||
|
ued*ued*(z0*ued/MAP_BLOCKSIZE)
|
||||||
|
+ued*(y0*ued/MAP_BLOCKSIZE)
|
||||||
|
+(x0*ued/MAP_BLOCKSIZE)])
|
||||||
|
{
|
||||||
|
n.d = CONTENT_AIR;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
n.d = CONTENT_STONE;
|
||||||
|
}
|
||||||
|
}
|
||||||
// If node is at or under heightmap y
|
// If node is at or under heightmap y
|
||||||
else if(real_y <= surface_y)
|
else if(real_y <= surface_y)
|
||||||
{
|
{
|
||||||
// If under water level, it's mud
|
// If under water level, it's mud
|
||||||
if(real_y < WATER_LEVEL)
|
if(real_y < WATER_LEVEL)
|
||||||
n.d = MATERIAL_MUD;
|
n.d = CONTENT_MUD;
|
||||||
|
// Only the topmost node is grass
|
||||||
|
else if(real_y <= surface_y - 1)
|
||||||
|
n.d = CONTENT_MUD;
|
||||||
// Else it's the main material
|
// Else it's the main material
|
||||||
else
|
else
|
||||||
n.d = material;
|
n.d = material;
|
||||||
@ -1819,13 +1926,12 @@ MapBlock * ServerMap::emergeBlock(
|
|||||||
// If under water level, it's water
|
// If under water level, it's water
|
||||||
if(real_y < WATER_LEVEL)
|
if(real_y < WATER_LEVEL)
|
||||||
{
|
{
|
||||||
//n.d = MATERIAL_WATER;
|
n.d = water_material;
|
||||||
n.d = MATERIAL_OCEAN;
|
|
||||||
n.setLight(diminish_light(LIGHT_SUN, WATER_LEVEL-real_y+1));
|
n.setLight(diminish_light(LIGHT_SUN, WATER_LEVEL-real_y+1));
|
||||||
}
|
}
|
||||||
// else air
|
// else air
|
||||||
else
|
else
|
||||||
n.d = MATERIAL_AIR;
|
n.d = CONTENT_AIR;
|
||||||
}
|
}
|
||||||
block->setNode(v3s16(x0,y0,z0), n);
|
block->setNode(v3s16(x0,y0,z0), n);
|
||||||
}
|
}
|
||||||
@ -1836,15 +1942,17 @@ MapBlock * ServerMap::emergeBlock(
|
|||||||
*/
|
*/
|
||||||
// Probably underground if the highest part of block is under lowest
|
// Probably underground if the highest part of block is under lowest
|
||||||
// ground height
|
// ground height
|
||||||
bool is_underground = (block_y+1) * MAP_BLOCKSIZE < lowest_ground_y;
|
bool is_underground = (block_y+1) * MAP_BLOCKSIZE <= lowest_ground_y;
|
||||||
block->setIsUnderground(is_underground);
|
block->setIsUnderground(is_underground);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Force lighting update if underground.
|
Force lighting update if some part of block is underground
|
||||||
This is needed because of ravines.
|
This is needed because of caves.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if(is_underground)
|
bool some_part_underground = (block_y+0) * MAP_BLOCKSIZE < highest_ground_y;
|
||||||
|
if(some_part_underground)
|
||||||
|
//if(is_underground)
|
||||||
{
|
{
|
||||||
lighting_invalidated_blocks[block->getPos()] = block;
|
lighting_invalidated_blocks[block->getPos()] = block;
|
||||||
}
|
}
|
||||||
@ -1867,15 +1975,15 @@ MapBlock * ServerMap::emergeBlock(
|
|||||||
);
|
);
|
||||||
|
|
||||||
MapNode n;
|
MapNode n;
|
||||||
n.d = MATERIAL_MESE;
|
n.d = CONTENT_MESE;
|
||||||
|
|
||||||
if(is_ground_material(block->getNode(cp).d))
|
if(is_ground_content(block->getNode(cp).d))
|
||||||
if(rand()%8 == 0)
|
if(rand()%8 == 0)
|
||||||
block->setNode(cp, n);
|
block->setNode(cp, n);
|
||||||
|
|
||||||
for(u16 i=0; i<26; i++)
|
for(u16 i=0; i<26; i++)
|
||||||
{
|
{
|
||||||
if(is_ground_material(block->getNode(cp+g_26dirs[i]).d))
|
if(is_ground_content(block->getNode(cp+g_26dirs[i]).d))
|
||||||
if(rand()%8 == 0)
|
if(rand()%8 == 0)
|
||||||
block->setNode(cp+g_26dirs[i], n);
|
block->setNode(cp+g_26dirs[i], n);
|
||||||
}
|
}
|
||||||
@ -1897,7 +2005,7 @@ MapBlock * ServerMap::emergeBlock(
|
|||||||
);
|
);
|
||||||
|
|
||||||
// Check that the place is empty
|
// Check that the place is empty
|
||||||
//if(!is_ground_material(block->getNode(cp).d))
|
//if(!is_ground_content(block->getNode(cp).d))
|
||||||
if(1)
|
if(1)
|
||||||
{
|
{
|
||||||
RatObject *obj = new RatObject(NULL, -1, intToFloat(cp));
|
RatObject *obj = new RatObject(NULL, -1, intToFloat(cp));
|
||||||
@ -1978,7 +2086,7 @@ MapBlock * ServerMap::emergeBlock(
|
|||||||
p + v3s16(0,0,0), &changed_blocks_sector))
|
p + v3s16(0,0,0), &changed_blocks_sector))
|
||||||
{
|
{
|
||||||
MapNode n;
|
MapNode n;
|
||||||
n.d = MATERIAL_LIGHT;
|
n.d = CONTENT_LIGHT;
|
||||||
sector->setNode(p, n);
|
sector->setNode(p, n);
|
||||||
objects_to_remove.push_back(p);
|
objects_to_remove.push_back(p);
|
||||||
}
|
}
|
||||||
@ -1991,13 +2099,13 @@ MapBlock * ServerMap::emergeBlock(
|
|||||||
&changed_blocks_sector))
|
&changed_blocks_sector))
|
||||||
{
|
{
|
||||||
MapNode n;
|
MapNode n;
|
||||||
n.d = MATERIAL_TREE;
|
n.d = CONTENT_TREE;
|
||||||
sector->setNode(p+v3s16(0,0,0), n);
|
sector->setNode(p+v3s16(0,0,0), n);
|
||||||
sector->setNode(p+v3s16(0,1,0), n);
|
sector->setNode(p+v3s16(0,1,0), n);
|
||||||
sector->setNode(p+v3s16(0,2,0), n);
|
sector->setNode(p+v3s16(0,2,0), n);
|
||||||
sector->setNode(p+v3s16(0,3,0), n);
|
sector->setNode(p+v3s16(0,3,0), n);
|
||||||
|
|
||||||
n.d = MATERIAL_LEAVES;
|
n.d = CONTENT_LEAVES;
|
||||||
|
|
||||||
sector->setNode(p+v3s16(0,4,0), n);
|
sector->setNode(p+v3s16(0,4,0), n);
|
||||||
|
|
||||||
@ -2032,7 +2140,7 @@ MapBlock * ServerMap::emergeBlock(
|
|||||||
p + v3s16(0,0,0), &changed_blocks_sector))
|
p + v3s16(0,0,0), &changed_blocks_sector))
|
||||||
{
|
{
|
||||||
MapNode n;
|
MapNode n;
|
||||||
n.d = MATERIAL_LEAVES;
|
n.d = CONTENT_LEAVES;
|
||||||
sector->setNode(p+v3s16(0,0,0), n);
|
sector->setNode(p+v3s16(0,0,0), n);
|
||||||
|
|
||||||
objects_to_remove.push_back(p);
|
objects_to_remove.push_back(p);
|
||||||
@ -2047,9 +2155,9 @@ MapBlock * ServerMap::emergeBlock(
|
|||||||
&changed_blocks_sector))
|
&changed_blocks_sector))
|
||||||
{
|
{
|
||||||
MapNode n;
|
MapNode n;
|
||||||
n.d = MATERIAL_STONE;
|
n.d = CONTENT_STONE;
|
||||||
MapNode n2;
|
MapNode n2;
|
||||||
n2.d = MATERIAL_AIR;
|
n2.d = CONTENT_AIR;
|
||||||
s16 depth = maxdepth + (rand()%10);
|
s16 depth = maxdepth + (rand()%10);
|
||||||
s16 z = 0;
|
s16 z = 0;
|
||||||
s16 minz = -6 - (-2);
|
s16 minz = -6 - (-2);
|
||||||
@ -2067,22 +2175,22 @@ MapBlock * ServerMap::emergeBlock(
|
|||||||
<<std::endl;*/
|
<<std::endl;*/
|
||||||
{
|
{
|
||||||
v3s16 p2 = p + v3s16(x,y,z-2);
|
v3s16 p2 = p + v3s16(x,y,z-2);
|
||||||
if(is_ground_material(sector->getNode(p2).d))
|
if(is_ground_content(sector->getNode(p2).d))
|
||||||
sector->setNode(p2, n);
|
sector->setNode(p2, n);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
v3s16 p2 = p + v3s16(x,y,z-1);
|
v3s16 p2 = p + v3s16(x,y,z-1);
|
||||||
if(is_ground_material(sector->getNode(p2).d))
|
if(is_ground_content(sector->getNode(p2).d))
|
||||||
sector->setNode(p2, n2);
|
sector->setNode(p2, n2);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
v3s16 p2 = p + v3s16(x,y,z+0);
|
v3s16 p2 = p + v3s16(x,y,z+0);
|
||||||
if(is_ground_material(sector->getNode(p2).d))
|
if(is_ground_content(sector->getNode(p2).d))
|
||||||
sector->setNode(p2, n2);
|
sector->setNode(p2, n2);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
v3s16 p2 = p + v3s16(x,y,z+1);
|
v3s16 p2 = p + v3s16(x,y,z+1);
|
||||||
if(is_ground_material(sector->getNode(p2).d))
|
if(is_ground_content(sector->getNode(p2).d))
|
||||||
sector->setNode(p2, n);
|
sector->setNode(p2, n);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3100,7 +3208,7 @@ void ClientMap::updateMesh()
|
|||||||
/*dstream<<"mesh_old refcount="<<mesh_old->getReferenceCount()
|
/*dstream<<"mesh_old refcount="<<mesh_old->getReferenceCount()
|
||||||
<<std::endl;
|
<<std::endl;
|
||||||
scene::IMeshBuffer *buf = mesh_new->getMeshBuffer
|
scene::IMeshBuffer *buf = mesh_new->getMeshBuffer
|
||||||
(g_materials[MATERIAL_GRASS]);
|
(g_materials[CONTENT_GRASS]);
|
||||||
if(buf != NULL)
|
if(buf != NULL)
|
||||||
dstream<<"grass buf refcount="<<buf->getReferenceCount()
|
dstream<<"grass buf refcount="<<buf->getReferenceCount()
|
||||||
<<std::endl;*/
|
<<std::endl;*/
|
||||||
|
157
src/mapblock.cpp
157
src/mapblock.cpp
@ -111,7 +111,7 @@ FastFace * MapBlock::makeFastFace(u8 material, u8 light, v3f p,
|
|||||||
|
|
||||||
u8 alpha = 255;
|
u8 alpha = 255;
|
||||||
|
|
||||||
if(material == MATERIAL_WATER || material == MATERIAL_OCEAN)
|
if(material == CONTENT_WATER || material == CONTENT_OCEAN)
|
||||||
{
|
{
|
||||||
alpha = 128;
|
alpha = 128;
|
||||||
}
|
}
|
||||||
@ -152,7 +152,11 @@ u8 MapBlock::getFaceLight(v3s16 p, v3s16 face_dir)
|
|||||||
MapNode n = getNodeParent(p);
|
MapNode n = getNodeParent(p);
|
||||||
MapNode n2 = getNodeParent(p + face_dir);
|
MapNode n2 = getNodeParent(p + face_dir);
|
||||||
u8 light;
|
u8 light;
|
||||||
if(n.solidness() < n2.solidness())
|
/*if(n.solidness() < n2.solidness())
|
||||||
|
light = n.getLight();
|
||||||
|
else
|
||||||
|
light = n2.getLight();*/
|
||||||
|
if(n.getLight() > n2.getLight())
|
||||||
light = n.getLight();
|
light = n.getLight();
|
||||||
else
|
else
|
||||||
light = n2.getLight();
|
light = n2.getLight();
|
||||||
@ -173,18 +177,18 @@ u8 MapBlock::getFaceLight(v3s16 p, v3s16 face_dir)
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
Gets node material from any place relative to block.
|
Gets node material from any place relative to block.
|
||||||
Returns MATERIAL_IGNORE if doesn't exist or should not be drawn.
|
Returns CONTENT_IGNORE if doesn't exist or should not be drawn.
|
||||||
*/
|
*/
|
||||||
u8 MapBlock::getNodeMaterial(v3s16 p)
|
u8 MapBlock::getNodeTile(v3s16 p)
|
||||||
{
|
{
|
||||||
try{
|
try{
|
||||||
MapNode n = getNodeParent(p);
|
MapNode n = getNodeParent(p);
|
||||||
|
|
||||||
return content_cube_material(n.d);
|
return content_tile(n.d);
|
||||||
}
|
}
|
||||||
catch(InvalidPositionException &e)
|
catch(InvalidPositionException &e)
|
||||||
{
|
{
|
||||||
return MATERIAL_IGNORE;
|
return CONTENT_IGNORE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -216,82 +220,82 @@ void MapBlock::updateFastFaceRow(v3s16 startpos,
|
|||||||
*/
|
*/
|
||||||
u8 light = getFaceLight(p, face_dir);
|
u8 light = getFaceLight(p, face_dir);
|
||||||
|
|
||||||
u16 continuous_materials_count = 0;
|
u16 continuous_tiles_count = 0;
|
||||||
|
|
||||||
u8 material0 = getNodeMaterial(p);
|
u8 tile0 = getNodeTile(p);
|
||||||
u8 material1 = getNodeMaterial(p + face_dir);
|
u8 tile1 = getNodeTile(p + face_dir);
|
||||||
|
|
||||||
for(u16 j=0; j<length; j++)
|
for(u16 j=0; j<length; j++)
|
||||||
{
|
{
|
||||||
bool next_is_different = true;
|
bool next_is_different = true;
|
||||||
|
|
||||||
v3s16 p_next;
|
v3s16 p_next;
|
||||||
u8 material0_next = 0;
|
u8 tile0_next = 0;
|
||||||
u8 material1_next = 0;
|
u8 tile1_next = 0;
|
||||||
u8 light_next = 0;
|
u8 light_next = 0;
|
||||||
|
|
||||||
if(j != length - 1){
|
if(j != length - 1){
|
||||||
p_next = p + translate_dir;
|
p_next = p + translate_dir;
|
||||||
material0_next = getNodeMaterial(p_next);
|
tile0_next = getNodeTile(p_next);
|
||||||
material1_next = getNodeMaterial(p_next + face_dir);
|
tile1_next = getNodeTile(p_next + face_dir);
|
||||||
light_next = getFaceLight(p_next, face_dir);
|
light_next = getFaceLight(p_next, face_dir);
|
||||||
|
|
||||||
if(material0_next == material0
|
if(tile0_next == tile0
|
||||||
&& material1_next == material1
|
&& tile1_next == tile1
|
||||||
&& light_next == light)
|
&& light_next == light)
|
||||||
{
|
{
|
||||||
next_is_different = false;
|
next_is_different = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
continuous_materials_count++;
|
continuous_tiles_count++;
|
||||||
|
|
||||||
if(next_is_different)
|
if(next_is_different)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
Create a face if there should be one
|
Create a face if there should be one
|
||||||
*/
|
*/
|
||||||
u8 mf = face_materials(material0, material1);
|
u8 mf = face_contents(tile0, tile1);
|
||||||
|
|
||||||
if(mf != 0)
|
if(mf != 0)
|
||||||
{
|
{
|
||||||
// Floating point conversion of the position vector
|
// Floating point conversion of the position vector
|
||||||
v3f pf(p.X, p.Y, p.Z);
|
v3f pf(p.X, p.Y, p.Z);
|
||||||
// Center point of face (kind of)
|
// Center point of face (kind of)
|
||||||
v3f sp = pf - ((f32)continuous_materials_count / 2. - 0.5) * translate_dir_f;
|
v3f sp = pf - ((f32)continuous_tiles_count / 2. - 0.5) * translate_dir_f;
|
||||||
v3f scale(1,1,1);
|
v3f scale(1,1,1);
|
||||||
if(translate_dir.X != 0){
|
if(translate_dir.X != 0){
|
||||||
scale.X = continuous_materials_count;
|
scale.X = continuous_tiles_count;
|
||||||
}
|
}
|
||||||
if(translate_dir.Y != 0){
|
if(translate_dir.Y != 0){
|
||||||
scale.Y = continuous_materials_count;
|
scale.Y = continuous_tiles_count;
|
||||||
}
|
}
|
||||||
if(translate_dir.Z != 0){
|
if(translate_dir.Z != 0){
|
||||||
scale.Z = continuous_materials_count;
|
scale.Z = continuous_tiles_count;
|
||||||
}
|
}
|
||||||
|
|
||||||
FastFace *f;
|
FastFace *f;
|
||||||
|
|
||||||
// If node at sp (material0) is more solid
|
// If node at sp (tile0) is more solid
|
||||||
if(mf == 1)
|
if(mf == 1)
|
||||||
{
|
{
|
||||||
f = makeFastFace(material0, light,
|
f = makeFastFace(tile0, light,
|
||||||
sp, face_dir_f, scale,
|
sp, face_dir_f, scale,
|
||||||
posRelative_f);
|
posRelative_f);
|
||||||
}
|
}
|
||||||
// If node at sp is less solid (mf == 2)
|
// If node at sp is less solid (mf == 2)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
f = makeFastFace(material1, light,
|
f = makeFastFace(tile1, light,
|
||||||
sp+face_dir_f, -1*face_dir_f, scale,
|
sp+face_dir_f, -1*face_dir_f, scale,
|
||||||
posRelative_f);
|
posRelative_f);
|
||||||
}
|
}
|
||||||
dest.push_back(f);
|
dest.push_back(f);
|
||||||
}
|
}
|
||||||
|
|
||||||
continuous_materials_count = 0;
|
continuous_tiles_count = 0;
|
||||||
material0 = material0_next;
|
tile0 = tile0_next;
|
||||||
material1 = material1_next;
|
tile1 = tile1_next;
|
||||||
light = light_next;
|
light = light_next;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -451,6 +455,8 @@ void MapBlock::updateMesh()
|
|||||||
|
|
||||||
scene::SMesh *mesh_new = NULL;
|
scene::SMesh *mesh_new = NULL;
|
||||||
|
|
||||||
|
mesh_new = new scene::SMesh();
|
||||||
|
|
||||||
if(fastfaces_new->getSize() > 0)
|
if(fastfaces_new->getSize() > 0)
|
||||||
{
|
{
|
||||||
MeshCollector collector;
|
MeshCollector collector;
|
||||||
@ -467,8 +473,6 @@ void MapBlock::updateMesh()
|
|||||||
indices, 6);
|
indices, 6);
|
||||||
}
|
}
|
||||||
|
|
||||||
mesh_new = new scene::SMesh();
|
|
||||||
|
|
||||||
collector.fillMesh(mesh_new);
|
collector.fillMesh(mesh_new);
|
||||||
|
|
||||||
// Use VBO for mesh (this just would set this for ever buffer)
|
// Use VBO for mesh (this just would set this for ever buffer)
|
||||||
@ -495,13 +499,103 @@ void MapBlock::updateMesh()
|
|||||||
/*
|
/*
|
||||||
Add special graphics:
|
Add special graphics:
|
||||||
- torches
|
- torches
|
||||||
|
|
||||||
|
TODO: Optimize by using same meshbuffer for same textures
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/*scene::ISceneManager *smgr = NULL;
|
||||||
|
video::IVideoDriver* driver = NULL;
|
||||||
|
if(g_device)
|
||||||
|
{
|
||||||
|
smgr = g_device->getSceneManager();
|
||||||
|
driver = smgr->getVideoDriver();
|
||||||
|
}*/
|
||||||
|
|
||||||
for(s16 z=0; z<MAP_BLOCKSIZE; z++)
|
for(s16 z=0; z<MAP_BLOCKSIZE; z++)
|
||||||
for(s16 y=0; y<MAP_BLOCKSIZE; y++)
|
for(s16 y=0; y<MAP_BLOCKSIZE; y++)
|
||||||
for(s16 x=0; x<MAP_BLOCKSIZE; x++)
|
for(s16 x=0; x<MAP_BLOCKSIZE; x++)
|
||||||
{
|
{
|
||||||
v3s16 p(x,y,z);
|
v3s16 p(x,y,z);
|
||||||
|
|
||||||
|
MapNode &n = getNodeRef(x,y,z);
|
||||||
|
|
||||||
|
if(n.d == CONTENT_LIGHT)
|
||||||
|
{
|
||||||
|
//scene::IMeshBuffer *buf = new scene::SMeshBuffer();
|
||||||
|
scene::SMeshBuffer *buf = new scene::SMeshBuffer();
|
||||||
|
video::SColor c(255,255,255,255);
|
||||||
|
|
||||||
|
video::S3DVertex vertices[4] =
|
||||||
|
{
|
||||||
|
video::S3DVertex(-BS/2,-BS/2,0, 0,0,0, c, 0,1),
|
||||||
|
video::S3DVertex(BS/2,-BS/2,0, 0,0,0, c, 1,1),
|
||||||
|
video::S3DVertex(BS/2,BS/2,0, 0,0,0, c, 1,0),
|
||||||
|
video::S3DVertex(-BS/2,BS/2,0, 0,0,0, c, 0,0),
|
||||||
|
};
|
||||||
|
|
||||||
|
v3s16 dir = unpackDir(n.dir);
|
||||||
|
|
||||||
|
for(s32 i=0; i<4; i++)
|
||||||
|
{
|
||||||
|
if(dir == v3s16(1,0,0))
|
||||||
|
vertices[i].Pos.rotateXZBy(0);
|
||||||
|
if(dir == v3s16(-1,0,0))
|
||||||
|
vertices[i].Pos.rotateXZBy(180);
|
||||||
|
if(dir == v3s16(0,0,1))
|
||||||
|
vertices[i].Pos.rotateXZBy(90);
|
||||||
|
if(dir == v3s16(0,0,-1))
|
||||||
|
vertices[i].Pos.rotateXZBy(-90);
|
||||||
|
if(dir == v3s16(0,-1,0))
|
||||||
|
vertices[i].Pos.rotateXZBy(45);
|
||||||
|
if(dir == v3s16(0,1,0))
|
||||||
|
vertices[i].Pos.rotateXZBy(-45);
|
||||||
|
|
||||||
|
vertices[i].Pos += intToFloat(p + getPosRelative());
|
||||||
|
}
|
||||||
|
|
||||||
|
u16 indices[] = {0,1,2,2,3,0};
|
||||||
|
buf->append(vertices, 4, indices, 6);
|
||||||
|
|
||||||
|
// Set material
|
||||||
|
buf->getMaterial().setFlag(video::EMF_LIGHTING, false);
|
||||||
|
buf->getMaterial().setFlag(video::EMF_BACK_FACE_CULLING, false);
|
||||||
|
buf->getMaterial().setFlag(video::EMF_BILINEAR_FILTER, false);
|
||||||
|
//buf->getMaterial().MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL;
|
||||||
|
buf->getMaterial().MaterialType
|
||||||
|
= video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF;
|
||||||
|
if(dir == v3s16(0,-1,0))
|
||||||
|
buf->getMaterial().setTexture(0,
|
||||||
|
g_texturecache.get("torch_on_floor"));
|
||||||
|
else if(dir == v3s16(0,1,0))
|
||||||
|
buf->getMaterial().setTexture(0,
|
||||||
|
g_texturecache.get("torch_on_ceiling"));
|
||||||
|
// For backwards compatibility
|
||||||
|
else if(dir == v3s16(0,0,0))
|
||||||
|
buf->getMaterial().setTexture(0,
|
||||||
|
g_texturecache.get("torch_on_floor"));
|
||||||
|
else
|
||||||
|
buf->getMaterial().setTexture(0, g_texturecache.get("torch"));
|
||||||
|
|
||||||
|
// Add to mesh
|
||||||
|
mesh_new->addMeshBuffer(buf);
|
||||||
|
buf->drop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Do some stuff to the mesh
|
||||||
|
*/
|
||||||
|
|
||||||
|
mesh_new->recalculateBoundingBox();
|
||||||
|
|
||||||
|
/*
|
||||||
|
Delete new mesh if it is empty
|
||||||
|
*/
|
||||||
|
|
||||||
|
if(mesh_new->getMeshBufferCount() == 0)
|
||||||
|
{
|
||||||
|
mesh_new->drop();
|
||||||
|
mesh_new = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -681,6 +775,11 @@ void MapBlock::copyTo(VoxelManipulator &dst)
|
|||||||
getPosRelative(), data_size);
|
getPosRelative(), data_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*void getPseudoObjects(v3f origin, f32 max_d,
|
||||||
|
core::array<DistanceSortedObject> &dest)
|
||||||
|
{
|
||||||
|
}*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Serialization
|
Serialization
|
||||||
*/
|
*/
|
||||||
|
@ -288,11 +288,7 @@ public:
|
|||||||
|
|
||||||
u8 getFaceLight(v3s16 p, v3s16 face_dir);
|
u8 getFaceLight(v3s16 p, v3s16 face_dir);
|
||||||
|
|
||||||
/*
|
u8 getNodeTile(v3s16 p);
|
||||||
Gets node material from any place relative to block.
|
|
||||||
Returns MATERIAL_AIR if doesn't exist.
|
|
||||||
*/
|
|
||||||
u8 getNodeMaterial(v3s16 p);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
startpos:
|
startpos:
|
||||||
@ -376,6 +372,9 @@ public:
|
|||||||
m_objects.getObjects(origin, max_d, dest);
|
m_objects.getObjects(origin, max_d, dest);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*void getPseudoObjects(v3f origin, f32 max_d,
|
||||||
|
core::array<DistanceSortedObject> &dest);*/
|
||||||
|
|
||||||
s32 getObjectCount()
|
s32 getObjectCount()
|
||||||
{
|
{
|
||||||
return m_objects.getCount();
|
return m_objects.getCount();
|
||||||
|
@ -145,7 +145,7 @@ void MovingObject::move(float dtime, v3f acceleration)
|
|||||||
for(s16 x = oldpos_i.X - 1; x <= oldpos_i.X + 1; x++)
|
for(s16 x = oldpos_i.X - 1; x <= oldpos_i.X + 1; x++)
|
||||||
{
|
{
|
||||||
try{
|
try{
|
||||||
if(material_walkable(m_block->getNodeParent(v3s16(x,y,z)).d)
|
if(content_walkable(m_block->getNodeParent(v3s16(x,y,z)).d)
|
||||||
== false)
|
== false)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -28,13 +28,12 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||||||
#include "constants.h"
|
#include "constants.h"
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
|
|
||||||
enum
|
#define MAPBLOCKOBJECT_TYPE_TEST 0
|
||||||
{
|
#define MAPBLOCKOBJECT_TYPE_TEST2 1
|
||||||
MAPBLOCKOBJECT_TYPE_TEST=0,
|
#define MAPBLOCKOBJECT_TYPE_SIGN 2
|
||||||
MAPBLOCKOBJECT_TYPE_TEST2=1,
|
#define MAPBLOCKOBJECT_TYPE_RAT 3
|
||||||
MAPBLOCKOBJECT_TYPE_SIGN=2,
|
// Used for handling selecting special stuff
|
||||||
MAPBLOCKOBJECT_TYPE_RAT=3,
|
//#define MAPBLOCKOBJECT_TYPE_PSEUDO 4
|
||||||
};
|
|
||||||
|
|
||||||
class MapBlock;
|
class MapBlock;
|
||||||
|
|
||||||
@ -170,6 +169,57 @@ protected:
|
|||||||
friend class MapBlockObjectList;
|
friend class MapBlockObjectList;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
/*
|
||||||
|
Used for handling selections of special stuff
|
||||||
|
*/
|
||||||
|
class PseudoMBObject : public MapBlockObject
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// The constructor of every MapBlockObject should be like this
|
||||||
|
PseudoMBObject(MapBlock *block, s16 id, v3f pos):
|
||||||
|
MapBlockObject(block, id, pos)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
virtual ~PseudoMBObject()
|
||||||
|
{
|
||||||
|
if(m_selection_box)
|
||||||
|
delete m_selection_box;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Implementation interface
|
||||||
|
*/
|
||||||
|
virtual u16 getTypeId() const
|
||||||
|
{
|
||||||
|
return MAPBLOCKOBJECT_TYPE_PSEUDO;
|
||||||
|
}
|
||||||
|
virtual void serialize(std::ostream &os, u8 version)
|
||||||
|
{
|
||||||
|
assert(0);
|
||||||
|
}
|
||||||
|
virtual void update(std::istream &is, u8 version)
|
||||||
|
{
|
||||||
|
assert(0);
|
||||||
|
}
|
||||||
|
virtual bool serverStep(float dtime)
|
||||||
|
{
|
||||||
|
assert(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Special methods
|
||||||
|
*/
|
||||||
|
|
||||||
|
void setSelectionBox(core::aabbox3d<f32> box)
|
||||||
|
{
|
||||||
|
m_selection_box = new core::aabbox3d<f32>(box);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
class TestObject : public MapBlockObject
|
class TestObject : public MapBlockObject
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
207
src/mapnode.h
207
src/mapnode.h
@ -41,66 +41,68 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||||||
Doesn't create faces with anything and is considered being
|
Doesn't create faces with anything and is considered being
|
||||||
out-of-map in the game map.
|
out-of-map in the game map.
|
||||||
*/
|
*/
|
||||||
#define MATERIAL_IGNORE 255
|
#define CONTENT_IGNORE 255
|
||||||
#define MATERIAL_IGNORE_DEFAULT_PARAM 0
|
#define CONTENT_IGNORE_DEFAULT_PARAM 0
|
||||||
|
|
||||||
/*
|
/*
|
||||||
The common material through which the player can walk and which
|
The common material through which the player can walk and which
|
||||||
is transparent to light
|
is transparent to light
|
||||||
*/
|
*/
|
||||||
#define MATERIAL_AIR 254
|
#define CONTENT_AIR 254
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Materials-todo:
|
Suggested materials:
|
||||||
|
|
||||||
GRAVEL
|
GRAVEL
|
||||||
- Dynamics of gravel: if there is a drop of more than two
|
- Dynamics of gravel: if there is a drop of more than two
|
||||||
blocks on any side, it will drop in there. Is this doable?
|
blocks on any side, it will drop in there. Is this doable?
|
||||||
|
|
||||||
TODO: These should be named to "content" or something like that
|
New naming scheme:
|
||||||
|
- Material = irrlicht's Material class
|
||||||
|
- Content = (u8) content of a node
|
||||||
|
- Tile = (u16) Material ID at some side of a node
|
||||||
*/
|
*/
|
||||||
|
|
||||||
enum Material
|
enum Content
|
||||||
{
|
{
|
||||||
MATERIAL_STONE=0,
|
CONTENT_STONE=0,
|
||||||
|
|
||||||
MATERIAL_GRASS,
|
CONTENT_GRASS,
|
||||||
|
|
||||||
MATERIAL_WATER,
|
CONTENT_WATER,
|
||||||
|
|
||||||
MATERIAL_LIGHT,
|
CONTENT_LIGHT,
|
||||||
|
|
||||||
MATERIAL_TREE,
|
CONTENT_TREE,
|
||||||
|
|
||||||
MATERIAL_LEAVES,
|
CONTENT_LEAVES,
|
||||||
|
|
||||||
MATERIAL_GRASS_FOOTSTEPS,
|
CONTENT_GRASS_FOOTSTEPS,
|
||||||
|
|
||||||
MATERIAL_MESE,
|
CONTENT_MESE,
|
||||||
|
|
||||||
MATERIAL_MUD,
|
CONTENT_MUD,
|
||||||
|
|
||||||
MATERIAL_OCEAN,
|
CONTENT_OCEAN,
|
||||||
|
|
||||||
// This is set to the number of the actual values in this enum
|
// This is set to the number of the actual values in this enum
|
||||||
USEFUL_MATERIAL_COUNT
|
USEFUL_CONTENT_COUNT
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
If true, the material allows light propagation and brightness is stored
|
If true, the material allows light propagation and brightness is stored
|
||||||
in param.
|
in param.
|
||||||
*/
|
*/
|
||||||
inline bool light_propagates_material(u8 m)
|
inline bool light_propagates_content(u8 m)
|
||||||
{
|
{
|
||||||
return (m == MATERIAL_AIR || m == MATERIAL_LIGHT || m == MATERIAL_WATER || m == MATERIAL_OCEAN);
|
return (m == CONTENT_AIR || m == CONTENT_LIGHT || m == CONTENT_WATER || m == CONTENT_OCEAN);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
If true, the material allows lossless sunlight propagation.
|
If true, the material allows lossless sunlight propagation.
|
||||||
*/
|
*/
|
||||||
inline bool sunlight_propagates_material(u8 m)
|
inline bool sunlight_propagates_content(u8 m)
|
||||||
{
|
{
|
||||||
return (m == MATERIAL_AIR);
|
return (m == CONTENT_AIR || m == CONTENT_LIGHT);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -110,98 +112,157 @@ inline bool sunlight_propagates_material(u8 m)
|
|||||||
1: Transparent
|
1: Transparent
|
||||||
2: Opaque
|
2: Opaque
|
||||||
*/
|
*/
|
||||||
inline u8 material_solidness(u8 m)
|
inline u8 content_solidness(u8 m)
|
||||||
{
|
{
|
||||||
if(m == MATERIAL_AIR)
|
if(m == CONTENT_AIR)
|
||||||
return 0;
|
return 0;
|
||||||
if(m == MATERIAL_WATER || m == MATERIAL_OCEAN)
|
if(m == CONTENT_WATER || m == CONTENT_OCEAN)
|
||||||
return 1;
|
return 1;
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Objects collide with walkable materials
|
// Objects collide with walkable contents
|
||||||
inline bool material_walkable(u8 m)
|
inline bool content_walkable(u8 m)
|
||||||
{
|
{
|
||||||
return (m != MATERIAL_AIR && m != MATERIAL_WATER && m != MATERIAL_OCEAN && m != MATERIAL_LIGHT);
|
return (m != CONTENT_AIR && m != CONTENT_WATER && m != CONTENT_OCEAN && m != CONTENT_LIGHT);
|
||||||
}
|
}
|
||||||
|
|
||||||
// A liquid resists fast movement
|
// A liquid resists fast movement
|
||||||
inline bool material_liquid(u8 m)
|
inline bool content_liquid(u8 m)
|
||||||
{
|
{
|
||||||
return (m == MATERIAL_WATER || m == MATERIAL_OCEAN);
|
return (m == CONTENT_WATER || m == CONTENT_OCEAN);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pointable materials can be pointed to in the map
|
// Pointable contents can be pointed to in the map
|
||||||
inline bool material_pointable(u8 m)
|
inline bool content_pointable(u8 m)
|
||||||
{
|
{
|
||||||
return (m != MATERIAL_AIR && m != MATERIAL_WATER && m != MATERIAL_OCEAN);
|
return (m != CONTENT_AIR && m != CONTENT_WATER && m != CONTENT_OCEAN);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool material_diggable(u8 m)
|
inline bool content_diggable(u8 m)
|
||||||
{
|
{
|
||||||
return (m != MATERIAL_AIR && m != MATERIAL_WATER && m != MATERIAL_OCEAN);
|
return (m != CONTENT_AIR && m != CONTENT_WATER && m != CONTENT_OCEAN);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool material_buildable_to(u8 m)
|
inline bool content_buildable_to(u8 m)
|
||||||
{
|
{
|
||||||
return (m == MATERIAL_AIR || m == MATERIAL_WATER || m == MATERIAL_OCEAN);
|
return (m == CONTENT_AIR || m == CONTENT_WATER || m == CONTENT_OCEAN);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
As of now, input is a "material" and the output is a "material"
|
TODO: Make a mapper class for mapping every side of a content
|
||||||
|
to some tile.
|
||||||
|
This dumbily maps all sides of content to the tile of the same id.
|
||||||
*/
|
*/
|
||||||
inline u8 content_cube_material(u8 c)
|
inline u8 content_tile(u8 c)
|
||||||
{
|
{
|
||||||
if(c == MATERIAL_IGNORE || c == MATERIAL_LIGHT)
|
if(c == CONTENT_IGNORE || c == CONTENT_LIGHT)
|
||||||
return MATERIAL_AIR;
|
return CONTENT_AIR;
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Returns true for materials that form the base ground that
|
Returns true for contents that form the base ground that
|
||||||
follows the main heightmap
|
follows the main heightmap
|
||||||
*/
|
*/
|
||||||
inline bool is_ground_material(u8 m)
|
inline bool is_ground_content(u8 m)
|
||||||
{
|
{
|
||||||
return(
|
return(
|
||||||
m == MATERIAL_STONE ||
|
m == CONTENT_STONE ||
|
||||||
m == MATERIAL_GRASS ||
|
m == CONTENT_GRASS ||
|
||||||
m == MATERIAL_GRASS_FOOTSTEPS ||
|
m == CONTENT_GRASS_FOOTSTEPS ||
|
||||||
m == MATERIAL_MESE ||
|
m == CONTENT_MESE ||
|
||||||
m == MATERIAL_MUD
|
m == CONTENT_MUD
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Nodes make a face if materials differ and solidness differs.
|
Nodes make a face if contents differ and solidness differs.
|
||||||
Return value:
|
Return value:
|
||||||
0: No face
|
0: No face
|
||||||
1: Face uses m1's material
|
1: Face uses m1's content
|
||||||
2: Face uses m2's material
|
2: Face uses m2's content
|
||||||
*/
|
*/
|
||||||
inline u8 face_materials(u8 m1, u8 m2)
|
inline u8 face_contents(u8 m1, u8 m2)
|
||||||
{
|
{
|
||||||
if(m1 == MATERIAL_IGNORE || m2 == MATERIAL_IGNORE)
|
if(m1 == CONTENT_IGNORE || m2 == CONTENT_IGNORE)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
bool materials_differ = (m1 != m2);
|
bool contents_differ = (m1 != m2);
|
||||||
bool solidness_differs = (material_solidness(m1) != material_solidness(m2));
|
bool solidness_differs = (content_solidness(m1) != content_solidness(m2));
|
||||||
bool makes_face = materials_differ && solidness_differs;
|
bool makes_face = contents_differ && solidness_differs;
|
||||||
|
|
||||||
if(makes_face == false)
|
if(makes_face == false)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if(material_solidness(m1) > material_solidness(m2))
|
if(content_solidness(m1) > content_solidness(m2))
|
||||||
return 1;
|
return 1;
|
||||||
else
|
else
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline bool liquid_replaces_content(u8 c)
|
||||||
|
{
|
||||||
|
return (c == CONTENT_AIR || c == CONTENT_LIGHT);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
When placing a node, drection info is added to it if this is true
|
||||||
|
*/
|
||||||
|
inline bool content_directional(u8 c)
|
||||||
|
{
|
||||||
|
return (c == CONTENT_LIGHT);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Packs directions like (1,0,0), (1,-1,0)
|
||||||
|
*/
|
||||||
|
inline u8 packDir(v3s16 dir)
|
||||||
|
{
|
||||||
|
u8 b = 0;
|
||||||
|
|
||||||
|
if(dir.X > 0)
|
||||||
|
b |= (1<<0);
|
||||||
|
else if(dir.X < 0)
|
||||||
|
b |= (1<<1);
|
||||||
|
|
||||||
|
if(dir.Y > 0)
|
||||||
|
b |= (1<<2);
|
||||||
|
else if(dir.Y < 0)
|
||||||
|
b |= (1<<3);
|
||||||
|
|
||||||
|
if(dir.Z > 0)
|
||||||
|
b |= (1<<4);
|
||||||
|
else if(dir.Z < 0)
|
||||||
|
b |= (1<<5);
|
||||||
|
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
inline v3s16 unpackDir(u8 b)
|
||||||
|
{
|
||||||
|
v3s16 d(0,0,0);
|
||||||
|
|
||||||
|
if(b & (1<<0))
|
||||||
|
d.X = 1;
|
||||||
|
else if(b & (1<<1))
|
||||||
|
d.X = -1;
|
||||||
|
|
||||||
|
if(b & (1<<2))
|
||||||
|
d.Y = 1;
|
||||||
|
else if(b & (1<<3))
|
||||||
|
d.Y = -1;
|
||||||
|
|
||||||
|
if(b & (1<<4))
|
||||||
|
d.Z = 1;
|
||||||
|
else if(b & (1<<5))
|
||||||
|
d.Z = -1;
|
||||||
|
|
||||||
|
return d;
|
||||||
|
}
|
||||||
|
|
||||||
struct MapNode
|
struct MapNode
|
||||||
{
|
{
|
||||||
//TODO: block type to differ from material
|
// Content
|
||||||
// (e.g. grass edges or something)
|
|
||||||
// block type
|
|
||||||
u8 d;
|
u8 d;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -212,14 +273,26 @@ struct MapNode
|
|||||||
*/
|
*/
|
||||||
s8 param;
|
s8 param;
|
||||||
|
|
||||||
u8 pressure;
|
union
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
Pressure for liquids
|
||||||
|
*/
|
||||||
|
u8 pressure;
|
||||||
|
|
||||||
|
/*
|
||||||
|
Direction for torches and other stuff.
|
||||||
|
If possible, packed with packDir.
|
||||||
|
*/
|
||||||
|
u8 dir;
|
||||||
|
};
|
||||||
|
|
||||||
MapNode(const MapNode & n)
|
MapNode(const MapNode & n)
|
||||||
{
|
{
|
||||||
*this = n;
|
*this = n;
|
||||||
}
|
}
|
||||||
|
|
||||||
MapNode(u8 data=MATERIAL_AIR, u8 a_param=0, u8 a_pressure=0)
|
MapNode(u8 data=CONTENT_AIR, u8 a_param=0, u8 a_pressure=0)
|
||||||
{
|
{
|
||||||
d = data;
|
d = data;
|
||||||
param = a_param;
|
param = a_param;
|
||||||
@ -235,17 +308,17 @@ struct MapNode
|
|||||||
|
|
||||||
bool light_propagates()
|
bool light_propagates()
|
||||||
{
|
{
|
||||||
return light_propagates_material(d);
|
return light_propagates_content(d);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool sunlight_propagates()
|
bool sunlight_propagates()
|
||||||
{
|
{
|
||||||
return sunlight_propagates_material(d);
|
return sunlight_propagates_content(d);
|
||||||
}
|
}
|
||||||
|
|
||||||
u8 solidness()
|
u8 solidness()
|
||||||
{
|
{
|
||||||
return material_solidness(d);
|
return content_solidness(d);
|
||||||
}
|
}
|
||||||
|
|
||||||
u8 light_source()
|
u8 light_source()
|
||||||
@ -253,7 +326,7 @@ struct MapNode
|
|||||||
/*
|
/*
|
||||||
Note that a block that isn't light_propagates() can be a light source.
|
Note that a block that isn't light_propagates() can be a light source.
|
||||||
*/
|
*/
|
||||||
if(d == MATERIAL_LIGHT)
|
if(d == CONTENT_LIGHT)
|
||||||
return LIGHT_MAX;
|
return LIGHT_MAX;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -261,7 +334,7 @@ struct MapNode
|
|||||||
|
|
||||||
u8 getLight()
|
u8 getLight()
|
||||||
{
|
{
|
||||||
// Select the brightest of [light_source, transparent_light]
|
// Select the brightest of [light source, propagated light]
|
||||||
u8 light = 0;
|
u8 light = 0;
|
||||||
if(light_propagates())
|
if(light_propagates())
|
||||||
light = param & 0x0f;
|
light = param & 0x0f;
|
||||||
|
@ -72,12 +72,12 @@ void Player::move(f32 dtime, Map &map)
|
|||||||
if(in_water)
|
if(in_water)
|
||||||
{
|
{
|
||||||
v3s16 pp = floatToInt(position + v3f(0,0,0));
|
v3s16 pp = floatToInt(position + v3f(0,0,0));
|
||||||
in_water = material_liquid(map.getNode(pp).d);
|
in_water = content_liquid(map.getNode(pp).d);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
v3s16 pp = floatToInt(position + v3f(0,BS/2,0));
|
v3s16 pp = floatToInt(position + v3f(0,BS/2,0));
|
||||||
in_water = material_liquid(map.getNode(pp).d);
|
in_water = content_liquid(map.getNode(pp).d);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch(InvalidPositionException &e)
|
catch(InvalidPositionException &e)
|
||||||
@ -122,7 +122,7 @@ void Player::move(f32 dtime, Map &map)
|
|||||||
for(s16 z = oldpos_i.Z - 1; z <= oldpos_i.Z + 1; z++){
|
for(s16 z = oldpos_i.Z - 1; z <= oldpos_i.Z + 1; z++){
|
||||||
for(s16 x = oldpos_i.X - 1; x <= oldpos_i.X + 1; x++){
|
for(s16 x = oldpos_i.X - 1; x <= oldpos_i.X + 1; x++){
|
||||||
try{
|
try{
|
||||||
if(material_walkable(map.getNode(v3s16(x,y,z)).d) == false){
|
if(content_walkable(map.getNode(v3s16(x,y,z)).d) == false){
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
266
src/server.cpp
266
src/server.cpp
@ -95,6 +95,8 @@ void * EmergeThread::Thread()
|
|||||||
|
|
||||||
//derr_server<<"EmergeThread::Thread(): running"<<std::endl;
|
//derr_server<<"EmergeThread::Thread(): running"<<std::endl;
|
||||||
|
|
||||||
|
//TimeTaker timer("block emerge", g_device);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Try to emerge it from somewhere.
|
Try to emerge it from somewhere.
|
||||||
|
|
||||||
@ -185,39 +187,32 @@ void * EmergeThread::Thread()
|
|||||||
dout_server<<std::endl;
|
dout_server<<std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Update water pressure
|
||||||
|
*/
|
||||||
|
|
||||||
|
m_server->UpdateBlockWaterPressure(block, modified_blocks);
|
||||||
|
|
||||||
|
for(core::map<v3s16, MapBlock*>::Iterator i = changed_blocks.getIterator();
|
||||||
|
i.atEnd() == false; i++)
|
||||||
|
{
|
||||||
|
MapBlock *block = i.getNode()->getValue();
|
||||||
|
m_server->UpdateBlockWaterPressure(block, modified_blocks);
|
||||||
|
//v3s16 p = i.getNode()->getKey();
|
||||||
|
//m_server->UpdateBlockWaterPressure(p, modified_blocks);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Collect a list of blocks that have been modified in
|
Collect a list of blocks that have been modified in
|
||||||
addition to the fetched one.
|
addition to the fetched one.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// Add all the "changed blocks"
|
// Add all the "changed blocks" to modified_blocks
|
||||||
for(core::map<v3s16, MapBlock*>::Iterator i = changed_blocks.getIterator();
|
for(core::map<v3s16, MapBlock*>::Iterator i = changed_blocks.getIterator();
|
||||||
i.atEnd() == false; i++)
|
i.atEnd() == false; i++)
|
||||||
{
|
{
|
||||||
MapBlock *block = i.getNode()->getValue();
|
MapBlock *block = i.getNode()->getValue();
|
||||||
modified_blocks.insert(block->getPos(), block);
|
modified_blocks.insert(block->getPos(), block);
|
||||||
|
|
||||||
/*
|
|
||||||
Update water pressure.
|
|
||||||
This also adds suitable nodes to active_nodes.
|
|
||||||
*/
|
|
||||||
|
|
||||||
MapVoxelManipulator v(&map);
|
|
||||||
|
|
||||||
VoxelArea area(block->getPosRelative(),
|
|
||||||
block->getPosRelative() + v3s16(1,1,1)*(MAP_BLOCKSIZE-1));
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
v.updateAreaWaterPressure(area, m_server->m_flow_active_nodes);
|
|
||||||
}
|
|
||||||
catch(ProcessingLimitException &e)
|
|
||||||
{
|
|
||||||
dstream<<"Processing limit reached (1)"<<std::endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
v.blitBack(modified_blocks);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*dstream<<"lighting "<<lighting_invalidated_blocks.size()
|
/*dstream<<"lighting "<<lighting_invalidated_blocks.size()
|
||||||
@ -1017,9 +1012,11 @@ void Server::AsyncRunStep()
|
|||||||
|
|
||||||
{
|
{
|
||||||
|
|
||||||
JMutexAutoLock lock(m_env_mutex);
|
JMutexAutoLock envlock(m_env_mutex);
|
||||||
|
|
||||||
MapVoxelManipulator v(&m_env.getMap());
|
MapVoxelManipulator v(&m_env.getMap());
|
||||||
|
v.m_disable_water_climb =
|
||||||
|
g_settings.getBool("disable_water_climb");
|
||||||
|
|
||||||
v.flowWater(m_flow_active_nodes, 0, false, 50);
|
v.flowWater(m_flow_active_nodes, 0, false, 50);
|
||||||
|
|
||||||
@ -1039,7 +1036,7 @@ void Server::AsyncRunStep()
|
|||||||
MapBlock *block = i.getNode()->getValue();
|
MapBlock *block = i.getNode()->getValue();
|
||||||
modified_blocks.insert(block->getPos(), block);
|
modified_blocks.insert(block->getPos(), block);
|
||||||
}
|
}
|
||||||
}
|
} // envlock
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Set the modified blocks unsent for all the clients
|
Set the modified blocks unsent for all the clients
|
||||||
@ -1492,7 +1489,7 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
|
|||||||
// Get material at position
|
// Get material at position
|
||||||
material = m_env.getMap().getNode(p_under).d;
|
material = m_env.getMap().getNode(p_under).d;
|
||||||
// If it's not diggable, do nothing
|
// If it's not diggable, do nothing
|
||||||
if(material_diggable(material) == false)
|
if(content_diggable(material) == false)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -1539,6 +1536,8 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
|
|||||||
// This also adds it to m_flow_active_nodes if appropriate
|
// This also adds it to m_flow_active_nodes if appropriate
|
||||||
|
|
||||||
MapVoxelManipulator v(&m_env.getMap());
|
MapVoxelManipulator v(&m_env.getMap());
|
||||||
|
v.m_disable_water_climb =
|
||||||
|
g_settings.getBool("disable_water_climb");
|
||||||
|
|
||||||
VoxelArea area(p_under-v3s16(1,1,1), p_under+v3s16(1,1,1));
|
VoxelArea area(p_under-v3s16(1,1,1), p_under+v3s16(1,1,1));
|
||||||
|
|
||||||
@ -1575,15 +1574,10 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
|
|||||||
*/
|
*/
|
||||||
if(std::string("MaterialItem") == item->getName())
|
if(std::string("MaterialItem") == item->getName())
|
||||||
{
|
{
|
||||||
MaterialItem *mitem = (MaterialItem*)item;
|
|
||||||
|
|
||||||
MapNode n;
|
|
||||||
n.d = mitem->getMaterial();
|
|
||||||
|
|
||||||
try{
|
try{
|
||||||
// Don't add a node if this is not a free space
|
// Don't add a node if this is not a free space
|
||||||
MapNode n2 = m_env.getMap().getNode(p_over);
|
MapNode n2 = m_env.getMap().getNode(p_over);
|
||||||
if(material_buildable_to(n2.d) == false)
|
if(content_buildable_to(n2.d) == false)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
catch(InvalidPositionException &e)
|
catch(InvalidPositionException &e)
|
||||||
@ -1596,17 +1590,14 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
|
|||||||
// Reset build time counter
|
// Reset build time counter
|
||||||
getClient(peer->id)->m_time_from_building.set(0.0);
|
getClient(peer->id)->m_time_from_building.set(0.0);
|
||||||
|
|
||||||
if(g_settings.getBool("creative_mode") == false)
|
// Create node data
|
||||||
{
|
MaterialItem *mitem = (MaterialItem*)item;
|
||||||
// Remove from inventory and send inventory
|
MapNode n;
|
||||||
if(mitem->getCount() == 1)
|
n.d = mitem->getMaterial();
|
||||||
player->inventory.deleteItem(item_i);
|
if(content_directional(n.d))
|
||||||
else
|
n.dir = packDir(p_under - p_over);
|
||||||
mitem->remove(1);
|
|
||||||
// Send inventory
|
|
||||||
SendInventory(peer_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
#if 1
|
||||||
// Create packet
|
// Create packet
|
||||||
u32 replysize = 8 + MapNode::serializedLength(peer_ser_ver);
|
u32 replysize = 8 + MapNode::serializedLength(peer_ser_ver);
|
||||||
SharedBuffer<u8> reply(replysize);
|
SharedBuffer<u8> reply(replysize);
|
||||||
@ -1618,6 +1609,20 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
|
|||||||
// Send as reliable
|
// Send as reliable
|
||||||
m_con.SendToAll(0, reply, true);
|
m_con.SendToAll(0, reply, true);
|
||||||
|
|
||||||
|
/*
|
||||||
|
Handle inventory
|
||||||
|
*/
|
||||||
|
if(g_settings.getBool("creative_mode") == false)
|
||||||
|
{
|
||||||
|
// Remove from inventory and send inventory
|
||||||
|
if(mitem->getCount() == 1)
|
||||||
|
player->inventory.deleteItem(item_i);
|
||||||
|
else
|
||||||
|
mitem->remove(1);
|
||||||
|
// Send inventory
|
||||||
|
SendInventory(peer_id);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Add node.
|
Add node.
|
||||||
|
|
||||||
@ -1625,6 +1630,49 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
|
|||||||
*/
|
*/
|
||||||
core::map<v3s16, MapBlock*> modified_blocks;
|
core::map<v3s16, MapBlock*> modified_blocks;
|
||||||
m_env.getMap().addNodeAndUpdate(p_over, n, modified_blocks);
|
m_env.getMap().addNodeAndUpdate(p_over, n, modified_blocks);
|
||||||
|
#endif
|
||||||
|
#if 0
|
||||||
|
/*
|
||||||
|
Handle inventory
|
||||||
|
*/
|
||||||
|
if(g_settings.getBool("creative_mode") == false)
|
||||||
|
{
|
||||||
|
// Remove from inventory and send inventory
|
||||||
|
if(mitem->getCount() == 1)
|
||||||
|
player->inventory.deleteItem(item_i);
|
||||||
|
else
|
||||||
|
mitem->remove(1);
|
||||||
|
// Send inventory
|
||||||
|
SendInventory(peer_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Add node.
|
||||||
|
|
||||||
|
This takes some time so it is done after the quick stuff
|
||||||
|
*/
|
||||||
|
core::map<v3s16, MapBlock*> modified_blocks;
|
||||||
|
m_env.getMap().addNodeAndUpdate(p_over, n, modified_blocks);
|
||||||
|
|
||||||
|
/*
|
||||||
|
Set the modified blocks unsent for all the clients
|
||||||
|
*/
|
||||||
|
|
||||||
|
//JMutexAutoLock lock2(m_con_mutex);
|
||||||
|
|
||||||
|
for(core::map<u16, RemoteClient*>::Iterator
|
||||||
|
i = m_clients.getIterator();
|
||||||
|
i.atEnd() == false; i++)
|
||||||
|
{
|
||||||
|
RemoteClient *client = i.getNode()->getValue();
|
||||||
|
|
||||||
|
if(modified_blocks.size() > 0)
|
||||||
|
{
|
||||||
|
// Remove block from sent history
|
||||||
|
client->SetBlocksNotSent(modified_blocks);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Update water
|
Update water
|
||||||
@ -1634,6 +1682,8 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
|
|||||||
// This also adds it to m_flow_active_nodes if appropriate
|
// This also adds it to m_flow_active_nodes if appropriate
|
||||||
|
|
||||||
MapVoxelManipulator v(&m_env.getMap());
|
MapVoxelManipulator v(&m_env.getMap());
|
||||||
|
v.m_disable_water_climb =
|
||||||
|
g_settings.getBool("disable_water_climb");
|
||||||
|
|
||||||
VoxelArea area(p_over-v3s16(1,1,1), p_over+v3s16(1,1,1));
|
VoxelArea area(p_over-v3s16(1,1,1), p_over+v3s16(1,1,1));
|
||||||
|
|
||||||
@ -1826,113 +1876,14 @@ void Server::SendBlockNoLock(u16 peer_id, MapBlock *block, u8 ver)
|
|||||||
writeS16(&reply[6], p.Z);
|
writeS16(&reply[6], p.Z);
|
||||||
memcpy(&reply[8], *blockdata, blockdata.getSize());
|
memcpy(&reply[8], *blockdata, blockdata.getSize());
|
||||||
|
|
||||||
|
//dstream<<"Sending block: packet size: "<<replysize<<std::endl;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Send packet
|
Send packet
|
||||||
*/
|
*/
|
||||||
m_con.Send(peer_id, 1, reply, true);
|
m_con.Send(peer_id, 1, reply, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*void Server::SendBlock(u16 peer_id, MapBlock *block, u8 ver)
|
|
||||||
{
|
|
||||||
JMutexAutoLock conlock(m_con_mutex);
|
|
||||||
|
|
||||||
SendBlockNoLock(peer_id, block, ver);
|
|
||||||
}*/
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
void Server::SendSectorMeta(u16 peer_id, core::list<v2s16> ps, u8 ver)
|
|
||||||
{
|
|
||||||
DSTACK(__FUNCTION_NAME);
|
|
||||||
dstream<<"Server sending sector meta of "
|
|
||||||
<<ps.getSize()<<" sectors"<<std::endl;
|
|
||||||
|
|
||||||
core::list<v2s16>::Iterator i = ps.begin();
|
|
||||||
core::list<v2s16> sendlist;
|
|
||||||
for(;;)
|
|
||||||
{
|
|
||||||
if(sendlist.size() == 255 || i == ps.end())
|
|
||||||
{
|
|
||||||
if(sendlist.size() == 0)
|
|
||||||
break;
|
|
||||||
/*
|
|
||||||
[0] u16 command
|
|
||||||
[2] u8 sector count
|
|
||||||
[3...] v2s16 pos + sector metadata
|
|
||||||
*/
|
|
||||||
std::ostringstream os(std::ios_base::binary);
|
|
||||||
u8 buf[4];
|
|
||||||
|
|
||||||
writeU16(buf, TOCLIENT_SECTORMETA);
|
|
||||||
os.write((char*)buf, 2);
|
|
||||||
|
|
||||||
writeU8(buf, sendlist.size());
|
|
||||||
os.write((char*)buf, 1);
|
|
||||||
|
|
||||||
for(core::list<v2s16>::Iterator
|
|
||||||
j = sendlist.begin();
|
|
||||||
j != sendlist.end(); j++)
|
|
||||||
{
|
|
||||||
// Write position
|
|
||||||
writeV2S16(buf, *j);
|
|
||||||
os.write((char*)buf, 4);
|
|
||||||
|
|
||||||
/*
|
|
||||||
Write ClientMapSector metadata
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
[0] u8 serialization version
|
|
||||||
[1] s16 corners[0]
|
|
||||||
[3] s16 corners[1]
|
|
||||||
[5] s16 corners[2]
|
|
||||||
[7] s16 corners[3]
|
|
||||||
size = 9
|
|
||||||
|
|
||||||
In which corners are in these positions
|
|
||||||
v2s16(0,0),
|
|
||||||
v2s16(1,0),
|
|
||||||
v2s16(1,1),
|
|
||||||
v2s16(0,1),
|
|
||||||
*/
|
|
||||||
|
|
||||||
// Write version
|
|
||||||
writeU8(buf, ver);
|
|
||||||
os.write((char*)buf, 1);
|
|
||||||
|
|
||||||
// Write corners
|
|
||||||
// TODO: Get real values
|
|
||||||
s16 corners[4];
|
|
||||||
((ServerMap&)m_env.getMap()).getSectorCorners(*j, corners);
|
|
||||||
|
|
||||||
writeS16(buf, corners[0]);
|
|
||||||
os.write((char*)buf, 2);
|
|
||||||
writeS16(buf, corners[1]);
|
|
||||||
os.write((char*)buf, 2);
|
|
||||||
writeS16(buf, corners[2]);
|
|
||||||
os.write((char*)buf, 2);
|
|
||||||
writeS16(buf, corners[3]);
|
|
||||||
os.write((char*)buf, 2);
|
|
||||||
}
|
|
||||||
|
|
||||||
SharedBuffer<u8> data((u8*)os.str().c_str(), os.str().size());
|
|
||||||
|
|
||||||
/*dstream<<"Server::SendSectorMeta(): sending packet"
|
|
||||||
" with "<<sendlist.size()<<" sectors"<<std::endl;*/
|
|
||||||
|
|
||||||
m_con.Send(peer_id, 1, data, true);
|
|
||||||
|
|
||||||
if(i == ps.end())
|
|
||||||
break;
|
|
||||||
|
|
||||||
sendlist.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
sendlist.push_back(*i);
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
core::list<PlayerInfo> Server::getPlayerInfo()
|
core::list<PlayerInfo> Server::getPlayerInfo()
|
||||||
{
|
{
|
||||||
DSTACK(__FUNCTION_NAME);
|
DSTACK(__FUNCTION_NAME);
|
||||||
@ -2039,11 +1990,11 @@ void Server::peerAdded(con::Peer *peer)
|
|||||||
if(g_settings.getBool("creative_mode"))
|
if(g_settings.getBool("creative_mode"))
|
||||||
{
|
{
|
||||||
// Give all materials
|
// Give all materials
|
||||||
assert(USEFUL_MATERIAL_COUNT <= PLAYER_INVENTORY_SIZE);
|
assert(USEFUL_CONTENT_COUNT <= PLAYER_INVENTORY_SIZE);
|
||||||
for(u16 i=0; i<USEFUL_MATERIAL_COUNT; i++)
|
for(u16 i=0; i<USEFUL_CONTENT_COUNT; i++)
|
||||||
{
|
{
|
||||||
// Skip some materials
|
// Skip some materials
|
||||||
if(i == MATERIAL_OCEAN)
|
if(i == CONTENT_OCEAN)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
InventoryItem *item = new MaterialItem(i, 1);
|
InventoryItem *item = new MaterialItem(i, 1);
|
||||||
@ -2272,4 +2223,27 @@ RemoteClient* Server::getClient(u16 peer_id)
|
|||||||
return n->getValue();
|
return n->getValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Server::UpdateBlockWaterPressure(MapBlock *block,
|
||||||
|
core::map<v3s16, MapBlock*> &modified_blocks)
|
||||||
|
{
|
||||||
|
MapVoxelManipulator v(&m_env.getMap());
|
||||||
|
v.m_disable_water_climb =
|
||||||
|
g_settings.getBool("disable_water_climb");
|
||||||
|
|
||||||
|
VoxelArea area(block->getPosRelative(),
|
||||||
|
block->getPosRelative() + v3s16(1,1,1)*(MAP_BLOCKSIZE-1));
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
v.updateAreaWaterPressure(area, m_flow_active_nodes);
|
||||||
|
}
|
||||||
|
catch(ProcessingLimitException &e)
|
||||||
|
{
|
||||||
|
dstream<<"Processing limit reached (1)"<<std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
v.blitBack(modified_blocks);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
12
src/server.h
12
src/server.h
@ -275,7 +275,7 @@ public:
|
|||||||
u8 pending_serialization_version;
|
u8 pending_serialization_version;
|
||||||
|
|
||||||
RemoteClient():
|
RemoteClient():
|
||||||
m_time_from_building(0.0)
|
m_time_from_building(9999)
|
||||||
//m_num_blocks_in_emerge_queue(0)
|
//m_num_blocks_in_emerge_queue(0)
|
||||||
{
|
{
|
||||||
peer_id = 0;
|
peer_id = 0;
|
||||||
@ -451,9 +451,17 @@ private:
|
|||||||
// When called, connection mutex should be locked
|
// When called, connection mutex should be locked
|
||||||
RemoteClient* getClient(u16 peer_id);
|
RemoteClient* getClient(u16 peer_id);
|
||||||
|
|
||||||
|
/*
|
||||||
|
Update water pressure.
|
||||||
|
This also adds suitable nodes to active_nodes.
|
||||||
|
|
||||||
|
environment has to be locked when calling.
|
||||||
|
*/
|
||||||
|
void UpdateBlockWaterPressure(MapBlock *block,
|
||||||
|
core::map<v3s16, MapBlock*> &modified_blocks);
|
||||||
|
|
||||||
// NOTE: If connection and environment are both to be locked,
|
// NOTE: If connection and environment are both to be locked,
|
||||||
// environment shall be locked first.
|
// environment shall be locked first.
|
||||||
|
|
||||||
JMutex m_env_mutex;
|
JMutex m_env_mutex;
|
||||||
Environment m_env;
|
Environment m_env;
|
||||||
|
|
||||||
|
32
src/test.cpp
32
src/test.cpp
@ -133,11 +133,11 @@ struct TestMapNode
|
|||||||
MapNode n;
|
MapNode n;
|
||||||
|
|
||||||
// Default values
|
// Default values
|
||||||
assert(n.d == MATERIAL_AIR);
|
assert(n.d == CONTENT_AIR);
|
||||||
assert(n.getLight() == 0);
|
assert(n.getLight() == 0);
|
||||||
|
|
||||||
// Transparency
|
// Transparency
|
||||||
n.d = MATERIAL_AIR;
|
n.d = CONTENT_AIR;
|
||||||
assert(n.light_propagates() == true);
|
assert(n.light_propagates() == true);
|
||||||
n.d = 0;
|
n.d = 0;
|
||||||
assert(n.light_propagates() == false);
|
assert(n.light_propagates() == false);
|
||||||
@ -243,11 +243,11 @@ struct TestVoxelManipulator
|
|||||||
MapNode n;
|
MapNode n;
|
||||||
//n.pressure = size.Y - y;
|
//n.pressure = size.Y - y;
|
||||||
if(*p == '#')
|
if(*p == '#')
|
||||||
n.d = MATERIAL_STONE;
|
n.d = CONTENT_STONE;
|
||||||
else if(*p == '.')
|
else if(*p == '.')
|
||||||
n.d = MATERIAL_WATER;
|
n.d = CONTENT_WATER;
|
||||||
else if(*p == ' ')
|
else if(*p == ' ')
|
||||||
n.d = MATERIAL_AIR;
|
n.d = CONTENT_AIR;
|
||||||
else
|
else
|
||||||
assert(0);
|
assert(0);
|
||||||
v.setNode(v3s16(x,y,z), n);
|
v.setNode(v3s16(x,y,z), n);
|
||||||
@ -262,8 +262,12 @@ struct TestVoxelManipulator
|
|||||||
v.print(dstream, VOXELPRINT_WATERPRESSURE);
|
v.print(dstream, VOXELPRINT_WATERPRESSURE);
|
||||||
|
|
||||||
s16 highest_y = -32768;
|
s16 highest_y = -32768;
|
||||||
assert(v.getWaterPressure(v3s16(7, 1, 1), highest_y, 0) == -1);
|
/*
|
||||||
assert(highest_y == 3);
|
NOTE: These are commented out because this behaviour is changed
|
||||||
|
all the time
|
||||||
|
*/
|
||||||
|
//assert(v.getWaterPressure(v3s16(7, 1, 1), highest_y, 0) == -1);
|
||||||
|
//assert(highest_y == 3);
|
||||||
/*assert(v.getWaterPressure(v3s16(7, 1, 1), highest_y, 0) == 3);
|
/*assert(v.getWaterPressure(v3s16(7, 1, 1), highest_y, 0) == 3);
|
||||||
//assert(highest_y == 3);*/
|
//assert(highest_y == 3);*/
|
||||||
|
|
||||||
@ -365,11 +369,11 @@ struct TestMapBlock
|
|||||||
assert(b.getChangedFlag() == false);
|
assert(b.getChangedFlag() == false);
|
||||||
|
|
||||||
// All nodes should have been set to
|
// All nodes should have been set to
|
||||||
// .d=MATERIAL_AIR and .getLight() = 0
|
// .d=CONTENT_AIR and .getLight() = 0
|
||||||
for(u16 z=0; z<MAP_BLOCKSIZE; z++)
|
for(u16 z=0; z<MAP_BLOCKSIZE; z++)
|
||||||
for(u16 y=0; y<MAP_BLOCKSIZE; y++)
|
for(u16 y=0; y<MAP_BLOCKSIZE; y++)
|
||||||
for(u16 x=0; x<MAP_BLOCKSIZE; x++){
|
for(u16 x=0; x<MAP_BLOCKSIZE; x++){
|
||||||
assert(b.getNode(v3s16(x,y,z)).d == MATERIAL_AIR);
|
assert(b.getNode(v3s16(x,y,z)).d == CONTENT_AIR);
|
||||||
assert(b.getNode(v3s16(x,y,z)).getLight() == 0);
|
assert(b.getNode(v3s16(x,y,z)).getLight() == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -385,7 +389,7 @@ struct TestMapBlock
|
|||||||
assert(b.isValidPositionParent(v3s16(0,0,0)) == true);
|
assert(b.isValidPositionParent(v3s16(0,0,0)) == true);
|
||||||
assert(b.isValidPositionParent(v3s16(MAP_BLOCKSIZE-1,MAP_BLOCKSIZE-1,MAP_BLOCKSIZE-1)) == true);
|
assert(b.isValidPositionParent(v3s16(MAP_BLOCKSIZE-1,MAP_BLOCKSIZE-1,MAP_BLOCKSIZE-1)) == true);
|
||||||
n = b.getNodeParent(v3s16(0,MAP_BLOCKSIZE-1,0));
|
n = b.getNodeParent(v3s16(0,MAP_BLOCKSIZE-1,0));
|
||||||
assert(n.d == MATERIAL_AIR);
|
assert(n.d == CONTENT_AIR);
|
||||||
|
|
||||||
// ...but outside the block they should be invalid
|
// ...but outside the block they should be invalid
|
||||||
assert(b.isValidPositionParent(v3s16(-121,2341,0)) == false);
|
assert(b.isValidPositionParent(v3s16(-121,2341,0)) == false);
|
||||||
@ -420,8 +424,8 @@ struct TestMapBlock
|
|||||||
n.d = 4;
|
n.d = 4;
|
||||||
b.setNode(p, n);
|
b.setNode(p, n);
|
||||||
assert(b.getNode(p).d == 4);
|
assert(b.getNode(p).d == 4);
|
||||||
assert(b.getNodeMaterial(p) == 4);
|
assert(b.getNodeTile(p) == 4);
|
||||||
assert(b.getNodeMaterial(v3s16(-1,-1,0)) == 5);
|
assert(b.getNodeTile(v3s16(-1,-1,0)) == 5);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
propagateSunlight()
|
propagateSunlight()
|
||||||
@ -442,7 +446,7 @@ struct TestMapBlock
|
|||||||
*/
|
*/
|
||||||
parent.position_valid = true;
|
parent.position_valid = true;
|
||||||
b.setIsUnderground(false);
|
b.setIsUnderground(false);
|
||||||
parent.node.d = MATERIAL_AIR;
|
parent.node.d = CONTENT_AIR;
|
||||||
parent.node.setLight(LIGHT_SUN);
|
parent.node.setLight(LIGHT_SUN);
|
||||||
core::map<v3s16, bool> light_sources;
|
core::map<v3s16, bool> light_sources;
|
||||||
// The bottom block is invalid, because we have a shadowing node
|
// The bottom block is invalid, because we have a shadowing node
|
||||||
@ -493,7 +497,7 @@ struct TestMapBlock
|
|||||||
for(u16 y=0; y<MAP_BLOCKSIZE; y++){
|
for(u16 y=0; y<MAP_BLOCKSIZE; y++){
|
||||||
for(u16 x=0; x<MAP_BLOCKSIZE; x++){
|
for(u16 x=0; x<MAP_BLOCKSIZE; x++){
|
||||||
MapNode n;
|
MapNode n;
|
||||||
n.d = MATERIAL_AIR;
|
n.d = CONTENT_AIR;
|
||||||
n.setLight(0);
|
n.setLight(0);
|
||||||
b.setNode(v3s16(x,y,z), n);
|
b.setNode(v3s16(x,y,z), n);
|
||||||
}
|
}
|
||||||
|
@ -32,6 +32,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
#include <jmutex.h>
|
||||||
|
#include <jmutexautolock.h>
|
||||||
|
|
||||||
extern const v3s16 g_26dirs[26];
|
extern const v3s16 g_26dirs[26];
|
||||||
|
|
||||||
@ -808,5 +810,45 @@ private:
|
|||||||
core::map<std::string, std::string> m_settings;
|
core::map<std::string, std::string> m_settings;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
A thread-safe texture cache.
|
||||||
|
|
||||||
|
This is used so that irrlicht doesn't get called from many threads
|
||||||
|
*/
|
||||||
|
|
||||||
|
class TextureCache
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
TextureCache()
|
||||||
|
{
|
||||||
|
m_mutex.Init();
|
||||||
|
assert(m_mutex.IsInitialized());
|
||||||
|
}
|
||||||
|
|
||||||
|
void set(std::string name, video::ITexture *texture)
|
||||||
|
{
|
||||||
|
JMutexAutoLock lock(m_mutex);
|
||||||
|
|
||||||
|
m_textures[name] = texture;
|
||||||
|
}
|
||||||
|
|
||||||
|
video::ITexture* get(std::string name)
|
||||||
|
{
|
||||||
|
JMutexAutoLock lock(m_mutex);
|
||||||
|
|
||||||
|
core::map<std::string, video::ITexture*>::Node *n;
|
||||||
|
n = m_textures.find(name);
|
||||||
|
|
||||||
|
if(n != NULL)
|
||||||
|
return n->getValue();
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
core::map<std::string, video::ITexture*> m_textures;
|
||||||
|
JMutex m_mutex;
|
||||||
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -41,6 +41,7 @@ VoxelManipulator::VoxelManipulator():
|
|||||||
m_data(NULL),
|
m_data(NULL),
|
||||||
m_flags(NULL)
|
m_flags(NULL)
|
||||||
{
|
{
|
||||||
|
m_disable_water_climb = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
VoxelManipulator::~VoxelManipulator()
|
VoxelManipulator::~VoxelManipulator()
|
||||||
@ -103,13 +104,13 @@ void VoxelManipulator::print(std::ostream &o, VoxelPrintMode mode)
|
|||||||
}
|
}
|
||||||
else if(mode == VOXELPRINT_WATERPRESSURE)
|
else if(mode == VOXELPRINT_WATERPRESSURE)
|
||||||
{
|
{
|
||||||
if(m == MATERIAL_WATER)
|
if(m == CONTENT_WATER)
|
||||||
{
|
{
|
||||||
c = 'w';
|
c = 'w';
|
||||||
if(pr <= 9)
|
if(pr <= 9)
|
||||||
c = pr + '0';
|
c = pr + '0';
|
||||||
}
|
}
|
||||||
else if(m == MATERIAL_AIR)
|
else if(liquid_replaces_content(m))
|
||||||
{
|
{
|
||||||
c = ' ';
|
c = ' ';
|
||||||
}
|
}
|
||||||
@ -249,7 +250,7 @@ void VoxelManipulator::interpolate(VoxelArea area)
|
|||||||
|
|
||||||
s16 total = 0;
|
s16 total = 0;
|
||||||
s16 airness = 0;
|
s16 airness = 0;
|
||||||
u8 m = MATERIAL_IGNORE;
|
u8 m = CONTENT_IGNORE;
|
||||||
|
|
||||||
for(s16 i=0; i<8; i++)
|
for(s16 i=0; i<8; i++)
|
||||||
//for(s16 i=0; i<26; i++)
|
//for(s16 i=0; i<26; i++)
|
||||||
@ -263,17 +264,17 @@ void VoxelManipulator::interpolate(VoxelArea area)
|
|||||||
|
|
||||||
MapNode &n = m_data[m_area.index(p2)];
|
MapNode &n = m_data[m_area.index(p2)];
|
||||||
|
|
||||||
airness += (n.d == MATERIAL_AIR) ? 1 : -1;
|
airness += (n.d == CONTENT_AIR) ? 1 : -1;
|
||||||
total++;
|
total++;
|
||||||
|
|
||||||
if(m == MATERIAL_IGNORE && n.d != MATERIAL_AIR)
|
if(m == CONTENT_IGNORE && n.d != CONTENT_AIR)
|
||||||
m = n.d;
|
m = n.d;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 1 if air, 0 if not
|
// 1 if air, 0 if not
|
||||||
buf[area.index(p)] = airness > -total/2 ? MATERIAL_AIR : m;
|
buf[area.index(p)] = airness > -total/2 ? CONTENT_AIR : m;
|
||||||
//buf[area.index(p)] = airness > -total ? MATERIAL_AIR : m;
|
//buf[area.index(p)] = airness > -total ? CONTENT_AIR : m;
|
||||||
//buf[area.index(p)] = airness >= -7 ? MATERIAL_AIR : m;
|
//buf[area.index(p)] = airness >= -7 ? CONTENT_AIR : m;
|
||||||
}
|
}
|
||||||
|
|
||||||
for(s32 z=area.MinEdge.Z; z<=area.MaxEdge.Z; z++)
|
for(s32 z=area.MinEdge.Z; z<=area.MaxEdge.Z; z++)
|
||||||
@ -366,13 +367,14 @@ int VoxelManipulator::getWaterPressure(v3s16 p, s16 &highest_y, int recur_count)
|
|||||||
continue;
|
continue;
|
||||||
MapNode &n = m_data[m_area.index(p2)];
|
MapNode &n = m_data[m_area.index(p2)];
|
||||||
// Ignore non-liquid nodes
|
// Ignore non-liquid nodes
|
||||||
if(material_liquid(n.d) == false)
|
if(content_liquid(n.d) == false)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
int pr;
|
int pr;
|
||||||
|
|
||||||
// If at ocean surface
|
// If at ocean surface
|
||||||
if(n.pressure == 1 && n.d == MATERIAL_OCEAN)
|
if(n.pressure == 1 && n.d == CONTENT_OCEAN)
|
||||||
|
//if(n.pressure == 1) // Causes glitches but is fast
|
||||||
{
|
{
|
||||||
pr = 1;
|
pr = 1;
|
||||||
}
|
}
|
||||||
@ -463,12 +465,15 @@ void VoxelManipulator::spreadWaterPressure(v3s16 p, int pr,
|
|||||||
NOTE: Do not remove anything from there. We cannot know
|
NOTE: Do not remove anything from there. We cannot know
|
||||||
here if some other neighbor of it causes flow.
|
here if some other neighbor of it causes flow.
|
||||||
*/
|
*/
|
||||||
if(n.d == MATERIAL_AIR)
|
if(liquid_replaces_content(n.d))
|
||||||
{
|
{
|
||||||
bool pressure_causes_flow = false;
|
bool pressure_causes_flow = false;
|
||||||
// If block is at top
|
// If empty block is at top
|
||||||
if(i == 0)
|
if(i == 0)
|
||||||
{
|
{
|
||||||
|
if(m_disable_water_climb)
|
||||||
|
continue;
|
||||||
|
|
||||||
//if(pr >= PRESERVE_WATER_VOLUME ? 3 : 2)
|
//if(pr >= PRESERVE_WATER_VOLUME ? 3 : 2)
|
||||||
if(pr >= 3)
|
if(pr >= 3)
|
||||||
pressure_causes_flow = true;
|
pressure_causes_flow = true;
|
||||||
@ -495,7 +500,7 @@ void VoxelManipulator::spreadWaterPressure(v3s16 p, int pr,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Ignore non-liquid nodes
|
// Ignore non-liquid nodes
|
||||||
if(material_liquid(n.d) == false)
|
if(content_liquid(n.d) == false)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
int pr2 = pr;
|
int pr2 = pr;
|
||||||
@ -512,6 +517,12 @@ void VoxelManipulator::spreadWaterPressure(v3s16 p, int pr,
|
|||||||
pr2++;
|
pr2++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*if(m_disable_water_climb)
|
||||||
|
{
|
||||||
|
if(pr2 > 3)
|
||||||
|
pr2 = 3;
|
||||||
|
}*/
|
||||||
|
|
||||||
// Ignore if correct pressure is already set and is not on
|
// Ignore if correct pressure is already set and is not on
|
||||||
// request_area.
|
// request_area.
|
||||||
// Thus, request_area can be used for updating as much
|
// Thus, request_area can be used for updating as much
|
||||||
@ -556,7 +567,7 @@ void VoxelManipulator::updateAreaWaterPressure(VoxelArea a,
|
|||||||
continue;
|
continue;
|
||||||
MapNode &n = m_data[m_area.index(p)];
|
MapNode &n = m_data[m_area.index(p)];
|
||||||
// Ignore non-liquid nodes
|
// Ignore non-liquid nodes
|
||||||
if(material_liquid(n.d) == false)
|
if(content_liquid(n.d) == false)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if(checked2_clear == false)
|
if(checked2_clear == false)
|
||||||
@ -654,14 +665,18 @@ bool VoxelManipulator::flowWater(v3s16 removed_pos,
|
|||||||
if(f & (VOXELFLAG_INEXISTENT | VOXELFLAG_CHECKED))
|
if(f & (VOXELFLAG_INEXISTENT | VOXELFLAG_CHECKED))
|
||||||
return false;
|
return false;
|
||||||
MapNode &n = m_data[m_area.index(removed_pos)];
|
MapNode &n = m_data[m_area.index(removed_pos)];
|
||||||
// Water can move only to air
|
// Ignore nodes to which the water can't go
|
||||||
if(n.d != MATERIAL_AIR)
|
if(liquid_replaces_content(n.d) == false)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
s32 i;
|
s32 i;
|
||||||
for(i=0; i<6; i++)
|
for(i=0; i<6; i++)
|
||||||
{
|
{
|
||||||
|
// Don't raise water from bottom
|
||||||
|
if(m_disable_water_climb && i == 5)
|
||||||
|
continue;
|
||||||
|
|
||||||
p = removed_pos + v3s16(s1*dirs[i].X, dirs[i].Y, s2*dirs[i].Z);
|
p = removed_pos + v3s16(s1*dirs[i].X, dirs[i].Y, s2*dirs[i].Z);
|
||||||
|
|
||||||
u8 f = m_flags[m_area.index(p)];
|
u8 f = m_flags[m_area.index(p)];
|
||||||
@ -670,7 +685,7 @@ bool VoxelManipulator::flowWater(v3s16 removed_pos,
|
|||||||
continue;
|
continue;
|
||||||
MapNode &n = m_data[m_area.index(p)];
|
MapNode &n = m_data[m_area.index(p)];
|
||||||
// Only liquid nodes can move
|
// Only liquid nodes can move
|
||||||
if(material_liquid(n.d) == false)
|
if(content_liquid(n.d) == false)
|
||||||
continue;
|
continue;
|
||||||
// If block is at top, select it always
|
// If block is at top, select it always
|
||||||
if(i == 0)
|
if(i == 0)
|
||||||
@ -704,7 +719,7 @@ bool VoxelManipulator::flowWater(v3s16 removed_pos,
|
|||||||
u8 m = m_data[m_area.index(p)].d;
|
u8 m = m_data[m_area.index(p)].d;
|
||||||
u8 f = m_flags[m_area.index(p)];
|
u8 f = m_flags[m_area.index(p)];
|
||||||
|
|
||||||
if(m == MATERIAL_OCEAN)
|
if(m == CONTENT_OCEAN)
|
||||||
from_ocean = true;
|
from_ocean = true;
|
||||||
|
|
||||||
// Move air bubble if not taking water from ocean
|
// Move air bubble if not taking water from ocean
|
||||||
@ -714,9 +729,23 @@ bool VoxelManipulator::flowWater(v3s16 removed_pos,
|
|||||||
m_flags[m_area.index(p)] = m_flags[m_area.index(removed_pos)];
|
m_flags[m_area.index(p)] = m_flags[m_area.index(removed_pos)];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
This has to be done to copy the brightness of a light source
|
||||||
|
correctly. Otherwise unspreadLight will fuck up when water
|
||||||
|
has replaced a light source.
|
||||||
|
*/
|
||||||
|
u8 light = m_data[m_area.index(removed_pos)].getLight();
|
||||||
|
|
||||||
m_data[m_area.index(removed_pos)].d = m;
|
m_data[m_area.index(removed_pos)].d = m;
|
||||||
m_flags[m_area.index(removed_pos)] = f;
|
m_flags[m_area.index(removed_pos)] = f;
|
||||||
|
|
||||||
|
m_data[m_area.index(removed_pos)].setLight(light);
|
||||||
|
|
||||||
|
/*// NOTE: HACK: This has to be set to LIGHT_MAX so that
|
||||||
|
// unspreadLight will clear all light that came from this node.
|
||||||
|
// Otherwise there will be weird bugs
|
||||||
|
m_data[m_area.index(removed_pos)].setLight(LIGHT_MAX);*/
|
||||||
|
|
||||||
// Mark removed_pos checked
|
// Mark removed_pos checked
|
||||||
m_flags[m_area.index(removed_pos)] |= VOXELFLAG_CHECKED;
|
m_flags[m_area.index(removed_pos)] |= VOXELFLAG_CHECKED;
|
||||||
|
|
||||||
@ -728,7 +757,7 @@ bool VoxelManipulator::flowWater(v3s16 removed_pos,
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
NOTE: This does not work as-is
|
NOTE: This does not work as-is
|
||||||
if(m == MATERIAL_OCEAN)
|
if(m == CONTENT_OCEAN)
|
||||||
{
|
{
|
||||||
// If block was raised to surface, increase pressure of
|
// If block was raised to surface, increase pressure of
|
||||||
// source node
|
// source node
|
||||||
@ -795,6 +824,10 @@ find_again:
|
|||||||
// They are checked in reverse order compared to the previous loop.
|
// They are checked in reverse order compared to the previous loop.
|
||||||
for(s32 i=5; i>=0; i--)
|
for(s32 i=5; i>=0; i--)
|
||||||
{
|
{
|
||||||
|
// Don't try to flow to top
|
||||||
|
if(m_disable_water_climb && i == 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
//v3s16 p = removed_pos + dirs[i];
|
//v3s16 p = removed_pos + dirs[i];
|
||||||
p = removed_pos + v3s16(s1*dirs[i].X, dirs[i].Y, s2*dirs[i].Z);
|
p = removed_pos + v3s16(s1*dirs[i].X, dirs[i].Y, s2*dirs[i].Z);
|
||||||
|
|
||||||
@ -804,7 +837,7 @@ find_again:
|
|||||||
continue;
|
continue;
|
||||||
MapNode &n = m_data[m_area.index(p)];
|
MapNode &n = m_data[m_area.index(p)];
|
||||||
// Water can only move to air
|
// Water can only move to air
|
||||||
if(n.d != MATERIAL_AIR)
|
if(liquid_replaces_content(n.d) == false)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// Flow water to node
|
// Flow water to node
|
||||||
|
@ -502,6 +502,12 @@ public:
|
|||||||
//TODO: Would these make any speed improvement?
|
//TODO: Would these make any speed improvement?
|
||||||
//bool m_pressure_route_valid;
|
//bool m_pressure_route_valid;
|
||||||
//v3s16 m_pressure_route_surface;
|
//v3s16 m_pressure_route_surface;
|
||||||
|
|
||||||
|
/*
|
||||||
|
Some settings
|
||||||
|
*/
|
||||||
|
bool m_disable_water_climb;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user