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
|
record amount of gold in hero's possession in xlogfile
|
||||||
new objects: amulets of flying and guarding
|
new objects: amulets of flying and guarding
|
||||||
new monsters: displacer beast ('f') and genetic engineer ('Q')
|
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
|
Platform- and/or Interface-Specific New Features
|
||||||
|
|||||||
@@ -52,7 +52,7 @@
|
|||||||
/*
|
/*
|
||||||
* Circle information
|
* 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). */
|
/* 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]])
|
#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));
|
(u.dz > 0) ? surface(u.ux, u.uy) : ceiling(u.ux, u.uy));
|
||||||
} else if (!u.dx && !u.dy) {
|
} else if (!u.dx && !u.dy) {
|
||||||
(void) zapyourself(obj, TRUE);
|
(void) zapyourself(obj, TRUE);
|
||||||
} else if ((mtmp = bhit(u.dx, u.dy, COLNO, FLASHED_LIGHT,
|
} else {
|
||||||
(int FDECL((*), (MONST_P, OBJ_P))) 0,
|
mtmp = bhit(u.dx, u.dy, COLNO, FLASHED_LIGHT,
|
||||||
(int FDECL((*), (OBJ_P, OBJ_P))) 0, &obj)) != 0) {
|
(int FDECL((*), (MONST_P, OBJ_P))) 0,
|
||||||
obj->ox = u.ux, obj->oy = u.uy;
|
(int FDECL((*), (OBJ_P, OBJ_P))) 0, &obj);
|
||||||
(void) flash_hits_mon(mtmp, 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;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|||||||
158
src/light.c
158
src/light.c
@@ -41,6 +41,9 @@
|
|||||||
#define LSF_SHOW 0x1 /* display the light source */
|
#define LSF_SHOW 0x1 /* display the light source */
|
||||||
#define LSF_NEEDS_FIXUP 0x2 /* need oid fixup */
|
#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 void FDECL(write_ls, (NHFILE *, light_source *));
|
||||||
static int FDECL(maybe_write_ls, (NHFILE *, int, BOOLEAN_P));
|
static int FDECL(maybe_write_ls, (NHFILE *, int, BOOLEAN_P));
|
||||||
|
|
||||||
@@ -49,18 +52,31 @@ extern char circle_data[];
|
|||||||
extern char circle_start[];
|
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
|
void
|
||||||
new_light_source(x, y, range, type, id)
|
new_light_source(x, y, range, type, id)
|
||||||
xchar x, y;
|
xchar x, y;
|
||||||
int range, type;
|
int range, type;
|
||||||
anything *id;
|
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;
|
light_source *ls;
|
||||||
|
|
||||||
if (range > MAX_RADIUS || range < 1) {
|
if (range > MAX_RADIUS || range < 0
|
||||||
impossible("new_light_source: illegal range %d", range);
|
/* camera flash uses radius 0 and passes Null object */
|
||||||
return;
|
|| (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);
|
ls = (light_source *) alloc(sizeof *ls);
|
||||||
@@ -75,6 +91,7 @@ new_light_source(x, y, range, type, id)
|
|||||||
g.light_base = ls;
|
g.light_base = ls;
|
||||||
|
|
||||||
g.vision_full_recalc = 1; /* make the source show up */
|
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) */
|
(in particular: chameleon vs prot. from shape changers) */
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case LS_OBJECT:
|
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;
|
break;
|
||||||
case LS_MONSTER:
|
case LS_MONSTER:
|
||||||
tmp_id.a_uint = id->a_monst->m_id;
|
tmp_id.a_uint = id->a_monst->m_id;
|
||||||
@@ -145,7 +162,8 @@ char **cs_rows;
|
|||||||
* vision recalc.
|
* vision recalc.
|
||||||
*/
|
*/
|
||||||
if (ls->type == LS_OBJECT) {
|
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;
|
ls->flags |= LSF_SHOW;
|
||||||
} else if (ls->type == LS_MONSTER) {
|
} else if (ls->type == LS_MONSTER) {
|
||||||
if (get_mon_location(ls->id.a_monst, &ls->x, &ls->y, 0))
|
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++) {
|
for (; y <= max_y; y++) {
|
||||||
row = cs_rows[y];
|
row = cs_rows[y];
|
||||||
offset = limits[abs(y - ls->y)];
|
offset = limits[abs(y - ls->y)];
|
||||||
if ((min_x = (ls->x - offset)) < 0)
|
if ((min_x = (ls->x - offset)) < 1)
|
||||||
min_x = 0;
|
min_x = 1;
|
||||||
if ((max_x = (ls->x + offset)) >= COLNO)
|
if ((max_x = (ls->x + offset)) >= COLNO)
|
||||||
max_x = COLNO - 1;
|
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
|
/* 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
|
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
|
void
|
||||||
show_transient_light(obj, x, y)
|
show_transient_light(obj, x, y)
|
||||||
struct obj *obj;
|
struct obj *obj;
|
||||||
int x, y;
|
int x, y;
|
||||||
{
|
{
|
||||||
light_source *ls;
|
light_source *ls = 0;
|
||||||
|
anything cameraflash;
|
||||||
struct monst *mon;
|
struct monst *mon;
|
||||||
int radius_squared;
|
int radius_squared;
|
||||||
|
|
||||||
/* caller has verified obj->lamplit and that hero is not Blind;
|
/* Null object indicates camera flash */
|
||||||
validate light source and obtain its radius (for monster sightings) */
|
if (!obj) {
|
||||||
for (ls = g.light_base; ls; ls = ls->next) {
|
/* no need to temporarily light an already lit spot */
|
||||||
if (ls->type != LS_OBJECT)
|
if (levl[x][y].lit)
|
||||||
continue;
|
return;
|
||||||
if (ls->id.a_obj == obj)
|
|
||||||
break;
|
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?",
|
impossible("transient light %s %s is not %s?",
|
||||||
obj->lamplit ? "lit" : "unlit", xname(obj),
|
obj->lamplit ? "lit" : "unlit", xname(obj),
|
||||||
!ls ? "a light source" : "free");
|
!ls ? "a light source" : "free");
|
||||||
} else {
|
return;
|
||||||
/* "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 */
|
|
||||||
|
|
||||||
radius_squared = ls->range * ls->range;
|
if (obj) /* put lit candle or lamp temporarily on the map */
|
||||||
for (mon = fmon; mon; mon = mon->nmon) {
|
place_object(obj, g.bhitpos.x, g.bhitpos.y);
|
||||||
if (DEADMONSTER(mon))
|
else /* camera flash: no object; directly set light source's location */
|
||||||
continue;
|
ls->x = x, ls->y = y;
|
||||||
/* light range is the radius of a circle and we're limiting
|
|
||||||
canseemon() to a square exclosing that circle, but setting
|
/* full recalc; runs do_light_sources() */
|
||||||
mtemplit 'erroneously' for a seen monster is not a problem;
|
vision_recalc(0);
|
||||||
it just flags monsters for another canseemon() check when
|
flush_screen(0);
|
||||||
'obj' has reached its destination after missile traversal */
|
|
||||||
if (dist2(mon->mx, mon->my, x, y) <= radius_squared
|
radius_squared = ls->range * ls->range;
|
||||||
&& canseemon(mon))
|
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;
|
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
|
/* delete any camera flash light sources and draw "remembered, unseen
|
||||||
was flagged for being visible during transient light movement but can't
|
monster" glyph at locations where a monster was flagged for being
|
||||||
be seen now */
|
visible during transient light movement but can't be seen now */
|
||||||
void
|
void
|
||||||
transient_light_cleanup()
|
transient_light_cleanup()
|
||||||
{
|
{
|
||||||
struct monst *mon;
|
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) {
|
for (mon = fmon; mon; mon = mon->nmon) {
|
||||||
if (DEADMONSTER(mon))
|
if (DEADMONSTER(mon))
|
||||||
continue;
|
continue;
|
||||||
@@ -276,9 +326,22 @@ transient_light_cleanup()
|
|||||||
map_invisible(mon->mx, mon->my);
|
map_invisible(mon->mx, mon->my);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (mtempcount) {
|
if (mtempcount)
|
||||||
vision_recalc(0);
|
|
||||||
flush_screen(0);
|
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;
|
int count, actual, is_global;
|
||||||
light_source **prev, *curr;
|
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)) {
|
if (perform_bwrite(nhfp)) {
|
||||||
count = maybe_write_ls(nhfp, range, FALSE);
|
count = maybe_write_ls(nhfp, range, FALSE);
|
||||||
if (nhfp->structlevel) {
|
if (nhfp->structlevel) {
|
||||||
@@ -330,7 +400,7 @@ int range;
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (release_data(nhfp)) {
|
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) {
|
if (!curr->id.a_monst) {
|
||||||
impossible("save_light_sources: no id! [range=%d]", range);
|
impossible("save_light_sources: no id! [range=%d]", range);
|
||||||
is_global = 0;
|
is_global = 0;
|
||||||
|
|||||||
22
src/uhitm.c
22
src/uhitm.c
@@ -3110,14 +3110,21 @@ struct monst *mon;
|
|||||||
u.umconf--;
|
u.umconf--;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* returns 1 if light flash has noticeable effect on 'mtmp', 0 otherwise */
|
||||||
int
|
int
|
||||||
flash_hits_mon(mtmp, otmp)
|
flash_hits_mon(mtmp, otmp)
|
||||||
struct monst *mtmp;
|
struct monst *mtmp;
|
||||||
struct obj *otmp; /* source of flash */
|
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;
|
mtmp->msleeping = 0;
|
||||||
if (useeit) {
|
if (useeit) {
|
||||||
pline_The("flash awakens %s.", mon_nam(mtmp));
|
pline_The("flash awakens %s.", mon_nam(mtmp));
|
||||||
@@ -3144,8 +3151,19 @@ struct obj *otmp; /* source of flash */
|
|||||||
mtmp->mcansee = 0;
|
mtmp->mcansee = 0;
|
||||||
mtmp->mblinded = (tmp < 3) ? 0 : rnd(1 + 50 / tmp);
|
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;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
99
src/vision.c
99
src/vision.c
@@ -24,45 +24,48 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
const char circle_data[] = {
|
const char circle_data[] = {
|
||||||
/* 0*/ 1, 1,
|
/* 0*/ 0,
|
||||||
/* 2*/ 2, 2, 1,
|
/* 1*/ 1, 1,
|
||||||
/* 5*/ 3, 3, 2, 1,
|
/* 3*/ 2, 2, 1,
|
||||||
/* 9*/ 4, 4, 4, 3, 2,
|
/* 6*/ 3, 3, 2, 1,
|
||||||
/* 14*/ 5, 5, 5, 4, 3, 2,
|
/* 10*/ 4, 4, 4, 3, 2,
|
||||||
/* 20*/ 6, 6, 6, 5, 5, 4, 2,
|
/* 15*/ 5, 5, 5, 4, 3, 2,
|
||||||
/* 27*/ 7, 7, 7, 6, 6, 5, 4, 2,
|
/* 21*/ 6, 6, 6, 5, 5, 4, 2,
|
||||||
/* 35*/ 8, 8, 8, 7, 7, 6, 6, 4, 2,
|
/* 28*/ 7, 7, 7, 6, 6, 5, 4, 2,
|
||||||
/* 44*/ 9, 9, 9, 9, 8, 8, 7, 6, 5, 3,
|
/* 36*/ 8, 8, 8, 7, 7, 6, 6, 4, 2,
|
||||||
/* 54*/ 10, 10, 10, 10, 9, 9, 8, 7, 6, 5, 3,
|
/* 45*/ 9, 9, 9, 9, 8, 8, 7, 6, 5, 3,
|
||||||
/* 65*/ 11, 11, 11, 11, 10, 10, 9, 9, 8, 7, 5, 3,
|
/* 55*/ 10, 10, 10, 10, 9, 9, 8, 7, 6, 5, 3,
|
||||||
/* 77*/ 12, 12, 12, 12, 11, 11, 10, 10, 9, 8, 7, 5, 3,
|
/* 66*/ 11, 11, 11, 11, 10, 10, 9, 9, 8, 7, 5, 3,
|
||||||
/* 90*/ 13, 13, 13, 13, 12, 12, 12, 11, 10, 10, 9, 7, 6, 3,
|
/* 78*/ 12, 12, 12, 12, 11, 11, 10, 10, 9, 8, 7, 5, 3,
|
||||||
/*104*/ 14, 14, 14, 14, 13, 13, 13, 12, 12, 11, 10, 9, 8, 6, 3,
|
/* 91*/ 13, 13, 13, 13, 12, 12, 12, 11, 10, 10, 9, 7, 6, 3,
|
||||||
/*119*/ 15, 15, 15, 15, 14, 14, 14, 13, 13, 12, 11, 10, 9, 8, 6, 3,
|
/*105*/ 14, 14, 14, 14, 13, 13, 13, 12, 12, 11, 10, 9, 8, 6, 3,
|
||||||
/*135*/ 16 /* MAX_RADIUS+1; used to terminate range loops -dlc */
|
/*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
|
* 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[] = {
|
const char circle_start[] = {
|
||||||
/* */ 0, /* circles of radius zero are not used */
|
/* 0*/ 0,
|
||||||
/* 1*/ 0,
|
/* 1*/ 1,
|
||||||
/* 2*/ 2,
|
/* 2*/ 3,
|
||||||
/* 3*/ 5,
|
/* 3*/ 6,
|
||||||
/* 4*/ 9,
|
/* 4*/ 10,
|
||||||
/* 5*/ 14,
|
/* 5*/ 15,
|
||||||
/* 6*/ 20,
|
/* 6*/ 21,
|
||||||
/* 7*/ 27,
|
/* 7*/ 38,
|
||||||
/* 8*/ 35,
|
/* 8*/ 36,
|
||||||
/* 9*/ 44,
|
/* 9*/ 45,
|
||||||
/*10*/ 54,
|
/*10*/ 55,
|
||||||
/*11*/ 65,
|
/*11*/ 66,
|
||||||
/*12*/ 77,
|
/*12*/ 78,
|
||||||
/*13*/ 90,
|
/*13*/ 91,
|
||||||
/*14*/ 104,
|
/*14*/ 105,
|
||||||
/*15*/ 119,
|
/*15*/ 120,
|
||||||
};
|
};
|
||||||
|
|
||||||
/*==========================================================================*/
|
/*==========================================================================*/
|
||||||
@@ -263,11 +266,10 @@ char **rmin, **rmax;
|
|||||||
nrmin = *rmin;
|
nrmin = *rmin;
|
||||||
nrmax = *rmax;
|
nrmax = *rmax;
|
||||||
|
|
||||||
(void) memset((genericptr_t) * *rows, 0,
|
(void) memset((genericptr_t) **rows, 0, ROWNO * COLNO); /* see nothing */
|
||||||
ROWNO * COLNO); /* we see nothing */
|
|
||||||
for (row = 0; row < ROWNO; row++) { /* set row min & max */
|
for (row = 0; row < ROWNO; row++) { /* set row min & max */
|
||||||
*nrmin++ = COLNO - 1;
|
*nrmin++ = COLNO - 1;
|
||||||
*nrmax++ = 0;
|
*nrmax++ = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -490,23 +492,23 @@ void
|
|||||||
vision_recalc(control)
|
vision_recalc(control)
|
||||||
int 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 **temp_array; /* points to the old vision array */
|
||||||
char **next_array; /* points to the new vision array */
|
char **next_array; /* points to the new vision array */
|
||||||
char *next_row; /* row pointer for the new array */
|
char *next_row; /* row pointer for the new array */
|
||||||
char *old_row; /* row pointer for the old array */
|
char *old_row; /* row pointer for the old array */
|
||||||
char *next_rmin; /* min pointer for the new array */
|
char *next_rmin; /* min pointer for the new array */
|
||||||
char *next_rmax; /* max 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 row = 0; /* row counter (outer loop) */
|
||||||
int start, stop; /* inner loop starting/stopping index */
|
int start, stop; /* inner loop starting/stopping index */
|
||||||
int dx, dy; /* one step from a lit door or lit wall (see below) */
|
int dx, dy; /* one step from a lit door or lit wall (see below) */
|
||||||
register int col; /* inner loop counter */
|
register int col; /* inner loop counter */
|
||||||
register struct rm *lev; /* pointer to current pos */
|
register struct rm *lev; /* pointer to current pos */
|
||||||
struct rm *flev; /* pointer to position in "front" of current pos */
|
struct rm *flev; /* pointer to position in "front" of current pos */
|
||||||
extern unsigned char seenv_matrix[3][3]; /* from display.c */
|
unsigned char *sv; /* ptr to seen angle bits */
|
||||||
static unsigned char colbump[COLNO + 1]; /* cols to bump sv */
|
int oldseenv; /* previous seenv value */
|
||||||
unsigned char *sv; /* ptr to seen angle bits */
|
|
||||||
int oldseenv; /* previous seenv value */
|
|
||||||
|
|
||||||
g.vision_full_recalc = 0; /* reset flag */
|
g.vision_full_recalc = 0; /* reset flag */
|
||||||
if (g.in_mklev || !iflags.vision_inited)
|
if (g.in_mklev || !iflags.vision_inited)
|
||||||
@@ -532,7 +534,6 @@ int control;
|
|||||||
*
|
*
|
||||||
* + Monsters to see with the "new" vision, even on the rogue
|
* + Monsters to see with the "new" vision, even on the rogue
|
||||||
* level.
|
* level.
|
||||||
*
|
|
||||||
* + Monsters can see you even when you're in a pit.
|
* + Monsters can see you even when you're in a pit.
|
||||||
*/
|
*/
|
||||||
view_from(u.uy, u.ux, next_array, next_rmin, next_rmax, 0,
|
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)) {
|
} else if (Is_rogue_level(&u.uz)) {
|
||||||
rogue_vision(next_array, next_rmin, next_rmax);
|
rogue_vision(next_array, next_rmin, next_rmax);
|
||||||
} else {
|
} 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)) {
|
if (Underwater && !Is_waterlevel(&u.uz)) {
|
||||||
/*
|
/*
|
||||||
@@ -574,8 +575,9 @@ int control;
|
|||||||
*/
|
*/
|
||||||
has_night_vision = 0;
|
has_night_vision = 0;
|
||||||
|
|
||||||
|
lo_col = max(u.ux - 1, 1);
|
||||||
for (row = u.uy - 1; row <= u.uy + 1; row++)
|
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))
|
if (!isok(col, row) || !is_pool(col, row))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
@@ -592,7 +594,7 @@ int control;
|
|||||||
if (row >= ROWNO)
|
if (row >= ROWNO)
|
||||||
break;
|
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_rmax[row] = min(COLNO - 1, u.ux + 1);
|
||||||
next_row = next_array[row];
|
next_row = next_array[row];
|
||||||
|
|
||||||
@@ -620,11 +622,12 @@ int control;
|
|||||||
dy = v_abs(u.uy - row);
|
dy = v_abs(u.uy - row);
|
||||||
next_row = next_array[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]);
|
stop = min(COLNO - 1, u.ux + ranges[dy]);
|
||||||
|
|
||||||
for (col = start; col <= stop; col++) {
|
for (col = start; col <= stop; col++) {
|
||||||
char old_row_val = next_row[col];
|
char old_row_val = next_row[col];
|
||||||
|
|
||||||
next_row[col] |= IN_SIGHT;
|
next_row[col] |= IN_SIGHT;
|
||||||
oldseenv = levl[col][row].seenv;
|
oldseenv = levl[col][row].seenv;
|
||||||
levl[col][row].seenv = SVALL; /* see all! */
|
levl[col][row].seenv = SVALL; /* see all! */
|
||||||
@@ -663,7 +666,7 @@ int control;
|
|||||||
dy = v_abs(u.uy - row);
|
dy = v_abs(u.uy - row);
|
||||||
next_row = next_array[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]);
|
stop = min(COLNO - 1, u.ux + ranges[dy]);
|
||||||
|
|
||||||
for (col = start; col <= stop; col++)
|
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 */
|
/* iron bars will block anything big enough and break some things */
|
||||||
if (weapon == THROWN_WEAPON || weapon == KICKED_WEAPON) {
|
if (weapon == THROWN_WEAPON || weapon == KICKED_WEAPON) {
|
||||||
|
if (obj->lamplit && !Blind)
|
||||||
|
show_transient_light(obj, g.bhitpos.x, g.bhitpos.y);
|
||||||
if (typ == IRONBARS
|
if (typ == IRONBARS
|
||||||
&& hits_bars(pobj, x - ddx, y - ddy, g.bhitpos.x, g.bhitpos.y,
|
&& hits_bars(pobj, x - ddx, y - ddy, g.bhitpos.x, g.bhitpos.y,
|
||||||
point_blank ? 0 : !rn2(5), 1)) {
|
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.x -= ddx;
|
||||||
g.bhitpos.y -= ddy;
|
g.bhitpos.y -= ddy;
|
||||||
break;
|
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)) {
|
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);
|
pay_for_damage("destroy", FALSE);
|
||||||
|
|
||||||
bhit_done:
|
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)
|
if (weapon == THROWN_WEAPON || weapon == KICKED_WEAPON)
|
||||||
transient_light_cleanup();
|
transient_light_cleanup();
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user