OSDN Git Service

update year to 2022
[jnethack/source.git] / src / region.c
index 9890458..332040e 100644 (file)
@@ -1,10 +1,10 @@
-/* NetHack 3.6 region.c        $NHDT-Date: 1496087244 2017/05/29 19:47:24 $  $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.40 $ */
+/* NetHack 3.6 region.c        $NHDT-Date: 1573957877 2019/11/17 02:31:17 $  $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.45 $ */
 /* Copyright (c) 1996 by Jean-Christophe Collet  */
 /* NetHack may be freely redistributed.  See license for details. */
 
 /* JNetHack Copyright */
 /* (c) Issei Numata, Naoki Hamada, Shigehiro Miyashita, 1994-2000  */
-/* For 3.4-, Copyright (c) SHIRAKATA Kentaro, 2002-2016            */
+/* For 3.4-, Copyright (c) SHIRAKATA Kentaro, 2002-2022            */
 /* JNetHack may be freely redistributed.  See license for details. */
 
 #include "hack.h"
@@ -345,6 +345,11 @@ NhRegion *reg;
     if (i == n_regions)
         return;
 
+    /* remove region before potential newsym() calls, but don't free it yet */
+    if (--n_regions != i)
+        regions[i] = regions[n_regions];
+    regions[n_regions] = (NhRegion *) 0;
+
     /* Update screen if necessary */
     reg->ttl = -2L; /* for visible_region_at */
     if (reg->visible)
@@ -354,9 +359,6 @@ NhRegion *reg;
                     newsym(x, y);
 
     free_region(reg);
-    regions[i] = regions[n_regions - 1];
-    regions[n_regions - 1] = (NhRegion *) 0;
-    n_regions--;
 }
 
 /*
@@ -413,7 +415,7 @@ run_regions()
                 struct monst *mtmp =
                     find_mid(regions[i]->monsters[j], FM_FMON);
 
-                if (!mtmp || mtmp->mhp <= 0
+                if (!mtmp || DEADMONSTER(mtmp)
                     || (*callbacks[f_indx])(regions[i], mtmp)) {
                     /* The monster died, remove it from list */
                     k = (regions[i]->n_monst -= 1);
@@ -433,26 +435,27 @@ boolean
 in_out_region(x, y)
 xchar x, y;
 {
-    int i, f_indx;
+    int i, f_indx = 0;
 
-    /* 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)
@@ -460,10 +463,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)
@@ -471,53 +477,59 @@ 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;
 xchar x, y;
 {
-    int i, f_indx;
+    int i, f_indx = 0;
 
-    /* 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;
 }
 
@@ -603,10 +615,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;
 }
 
@@ -862,15 +876,27 @@ genericptr_t p2;
 
     if (p2 == (genericptr_t) 0) { /* That means the player */
         if (!Blind)
-            You("bump into %s. Ouch!",
+#if 0 /*JP*/
+            You("bump into %s.  Ouch!",
                 Hallucination ? "an invisible tree"
                               : "some kind of invisible wall");
+#else
+            You("%s\82É\82Ô\82¿\82 \82½\82Á\82½\81D\82¢\82Ä\82Á\81I",
+                Hallucination ? "\96Ú\82É\8c©\82¦\82È\82¢\96Ø"
+                              : "\82È\82ñ\82ç\82©\82Ì\96Ú\82É\8c©\82¦\82È\82¢\95Ç");
+#endif
         else
+/*JP
             pline("Ouch!");
+*/
+            pline("\82¢\82Ä\82Á\81I");
     } else {
         mtmp = (struct monst *) p2;
         if (canseemon(mtmp))
+/*JP
             pline("%s bumps into %s!", Monnam(mtmp), something);
+*/
+            pline("%s\82Í%s\82É\82Ô\82¿\82 \82½\82Á\82½\81I", Monnam(mtmp), something);
     }
     return FALSE;
 }
@@ -952,10 +978,16 @@ genericptr_t p2;
     struct monst *mtmp;
     int dam;
 
+    /*
+     * Gas clouds can't be targetted at water locations, but they can
+     * start next to water and spread over it.
+     */
+
     reg = (NhRegion *) p1;
     dam = reg->arg.a_int;
     if (p2 == (genericptr_t) 0) { /* This means *YOU* Bozo! */
-        if (u.uinvulnerable || nonliving(youmonst.data) || Breathless)
+        if (u.uinvulnerable || nonliving(youmonst.data) || Breathless
+            || Underwater)
             return FALSE;
         if (!Blind) {
 /*JP
@@ -965,7 +997,7 @@ genericptr_t p2;
             make_blinded(1L, FALSE);
         }
         if (!Poison_resistance) {
-#if 0 /*JP*/
+#if 0 /*JP:T*/
             pline("%s is burning your %s!", Something,
                   makeplural(body_part(LUNG)));
 #else
@@ -994,6 +1026,11 @@ genericptr_t p2;
            adult green dragon is not affected by gas cloud, baby one is */
         if (!(nonliving(mtmp->data) || is_vampshifter(mtmp))
             && !breathless(mtmp->data)
+            /* not is_swimmer(); assume that non-fish are swimming on
+               the surface and breathing the air above it periodically
+               unless located at water spot on plane of water */
+            && !((mtmp->data->mlet == S_EEL || Is_waterlevel(&u.uz))
+                 && is_pool(mtmp->mx, mtmp->my))
             /* exclude monsters with poison gas breath attack:
                adult green dragon and Chromatic Dragon (and iron golem,
                but nonliving() and breathless() tests also catch that) */
@@ -1013,7 +1050,7 @@ genericptr_t p2;
             if (resists_poison(mtmp))
                 return FALSE;
             mtmp->mhp -= rnd(dam) + 5;
-            if (mtmp->mhp <= 0) {
+            if (DEADMONSTER(mtmp)) {
                 if (heros_fault(reg))
                     killed(mtmp);
                 else
@@ -1021,7 +1058,7 @@ genericptr_t p2;
                     monkilled(mtmp, "gas cloud", AD_DRST);
 */
                     monkilled(mtmp, "\83K\83X\89_", AD_DRST);
-                if (mtmp->mhp <= 0) { /* not lifesaved */
+                if (DEADMONSTER(mtmp)) { /* not lifesaved */
                     return TRUE;
                 }
             }