void ghack_map_print_glyph(GtkObject *win, guint x, guint y, GdkImlibImage *im, gpointer data) { GnomeCanvasGroup *group; int i = y * COLNO + x; int glyph = glyph_at(x, y); GnomeCanvasImage *canvas_image = GNOME_CANVAS_IMAGE(ghack_map.map[i]); group = gnome_canvas_root(GNOME_CANVAS(ghack_map.canvas)); gnome_canvas_item_set(GNOME_CANVAS_ITEM(canvas_image), "image", im, NULL); gnome_canvas_item_show(GNOME_CANVAS_ITEM(canvas_image)); canvas_image = GNOME_CANVAS_IMAGE(ghack_map.overlay[i]); if (x == u.ux && y == u.uy) ghack_map_cliparound(NULL, x, y, NULL); if (glyph_is_pet(glyph) #ifdef TEXTCOLOR && iflags.hilite_pet #endif ) { gnome_canvas_item_raise_to_top(GNOME_CANVAS_ITEM(canvas_image)); gnome_canvas_item_show(GNOME_CANVAS_ITEM(canvas_image)); } else { gnome_canvas_item_hide(GNOME_CANVAS_ITEM(canvas_image)); } }
/* quick: use cursor && don't search for "more info" */ static int do_look (bool quick) { char out_str[BUFSZ], look_buf[BUFSZ]; const char *x_str, *firstmatch = 0; struct permonst *pm = 0; int i, ans = 0; int sym; /* typed symbol or converted glyph */ int found; /* count of matching syms found */ coord cc; /* screen pos of unknown glyph */ bool save_verbose; /* saved value of flags.verbose */ bool from_screen; /* question from the screen */ bool need_to_look; /* need to get explan. from glyph */ bool hit_trap; /* true if found trap explanation */ int skipped_venom; /* non-zero if we ignored "splash of venom" */ static const char *mon_interior = "the interior of a monster"; if (quick) { from_screen = true; /* yes, we want to use the cursor */ } else { i = ynq("Specify unknown object by cursor?"); if (i == 'q') return 0; from_screen = (i == 'y'); } if (from_screen) { cc.x = u.ux; cc.y = u.uy; sym = 0; /* gcc -Wall lint */ } else { getlin("Specify what? (type the word)", out_str); if (out_str[0] == '\0' || out_str[0] == '\033') return 0; if (out_str[1]) { /* user typed in a complete string */ checkfile(out_str, pm, true, true); return 0; } sym = out_str[0]; } /* Save the verbose flag, we change it later. */ save_verbose = flags.verbose; flags.verbose = flags.verbose && !quick; /* * The user typed one letter, or we're identifying from the screen. */ do { /* Reset some variables. */ need_to_look = false; pm = (struct permonst *)0; skipped_venom = 0; found = 0; out_str[0] = '\0'; if (from_screen) { int glyph; /* glyph at selected position */ if (flags.verbose) pline("Please move the cursor to %s.", what_is_an_unknown_object); else pline("Pick an object."); ans = getpos(&cc, quick, what_is_an_unknown_object); if (ans < 0 || cc.x < 0) { flags.verbose = save_verbose; return 0; /* done */ } flags.verbose = false; /* only print long question once */ /* Convert the glyph at the selected position to a symbol. */ glyph = glyph_at(cc.x,cc.y); if (glyph_is_cmap(glyph)) { sym = showsyms[glyph_to_cmap(glyph)]; } else if (glyph_is_trap(glyph)) { sym = showsyms[trap_to_defsym(glyph_to_trap(glyph))]; } else if (glyph_is_object(glyph)) { sym = oc_syms[(int)objects[glyph_to_obj(glyph)].oc_class]; if (sym == '`' && iflags.bouldersym && (int)glyph_to_obj(glyph) == BOULDER) sym = iflags.bouldersym; } else if (glyph_is_monster(glyph)) { /* takes care of pets, detected, ridden, and regular mons */ sym = monsyms[(int)mons[glyph_to_mon(glyph)].mlet]; } else if (glyph_is_swallow(glyph)) { sym = showsyms[glyph_to_swallow(glyph)+S_sw_tl]; } else if (glyph_is_invisible(glyph)) { sym = DEF_INVISIBLE; } else if (glyph_is_warning(glyph)) { sym = glyph_to_warning(glyph); sym = warnsyms[sym]; } else { impossible("do_look: bad glyph %d at (%d,%d)", glyph, (int)cc.x, (int)cc.y); sym = ' '; } } /* * Check all the possibilities, saving all explanations in a buffer. * When all have been checked then the string is printed. */ /* Check for monsters */ for (i = 0; i < MAXMCLASSES; i++) { if (sym == (from_screen ? monsyms[i] : def_monsyms[i]) && monexplain[i]) { need_to_look = true; if (!found) { sprintf(out_str, "%c %s", sym, an(monexplain[i])); firstmatch = monexplain[i]; found++; } else { found += append_str(out_str, an(monexplain[i])); } } } /* handle '@' as a special case if it refers to you and you're playing a character which isn't normally displayed by that symbol; firstmatch is assumed to already be set for '@' */ if ((from_screen ? (sym == monsyms[S_HUMAN] && cc.x == u.ux && cc.y == u.uy) : (sym == def_monsyms[S_HUMAN] && !iflags.showrace)) && !(Race_if(PM_HUMAN) || Race_if(PM_ELF)) && !Upolyd) found += append_str(out_str, "you"); /* tack on "or you" */ /* * Special case: if identifying from the screen, and we're swallowed, * and looking at something other than our own symbol, then just say * "the interior of a monster". */ if (u.uswallow && from_screen && is_swallow_sym(sym)) { if (!found) { sprintf(out_str, "%c %s", sym, mon_interior); firstmatch = mon_interior; } else { found += append_str(out_str, mon_interior); } need_to_look = true; } /* Now check for objects */ for (i = 1; i < MAXOCLASSES; i++) { if (sym == (from_screen ? oc_syms[i] : def_oc_syms[i])) { need_to_look = true; if (from_screen && i == VENOM_CLASS) { skipped_venom++; continue; } if (!found) { sprintf(out_str, "%c %s", sym, an(objexplain[i])); firstmatch = objexplain[i]; found++; } else { found += append_str(out_str, an(objexplain[i])); } } } if (sym == DEF_INVISIBLE) { if (!found) { sprintf(out_str, "%c %s", sym, an(invisexplain)); firstmatch = invisexplain; found++; } else { found += append_str(out_str, an(invisexplain)); } } #define is_cmap_trap(i) ((i) >= S_arrow_trap && (i) <= S_polymorph_trap) #define is_cmap_drawbridge(i) ((i) >= S_vodbridge && (i) <= S_hcdbridge) /* Now check for graphics symbols */ for (hit_trap = false, i = 0; i < MAXPCHARS; i++) { x_str = defsyms[i].explanation; if (sym == (from_screen ? showsyms[i] : defsyms[i].sym) && *x_str) { /* avoid "an air", "a water", or "a floor of a room" */ int article = (i == S_room) ? 2 : /* 2=>"the" */ !(strcmp(x_str, "air") == 0 || /* 1=>"an" */ strcmp(x_str, "water") == 0); /* 0=>(none)*/ if (!found) { if (is_cmap_trap(i)) { sprintf(out_str, "%c a trap", sym); hit_trap = true; } else { sprintf(out_str, "%c %s", sym, article == 2 ? the(x_str) : article == 1 ? an(x_str) : x_str); } firstmatch = x_str; found++; } else if (!u.uswallow && !(hit_trap && is_cmap_trap(i)) && !(found >= 3 && is_cmap_drawbridge(i))) { found += append_str(out_str, article == 2 ? the(x_str) : article == 1 ? an(x_str) : x_str); if (is_cmap_trap(i)) hit_trap = true; } if (i == S_altar || is_cmap_trap(i)) need_to_look = true; } } /* Now check for warning symbols */ for (i = 1; i < WARNCOUNT; i++) { x_str = def_warnsyms[i].explanation; if (sym == (from_screen ? warnsyms[i] : def_warnsyms[i].sym)) { if (!found) { sprintf(out_str, "%c %s", sym, def_warnsyms[i].explanation); firstmatch = def_warnsyms[i].explanation; found++; } else { found += append_str(out_str, def_warnsyms[i].explanation); } /* Kludge: warning trumps boulders on the display. Reveal the boulder too or player can get confused */ if (from_screen && sobj_at(BOULDER, cc.x, cc.y)) strcat(out_str, " co-located with a boulder"); break; /* out of for loop*/ } } /* if we ignored venom and list turned out to be short, put it back */ if (skipped_venom && found < 2) { x_str = objexplain[VENOM_CLASS]; if (!found) { sprintf(out_str, "%c %s", sym, an(x_str)); firstmatch = x_str; found++; } else { found += append_str(out_str, an(x_str)); } } /* handle optional boulder symbol as a special case */ if (iflags.bouldersym && sym == iflags.bouldersym) { if (!found) { firstmatch = "boulder"; sprintf(out_str, "%c %s", sym, an(firstmatch)); found++; } else { found += append_str(out_str, "boulder"); } } /* * If we are looking at the screen, follow multiple possibilities or * an ambiguous explanation by something more detailed. */ if (from_screen) { if (found > 1 || need_to_look) { char monbuf[BUFSZ]; char temp_buf[BUFSZ]; pm = lookat(cc.x, cc.y, look_buf, monbuf); firstmatch = look_buf; if (*firstmatch) { sprintf(temp_buf, " (%s)", firstmatch); (void)strncat(out_str, temp_buf, BUFSZ-strlen(out_str)-1); found = 1; /* we have something to look up */ } if (monbuf[0]) { sprintf(temp_buf, " [seen: %s]", monbuf); (void)strncat(out_str, temp_buf, BUFSZ-strlen(out_str)-1); } } } /* Finally, print out our explanation. */ if (found) { pline("%s", out_str); /* check the data file for information about this thing */ if (found == 1 && ans != LOOK_QUICK && ans != LOOK_ONCE && (ans == LOOK_VERBOSE || (flags.help && !quick))) { char temp_buf[BUFSZ]; strcpy(temp_buf, firstmatch); checkfile(temp_buf, pm, false, (bool)(ans == LOOK_VERBOSE)); } } else { pline("I've never heard of such things."); } } while (from_screen && !quick && ans != LOOK_ONCE); flags.verbose = save_verbose; return 0; }