Exemplo n.º 1
0
bool light_map::sees(int fx, int fy, int tx, int ty, int max_range)
{
 if(!INBOUNDS_LARGE(fx, fy) || !INBOUNDS_LARGE(tx, ty))
  return false;

 if (max_range >= 0 && (abs(tx - fx) > max_range || abs(ty - fy) > max_range))
  return false; // Out of range!

 int ax = abs(tx - fx) << 1;
 int ay = abs(ty - fy) << 1;
 int dx = (fx < tx) ? 1 : -1;
 int dy = (fy < ty) ? 1 : -1;
 int x = fx;
 int y = fy;

 float transparency = LIGHT_TRANSPARENCY_CLEAR;

 // TODO: [lightmap] Pull out the common code here rather than duplication
 if (ax > ay) {
  int t = ay - (ax >> 1);
  do {
   if(t >= 0 && ((y + dy != ty) || (x + dx == tx))) {
    y += dy;
    t -= ax;
   }

   x += dx;
   t += ay;

   if(c[x + LIGHTMAP_RANGE_X][y + LIGHTMAP_RANGE_Y].transparency == LIGHT_TRANSPARENCY_SOLID)
    break;

  } while(!(x == tx && y == ty));
 } else {
Exemplo n.º 2
0
bool light_map::is_outside(int dx, int dy)
{
 // We don't know and true seems a better default than false
 if (!INBOUNDS_LARGE(dx, dy))
  return true;

 return c[dx + LIGHTMAP_RANGE_X][dy + LIGHTMAP_RANGE_Y].is_outside;
}
Exemplo n.º 3
0
void light_map::generate(game* g, int x, int y, float natural_light, float luminance)
{
 build_light_cache(g, x, y);
 fill(lm, 0.0f);
 fill(sm, 0.0f);

 int dir_x[] = { 1, 0 , -1,  0 };
 int dir_y[] = { 0, 1 ,  0, -1 };
 int dir_d[] = { 180, 270, 0, 90 };

 // Daylight vision handling returned back to map due to issues it causes here
 if (natural_light > LIGHT_SOURCE_BRIGHT) {
  // Apply sunlight, first light source so just assign
  for(int sx = x - SEEX; sx <= x + SEEX; ++sx) {
   for(int sy = y - SEEY; sy <= y + SEEY; ++sy) {
    // In bright light indoor light exists to some degree
    if (!c[sx - x + LIGHTMAP_RANGE_X][sy - y + LIGHTMAP_RANGE_Y].is_outside)
     lm[sx - x + SEEX][sy - y + SEEY] = LIGHT_AMBIENT_LOW;
   }
  }
 }

 // Apply player light sources
 if (luminance > LIGHT_AMBIENT_LOW)
  apply_light_source(x, y, x, y, luminance);

 for(int sx = x - LIGHTMAP_RANGE_X; sx <= x + LIGHTMAP_RANGE_X; ++sx) {
  for(int sy = y - LIGHTMAP_RANGE_Y; sy <= y + LIGHTMAP_RANGE_Y; ++sy) {
   // When underground natural_light is 0, if this changes we need to revisit
   if (natural_light > LIGHT_AMBIENT_LOW) {
    if (!c[sx - x + LIGHTMAP_RANGE_X][sy - y + LIGHTMAP_RANGE_Y].is_outside) {
     // Apply light sources for external/internal divide
     for(int i = 0; i < 4; ++i) {
      if (INBOUNDS_LARGE(sx - x + dir_x[i], sy - y + dir_y[i]) &&
          c[sx - x + LIGHTMAP_RANGE_X + dir_x[i]][sy - y + LIGHTMAP_RANGE_Y + dir_y[i]].is_outside) {
       if (INBOUNDS(sx - x, sy - y) && c[LIGHTMAP_RANGE_X][LIGHTMAP_RANGE_Y].is_outside)
        lm[sx - x + SEEX][sy - y + SEEY] = natural_light;
       
       if (c[sx - x + LIGHTMAP_RANGE_X][sy - y + LIGHTMAP_RANGE_Y].transparency > LIGHT_TRANSPARENCY_SOLID)
       	apply_light_arc(sx, sy, dir_d[i], x, y, natural_light);
      }
	    }
    }
   }

   if (g->m.i_at(sx, sy).size() == 1 &&
       g->m.i_at(sx, sy)[0].type->id == itm_flashlight_on)
    apply_light_source(sx, sy, x, y, 20);
   
   if(g->m.ter(sx, sy) == t_lava)
    apply_light_source(sx, sy, x, y, 50);
   
   if(g->m.ter(sx, sy) == t_console)
    apply_light_source(sx, sy, x, y, 3);

   if (g->m.i_at(sx, sy).size() == 1 &&
       g->m.i_at(sx, sy)[0].type->id == itm_candle_lit)
    apply_light_source(sx, sy, x, y, 4);

   if(g->m.ter(sx, sy) == t_emergency_light)
    apply_light_source(sx, sy, x, y, 3);

   // TODO: [lightmap] Attach light brightness to fields
   switch(g->m.field_at(sx, sy).type) {
    case fd_fire:
     if (3 == g->m.field_at(sx, sy).density)
      apply_light_source(sx, sy, x, y, 160);
     else if (2 == g->m.field_at(sx, sy).density)
      apply_light_source(sx, sy, x, y, 60);
     else
      apply_light_source(sx, sy, x, y, 16);
     break;
    case fd_fire_vent:
    case fd_flame_burst:
     apply_light_source(sx, sy, x, y, 8);
     break;
    case fd_electricity:
     if (3 == g->m.field_at(sx, sy).density)
      apply_light_source(sx, sy, x, y, 8);
     else if (2 == g->m.field_at(sx, sy).density)
      apply_light_source(sx, sy, x, y, 1);
     else
      apply_light_source(sx, sy, x, y, LIGHT_SOURCE_LOCAL);  // kinda a hack as the square will still get marked
     break;
   }

   // Apply any vehicle light sources
   if (c[sx - x + LIGHTMAP_RANGE_X][sy - y + LIGHTMAP_RANGE_Y].veh &&
       c[sx - x + LIGHTMAP_RANGE_X][sy - y + LIGHTMAP_RANGE_Y].veh_light > LL_DARK) {
    if (c[sx - x + LIGHTMAP_RANGE_X][sy - y + LIGHTMAP_RANGE_Y].veh_light > LL_LIT) {
     int dir = c[sx - x + LIGHTMAP_RANGE_X][sy - y + LIGHTMAP_RANGE_Y].veh->face.dir();
     float luminance = c[sx - x + LIGHTMAP_RANGE_X][sy - y + LIGHTMAP_RANGE_Y].veh_light;
     apply_light_arc(sx, sy, dir, x, y, luminance);
    }
   }

   if (c[sx - x + LIGHTMAP_RANGE_X][sy - y + LIGHTMAP_RANGE_Y].mon >= 0) {
    if (g->z[c[sx - x + LIGHTMAP_RANGE_X][sy - y + LIGHTMAP_RANGE_Y].mon].has_effect(ME_ONFIRE))
     apply_light_source(sx, sy, x, y, 3);

    // TODO: [lightmap] Attach natural light brightness to creatures
    // TODO: [lightmap] Allow creatures to have light attacks (ie: eyebot)
    // TODO: [lightmap] Allow creatures to have facing and arc lights
    switch(g->z[c[sx - x + LIGHTMAP_RANGE_X][sy - y + LIGHTMAP_RANGE_Y].mon].type->id) {
     case mon_zombie_electric:
      apply_light_source(sx, sy, x, y, 1);
      break;
     case mon_flaming_eye:
      apply_light_source(sx, sy, x, y, LIGHT_SOURCE_BRIGHT);
      break;
     case mon_manhack:
      apply_light_source(sx, sy, x, y, LIGHT_SOURCE_LOCAL);
      break;
    }
   }
  }
 }
}
Exemplo n.º 4
0
void light_map::generate(game* g, int x, int y, float natural_light, float luminance)
{
 build_light_cache(g, x, y);
 memset(lm, 0, sizeof(lm));
 memset(sm, 0, sizeof(sm));

 int dir_x[] = { 1, 0 , -1,  0 };
 int dir_y[] = { 0, 1 ,  0, -1 };
 int dir_d[] = { 180, 270, 0, 90 };


//g->add_msg("natural_light %f", natural_light);

//CAT-mgs: this is just for indoors to initialize it at low ambient light
 if(natural_light > LIGHT_AMBIENT_LOW) // LIGHT_SOURCE_BRIGHT
 {
	for(int sx = x - CAT_VX; sx <= x + CAT_VX; ++sx)
	{
		for(int sy = y - CAT_VY; sy <= y + CAT_VY; ++sy)
		{
			if(!is_outside(sx - x + g->u.view_offset_x, sy - y + g->u.view_offset_y))
				lm[sx - x + CAT_VX][sy - y + CAT_VY] = LIGHT_AMBIENT_LOW;	
		}
	}
 }


 if(luminance > LIGHT_AMBIENT_LOW)
  apply_light_source(g->u.posx, g->u.posy, x, y, luminance);


 for(int sx = x - LIGHTMAP_RANGE_X; sx <= x + LIGHTMAP_RANGE_X; ++sx) {
  for(int sy = y - LIGHTMAP_RANGE_Y; sy <= y + LIGHTMAP_RANGE_Y; ++sy) {
   const ter_id terrain = g->m.ter(sx, sy);
   const std::vector<item> items = g->m.i_at(sx, sy);
   const field current_field = g->m.field_at(sx, sy);

   // When underground natural_light is 0, if this changes we need to revisit
   if (natural_light > LIGHT_AMBIENT_LOW) {

    int lx= sx - x  + g->u.view_offset_x;
    int ly= sy - y + g->u.view_offset_y;

    if(!is_outside(lx, ly)) {
     // Apply light sources for external/internal divide
     for(int i = 0; i < 4; ++i) {
      if(INBOUNDS_LARGE(lx + dir_x[i], ly + dir_y[i])
			&& is_outside(lx + dir_x[i], ly + dir_y[i]))
	{

//CAT-mgs: I did that above, didn't I?
//... no, yes, what's this for anyway?
		if(INBOUNDS(sx - x, sy - y) && is_outside(0, 0))
			lm[sx - x + CAT_VX][sy - y + CAT_VY]= natural_light;

		if(c[sx - x + LIGHTMAP_RANGE_X][sy - y + LIGHTMAP_RANGE_Y].transparency > LIGHT_TRANSPARENCY_SOLID)
			apply_light_arc(sx, sy, dir_d[i], x, y, natural_light);
      }
     }
    }
   }


//CAT-g:
   if(items.size() > 0)
   {
	   if(items[0].type->id == itm_flashlight_on
			|| items[items.size()-1].type->id == itm_flashlight_on)
		apply_light_source(sx, sy, x, y, 48); 

	   if(items[0].type->id == itm_torch_lit
			|| items[items.size()-1].type->id == itm_torch_lit)
		apply_light_source(sx, sy, x, y, 20);

	   if(items[0].type->id == itm_candle_lit
			|| items[items.size()-1].type->id == itm_candle_lit)
		apply_light_source(sx, sy, x, y, 9); 
   }


   if(terrain == t_lava)
    apply_light_source(sx, sy, x, y, 48);

   if(terrain == t_console)
    apply_light_source(sx, sy, x, y, 3);

   if(terrain == t_emergency_light)
    apply_light_source(sx, sy, x, y, 3);



   // TODO: [lightmap] Attach light brightness to fields
   switch(current_field.type) {
    case fd_fire:
     if(current_field.density > 5)
      apply_light_source(sx, sy, x, y, 48);
     else if (current_field.density > 2)
      apply_light_source(sx, sy, x, y, 20);
     else
      apply_light_source(sx, sy, x, y, 9);
     break;
    case fd_fire_vent:
      apply_light_source(sx, sy, x, y, 3);
    case fd_flame_burst:
      apply_light_source(sx, sy, x, y, 8);
     break;
    case fd_electricity:
     if (3 == current_field.density)
      apply_light_source(sx, sy, x, y, 9);
     else if (2 == current_field.density)
      apply_light_source(sx, sy, x, y, 1);
     else
      apply_light_source(sx, sy, x, y, LIGHT_SOURCE_LOCAL);  // kinda a hack as the square will still get marked
     break;
   }

   // Apply any vehicle light sources
   if (c[sx - x + LIGHTMAP_RANGE_X][sy - y + LIGHTMAP_RANGE_Y].veh &&
       c[sx - x + LIGHTMAP_RANGE_X][sy - y + LIGHTMAP_RANGE_Y].veh_light > LL_DARK) {
    if (c[sx - x + LIGHTMAP_RANGE_X][sy - y + LIGHTMAP_RANGE_Y].veh_light > LL_LIT) {
     int dir = c[sx - x + LIGHTMAP_RANGE_X][sy - y + LIGHTMAP_RANGE_Y].veh->face.dir();

//CAT-g: longer range headlights
//     float luminance = c[sx - x + LIGHTMAP_RANGE_X][sy - y + LIGHTMAP_RANGE_Y].veh_light;
	 float luminance = 4000 + c[sx - x + LIGHTMAP_RANGE_X][sy - y + LIGHTMAP_RANGE_Y].veh_light;    

	apply_light_arc(sx, sy, dir, x, y, luminance);
    }
   }

   if (c[sx - x + LIGHTMAP_RANGE_X][sy - y + LIGHTMAP_RANGE_Y].mon >= 0) {
    if (g->z[c[sx - x + LIGHTMAP_RANGE_X][sy - y + LIGHTMAP_RANGE_Y].mon].has_effect(ME_ONFIRE))
     apply_light_source(sx, sy, x, y, 3);

    // TODO: [lightmap] Attach natural light brightness to creatures
    // TODO: [lightmap] Allow creatures to have light attacks (ie: eyebot)
    // TODO: [lightmap] Allow creatures to have facing and arc lights
    switch(g->z[c[sx - x + LIGHTMAP_RANGE_X][sy - y + LIGHTMAP_RANGE_Y].mon].type->id) {
     case mon_zombie_electric:
      apply_light_source(sx, sy, x, y, 1);
      break;
     case mon_turret:
      apply_light_source(sx, sy, x, y, 2);
      break;
     case mon_flaming_eye:
      apply_light_source(sx, sy, x, y, LIGHT_SOURCE_BRIGHT);
      break;
     case mon_manhack:
      apply_light_source(sx, sy, x, y, LIGHT_SOURCE_LOCAL);
      break;
    }
   }
  }
 }

}