#include #include "vars.h" #include "math.h" #include "structs.h" #include "display.h" #include "see.h" /* * See a cell. The observer's location for wall display purposes is * taken from seecell_loc. */ void seecell(LOC *lc) { if ((lc->type == LOC_WALL) || (lc->type == LOC_SDOOR)) { checkwall_from(lc,seecell_loc); } upddisp(lc); } /* * Return true if we have line-of-sight from lc to offset (dx,dy). */ static int los(LOC *lc, int dx, int dy) { int px; int py; LEVEL *lv; LOC *lc2; int i; int df; lv = lc->on; df = isqrt((dx*dx)+(dy*dy)); for (i=0;ix + ((dx * i) / df); py = lc->y + ((dy * i) / df); if (lv->flags & LVF_WRAPAROUND) { if (px < 0) px += LEV_X; else if (px >= LEV_X) px -= LEV_X; if (py < 0) py += LEV_Y; else if (py >= LEV_Y) py -= LEV_Y; } else if ((px < 0) || (py < 0) || (px >= LEV_X) || (py >= LEV_Y)) { return(0); } lc2 = &lv->cells[px][py]; if ( (lc2->type != LOC_CAVE) && ( (lc2->type != LOC_DOOR) || !(lc2->walldoor & LOC_DOOR_OPEN) ) ) { return(0); } } return(1); } /* * See level cells. lc is the observer's location. rad is the vision * radius. Each seen LOC has flg set in its flags and has (*fxn)() * called on it. perc indicates that potion-of-perception style sight * should be done (see through walls). */ void see(LOC *lc, int rad, int flg, void (*fxn)(LOC *), int perc) { int atx; int aty; int x1; int y1; int x2; int y2; int x; int y; int dx; int dy; int px; int py; int sd2; int d2; int r2; LOC *lc2; LEVEL *lv; atx = lc->x; aty = lc->y; lv = lc->on; x1 = atx - rad; x2 = atx + rad; y1 = aty - rad; y2 = aty + rad; if (! lv->flags & LVF_WRAPAROUND) { if (x1 < 0) x1 = 0; if (x2 >= LEV_X) x2 = LEV_X - 1; if (y1 < 0) y1 = 0; if (y2 >= LEV_Y) y2 = LEV_Y - 1; } r2 = rad * rad; sd2 = ((x1-atx)*(x1-atx)) + ((y1-aty)*(y1-aty)); for (x=x1,dx=x1-atx;x<=x2;x++,dx++) { px = (x < 0) ? x+LEV_X : (x >= LEV_X) ? x-LEV_X : x; d2 = sd2; for (y=y1,dy=y1-aty;y<=y2;y++,dy++) { if (d2 <= r2) { py = (y < 0) ? y+LEV_Y : (y >= LEV_Y) ? y-LEV_Y : y; if (perc || los(lc,dx,dy)) { lc2 = &lv->cells[px][py]; lc2->flags |= flg; (*fxn)(lc2); } } d2 += (2 * (y-aty)) + 1; } sd2 += (2 * (x-atx)) + 1; } }