Wikia

Wikihack

Source:SLASH'EM 0.0.7E7F2/light.c

2,032pages on
this wiki
Talk0

Below is the full text to light.c from the source code of SLASH'EM 0.0.7E7F2. To link to a particular line, write [[SLASH'EM 0.0.7E7F2/light.c#line123]], for example.

The latest source code for vanilla NetHack is at Source code.


The NetHack General Public License applies to screenshots, source code and other content from NetHack.
1.    /*	SCCS Id: @(#)light.c	3.4	1997/04/10	*/
2.    /* Copyright (c) Dean Luick, 1994					*/
3.    /* NetHack may be freely redistributed.  See license for details.	*/
4.    
5.    #include "hack.h"
6.    #include "lev.h"	/* for checking save modes */
7.    
8.    /*
9.     * Mobile light sources.
10.    *
11.    * This implementation minimizes memory at the expense of extra
12.    * recalculations.
13.    *
14.    * Light sources are "things" that have a physical position and range.
15.    * They have a type, which gives us information about them.  Currently
16.    * they are only attached to objects and monsters.  Note well:  the
17.    * polymorphed-player handling assumes that both youmonst.m_id and
18.    * youmonst.mx will always remain 0.
19.    *
20.    * Light sources, like timers, either follow game play (RANGE_GLOBAL) or
21.    * stay on a level (RANGE_LEVEL).  Light sources are unique by their
22.    * (type, id) pair.  For light sources attached to objects, this id
23.    * is a pointer to the object.
24.    *
25.    * The major working function is do_light_sources(). It is called
26.    * when the vision system is recreating its "could see" array.  Here
27.    * we add a flag (TEMP_LIT) to the array for all locations that are lit
28.    * via a light source.  The bad part of this is that we have to
29.    * re-calculate the LOS of each light source every time the vision
30.    * system runs.  Even if the light sources and any topology (vision blocking
31.    * positions) have not changed.  The good part is that no extra memory
32.    * is used, plus we don't have to figure out how far the sources have moved,
33.    * or if the topology has changed.
34.    *
35.    * The structure of the save/restore mechanism is amazingly similar to
36.    * the timer save/restore.  This is because they both have the same
37.    * principals of having pointers into objects that must be recalculated
38.    * across saves and restores.
39.    */
40.   
41.   #ifdef OVL3
42.   
43.   /* flags */
44.   #define LSF_SHOW	0x1		/* display the light source */
45.   #define LSF_NEEDS_FIXUP	0x2		/* need oid fixup */
46.   #define LSF_FLOATING	0x4		/* location not yet determined */
47.   
48.   static light_source *light_base = 0;
49.   
50.   STATIC_DCL void FDECL(write_ls, (int, light_source *));
51.   STATIC_DCL int FDECL(maybe_write_ls, (int, int, BOOLEAN_P));
52.   
53.   /* imported from vision.c, for small circles */
54.   extern char circle_data[];
55.   extern char circle_start[];
56.   
57.   /* WAC in artifact.c,  for obj_sheds_light*/
58.   extern boolean FDECL(obj_special_light, (struct obj *));
59.   
60.   /* Create a new light source.  */
61.   void
62.   new_light_source(x, y, range, type, id)
63.       xchar x, y;
64.       int range, type;
65.       genericptr_t id;
66.   {
67.       light_source *ls;
68.   
69.       if (range > MAX_RADIUS || range < 1) {
70.   	impossible("new_light_source:  illegal range %d", range);
71.   	return;
72.       }
73.   
74.       ls = (light_source *) alloc(sizeof(light_source));
75.   
76.       ls->next = light_base;
77.       ls->x = x;
78.       ls->y = y;
79.       ls->range = range;
80.       ls->type = type;
81.       ls->id = id;
82.       if (ls->type != LS_TEMP && x == 0)
83.   	ls->flags = LSF_FLOATING;
84.       else
85.       ls->flags = 0;
86.       light_base = ls;
87.   
88.       vision_full_recalc = 1;	/* make the source show up */
89.   }
90.   
91.   /*
92.    * Delete a light source. This assumes only one light source is attached
93.    * to an object at a time.
94.    */
95.   void
96.   del_light_source(type, id)
97.       int type;
98.       genericptr_t id;
99.   {
100.      light_source *curr, *prev;
101.      genericptr_t tmp_id;
102.  
103.      /* need to be prepared for dealing a with light source which
104.         has only been partially restored during a level change
105.         (in particular: chameleon vs prot. from shape changers) */
106.      switch (type) {
107.      case LS_OBJECT:	tmp_id = (genericptr_t)(((struct obj *)id)->o_id);
108.  			break;
109.      case LS_MONSTER:	tmp_id = (genericptr_t)(((struct monst *)id)->m_id);
110.  			break;
111.      case LS_TEMP:       tmp_id = id;
112.      			break;
113.      default:		tmp_id = 0;
114.  			break;
115.      }
116.  
117.      for (prev = 0, curr = light_base; curr; prev = curr, curr = curr->next) {
118.  	if (curr->type != type) continue;
119.          if (curr->id == ((curr->flags & LSF_NEEDS_FIXUP) ? tmp_id : id))
120.            {
121.  	    if (prev)
122.  		prev->next = curr->next;
123.  	    else
124.  		light_base = curr->next;
125.  
126.  	    free((genericptr_t)curr);
127.  	    vision_full_recalc = 1;
128.  	    return;
129.  	}
130.      }
131.      impossible("del_light_source: not found type=%d, id=0x%lx", type, (long)id);
132.  }
133.  
134.  /* Mark locations that are temporarily lit via mobile light sources. */
135.  void
136.  do_light_sources(cs_rows)
137.      char **cs_rows;
138.  {
139.      int x, y, min_x, max_x, max_y, offset;
140.      char *limits;
141.      short at_hero_range = 0;
142.      light_source *ls;
143.      char *row;
144.  
145.      for (ls = light_base; ls; ls = ls->next) {
146.  	ls->flags &= ~LSF_SHOW;
147.  
148.  	/*
149.  	 * See if floating light source has been finalized yet.
150.  	 * If not, arrange for vision to be recalculated later.
151.  	 */
152.  	if (ls->flags & LSF_FLOATING) {
153.  	    if (ls->type == LS_OBJECT) {
154.  		if (get_obj_location((struct obj *) ls->id, &ls->x, &ls->y, 
155.  		  CONTAINED_TOO | BURIED_TOO))
156.  		    ls->flags &= ~LSF_FLOATING;
157.  	    } else if (ls->type == LS_MONSTER) {
158.  		if (get_mon_location((struct monst *) ls->id, &ls->x, &ls->y, 
159.  		  CONTAINED_TOO | BURIED_TOO))
160.  		    ls->flags &= ~LSF_FLOATING;
161.  	    }
162.  	    if (ls->flags & LSF_FLOATING) {
163.  		vision_full_recalc = 1;
164.  		continue;
165.  	    }
166.  	}
167.  	/*
168.  	 * Check for moved light sources.  It may be possible to
169.  	 * save some effort if an object has not moved, but not in
170.  	 * the current setup -- we need to recalculate for every
171.  	 * vision recalc.
172.  	 */
173.  	if (ls->type == LS_OBJECT) {
174.  	    if (get_obj_location((struct obj *) ls->id, &ls->x, &ls->y, 0))
175.  		ls->flags |= LSF_SHOW;
176.  	} else if (ls->type == LS_MONSTER) {
177.  	    if (get_mon_location((struct monst *) ls->id, &ls->x, &ls->y, 0))
178.  		ls->flags |= LSF_SHOW;
179.          } else if (ls->type == LS_TEMP) {
180.              ls->flags |= LSF_SHOW;
181.  	}
182.  
183.  	/* minor optimization: don't bother with duplicate light sources */
184.  	/* at hero */
185.  	if (ls->x == u.ux && ls->y == u.uy) {
186.  	    if (at_hero_range >= ls->range)
187.  		ls->flags &= ~LSF_SHOW;
188.  	    else
189.  		at_hero_range = ls->range;
190.  	}
191.  
192.  	if (ls->flags & LSF_SHOW) {
193.  	    /*
194.  	     * Walk the points in the circle and see if they are
195.  	     * visible from the center.  If so, mark'em.
196.  	     *
197.  	     * Kevin's tests indicated that doing this brute-force
198.  	     * method is faster for radius <= 3 (or so).
199.  	     */
200.  	    limits = circle_ptr(ls->range);
201.  	    if ((max_y = (ls->y + ls->range)) >= ROWNO) max_y = ROWNO-1;
202.  	    if ((y = (ls->y - ls->range)) < 0) y = 0;
203.  	    for (; y <= max_y; y++) {
204.  		row = cs_rows[y];
205.  		offset = limits[abs(y - ls->y)];
206.  		if ((min_x = (ls->x - offset)) < 0) min_x = 0;
207.  		if ((max_x = (ls->x + offset)) >= COLNO) max_x = COLNO-1;
208.  
209.  		if (ls->x == u.ux && ls->y == u.uy) {
210.  		    /*
211.  		     * If the light source is located at the hero, then
212.  		     * we can use the COULD_SEE bits already calcualted
213.  		     * by the vision system.  More importantly than
214.  		     * this optimization, is that it allows the vision
215.  		     * system to correct problems with clear_path().
216.  		     * The function clear_path() is a simple LOS
217.  		     * path checker that doesn't go out of its way
218.  		     * make things look "correct".  The vision system
219.  		     * does this.
220.  		     */
221.  		    for (x = min_x; x <= max_x; x++)
222.  			if (row[x] & COULD_SEE)
223.  			    row[x] |= TEMP_LIT;
224.  		} else {
225.  		    for (x = min_x; x <= max_x; x++)
226.  			if ((ls->x == x && ls->y == y)
227.  				|| clear_path((int)ls->x, (int) ls->y, x, y))
228.  			    row[x] |= TEMP_LIT;
229.  		}
230.  	    }
231.  	}
232.      }
233.  }
234.  
235.  /* (mon->mx == 0) implies migrating */
236.  #define mon_is_local(mon)	((mon)->mx > 0)
237.  
238.  struct monst *
239.  find_mid(nid, fmflags)
240.  unsigned nid;
241.  unsigned fmflags;
242.  {
243.  	struct monst *mtmp;
244.  
245.  	if (!nid)
246.  	    return &youmonst;
247.  	if (fmflags & FM_FMON)
248.  		for (mtmp = fmon; mtmp; mtmp = mtmp->nmon)
249.  		    if (!DEADMONSTER(mtmp) && mtmp->m_id == nid) return mtmp;
250.  	if (fmflags & FM_MIGRATE)
251.  		for (mtmp = migrating_mons; mtmp; mtmp = mtmp->nmon)
252.  	    	    if (mtmp->m_id == nid) return mtmp;
253.  	if (fmflags & FM_MYDOGS)
254.  		for (mtmp = mydogs; mtmp; mtmp = mtmp->nmon)
255.  	    	    if (mtmp->m_id == nid) return mtmp;
256.  	return (struct monst *) 0;
257.  }
258.  
259.  /* Save all light sources of the given range. */
260.  void
261.  save_light_sources(fd, mode, range)
262.      int fd, mode, range;
263.  {
264.      int count, actual, is_global;
265.      light_source **prev, *curr;
266.  
267.      if (perform_bwrite(mode)) {
268.  	count = maybe_write_ls(fd, range, FALSE);
269.  	bwrite(fd, (genericptr_t) &count, sizeof count);
270.  	actual = maybe_write_ls(fd, range, TRUE);
271.  	if (actual != count)
272.  	    panic("counted %d light sources, wrote %d! [range=%d]",
273.  		  count, actual, range);
274.      }
275.  
276.      if (release_data(mode)) {
277.  	for (prev = &light_base; (curr = *prev) != 0; ) {
278.  	    if (!curr->id) {
279.  		impossible("save_light_sources: no id! [range=%d]", range);
280.  		is_global = 0;
281.  	    } else
282.  	    switch (curr->type) {
283.  	    case LS_OBJECT:
284.  		is_global = !obj_is_local((struct obj *)curr->id);
285.  		break;
286.  	    case LS_MONSTER:
287.  		is_global = !mon_is_local((struct monst *)curr->id);
288.  		break;
289.  	    case LS_TEMP:
290.  	    	/* Temp light sources should never be saved, but need to 
291.  	    	 * 	set next (or else you get caught in an infinite loop
292.  	    	 */
293.  		prev = &(*prev)->next;
294.  		continue; 
295.  	    default:
296.  		is_global = 0;
297.  		impossible("save_light_sources: bad type (%d) [range=%d]",
298.  			   curr->type, range);
299.  		break;
300.  	    }
301.  	    /* if global and not doing local, or vice versa, remove it */
302.  	    if (is_global ^ (range == RANGE_LEVEL)) {
303.  		*prev = curr->next;
304.  		free((genericptr_t)curr);
305.  	    } else {
306.  		prev = &(*prev)->next;
307.  	    }
308.  	}
309.      }
310.  }
311.  
312.  /*
313.   * Pull in the structures from disk, but don't recalculate the object
314.   * pointers.
315.   */
316.  void
317.  restore_light_sources(fd)
318.      int fd;
319.  {
320.      int count;
321.      light_source *ls;
322.  
323.      /* restore elements */
324.      mread(fd, (genericptr_t) &count, sizeof count);
325.  
326.      while (count-- > 0) {
327.  	ls = (light_source *) alloc(sizeof(light_source));
328.  	mread(fd, (genericptr_t) ls, sizeof(light_source));
329.  	ls->next = light_base;
330.  	light_base = ls;
331.      }
332.  }
333.  
334.  /* Relink all lights that are so marked. */
335.  void
336.  relink_light_sources(ghostly)
337.      boolean ghostly;
338.  {
339.      char which;
340.      unsigned nid;
341.      light_source *ls;
342.  
343.      for (ls = light_base; ls; ls = ls->next) {
344.  	if (ls->flags & LSF_NEEDS_FIXUP) {
345.  	    if (ls->type == LS_OBJECT || ls->type == LS_MONSTER) {
346.  		if (ghostly) {
347.  		    if (!lookup_id_mapping((unsigned)ls->id, &nid))
348.  			impossible("relink_light_sources: no id mapping");
349.  		} else
350.  		    nid = (unsigned) ls->id;
351.  		if (ls->type == LS_OBJECT) {
352.  		    which = 'o';
353.  		    ls->id = (genericptr_t) find_oid(nid);
354.  		} else {
355.  		    which = 'm';
356.  		    ls->id = (genericptr_t) find_mid(nid, FM_EVERYWHERE);
357.  		}
358.  		if (!ls->id)
359.  		    impossible("relink_light_sources: cant find %c_id %d",
360.  			       which, nid);
361.  	    } else
362.  		impossible("relink_light_sources: bad type (%d)", ls->type);
363.  
364.  	    ls->flags &= ~LSF_NEEDS_FIXUP;
365.  	}
366.      }
367.  }
368.  
369.  /*
370.   * Part of the light source save routine.  Count up the number of light
371.   * sources that would be written.  If write_it is true, actually write
372.   * the light source out.
373.   */
374.  STATIC_OVL int
375.  maybe_write_ls(fd, range, write_it)
376.      int fd, range;
377.      boolean write_it;
378.  {
379.      int count = 0, is_global;
380.      light_source *ls;
381.  
382.      for (ls = light_base; ls; ls = ls->next) {
383.  	if (!ls->id) {
384.  	    impossible("maybe_write_ls: no id! [range=%d]", range);
385.  	    continue;
386.  	}
387.  	switch (ls->type) {
388.  	case LS_OBJECT:
389.  	    is_global = !obj_is_local((struct obj *)ls->id);
390.  	    break;
391.  	case LS_MONSTER:
392.  	    is_global = !mon_is_local((struct monst *)ls->id);
393.  	    break;
394.  		case LS_TEMP:
395.  		    continue;
396.  	default:
397.  	    is_global = 0;
398.  	    impossible("maybe_write_ls: bad type (%d) [range=%d]",
399.  		       ls->type, range);
400.  	    break;
401.  	}
402.  	/* if global and not doing local, or vice versa, count it */
403.  	if (is_global ^ (range == RANGE_LEVEL)) {
404.  	    count++;
405.  	    if (write_it) write_ls(fd, ls);
406.  	}
407.      }
408.  
409.      return count;
410.  }
411.  
412.  /* Write a light source structure to disk. */
413.  STATIC_OVL void
414.  write_ls(fd, ls)
415.      int fd;
416.      light_source *ls;
417.  {
418.      genericptr_t arg_save;
419.      struct obj *otmp;
420.      struct monst *mtmp;
421.  
422.      if (ls->type == LS_OBJECT || ls->type == LS_MONSTER) {
423.  	if (ls->flags & LSF_NEEDS_FIXUP)
424.  	    bwrite(fd, (genericptr_t)ls, sizeof(light_source));
425.  	else {
426.  	    /* replace object pointer with id for write, then put back */
427.  	    arg_save = ls->id;
428.  	    if (ls->type == LS_OBJECT) {
429.  		otmp = (struct obj *)ls->id;
430.  		ls->id = (genericptr_t)otmp->o_id;
431.  #ifdef DEBUG
432.  		if (find_oid((unsigned)ls->id) != otmp)
433.  		    panic("write_ls: can't find obj #%u!", (unsigned)ls->id);
434.  #endif
435.  	    } else { /* ls->type == LS_MONSTER */
436.  		mtmp = (struct monst *)ls->id;
437.  		ls->id = (genericptr_t)mtmp->m_id;
438.  #ifdef DEBUG
439.  		if (find_mid((unsigned)ls->id, FM_EVERYWHERE) != mtmp)
440.  		    panic("write_ls: can't find mon #%u!", (unsigned)ls->id);
441.  #endif
442.  	    }
443.  	    ls->flags |= LSF_NEEDS_FIXUP;
444.  	    bwrite(fd, (genericptr_t)ls, sizeof(light_source));
445.  	    ls->id = arg_save;
446.  	    ls->flags &= ~LSF_NEEDS_FIXUP;
447.  	}
448.      } else {
449.  	impossible("write_ls: bad type (%d)", ls->type);
450.      }
451.  }
452.  
453.  /* Change light source's ID from src to dest. */
454.  void
455.  obj_move_light_source(src, dest)
456.      struct obj *src, *dest;
457.  {
458.      light_source *ls;
459.  
460.      for (ls = light_base; ls; ls = ls->next)
461.  	if (ls->type == LS_OBJECT && ls->id == (genericptr_t) src)
462.  	    ls->id = (genericptr_t) dest;
463.      src->lamplit = 0;
464.      dest->lamplit = 1;
465.  }
466.  
467.  /* return true if there exist any light sources */
468.  boolean
469.  any_light_source()
470.  {
471.      return light_base != (light_source *) 0;
472.  }
473.  
474.  /*
475.   * Snuff an object light source if at (x,y).  This currently works
476.   * only for burning light sources.
477.   */
478.  void
479.  snuff_light_source(x, y)
480.      int x, y;
481.  {
482.      light_source *ls;
483.      struct obj *obj;
484.  
485.      for (ls = light_base; ls; ls = ls->next)
486.  	/*
487.  	Is this position check valid??? Can I assume that the positions
488.  	will always be correct because the objects would have been
489.  	updated with the last vision update?  [Is that recent enough???]
490.  	*/
491.  	if (ls->type == LS_OBJECT && ls->x == x && ls->y == y) {
492.  	    obj = (struct obj *) ls->id;
493.  	    if (obj_is_burning(obj)) {
494.  		/* The only way to snuff Sunsword is to unwield it.  Darkness
495.  		 * scrolls won't affect it.  (If we got here because it was
496.  		 * dropped or thrown inside a monster, this won't matter anyway
497.  		 * because it will go out when dropped.)
498.  		 */
499.  		if (artifact_light(obj)) continue;
500.  		end_burn(obj, obj->otyp != MAGIC_LAMP);
501.  		/*
502.  		 * The current ls element has just been removed (and
503.  		 * ls->next is now invalid).  Return assuming that there
504.  		 * is only one light source attached to each object.
505.  		 */
506.  		return;
507.  	    }
508.  	}
509.  }
510.  
511.  /* Return TRUE if object sheds any light at all. */
512.  boolean
513.  obj_sheds_light(obj)
514.      struct obj *obj;
515.  {
516.      /* so far, only burning objects shed light */
517.      /* WAC - Some artifacts now shed light */
518.  
519.      return (obj_is_burning(obj) || obj_permanent_light(obj));
520.  }
521.  
522.  /* Return TRUE if sheds light AND will be snuffed by end_burn(). */
523.  boolean
524.  obj_is_burning(obj)
525.      struct obj *obj;
526.  {
527.      return (obj->lamplit &&
528.   		(  obj->otyp == MAGIC_LAMP 
529.  		|| obj->otyp == MAGIC_CANDLE
530.  		|| ignitable(obj) 
531.  #ifdef LIGHTSABERS
532.  		|| is_lightsaber(obj)
533.  #endif
534.  		|| artifact_light(obj)));
535.  }
536.  
537.  /* WAC Return TRUE if object always lights up
538.   * Currently only artifacts have this property
539.   */
540.  boolean
541.  obj_permanent_light(obj)
542.      struct obj *obj;
543.  {
544.      return ((obj->lamplit) &&
545.          (artifact_light(obj)));
546.  }
547.  
548.  /* copy the light source(s) attachted to src, and attach it/them to dest */
549.  void
550.  obj_split_light_source(src, dest)
551.      struct obj *src, *dest;
552.  {
553.      light_source *ls, *new_ls;
554.  
555.      for (ls = light_base; ls; ls = ls->next)
556.  	if (ls->type == LS_OBJECT && ls->id == (genericptr_t) src) {
557.  	    /*
558.  	     * Insert the new source at beginning of list.  This will
559.  	     * never interfere us walking down the list - we are already
560.  	     * past the insertion point.
561.  	     */
562.  	    new_ls = (light_source *) alloc(sizeof(light_source));
563.  	    *new_ls = *ls;
564.  	    if (Is_candle(src)) {
565.  		/* split candles may emit less light than original group */
566.  		ls->range = candle_light_range(src);
567.  		new_ls->range = candle_light_range(dest);
568.  		vision_full_recalc = 1;	/* in case range changed */
569.  	    }
570.  	    new_ls->id = (genericptr_t) dest;
571.  	    new_ls->next = light_base;
572.  	    light_base = new_ls;
573.  	    dest->lamplit = 1;		/* now an active light source */
574.  	}
575.  }
576.  
577.  /* light source `src' has been folded into light source `dest';
578.     used for merging lit candles and adding candle(s) to lit candelabrum */
579.  void
580.  obj_merge_light_sources(src, dest)
581.  struct obj *src, *dest;
582.  {
583.      light_source *ls;
584.  
585.      /* src == dest implies adding to candelabrum */
586.      if (src != dest) end_burn(src, TRUE);		/* extinguish candles */
587.  
588.      for (ls = light_base; ls; ls = ls->next)
589.  	if (ls->type == LS_OBJECT && ls->id == (genericptr_t) dest) {
590.  	    ls->range = candle_light_range(dest);
591.  	    vision_full_recalc = 1;	/* in case range changed */
592.  	    break;
593.  	}
594.  }
595.  
596.  /* Candlelight is proportional to the number of candles;
597.     minimum range is 2 rather than 1 for playability. */
598.  int
599.  candle_light_range(obj)
600.  struct obj *obj;
601.  {
602.      int radius;
603.  
604.      if (obj->otyp == CANDELABRUM_OF_INVOCATION) {
605.  	/*
606.  	 *	The special candelabrum emits more light than the
607.  	 *	corresponding number of candles would.
608.  	 *	 1..3 candles, range 2 (minimum range);
609.  	 *	 4..6 candles, range 3 (normal lamp range);
610.  	 *	    7 candles, range 4 (bright).
611.  	 */
612.  	radius = (obj->spe < 4) ? 2 : (obj->spe < 7) ? 3 : 4;
613.      } else if (Is_candle(obj)) {
614.  	/*
615.  	 *	Range is incremented by powers of 7 so that it will take
616.  	 *	wizard mode quantities of candles to get more light than
617.  	 *	from a lamp, without imposing an arbitrary limit.
618.  	 *	 1..6   candles, range 2;
619.  	 *	 7..48  candles, range 3;
620.  	 *	49..342 candles, range 4; &c.
621.  	 */
622.  	long n = obj->quan;
623.  
624.  	radius = 1;	/* always incremented at least once */
625.  	do {
626.  	    radius++;
627.  	    n /= 7L;
628.  	} while (n > 0L);
629.      } else {
630.  	/* we're only called for lit candelabrum or candles */
631.       /* impossible("candlelight for %d?", obj->otyp); */
632.  	radius = 3;		/* lamp's value */
633.      }
634.      return radius;
635.  }
636.  
637.  #ifdef WIZARD
638.  extern char *FDECL(fmt_ptr, (const genericptr, char *));  /* from alloc.c */
639.  
640.  int
641.  wiz_light_sources()
642.  {
643.      winid win;
644.      char buf[BUFSZ], arg_address[20];
645.      light_source *ls;
646.  
647.      win = create_nhwindow(NHW_MENU);	/* corner text window */
648.      if (win == WIN_ERR) return 0;
649.  
650.      Sprintf(buf, "Mobile light sources: hero @ (%2d,%2d)", u.ux, u.uy);
651.      putstr(win, 0, buf);
652.      putstr(win, 0, "");
653.  
654.      if (light_base) {
655.  	putstr(win, 0, "location range flags  type    id");
656.  	putstr(win, 0, "-------- ----- ------ ----  -------");
657.  	for (ls = light_base; ls; ls = ls->next) {
658.  	    Sprintf(buf, "  %2d,%2d   %2d   0x%04x  %s  %s",
659.  		ls->x, ls->y, ls->range, ls->flags,
660.  		(ls->type == LS_OBJECT ? "obj" :
661.  		 ls->type == LS_MONSTER ?
662.  		    (mon_is_local((struct monst *)ls->id) ? "mon" :
663.  		     ((struct monst *)ls->id == &youmonst) ? "you" :
664.  		     "<m>") :		/* migrating monster */
665.  		 "???"),
666.  		fmt_ptr(ls->id, arg_address));
667.  	    putstr(win, 0, buf);
668.  	}
669.      } else
670.  	putstr(win, 0, "<none>");
671.  
672.  
673.      display_nhwindow(win, FALSE);
674.      destroy_nhwindow(win);
675.  
676.      return 0;
677.  }
678.  
679.  #endif /* WIZARD */
680.  
681.  #endif /* OVL3 */
682.  
683.  /*light.c*/

Around Wikia's network

Random Wiki