--- deliantra/server/common/los.C 2008/12/24 01:37:23 1.51 +++ deliantra/server/common/los.C 2008/12/27 07:50:05 1.54 @@ -103,6 +103,8 @@ calculate_los (player *pl) { { + memset (los, 0, sizeof (los)); + // we keep one line for ourselves, for the border flag // so the client area is actually MAP_CLIENT_(X|Y) - 2 int half_x = min (LOS_X0 - 1, pl->ns->mapx / 2); @@ -120,14 +122,15 @@ // now reset the los area and also add blocked flags // which supposedly is faster than doing it inside the // spiral path algorithm below, except when very little - // area is visible, in which case it is slower, evening + // area is visible, in which case it is slower. which evens // out los calculation times between large and small los maps. // apply_lights also iterates over this area, maybe these // two passes could be combined somehow. - rectangular_mapspace_iterate_begin (pl->observe, -half_x, half_x, -half_y, half_y) - los_info &l = los [LOS_X0 + dx][LOS_Y0 + dy]; - l.flags = m && m->at (nx, ny).flags () & P_BLOCKSVIEW ? FLG_BLOCKED : 0; - rectangular_mapspace_iterate_end + unordered_mapwalk (pl->observe, -half_x, -half_y, half_x, half_y) + { + los_info &l = los [LOS_X0 + dx][LOS_Y0 + dy]; + l.flags = m->at (nx, ny).flags () & P_BLOCKSVIEW ? FLG_BLOCKED : 0; + } } q1 = 0; q2 = 0; // initialise queue, not strictly required @@ -363,6 +366,13 @@ int pass2 = 0; // negative lights have an extra pass + maprect *rects = pl->observe->map->split_to_tiles ( + pl->observe->x - half_x - MAX_LIGHT_RADIUS, + pl->observe->y - half_y - MAX_LIGHT_RADIUS, + pl->observe->x + half_x + MAX_LIGHT_RADIUS + 1, + pl->observe->y + half_y + MAX_LIGHT_RADIUS + 1 + ); + if (!darklevel) pass2 = 1; else @@ -378,8 +388,8 @@ * array. Its easier to just increment them here (and start with the right * value) than to recalculate them down below. */ - rectangular_mapspace_iterate_begin (pl->observe, -half_x - MAX_LIGHT_RADIUS, half_x + MAX_LIGHT_RADIUS, -half_y - MAX_LIGHT_RADIUS, half_y + MAX_LIGHT_RADIUS) - if (m) + for (maprect *r = rects; r->m; ++r) + rect_mapwalk (r, 0, 0) { mapspace &ms = m->at (nx, ny); ms.update (); @@ -389,9 +399,8 @@ if (light < 0) pass2 = 1; else - apply_light (pl, dx, dy, light, light_atten [light + MAX_LIGHT_RADIUS]); + apply_light (pl, dx - pl->observe->x, dy - pl->observe->y, light, light_atten [light + MAX_LIGHT_RADIUS]); } - rectangular_mapspace_iterate_end /* grant some vision to the player, based on the darklevel */ { @@ -409,17 +418,16 @@ // for effect, those are always considered to be stronger than anything else // but they can't darken a place completely if (pass2) - rectangular_mapspace_iterate_begin (pl->observe, -half_x - MAX_LIGHT_RADIUS, half_x + MAX_LIGHT_RADIUS, -half_y - MAX_LIGHT_RADIUS, half_y + MAX_LIGHT_RADIUS) - if (m) - { - mapspace &ms = m->at (nx, ny); - ms.update (); - sint8 light = ms.light; - - if (expect_false (light < 0)) - apply_light (pl, dx, dy, -light, light_atten [light + MAX_LIGHT_RADIUS]); - } - rectangular_mapspace_iterate_end + for (maprect *r = rects; r->m; ++r) + rect_mapwalk (r, 0, 0) + { + mapspace &ms = m->at (nx, ny); + ms.update (); + sint8 light = ms.light; + + if (expect_false (light < 0)) + apply_light (pl, dx - pl->observe->x, dy - pl->observe->y, -light, light_atten [light + MAX_LIGHT_RADIUS]); + } } /* blinded_sight() - sets all viewable squares to blocked except @@ -496,6 +504,10 @@ void update_all_los (const maptile *map, int x, int y) { + // no need to do anything if we don't have darkness + if (map->darklevel () <= 0) + return; + map->at (x, y).invalidate (); for_all_players (pl) @@ -516,10 +528,8 @@ * some. */ if (pl->ob->map == map) - { - if ((abs (pl->ob->x - x) <= pl->ns->mapx / 2) && (abs (pl->ob->y - y) <= pl->ns->mapy / 2)) - pl->do_los = 1; - } + if ((abs (pl->ob->x - x) <= pl->ns->mapx / 2) && (abs (pl->ob->y - y) <= pl->ns->mapy / 2)) + pl->do_los = 1; /* Now we check to see if player is on adjacent * maps to the one that changed and also within @@ -638,3 +648,4 @@ pl->ob->y + pl->ns->mapy / 2 >= op->y && pl->ob->x - pl->ns->mapx / 2 <= op->x && pl->ob->x + pl->ns->mapx / 2 >= op->x) pl->do_los = 1; } +