monsters entering regions
Region processing does a lot of looping--when there are actually regions present--and calls functions in those loops which do more looping of their own. This moves some of the simpler tests so that they get done sooner and can avoid some of those function calls. I was hoping that it would speed up the turn cycle on the Plane of Fire where the spontaneous irregularly shaped fumaroles are composed of a lot of small regions but I don't think there's any noticeable difference. In process of doing that, I discovered a bug (no doubt copy+paste which escaped an intended update) with monster handling. The check for whether a monster is entering a region depends upon whether the hero is in that same region rather than whether the monster is already inside. So a monster can enter a region--or have a moving one enclose it--with impunity if the hero is already in that region. Once the hero moves out of it, the monster will finally enter it.
This commit is contained in:
94
src/region.c
94
src/region.c
@@ -1,4 +1,4 @@
|
||||
/* NetHack 3.6 region.c $NHDT-Date: 1543455828 2018/11/29 01:43:48 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.43 $ */
|
||||
/* NetHack 3.6 region.c $NHDT-Date: 1573933605 2019/11/16 19:46:45 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.44 $ */
|
||||
/* Copyright (c) 1996 by Jean-Christophe Collet */
|
||||
/* NetHack may be freely redistributed. See license for details. */
|
||||
|
||||
@@ -430,24 +430,25 @@ xchar x, y;
|
||||
{
|
||||
int i, f_indx;
|
||||
|
||||
/* First check if we can do the move */
|
||||
/* First check if hero can do the move */
|
||||
for (i = 0; i < n_regions; i++) {
|
||||
if (inside_region(regions[i], x, y) && !hero_inside(regions[i])
|
||||
&& !regions[i]->attach_2_u) {
|
||||
if ((f_indx = regions[i]->can_enter_f) != NO_CALLBACK)
|
||||
if (!(*callbacks[f_indx])(regions[i], (genericptr_t) 0))
|
||||
return FALSE;
|
||||
} else if (hero_inside(regions[i]) && !inside_region(regions[i], x, y)
|
||||
&& !regions[i]->attach_2_u) {
|
||||
if ((f_indx = regions[i]->can_leave_f) != NO_CALLBACK)
|
||||
if (!(*callbacks[f_indx])(regions[i], (genericptr_t) 0))
|
||||
return FALSE;
|
||||
if (regions[i]->attach_2_u)
|
||||
continue;
|
||||
if (inside_region(regions[i], x, y)
|
||||
? (!hero_inside(regions[i])
|
||||
&& (f_indx = regions[i]->can_enter_f) != NO_CALLBACK)
|
||||
: (hero_inside(regions[i])
|
||||
&& (f_indx = regions[i]->can_leave_f) != NO_CALLBACK)) {
|
||||
if (!(*callbacks[f_indx])(regions[i], (genericptr_t) 0))
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/* Callbacks for the regions we do leave */
|
||||
for (i = 0; i < n_regions; i++)
|
||||
if (hero_inside(regions[i]) && !regions[i]->attach_2_u
|
||||
/* Callbacks for the regions hero does leave */
|
||||
for (i = 0; i < n_regions; i++) {
|
||||
if (regions[i]->attach_2_u)
|
||||
continue;
|
||||
if (hero_inside(regions[i])
|
||||
&& !inside_region(regions[i], x, y)) {
|
||||
clear_hero_inside(regions[i]);
|
||||
if (regions[i]->leave_msg != (const char *) 0)
|
||||
@@ -455,10 +456,13 @@ xchar x, y;
|
||||
if ((f_indx = regions[i]->leave_f) != NO_CALLBACK)
|
||||
(void) (*callbacks[f_indx])(regions[i], (genericptr_t) 0);
|
||||
}
|
||||
}
|
||||
|
||||
/* Callbacks for the regions we do enter */
|
||||
for (i = 0; i < n_regions; i++)
|
||||
if (!hero_inside(regions[i]) && !regions[i]->attach_2_u
|
||||
/* Callbacks for the regions hero does enter */
|
||||
for (i = 0; i < n_regions; i++) {
|
||||
if (regions[i]->attach_2_u)
|
||||
continue;
|
||||
if (!hero_inside(regions[i])
|
||||
&& inside_region(regions[i], x, y)) {
|
||||
set_hero_inside(regions[i]);
|
||||
if (regions[i]->enter_msg != (const char *) 0)
|
||||
@@ -466,12 +470,14 @@ xchar x, y;
|
||||
if ((f_indx = regions[i]->enter_f) != NO_CALLBACK)
|
||||
(void) (*callbacks[f_indx])(regions[i], (genericptr_t) 0);
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* check whether a monster enters/leaves one or more region.
|
||||
*/
|
||||
* check whether a monster enters/leaves one or more regions.
|
||||
*/
|
||||
boolean
|
||||
m_in_out_region(mon, x, y)
|
||||
struct monst *mon;
|
||||
@@ -479,40 +485,44 @@ xchar x, y;
|
||||
{
|
||||
int i, f_indx;
|
||||
|
||||
/* First check if we can do the move */
|
||||
/* First check if mon can do the move */
|
||||
for (i = 0; i < n_regions; i++) {
|
||||
if (inside_region(regions[i], x, y) && !mon_in_region(regions[i], mon)
|
||||
&& regions[i]->attach_2_m != mon->m_id) {
|
||||
if ((f_indx = regions[i]->can_enter_f) != NO_CALLBACK)
|
||||
if (!(*callbacks[f_indx])(regions[i], mon))
|
||||
return FALSE;
|
||||
} else if (mon_in_region(regions[i], mon)
|
||||
&& !inside_region(regions[i], x, y)
|
||||
&& regions[i]->attach_2_m != mon->m_id) {
|
||||
if ((f_indx = regions[i]->can_leave_f) != NO_CALLBACK)
|
||||
if (!(*callbacks[f_indx])(regions[i], mon))
|
||||
return FALSE;
|
||||
if (regions[i]->attach_2_m == mon->m_id)
|
||||
continue;
|
||||
if (inside_region(regions[i], x, y)
|
||||
? (!mon_in_region(regions[i], mon)
|
||||
&& (f_indx = regions[i]->can_enter_f) != NO_CALLBACK)
|
||||
: (mon_in_region(regions[i], mon)
|
||||
&& (f_indx = regions[i]->can_leave_f) != NO_CALLBACK)) {
|
||||
if (!(*callbacks[f_indx])(regions[i], mon))
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/* Callbacks for the regions we do leave */
|
||||
for (i = 0; i < n_regions; i++)
|
||||
/* Callbacks for the regions mon does leave */
|
||||
for (i = 0; i < n_regions; i++) {
|
||||
if (regions[i]->attach_2_m == mon->m_id)
|
||||
continue;
|
||||
if (mon_in_region(regions[i], mon)
|
||||
&& regions[i]->attach_2_m != mon->m_id
|
||||
&& !inside_region(regions[i], x, y)) {
|
||||
remove_mon_from_reg(regions[i], mon);
|
||||
if ((f_indx = regions[i]->leave_f) != NO_CALLBACK)
|
||||
(void) (*callbacks[f_indx])(regions[i], mon);
|
||||
}
|
||||
}
|
||||
|
||||
/* Callbacks for the regions we do enter */
|
||||
for (i = 0; i < n_regions; i++)
|
||||
if (!hero_inside(regions[i]) && !regions[i]->attach_2_u
|
||||
/* Callbacks for the regions mon does enter */
|
||||
for (i = 0; i < n_regions; i++) {
|
||||
if (regions[i]->attach_2_m == mon->m_id)
|
||||
continue;
|
||||
if (!mon_in_region(regions[i], mon)
|
||||
&& inside_region(regions[i], x, y)) {
|
||||
add_mon_to_reg(regions[i], mon);
|
||||
if ((f_indx = regions[i]->enter_f) != NO_CALLBACK)
|
||||
(void) (*callbacks[f_indx])(regions[i], mon);
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -598,10 +608,12 @@ xchar x, y;
|
||||
{
|
||||
register int i;
|
||||
|
||||
for (i = 0; i < n_regions; i++)
|
||||
if (inside_region(regions[i], x, y) && regions[i]->visible
|
||||
&& regions[i]->ttl != -2L)
|
||||
for (i = 0; i < n_regions; i++) {
|
||||
if (!regions[i]->visible || regions[i]->ttl == -2L)
|
||||
continue;
|
||||
if (inside_region(regions[i], x, y))
|
||||
return regions[i];
|
||||
}
|
||||
return (NhRegion *) 0;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user