From: PatR Date: Sat, 16 Nov 2019 19:46:50 +0000 (-0800) Subject: monsters entering regions X-Git-Tag: NetHack-3.6.3.beta1.2019.11.17~15^2~1 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=020825bc73d3142a0781a87d19a4f5da463b6456;p=nethack 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. --- diff --git a/doc/fixes36.3 b/doc/fixes36.3 index d65976a9d..302dd0e0c 100644 --- a/doc/fixes36.3 +++ b/doc/fixes36.3 @@ -1,4 +1,4 @@ -$NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.178 $ $NHDT-Date: 1573848574 2019/11/15 20:09:34 $ +$NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.180 $ $NHDT-Date: 1573933605 2019/11/16 19:46:45 $ This fixes36.3 file is here to capture information about updates in the 3.6.x lineage following the release of 3.6.2 in May 2019. Please note, however, @@ -233,6 +233,8 @@ dipping into an undiscovered potion would offer chance to give a name to the dipping lichen corpse into acid when not blind and acid was undicovered would not offer a chance to give a name to the potion after lichen feedback pluralization improvement for words ending in a k-sound like "biotech" +check for whether a monster was entering a region (gas cloud) erroneously + depended upon whether or not the hero was inside the same region Fixes to Post-3.6.2 Problems that Were Exposed Via git Repository diff --git a/src/region.c b/src/region.c index ad94426fa..9422de20c 100644 --- a/src/region.c +++ b/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; }