/* Check whether the location has an outdated object displayed on it. */ static boolean check_map_spot(int x, int y, char oclass, unsigned material) { int memobj; struct obj *otmp; struct monst *mtmp; memobj = level->locations[x][y].mem_obj; if (memobj) { /* there's some object shown here */ if (oclass == ALL_CLASSES) { return (!(level->objects[x][y] || /* stale if nothing here */ ((mtmp = m_at(level, x, y)) != 0 && mtmp->minvent))); } else { if (material && objects[memobj - 1].oc_material == material) { /* the object shown here is of interest because material matches */ for (otmp = level->objects[x][y]; otmp; otmp = otmp->nexthere) if (o_material(otmp, GOLD)) return FALSE; /* didn't find it; perhaps a monster is carrying it */ if ((mtmp = m_at(level, x, y)) != 0) { for (otmp = mtmp->minvent; otmp; otmp = otmp->nobj) if (o_material(otmp, GOLD)) return FALSE; } /* detection indicates removal of this object from the map */ return TRUE; } if (oclass && objects[memobj - 1].oc_class == oclass) { /* the object shown here is of interest because its class matches */ for (otmp = level->objects[x][y]; otmp; otmp = otmp->nexthere) if (o_in(otmp, oclass)) return FALSE; /* didn't find it; perhaps a monster is carrying it */ if ((mtmp = m_at(level, x, y)) != 0) { for (otmp = mtmp->minvent; otmp; otmp = otmp->nobj) if (o_in(otmp, oclass)) return FALSE; } /* detection indicates removal of this object from the map */ return TRUE; } } } return FALSE; }
/* Recursively search obj for an object in class oclass and return 1st found */ static struct obj *o_in(struct obj *obj, char oclass) { struct obj *otmp; struct obj *temp; if (obj->oclass == oclass) return obj; if (Has_contents(obj)) { for (otmp = obj->cobj; otmp; otmp = otmp->nobj) if (otmp->oclass == oclass) return otmp; else if (Has_contents(otmp) && (temp = o_in(otmp, oclass))) return temp; } return NULL; }
/* returns 0 if something was detected */ int food_detect(struct obj *sobj, boolean *scr_known) { struct obj *obj; struct monst *mtmp; int ct = 0, ctu = 0; boolean confused = (Confusion || (sobj && sobj->cursed)), stale; char oclass = confused ? POTION_CLASS : FOOD_CLASS; const char *what = confused ? "something" : "food"; int uw = u.uinwater; stale = clear_stale_map(oclass, 0); for (obj = level->objlist; obj; obj = obj->nobj) if (o_in(obj, oclass)) { if (obj->ox == u.ux && obj->oy == u.uy) ctu++; else ct++; } for (mtmp = level->monlist; mtmp && !ct; mtmp = mtmp->nmon) { /* no DEADMONSTER(mtmp) check needed since dmons never have inventory */ for (obj = mtmp->minvent; obj; obj = obj->nobj) if (o_in(obj, oclass)) { ct++; break; } } if (!ct && !ctu) { *scr_known = stale && !confused; if (stale) { doredraw(); pline("You sense a lack of %s nearby.", what); if (sobj && sobj->blessed) { if (!u.uedibility) pline("Your %s starts to tingle.", body_part(NOSE)); u.uedibility = 1; } } else if (sobj) { char buf[BUFSZ]; sprintf(buf, "Your %s twitches%s.", body_part(NOSE), (sobj->blessed && !u.uedibility) ? " then starts to tingle" : ""); if (sobj->blessed && !u.uedibility) { boolean savebeginner = flags.beginner; /* prevent non-delivery of */ flags.beginner = FALSE; /* message */ strange_feeling(sobj, buf); flags.beginner = savebeginner; u.uedibility = 1; } else strange_feeling(sobj, buf); } return !stale; } else if (!ct) { *scr_known = TRUE; pline("You %s %s nearby.", sobj ? "smell" : "sense", what); if (sobj && sobj->blessed) { if (!u.uedibility) pline("Your %s starts to tingle.", body_part(NOSE)); u.uedibility = 1; } } else { struct obj *temp; *scr_known = TRUE; cls(); u.uinwater = 0; for (obj = level->objlist; obj; obj = obj->nobj) if ((temp = o_in(obj, oclass)) != 0) { if (temp != obj) { temp->ox = obj->ox; temp->oy = obj->oy; } map_object(temp,1); } for (mtmp = level->monlist; mtmp; mtmp = mtmp->nmon) /* no DEADMONSTER(mtmp) check needed since dmons never have inventory */ for (obj = mtmp->minvent; obj; obj = obj->nobj) if ((temp = o_in(obj, oclass)) != 0) { temp->ox = mtmp->mx; temp->oy = mtmp->my; map_object(temp,1); break; /* skip rest of this monster's inventory */ } newsym(u.ux,u.uy); if (sobj) { if (sobj->blessed) { pline("Your %s %s to tingle and you smell %s.", body_part(NOSE), u.uedibility ? "continues" : "starts", what); u.uedibility = 1; } else pline("Your %s tingles and you smell %s.", body_part(NOSE), what); } else pline("You sense %s.", what); win_pause_output(P_MAP); exercise(A_WIS, TRUE); doredraw(); u.uinwater = uw; if (Underwater) under_water(2); if (u.uburied) under_ground(2); } return 0; }
/* look for gold, on the floor or in monsters' possession */ int gold_detect(struct obj *sobj, boolean *scr_known) { struct obj *obj; struct monst *mtmp; int uw = u.uinwater; struct obj *temp; boolean stale; *scr_known = stale = clear_stale_map(COIN_CLASS, sobj->blessed ? GOLD : 0); /* look for gold carried by monsters (might be in a container) */ for (mtmp = level->monlist; mtmp; mtmp = mtmp->nmon) { if (DEADMONSTER(mtmp)) continue; /* probably not needed in this case but... */ if (findgold(mtmp->minvent) || monsndx(mtmp->data) == PM_GOLD_GOLEM) { *scr_known = TRUE; goto outgoldmap; /* skip further searching */ } else for (obj = mtmp->minvent; obj; obj = obj->nobj) if (sobj->blessed && o_material(obj, GOLD)) { *scr_known = TRUE; goto outgoldmap; } else if (o_in(obj, COIN_CLASS)) { *scr_known = TRUE; goto outgoldmap; /* skip further searching */ } } /* look for gold objects */ for (obj = level->objlist; obj; obj = obj->nobj) { if (sobj->blessed && o_material(obj, GOLD)) { *scr_known = TRUE; if (obj->ox != u.ux || obj->oy != u.uy) goto outgoldmap; } else if (o_in(obj, COIN_CLASS)) { *scr_known = TRUE; if (obj->ox != u.ux || obj->oy != u.uy) goto outgoldmap; } } if (!*scr_known) { /* no gold found on floor or monster's inventory. adjust message if you have gold in your inventory */ char buf[BUFSZ]; if (youmonst.data == &mons[PM_GOLD_GOLEM]) { sprintf(buf, "You feel like a million %s!", currency(2L)); } else if (hidden_gold() || money_cnt(invent)) strcpy(buf, "You feel worried about your future financial situation."); else strcpy(buf, "You feel materially poor."); strange_feeling(sobj, buf); return 1; } /* only under me - no separate display required */ if (stale) doredraw(); pline("You notice some gold between your %s.", makeplural(body_part(FOOT))); return 0; outgoldmap: cls(); u.uinwater = 0; /* Discover gold locations. */ for (obj = level->objlist; obj; obj = obj->nobj) { if (sobj->blessed && (temp = o_material(obj, GOLD))) { if (temp != obj) { temp->ox = obj->ox; temp->oy = obj->oy; } map_object(temp,1); } else if ((temp = o_in(obj, COIN_CLASS))) { if (temp != obj) { temp->ox = obj->ox; temp->oy = obj->oy; } map_object(temp,1); } } for (mtmp = level->monlist; mtmp; mtmp = mtmp->nmon) { if (DEADMONSTER(mtmp)) continue; /* probably overkill here */ if (findgold(mtmp->minvent) || monsndx(mtmp->data) == PM_GOLD_GOLEM) { struct obj gold; gold.otyp = GOLD_PIECE; gold.ox = mtmp->mx; gold.oy = mtmp->my; map_object(&gold,1); } else for (obj = mtmp->minvent; obj; obj = obj->nobj) if (sobj->blessed && (temp = o_material(obj, GOLD))) { temp->ox = mtmp->mx; temp->oy = mtmp->my; map_object(temp,1); break; } else if ((temp = o_in(obj, COIN_CLASS))) { temp->ox = mtmp->mx; temp->oy = mtmp->my; map_object(temp,1); break; } } newsym(u.ux,u.uy); pline("You feel very greedy, and sense gold!"); exercise(A_WIS, TRUE); win_pause_output(P_MAP); doredraw(); u.uinwater = uw; if (Underwater) under_water(2); if (u.uburied) under_ground(2); return 0; }