mirror of
https://codeberg.org/noisytoot/notnotdnethack.git
synced 2025-08-13 08:01:40 +01:00
Merge pull request #1182 from NeroOneTrueKing/patch-attach-ls
Attach lightsources directly to mons/objs
This commit is contained in:
commit
01894e0256
13 changed files with 226 additions and 409 deletions
|
@ -1147,15 +1147,13 @@ E int NDECL(dosuspend);
|
|||
|
||||
/* ### light.c ### */
|
||||
|
||||
E void FDECL(new_light_source, (XCHAR_P, XCHAR_P, int, int, genericptr_t));
|
||||
E void FDECL(del_light_source, (int, genericptr_t, int));
|
||||
E void FDECL(new_light_source, (int, genericptr_t, int));
|
||||
E void FDECL(del_light_source, (struct ls_t *));
|
||||
E void FDECL(do_light_sources, (char **));
|
||||
E boolean NDECL(uswallow_indark);
|
||||
E struct monst *FDECL(find_mid, (unsigned, unsigned));
|
||||
E void FDECL(save_light_sources, (int, int, int));
|
||||
E void FDECL(restore_light_sources, (int));
|
||||
E void FDECL(relink_light_sources, (BOOLEAN_P));
|
||||
E void FDECL(obj_move_light_source, (struct obj *, struct obj *));
|
||||
E void FDECL(save_lightsource, (struct ls_t *, int, int));
|
||||
E void FDECL(rest_lightsource, (int, genericptr_t, struct ls_t *, int, boolean));
|
||||
E boolean NDECL(any_light_source);
|
||||
E void FDECL(snuff_light_source, (int, int));
|
||||
E boolean FDECL(obj_sheds_light, (struct obj *));
|
||||
|
|
|
@ -39,13 +39,13 @@ struct bubble {
|
|||
};
|
||||
|
||||
/* used in light.c */
|
||||
typedef struct ls_t {
|
||||
struct ls_t *next;
|
||||
struct ls_t {
|
||||
struct ls_t *next; /* next in global processing chain */
|
||||
xchar x, y; /* source's position */
|
||||
short range; /* source's current range */
|
||||
short flags;
|
||||
short type; /* type of light source */
|
||||
genericptr_t id; /* source's identifier */
|
||||
} light_source;
|
||||
short lstype; /* type of light source */
|
||||
genericptr_t owner; /* source's identifier */
|
||||
};
|
||||
|
||||
#endif /* LEV_H */
|
||||
|
|
|
@ -260,6 +260,8 @@ struct monst {
|
|||
long mvar2;
|
||||
long mvar3;
|
||||
|
||||
struct ls_t * light;
|
||||
|
||||
union mextra * mextra_p;
|
||||
};
|
||||
|
||||
|
|
|
@ -346,6 +346,8 @@ struct obj {
|
|||
|
||||
struct mask_properties *mp;
|
||||
|
||||
struct ls_t * light;
|
||||
|
||||
union oextra * oextra_p;
|
||||
};
|
||||
|
||||
|
|
465
src/light.c
465
src/light.c
|
@ -46,25 +46,69 @@
|
|||
#define LSF_SHOW 0x1 /* display the light source */
|
||||
#define LSF_NEEDS_FIXUP 0x2 /* need oid fixup */
|
||||
|
||||
static light_source *light_base = 0;
|
||||
static struct ls_t *light_base = 0;
|
||||
|
||||
STATIC_DCL void FDECL(write_ls, (int, light_source *));
|
||||
STATIC_DCL void FDECL(add_chain_ls, (struct ls_t *));
|
||||
STATIC_DCL void FDECL(rem_chain_ls, (struct ls_t *));
|
||||
STATIC_DCL void FDECL(write_ls, (int, struct ls_t *));
|
||||
STATIC_DCL int FDECL(maybe_write_ls, (int, int, BOOLEAN_P));
|
||||
|
||||
/* imported from vision.c, for small circles */
|
||||
extern char circle_data[];
|
||||
extern char circle_start[];
|
||||
|
||||
#define owner_ls(lstype, owner) (\
|
||||
(lstype) == LS_OBJECT ? &(((struct obj *)(owner))->light) : \
|
||||
(lstype) == LS_MONSTER ? &(((struct monst *)(owner))->light) : \
|
||||
(struct ls_t **)0)
|
||||
|
||||
/* adds an existing light source to the processing chain */
|
||||
void
|
||||
add_chain_ls(ls)
|
||||
struct ls_t * ls;
|
||||
{
|
||||
struct ls_t * lstmp;
|
||||
/* check for duplicates */
|
||||
for (lstmp = light_base; lstmp; lstmp = lstmp->next) {
|
||||
if (lstmp == ls) {
|
||||
impossible("ls already in processing chain");
|
||||
return;
|
||||
}
|
||||
}
|
||||
ls->next = light_base;
|
||||
light_base = ls;
|
||||
return;
|
||||
}
|
||||
|
||||
/* removes a light source from the procesing chain */
|
||||
void
|
||||
rem_chain_ls(ls)
|
||||
struct ls_t * ls;
|
||||
{
|
||||
struct ls_t * lstmp;
|
||||
if (light_base == ls) {
|
||||
light_base = light_base->next;
|
||||
return;
|
||||
}
|
||||
else for (lstmp = light_base; lstmp; lstmp = lstmp->next) {
|
||||
if (lstmp->next == ls) {
|
||||
lstmp->next = ls->next;
|
||||
return;
|
||||
}
|
||||
}
|
||||
impossible("couldn't find ls in processing chain");
|
||||
return;
|
||||
}
|
||||
|
||||
/* Create a new light source. */
|
||||
/* If a lightsource is already attached to (type, id), replace it (with a warning) */
|
||||
void
|
||||
new_light_source(x, y, range, type, id)
|
||||
xchar x, y;
|
||||
int range, type;
|
||||
genericptr_t id;
|
||||
new_light_source(lstype, owner, range)
|
||||
int lstype; /* is it attached to a mon or an obj? */
|
||||
genericptr_t owner; /* pointer to mon/obj this is attached to */
|
||||
int range; /* range of ls */
|
||||
{
|
||||
light_source *ls;
|
||||
struct ls_t *ls;
|
||||
boolean duplicate = FALSE;
|
||||
|
||||
if (range > MAX_RADIUS || range < 0) {
|
||||
|
@ -73,72 +117,57 @@ new_light_source(x, y, range, type, id)
|
|||
}
|
||||
|
||||
/* check that this is a unique lightsource */
|
||||
for (ls = light_base; ls; ls = ls->next) {
|
||||
if (ls->type == type && ls->id == id) {
|
||||
/* Duplicate */
|
||||
duplicate = TRUE;
|
||||
impossible("duplicate lightsource attempting to be created, type %d", type);
|
||||
break;
|
||||
}
|
||||
if (ls = *owner_ls(lstype, owner))
|
||||
duplicate = TRUE;
|
||||
|
||||
if (duplicate) {
|
||||
impossible("duplicate lightsource attempting to be created on %s",
|
||||
lstype == LS_OBJECT ? xname(owner) : m_monnam(owner));
|
||||
}
|
||||
if (!duplicate) {
|
||||
ls = (light_source *)alloc(sizeof(light_source));
|
||||
ls->next = light_base;
|
||||
light_base = ls;
|
||||
else {
|
||||
ls = (struct ls_t *)alloc(sizeof(struct ls_t));
|
||||
}
|
||||
ls->x = x;
|
||||
ls->y = y;
|
||||
/* set ls data */
|
||||
ls->range = range;
|
||||
ls->type = type;
|
||||
ls->id = id;
|
||||
ls->lstype = lstype;
|
||||
ls->owner = owner;
|
||||
ls->flags = 0;
|
||||
/* set initial location of lightsource */
|
||||
switch(lstype) {
|
||||
case LS_OBJECT:
|
||||
get_obj_location((struct obj *) ls->owner, &ls->x, &ls->y, 0);
|
||||
break;
|
||||
case LS_MONSTER:
|
||||
get_mon_location((struct monst *) ls->owner, &ls->x, &ls->y, 0);
|
||||
break;
|
||||
}
|
||||
/* add to owner */
|
||||
*owner_ls(lstype, owner) = ls;
|
||||
/* add to processing chain */
|
||||
if (!duplicate)
|
||||
add_chain_ls(ls);
|
||||
|
||||
vision_full_recalc = 1; /* make the source show up */
|
||||
}
|
||||
|
||||
/*
|
||||
* Delete all light sources attached to (type, id). There *should* only be one.
|
||||
* Delete light source.
|
||||
*/
|
||||
void
|
||||
del_light_source(type, id, silent)
|
||||
int type;
|
||||
genericptr_t id;
|
||||
int silent;
|
||||
del_light_source(ls)
|
||||
struct ls_t * ls;
|
||||
{
|
||||
light_source *curr, *prev, *next;
|
||||
genericptr_t tmp_id;
|
||||
boolean found_it = FALSE;
|
||||
|
||||
/* need to be prepared for dealing a with light source which
|
||||
has only been partially restored during a level change
|
||||
(in particular: chameleon vs prot. from shape changers) */
|
||||
switch (type) {
|
||||
case LS_OBJECT: tmp_id = (genericptr_t)(intptr_t)(((struct obj *)id)->o_id);
|
||||
break;
|
||||
case LS_MONSTER: tmp_id = (genericptr_t)(intptr_t)(((struct monst *)id)->m_id);
|
||||
break;
|
||||
default: tmp_id = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
for (prev = 0, curr = light_base; curr; prev = curr, curr = next) {
|
||||
next = curr->next;
|
||||
if (curr->type != type) continue;
|
||||
if (curr->id == ((curr->flags & LSF_NEEDS_FIXUP) ? tmp_id : id)) {
|
||||
if (prev)
|
||||
prev->next = curr->next;
|
||||
else
|
||||
light_base = curr->next;
|
||||
|
||||
free((genericptr_t)curr);
|
||||
curr = prev; /* retain prev for next loop */
|
||||
vision_full_recalc = 1;
|
||||
if (found_it)
|
||||
impossible("multiple ls attached to type %d", type);
|
||||
found_it = TRUE;
|
||||
}
|
||||
}
|
||||
if(!found_it && !silent) impossible("del_light_source: not found type=%d, id=0x%lx", type, (long)id);
|
||||
/* check it exists */
|
||||
if (!ls) return;
|
||||
/* remove from processing chain */
|
||||
rem_chain_ls(ls);
|
||||
/* need to update vision */
|
||||
vision_full_recalc = 1;
|
||||
/* clean owner */
|
||||
*owner_ls(ls->lstype, ls->owner) = (struct ls_t *)0;
|
||||
/* free it */
|
||||
free(ls);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Mark locations that are temporarily lit via mobile light sources. */
|
||||
|
@ -149,7 +178,7 @@ do_light_sources(cs_rows)
|
|||
int x, y, min_x, max_x, max_y, offset;
|
||||
char *limits;
|
||||
short at_hero_range = 0;
|
||||
light_source *ls;
|
||||
struct ls_t *ls;
|
||||
char *row;
|
||||
|
||||
for (ls = light_base; ls; ls = ls->next) {
|
||||
|
@ -161,11 +190,11 @@ do_light_sources(cs_rows)
|
|||
* the current setup -- we need to recalculate for every
|
||||
* vision recalc.
|
||||
*/
|
||||
if (ls->type == LS_OBJECT) {
|
||||
if (get_obj_location((struct obj *) ls->id, &ls->x, &ls->y, 0))
|
||||
if (ls->lstype == LS_OBJECT) {
|
||||
if (get_obj_location((struct obj *) ls->owner, &ls->x, &ls->y, 0))
|
||||
ls->flags |= LSF_SHOW;
|
||||
} else if (ls->type == LS_MONSTER) {
|
||||
if (get_mon_location((struct monst *) ls->id, &ls->x, &ls->y, 0))
|
||||
} else if (ls->lstype == LS_MONSTER) {
|
||||
if (get_mon_location((struct monst *) ls->owner, &ls->x, &ls->y, 0))
|
||||
ls->flags |= LSF_SHOW;
|
||||
}
|
||||
|
||||
|
@ -173,40 +202,40 @@ do_light_sources(cs_rows)
|
|||
/* note: contained objects are not found by get_obj_location()
|
||||
* without a specific flag set, so they don't need extra handling */
|
||||
if (ls->flags & LSF_SHOW) {
|
||||
if (ls->type == LS_OBJECT && (
|
||||
if (ls->lstype == LS_OBJECT && (
|
||||
(
|
||||
/* lightsource is in the stomach of an engulfer */
|
||||
mcarried((struct obj *)ls->id) &&
|
||||
attacktype(((struct obj *)ls->id)->ocarry->data, AT_ENGL))
|
||||
mcarried((struct obj *)ls->owner) &&
|
||||
attacktype(((struct obj *)ls->owner)->ocarry->data, AT_ENGL))
|
||||
||
|
||||
(
|
||||
/* lightsource carried by player, who is engulfed */
|
||||
carried((struct obj *)ls->id) &&
|
||||
carried((struct obj *)ls->owner) &&
|
||||
u.uswallow)
|
||||
)){
|
||||
ls->flags &= ~LSF_SHOW;
|
||||
}
|
||||
else if (ls->type == LS_MONSTER && (
|
||||
else if (ls->lstype == LS_MONSTER && (
|
||||
(
|
||||
/* lightsource is the player; player is engulfed */
|
||||
u.uswallow &&
|
||||
(((struct monst *)ls->id) == &youmonst))
|
||||
(((struct monst *)ls->owner) == &youmonst))
|
||||
)){
|
||||
ls->flags &= ~LSF_SHOW;
|
||||
}
|
||||
}
|
||||
|
||||
/* Candle ranges need to be recomputed to allow altar effects */
|
||||
if (ls->type == LS_OBJECT) {
|
||||
struct obj *otmp = (struct obj *) ls->id;
|
||||
if (ls->lstype == LS_OBJECT) {
|
||||
struct obj *otmp = (struct obj *) ls->owner;
|
||||
if (Is_candle(otmp)) {
|
||||
ls->range = candle_light_range(otmp);
|
||||
}
|
||||
}
|
||||
|
||||
if ((ls->flags & LSF_SHOW) && ls->range > 0) {
|
||||
if((ls->type == LS_OBJECT && Is_darklight_source(((struct obj *)(ls->id)))) ||
|
||||
(ls->type == LS_MONSTER && Is_darklight_monster(((struct monst *)(ls->id))->data))
|
||||
if((ls->lstype == LS_OBJECT && Is_darklight_source(((struct obj *)(ls->owner)))) ||
|
||||
(ls->lstype == LS_MONSTER && Is_darklight_monster(((struct monst *)(ls->owner))->data))
|
||||
){
|
||||
int range = ls->range;
|
||||
/*
|
||||
|
@ -450,14 +479,14 @@ uswallow_indark()
|
|||
tlit = TRUE;
|
||||
}
|
||||
/* your carried lightsources */
|
||||
light_source *ls;
|
||||
struct ls_t *ls;
|
||||
for (ls = light_base; ls; ls = ls->next) {
|
||||
if ((ls->type == LS_OBJECT) &&
|
||||
if ((ls->lstype == LS_OBJECT) &&
|
||||
(ls->x == u.ux) &&
|
||||
(ls->y == u.uy) &&
|
||||
(carried(((struct obj *)ls->id))))
|
||||
(carried(((struct obj *)ls->owner))))
|
||||
{
|
||||
if (Is_darklight_source(((struct obj *)(ls->id))))
|
||||
if (Is_darklight_source(((struct obj *)(ls->owner))))
|
||||
tdark = TRUE;
|
||||
else
|
||||
tlit = TRUE;
|
||||
|
@ -490,211 +519,40 @@ unsigned fmflags;
|
|||
return (struct monst *) 0;
|
||||
}
|
||||
|
||||
/* Save all light sources of the given range. */
|
||||
void
|
||||
save_light_sources(fd, mode, range)
|
||||
int fd, mode, range;
|
||||
save_lightsource(ls, fd, mode)
|
||||
struct ls_t * ls;
|
||||
int fd;
|
||||
int mode;
|
||||
{
|
||||
int count, actual, is_global;
|
||||
light_source **prev, *curr;
|
||||
|
||||
if (perform_bwrite(mode)) {
|
||||
count = maybe_write_ls(fd, range, FALSE);
|
||||
bwrite(fd, (genericptr_t) &count, sizeof count);
|
||||
actual = maybe_write_ls(fd, range, TRUE);
|
||||
if (actual != count)
|
||||
panic("counted %d light sources, wrote %d! [range=%d]",
|
||||
count, actual, range);
|
||||
}
|
||||
|
||||
if (release_data(mode)) {
|
||||
for (prev = &light_base; (curr = *prev) != 0; ) {
|
||||
if (!curr->id) {
|
||||
impossible("save_light_sources: no id! [range=%d]", range);
|
||||
is_global = 0;
|
||||
} else
|
||||
switch (curr->type) {
|
||||
case LS_OBJECT:
|
||||
is_global = !obj_is_local((struct obj *)curr->id);
|
||||
break;
|
||||
case LS_MONSTER:
|
||||
is_global = !mon_is_local((struct monst *)curr->id);
|
||||
break;
|
||||
default:
|
||||
is_global = 0;
|
||||
impossible("save_light_sources: bad type (%d) [range=%d]",
|
||||
curr->type, range);
|
||||
break;
|
||||
}
|
||||
/* if global and not doing local, or vice versa, remove it */
|
||||
if (is_global ^ (range == RANGE_LEVEL)) {
|
||||
*prev = curr->next;
|
||||
free((genericptr_t)curr);
|
||||
} else {
|
||||
prev = &(*prev)->next;
|
||||
}
|
||||
}
|
||||
}
|
||||
bwrite(fd, (genericptr_t)ls, sizeof(struct ls_t));
|
||||
if (release_data(mode))
|
||||
del_light_source(ls);
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Pull in the structures from disk, but don't recalculate the object
|
||||
* pointers.
|
||||
*/
|
||||
void
|
||||
restore_light_sources(fd)
|
||||
int fd;
|
||||
rest_lightsource(lstype, owner, ls, fd, ghostly)
|
||||
int lstype;
|
||||
genericptr_t owner;
|
||||
struct ls_t * ls;
|
||||
int fd;
|
||||
boolean ghostly; /* unused */
|
||||
{
|
||||
int count;
|
||||
light_source *ls;
|
||||
|
||||
/* restore elements */
|
||||
mread(fd, (genericptr_t) &count, sizeof count);
|
||||
|
||||
while (count-- > 0) {
|
||||
ls = (light_source *) alloc(sizeof(light_source));
|
||||
mread(fd, (genericptr_t) ls, sizeof(light_source));
|
||||
ls->next = light_base;
|
||||
light_base = ls;
|
||||
}
|
||||
}
|
||||
|
||||
/* Relink all lights that are so marked. */
|
||||
void
|
||||
relink_light_sources(ghostly)
|
||||
boolean ghostly;
|
||||
{
|
||||
char which;
|
||||
unsigned nid;
|
||||
light_source *ls;
|
||||
|
||||
for (ls = light_base; ls; ls = ls->next) {
|
||||
if (ls->flags & LSF_NEEDS_FIXUP) {
|
||||
if (ls->type == LS_OBJECT || ls->type == LS_MONSTER) {
|
||||
if (ghostly) {
|
||||
if (!lookup_id_mapping((unsigned)(intptr_t)ls->id, &nid))
|
||||
impossible("relink_light_sources: no id mapping");
|
||||
} else
|
||||
nid = (unsigned)(intptr_t)ls->id;
|
||||
if (ls->type == LS_OBJECT) {
|
||||
which = 'o';
|
||||
ls->id = (genericptr_t) find_oid(nid);
|
||||
} else {
|
||||
which = 'm';
|
||||
ls->id = (genericptr_t) find_mid(nid, FM_EVERYWHERE);
|
||||
}
|
||||
if (!ls->id)
|
||||
impossible("relink_light_sources: cant find %c_id %d",
|
||||
which, nid);
|
||||
} else
|
||||
impossible("relink_light_sources: bad type (%d)", ls->type);
|
||||
|
||||
ls->flags &= ~LSF_NEEDS_FIXUP;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Part of the light source save routine. Count up the number of light
|
||||
* sources that would be written. If write_it is true, actually write
|
||||
* the light source out.
|
||||
*/
|
||||
STATIC_OVL int
|
||||
maybe_write_ls(fd, range, write_it)
|
||||
int fd, range;
|
||||
boolean write_it;
|
||||
{
|
||||
int count = 0, is_global;
|
||||
light_source *ls;
|
||||
|
||||
for (ls = light_base; ls; ls = ls->next) {
|
||||
if (!ls->id) {
|
||||
impossible("maybe_write_ls: no id! [range=%d]", range);
|
||||
continue;
|
||||
}
|
||||
switch (ls->type) {
|
||||
case LS_OBJECT:
|
||||
is_global = !obj_is_local((struct obj *)ls->id);
|
||||
break;
|
||||
case LS_MONSTER:
|
||||
is_global = !mon_is_local((struct monst *)ls->id);
|
||||
break;
|
||||
default:
|
||||
is_global = 0;
|
||||
impossible("maybe_write_ls: bad type (%d) [range=%d]",
|
||||
ls->type, range);
|
||||
break;
|
||||
}
|
||||
/* if global and not doing local, or vice versa, count it */
|
||||
if (is_global ^ (range == RANGE_LEVEL)) {
|
||||
count++;
|
||||
if (write_it) write_ls(fd, ls);
|
||||
}
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
/* Write a light source structure to disk. */
|
||||
STATIC_OVL void
|
||||
write_ls(fd, ls)
|
||||
int fd;
|
||||
light_source *ls;
|
||||
{
|
||||
genericptr_t arg_save;
|
||||
struct obj *otmp;
|
||||
struct monst *mtmp;
|
||||
|
||||
if (ls->type == LS_OBJECT || ls->type == LS_MONSTER) {
|
||||
if (ls->flags & LSF_NEEDS_FIXUP)
|
||||
bwrite(fd, (genericptr_t)ls, sizeof(light_source));
|
||||
else {
|
||||
/* replace object pointer with id for write, then put back */
|
||||
arg_save = ls->id;
|
||||
if (ls->type == LS_OBJECT) {
|
||||
otmp = (struct obj *)ls->id;
|
||||
ls->id = (genericptr_t)(intptr_t)otmp->o_id;
|
||||
#ifdef DEBUG
|
||||
if (find_oid((unsigned)(intptr_t)ls->id) != otmp)
|
||||
panic("write_ls: can't find obj #%u!", (unsigned)(intptr_t)ls->id);
|
||||
#endif
|
||||
} else { /* ls->type == LS_MONSTER */
|
||||
mtmp = (struct monst *)ls->id;
|
||||
ls->id = (genericptr_t)(intptr_t)(intptr_t)mtmp->m_id;
|
||||
#ifdef DEBUG
|
||||
if (find_mid((unsigned)(intptr_t)ls->id, FM_EVERYWHERE) != mtmp)
|
||||
panic("write_ls: can't find mon #%u!", (unsigned)ls->id);
|
||||
#endif
|
||||
}
|
||||
ls->flags |= LSF_NEEDS_FIXUP;
|
||||
bwrite(fd, (genericptr_t)ls, sizeof(light_source));
|
||||
ls->id = arg_save;
|
||||
ls->flags &= ~LSF_NEEDS_FIXUP;
|
||||
}
|
||||
} else {
|
||||
impossible("write_ls: bad type (%d)", ls->type);
|
||||
}
|
||||
}
|
||||
|
||||
/* Change light source's ID from src to dest. */
|
||||
void
|
||||
obj_move_light_source(src, dest)
|
||||
struct obj *src, *dest;
|
||||
{
|
||||
light_source *ls;
|
||||
|
||||
for (ls = light_base; ls; ls = ls->next)
|
||||
if (ls->type == LS_OBJECT && ls->id == (genericptr_t) src)
|
||||
ls->id = (genericptr_t) dest;
|
||||
src->lamplit = 0;
|
||||
dest->lamplit = 1;
|
||||
ls = (struct ls_t *)alloc(sizeof(struct ls_t));
|
||||
mread(fd, (genericptr_t) ls, sizeof(struct ls_t));
|
||||
add_chain_ls(ls);
|
||||
/* relink owner */
|
||||
ls->owner = owner;
|
||||
*owner_ls(lstype, owner) = ls;
|
||||
return;
|
||||
}
|
||||
|
||||
/* return true if there exist any light sources */
|
||||
boolean
|
||||
any_light_source()
|
||||
{
|
||||
return light_base != (light_source *) 0;
|
||||
return light_base != (struct ls_t *) 0;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -705,7 +563,7 @@ void
|
|||
snuff_light_source(x, y)
|
||||
int x, y;
|
||||
{
|
||||
light_source *ls, *nls;
|
||||
struct ls_t *ls, *nls;
|
||||
struct obj *obj;
|
||||
|
||||
for (ls = light_base; ls; ls = nls){
|
||||
|
@ -715,8 +573,8 @@ snuff_light_source(x, y)
|
|||
will always be correct because the objects would have been
|
||||
updated with the last vision update? [Is that recent enough???]
|
||||
*/
|
||||
if (ls->type == LS_OBJECT && ls->x == x && ls->y == y) {
|
||||
obj = (struct obj *) ls->id;
|
||||
if (ls->lstype == LS_OBJECT && ls->x == x && ls->y == y) {
|
||||
obj = (struct obj *) ls->owner;
|
||||
if (obj_is_burning(obj) && !Darkness_cant_snuff(obj)) {
|
||||
// this assumes snuff_light_source is only called on you're making DARKNESS,
|
||||
// never when you're making LIGHT sources to "snuff" darkness sources (shadow torches)
|
||||
|
@ -785,33 +643,27 @@ litsaber(obj)
|
|||
}
|
||||
}
|
||||
|
||||
/* copy the light source(s) attached to src, and attach it/them to dest */
|
||||
/* copy the light source attached to src, and attach it to dest */
|
||||
void
|
||||
obj_split_light_source(src, dest)
|
||||
struct obj *src, *dest;
|
||||
{
|
||||
light_source *ls, *new_ls;
|
||||
/* safety check */
|
||||
if (!src->light)
|
||||
return;
|
||||
|
||||
for (ls = light_base; ls; ls = ls->next)
|
||||
if (ls->type == LS_OBJECT && ls->id == (genericptr_t) src) {
|
||||
/*
|
||||
* Insert the new source at beginning of list. This will
|
||||
* never interfere us walking down the list - we are already
|
||||
* past the insertion point.
|
||||
*/
|
||||
new_ls = (light_source *) alloc(sizeof(light_source));
|
||||
*new_ls = *ls;
|
||||
if (Is_candle(src)) {
|
||||
/* make a new ls on dest */
|
||||
new_light_source(LS_OBJECT, (genericptr_t)dest, src->light->range);
|
||||
dest->lamplit = 1; /* now an active light source */
|
||||
|
||||
/* split candles may emit less light than original group */
|
||||
if (Is_candle(src)) {
|
||||
/* split candles may emit less light than original group */
|
||||
ls->range = candle_light_range(src);
|
||||
new_ls->range = candle_light_range(dest);
|
||||
src->light->range = candle_light_range(src);
|
||||
dest->light->range = candle_light_range(dest);
|
||||
vision_full_recalc = 1; /* in case range changed */
|
||||
}
|
||||
new_ls->id = (genericptr_t) dest;
|
||||
new_ls->next = light_base;
|
||||
light_base = new_ls;
|
||||
dest->lamplit = 1; /* now an active light source */
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/* light source `src' has been folded into light source `dest';
|
||||
|
@ -820,17 +672,16 @@ void
|
|||
obj_merge_light_sources(src, dest)
|
||||
struct obj *src, *dest;
|
||||
{
|
||||
light_source *ls;
|
||||
struct ls_t *ls;
|
||||
|
||||
/* src == dest implies adding to candelabrum */
|
||||
if (src != dest) end_burn(src, TRUE); /* extinguish candles */
|
||||
|
||||
for (ls = light_base; ls; ls = ls->next)
|
||||
if (ls->type == LS_OBJECT && ls->id == (genericptr_t) dest) {
|
||||
ls->range = candle_light_range(dest);
|
||||
vision_full_recalc = 1; /* in case range changed */
|
||||
break;
|
||||
if (dest->light) {
|
||||
dest->light->range = candle_light_range(dest);
|
||||
vision_full_recalc = 1;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/* Candlelight is proportional to the number of candles;
|
||||
|
@ -882,7 +733,7 @@ wiz_light_sources()
|
|||
{
|
||||
winid win;
|
||||
char buf[BUFSZ], arg_address[20];
|
||||
light_source *ls;
|
||||
struct ls_t *ls;
|
||||
|
||||
win = create_nhwindow(NHW_MENU); /* corner text window */
|
||||
if (win == WIN_ERR) return 0;
|
||||
|
@ -897,13 +748,13 @@ wiz_light_sources()
|
|||
for (ls = light_base; ls; ls = ls->next) {
|
||||
Sprintf(buf, " %2d,%2d %2d 0x%04x %s %s",
|
||||
ls->x, ls->y, ls->range, ls->flags,
|
||||
(ls->type == LS_OBJECT ? "obj" :
|
||||
ls->type == LS_MONSTER ?
|
||||
(mon_is_local((struct monst *)ls->id) ? "mon" :
|
||||
((struct monst *)ls->id == &youmonst) ? "you" :
|
||||
(ls->lstype == LS_OBJECT ? "obj" :
|
||||
ls->lstype == LS_MONSTER ?
|
||||
(mon_is_local((struct monst *)ls->owner) ? "mon" :
|
||||
((struct monst *)ls->owner == &youmonst) ? "you" :
|
||||
"<m>") : /* migrating monster */
|
||||
"???"),
|
||||
fmt_ptr(ls->id, arg_address));
|
||||
fmt_ptr(ls->owner, arg_address));
|
||||
putstr(win, 0, buf);
|
||||
}
|
||||
} else
|
||||
|
|
|
@ -7643,8 +7643,7 @@ xchar x, y; /* clone's preferred location or 0 (near mon) */
|
|||
if (mon->ispriest) m2->ispriest = FALSE;
|
||||
place_monster(m2, m2->mx, m2->my);
|
||||
if (emits_light_mon(m2))
|
||||
new_light_source(m2->mx, m2->my, emits_light_mon(m2),
|
||||
LS_MONSTER, (genericptr_t)m2);
|
||||
new_light_source(LS_MONSTER, (genericptr_t)m2, emits_light_mon(m2));
|
||||
if (M_HAS_NAME(mon)) {
|
||||
cpy_mx(mon, m2, MX_ENAM);
|
||||
} else if (mon->isshk) {
|
||||
|
@ -8947,8 +8946,7 @@ register int mmflags;
|
|||
mtmp->mhp = mtmp->mhpmax;
|
||||
}
|
||||
if ((ct = emits_light_mon(mtmp)) > 0)
|
||||
new_light_source(mtmp->mx, mtmp->my, ct,
|
||||
LS_MONSTER, (genericptr_t)mtmp);
|
||||
new_light_source(LS_MONSTER, (genericptr_t)mtmp, ct);
|
||||
mitem = 0; /* extra inventory item for this monster */
|
||||
|
||||
if ((mcham = pm_to_cham(mndx)) != CHAM_ORDINARY) {
|
||||
|
|
10
src/mkobj.c
10
src/mkobj.c
|
@ -391,6 +391,11 @@ long num;
|
|||
panic("splitobj"); /* can't split containers */
|
||||
otmp = newobj(0);
|
||||
*otmp = *obj; /* copies whole structure */
|
||||
/* invalidate pointers */
|
||||
otmp->light = (struct ls_t *)0;
|
||||
otmp->oextra_p = (union oextra *)0;
|
||||
otmp->mp = (struct mask_properties *)0; /* not sure if correct -- these are very unfinished */
|
||||
|
||||
otmp->o_id = flags.ident++;
|
||||
if (!otmp->o_id) otmp->o_id = flags.ident++; /* ident overflowed */
|
||||
otmp->timed = 0; /* not timed, yet */
|
||||
|
@ -2534,6 +2539,7 @@ struct monst *mtmp;
|
|||
EMON(obj)->nmon = (struct monst *)0;
|
||||
EMON(obj)->data = (struct permonst *)0;
|
||||
EMON(obj)->minvent = (struct obj *)0;
|
||||
EMON(obj)->light = (struct ls_t *)0;
|
||||
return obj;
|
||||
}
|
||||
|
||||
|
@ -3186,9 +3192,9 @@ dealloc_obj(obj)
|
|||
|
||||
/*
|
||||
* Free up any light sources attached to the object.
|
||||
*
|
||||
*/
|
||||
del_light_source(LS_OBJECT, (genericptr_t) obj, TRUE);
|
||||
if (obj->light)
|
||||
del_light_source(obj->light);
|
||||
|
||||
//if (obj == thrownobj) thrownobj = (struct obj*)0;
|
||||
|
||||
|
|
30
src/mon.c
30
src/mon.c
|
@ -3782,11 +3782,9 @@ register struct monst *mtmp, *mtmp2;
|
|||
place_wsegs(mtmp2); /* locations to mtmp2 not mtmp. */
|
||||
if (emits_light_mon(mtmp2)) {
|
||||
/* since this is so rare, we don't have any `mon_move_light_source' */
|
||||
new_light_source(mtmp2->mx, mtmp2->my,
|
||||
emits_light_mon(mtmp2),
|
||||
LS_MONSTER, (genericptr_t)mtmp2);
|
||||
new_light_source(LS_MONSTER, (genericptr_t)mtmp2, emits_light_mon(mtmp2));
|
||||
/* here we rely on the fact that `mtmp' hasn't actually been deleted */
|
||||
del_light_source(LS_MONSTER, (genericptr_t)mtmp, FALSE);
|
||||
del_light_source(mtmp->light);
|
||||
}
|
||||
mtmp2->nmon = fmon;
|
||||
fmon = mtmp2;
|
||||
|
@ -3831,8 +3829,7 @@ struct permonst *mptr; /* reflects mtmp->data _prior_ to mtmp's death */
|
|||
mtmp->mhp = 0; /* simplify some tests: force mhp to 0 */
|
||||
relobj(mtmp, 0, FALSE);
|
||||
remove_monster(mtmp->mx, mtmp->my);
|
||||
if (emits_light_mon(mtmp) || emits_light(mptr)) /* TODO: actually check if the monster has an attached ls */
|
||||
del_light_source(LS_MONSTER, (genericptr_t)mtmp, FALSE);
|
||||
del_light_source(mtmp->light);
|
||||
newsym(mtmp->mx,mtmp->my);
|
||||
unstuck(mtmp);
|
||||
fill_pit(mtmp->mx, mtmp->my);
|
||||
|
@ -4082,10 +4079,9 @@ struct monst *mtmp;
|
|||
/* If marked to do so, remve illuminated status */
|
||||
if (!(lifesavers&LSVD_ILU)){
|
||||
set_template(mtmp, 0);
|
||||
del_light_source(LS_MONSTER, (genericptr_t)mtmp, FALSE);
|
||||
del_light_source(mtmp->light);
|
||||
if (emits_light_mon(mtmp))
|
||||
new_light_source(mtmp->mx, mtmp->my, emits_light_mon(mtmp),
|
||||
LS_MONSTER, (genericptr_t)mtmp);
|
||||
new_light_source(LS_MONSTER, (genericptr_t)mtmp, emits_light_mon(mtmp));
|
||||
}
|
||||
break;
|
||||
case LSVD_PLY:
|
||||
|
@ -6602,18 +6598,14 @@ boolean msg; /* "The oldmon turns into a newmon!" */
|
|||
/* take on the new form... */
|
||||
set_mon_data(mtmp, mtyp);
|
||||
|
||||
if (emits_light(olddata) != emits_light_mon(mtmp)
|
||||
|| olddata->mtyp == PM_MASKED_QUEEN
|
||||
) {
|
||||
/* used to give light, now doesn't, or vice versa,
|
||||
or light's range has changed */
|
||||
if (emits_light(olddata) || has_template(mtmp, ILLUMINATED))
|
||||
del_light_source(LS_MONSTER, (genericptr_t)mtmp, FALSE);
|
||||
/* monster lightsources */
|
||||
del_light_source(mtmp->light); /* clear old */
|
||||
if (emits_light_mon(mtmp)|| olddata->mtyp == PM_MASKED_QUEEN) {
|
||||
/* masked queen is effectively illuminated, but not -- poly should add illumination */
|
||||
if(olddata->mtyp == PM_MASKED_QUEEN)
|
||||
set_template(mtmp, ILLUMINATED);
|
||||
if (emits_light_mon(mtmp))
|
||||
new_light_source(mtmp->mx, mtmp->my, emits_light_mon(mtmp),
|
||||
LS_MONSTER, (genericptr_t)mtmp);
|
||||
/* now add lightsource */
|
||||
new_light_source(LS_MONSTER, (genericptr_t)mtmp, emits_light_mon(mtmp));
|
||||
}
|
||||
if (!mtmp->perminvis || pm_invisible(olddata))
|
||||
mtmp->perminvis = pm_invisible(mdat);
|
||||
|
|
|
@ -351,12 +351,10 @@ boolean forcecontrol;
|
|||
made_change:
|
||||
new_light = Upolyd ? emits_light(youmonst.data) : 0;
|
||||
if (old_light != new_light) {
|
||||
if (old_light)
|
||||
del_light_source(LS_MONSTER, (genericptr_t)&youmonst, FALSE);
|
||||
del_light_source((&youmonst)->light);
|
||||
if (new_light == 1) ++new_light; /* otherwise it's undetectable */
|
||||
if (new_light)
|
||||
new_light_source(u.ux, u.uy, new_light,
|
||||
LS_MONSTER, (genericptr_t)&youmonst);
|
||||
new_light_source(LS_MONSTER, (genericptr_t)&youmonst, new_light);
|
||||
}
|
||||
if (is_pool(u.ux,u.uy, FALSE) && was_floating && !(Levitation || Flying) &&
|
||||
!breathless(youmonst.data) && !amphibious(youmonst.data) &&
|
||||
|
@ -804,8 +802,9 @@ rehumanize()
|
|||
done(DIED);
|
||||
}
|
||||
|
||||
if (emits_light(youracedata))
|
||||
del_light_source(LS_MONSTER, (genericptr_t)&youmonst, FALSE);
|
||||
/* delete any ls attached to you */
|
||||
del_light_source((&youmonst)->light);
|
||||
|
||||
polyman("return to %s form!", urace.adj);
|
||||
|
||||
if (u.uhp < 1) {
|
||||
|
|
|
@ -216,6 +216,9 @@ boolean ghostly, frozen;
|
|||
if(otmp->oextra_p){
|
||||
rest_oextra(otmp, fd, ghostly);
|
||||
}
|
||||
if (otmp->light) {
|
||||
rest_lightsource(LS_OBJECT, otmp, otmp->light, fd, ghostly);
|
||||
}
|
||||
if (ghostly) {
|
||||
unsigned nid = flags.ident++;
|
||||
add_id_mapping(otmp->o_id, nid);
|
||||
|
@ -276,6 +279,9 @@ boolean ghostly;
|
|||
if (mtmp->mextra_p) {
|
||||
rest_mextra(mtmp, fd, ghostly);
|
||||
}
|
||||
if (mtmp->light) {
|
||||
rest_lightsource(LS_MONSTER, mtmp, mtmp->light, fd, ghostly);
|
||||
}
|
||||
if (ghostly) {
|
||||
unsigned nid = flags.ident++;
|
||||
add_id_mapping(mtmp->m_id, nid);
|
||||
|
@ -462,7 +468,6 @@ unsigned int *stuckid, *steedid; /* STEED */
|
|||
|
||||
/* this stuff comes after potential aborted restore attempts */
|
||||
restore_timers(fd, RANGE_GLOBAL, FALSE, 0L);
|
||||
restore_light_sources(fd);
|
||||
invent = restobjchn(fd, FALSE, FALSE);
|
||||
bc_obj = restobjchn(fd, FALSE, FALSE);
|
||||
while (bc_obj) {
|
||||
|
@ -523,7 +528,6 @@ unsigned int *stuckid, *steedid; /* STEED */
|
|||
#endif
|
||||
/* must come after all mons & objs are restored */
|
||||
relink_timers(FALSE);
|
||||
relink_light_sources(FALSE);
|
||||
#ifdef WHEREIS_FILE
|
||||
touch_whereis();
|
||||
#endif
|
||||
|
@ -901,7 +905,6 @@ boolean ghostly;
|
|||
doorindex = 0;
|
||||
|
||||
restore_timers(fd, RANGE_LEVEL, ghostly, monstermoves - omoves);
|
||||
restore_light_sources(fd);
|
||||
fmon = restmonchn(fd, ghostly);
|
||||
|
||||
rest_worm(fd); /* restore worm information */
|
||||
|
@ -995,7 +998,6 @@ boolean ghostly;
|
|||
|
||||
/* must come after all mons & objs are restored */
|
||||
relink_timers(ghostly);
|
||||
relink_light_sources(ghostly);
|
||||
reset_oattached_mids(ghostly);
|
||||
|
||||
/* regenerate animals while on another level */
|
||||
|
|
11
src/save.c
11
src/save.c
|
@ -314,7 +314,6 @@ register int fd, mode;
|
|||
|
||||
/* must come before migrating_objs and migrating_mons are freed */
|
||||
save_timers(fd, mode, RANGE_GLOBAL);
|
||||
save_light_sources(fd, mode, RANGE_GLOBAL);
|
||||
|
||||
if (CHAIN_IN_MON) {
|
||||
uchain->nobj = bc_objs;
|
||||
|
@ -583,7 +582,6 @@ int mode;
|
|||
skip_lots:
|
||||
/* must be saved before mons, objs, and buried objs */
|
||||
save_timers(fd, mode, RANGE_LEVEL);
|
||||
save_light_sources(fd, mode, RANGE_LEVEL);
|
||||
|
||||
savemonchn(fd, fmon, mode);
|
||||
save_worm(fd, mode); /* save worm information */
|
||||
|
@ -910,6 +908,9 @@ register struct obj *otmp;
|
|||
if (otmp->oextra_p) {
|
||||
save_oextra(otmp, fd, mode);
|
||||
}
|
||||
if (otmp->light) {
|
||||
save_lightsource(otmp->light, fd, mode);
|
||||
}
|
||||
}
|
||||
if (Has_contents(otmp))
|
||||
saveobjchn(fd,otmp->cobj,mode);
|
||||
|
@ -948,6 +949,9 @@ register struct monst *mtmp;
|
|||
if(mtmp->mextra_p)
|
||||
save_mextra(mtmp, fd, mode);
|
||||
}
|
||||
if (mtmp->light) {
|
||||
save_lightsource(mtmp->light, fd, mode);
|
||||
}
|
||||
if (mtmp->minvent)
|
||||
saveobjchn(fd,mtmp->minvent,mode);
|
||||
if (release_data(mode))
|
||||
|
@ -1092,7 +1096,6 @@ freedynamicdata()
|
|||
# define free_waterlevel() save_waterlevel(0, FREE_SAVE)
|
||||
# define free_worm() save_worm(0, FREE_SAVE)
|
||||
# define free_timers(R) save_timers(0, FREE_SAVE, R)
|
||||
# define free_light_sources(R) save_light_sources(0, FREE_SAVE, R);
|
||||
# define free_engravings() save_engravings(0, FREE_SAVE)
|
||||
# define freedamage() savedamage(0, FREE_SAVE)
|
||||
# define free_animals() mon_animal_list(FALSE)
|
||||
|
@ -1102,7 +1105,6 @@ freedynamicdata()
|
|||
|
||||
/* level-specific data */
|
||||
free_timers(RANGE_LEVEL);
|
||||
free_light_sources(RANGE_LEVEL);
|
||||
freemonchn(fmon);
|
||||
free_worm(); /* release worm segment information */
|
||||
freetrapchn(ftrap);
|
||||
|
@ -1114,7 +1116,6 @@ freedynamicdata()
|
|||
|
||||
/* game-state data */
|
||||
free_timers(RANGE_GLOBAL);
|
||||
free_light_sources(RANGE_GLOBAL);
|
||||
freeobjchn(invent);
|
||||
for(i=0;i<10;i++) freeobjchn(magic_chest_objs[i]);
|
||||
freeobjchn(migrating_objs);
|
||||
|
|
|
@ -2328,15 +2328,9 @@ begin_burn(obj)
|
|||
|
||||
if (obj->lamplit) {
|
||||
xchar x, y;
|
||||
if (already_lit)
|
||||
del_light_source(LS_OBJECT, (genericptr_t)obj, TRUE);
|
||||
if (get_obj_location(obj, &x, &y, CONTAINED_TOO | BURIED_TOO)) {
|
||||
new_light_source(x, y, radius, LS_OBJECT, (genericptr_t)obj);
|
||||
}
|
||||
else{
|
||||
/* make the new light source at (0,0) since we can't get its position */
|
||||
new_light_source(0, 0, radius, LS_OBJECT, (genericptr_t)obj);
|
||||
}
|
||||
if (already_lit) /* to give an error if already_lit != actually had an ls */
|
||||
del_light_source(obj->light);
|
||||
new_light_source(LS_OBJECT, (genericptr_t)obj, radius);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2364,7 +2358,7 @@ end_burn(obj, timer_attached)
|
|||
|
||||
if (!timer_attached) {
|
||||
/* [DS] Cleanup explicitly, since timer cleanup won't happen */
|
||||
del_light_source(LS_OBJECT, (genericptr_t)obj, FALSE);
|
||||
del_light_source(obj->light);
|
||||
obj->lamplit = 0;
|
||||
if (obj->where == OBJ_INVENT)
|
||||
update_inventory();
|
||||
|
@ -2394,8 +2388,7 @@ cleanup_burn(arg, expire_time)
|
|||
impossible("cleanup_burn: obj %s not lit", xname(obj));
|
||||
return;
|
||||
}
|
||||
|
||||
del_light_source(LS_OBJECT, arg, FALSE);
|
||||
del_light_source(((struct obj *)arg)->light);
|
||||
|
||||
/* restore unused time */
|
||||
obj->age += expire_time - monstermoves;
|
||||
|
|
51
src/were.c
51
src/were.c
|
@ -195,14 +195,10 @@ struct monst *mon;
|
|||
}
|
||||
/* regenerate by 1/4 of the lost hit points */
|
||||
mon->mhp += (mon->mhpmax - mon->mhp) / 4;
|
||||
if (emits_light(olddata) != emits_light_mon(mon)) {
|
||||
/* used to give light, now doesn't, or vice versa,
|
||||
or light's range has changed */
|
||||
if (emits_light(olddata) || has_template(mon, ILLUMINATED))
|
||||
del_light_source(LS_MONSTER, (genericptr_t)mon, FALSE);
|
||||
if (emits_light_mon(mon))
|
||||
new_light_source(mon->mx, mon->my, emits_light_mon(mon),
|
||||
LS_MONSTER, (genericptr_t)mon);
|
||||
/* recheck if monster is a lightsource */
|
||||
del_light_source(mon->light);
|
||||
if (emits_light_mon(mon)) {
|
||||
new_light_source(LS_MONSTER, (genericptr_t)mon, emits_light_mon(mon));
|
||||
}
|
||||
newsym(mon->mx,mon->my);
|
||||
if(is_eeladrin(mon->data)){
|
||||
|
@ -229,38 +225,15 @@ struct monst *mon;
|
|||
}
|
||||
}
|
||||
if(mon->mtyp == PM_ANCIENT_TEMPEST){
|
||||
static int elemtypes[] = {PM_WATER_ELEMENTAL, PM_AIR_ELEMENTAL, PM_LIGHTNING_PARAELEMENTAL, PM_ICE_PARAELEMENTAL};
|
||||
struct monst *ltnt;
|
||||
for(ltnt = fmon; ltnt; ltnt = ltnt->nmon) if(ltnt->mtyp == PM_WIDE_CLUBBED_TENTACLE){
|
||||
switch(rnd(4)){
|
||||
case 1:
|
||||
if (emits_light_mon(ltnt)) del_light_source(LS_MONSTER, (genericptr_t)ltnt, FALSE);
|
||||
set_mon_data(ltnt, PM_WATER_ELEMENTAL);
|
||||
newsym(ltnt->mx,ltnt->my);
|
||||
if (emits_light_mon(ltnt)) new_light_source(ltnt->mx, ltnt->my, emits_light_mon(ltnt),
|
||||
LS_MONSTER, (genericptr_t)ltnt);
|
||||
break;
|
||||
case 2:
|
||||
if (emits_light_mon(ltnt)) del_light_source(LS_MONSTER, (genericptr_t)ltnt, FALSE);
|
||||
set_mon_data(ltnt, PM_AIR_ELEMENTAL);
|
||||
newsym(ltnt->mx,ltnt->my);
|
||||
if (emits_light_mon(ltnt)) new_light_source(ltnt->mx, ltnt->my, emits_light_mon(ltnt),
|
||||
LS_MONSTER, (genericptr_t)ltnt);
|
||||
break;
|
||||
case 3:
|
||||
if (emits_light_mon(ltnt)) del_light_source(LS_MONSTER, (genericptr_t)ltnt, FALSE);
|
||||
set_mon_data(ltnt, PM_LIGHTNING_PARAELEMENTAL);
|
||||
newsym(ltnt->mx,ltnt->my);
|
||||
if (emits_light_mon(ltnt)) new_light_source(ltnt->mx, ltnt->my, emits_light_mon(ltnt),
|
||||
LS_MONSTER, (genericptr_t)ltnt);
|
||||
break;
|
||||
case 4:
|
||||
if (emits_light_mon(ltnt)) del_light_source(LS_MONSTER, (genericptr_t)ltnt, FALSE);
|
||||
set_mon_data(ltnt, PM_ICE_PARAELEMENTAL);
|
||||
newsym(ltnt->mx,ltnt->my);
|
||||
if (emits_light_mon(ltnt)) new_light_source(ltnt->mx, ltnt->my, emits_light_mon(ltnt),
|
||||
LS_MONSTER, (genericptr_t)ltnt);
|
||||
break;
|
||||
}
|
||||
for(ltnt = fmon; ltnt; ltnt = ltnt->nmon)
|
||||
if(ltnt->mtyp == PM_WIDE_CLUBBED_TENTACLE){
|
||||
del_light_source(ltnt->light);
|
||||
set_mon_data(ltnt, elemtypes[rn2(4)]);
|
||||
newsym(ltnt->mx,ltnt->my);
|
||||
if (emits_light_mon(ltnt))
|
||||
new_light_source(LS_MONSTER, (genericptr_t)ltnt, emits_light_mon(ltnt));
|
||||
}
|
||||
}
|
||||
} else if(is_heladrin(mon->data)){
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue