fine-tuning of map generator and server and stuff.
This commit is contained in:
parent
7068bc90af
commit
3891bc43e0
|
@ -61,10 +61,11 @@ void set_default_settings()
|
||||||
g_settings.setDefault("active_object_range", "2");
|
g_settings.setDefault("active_object_range", "2");
|
||||||
g_settings.setDefault("max_simultaneous_block_sends_per_client", "1");
|
g_settings.setDefault("max_simultaneous_block_sends_per_client", "1");
|
||||||
g_settings.setDefault("max_simultaneous_block_sends_server_total", "4");
|
g_settings.setDefault("max_simultaneous_block_sends_server_total", "4");
|
||||||
|
g_settings.setDefault("water_moves", "true");
|
||||||
g_settings.setDefault("disable_water_climb", "true");
|
g_settings.setDefault("disable_water_climb", "true");
|
||||||
g_settings.setDefault("endless_water", "true");
|
g_settings.setDefault("endless_water", "true");
|
||||||
g_settings.setDefault("max_block_send_distance", "5");
|
g_settings.setDefault("max_block_send_distance", "6");
|
||||||
g_settings.setDefault("max_block_generate_distance", "5");
|
g_settings.setDefault("max_block_generate_distance", "6");
|
||||||
g_settings.setDefault("time_send_interval", "20");
|
g_settings.setDefault("time_send_interval", "20");
|
||||||
g_settings.setDefault("time_speed", "96");
|
g_settings.setDefault("time_speed", "96");
|
||||||
g_settings.setDefault("server_unload_unused_sectors_timeout", "60");
|
g_settings.setDefault("server_unload_unused_sectors_timeout", "60");
|
||||||
|
|
|
@ -168,6 +168,8 @@ TODO: Check what goes wrong with caching map to disk (Kray)
|
||||||
TODO: When server sees that client is removing an inexistent block or
|
TODO: When server sees that client is removing an inexistent block or
|
||||||
adding a block to an existent position, resend the MapBlock.
|
adding a block to an existent position, resend the MapBlock.
|
||||||
|
|
||||||
|
TODO: Generate map from the area the client is looking at
|
||||||
|
|
||||||
Objects:
|
Objects:
|
||||||
|
|
||||||
TODO: Better handling of objects and mobs
|
TODO: Better handling of objects and mobs
|
||||||
|
@ -1409,10 +1411,11 @@ int main(int argc, char *argv[])
|
||||||
video::E_DRIVER_TYPE driverType;
|
video::E_DRIVER_TYPE driverType;
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
//driverType = video::EDT_DIRECT3D9; // Doesn't seem to work
|
//driverType = video::EDT_DIRECT3D9;
|
||||||
driverType = video::EDT_OPENGL;
|
driverType = video::EDT_OPENGL;
|
||||||
#else
|
#else
|
||||||
driverType = video::EDT_OPENGL;
|
driverType = video::EDT_OPENGL;
|
||||||
|
//driverType = video::EDT_BURNINGSVIDEO;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// create device and exit if creation failed
|
// create device and exit if creation failed
|
||||||
|
|
241
src/map.cpp
241
src/map.cpp
|
@ -1317,17 +1317,26 @@ ServerMap::ServerMap(std::string savedir, HMParams hmp, MapParams mp):
|
||||||
*/
|
*/
|
||||||
|
|
||||||
{
|
{
|
||||||
|
dstream<<"Generating map point attribute lists"<<std::endl;
|
||||||
|
|
||||||
PointAttributeList *list_baseheight = m_padb.getList("hm_baseheight");
|
PointAttributeList *list_baseheight = m_padb.getList("hm_baseheight");
|
||||||
PointAttributeList *list_randmax = m_padb.getList("hm_randmax");
|
PointAttributeList *list_randmax = m_padb.getList("hm_randmax");
|
||||||
PointAttributeList *list_randfactor = m_padb.getList("hm_randfactor");
|
PointAttributeList *list_randfactor = m_padb.getList("hm_randfactor");
|
||||||
PointAttributeList *list_plants_amount = m_padb.getList("plants_amount");
|
PointAttributeList *list_plants_amount = m_padb.getList("plants_amount");
|
||||||
PointAttributeList *list_caves_amount = m_padb.getList("caves_amount");
|
PointAttributeList *list_caves_amount = m_padb.getList("caves_amount");
|
||||||
|
|
||||||
|
/*
|
||||||
|
NOTE: BEWARE: Too big amount of these will make map generation
|
||||||
|
slow. Especially those that are read by every block emerge.
|
||||||
|
*/
|
||||||
|
|
||||||
for(u32 i=0; i<3000; i++)
|
for(u32 i=0; i<15000; i++)
|
||||||
{
|
{
|
||||||
u32 lim = MAP_GENERATION_LIMIT;
|
/*u32 lim = MAP_GENERATION_LIMIT;
|
||||||
if(i < 200)
|
if(i < 400)
|
||||||
lim = 1000;
|
lim = 2000;*/
|
||||||
|
|
||||||
|
u32 lim = 1000 + MAP_GENERATION_LIMIT * i / 15000;
|
||||||
|
|
||||||
v3s16 p(
|
v3s16 p(
|
||||||
-lim + myrand()%(lim*2),
|
-lim + myrand()%(lim*2),
|
||||||
|
@ -1356,6 +1365,24 @@ ServerMap::ServerMap(std::string savedir, HMParams hmp, MapParams mp):
|
||||||
plants_amount = 0.0;
|
plants_amount = 0.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
list_plants_amount->addPoint(p, Attribute(plants_amount));
|
||||||
|
}
|
||||||
|
|
||||||
|
for(u32 i=0; i<1000; i++)
|
||||||
|
{
|
||||||
|
/*u32 lim = MAP_GENERATION_LIMIT;
|
||||||
|
if(i < 400)
|
||||||
|
lim = 2000;*/
|
||||||
|
|
||||||
|
u32 lim = 500 + MAP_GENERATION_LIMIT * i / 1000;
|
||||||
|
|
||||||
|
v3s16 p(
|
||||||
|
-lim + myrand()%(lim*2),
|
||||||
|
0,
|
||||||
|
-lim + myrand()%(lim*2)
|
||||||
|
);
|
||||||
|
|
||||||
float caves_amount = 0;
|
float caves_amount = 0;
|
||||||
if(myrand()%5 == 0)
|
if(myrand()%5 == 0)
|
||||||
{
|
{
|
||||||
|
@ -1370,20 +1397,21 @@ ServerMap::ServerMap(std::string savedir, HMParams hmp, MapParams mp):
|
||||||
caves_amount = 0.05;
|
caves_amount = 0.05;
|
||||||
}
|
}
|
||||||
|
|
||||||
list_plants_amount->addPoint(p, Attribute(plants_amount));
|
|
||||||
list_caves_amount->addPoint(p, Attribute(caves_amount));
|
list_caves_amount->addPoint(p, Attribute(caves_amount));
|
||||||
}
|
}
|
||||||
#if 1
|
|
||||||
for(u32 i=0; i<3000; i++)
|
for(u32 i=0; i<5000; i++)
|
||||||
{
|
{
|
||||||
u32 lim = MAP_GENERATION_LIMIT;
|
/*u32 lim = MAP_GENERATION_LIMIT;
|
||||||
if(i < 100)
|
if(i < 400)
|
||||||
lim = 1000;
|
lim = 2000;*/
|
||||||
|
|
||||||
|
u32 lim = 1000 + MAP_GENERATION_LIMIT * i / 5000;
|
||||||
|
|
||||||
v3s16 p(
|
v3s16 p(
|
||||||
-lim + myrand()%(lim*2),
|
-lim + (myrand()%(lim*2)),
|
||||||
0,
|
0,
|
||||||
-lim + myrand()%(lim*2)
|
-lim + (myrand()%(lim*2))
|
||||||
);
|
);
|
||||||
|
|
||||||
/*s32 bh_i = (myrand()%200) - 50;
|
/*s32 bh_i = (myrand()%200) - 50;
|
||||||
|
@ -1404,13 +1432,13 @@ ServerMap::ServerMap(std::string savedir, HMParams hmp, MapParams mp):
|
||||||
if(myrand()%4 == 0)
|
if(myrand()%4 == 0)
|
||||||
{
|
{
|
||||||
baseheight = 100;
|
baseheight = 100;
|
||||||
randmax = 100;
|
randmax = 50;
|
||||||
randfactor = 0.63;
|
randfactor = 0.63;
|
||||||
}
|
}
|
||||||
else if(myrand()%5 == 0)
|
else if(myrand()%6 == 0)
|
||||||
{
|
{
|
||||||
baseheight = 200;
|
baseheight = 200;
|
||||||
randmax = 200;
|
randmax = 100;
|
||||||
randfactor = 0.66;
|
randfactor = 0.66;
|
||||||
}
|
}
|
||||||
else if(myrand()%4 == 0)
|
else if(myrand()%4 == 0)
|
||||||
|
@ -1423,7 +1451,7 @@ ServerMap::ServerMap(std::string savedir, HMParams hmp, MapParams mp):
|
||||||
{
|
{
|
||||||
baseheight = 0;
|
baseheight = 0;
|
||||||
randmax = 30;
|
randmax = 30;
|
||||||
randfactor = 0.60;
|
randfactor = 0.63;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -1436,68 +1464,16 @@ ServerMap::ServerMap(std::string savedir, HMParams hmp, MapParams mp):
|
||||||
list_randmax->addPoint(p, Attribute(randmax));
|
list_randmax->addPoint(p, Attribute(randmax));
|
||||||
list_randfactor->addPoint(p, Attribute(randfactor));
|
list_randfactor->addPoint(p, Attribute(randfactor));
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
/*list_baseheight->addPoint(v3s16(0,0,0), Attribute(5));
|
/*list_baseheight->addPoint(v3s16(0,0,0), Attribute(5));
|
||||||
list_randmax->addPoint(v3s16(0,0,0), Attribute(20));
|
list_randmax->addPoint(v3s16(0,0,0), Attribute(20));
|
||||||
list_randfactor->addPoint(v3s16(0,0,0), Attribute(0.6));*/
|
list_randfactor->addPoint(v3s16(0,0,0), Attribute(0.6));*/
|
||||||
}
|
|
||||||
|
|
||||||
#if 0
|
// Easy spawn point
|
||||||
{
|
/*list_baseheight->addPoint(v3s16(0,0,0), Attribute(0));
|
||||||
PointAttributeList *palist = m_padb.getList("hm_baseheight");
|
list_randmax->addPoint(v3s16(0,0,0), Attribute(10));
|
||||||
|
list_randfactor->addPoint(v3s16(0,0,0), Attribute(0.65));*/
|
||||||
{
|
|
||||||
v3s16 p(0,0,0);
|
|
||||||
Attribute attr;
|
|
||||||
attr.set("5");
|
|
||||||
palist->addPoint(p, attr);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*{
|
|
||||||
v3s16 p(-50,-50,0);
|
|
||||||
Attribute attr;
|
|
||||||
attr.set("-10");
|
|
||||||
palist->addPoint(p, attr);
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
v3s16 p(50,0,50);
|
|
||||||
Attribute attr;
|
|
||||||
attr.set("200");
|
|
||||||
palist->addPoint(p, attr);
|
|
||||||
}*/
|
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
#if 0
|
|
||||||
{
|
|
||||||
PointAttributeList *palist = m_padb.getList("plants_amount");
|
|
||||||
|
|
||||||
// Back
|
|
||||||
{
|
|
||||||
v3s16 p(0,0,-100);
|
|
||||||
Attribute attr;
|
|
||||||
attr.set("0");
|
|
||||||
palist->addPoint(p, attr);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Front right
|
|
||||||
{
|
|
||||||
v3s16 p(100,0,100);
|
|
||||||
Attribute attr;
|
|
||||||
attr.set("2.0");
|
|
||||||
palist->addPoint(p, attr);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Front left
|
|
||||||
{
|
|
||||||
v3s16 p(-100,0,100);
|
|
||||||
Attribute attr;
|
|
||||||
attr.set("0.2");
|
|
||||||
palist->addPoint(p, attr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Try to load map; if not found, create a new one.
|
Try to load map; if not found, create a new one.
|
||||||
|
@ -1704,6 +1680,8 @@ MapSector * ServerMap::emergeSector(v2s16 p2d)
|
||||||
Get local attributes
|
Get local attributes
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
//dstream<<"emergeSector(): Reading point attribute lists"<<std::endl;
|
||||||
|
|
||||||
// Get plant amount from attributes
|
// Get plant amount from attributes
|
||||||
PointAttributeList *palist = m_padb.getList("plants_amount");
|
PointAttributeList *palist = m_padb.getList("plants_amount");
|
||||||
assert(palist);
|
assert(palist);
|
||||||
|
@ -1712,6 +1690,8 @@ MapSector * ServerMap::emergeSector(v2s16 p2d)
|
||||||
float local_plants_amount =
|
float local_plants_amount =
|
||||||
palist->getInterpolatedFloat(nodepos2d);
|
palist->getInterpolatedFloat(nodepos2d);
|
||||||
|
|
||||||
|
//dstream<<"emergeSector(): done."<<std::endl;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Generate sector heightmap
|
Generate sector heightmap
|
||||||
*/
|
*/
|
||||||
|
@ -1810,7 +1790,7 @@ MapSector * ServerMap::emergeSector(v2s16 p2d)
|
||||||
/*
|
/*
|
||||||
Add ravine (randomly)
|
Add ravine (randomly)
|
||||||
*/
|
*/
|
||||||
if(m_params.ravines_amount != 0)
|
if(m_params.ravines_amount > 0.001)
|
||||||
{
|
{
|
||||||
if(myrand()%(s32)(200.0 / m_params.ravines_amount) == 0)
|
if(myrand()%(s32)(200.0 / m_params.ravines_amount) == 0)
|
||||||
{
|
{
|
||||||
|
@ -2061,13 +2041,32 @@ MapBlock * ServerMap::emergeBlock(
|
||||||
|
|
||||||
bool some_part_underground = block_y * MAP_BLOCKSIZE <= highest_ground_y;
|
bool some_part_underground = block_y * MAP_BLOCKSIZE <= highest_ground_y;
|
||||||
|
|
||||||
|
bool mostly_underwater_surface = false;
|
||||||
|
if(highest_ground_y < WATER_LEVEL
|
||||||
|
&& some_part_underground && !completely_underground)
|
||||||
|
mostly_underwater_surface = true;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Get local attributes
|
Get local attributes
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
//dstream<<"emergeBlock(): Getting local attributes"<<std::endl;
|
||||||
|
|
||||||
|
float caves_amount = 0;
|
||||||
|
|
||||||
v2s16 nodepos2d = p2d * MAP_BLOCKSIZE;
|
{
|
||||||
PointAttributeList *list_caves_amount = m_padb.getList("caves_amount");
|
/*
|
||||||
float caves_amount = list_caves_amount->getInterpolatedFloat(nodepos2d);
|
NOTE: BEWARE: Too big amount of attribute points slows verything
|
||||||
|
down by a lot.
|
||||||
|
1 interpolation from 5000 points takes 2-3ms.
|
||||||
|
*/
|
||||||
|
//TimeTaker timer("emergeBlock() local attribute retrieval");
|
||||||
|
v2s16 nodepos2d = p2d * MAP_BLOCKSIZE;
|
||||||
|
PointAttributeList *list_caves_amount = m_padb.getList("caves_amount");
|
||||||
|
caves_amount = list_caves_amount->getInterpolatedFloat(nodepos2d);
|
||||||
|
}
|
||||||
|
|
||||||
|
//dstream<<"emergeBlock(): Done"<<std::endl;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Generate dungeons
|
Generate dungeons
|
||||||
|
@ -2082,6 +2081,7 @@ MapBlock * ServerMap::emergeBlock(
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fill table
|
// Fill table
|
||||||
|
#if 1
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
Initialize orp and ors. Try to find if some neighboring
|
Initialize orp and ors. Try to find if some neighboring
|
||||||
|
@ -2207,21 +2207,34 @@ MapBlock * ServerMap::emergeBlock(
|
||||||
continue_generating:
|
continue_generating:
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Don't always generate dungeon
|
Choose whether to actually generate dungeon
|
||||||
*/
|
*/
|
||||||
bool do_generate_dungeons = true;
|
bool do_generate_dungeons = true;
|
||||||
// Don't generate if no part is underground
|
// Don't generate if no part is underground
|
||||||
if(!some_part_underground)
|
if(!some_part_underground)
|
||||||
|
{
|
||||||
do_generate_dungeons = false;
|
do_generate_dungeons = false;
|
||||||
// If block is partly underground, caves are generated.
|
}
|
||||||
|
// Don't generate if mostly underwater surface
|
||||||
|
else if(mostly_underwater_surface)
|
||||||
|
{
|
||||||
|
do_generate_dungeons = false;
|
||||||
|
}
|
||||||
|
// Partly underground = cave
|
||||||
else if(!completely_underground)
|
else if(!completely_underground)
|
||||||
do_generate_dungeons = (rand() % 100 <= (u32)(caves_amount*100));
|
{
|
||||||
// Always continue if found existing dungeons underground
|
do_generate_dungeons = (rand() % 100 <= (s32)(caves_amount*100));
|
||||||
|
}
|
||||||
|
// Found existing dungeon underground
|
||||||
else if(found_existing && completely_underground)
|
else if(found_existing && completely_underground)
|
||||||
do_generate_dungeons = true;
|
{
|
||||||
// If underground and no dungeons found
|
do_generate_dungeons = (rand() % 100 <= (s32)(caves_amount*100));
|
||||||
|
}
|
||||||
|
// Underground and no dungeons found
|
||||||
else
|
else
|
||||||
do_generate_dungeons = (rand() % 2 == 0);
|
{
|
||||||
|
do_generate_dungeons = (rand() % 300 <= (s32)(caves_amount*100));
|
||||||
|
}
|
||||||
|
|
||||||
if(do_generate_dungeons)
|
if(do_generate_dungeons)
|
||||||
{
|
{
|
||||||
|
@ -2271,10 +2284,11 @@ continue_generating:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// Set to true if has caves.
|
// Set to true if has caves.
|
||||||
// Set when some non-air is changed to air when making caves.
|
// Set when some non-air is changed to air when making caves.
|
||||||
bool has_caves = false;
|
bool has_dungeons = false;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Apply temporary cave data to block
|
Apply temporary cave data to block
|
||||||
|
@ -2296,7 +2310,7 @@ continue_generating:
|
||||||
if(is_ground_content(n.d))
|
if(is_ground_content(n.d))
|
||||||
{
|
{
|
||||||
// Has now caves
|
// Has now caves
|
||||||
has_caves = true;
|
has_dungeons = true;
|
||||||
// Set air to node
|
// Set air to node
|
||||||
n.d = CONTENT_AIR;
|
n.d = CONTENT_AIR;
|
||||||
}
|
}
|
||||||
|
@ -2316,7 +2330,7 @@ continue_generating:
|
||||||
Force lighting update if some part of block is partly
|
Force lighting update if some part of block is partly
|
||||||
underground and has caves.
|
underground and has caves.
|
||||||
*/
|
*/
|
||||||
/*if(some_part_underground && !completely_underground && has_caves)
|
/*if(some_part_underground && !completely_underground && has_dungeons)
|
||||||
{
|
{
|
||||||
//dstream<<"Half-ground caves"<<std::endl;
|
//dstream<<"Half-ground caves"<<std::endl;
|
||||||
lighting_invalidated_blocks[block->getPos()] = block;
|
lighting_invalidated_blocks[block->getPos()] = block;
|
||||||
|
@ -2336,9 +2350,9 @@ continue_generating:
|
||||||
/*
|
/*
|
||||||
Add meseblocks
|
Add meseblocks
|
||||||
*/
|
*/
|
||||||
for(s16 i=0; i< underground_level/4 + 1; i++)
|
for(s16 i=0; i<underground_level/4 + 1; i++)
|
||||||
{
|
{
|
||||||
if(myrand()%10 == 0)
|
if(myrand()%50 == 0)
|
||||||
{
|
{
|
||||||
v3s16 cp(
|
v3s16 cp(
|
||||||
(myrand()%(MAP_BLOCKSIZE-2))+1,
|
(myrand()%(MAP_BLOCKSIZE-2))+1,
|
||||||
|
@ -2697,7 +2711,27 @@ continue_generating:
|
||||||
|
|
||||||
changed_blocks.insert(block->getPos(), block);
|
changed_blocks.insert(block->getPos(), block);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Debug information
|
||||||
|
*/
|
||||||
|
if(0)
|
||||||
|
{
|
||||||
|
dstream
|
||||||
|
<<"lighting_invalidated_blocks.size()"
|
||||||
|
<<", has_dungeons"
|
||||||
|
<<", completely_ug"
|
||||||
|
<<", some_part_ug"
|
||||||
|
<<" "<<lighting_invalidated_blocks.size()
|
||||||
|
<<", "<<has_dungeons
|
||||||
|
<<", "<<completely_underground
|
||||||
|
<<", "<<some_part_underground
|
||||||
|
<<std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Debug mode operation
|
||||||
|
*/
|
||||||
if(HAXMODE)
|
if(HAXMODE)
|
||||||
{
|
{
|
||||||
// Don't calculate lighting at all
|
// Don't calculate lighting at all
|
||||||
|
@ -3412,6 +3446,17 @@ void ClientMap::renderMap(video::IVideoDriver* driver, s32 pass)
|
||||||
if not seen on display
|
if not seen on display
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
float range = 100000 * BS;
|
||||||
|
if(m_control.range_all == false)
|
||||||
|
range = m_control.wanted_range * BS;
|
||||||
|
|
||||||
|
if(isBlockInSight(block->getPos(), camera_position,
|
||||||
|
camera_direction, range) == false)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
v3s16 blockpos_nodes = block->getPosRelative();
|
v3s16 blockpos_nodes = block->getPosRelative();
|
||||||
|
|
||||||
// Block center position
|
// Block center position
|
||||||
|
@ -3434,8 +3479,6 @@ void ClientMap::renderMap(video::IVideoDriver* driver, s32 pass)
|
||||||
{
|
{
|
||||||
// If block is far away, don't draw it
|
// If block is far away, don't draw it
|
||||||
if(d > m_control.wanted_range * BS)
|
if(d > m_control.wanted_range * BS)
|
||||||
// This is nicer when fog is used
|
|
||||||
//if((dforward+d)/2 > m_control.wanted_range * BS)
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3460,7 +3503,23 @@ void ClientMap::renderMap(video::IVideoDriver* driver, s32 pass)
|
||||||
if(cosangle < cos(FOV_ANGLE/2. * 4./3.))
|
if(cosangle < cos(FOV_ANGLE/2. * 4./3.))
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
v3s16 blockpos_nodes = block->getPosRelative();
|
||||||
|
|
||||||
|
// Block center position
|
||||||
|
v3f blockpos(
|
||||||
|
((float)blockpos_nodes.X + MAP_BLOCKSIZE/2) * BS,
|
||||||
|
((float)blockpos_nodes.Y + MAP_BLOCKSIZE/2) * BS,
|
||||||
|
((float)blockpos_nodes.Z + MAP_BLOCKSIZE/2) * BS
|
||||||
|
);
|
||||||
|
|
||||||
|
// Block position relative to camera
|
||||||
|
v3f blockpos_relative = blockpos - camera_position;
|
||||||
|
|
||||||
|
// Total distance
|
||||||
|
f32 d = blockpos_relative.getLength();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Draw the faces of the block
|
Draw the faces of the block
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -206,7 +206,7 @@ public:
|
||||||
their differing fetch methods.
|
their differing fetch methods.
|
||||||
*/
|
*/
|
||||||
virtual MapSector * emergeSector(v2s16 p) = 0;
|
virtual MapSector * emergeSector(v2s16 p) = 0;
|
||||||
|
|
||||||
// Returns InvalidPositionException if not found
|
// Returns InvalidPositionException if not found
|
||||||
MapBlock * getBlockNoCreate(v3s16 p);
|
MapBlock * getBlockNoCreate(v3s16 p);
|
||||||
// Returns NULL if not found
|
// Returns NULL if not found
|
||||||
|
|
|
@ -13,9 +13,9 @@ void setStoneLikeDiggingProperties(u8 material, float toughness)
|
||||||
DiggingProperties(true, 15.0*toughness, 0));
|
DiggingProperties(true, 15.0*toughness, 0));
|
||||||
|
|
||||||
g_material_properties[material].setDiggingProperties("WPick",
|
g_material_properties[material].setDiggingProperties("WPick",
|
||||||
DiggingProperties(true, 1.5*toughness, 65535./20.*toughness));
|
DiggingProperties(true, 1.5*toughness, 65535./30.*toughness));
|
||||||
g_material_properties[material].setDiggingProperties("STPick",
|
g_material_properties[material].setDiggingProperties("STPick",
|
||||||
DiggingProperties(true, 0.7*toughness, 65535./60.*toughness));
|
DiggingProperties(true, 0.7*toughness, 65535./100.*toughness));
|
||||||
|
|
||||||
/*g_material_properties[material].setDiggingProperties("MesePick",
|
/*g_material_properties[material].setDiggingProperties("MesePick",
|
||||||
DiggingProperties(true, 0.0*toughness, 65535./20.*toughness));*/
|
DiggingProperties(true, 0.0*toughness, 65535./20.*toughness));*/
|
||||||
|
|
|
@ -46,6 +46,20 @@ Player::~Player()
|
||||||
// Y direction is ignored
|
// Y direction is ignored
|
||||||
void Player::accelerate(v3f target_speed, f32 max_increase)
|
void Player::accelerate(v3f target_speed, f32 max_increase)
|
||||||
{
|
{
|
||||||
|
v3f d_wanted = target_speed - m_speed;
|
||||||
|
d_wanted.Y = 0;
|
||||||
|
f32 dl_wanted = d_wanted.getLength();
|
||||||
|
f32 dl = dl_wanted;
|
||||||
|
if(dl > max_increase)
|
||||||
|
dl = max_increase;
|
||||||
|
|
||||||
|
v3f d = d_wanted.normalize() * dl;
|
||||||
|
|
||||||
|
m_speed.X += d.X;
|
||||||
|
m_speed.Z += d.Z;
|
||||||
|
//m_speed += d;
|
||||||
|
|
||||||
|
#if 0 // old code
|
||||||
if(m_speed.X < target_speed.X - max_increase)
|
if(m_speed.X < target_speed.X - max_increase)
|
||||||
m_speed.X += max_increase;
|
m_speed.X += max_increase;
|
||||||
else if(m_speed.X > target_speed.X + max_increase)
|
else if(m_speed.X > target_speed.X + max_increase)
|
||||||
|
@ -63,6 +77,7 @@ void Player::accelerate(v3f target_speed, f32 max_increase)
|
||||||
m_speed.Z = target_speed.Z;
|
m_speed.Z = target_speed.Z;
|
||||||
else if(m_speed.Z > target_speed.Z)
|
else if(m_speed.Z > target_speed.Z)
|
||||||
m_speed.Z = target_speed.Z;
|
m_speed.Z = target_speed.Z;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -209,7 +224,7 @@ void LocalPlayer::move(f32 dtime, Map &map)
|
||||||
position += m_speed * dtime;
|
position += m_speed * dtime;
|
||||||
|
|
||||||
// Skip collision detection if player is non-local
|
// Skip collision detection if player is non-local
|
||||||
if(isLocal() == false)
|
if(isLocal() == false || HAXMODE)
|
||||||
{
|
{
|
||||||
setPosition(position);
|
setPosition(position);
|
||||||
return;
|
return;
|
||||||
|
@ -286,10 +301,6 @@ void LocalPlayer::move(f32 dtime, Map &map)
|
||||||
{
|
{
|
||||||
// Doing nothing here will block the player from
|
// Doing nothing here will block the player from
|
||||||
// walking over map borders
|
// walking over map borders
|
||||||
|
|
||||||
// Go over borders in debug mode
|
|
||||||
if(HAXMODE)
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
core::aabbox3d<f32> nodebox = Map::getNodeBox(
|
core::aabbox3d<f32> nodebox = Map::getNodeBox(
|
||||||
|
|
|
@ -328,6 +328,13 @@ void RemoteClient::GetNextBlocks(Server *server, float dtime,
|
||||||
v3s16 center_nodepos = floatToInt(playerpos);
|
v3s16 center_nodepos = floatToInt(playerpos);
|
||||||
|
|
||||||
v3s16 center = getNodeBlockPos(center_nodepos);
|
v3s16 center = getNodeBlockPos(center_nodepos);
|
||||||
|
|
||||||
|
// Camera position and direction
|
||||||
|
v3f camera_pos =
|
||||||
|
playerpos + v3f(0, BS+BS/2, 0);
|
||||||
|
v3f camera_dir = v3f(0,0,1);
|
||||||
|
camera_dir.rotateYZBy(player->getPitch());
|
||||||
|
camera_dir.rotateXZBy(player->getYaw());
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Get the starting value of the block finder radius.
|
Get the starting value of the block finder radius.
|
||||||
|
@ -496,6 +503,15 @@ void RemoteClient::GetNextBlocks(Server *server, float dtime,
|
||||||
if(abs(p.Y - center.Y) > d_max_gen - d_max_gen / 3)
|
if(abs(p.Y - center.Y) > d_max_gen - d_max_gen / 3)
|
||||||
generate = false;
|
generate = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Don't draw if not in sight
|
||||||
|
*/
|
||||||
|
|
||||||
|
if(isBlockInSight(p, camera_pos, camera_dir, 10000*BS) == false)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Don't send already sent blocks
|
Don't send already sent blocks
|
||||||
|
@ -511,6 +527,7 @@ void RemoteClient::GetNextBlocks(Server *server, float dtime,
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
Ignore block if it is not at ground surface
|
Ignore block if it is not at ground surface
|
||||||
|
but don't ignore water surface blocks
|
||||||
*/
|
*/
|
||||||
v2s16 p2d(p.X*MAP_BLOCKSIZE + MAP_BLOCKSIZE/2,
|
v2s16 p2d(p.X*MAP_BLOCKSIZE + MAP_BLOCKSIZE/2,
|
||||||
p.Z*MAP_BLOCKSIZE + MAP_BLOCKSIZE/2);
|
p.Z*MAP_BLOCKSIZE + MAP_BLOCKSIZE/2);
|
||||||
|
@ -519,7 +536,8 @@ void RemoteClient::GetNextBlocks(Server *server, float dtime,
|
||||||
if(y > GROUNDHEIGHT_VALID_MINVALUE)
|
if(y > GROUNDHEIGHT_VALID_MINVALUE)
|
||||||
{
|
{
|
||||||
f32 by = p.Y*MAP_BLOCKSIZE + MAP_BLOCKSIZE/2;
|
f32 by = p.Y*MAP_BLOCKSIZE + MAP_BLOCKSIZE/2;
|
||||||
if(fabs(by - y) > MAP_BLOCKSIZE + MAP_BLOCKSIZE/3)
|
if(fabs(by - y) > MAP_BLOCKSIZE + MAP_BLOCKSIZE/3
|
||||||
|
&& fabs(by - WATER_LEVEL) >= MAP_BLOCKSIZE)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -839,8 +857,11 @@ void RemoteClient::GotBlock(v3s16 p)
|
||||||
if(m_blocks_sending.find(p) != NULL)
|
if(m_blocks_sending.find(p) != NULL)
|
||||||
m_blocks_sending.remove(p);
|
m_blocks_sending.remove(p);
|
||||||
else
|
else
|
||||||
dstream<<"RemoteClient::GotBlock(): Didn't find in"
|
{
|
||||||
" m_blocks_sending"<<std::endl;
|
/*dstream<<"RemoteClient::GotBlock(): Didn't find in"
|
||||||
|
" m_blocks_sending"<<std::endl;*/
|
||||||
|
m_excess_gotblocks++;
|
||||||
|
}
|
||||||
m_blocks_sent.insert(p, true);
|
m_blocks_sent.insert(p, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1118,6 +1139,7 @@ void Server::AsyncRunStep()
|
||||||
/*
|
/*
|
||||||
Flow water
|
Flow water
|
||||||
*/
|
*/
|
||||||
|
if(g_settings.getBool("water_moves") == true)
|
||||||
{
|
{
|
||||||
float interval;
|
float interval;
|
||||||
|
|
||||||
|
@ -3040,12 +3062,12 @@ Player *Server::emergePlayer(const char *name, const char *password)
|
||||||
v2s16 nodepos;
|
v2s16 nodepos;
|
||||||
f32 groundheight = 0;
|
f32 groundheight = 0;
|
||||||
// Try to find a good place a few times
|
// Try to find a good place a few times
|
||||||
for(s32 i=0; i<100; i++)
|
for(s32 i=0; i<500; i++)
|
||||||
{
|
{
|
||||||
s32 range = 1 + i*4;
|
s32 range = 1 + i;
|
||||||
// We're going to try to throw the player to this position
|
// We're going to try to throw the player to this position
|
||||||
nodepos = v2s16(-range/2 + (myrand()%range),
|
nodepos = v2s16(-range + (myrand()%(range*2)),
|
||||||
-range/2 + (myrand()%range));
|
-range + (myrand()%(range*2)));
|
||||||
v2s16 sectorpos = getNodeSectorPos(nodepos);
|
v2s16 sectorpos = getNodeSectorPos(nodepos);
|
||||||
// Get sector
|
// Get sector
|
||||||
m_env.getMap().emergeSector(sectorpos);
|
m_env.getMap().emergeSector(sectorpos);
|
||||||
|
@ -3055,23 +3077,38 @@ Player *Server::emergePlayer(const char *name, const char *password)
|
||||||
assert(groundheight > GROUNDHEIGHT_VALID_MINVALUE);
|
assert(groundheight > GROUNDHEIGHT_VALID_MINVALUE);
|
||||||
// Don't go underwater
|
// Don't go underwater
|
||||||
if(groundheight < WATER_LEVEL)
|
if(groundheight < WATER_LEVEL)
|
||||||
|
{
|
||||||
|
//dstream<<"-> Underwater"<<std::endl;
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
#if 0 // Doesn't work, generating blocks is a bit too complicated for doing here
|
||||||
|
// Get block at point
|
||||||
|
v3s16 nodepos3d;
|
||||||
|
nodepos3d = v3s16(nodepos.X, groundheight+1, nodepos.Y);
|
||||||
|
v3s16 blockpos = getNodeBlockPos(nodepos3d);
|
||||||
|
((ServerMap*)(&m_env.getMap()))->emergeBlock(blockpos);
|
||||||
// Don't go inside ground
|
// Don't go inside ground
|
||||||
try{
|
try{
|
||||||
v3s16 footpos(nodepos.X, groundheight+1, nodepos.Y);
|
/*v3s16 footpos(nodepos.X, groundheight+1, nodepos.Y);
|
||||||
v3s16 headpos(nodepos.X, groundheight+2, nodepos.Y);
|
v3s16 headpos(nodepos.X, groundheight+2, nodepos.Y);*/
|
||||||
|
v3s16 footpos = nodepos3d + v3s16(0,0,0);
|
||||||
|
v3s16 headpos = nodepos3d + v3s16(0,1,0);
|
||||||
if(m_env.getMap().getNode(footpos).d != CONTENT_AIR
|
if(m_env.getMap().getNode(footpos).d != CONTENT_AIR
|
||||||
|| m_env.getMap().getNode(headpos).d != CONTENT_AIR)
|
|| m_env.getMap().getNode(headpos).d != CONTENT_AIR)
|
||||||
{
|
{
|
||||||
|
dstream<<"-> Inside ground"<<std::endl;
|
||||||
// In ground
|
// In ground
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}catch(InvalidPositionException &e)
|
}catch(InvalidPositionException &e)
|
||||||
{
|
{
|
||||||
|
dstream<<"-> Invalid position"<<std::endl;
|
||||||
// Ignore invalid position
|
// Ignore invalid position
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
// Found a good place
|
// Found a good place
|
||||||
|
dstream<<"Searched through "<<i<<" places."<<std::endl;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
14
src/server.h
14
src/server.h
|
@ -231,7 +231,8 @@ public:
|
||||||
u8 pending_serialization_version;
|
u8 pending_serialization_version;
|
||||||
|
|
||||||
RemoteClient():
|
RemoteClient():
|
||||||
m_time_from_building(9999)
|
m_time_from_building(9999),
|
||||||
|
m_excess_gotblocks(0)
|
||||||
{
|
{
|
||||||
peer_id = 0;
|
peer_id = 0;
|
||||||
serialization_version = SER_FMT_VER_INVALID;
|
serialization_version = SER_FMT_VER_INVALID;
|
||||||
|
@ -295,7 +296,9 @@ public:
|
||||||
<<", m_blocks_sent.size()="<<m_blocks_sent.size()
|
<<", m_blocks_sent.size()="<<m_blocks_sent.size()
|
||||||
<<", m_blocks_sending.size()="<<m_blocks_sending.size()
|
<<", m_blocks_sending.size()="<<m_blocks_sending.size()
|
||||||
<<", m_nearest_unsent_d="<<m_nearest_unsent_d
|
<<", m_nearest_unsent_d="<<m_nearest_unsent_d
|
||||||
|
<<", m_excess_gotblocks="<<m_excess_gotblocks
|
||||||
<<std::endl;
|
<<std::endl;
|
||||||
|
m_excess_gotblocks = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Time from last placing or removing blocks
|
// Time from last placing or removing blocks
|
||||||
|
@ -347,6 +350,15 @@ private:
|
||||||
*/
|
*/
|
||||||
core::map<v3s16, float> m_blocks_sending;
|
core::map<v3s16, float> m_blocks_sending;
|
||||||
JMutex m_blocks_sending_mutex;
|
JMutex m_blocks_sending_mutex;
|
||||||
|
|
||||||
|
/*
|
||||||
|
Count of excess GotBlocks().
|
||||||
|
There is an excess amount because the client sometimes
|
||||||
|
gets a block so late that the server sends it again,
|
||||||
|
and the client then sends two GOTBLOCKs.
|
||||||
|
This is resetted by PrintInfo()
|
||||||
|
*/
|
||||||
|
u32 m_excess_gotblocks;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*struct ServerSettings
|
/*struct ServerSettings
|
||||||
|
|
|
@ -748,7 +748,7 @@ struct TestHeightmap
|
||||||
|
|
||||||
padb.getList("hm_baseheight")->addPoint(v2s16(BS1*2,BS1), Attribute(0));
|
padb.getList("hm_baseheight")->addPoint(v2s16(BS1*2,BS1), Attribute(0));
|
||||||
padb.getList("hm_randmax")->addPoint(v2s16(BS1*2,BS1), Attribute(30));
|
padb.getList("hm_randmax")->addPoint(v2s16(BS1*2,BS1), Attribute(30));
|
||||||
padb.getList("hm_randfactor")->addPoint(v2s16(BS1*2,BS1), Attribute(0.9));
|
padb.getList("hm_randfactor")->addPoint(v2s16(BS1*2,BS1), Attribute(0.63));
|
||||||
|
|
||||||
UnlimitedHeightmap hm1(BS1, &padb);
|
UnlimitedHeightmap hm1(BS1, &padb);
|
||||||
|
|
||||||
|
|
|
@ -24,6 +24,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
#include "utility.h"
|
#include "utility.h"
|
||||||
#include "irrlichtwrapper.h"
|
#include "irrlichtwrapper.h"
|
||||||
#include "gettime.h"
|
#include "gettime.h"
|
||||||
|
#include "mapblock.h"
|
||||||
|
|
||||||
TimeTaker::TimeTaker(const char *name, u32 *result)
|
TimeTaker::TimeTaker(const char *name, u32 *result)
|
||||||
{
|
{
|
||||||
|
@ -328,4 +329,58 @@ lopuks sit otetaan a/b
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
blockpos: position of block in block coordinates
|
||||||
|
camera_pos: position of camera in nodes
|
||||||
|
camera_dir: an unit vector pointing to camera direction
|
||||||
|
range: viewing range
|
||||||
|
*/
|
||||||
|
bool isBlockInSight(v3s16 blockpos_b, v3f camera_pos, v3f camera_dir, f32 range)
|
||||||
|
{
|
||||||
|
v3s16 blockpos_nodes = blockpos_b * MAP_BLOCKSIZE;
|
||||||
|
|
||||||
|
// Block center position
|
||||||
|
v3f blockpos(
|
||||||
|
((float)blockpos_nodes.X + MAP_BLOCKSIZE/2) * BS,
|
||||||
|
((float)blockpos_nodes.Y + MAP_BLOCKSIZE/2) * BS,
|
||||||
|
((float)blockpos_nodes.Z + MAP_BLOCKSIZE/2) * BS
|
||||||
|
);
|
||||||
|
|
||||||
|
// Block position relative to camera
|
||||||
|
v3f blockpos_relative = blockpos - camera_pos;
|
||||||
|
|
||||||
|
// Distance in camera direction (+=front, -=back)
|
||||||
|
f32 dforward = blockpos_relative.dotProduct(camera_dir);
|
||||||
|
|
||||||
|
// Total distance
|
||||||
|
f32 d = blockpos_relative.getLength();
|
||||||
|
|
||||||
|
// If block is far away, it's not in sight
|
||||||
|
if(d > range * BS)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// Maximum radius of a block
|
||||||
|
f32 block_max_radius = 0.5*1.44*1.44*MAP_BLOCKSIZE*BS;
|
||||||
|
|
||||||
|
// If block is (nearly) touching the camera, don't
|
||||||
|
// bother validating further (that is, render it anyway)
|
||||||
|
if(d > block_max_radius * 1.5)
|
||||||
|
{
|
||||||
|
// Cosine of the angle between the camera direction
|
||||||
|
// and the block direction (camera_dir is an unit vector)
|
||||||
|
f32 cosangle = dforward / d;
|
||||||
|
|
||||||
|
// Compensate for the size of the block
|
||||||
|
// (as the block has to be shown even if it's a bit off FOV)
|
||||||
|
// This is an estimate.
|
||||||
|
cosangle += block_max_radius / dforward;
|
||||||
|
|
||||||
|
// If block is not in the field of view, skip it
|
||||||
|
//if(cosangle < cos(FOV_ANGLE/2))
|
||||||
|
if(cosangle < cos(FOV_ANGLE/2. * 4./3.))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -1574,5 +1574,12 @@ private:
|
||||||
core::map<std::string, PointAttributeList*> m_lists;
|
core::map<std::string, PointAttributeList*> m_lists;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
Miscellaneous functions
|
||||||
|
*/
|
||||||
|
|
||||||
|
bool isBlockInSight(v3s16 blockpos_b, v3f camera_pos, v3f camera_dir, f32 range);
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue