Example #1
0
void paintLight(lightSource *theLight, short x, short y, boolean isMinersLight) {
	short i, j, k;
	short colorComponents[3], randComponent, lightMultiplier, thisComponent;
	short fadeToPercent;
	float radius;
	char grid[DCOLS][DROWS];
	boolean dispelShadows;
	
#ifdef BROGUE_ASSERTS
	assert(rogue.RNG == RNG_SUBSTANTIVE);
#endif
	
	radius = randClump(theLight->lightRadius);
	radius /= 100;
	
	randComponent = rand_range(0, theLight->lightColor->rand);
	colorComponents[0] = randComponent + theLight->lightColor->red + rand_range(0, theLight->lightColor->redRand);
	colorComponents[1] = randComponent + theLight->lightColor->green + rand_range(0, theLight->lightColor->greenRand);
	colorComponents[2] = randComponent + theLight->lightColor->blue + rand_range(0, theLight->lightColor->blueRand);
	
	// the miner's light does not dispel IS_IN_SHADOW,
	// so the player can be in shadow despite casting his own light.
	dispelShadows = !isMinersLight && colorComponents[0] + colorComponents[1] + colorComponents[2] > 0;
	
	fadeToPercent = theLight->radialFadeToPercent;
	
	// zero out only the relevant rectangle of the grid
	for (i = max(0, x - radius); i < DCOLS && i < x + radius; i++) {
		for (j = max(0, y - radius); j < DROWS && j < y + radius; j++) {
			grid[i][j] = 0;
		}
	}
	
	getFOVMask(grid, x, y, radius, T_OBSTRUCTS_VISION, (theLight->passThroughCreatures ? 0 : (HAS_MONSTER | HAS_PLAYER)),
			   (!isMinersLight));
	
	for (i = max(0, x - radius); i < DCOLS && i < x + radius; i++) {
		for (j = max(0, y - radius); j < DROWS && j < y + radius; j++) {
			if (grid[i][j]) {
				lightMultiplier = 100 - (100 - fadeToPercent) * (sqrt((i-x) * (i-x) + (j-y) * (j-y)) / (radius));
				for (k=0; k<3; k++) {
						thisComponent = colorComponents[k] * lightMultiplier / 100;
						tmap[i][j].light[k] += thisComponent;
				}
				if (dispelShadows) {
					pmap[i][j].flags &= ~IS_IN_SHADOW;
				}
			}
		}
	}
	
	tmap[x][y].light[0] += colorComponents[0];
	tmap[x][y].light[1] += colorComponents[1];
	tmap[x][y].light[2] += colorComponents[2];
	
	if (dispelShadows) {
		pmap[x][y].flags &= ~IS_IN_SHADOW;
	}
}
Example #2
0
// Returns true if any part of the light hit cells that are in the player's field of view.
boolean paintLight(lightSource *theLight, short x, short y, boolean isMinersLight, boolean maintainShadows) {
	short i, j, k;
	short colorComponents[3], randComponent, lightMultiplier;
	short fadeToPercent;
	double radius;
	char grid[DCOLS][DROWS];
	boolean dispelShadows, overlappedFieldOfView;
	
#ifdef BROGUE_ASSERTS
	assert(rogue.RNG == RNG_SUBSTANTIVE);
#endif
	
	radius = randClump(theLight->lightRadius);
	radius /= 100;
	
	randComponent = rand_range(0, theLight->lightColor->rand);
	colorComponents[0] = randComponent + theLight->lightColor->red + rand_range(0, theLight->lightColor->redRand);
	colorComponents[1] = randComponent + theLight->lightColor->green + rand_range(0, theLight->lightColor->greenRand);
	colorComponents[2] = randComponent + theLight->lightColor->blue + rand_range(0, theLight->lightColor->blueRand);
	
	// the miner's light does not dispel IS_IN_SHADOW,
	// so the player can be in shadow despite casting his own light.
	dispelShadows = !maintainShadows && (colorComponents[0] + colorComponents[1] + colorComponents[2]) > 0;
	
	fadeToPercent = theLight->radialFadeToPercent;
	
	// zero out only the relevant rectangle of the grid
	for (i = max(0, x - (radius + FLOAT_FUDGE)); i < DCOLS && i < x + radius + FLOAT_FUDGE; i++) {
		for (j = max(0, y - (radius + FLOAT_FUDGE)); j < DROWS && j < y + radius + FLOAT_FUDGE; j++) {
			grid[i][j] = 0;
		}
	}
	
	getFOVMask(grid, x, y, radius, T_OBSTRUCTS_VISION, (theLight->passThroughCreatures ? 0 : (HAS_MONSTER | HAS_PLAYER)),
			   (!isMinersLight));
    
    overlappedFieldOfView = false;
	
	for (i = max(0, x - (radius + FLOAT_FUDGE)); i < DCOLS && i < x + radius; i++) {
		for (j = max(0, y - (radius + FLOAT_FUDGE)); j < DROWS && j < y + radius; j++) {
			if (grid[i][j]) {
				lightMultiplier = 100 - (100 - fadeToPercent) * (sqrt((i-x) * (i-x) + (j-y) * (j-y)) / radius + FLOAT_FUDGE);
				for (k=0; k<3; k++) {
					tmap[i][j].light[k] += colorComponents[k] * lightMultiplier / 100;
				}
				if (dispelShadows) {
					pmap[i][j].flags &= ~IS_IN_SHADOW;
				}
                if (pmap[i][j].flags & (IN_FIELD_OF_VIEW | ANY_KIND_OF_VISIBLE)) {
                    overlappedFieldOfView = true;
                }
			}
		}
	}

	for (i = x - radius - 1; i < x + radius + 1; i++)
	{
		if (i < 0 || i >= DCOLS + 1)
		{
			continue;
		}

		for (j = y - radius - 1; j < y + radius + 1; j++)
		{
			boolean visible = false;

			if (j < 0 || j >= DROWS + 1)
			{
				continue;
			}

			if (i > 0 && j > 0 && grid[i - 1][j - 1])
			{
				visible = true;
			}
			if (i < DCOLS && j > 0 && grid[i][j - 1])
			{
				visible = true;
			}
			if (i > 0 && j < DROWS && grid[i - 1][j])
			{
				visible = true;
			}
			if (i < DCOLS && j < DROWS && grid[i][j])
			{
				visible = true;
			}

			if (visible)
			{
				lightMultiplier = 100 - (100 - fadeToPercent) * (sqrt((i - x + 0.5) * (i - x + 0.5) + (j - y + 0.5) * (j - y + 0.5)) / radius + FLOAT_FUDGE);
				if (lightMultiplier > 0) {
					for (k=0; k<3; k++) {
						lightmap[i][j].light[k] += colorComponents[k] * lightMultiplier / 100;
					}
				}
			}
		}
	}
	
	tmap[x][y].light[0] += colorComponents[0];
	tmap[x][y].light[1] += colorComponents[1];
	tmap[x][y].light[2] += colorComponents[2];
	
	if (dispelShadows) {
		pmap[x][y].flags &= ~IS_IN_SHADOW;
	}
    
    return overlappedFieldOfView;
}