Skip to content

Commit 0338c2e

Browse files
committedMar 29, 2016
Mapgen: Spread both night and day light banks in spreadLight
1 parent 8f43aaf commit 0338c2e

File tree

1 file changed

+40
-11
lines changed

1 file changed

+40
-11
lines changed
 

‎src/mapgen.cpp

+40-11
Original file line numberDiff line numberDiff line change
@@ -242,18 +242,38 @@ void Mapgen::setLighting(u8 light, v3s16 nmin, v3s16 nmax)
242242

243243
void Mapgen::lightSpread(VoxelArea &a, v3s16 p, u8 light)
244244
{
245-
if (light <= 1 || !a.contains(p))
245+
if (light <= 1)
246246
return;
247247

248248
u32 vi = vm->m_area.index(p);
249-
MapNode &nn = vm->m_data[vi];
249+
if (!a.contains(vi))
250+
return;
251+
252+
MapNode &n = vm->m_data[vi];
253+
254+
// Decay light in each of the banks separately
255+
u8 light_day = light & 0x0F;
256+
if (light_day > 0)
257+
light_day -= 0x01;
250258

251-
light--;
252-
// should probably compare masked, but doesn't seem to make a difference
253-
if (light <= nn.param1 || !ndef->get(nn).light_propagates)
259+
u8 light_night = light & 0xF0;
260+
if (light_night > 0)
261+
light_night -= 0x10;
262+
263+
// Bail out only if we have no more light from either bank to propogate, or
264+
// we hit a solid block that light cannot pass through.
265+
if ((light_day <= (n.param1 & 0x0F) &&
266+
light_night <= (n.param1 & 0xF0)) ||
267+
!ndef->get(n).light_propagates)
254268
return;
255269

256-
nn.param1 = light;
270+
// Since this recursive function only terminates when there is no light from
271+
// either bank left, we need to take the max of both banks into account for
272+
// the case where spreading has stopped for one light bank but not the other.
273+
light = MYMAX(light_day, n.param1 & 0x0F) |
274+
MYMAX(light_night, n.param1 & 0xF0);
275+
276+
n.param1 = light;
257277

258278
lightSpread(a, p + v3s16(0, 0, 1), light);
259279
lightSpread(a, p + v3s16(0, 1, 0), light);
@@ -284,6 +304,9 @@ void Mapgen::propagateSunlight(v3s16 nmin, v3s16 nmax, bool propagate_shadow)
284304
bool block_is_underground = (water_level >= nmax.Y);
285305
v3s16 em = vm->m_area.getExtent();
286306

307+
// NOTE: Direct access to the low 4 bits of param1 is okay here because,
308+
// by definition, sunlight will never be in the night lightbank.
309+
287310
for (int z = a.MinEdge.Z; z <= a.MaxEdge.Z; z++) {
288311
for (int x = a.MinEdge.X; x <= a.MaxEdge.X; x++) {
289312
// see if we can get a light value from the overtop
@@ -320,15 +343,21 @@ void Mapgen::spreadLight(v3s16 nmin, v3s16 nmax)
320343
u32 i = vm->m_area.index(a.MinEdge.X, y, z);
321344
for (int x = a.MinEdge.X; x <= a.MaxEdge.X; x++, i++) {
322345
MapNode &n = vm->m_data[i];
323-
if (n.getContent() == CONTENT_IGNORE ||
324-
!ndef->get(n).light_propagates)
346+
if (n.getContent() == CONTENT_IGNORE)
347+
continue;
348+
349+
const ContentFeatures &cf = ndef->get(n);
350+
if (!cf.light_propagates)
325351
continue;
326352

327-
u8 light_produced = ndef->get(n).light_source & 0x0F;
353+
// TODO(hmmmmm): Abstract away direct param1 accesses with a
354+
// wrapper, but something lighter than MapNode::get/setLight
355+
356+
u8 light_produced = cf.light_source;
328357
if (light_produced)
329-
n.param1 = light_produced;
358+
n.param1 = light_produced | (light_produced << 4);
330359

331-
u8 light = n.param1 & 0x0F;
360+
u8 light = n.param1;
332361
if (light) {
333362
lightSpread(a, v3s16(x, y, z + 1), light);
334363
lightSpread(a, v3s16(x, y + 1, z ), light);

0 commit comments

Comments
 (0)