MCPcopy Create free account
hub / github.com/NetHack/NetHack / show_transient_light

Function show_transient_light

src/light.c:256–324  ·  view source on GitHub ↗

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; if 'obj' is Null, is being hit by a camera's light flash */

Source from the content-addressed store, hash-verified

254 remember terrain, objects, and monsters being revealed;
255 if 'obj' is Null, <x,y> is being hit by a camera's light flash */
256void
257show_transient_light(struct obj *obj, coordxy x, coordxy y)
258{
259 light_source *ls = 0;
260 anything cameraflash;
261 struct monst *mon;
262 int radius_squared;
263
264 /* Null object indicates camera flash */
265 if (!obj) {
266 /* no need to temporarily light an already lit spot */
267 if (levl[x][y].lit)
268 return;
269
270 cameraflash = cg.zeroany;
271 /* radius 0 will just light <x,y>; cameraflash.a_obj is Null */
272 ls = new_light_core(x, y, 0, LS_OBJECT, &cameraflash);
273 /* pacify static analysis; 'ls' is never Null for
274 new_light_core(,,0,LS_OBJECT,&zeroany) */
275 assert(ls != NULL);
276 } else {
277 /* thrown or kicked object which is emitting light; validate its
278 light source to obtain its radius (for monster sightings) */
279 for (ls = gl.light_base; ls; ls = ls->next) {
280 if (ls->type != LS_OBJECT)
281 continue;
282 if (ls->id.a_obj == obj)
283 break;
284 }
285 assert(obj != NULL); /* necessary condition to get into this 'else' */
286 if (!ls || obj->where != OBJ_FREE) {
287 impossible("transient light %s %s %s not %s?",
288 obj->lamplit ? "lit" : "unlit",
289 simpleonames(obj), otense(obj, "are"),
290 !ls ? "a light source" : "free");
291 return;
292 }
293 }
294
295 if (obj) /* put lit candle or lamp temporarily on the map */
296 place_object(obj, gb.bhitpos.x, gb.bhitpos.y);
297 else /* camera flash: no object; directly set light source's location */
298 ls->x = x, ls->y = y;
299
300 /* full recalc; runs do_light_sources() */
301 vision_recalc(0);
302 flush_screen(0);
303
304 radius_squared = ls->range * ls->range;
305 for (mon = fmon; mon; mon = mon->nmon) {
306 if (DEADMONSTER(mon) || (mon->isgd && !mon->mx))
307 continue;
308 /* light range is the radius of a circle and we're limiting
309 canseemon() to a square enclosing that circle, but setting
310 mtemplit 'erroneously' for a seen monster is not a problem;
311 it just flags monsters for another canseemon() check when
312 'obj' has reached its destination after missile traversal */
313 if (dist2(mon->mx, mon->my, x, y) <= radius_squared) {

Callers 2

msummonFunction · 0.85
bhitFunction · 0.85

Calls 10

new_light_coreFunction · 0.85
simpleonamesFunction · 0.85
otenseFunction · 0.85
place_objectFunction · 0.85
vision_recalcFunction · 0.85
flush_screenFunction · 0.85
dist2Function · 0.85
canseemonFunction · 0.85
remove_objectFunction · 0.85
impossibleFunction · 0.70

Tested by

no test coverage detected