extracted from lookat(); also used by namefloorobj() */
| 281 | |
| 282 | /* extracted from lookat(); also used by namefloorobj() */ |
| 283 | boolean |
| 284 | object_from_map( |
| 285 | int glyph, |
| 286 | coordxy x, coordxy y, |
| 287 | struct obj **obj_p) |
| 288 | { |
| 289 | boolean fakeobj = FALSE, mimic_obj = FALSE; |
| 290 | struct monst *mtmp; |
| 291 | struct obj *otmp; |
| 292 | int glyphotyp = glyph_is_object(glyph) ? glyph_to_obj(glyph) |
| 293 | /* if not an object, probably a detected chest trap */ |
| 294 | : glyph_is_cmap(glyph) /* assume trapped chest|door */ |
| 295 | ? (sobj_at(CHEST, x, y) ? CHEST : LARGE_BOX) |
| 296 | : STRANGE_OBJECT; |
| 297 | |
| 298 | *obj_p = (struct obj *) 0; |
| 299 | /* TODO: check inside containers in case glyph came from detection */ |
| 300 | if ((otmp = sobj_at(glyphotyp, x, y)) == 0) |
| 301 | for (otmp = svl.level.buriedobjlist; otmp; otmp = otmp->nobj) |
| 302 | if (otmp->ox == x && otmp->oy == y && otmp->otyp == glyphotyp) |
| 303 | break; |
| 304 | |
| 305 | /* there might be a mimic here posing as an object */ |
| 306 | mtmp = m_at(x, y); |
| 307 | if (mtmp && is_obj_mappear(mtmp, (unsigned) glyphotyp)) { |
| 308 | otmp = 0; |
| 309 | mimic_obj = TRUE; |
| 310 | } else |
| 311 | mtmp = 0; |
| 312 | |
| 313 | if (!otmp || otmp->otyp != glyphotyp) { |
| 314 | /* this used to exclude STRANGE_OBJECT; now caller deals with it */ |
| 315 | if (OBJ_NAME(objects[glyphotyp])) { |
| 316 | /* map shows a regular object, but one that's not actually here */ |
| 317 | otmp = mksobj(glyphotyp, FALSE, FALSE); |
| 318 | } else { |
| 319 | /* map shows a non-item that holds an extra object type (shown |
| 320 | on map due to hallucination) for a name which might have been |
| 321 | shuffled into play but wasn't (or was shuffled out of play); |
| 322 | pick another item that is a regular one in same object class */ |
| 323 | otmp = mkobj(objects[glyphotyp].oc_class, FALSE); |
| 324 | /* mkobj() doesn't provide any no-init option; however, there |
| 325 | aren't any extra tool items (or statues) so we won't get here |
| 326 | for tools and don't need to check for and delete container |
| 327 | contents or extinguish lights on the temporary object */ |
| 328 | } |
| 329 | /* even though we pass False for mksobj()'s 'init' arg, corpse-rot, |
| 330 | egg-hatch, and figurine-transform timers get initialized */ |
| 331 | if (otmp->timed) |
| 332 | obj_stop_timers(otmp); |
| 333 | fakeobj = TRUE; |
| 334 | if (otmp->oclass == COIN_CLASS) |
| 335 | otmp->quan = 2L; /* to force pluralization */ |
| 336 | else if (otmp->otyp == SLIME_MOLD) |
| 337 | otmp->spe = svc.context.current_fruit; /* give it a type */ |
| 338 | if (mtmp && has_mcorpsenm(mtmp)) { /* mimic as corpse/statue */ |
| 339 | if (otmp->otyp == SLIME_MOLD) |
| 340 | /* override svc.context.current_fruit to avoid |
no test coverage detected