OSDN Git Service

update year to 2022
[jnethack/source.git] / src / light.c
index 33aad10..6a48327 100644 (file)
@@ -1,9 +1,9 @@
-/* NetHack 3.6 light.c $NHDT-Date: 1446191876 2015/10/30 07:57:56 $  $NHDT-Branch: master $:$NHDT-Revision: 1.28 $ */
+/* NetHack 3.6 light.c $NHDT-Date: 1559994625 2019/06/08 11:50:25 $  $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.30 $ */
 /* Copyright (c) Dean Luick, 1994                                       */
 /* NetHack may be freely redistributed.  See license for details.       */
 
 /* JNetHack Copyright */
-/* For 3.6-, Copyright (c) SHIRAKATA Kentaro, 2002-2016            */
+/* For 3.6-, Copyright (c) SHIRAKATA Kentaro, 2002-2022            */
 /* JNetHack may be freely redistributed.  See license for details. */
 
 #include "hack.h"
@@ -69,7 +69,7 @@ anything *id;
         return;
     }
 
-    ls = (light_source *) alloc(sizeof(light_source));
+    ls = (light_source *) alloc(sizeof *ls);
 
     ls->next = light_base;
     ls->x = x;
@@ -158,8 +158,8 @@ char **cs_rows;
                 ls->flags |= LSF_SHOW;
         }
 
-        /* minor optimization: don't bother with duplicate light sources */
-        /* at hero */
+        /* minor optimization: don't bother with duplicate light sources
+           at hero */
         if (ls->x == u.ux && ls->y == u.uy) {
             if (at_hero_range >= ls->range)
                 ls->flags &= ~LSF_SHOW;
@@ -196,7 +196,7 @@ char **cs_rows;
                      * this optimization, is that it allows the vision
                      * system to correct problems with clear_path().
                      * The function clear_path() is a simple LOS
-                     * path checker that doesn't go out of its way
+                     * path checker that doesn't go out of its way to
                      * make things look "correct".  The vision system
                      * does this.
                      */
@@ -214,6 +214,80 @@ char **cs_rows;
     }
 }
 
+/* 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
+   remember terrain, objects, and monsters being revealed */
+void
+show_transient_light(obj, x, y)
+struct obj *obj;
+int x, y;
+{
+    light_source *ls;
+    struct monst *mon;
+    int radius_squared;
+
+    /* caller has verified obj->lamplit and that hero is not Blind;
+       validate light source and obtain its radius (for monster sightings) */
+    for (ls = 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) {
+        impossible("transient light %s %s is not %s?",
+                   obj->lamplit ? "lit" : "unlit", xname(obj),
+                   !ls ? "a light source" : "free");
+    } else {
+        /* "expensive" but rare */
+        place_object(obj, bhitpos.x, 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;
+        for (mon = fmon; mon; mon = mon->nmon) {
+            if (DEADMONSTER(mon))
+                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
+                && canseemon(mon))
+                mon->mtemplit = 1;
+            /* [what about worm tails?] */
+        }
+    }
+}
+
+/* draw "remembered, unseen monster" glyph at locations where a monster
+   was flagged for being visible during transient light movement but can't
+   be seen now */
+void
+transient_light_cleanup()
+{
+    struct monst *mon;
+    int mtempcount = 0;
+
+    for (mon = fmon; mon; mon = mon->nmon) {
+        if (DEADMONSTER(mon))
+            continue;
+        if (mon->mtemplit) {
+            mon->mtemplit = 0;
+            ++mtempcount;
+            if (!canseemon(mon))
+                map_invisible(mon->mx, mon->my);
+        }
+    }
+    if (mtempcount) {
+        vision_recalc(0);
+        flush_screen(0);
+    }
+}
+
 /* (mon->mx == 0) implies migrating */
 #define mon_is_local(mon) ((mon)->mx > 0)
 
@@ -310,6 +384,23 @@ int fd;
     }
 }
 
+/* to support '#stats' wizard-mode command */
+void
+light_stats(hdrfmt, hdrbuf, count, size)
+const char *hdrfmt;
+char *hdrbuf;
+long *count, *size;
+{
+    light_source *ls;
+
+    Sprintf(hdrbuf, hdrfmt, (long) sizeof (light_source));
+    *count = *size = 0L;
+    for (ls = light_base; ls; ls = ls->next) {
+        ++*count;
+        *size += (long) sizeof *ls;
+    }
+}
+
 /* Relink all lights that are so marked. */
 void
 relink_light_sources(ghostly)
@@ -670,19 +761,19 @@ struct obj *obj;
 {
     switch (arti_light_radius(obj)) {
     case 3:
-#if 0 /*JP*/
+#if 0 /*JP:T*/
         return "brilliantly"; /* blessed */
 #else
         return "\83L\83\89\83L\83\89\82Æ"; /* blessed */
 #endif
     case 2:
-#if 0 /*JP*/
+#if 0 /*JP:T*/
         return "brightly"; /* uncursed */
 #else
         return "\96¾\82é\82­"; /* uncursed */
 #endif
     case 1:
-#if 0 /*JP*/
+#if 0 /*JP:T*/
         return "dimly"; /* cursed */
 #else
         return "\94\96\88Ã\82­"; /* cursed */