forked from Mirrorlandia_minetest/minetest
generate-time lighting optimization
This commit is contained in:
parent
83e083a667
commit
a176f9eb36
@ -48,8 +48,8 @@ void set_default_settings()
|
|||||||
g_settings.setDefault("ravines_amount", "1.0");
|
g_settings.setDefault("ravines_amount", "1.0");
|
||||||
g_settings.setDefault("coal_amount", "1.0");*/
|
g_settings.setDefault("coal_amount", "1.0");*/
|
||||||
g_settings.setDefault("heightmap_blocksize", "16");
|
g_settings.setDefault("heightmap_blocksize", "16");
|
||||||
g_settings.setDefault("height_randmax", "linear 0 0 40");
|
g_settings.setDefault("height_randmax", "linear 0 0 30");
|
||||||
g_settings.setDefault("height_randfactor", "linear 0.60 -0.10 0");
|
g_settings.setDefault("height_randfactor", "linear 0.50 -0.10 0");
|
||||||
g_settings.setDefault("height_base", "linear 5 0 0");
|
g_settings.setDefault("height_base", "linear 5 0 0");
|
||||||
g_settings.setDefault("plants_amount", "0.2");
|
g_settings.setDefault("plants_amount", "0.2");
|
||||||
g_settings.setDefault("ravines_amount", "0");
|
g_settings.setDefault("ravines_amount", "0");
|
||||||
|
402
src/map.cpp
402
src/map.cpp
@ -1692,6 +1692,8 @@ MapBlock * ServerMap::emergeBlock(
|
|||||||
/*
|
/*
|
||||||
If block doesn't exist, create one.
|
If block doesn't exist, create one.
|
||||||
If it exists, it is a dummy. In that case unDummify() it.
|
If it exists, it is a dummy. In that case unDummify() it.
|
||||||
|
|
||||||
|
NOTE: This already sets the map as the parent of the block
|
||||||
*/
|
*/
|
||||||
if(block == NULL)
|
if(block == NULL)
|
||||||
{
|
{
|
||||||
@ -1701,161 +1703,10 @@ MapBlock * ServerMap::emergeBlock(
|
|||||||
{
|
{
|
||||||
// Remove the block so that nobody can get a half-generated one.
|
// Remove the block so that nobody can get a half-generated one.
|
||||||
sector->removeBlock(block);
|
sector->removeBlock(block);
|
||||||
// Allocate the block to be a proper one.
|
// Allocate the block to contain the generated data
|
||||||
block->unDummify();
|
block->unDummify();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
Create dungeon making table
|
|
||||||
*/
|
|
||||||
const s32 ued = MAP_BLOCKSIZE;
|
|
||||||
bool underground_emptiness[ued*ued*ued];
|
|
||||||
for(s32 i=0; i<ued*ued*ued; i++)
|
|
||||||
{
|
|
||||||
underground_emptiness[i] = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Generate dungeons
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
Initialize orp and ors. Try to find if some neighboring
|
|
||||||
MapBlock has a tunnel ended in its side
|
|
||||||
*/
|
|
||||||
|
|
||||||
v3f orp(
|
|
||||||
(float)(myrand()%ued)+0.5,
|
|
||||||
(float)(myrand()%ued)+0.5,
|
|
||||||
(float)(myrand()%ued)+0.5
|
|
||||||
);
|
|
||||||
|
|
||||||
bool found_existing = false;
|
|
||||||
|
|
||||||
// Check z-
|
|
||||||
try
|
|
||||||
{
|
|
||||||
s16 z = -1;
|
|
||||||
for(s16 y=0; y<ued; y++)
|
|
||||||
for(s16 x=0; x<ued; x++)
|
|
||||||
{
|
|
||||||
v3s16 ap = v3s16(x,y,z) + block->getPosRelative();
|
|
||||||
if(getNode(ap).d == CONTENT_AIR)
|
|
||||||
{
|
|
||||||
orp = v3f(x+1,y+1,0);
|
|
||||||
found_existing = true;
|
|
||||||
goto continue_generating;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch(InvalidPositionException &e){}
|
|
||||||
|
|
||||||
// Check z+
|
|
||||||
try
|
|
||||||
{
|
|
||||||
s16 z = ued;
|
|
||||||
for(s16 y=0; y<ued; y++)
|
|
||||||
for(s16 x=0; x<ued; x++)
|
|
||||||
{
|
|
||||||
v3s16 ap = v3s16(x,y,z) + block->getPosRelative();
|
|
||||||
if(getNode(ap).d == CONTENT_AIR)
|
|
||||||
{
|
|
||||||
orp = v3f(x+1,y+1,ued-1);
|
|
||||||
found_existing = true;
|
|
||||||
goto continue_generating;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch(InvalidPositionException &e){}
|
|
||||||
|
|
||||||
// Check x-
|
|
||||||
try
|
|
||||||
{
|
|
||||||
s16 x = -1;
|
|
||||||
for(s16 y=0; y<ued; y++)
|
|
||||||
for(s16 z=0; z<ued; z++)
|
|
||||||
{
|
|
||||||
v3s16 ap = v3s16(x,y,z) + block->getPosRelative();
|
|
||||||
if(getNode(ap).d == CONTENT_AIR)
|
|
||||||
{
|
|
||||||
orp = v3f(0,y+1,z+1);
|
|
||||||
found_existing = true;
|
|
||||||
goto continue_generating;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch(InvalidPositionException &e){}
|
|
||||||
|
|
||||||
// Check x+
|
|
||||||
try
|
|
||||||
{
|
|
||||||
s16 x = ued;
|
|
||||||
for(s16 y=0; y<ued; y++)
|
|
||||||
for(s16 z=0; z<ued; z++)
|
|
||||||
{
|
|
||||||
v3s16 ap = v3s16(x,y,z) + block->getPosRelative();
|
|
||||||
if(getNode(ap).d == CONTENT_AIR)
|
|
||||||
{
|
|
||||||
orp = v3f(ued-1,y+1,z+1);
|
|
||||||
found_existing = true;
|
|
||||||
goto continue_generating;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch(InvalidPositionException &e){}
|
|
||||||
|
|
||||||
continue_generating:
|
|
||||||
|
|
||||||
/*
|
|
||||||
Don't always generate dungeon
|
|
||||||
*/
|
|
||||||
if(found_existing || rand() % 2 == 0)
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
Generate some tunnel starting from orp and ors
|
|
||||||
*/
|
|
||||||
for(u16 i=0; i<3; i++)
|
|
||||||
{
|
|
||||||
v3f rp(
|
|
||||||
(float)(myrand()%ued)+0.5,
|
|
||||||
(float)(myrand()%ued)+0.5,
|
|
||||||
(float)(myrand()%ued)+0.5
|
|
||||||
);
|
|
||||||
s16 min_d = 0;
|
|
||||||
s16 max_d = 4;
|
|
||||||
s16 rs = (myrand()%(max_d-min_d+1))+min_d;
|
|
||||||
|
|
||||||
v3f vec = rp - orp;
|
|
||||||
|
|
||||||
for(float f=0; f<1.0; f+=0.04)
|
|
||||||
{
|
|
||||||
v3f fp = orp + vec * f;
|
|
||||||
v3s16 cp(fp.X, fp.Y, fp.Z);
|
|
||||||
s16 d0 = -rs/2;
|
|
||||||
s16 d1 = d0 + rs - 1;
|
|
||||||
for(s16 z0=d0; z0<=d1; z0++)
|
|
||||||
{
|
|
||||||
s16 si = rs - abs(z0);
|
|
||||||
for(s16 x0=-si; x0<=si-1; x0++)
|
|
||||||
{
|
|
||||||
s16 si2 = rs - abs(x0);
|
|
||||||
for(s16 y0=-si2+1; y0<=si2-1; y0++)
|
|
||||||
{
|
|
||||||
s16 z = cp.Z + z0;
|
|
||||||
s16 y = cp.Y + y0;
|
|
||||||
s16 x = cp.X + x0;
|
|
||||||
v3s16 p(x,y,z);
|
|
||||||
if(isInArea(p, ued) == false)
|
|
||||||
continue;
|
|
||||||
underground_emptiness[ued*ued*z + ued*y + x] = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
orp = rp;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
u8 water_material = CONTENT_WATER;
|
u8 water_material = CONTENT_WATER;
|
||||||
if(g_settings.getBool("endless_water"))
|
if(g_settings.getBool("endless_water"))
|
||||||
water_material = CONTENT_OCEAN;
|
water_material = CONTENT_OCEAN;
|
||||||
@ -1866,10 +1717,6 @@ continue_generating:
|
|||||||
// DEBUG
|
// DEBUG
|
||||||
//sector->printHeightmaps();
|
//sector->printHeightmaps();
|
||||||
|
|
||||||
// Set to true if has caves.
|
|
||||||
// Set when some non-air is changed to air when making caves.
|
|
||||||
bool has_caves = false;
|
|
||||||
|
|
||||||
for(s16 z0=0; z0<MAP_BLOCKSIZE; z0++)
|
for(s16 z0=0; z0<MAP_BLOCKSIZE; z0++)
|
||||||
for(s16 x0=0; x0<MAP_BLOCKSIZE; x0++)
|
for(s16 x0=0; x0<MAP_BLOCKSIZE; x0++)
|
||||||
{
|
{
|
||||||
@ -1972,6 +1819,202 @@ continue_generating:
|
|||||||
else
|
else
|
||||||
n.d = CONTENT_GRASS;*/
|
n.d = CONTENT_GRASS;*/
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
block->setNode(v3s16(x0,y0,z0), n);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Calculate some helper variables
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Completely underground if the highest part of block is under lowest
|
||||||
|
// ground height.
|
||||||
|
// This has to be very sure; it's probably one too strict now but
|
||||||
|
// that's just better.
|
||||||
|
bool completely_underground =
|
||||||
|
block_y * MAP_BLOCKSIZE + MAP_BLOCKSIZE < lowest_ground_y;
|
||||||
|
|
||||||
|
bool some_part_underground = block_y * MAP_BLOCKSIZE <= highest_ground_y;
|
||||||
|
|
||||||
|
/*
|
||||||
|
Generate dungeons
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Initialize temporary table
|
||||||
|
const s32 ued = MAP_BLOCKSIZE;
|
||||||
|
bool underground_emptiness[ued*ued*ued];
|
||||||
|
for(s32 i=0; i<ued*ued*ued; i++)
|
||||||
|
{
|
||||||
|
underground_emptiness[i] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fill table
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
Initialize orp and ors. Try to find if some neighboring
|
||||||
|
MapBlock has a tunnel ended in its side
|
||||||
|
*/
|
||||||
|
|
||||||
|
v3f orp(
|
||||||
|
(float)(myrand()%ued)+0.5,
|
||||||
|
(float)(myrand()%ued)+0.5,
|
||||||
|
(float)(myrand()%ued)+0.5
|
||||||
|
);
|
||||||
|
|
||||||
|
bool found_existing = false;
|
||||||
|
|
||||||
|
// Check z-
|
||||||
|
try
|
||||||
|
{
|
||||||
|
s16 z = -1;
|
||||||
|
for(s16 y=0; y<ued; y++)
|
||||||
|
for(s16 x=0; x<ued; x++)
|
||||||
|
{
|
||||||
|
v3s16 ap = v3s16(x,y,z) + block->getPosRelative();
|
||||||
|
if(getNode(ap).d == CONTENT_AIR)
|
||||||
|
{
|
||||||
|
orp = v3f(x+1,y+1,0);
|
||||||
|
found_existing = true;
|
||||||
|
goto continue_generating;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch(InvalidPositionException &e){}
|
||||||
|
|
||||||
|
// Check z+
|
||||||
|
try
|
||||||
|
{
|
||||||
|
s16 z = ued;
|
||||||
|
for(s16 y=0; y<ued; y++)
|
||||||
|
for(s16 x=0; x<ued; x++)
|
||||||
|
{
|
||||||
|
v3s16 ap = v3s16(x,y,z) + block->getPosRelative();
|
||||||
|
if(getNode(ap).d == CONTENT_AIR)
|
||||||
|
{
|
||||||
|
orp = v3f(x+1,y+1,ued-1);
|
||||||
|
found_existing = true;
|
||||||
|
goto continue_generating;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch(InvalidPositionException &e){}
|
||||||
|
|
||||||
|
// Check x-
|
||||||
|
try
|
||||||
|
{
|
||||||
|
s16 x = -1;
|
||||||
|
for(s16 y=0; y<ued; y++)
|
||||||
|
for(s16 z=0; z<ued; z++)
|
||||||
|
{
|
||||||
|
v3s16 ap = v3s16(x,y,z) + block->getPosRelative();
|
||||||
|
if(getNode(ap).d == CONTENT_AIR)
|
||||||
|
{
|
||||||
|
orp = v3f(0,y+1,z+1);
|
||||||
|
found_existing = true;
|
||||||
|
goto continue_generating;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch(InvalidPositionException &e){}
|
||||||
|
|
||||||
|
// Check x+
|
||||||
|
try
|
||||||
|
{
|
||||||
|
s16 x = ued;
|
||||||
|
for(s16 y=0; y<ued; y++)
|
||||||
|
for(s16 z=0; z<ued; z++)
|
||||||
|
{
|
||||||
|
v3s16 ap = v3s16(x,y,z) + block->getPosRelative();
|
||||||
|
if(getNode(ap).d == CONTENT_AIR)
|
||||||
|
{
|
||||||
|
orp = v3f(ued-1,y+1,z+1);
|
||||||
|
found_existing = true;
|
||||||
|
goto continue_generating;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch(InvalidPositionException &e){}
|
||||||
|
|
||||||
|
continue_generating:
|
||||||
|
|
||||||
|
/*
|
||||||
|
Don't always generate dungeon
|
||||||
|
*/
|
||||||
|
bool do_generate_dungeons = true;
|
||||||
|
if(!some_part_underground)
|
||||||
|
do_generate_dungeons = false;
|
||||||
|
else if(!completely_underground)
|
||||||
|
do_generate_dungeons = rand() % 5;
|
||||||
|
else if(found_existing)
|
||||||
|
do_generate_dungeons = true;
|
||||||
|
else
|
||||||
|
do_generate_dungeons = rand() % 2;
|
||||||
|
|
||||||
|
if(do_generate_dungeons)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
Generate some tunnel starting from orp and ors
|
||||||
|
*/
|
||||||
|
for(u16 i=0; i<3; i++)
|
||||||
|
{
|
||||||
|
v3f rp(
|
||||||
|
(float)(myrand()%ued)+0.5,
|
||||||
|
(float)(myrand()%ued)+0.5,
|
||||||
|
(float)(myrand()%ued)+0.5
|
||||||
|
);
|
||||||
|
s16 min_d = 0;
|
||||||
|
s16 max_d = 6;
|
||||||
|
s16 rs = (myrand()%(max_d-min_d+1))+min_d;
|
||||||
|
|
||||||
|
v3f vec = rp - orp;
|
||||||
|
|
||||||
|
for(float f=0; f<1.0; f+=0.04)
|
||||||
|
{
|
||||||
|
v3f fp = orp + vec * f;
|
||||||
|
v3s16 cp(fp.X, fp.Y, fp.Z);
|
||||||
|
s16 d0 = -rs/2;
|
||||||
|
s16 d1 = d0 + rs - 1;
|
||||||
|
for(s16 z0=d0; z0<=d1; z0++)
|
||||||
|
{
|
||||||
|
s16 si = rs - abs(z0);
|
||||||
|
for(s16 x0=-si; x0<=si-1; x0++)
|
||||||
|
{
|
||||||
|
s16 si2 = rs - abs(x0);
|
||||||
|
for(s16 y0=-si2+1; y0<=si2-1; y0++)
|
||||||
|
{
|
||||||
|
s16 z = cp.Z + z0;
|
||||||
|
s16 y = cp.Y + y0;
|
||||||
|
s16 x = cp.X + x0;
|
||||||
|
v3s16 p(x,y,z);
|
||||||
|
if(isInArea(p, ued) == false)
|
||||||
|
continue;
|
||||||
|
underground_emptiness[ued*ued*z + ued*y + x] = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
orp = rp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set to true if has caves.
|
||||||
|
// Set when some non-air is changed to air when making caves.
|
||||||
|
bool has_caves = false;
|
||||||
|
|
||||||
|
/*
|
||||||
|
Apply temporary cave data to block
|
||||||
|
*/
|
||||||
|
|
||||||
|
for(s16 z0=0; z0<MAP_BLOCKSIZE; z0++)
|
||||||
|
for(s16 x0=0; x0<MAP_BLOCKSIZE; x0++)
|
||||||
|
{
|
||||||
|
for(s16 y0=0; y0<MAP_BLOCKSIZE; y0++)
|
||||||
|
{
|
||||||
|
MapNode n = block->getNode(v3s16(x0,y0,z0));
|
||||||
|
|
||||||
// Create dungeons
|
// Create dungeons
|
||||||
if(underground_emptiness[
|
if(underground_emptiness[
|
||||||
@ -1979,12 +2022,11 @@ continue_generating:
|
|||||||
+ued*(y0*ued/MAP_BLOCKSIZE)
|
+ued*(y0*ued/MAP_BLOCKSIZE)
|
||||||
+(x0*ued/MAP_BLOCKSIZE)])
|
+(x0*ued/MAP_BLOCKSIZE)])
|
||||||
{
|
{
|
||||||
// Has now caves if previous content is air
|
if(is_ground_content(n.d))
|
||||||
if(n.d != CONTENT_AIR)
|
|
||||||
{
|
{
|
||||||
|
// Has now caves
|
||||||
has_caves = true;
|
has_caves = true;
|
||||||
}
|
// Set air to node
|
||||||
|
|
||||||
n.d = CONTENT_AIR;
|
n.d = CONTENT_AIR;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1994,30 +2036,20 @@ continue_generating:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Calculate completely_underground
|
This is used for guessing whether or not the block should
|
||||||
|
receive sunlight from the top if the top block doesn't exist
|
||||||
*/
|
*/
|
||||||
// Completely underground if the highest part of block is under lowest
|
|
||||||
// ground height.
|
|
||||||
// This has to be very sure; it's probably one too strict now but
|
|
||||||
// that's just better.
|
|
||||||
bool completely_underground =
|
|
||||||
block_y * MAP_BLOCKSIZE + MAP_BLOCKSIZE < lowest_ground_y;
|
|
||||||
|
|
||||||
// This isn't used anymore (?) but set it anyway
|
|
||||||
block->setIsUnderground(completely_underground);
|
block->setIsUnderground(completely_underground);
|
||||||
|
|
||||||
bool some_part_underground = block_y * MAP_BLOCKSIZE <= highest_ground_y;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
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_caves)
|
|
||||||
{
|
{
|
||||||
//dstream<<"Half-ground caves"<<std::endl;
|
//dstream<<"Half-ground caves"<<std::endl;
|
||||||
lighting_invalidated_blocks[block->getPos()] = block;
|
lighting_invalidated_blocks[block->getPos()] = block;
|
||||||
}
|
}*/
|
||||||
|
|
||||||
// DEBUG: Always update lighting
|
// DEBUG: Always update lighting
|
||||||
//lighting_invalidated_blocks[block->getPos()] = block;
|
//lighting_invalidated_blocks[block->getPos()] = block;
|
||||||
@ -2364,6 +2396,28 @@ continue_generating:
|
|||||||
objects->remove(*i);
|
objects->remove(*i);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Initially update sunlight
|
||||||
|
*/
|
||||||
|
|
||||||
|
{
|
||||||
|
core::map<v3s16, bool> light_sources;
|
||||||
|
bool black_air_left = false;
|
||||||
|
bool bottom_invalid =
|
||||||
|
block->propagateSunlight(light_sources, true, &black_air_left);
|
||||||
|
|
||||||
|
// If sunlight didn't reach everywhere and part of block is
|
||||||
|
// above ground, lighting has to be properly updated
|
||||||
|
if(black_air_left && some_part_underground)
|
||||||
|
{
|
||||||
|
lighting_invalidated_blocks[block->getPos()] = block;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Translate sector's changed blocks to global changed blocks
|
||||||
|
*/
|
||||||
|
|
||||||
for(core::map<s16, MapBlock*>::Iterator
|
for(core::map<s16, MapBlock*>::Iterator
|
||||||
i = changed_blocks_sector.getIterator();
|
i = changed_blocks_sector.getIterator();
|
||||||
i.atEnd() == false; i++)
|
i.atEnd() == false; i++)
|
||||||
|
@ -934,60 +934,67 @@ bool MapBlock::propagateSunlight(core::map<v3s16, bool> & light_sources,
|
|||||||
|
|
||||||
s16 y = MAP_BLOCKSIZE-1;
|
s16 y = MAP_BLOCKSIZE-1;
|
||||||
|
|
||||||
if(no_sunlight == false)
|
// This makes difference to diminishing in water.
|
||||||
{
|
bool stopped_to_solid_object = false;
|
||||||
// Continue spreading sunlight downwards through transparent
|
|
||||||
// nodes
|
u8 current_light = no_sunlight ? 0 : LIGHT_SUN;
|
||||||
|
|
||||||
for(; y >= 0; y--)
|
for(; y >= 0; y--)
|
||||||
{
|
{
|
||||||
v3s16 pos(x, y, z);
|
v3s16 pos(x, y, z);
|
||||||
|
|
||||||
MapNode &n = getNodeRef(pos);
|
MapNode &n = getNodeRef(pos);
|
||||||
|
|
||||||
if(n.sunlight_propagates())
|
if(current_light == 0)
|
||||||
{
|
{
|
||||||
n.setLight(LIGHTBANK_DAY, LIGHT_SUN);
|
// Do nothing
|
||||||
|
|
||||||
light_sources.insert(pos_relative + pos, true);
|
|
||||||
}
|
}
|
||||||
else
|
else if(current_light == LIGHT_SUN && n.sunlight_propagates())
|
||||||
|
{
|
||||||
|
// Do nothing: Sunlight is continued
|
||||||
|
}
|
||||||
|
else if(n.light_propagates() == false)
|
||||||
{
|
{
|
||||||
// Turn mud into grass
|
// Turn mud into grass
|
||||||
if(n.d == CONTENT_MUD)
|
if(n.d == CONTENT_MUD && current_light == LIGHT_SUN)
|
||||||
{
|
{
|
||||||
n.d = CONTENT_GRASS;
|
n.d = CONTENT_GRASS;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sunlight goes no further
|
// A solid object is on the way.
|
||||||
break;
|
stopped_to_solid_object = true;
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool sunlight_should_go_down = (y==-1);
|
// Light stops.
|
||||||
|
current_light = 0;
|
||||||
/*
|
}
|
||||||
Check rest through to the bottom of the block
|
else
|
||||||
*/
|
|
||||||
for(; y >= 0; y--)
|
|
||||||
{
|
{
|
||||||
v3s16 pos(x, y, z);
|
// Diminish light
|
||||||
MapNode &n = getNodeRef(pos);
|
current_light = diminish_light(current_light);
|
||||||
|
}
|
||||||
|
|
||||||
if(n.light_propagates())
|
u8 old_light = n.getLight(LIGHTBANK_DAY);
|
||||||
|
|
||||||
|
if(current_light > old_light || remove_light)
|
||||||
|
{
|
||||||
|
n.setLight(LIGHTBANK_DAY, current_light);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(diminish_light(current_light) != 0)
|
||||||
|
{
|
||||||
|
light_sources.insert(pos_relative + pos, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(current_light == 0 && stopped_to_solid_object)
|
||||||
{
|
{
|
||||||
if(black_air_left)
|
if(black_air_left)
|
||||||
{
|
{
|
||||||
*black_air_left = true;
|
*black_air_left = true;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if(remove_light)
|
// Whether or not the block below should see LIGHT_SUN
|
||||||
{
|
bool sunlight_should_go_down = (current_light == LIGHT_SUN);
|
||||||
// Fill transparent nodes with black
|
|
||||||
n.setLight(LIGHTBANK_DAY, 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
If the block below hasn't already been marked invalid:
|
If the block below hasn't already been marked invalid:
|
||||||
|
@ -312,7 +312,8 @@ public:
|
|||||||
#endif // !SERVER
|
#endif // !SERVER
|
||||||
|
|
||||||
// See comments in mapblock.cpp
|
// See comments in mapblock.cpp
|
||||||
bool propagateSunlight(core::map<v3s16, bool> & light_sources);
|
bool propagateSunlight(core::map<v3s16, bool> & light_sources,
|
||||||
|
bool remove_light=false, bool *black_air_left=NULL);
|
||||||
|
|
||||||
// Copies data to VoxelManipulator to getPosRelative()
|
// Copies data to VoxelManipulator to getPosRelative()
|
||||||
void copyTo(VoxelManipulator &dst);
|
void copyTo(VoxelManipulator &dst);
|
||||||
|
@ -3003,7 +3003,7 @@ Player *Server::emergePlayer(const char *name, const char *password)
|
|||||||
// 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<100; i++)
|
||||||
{
|
{
|
||||||
s32 range = 1 + i*5;
|
s32 range = 1 + i*2;
|
||||||
// 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/2 + (myrand()%range),
|
||||||
-range/2 + (myrand()%range));
|
-range/2 + (myrand()%range));
|
||||||
@ -3037,6 +3037,10 @@ Player *Server::emergePlayer(const char *name, const char *password)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// If no suitable place was not found, go above water at least.
|
||||||
|
if(groundheight < WATER_LEVEL)
|
||||||
|
groundheight = WATER_LEVEL;
|
||||||
|
|
||||||
player->setPosition(intToFloat(v3s16(
|
player->setPosition(intToFloat(v3s16(
|
||||||
nodepos.X,
|
nodepos.X,
|
||||||
groundheight + 1,
|
groundheight + 1,
|
||||||
|
@ -537,7 +537,7 @@ struct TestMapBlock
|
|||||||
core::map<v3s16, bool> light_sources;
|
core::map<v3s16, bool> light_sources;
|
||||||
// The block below should be valid because there shouldn't be
|
// The block below should be valid because there shouldn't be
|
||||||
// sunlight in there either
|
// sunlight in there either
|
||||||
assert(b.propagateSunlight(light_sources) == true);
|
assert(b.propagateSunlight(light_sources, true) == true);
|
||||||
// Should not touch nodes that are not affected (that is, all of them)
|
// Should not touch nodes that are not affected (that is, all of them)
|
||||||
//assert(b.getNode(v3s16(1,2,3)).getLight() == LIGHT_SUN);
|
//assert(b.getNode(v3s16(1,2,3)).getLight() == LIGHT_SUN);
|
||||||
// Should set light of non-sunlighted blocks to 0.
|
// Should set light of non-sunlighted blocks to 0.
|
||||||
|
@ -1323,10 +1323,17 @@ private:
|
|||||||
MutexedQueue< GetRequest<Key, T, Caller, CallerData> > m_queue;
|
MutexedQueue< GetRequest<Key, T, Caller, CallerData> > m_queue;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Pseudo-random (VC++ rand() sucks)
|
/*
|
||||||
|
Pseudo-random (VC++ rand() sucks)
|
||||||
|
*/
|
||||||
int myrand(void);
|
int myrand(void);
|
||||||
void mysrand(unsigned seed);
|
void mysrand(unsigned seed);
|
||||||
#define MYRAND_MAX 32767
|
#define MYRAND_MAX 32767
|
||||||
|
|
||||||
|
/*
|
||||||
|
TODO: Some kind of a thing that stores arbitary data related to
|
||||||
|
2D coordinate points
|
||||||
|
*/
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user