implement #986 - camera flash 'tweak'
Implement the suggested feature that a camera's flash actually update hero's memory of the map as it traverses across the level. Turned out to be more work than anticipated despite having the code for a thrown or kicked lit candle or lamp to build upon. Among other things it needed to update the circle code to handle previously unused radius 0 to operate on the center point only. I've never touched that before and hope this hasn't introduced any bugs. Also removes several instances of vision code operating on column #0. (At least one is still present.)
This commit is contained in:
@@ -324,6 +324,8 @@ extended achievement and conduct fields for xlogfile
|
||||
record amount of gold in hero's possession in xlogfile
|
||||
new objects: amulets of flying and guarding
|
||||
new monsters: displacer beast ('f') and genetic engineer ('Q')
|
||||
make camera flash which reveals previously unseen map features or objects or
|
||||
monsters record those on the hero's map; monsters revert to 'unseen'
|
||||
|
||||
|
||||
Platform- and/or Interface-Specific New Features
|
||||
|
||||
@@ -52,7 +52,7 @@
|
||||
/*
|
||||
* Circle information
|
||||
*/
|
||||
#define MAX_RADIUS 15 /* this is in points from the source */
|
||||
#define MAX_RADIUS 16 /* this is in points from the source */
|
||||
|
||||
/* Use this macro to get a list of distances of the edges (see vision.c). */
|
||||
#define circle_ptr(z) (&circle_data[(int) circle_start[z]])
|
||||
|
||||
15
src/apply.c
15
src/apply.c
@@ -75,11 +75,16 @@ struct obj *obj;
|
||||
(u.dz > 0) ? surface(u.ux, u.uy) : ceiling(u.ux, u.uy));
|
||||
} else if (!u.dx && !u.dy) {
|
||||
(void) zapyourself(obj, TRUE);
|
||||
} else if ((mtmp = bhit(u.dx, u.dy, COLNO, FLASHED_LIGHT,
|
||||
(int FDECL((*), (MONST_P, OBJ_P))) 0,
|
||||
(int FDECL((*), (OBJ_P, OBJ_P))) 0, &obj)) != 0) {
|
||||
obj->ox = u.ux, obj->oy = u.uy;
|
||||
(void) flash_hits_mon(mtmp, obj);
|
||||
} else {
|
||||
mtmp = bhit(u.dx, u.dy, COLNO, FLASHED_LIGHT,
|
||||
(int FDECL((*), (MONST_P, OBJ_P))) 0,
|
||||
(int FDECL((*), (OBJ_P, OBJ_P))) 0, &obj);
|
||||
obj->ox = u.ux, obj->oy = u.uy; /* flash_hits_mon() wants this */
|
||||
if (mtmp)
|
||||
(void) flash_hits_mon(mtmp, obj);
|
||||
/* normally bhit() would do this but for FLASHED_LIGHT we want it
|
||||
to be deferred until after flash_hits_mon() */
|
||||
transient_light_cleanup();
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
158
src/light.c
158
src/light.c
@@ -41,6 +41,9 @@
|
||||
#define LSF_SHOW 0x1 /* display the light source */
|
||||
#define LSF_NEEDS_FIXUP 0x2 /* need oid fixup */
|
||||
|
||||
static light_source *FDECL(new_light_core, (XCHAR_P, XCHAR_P, int, int,
|
||||
anything *));
|
||||
static void NDECL(discard_flashes);
|
||||
static void FDECL(write_ls, (NHFILE *, light_source *));
|
||||
static int FDECL(maybe_write_ls, (NHFILE *, int, BOOLEAN_P));
|
||||
|
||||
@@ -49,18 +52,31 @@ extern char circle_data[];
|
||||
extern char circle_start[];
|
||||
|
||||
|
||||
/* Create a new light source. */
|
||||
/* Create a new light source. Caller (and extern.h) doesn't need to know
|
||||
anything about type 'light_source'. */
|
||||
void
|
||||
new_light_source(x, y, range, type, id)
|
||||
xchar x, y;
|
||||
int range, type;
|
||||
anything *id;
|
||||
{
|
||||
(void) new_light_core(x, y, range, type, id);
|
||||
}
|
||||
|
||||
/* Create a new light source and return it. Only used within this file. */
|
||||
static light_source *
|
||||
new_light_core(x, y, range, type, id)
|
||||
xchar x, y;
|
||||
int range, type;
|
||||
anything *id;
|
||||
{
|
||||
light_source *ls;
|
||||
|
||||
if (range > MAX_RADIUS || range < 1) {
|
||||
impossible("new_light_source: illegal range %d", range);
|
||||
return;
|
||||
if (range > MAX_RADIUS || range < 0
|
||||
/* camera flash uses radius 0 and passes Null object */
|
||||
|| (range == 0 && (type != LS_OBJECT || id->a_obj != 0))) {
|
||||
impossible("new_light_source: illegal range %d", range);
|
||||
return (light_source *) 0;
|
||||
}
|
||||
|
||||
ls = (light_source *) alloc(sizeof *ls);
|
||||
@@ -75,6 +91,7 @@ new_light_source(x, y, range, type, id)
|
||||
g.light_base = ls;
|
||||
|
||||
g.vision_full_recalc = 1; /* make the source show up */
|
||||
return ls;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -95,7 +112,7 @@ anything *id;
|
||||
(in particular: chameleon vs prot. from shape changers) */
|
||||
switch (type) {
|
||||
case LS_OBJECT:
|
||||
tmp_id.a_uint = id->a_obj->o_id;
|
||||
tmp_id.a_uint = id->a_obj ? id->a_obj->o_id : 0;
|
||||
break;
|
||||
case LS_MONSTER:
|
||||
tmp_id.a_uint = id->a_monst->m_id;
|
||||
@@ -145,7 +162,8 @@ char **cs_rows;
|
||||
* vision recalc.
|
||||
*/
|
||||
if (ls->type == LS_OBJECT) {
|
||||
if (get_obj_location(ls->id.a_obj, &ls->x, &ls->y, 0))
|
||||
if (ls->range == 0 /* camera flash; caller has set ls->{x,y} */
|
||||
|| get_obj_location(ls->id.a_obj, &ls->x, &ls->y, 0))
|
||||
ls->flags |= LSF_SHOW;
|
||||
} else if (ls->type == LS_MONSTER) {
|
||||
if (get_mon_location(ls->id.a_monst, &ls->x, &ls->y, 0))
|
||||
@@ -177,8 +195,8 @@ char **cs_rows;
|
||||
for (; y <= max_y; y++) {
|
||||
row = cs_rows[y];
|
||||
offset = limits[abs(y - ls->y)];
|
||||
if ((min_x = (ls->x - offset)) < 0)
|
||||
min_x = 0;
|
||||
if ((min_x = (ls->x - offset)) < 1)
|
||||
min_x = 1;
|
||||
if ((max_x = (ls->x + offset)) >= COLNO)
|
||||
max_x = COLNO - 1;
|
||||
|
||||
@@ -210,62 +228,94 @@ char **cs_rows;
|
||||
|
||||
/* lit 'obj' has been thrown or kicked and is passing through x,y on the
|
||||
way to its destination; show its light so that hero has a chance to
|
||||
remember terrain, objects, and monsters being revealed */
|
||||
remember terrain, objects, and monsters being revealed;
|
||||
if 'obj' is Null, <x,y> is being hit by a camera's light flash */
|
||||
void
|
||||
show_transient_light(obj, x, y)
|
||||
struct obj *obj;
|
||||
int x, y;
|
||||
{
|
||||
light_source *ls;
|
||||
light_source *ls = 0;
|
||||
anything cameraflash;
|
||||
struct monst *mon;
|
||||
int radius_squared;
|
||||
|
||||
/* caller has verified obj->lamplit and that hero is not Blind;
|
||||
validate light source and obtain its radius (for monster sightings) */
|
||||
for (ls = g.light_base; ls; ls = ls->next) {
|
||||
if (ls->type != LS_OBJECT)
|
||||
continue;
|
||||
if (ls->id.a_obj == obj)
|
||||
break;
|
||||
/* Null object indicates camera flash */
|
||||
if (!obj) {
|
||||
/* no need to temporarily light an already lit spot */
|
||||
if (levl[x][y].lit)
|
||||
return;
|
||||
|
||||
cameraflash = cg.zeroany;
|
||||
/* radius 0 will just light <x,y>; cameraflash.a_obj is Null */
|
||||
ls = new_light_core(x, y, 0, LS_OBJECT, &cameraflash);
|
||||
} else {
|
||||
/* thrown or kicked object which is emitting light; validate its
|
||||
light source to obtain its radius (for monster sightings) */
|
||||
for (ls = g.light_base; ls; ls = ls->next) {
|
||||
if (ls->type != LS_OBJECT)
|
||||
continue;
|
||||
if (ls->id.a_obj == obj)
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!ls || obj->where != OBJ_FREE) {
|
||||
if (!ls || (obj && obj->where != OBJ_FREE)) {
|
||||
impossible("transient light %s %s is not %s?",
|
||||
obj->lamplit ? "lit" : "unlit", xname(obj),
|
||||
!ls ? "a light source" : "free");
|
||||
} else {
|
||||
/* "expensive" but rare */
|
||||
place_object(obj, g.bhitpos.x, g.bhitpos.y); /* temporarily put on map */
|
||||
vision_recalc(0);
|
||||
flush_screen(0);
|
||||
delay_output();
|
||||
remove_object(obj); /* take back off of map */
|
||||
return;
|
||||
}
|
||||
|
||||
radius_squared = ls->range * ls->range;
|
||||
for (mon = fmon; mon; mon = mon->nmon) {
|
||||
if (DEADMONSTER(mon))
|
||||
continue;
|
||||
/* light range is the radius of a circle and we're limiting
|
||||
canseemon() to a square exclosing that circle, but setting
|
||||
mtemplit 'erroneously' for a seen monster is not a problem;
|
||||
it just flags monsters for another canseemon() check when
|
||||
'obj' has reached its destination after missile traversal */
|
||||
if (dist2(mon->mx, mon->my, x, y) <= radius_squared
|
||||
&& canseemon(mon))
|
||||
if (obj) /* put lit candle or lamp temporarily on the map */
|
||||
place_object(obj, g.bhitpos.x, g.bhitpos.y);
|
||||
else /* camera flash: no object; directly set light source's location */
|
||||
ls->x = x, ls->y = y;
|
||||
|
||||
/* full recalc; runs do_light_sources() */
|
||||
vision_recalc(0);
|
||||
flush_screen(0);
|
||||
|
||||
radius_squared = ls->range * ls->range;
|
||||
for (mon = fmon; mon; mon = mon->nmon) {
|
||||
if (DEADMONSTER(mon) || (mon->isgd && !mon->mx))
|
||||
continue;
|
||||
/* light range is the radius of a circle and we're limiting
|
||||
canseemon() to a square exclosing that circle, but setting
|
||||
mtemplit 'erroneously' for a seen monster is not a problem;
|
||||
it just flags monsters for another canseemon() check when
|
||||
'obj' has reached its destination after missile traversal */
|
||||
if (dist2(mon->mx, mon->my, x, y) <= radius_squared) {
|
||||
if (canseemon(mon))
|
||||
mon->mtemplit = 1;
|
||||
/* [what about worm tails?] */
|
||||
}
|
||||
/* [what about worm tails?] */
|
||||
}
|
||||
|
||||
if (obj) { /* take thrown/kicked candle or lamp off the map */
|
||||
delay_output();
|
||||
remove_object(obj);
|
||||
}
|
||||
}
|
||||
|
||||
/* draw "remembered, unseen monster" glyph at locations where a monster
|
||||
was flagged for being visible during transient light movement but can't
|
||||
be seen now */
|
||||
/* delete any camera flash light sources and draw "remembered, unseen
|
||||
monster" glyph at locations where a monster was flagged for being
|
||||
visible during transient light movement but can't be seen now */
|
||||
void
|
||||
transient_light_cleanup()
|
||||
{
|
||||
struct monst *mon;
|
||||
int mtempcount = 0;
|
||||
int mtempcount;
|
||||
|
||||
/* in case we're cleaning up a camera flash, remove all object light
|
||||
sources which aren't associated with a specific object */
|
||||
discard_flashes();
|
||||
if (g.vision_full_recalc) /* set by del_light_source() */
|
||||
vision_recalc(0);
|
||||
|
||||
/* for thrown/kicked candle or lamp or for camera flash, some
|
||||
monsters may have been mapped in light which has now gone away
|
||||
so need to be replaced by "remembered, unseen monster" glyph */
|
||||
mtempcount = 0;
|
||||
for (mon = fmon; mon; mon = mon->nmon) {
|
||||
if (DEADMONSTER(mon))
|
||||
continue;
|
||||
@@ -276,9 +326,22 @@ transient_light_cleanup()
|
||||
map_invisible(mon->mx, mon->my);
|
||||
}
|
||||
}
|
||||
if (mtempcount) {
|
||||
vision_recalc(0);
|
||||
if (mtempcount)
|
||||
flush_screen(0);
|
||||
}
|
||||
|
||||
/* camera flashes have Null object; caller wants to get rid of them now */
|
||||
static void
|
||||
discard_flashes()
|
||||
{
|
||||
light_source *ls, *nxt_ls;
|
||||
|
||||
for (ls = g.light_base; ls; ls = nxt_ls) {
|
||||
nxt_ls = ls->next;
|
||||
if (ls->type != LS_OBJECT)
|
||||
continue;
|
||||
if (!ls->id.a_obj)
|
||||
del_light_source(LS_OBJECT, &ls->id);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -318,6 +381,13 @@ int range;
|
||||
int count, actual, is_global;
|
||||
light_source **prev, *curr;
|
||||
|
||||
/* camera flash light sources have Null object and would trigger
|
||||
impossible("no id!") below; they can only happen here if we're
|
||||
in the midst of a panic save and they wouldn't be useful after
|
||||
restore so just throw any that are present away */
|
||||
discard_flashes();
|
||||
g.vision_full_recalc = 0;
|
||||
|
||||
if (perform_bwrite(nhfp)) {
|
||||
count = maybe_write_ls(nhfp, range, FALSE);
|
||||
if (nhfp->structlevel) {
|
||||
@@ -330,7 +400,7 @@ int range;
|
||||
}
|
||||
|
||||
if (release_data(nhfp)) {
|
||||
for (prev = &g.light_base; (curr = *prev) != 0;) {
|
||||
for (prev = &g.light_base; (curr = *prev) != 0; ) {
|
||||
if (!curr->id.a_monst) {
|
||||
impossible("save_light_sources: no id! [range=%d]", range);
|
||||
is_global = 0;
|
||||
|
||||
22
src/uhitm.c
22
src/uhitm.c
@@ -3110,14 +3110,21 @@ struct monst *mon;
|
||||
u.umconf--;
|
||||
}
|
||||
|
||||
/* returns 1 if light flash has noticeable effect on 'mtmp', 0 otherwise */
|
||||
int
|
||||
flash_hits_mon(mtmp, otmp)
|
||||
struct monst *mtmp;
|
||||
struct obj *otmp; /* source of flash */
|
||||
{
|
||||
int tmp, amt, res = 0, useeit = canseemon(mtmp);
|
||||
struct rm *lev;
|
||||
int tmp, amt, useeit, res = 0;
|
||||
|
||||
if (mtmp->msleeping) {
|
||||
if (g.notonhead)
|
||||
return 0;
|
||||
lev = &levl[mtmp->mx][mtmp->my];
|
||||
useeit = canseemon(mtmp);
|
||||
|
||||
if (mtmp->msleeping && haseyes(mtmp->data)) {
|
||||
mtmp->msleeping = 0;
|
||||
if (useeit) {
|
||||
pline_The("flash awakens %s.", mon_nam(mtmp));
|
||||
@@ -3144,8 +3151,19 @@ struct obj *otmp; /* source of flash */
|
||||
mtmp->mcansee = 0;
|
||||
mtmp->mblinded = (tmp < 3) ? 0 : rnd(1 + 50 / tmp);
|
||||
}
|
||||
} else if (flags.verbose && useeit) {
|
||||
if (lev->lit)
|
||||
pline("The flash of light shines on %s.", mon_nam(mtmp));
|
||||
else
|
||||
pline("%s is illuminated.", Monnam(mtmp));
|
||||
res = 2; /* 'message has been given' temporary value */
|
||||
}
|
||||
}
|
||||
if (res) {
|
||||
if (!lev->lit)
|
||||
display_nhwindow(WIN_MESSAGE, TRUE);
|
||||
res &= 1; /* change temporary 2 back to 0 */
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
99
src/vision.c
99
src/vision.c
@@ -24,45 +24,48 @@
|
||||
*
|
||||
*/
|
||||
const char circle_data[] = {
|
||||
/* 0*/ 1, 1,
|
||||
/* 2*/ 2, 2, 1,
|
||||
/* 5*/ 3, 3, 2, 1,
|
||||
/* 9*/ 4, 4, 4, 3, 2,
|
||||
/* 14*/ 5, 5, 5, 4, 3, 2,
|
||||
/* 20*/ 6, 6, 6, 5, 5, 4, 2,
|
||||
/* 27*/ 7, 7, 7, 6, 6, 5, 4, 2,
|
||||
/* 35*/ 8, 8, 8, 7, 7, 6, 6, 4, 2,
|
||||
/* 44*/ 9, 9, 9, 9, 8, 8, 7, 6, 5, 3,
|
||||
/* 54*/ 10, 10, 10, 10, 9, 9, 8, 7, 6, 5, 3,
|
||||
/* 65*/ 11, 11, 11, 11, 10, 10, 9, 9, 8, 7, 5, 3,
|
||||
/* 77*/ 12, 12, 12, 12, 11, 11, 10, 10, 9, 8, 7, 5, 3,
|
||||
/* 90*/ 13, 13, 13, 13, 12, 12, 12, 11, 10, 10, 9, 7, 6, 3,
|
||||
/*104*/ 14, 14, 14, 14, 13, 13, 13, 12, 12, 11, 10, 9, 8, 6, 3,
|
||||
/*119*/ 15, 15, 15, 15, 14, 14, 14, 13, 13, 12, 11, 10, 9, 8, 6, 3,
|
||||
/*135*/ 16 /* MAX_RADIUS+1; used to terminate range loops -dlc */
|
||||
/* 0*/ 0,
|
||||
/* 1*/ 1, 1,
|
||||
/* 3*/ 2, 2, 1,
|
||||
/* 6*/ 3, 3, 2, 1,
|
||||
/* 10*/ 4, 4, 4, 3, 2,
|
||||
/* 15*/ 5, 5, 5, 4, 3, 2,
|
||||
/* 21*/ 6, 6, 6, 5, 5, 4, 2,
|
||||
/* 28*/ 7, 7, 7, 6, 6, 5, 4, 2,
|
||||
/* 36*/ 8, 8, 8, 7, 7, 6, 6, 4, 2,
|
||||
/* 45*/ 9, 9, 9, 9, 8, 8, 7, 6, 5, 3,
|
||||
/* 55*/ 10, 10, 10, 10, 9, 9, 8, 7, 6, 5, 3,
|
||||
/* 66*/ 11, 11, 11, 11, 10, 10, 9, 9, 8, 7, 5, 3,
|
||||
/* 78*/ 12, 12, 12, 12, 11, 11, 10, 10, 9, 8, 7, 5, 3,
|
||||
/* 91*/ 13, 13, 13, 13, 12, 12, 12, 11, 10, 10, 9, 7, 6, 3,
|
||||
/*105*/ 14, 14, 14, 14, 13, 13, 13, 12, 12, 11, 10, 9, 8, 6, 3,
|
||||
/*120*/ 15, 15, 15, 15, 14, 14, 14, 13, 13, 12, 11, 10, 9, 8, 6, 3,
|
||||
/*136*/ 16 /* MAX_RADIUS+1; used to terminate range loops -dlc */
|
||||
};
|
||||
|
||||
/*
|
||||
* These are the starting indexes into the circle_data[] array for a
|
||||
* circle of a given radius.
|
||||
* circle of a given radius. Radius 0 used to be unused, but is now
|
||||
* used for a single point: temporary light source of a camera flash
|
||||
* as it traverses its path.
|
||||
*/
|
||||
const char circle_start[] = {
|
||||
/* */ 0, /* circles of radius zero are not used */
|
||||
/* 1*/ 0,
|
||||
/* 2*/ 2,
|
||||
/* 3*/ 5,
|
||||
/* 4*/ 9,
|
||||
/* 5*/ 14,
|
||||
/* 6*/ 20,
|
||||
/* 7*/ 27,
|
||||
/* 8*/ 35,
|
||||
/* 9*/ 44,
|
||||
/*10*/ 54,
|
||||
/*11*/ 65,
|
||||
/*12*/ 77,
|
||||
/*13*/ 90,
|
||||
/*14*/ 104,
|
||||
/*15*/ 119,
|
||||
/* 0*/ 0,
|
||||
/* 1*/ 1,
|
||||
/* 2*/ 3,
|
||||
/* 3*/ 6,
|
||||
/* 4*/ 10,
|
||||
/* 5*/ 15,
|
||||
/* 6*/ 21,
|
||||
/* 7*/ 38,
|
||||
/* 8*/ 36,
|
||||
/* 9*/ 45,
|
||||
/*10*/ 55,
|
||||
/*11*/ 66,
|
||||
/*12*/ 78,
|
||||
/*13*/ 91,
|
||||
/*14*/ 105,
|
||||
/*15*/ 120,
|
||||
};
|
||||
|
||||
/*==========================================================================*/
|
||||
@@ -263,11 +266,10 @@ char **rmin, **rmax;
|
||||
nrmin = *rmin;
|
||||
nrmax = *rmax;
|
||||
|
||||
(void) memset((genericptr_t) * *rows, 0,
|
||||
ROWNO * COLNO); /* we see nothing */
|
||||
(void) memset((genericptr_t) **rows, 0, ROWNO * COLNO); /* see nothing */
|
||||
for (row = 0; row < ROWNO; row++) { /* set row min & max */
|
||||
*nrmin++ = COLNO - 1;
|
||||
*nrmax++ = 0;
|
||||
*nrmax++ = 1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -490,23 +492,23 @@ void
|
||||
vision_recalc(control)
|
||||
int control;
|
||||
{
|
||||
extern unsigned char seenv_matrix[3][3]; /* from display.c */
|
||||
static unsigned char colbump[COLNO + 1]; /* cols to bump sv */
|
||||
char **temp_array; /* points to the old vision array */
|
||||
char **next_array; /* points to the new vision array */
|
||||
char *next_row; /* row pointer for the new array */
|
||||
char *old_row; /* row pointer for the old array */
|
||||
char *next_rmin; /* min pointer for the new array */
|
||||
char *next_rmax; /* max pointer for the new array */
|
||||
const char *ranges; /* circle ranges -- used for xray & night vision */
|
||||
const char *ranges; /* circle ranges -- used for xray & night vision */
|
||||
int row = 0; /* row counter (outer loop) */
|
||||
int start, stop; /* inner loop starting/stopping index */
|
||||
int dx, dy; /* one step from a lit door or lit wall (see below) */
|
||||
register int col; /* inner loop counter */
|
||||
register struct rm *lev; /* pointer to current pos */
|
||||
struct rm *flev; /* pointer to position in "front" of current pos */
|
||||
extern unsigned char seenv_matrix[3][3]; /* from display.c */
|
||||
static unsigned char colbump[COLNO + 1]; /* cols to bump sv */
|
||||
unsigned char *sv; /* ptr to seen angle bits */
|
||||
int oldseenv; /* previous seenv value */
|
||||
struct rm *flev; /* pointer to position in "front" of current pos */
|
||||
unsigned char *sv; /* ptr to seen angle bits */
|
||||
int oldseenv; /* previous seenv value */
|
||||
|
||||
g.vision_full_recalc = 0; /* reset flag */
|
||||
if (g.in_mklev || !iflags.vision_inited)
|
||||
@@ -532,7 +534,6 @@ int control;
|
||||
*
|
||||
* + Monsters to see with the "new" vision, even on the rogue
|
||||
* level.
|
||||
*
|
||||
* + Monsters can see you even when you're in a pit.
|
||||
*/
|
||||
view_from(u.uy, u.ux, next_array, next_rmin, next_rmax, 0,
|
||||
@@ -564,7 +565,7 @@ int control;
|
||||
} else if (Is_rogue_level(&u.uz)) {
|
||||
rogue_vision(next_array, next_rmin, next_rmax);
|
||||
} else {
|
||||
int has_night_vision = 1; /* hero has night vision */
|
||||
int lo_col, has_night_vision = 1; /* hero has night vision */
|
||||
|
||||
if (Underwater && !Is_waterlevel(&u.uz)) {
|
||||
/*
|
||||
@@ -574,8 +575,9 @@ int control;
|
||||
*/
|
||||
has_night_vision = 0;
|
||||
|
||||
lo_col = max(u.ux - 1, 1);
|
||||
for (row = u.uy - 1; row <= u.uy + 1; row++)
|
||||
for (col = u.ux - 1; col <= u.ux + 1; col++) {
|
||||
for (col = lo_col; col <= u.ux + 1; col++) {
|
||||
if (!isok(col, row) || !is_pool(col, row))
|
||||
continue;
|
||||
|
||||
@@ -592,7 +594,7 @@ int control;
|
||||
if (row >= ROWNO)
|
||||
break;
|
||||
|
||||
next_rmin[row] = max(0, u.ux - 1);
|
||||
next_rmin[row] = max(1, u.ux - 1);
|
||||
next_rmax[row] = min(COLNO - 1, u.ux + 1);
|
||||
next_row = next_array[row];
|
||||
|
||||
@@ -620,11 +622,12 @@ int control;
|
||||
dy = v_abs(u.uy - row);
|
||||
next_row = next_array[row];
|
||||
|
||||
start = max(0, u.ux - ranges[dy]);
|
||||
start = max(1, u.ux - ranges[dy]);
|
||||
stop = min(COLNO - 1, u.ux + ranges[dy]);
|
||||
|
||||
for (col = start; col <= stop; col++) {
|
||||
char old_row_val = next_row[col];
|
||||
|
||||
next_row[col] |= IN_SIGHT;
|
||||
oldseenv = levl[col][row].seenv;
|
||||
levl[col][row].seenv = SVALL; /* see all! */
|
||||
@@ -663,7 +666,7 @@ int control;
|
||||
dy = v_abs(u.uy - row);
|
||||
next_row = next_array[row];
|
||||
|
||||
start = max(0, u.ux - ranges[dy]);
|
||||
start = max(1, u.ux - ranges[dy]);
|
||||
stop = min(COLNO - 1, u.ux + ranges[dy]);
|
||||
|
||||
for (col = start; col <= stop; col++)
|
||||
|
||||
10
src/zap.c
10
src/zap.c
@@ -3320,6 +3320,8 @@ struct obj **pobj; /* object tossed/used, set to NULL
|
||||
|
||||
/* iron bars will block anything big enough and break some things */
|
||||
if (weapon == THROWN_WEAPON || weapon == KICKED_WEAPON) {
|
||||
if (obj->lamplit && !Blind)
|
||||
show_transient_light(obj, g.bhitpos.x, g.bhitpos.y);
|
||||
if (typ == IRONBARS
|
||||
&& hits_bars(pobj, x - ddx, y - ddy, g.bhitpos.x, g.bhitpos.y,
|
||||
point_blank ? 0 : !rn2(5), 1)) {
|
||||
@@ -3328,9 +3330,11 @@ struct obj **pobj; /* object tossed/used, set to NULL
|
||||
g.bhitpos.x -= ddx;
|
||||
g.bhitpos.y -= ddy;
|
||||
break;
|
||||
} else if (obj->lamplit && !Blind) {
|
||||
show_transient_light(obj, g.bhitpos.x, g.bhitpos.y);
|
||||
}
|
||||
} else if (weapon == FLASHED_LIGHT) {
|
||||
if (!Blind)
|
||||
show_transient_light((struct obj *) 0,
|
||||
g.bhitpos.x, g.bhitpos.y);
|
||||
}
|
||||
|
||||
if (weapon == ZAPPED_WAND && find_drawbridge(&x, &y)) {
|
||||
@@ -3546,6 +3550,8 @@ struct obj **pobj; /* object tossed/used, set to NULL
|
||||
pay_for_damage("destroy", FALSE);
|
||||
|
||||
bhit_done:
|
||||
/* note: for FLASHED_LIGHT, _caller_ must call transient_light_cleanup()
|
||||
after possibly calling flash_hits_mon() */
|
||||
if (weapon == THROWN_WEAPON || weapon == KICKED_WEAPON)
|
||||
transient_light_cleanup();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user