Give the name of an object seen at a distance. Unlike xname/doname, we usually don't want to set dknown if it's not set already. */
| 344 | /* Give the name of an object seen at a distance. Unlike xname/doname, |
| 345 | we usually don't want to set dknown if it's not set already. */ |
| 346 | char * |
| 347 | distant_name( |
| 348 | struct obj *obj, /* object to be formatted */ |
| 349 | char *(*func)(OBJ_P)) /* formatting routine (usually xname or doname) */ |
| 350 | { |
| 351 | char *str; |
| 352 | unsigned save_oid; |
| 353 | coordxy ox = 0, oy = 0; |
| 354 | /* |
| 355 | * (r * r): square of the x or y distance; |
| 356 | * (r * r) * 2: sum of squares of both x and y distances |
| 357 | * (r * r) * 2 - r: instead of a square extending from the hero, |
| 358 | * round the corners (so shorter distance imposed for diagonal). |
| 359 | * |
| 360 | * distu() matrix covering a range of 3+ for one quadrant: |
| 361 | * 16 17 - - - |
| 362 | * 9 10 13 18 - |
| 363 | * 4 5 8 13 - |
| 364 | * 1 2 5 10 17 |
| 365 | * @ 1 4 9 16 |
| 366 | * Theoretical r==1 would yield 1. |
| 367 | * r==2 yields 6, functionally equivalent to 5, a knight's jump, |
| 368 | * r==3, the xray range of the Eyes of the Overworld, yields 15. |
| 369 | */ |
| 370 | int r = (u.xray_range > 2) ? u.xray_range : 2, |
| 371 | neardist = (r * r) * 2 - r; /* same as r*r + r*(r-1) */ |
| 372 | |
| 373 | /* setting o_id to 0 prevents xname() from adding T-shirt or apron |
| 374 | slogan, Hawaiian shirt motif, or candy wrapper label when called |
| 375 | with 'program_state.gameover' set; we want this suppression for |
| 376 | html-dump (not implemented in nethack) to prevent object-on-map |
| 377 | tooltips from including that extra text; also guards against a |
| 378 | potential change to minimal_xname() [indirectly used by attribute |
| 379 | disclosure] that propagates o_id rather than leave it 0, and |
| 380 | against a potential extra chance to browse the map with getpos() |
| 381 | during final disclosure (not currently implemented, nor planned) */ |
| 382 | save_oid = obj->o_id; |
| 383 | if (program_state.gameover) |
| 384 | obj->o_id = 0; |
| 385 | |
| 386 | /* this maybe-nearby part used to be replicated in multiple callers */ |
| 387 | if (get_obj_location(obj, &ox, &oy, 0) && cansee(ox, oy) |
| 388 | && (obj->oartifact || distu(ox, oy) <= neardist)) { |
| 389 | /* side-effects: treat as having been seen up close; |
| 390 | cansee() is True hence hero isn't Blind so if 'func' is |
| 391 | the usual doname or xname, obj->dknown will become set |
| 392 | and then for an artifact, find_artifact() will be called */ |
| 393 | str = (*func)(obj); |
| 394 | } else { |
| 395 | /* prior to 3.6.1, this used to save current blindness state, |
| 396 | explicitly set state to hero-is-blind, make the call (which |
| 397 | won't set obj->dknown when blind), then restore the saved |
| 398 | value; but the Eyes of the Overworld override blindness and |
| 399 | would let characters wearing them get obj->dknown set for |
| 400 | distant items, so the external flag was added */ |
| 401 | ++gd.distantname; |
| 402 | str = (*func)(obj); |
| 403 | --gd.distantname; |
no test coverage detected