5KZF63OICCGFAZ5E3TRS5GKZJLKQYWLGKOA7IYV4X3C6AOXB4MMAC
BEBIJRW2J3ZMUXNK7ZTKUXY6KDXZVTACUSB5XCBRN5Z3TNG6QNQAC
ON4ZQE4HSC2FJXEQZ5FAASYDAD46SD6FMHBCGL2KKDF34DFMVFHAC
QWRLAVPB4UM3B7OSNEJYN5L72NZQQBNLCM2OLOIBA6OD7IC6JW4AC
ACZYEIX7WMPIIODKCATBCUE626AJ4ZGGBOMVC6BGXM27EQU2RECAC
YGPAMROCZY2O2N4PJONW6NMFUNOFHAGT5ZA4APCXKFXQUHLEIN2AC
WY3Q6JZ3HTBF2CYFJOUVG4MMFINBK4PI2DJ625CVKMJ5BPMXAW2AC
PHJ2TT2CQ2IRXOB5KAV2664KKTPYFPFUIBEGAOQBGB4SAZ7PKNHAC
ICVDXXH2Z5MV7BLYVWQNLQSV63THIB4E6NVORIDBB7D6TBEHBXOAC
RGO2JV5HFKZFXO7KJWDXGDMNBR6NIAOMJW34NHRTLLVN2N7XGW7QC
2EBEWIV4YHXXAFR4GG2GMZJ2K77NK762HNQ77CZLHI3LDVGX7RJAC
// These store certain unique subsequences of ray_coords.
// Filled during precomputation (_create_blockrays)
std::vector<coord_def> compressed_ray;
// 3D bit array indexed by coordinate and cellray index.
// Bit los_blockrays[x][y][i] is set iff a wall at (x,y) blocks
// the cellray starting at compressed_ray[i].
// These store all unique minimal cellrays. For each i,
// cellray i ends in cellray_ends[i] and passes through
// thoses cells p that have blockrays(p)[i] set. In other
// words, blockrays(p)[i] is set iff an opaque cell p blocks
// the cellray with index i.
std::vector<coord_def> cellray_ends;
// determine nonduplicated rays
std::vector<int> nondupe_cellrays = _find_nonduped_cellrays();
const int num_nondupe_rays = nondupe_cellrays.size();
const int num_cellrays = ray_coords.size();
blockrays_t full_los_blockrays;
// First, we calculate blocking information for all cell rays.
// Cellrays are numbered according to the index of their end
// cell in ray_coords.
const int n_cellrays = ray_coords.size();
blockrays_t all_blockrays;
// we want to only keep the cellrays from nondupe_cellrays.
compressed_ray.resize(num_nondupe_rays);
for (int i = 0; i < num_nondupe_rays; ++i)
compressed_ray[i] = ray_coords[nondupe_cellrays[i]];
// Determine nonduplicated rays and store their end points.
std::vector<int> nondupe_cellrays = _find_nonduped_cellrays();
const int n_nondupe_rays = nondupe_cellrays.size();
cellray_ends.resize(n_nondupe_rays);
for (int i = 0; i < n_nondupe_rays; ++i)
cellray_ends[i] = ray_coords[nondupe_cellrays[i]];
for (int i = 0; i < num_nondupe_rays; ++i)
los_blockrays(*qi)->set(i, full_los_blockrays(*qi)
->get(nondupe_cellrays[i]));
{
blockrays(*qi) = new bit_array(n_nondupe_rays);
for (int i = 0; i < n_nondupe_rays; ++i)
blockrays(*qi)->set(i, all_blockrays(*qi)
->get(nondupe_cellrays[i]));
}
// block rays which have already seen a cloud
*dead_rays |= (*smoke_rays & *los_blockrays(*qi));
*smoke_rays |= *los_blockrays(*qi);
// Block rays which have already seen a cloud.
*dead_rays |= (*smoke_rays & *blockrays(*qi));
*smoke_rays |= *blockrays(*qi);
// this ray is alive!
const coord_def p = coord_def(sx * compressed_ray[rayidx].x,
sy * compressed_ray[rayidx].y);
// update shadow map
// This ray is alive, thus the end cell is visible.
const coord_def p = coord_def(sx * cellray_ends[rayidx].x,
sy * cellray_ends[rayidx].y);