- u32 i = vmanip.m_area.index(p);
- vmanip.m_data[i] = airnode;
-
- if(bruise_surface == false)
- {
- // Set tunnel flag
- vmanip.m_flags[i] |= VMANIP_FLAG_DUNGEON;
- }
- }
- }
- }
- }
-
- orp = rp;
- }
-
- }
-
- }//timer1
- {
- // 46ms @cs=8
- //TimeTaker timer1("ore veins");
-
- /*
- Make ore veins
- */
- for(u32 jj=0; jj<relative_volume/1000; jj++)
- {
- s16 max_vein_diameter = 3;
-
- // Allowed route area size in nodes
- v3s16 ar(
- sectorpos_base_size*MAP_BLOCKSIZE,
- h_blocks*MAP_BLOCKSIZE,
- sectorpos_base_size*MAP_BLOCKSIZE
- );
-
- // Area starting point in nodes
- v3s16 of(
- sectorpos_base.X*MAP_BLOCKSIZE,
- y_blocks_min*MAP_BLOCKSIZE,
- sectorpos_base.Y*MAP_BLOCKSIZE
- );
-
- // Allow a bit more
- //(this should be more than the maximum radius of the tunnel)
- s16 insure = 3;
- s16 more = max_spread_amount - max_vein_diameter/2 - insure;
- ar += v3s16(1,0,1) * more * 2;
- of -= v3s16(1,0,1) * more;
-
- // Randomize starting position
- v3f orp(
- (float)(myrand()%ar.X)+0.5,
- (float)(myrand()%ar.Y)+0.5,
- (float)(myrand()%ar.Z)+0.5
- );
-
- // Randomize mineral
- u8 mineral;
- if(myrand()%3 != 0)
- mineral = MINERAL_COAL;
- else
- mineral = MINERAL_IRON;
-
- /*
- Generate some vein starting from orp
- */
-
- for(u16 j=0; j<2; j++)
- {
- /*v3f rp(
- (float)(myrand()%ar.X)+0.5,
- (float)(myrand()%ar.Y)+0.5,
- (float)(myrand()%ar.Z)+0.5
- );
- v3f vec = rp - orp;*/
-
- v3s16 maxlen(5, 5, 5);
- v3f vec(
- (float)(myrand()%(maxlen.X*2))-(float)maxlen.X,
- (float)(myrand()%(maxlen.Y*2))-(float)maxlen.Y,
- (float)(myrand()%(maxlen.Z*2))-(float)maxlen.Z
- );
- v3f rp = orp + vec;
- if(rp.X < 0)
- rp.X = 0;
- else if(rp.X >= ar.X)
- rp.X = ar.X;
- if(rp.Y < 0)
- rp.Y = 0;
- else if(rp.Y >= ar.Y)
- rp.Y = ar.Y;
- if(rp.Z < 0)
- rp.Z = 0;
- else if(rp.Z >= ar.Z)
- rp.Z = ar.Z;
- vec = rp - orp;
-
- // Randomize size
- s16 min_d = 0;
- s16 max_d = max_vein_diameter;
- s16 rs = myrand_range(min_d, max_d);
-
- for(float f=0; f<1.0; f+=1.0/vec.getLength())
- {
- 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++)
- {
- // Don't put mineral to every place
- if(myrand()%5 != 0)
- continue;
-
- s16 z = cp.Z + z0;
- s16 y = cp.Y + y0;
- s16 x = cp.X + x0;
- v3s16 p(x,y,z);
- /*if(isInArea(p, ar) == false)
- continue;*/
- // Check only height
- if(y < 0 || y >= ar.Y)
- continue;
- p += of;
-
- assert(vmanip.m_area.contains(p));
-
- // Just set it to air, it will be changed to
- // water afterwards
- u32 i = vmanip.m_area.index(p);
- MapNode *n = &vmanip.m_data[i];
- if(n->d == CONTENT_STONE)
- n->param = mineral;
- }
- }
- }
- }
-
- orp = rp;
- }
-
- }
-
- }//timer1
- {
- // 15ms @cs=8
- //TimeTaker timer1("add mud");
-
- /*
- Add mud to the central chunk
- */
-
- for(s16 x=0; x<sectorpos_base_size*MAP_BLOCKSIZE; x++)
- for(s16 z=0; z<sectorpos_base_size*MAP_BLOCKSIZE; z++)
- {
- // Node position in 2d
- v2s16 p2d = sectorpos_base*MAP_BLOCKSIZE + v2s16(x,z);
-
- // Randomize mud amount
- s16 mud_add_amount = get_mud_amount(m_seed, v2f(p2d.X,p2d.Y))/age_count;
-
- // Find ground level
- s16 surface_y = find_ground_level_clever(vmanip, p2d);
-
- /*
- If topmost node is grass, change it to mud.
- It might be if it was flown to there from a neighboring
- chunk and then converted.
- */
- {
- u32 i = vmanip.m_area.index(v3s16(p2d.X, surface_y, p2d.Y));
- MapNode *n = &vmanip.m_data[i];
- if(n->d == CONTENT_GRASS)
- n->d = CONTENT_MUD;
- }
-
- /*
- Add mud on ground
- */
- {
- s16 mudcount = 0;
- v3s16 em = vmanip.m_area.getExtent();
- s16 y_start = surface_y+1;
- u32 i = vmanip.m_area.index(v3s16(p2d.X, y_start, p2d.Y));
- for(s16 y=y_start; y<=y_nodes_max; y++)
- {
- if(mudcount >= mud_add_amount)
- break;
-
- MapNode &n = vmanip.m_data[i];
- n.d = CONTENT_MUD;
- mudcount++;
-
- vmanip.m_area.add_y(em, i, 1);
- }
- }
-
- }
-
- }//timer1
- {
- // 340ms @cs=8
- //TimeTaker timer1("flow mud");
-
- /*
- Flow mud away from steep edges
- */
-
- // Limit area by 1 because mud is flown into neighbors.
- s16 mudflow_minpos = 0-max_spread_amount+1;
- s16 mudflow_maxpos = sectorpos_base_size*MAP_BLOCKSIZE+max_spread_amount-2;
-
- // Iterate a few times
- for(s16 k=0; k<3; k++)
- {
-
- for(s16 x=mudflow_minpos;
- x<=mudflow_maxpos;
- x++)
- for(s16 z=mudflow_minpos;
- z<=mudflow_maxpos;
- z++)
- {
- // Invert coordinates every 2nd iteration
- if(k%2 == 0)
- {
- x = mudflow_maxpos - (x-mudflow_minpos);
- z = mudflow_maxpos - (z-mudflow_minpos);
- }
-
- // Node position in 2d
- v2s16 p2d = sectorpos_base*MAP_BLOCKSIZE + v2s16(x,z);
-
- v3s16 em = vmanip.m_area.getExtent();
- u32 i = vmanip.m_area.index(v3s16(p2d.X, y_nodes_max, p2d.Y));
- s16 y=y_nodes_max;
-
- for(;; y--)
- {
- MapNode *n = NULL;
- // Find mud
- for(; y>=y_nodes_min; y--)
- {
- n = &vmanip.m_data[i];
- //if(content_walkable(n->d))
- // break;
- if(n->d == CONTENT_MUD || n->d == CONTENT_GRASS)
- break;
-
- vmanip.m_area.add_y(em, i, -1);
- }
-
- // Stop if out of area
- //if(vmanip.m_area.contains(i) == false)
- if(y < y_nodes_min)
- break;
-
- /*// If not mud, do nothing to it
- MapNode *n = &vmanip.m_data[i];
- if(n->d != CONTENT_MUD && n->d != CONTENT_GRASS)
- continue;*/
-
- /*
- Don't flow it if the stuff under it is not mud
- */
- {
- u32 i2 = i;
- vmanip.m_area.add_y(em, i2, -1);
- // Cancel if out of area
- if(vmanip.m_area.contains(i2) == false)
- continue;
- MapNode *n2 = &vmanip.m_data[i2];
- if(n2->d != CONTENT_MUD && n2->d != CONTENT_GRASS)
- continue;
- }
-
- // Make it exactly mud
- n->d = CONTENT_MUD;
-
- /*s16 recurse_count = 0;
- mudflow_recurse:*/
-
- v3s16 dirs4[4] = {
- v3s16(0,0,1), // back
- v3s16(1,0,0), // right
- v3s16(0,0,-1), // front
- v3s16(-1,0,0), // left
- };
-
- // Theck that upper is air or doesn't exist.
- // Cancel dropping if upper keeps it in place
- u32 i3 = i;
- vmanip.m_area.add_y(em, i3, 1);
- if(vmanip.m_area.contains(i3) == true
- && content_walkable(vmanip.m_data[i3].d) == true)
- {
- continue;
- }
-
- // Drop mud on side
-
- for(u32 di=0; di<4; di++)
- {
- v3s16 dirp = dirs4[di];
- u32 i2 = i;
- // Move to side
- vmanip.m_area.add_p(em, i2, dirp);
- // Fail if out of area
- if(vmanip.m_area.contains(i2) == false)
- continue;
- // Check that side is air
- MapNode *n2 = &vmanip.m_data[i2];
- if(content_walkable(n2->d))
- continue;
- // Check that under side is air
- vmanip.m_area.add_y(em, i2, -1);
- if(vmanip.m_area.contains(i2) == false)
- continue;
- n2 = &vmanip.m_data[i2];
- if(content_walkable(n2->d))
- continue;
- /*// Check that under that is air (need a drop of 2)
- vmanip.m_area.add_y(em, i2, -1);
- if(vmanip.m_area.contains(i2) == false)
- continue;
- n2 = &vmanip.m_data[i2];
- if(content_walkable(n2->d))
- continue;*/
- // Loop further down until not air
- do{
- vmanip.m_area.add_y(em, i2, -1);
- // Fail if out of area
- if(vmanip.m_area.contains(i2) == false)
- continue;
- n2 = &vmanip.m_data[i2];
- }while(content_walkable(n2->d) == false);
- // Loop one up so that we're in air
- vmanip.m_area.add_y(em, i2, 1);
- n2 = &vmanip.m_data[i2];
-
- // Move mud to new place
- *n2 = *n;
- // Set old place to be air
- *n = MapNode(CONTENT_AIR);
-
- // Done
- break;
- }
- }
- }
-
- }
-
- }//timer1
- {
- // 50ms @cs=8
- //TimeTaker timer1("add water");
-
- /*
- Add water to the central chunk (and a bit more)
- */
-
- for(s16 x=0-max_spread_amount;
- x<sectorpos_base_size*MAP_BLOCKSIZE+max_spread_amount;
- x++)
- for(s16 z=0-max_spread_amount;
- z<sectorpos_base_size*MAP_BLOCKSIZE+max_spread_amount;
- z++)
- {
- // Node position in 2d
- v2s16 p2d = sectorpos_base*MAP_BLOCKSIZE + v2s16(x,z);
-
- // Find ground level
- //s16 surface_y = find_ground_level(vmanip, p2d);
-
- /*
- If ground level is over water level, skip.
- NOTE: This leaves caves near water without water,
- which looks especially crappy when the nearby water
- won't start flowing either for some reason
- */
- /*if(surface_y > WATER_LEVEL)
- continue;*/
-
- /*
- Add water on ground
- */
- {
- v3s16 em = vmanip.m_area.getExtent();
- u8 light = LIGHT_MAX;
- // Start at global water surface level
- s16 y_start = WATER_LEVEL;
- u32 i = vmanip.m_area.index(v3s16(p2d.X, y_start, p2d.Y));
- MapNode *n = &vmanip.m_data[i];
-
- /*// Add first one to transforming liquid queue, if water
- if(n->d == CONTENT_WATER || n->d == CONTENT_WATERSOURCE)
- {
- v3s16 p = v3s16(p2d.X, y_start, p2d.Y);
- m_transforming_liquid.push_back(p);
- }*/
-
- for(s16 y=y_start; y>=y_nodes_min; y--)
- {
- n = &vmanip.m_data[i];
-
- // Stop when there is no water and no air
- if(n->d != CONTENT_AIR && n->d != CONTENT_WATERSOURCE
- && n->d != CONTENT_WATER)
- {
- /*// Add bottom one to transforming liquid queue
- vmanip.m_area.add_y(em, i, 1);
- n = &vmanip.m_data[i];
- if(n->d == CONTENT_WATER || n->d == CONTENT_WATERSOURCE)
- {
- v3s16 p = v3s16(p2d.X, y, p2d.Y);
- m_transforming_liquid.push_back(p);
- }*/
-
- break;
- }
-
- // Make water only not in dungeons
- if(!(vmanip.m_flags[i]&VMANIP_FLAG_DUNGEON))
- {
- n->d = CONTENT_WATERSOURCE;
- //n->setLight(LIGHTBANK_DAY, light);
-
- // Add to transforming liquid queue (in case it'd
- // start flowing)
- v3s16 p = v3s16(p2d.X, y, p2d.Y);
- m_transforming_liquid.push_back(p);
- }
-
- // Next one
- vmanip.m_area.add_y(em, i, -1);
- if(light > 0)
- light--;
- }
- }
-
- }
-
- }//timer1
-
- } // Aging loop
-
- {
- //TimeTaker timer1("convert mud to sand");
-
- /*
- Convert mud to sand
- */
-
- //s16 mud_add_amount = myrand_range(2, 4);
- //s16 mud_add_amount = 0;
-
- /*for(s16 x=0; x<sectorpos_base_size*MAP_BLOCKSIZE; x++)
- for(s16 z=0; z<sectorpos_base_size*MAP_BLOCKSIZE; z++)*/
- for(s16 x=0-max_spread_amount+1;
- x<sectorpos_base_size*MAP_BLOCKSIZE+max_spread_amount-1;
- x++)
- for(s16 z=0-max_spread_amount+1;
- z<sectorpos_base_size*MAP_BLOCKSIZE+max_spread_amount-1;
- z++)
- {
- // Node position in 2d
- v2s16 p2d = sectorpos_base*MAP_BLOCKSIZE + v2s16(x,z);
-
- // Determine whether to have sand here
- bool have_sand = get_have_sand_coast(p2d);
-
- if(have_sand == false)
- continue;
-
- // Find ground level
- s16 surface_y = find_ground_level_clever(vmanip, p2d);
-
- if(surface_y > WATER_LEVEL + 2)
- continue;
-
- {
- v3s16 em = vmanip.m_area.getExtent();
- s16 y_start = surface_y;
- u32 i = vmanip.m_area.index(v3s16(p2d.X, y_start, p2d.Y));
- u32 not_sand_counter = 0;
- for(s16 y=y_start; y>=y_nodes_min; y--)
- {
- MapNode *n = &vmanip.m_data[i];
- if(n->d == CONTENT_MUD || n->d == CONTENT_GRASS)
- {
- n->d = CONTENT_SAND;
- }
- else
- {
- not_sand_counter++;
- if(not_sand_counter > 3)
- break;
- }
-
- vmanip.m_area.add_y(em, i, -1);
- }
- }
-
- }
-
- }//timer1
- {
- // 1ms @cs=8
- //TimeTaker timer1("generate trees");
-
- /*
- Generate some trees
- */
- {
- // Divide area into parts
- s16 div = 8;
- s16 sidelen = sectorpos_base_size*MAP_BLOCKSIZE / div;
- double area = sidelen * sidelen;
- for(s16 x0=0; x0<div; x0++)
- for(s16 z0=0; z0<div; z0++)
- {
- // Center position of part of division
- v2s16 p2d_center(
- sectorpos_base.X*MAP_BLOCKSIZE + sidelen/2 + sidelen*x0,
- sectorpos_base.Y*MAP_BLOCKSIZE + sidelen/2 + sidelen*z0
- );
- // Minimum edge of part of division
- v2s16 p2d_min(
- sectorpos_base.X*MAP_BLOCKSIZE + sidelen*x0,
- sectorpos_base.Y*MAP_BLOCKSIZE + sidelen*z0
- );
- // Maximum edge of part of division
- v2s16 p2d_max(
- sectorpos_base.X*MAP_BLOCKSIZE + sidelen + sidelen*x0 - 1,
- sectorpos_base.Y*MAP_BLOCKSIZE + sidelen + sidelen*z0 - 1
- );
- // Amount of trees
- u32 tree_count = area * tree_amount_2d(m_seed, p2d_center);
- // Put trees in random places on part of division
- for(u32 i=0; i<tree_count; i++)
- {
- s16 x = myrand_range(p2d_min.X, p2d_max.X);
- s16 z = myrand_range(p2d_min.Y, p2d_max.Y);
- s16 y = find_ground_level(vmanip, v2s16(x,z));
- // Don't make a tree under water level
- if(y < WATER_LEVEL)
- continue;
- v3s16 p(x,y,z);
- /*
- Trees grow only on mud and grass
- */
- {
- u32 i = vmanip.m_area.index(v3s16(p));
- MapNode *n = &vmanip.m_data[i];
- if(n->d != CONTENT_MUD && n->d != CONTENT_GRASS)
- continue;
- }
- p.Y++;
- // Make a tree
- make_tree(vmanip, p);
- }
- }
- /*u32 tree_max = relative_area / 60;
- //u32 count = myrand_range(0, tree_max);
- for(u32 i=0; i<count; i++)
- {
- s16 x = myrand_range(0, sectorpos_base_size*MAP_BLOCKSIZE-1);
- s16 z = myrand_range(0, sectorpos_base_size*MAP_BLOCKSIZE-1);
- x += sectorpos_base.X*MAP_BLOCKSIZE;
- z += sectorpos_base.Y*MAP_BLOCKSIZE;
- s16 y = find_ground_level(vmanip, v2s16(x,z));
- // Don't make a tree under water level
- if(y < WATER_LEVEL)
- continue;
- v3s16 p(x,y+1,z);
- // Make a tree
- make_tree(vmanip, p);
- }*/
- }
-
- }//timer1
-
- {
- // 19ms @cs=8
- //TimeTaker timer1("grow grass");
-
- /*
- Grow grass
- */
-
- /*for(s16 x=0-4; x<sectorpos_base_size*MAP_BLOCKSIZE+4; x++)
- for(s16 z=0-4; z<sectorpos_base_size*MAP_BLOCKSIZE+4; z++)*/
- for(s16 x=0-max_spread_amount;
- x<sectorpos_base_size*MAP_BLOCKSIZE+max_spread_amount;
- x++)
- for(s16 z=0-max_spread_amount;
- z<sectorpos_base_size*MAP_BLOCKSIZE+max_spread_amount;
- z++)
- {
- // Node position in 2d
- v2s16 p2d = sectorpos_base*MAP_BLOCKSIZE + v2s16(x,z);
-
- /*
- Find the lowest surface to which enough light ends up
- to make grass grow.
-
- Basically just wait until not air and not leaves.
- */
- s16 surface_y = 0;
- {
- v3s16 em = vmanip.m_area.getExtent();
- u32 i = vmanip.m_area.index(v3s16(p2d.X, y_nodes_max, p2d.Y));
- s16 y;
- // Go to ground level
- for(y=y_nodes_max; y>=y_nodes_min; y--)
- {
- MapNode &n = vmanip.m_data[i];
- if(n.d != CONTENT_AIR
- && n.d != CONTENT_LEAVES)
- break;
- vmanip.m_area.add_y(em, i, -1);
- }
- if(y >= y_nodes_min)
- surface_y = y;
- else
- surface_y = y_nodes_min;
- }
-
- u32 i = vmanip.m_area.index(p2d.X, surface_y, p2d.Y);
- MapNode *n = &vmanip.m_data[i];
- if(n->d == CONTENT_MUD)
- n->d = CONTENT_GRASS;
- }
-
- }//timer1
-
- /*
- Initial lighting (sunlight)
- */
-
- core::map<v3s16, bool> light_sources;
-
- {
- // 750ms @cs=8, can't optimize more
- TimeTaker timer1("initial lighting");
-
-#if 0
- /*
- Go through the edges and add all nodes that have light to light_sources
- */
-
- // Four edges
- for(s16 i=0; i<4; i++)
- // Edge length
- for(s16 j=lighting_min_d;
- j<=lighting_max_d;
- j++)
- {
- s16 x;
- s16 z;
- // +-X
- if(i == 0 || i == 1)
- {
- x = (i==0) ? lighting_min_d : lighting_max_d;
- if(i == 0)
- z = lighting_min_d;
- else
- z = lighting_max_d;
- }
- // +-Z
- else
- {
- z = (i==0) ? lighting_min_d : lighting_max_d;
- if(i == 0)
- x = lighting_min_d;
- else
- x = lighting_max_d;
- }
-
- // Node position in 2d
- v2s16 p2d = sectorpos_base*MAP_BLOCKSIZE + v2s16(x,z);
-
- {
- v3s16 em = vmanip.m_area.getExtent();
- s16 y_start = y_nodes_max;
- u32 i = vmanip.m_area.index(v3s16(p2d.X, y_start, p2d.Y));
- for(s16 y=y_start; y>=y_nodes_min; y--)
- {
- MapNode *n = &vmanip.m_data[i];
- if(n->getLight(LIGHTBANK_DAY) != 0)
- {
- light_sources.insert(v3s16(p2d.X, y, p2d.Y), true);
- }
- //NOTE: This is broken, at least the index has to
- // be incremented
- }
- }
- }
-#endif
-
-#if 1
- /*
- Go through the edges and apply sunlight to them, not caring
- about neighbors
- */
-
- // Four edges
- for(s16 i=0; i<4; i++)
- // Edge length
- for(s16 j=lighting_min_d;
- j<=lighting_max_d;
- j++)
- {
- s16 x;
- s16 z;
- // +-X
- if(i == 0 || i == 1)
- {
- x = (i==0) ? lighting_min_d : lighting_max_d;
- if(i == 0)
- z = lighting_min_d;
- else
- z = lighting_max_d;
- }
- // +-Z
- else
- {
- z = (i==0) ? lighting_min_d : lighting_max_d;
- if(i == 0)
- x = lighting_min_d;
- else
- x = lighting_max_d;
- }
-
- // Node position in 2d
- v2s16 p2d = sectorpos_base*MAP_BLOCKSIZE + v2s16(x,z);
-
- // Loop from top to down
- {
- u8 light = LIGHT_SUN;
- v3s16 em = vmanip.m_area.getExtent();
- s16 y_start = y_nodes_max;
- u32 i = vmanip.m_area.index(v3s16(p2d.X, y_start, p2d.Y));
- for(s16 y=y_start; y>=y_nodes_min; y--)
- {
- MapNode *n = &vmanip.m_data[i];
- if(light_propagates_content(n->d) == false)
- {
- light = 0;
- }
- else if(light != LIGHT_SUN
- || sunlight_propagates_content(n->d) == false)
- {
- if(light > 0)
- light--;
- }
-
- n->setLight(LIGHTBANK_DAY, light);
- n->setLight(LIGHTBANK_NIGHT, 0);
-
- if(light != 0)
- {
- // Insert light source
- light_sources.insert(v3s16(p2d.X, y, p2d.Y), true);
- }
-
- // Increment index by y
- vmanip.m_area.add_y(em, i, -1);
- }
- }
- }
-#endif
-
- /*for(s16 x=0; x<sectorpos_base_size*MAP_BLOCKSIZE; x++)
- for(s16 z=0; z<sectorpos_base_size*MAP_BLOCKSIZE; z++)*/
- /*for(s16 x=0-max_spread_amount+1;
- x<sectorpos_base_size*MAP_BLOCKSIZE+max_spread_amount-1;
- x++)
- for(s16 z=0-max_spread_amount+1;
- z<sectorpos_base_size*MAP_BLOCKSIZE+max_spread_amount-1;
- z++)*/
-#if 1
- /*
- This has to be 1 smaller than the actual area, because
- neighboring nodes are checked.
- */
- for(s16 x=lighting_min_d+1;
- x<=lighting_max_d-1;
- x++)
- for(s16 z=lighting_min_d+1;
- z<=lighting_max_d-1;
- z++)
- {
- // Node position in 2d
- v2s16 p2d = sectorpos_base*MAP_BLOCKSIZE + v2s16(x,z);
-
- /*
- Apply initial sunlight
- */
- {
- u8 light = LIGHT_SUN;
- bool add_to_sources = false;
- v3s16 em = vmanip.m_area.getExtent();
- s16 y_start = y_nodes_max;
- u32 i = vmanip.m_area.index(v3s16(p2d.X, y_start, p2d.Y));
- for(s16 y=y_start; y>=y_nodes_min; y--)
- {
- MapNode *n = &vmanip.m_data[i];
-
- if(light_propagates_content(n->d) == false)
- {
- light = 0;
- }
- else if(light != LIGHT_SUN
- || sunlight_propagates_content(n->d) == false)
- {
- if(light > 0)
- light--;
- }
-
- // This doesn't take much time
- if(add_to_sources == false)
- {
- /*
- Check sides. If side is not air or water, start
- adding to light_sources.
- */
- v3s16 dirs4[4] = {
- v3s16(0,0,1), // back
- v3s16(1,0,0), // right
- v3s16(0,0,-1), // front
- v3s16(-1,0,0), // left
- };
- for(u32 di=0; di<4; di++)
- {
- v3s16 dirp = dirs4[di];
- u32 i2 = i;
- vmanip.m_area.add_p(em, i2, dirp);
- MapNode *n2 = &vmanip.m_data[i2];
- if(
- n2->d != CONTENT_AIR
- && n2->d != CONTENT_WATERSOURCE
- && n2->d != CONTENT_WATER
- ){
- add_to_sources = true;
- break;