diff -r -U 5 -N nethack-3.4.3/include/extern.h nethack-DYWYPISI/include/extern.h --- nethack-3.4.3/include/extern.h 2003-12-08 07:39:13.000000000 +0800 +++ nethack-DYWYPISI/include/extern.h 2011-03-05 21:03:39.000000000 +0800 @@ -1343,10 +1343,12 @@ E int NDECL(dodiscovered); /* ### objects.c ### */ E void NDECL(objects_init); +E void NDECL(dump_ID_on); +E void NDECL(dump_ID_off); /* ### objnam.c ### */ E char *FDECL(obj_typename, (int)); E char *FDECL(simple_typename, (int)); diff -r -U 5 -N nethack-3.4.3/src/end.c nethack-DYWYPISI/src/end.c --- nethack-3.4.3/src/end.c 2003-12-08 07:39:13.000000000 +0800 +++ nethack-DYWYPISI/src/end.c 2011-03-05 23:33:15.000000000 +0800 @@ -365,16 +365,11 @@ ask = should_query_disclose_option('i', &defquery); if (!done_stopprint) { c = ask ? yn_function(qbuf, ynqchars, defquery) : defquery; if (c == 'y') { - struct obj *obj; - - for (obj = invent; obj; obj = obj->nobj) { - makeknown(obj->otyp); - obj->known = obj->bknown = obj->dknown = obj->rknown = 1; - } + dump_ID_on(); (void) display_inventory((char *)0, TRUE); container_contents(invent, TRUE, TRUE); } if (c == 'q') done_stopprint++; } @@ -922,35 +917,32 @@ { register struct obj *box, *obj; char buf[BUFSZ]; for (box = list; box; box = box->nobj) { + int saveknown = objects[box->otyp].oc_name_known; + objects[box->otyp].oc_name_known = 1; if (Is_container(box) || box->otyp == STATUE) { if (box->otyp == BAG_OF_TRICKS) { continue; /* wrong type of container */ } else if (box->cobj) { winid tmpwin = create_nhwindow(NHW_MENU); Sprintf(buf, "Contents of %s:", the(xname(box))); putstr(tmpwin, 0, buf); putstr(tmpwin, 0, ""); - for (obj = box->cobj; obj; obj = obj->nobj) { - if (identified) { - makeknown(obj->otyp); - obj->known = obj->bknown = - obj->dknown = obj->rknown = 1; - } + for (obj = box->cobj; obj; obj = obj->nobj) putstr(tmpwin, 0, doname(obj)); - } display_nhwindow(tmpwin, TRUE); destroy_nhwindow(tmpwin); if (all_containers) container_contents(box->cobj, identified, TRUE); } else { pline("%s empty.", Tobjnam(box, "are")); display_nhwindow(WIN_MESSAGE, FALSE); } } + objects[box->otyp].oc_name_known = saveknown; if (!all_containers) break; } } diff -r -U 5 -N nethack-3.4.3/src/objnam.c nethack-DYWYPISI/src/objnam.c --- nethack-3.4.3/src/objnam.c 2003-12-08 07:39:13.000000000 +0800 +++ nethack-DYWYPISI/src/objnam.c 2011-03-16 01:14:28.000000000 +0800 @@ -2,12 +2,12 @@ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* NetHack may be freely redistributed. See license for details. */ #include "hack.h" -/* "an uncursed greased partly eaten guardian naga hatchling [corpse]" */ -#define PREFIX 80 /* (56) */ +/* "an [uncursed] greased [very rotten] partly eaten guardian naga hatchling (corpse)" */ +#define PREFIX 80 /* (73) */ #define SCHAR_LIM 127 #define NUMOBUF 12 STATIC_DCL char *FDECL(strprepend,(char *,const char *)); #ifdef OVLB @@ -85,10 +85,22 @@ bufidx = (bufidx + 1) % NUMOBUF; return bufs[bufidx]; } +boolean dump_ID_flag = FALSE; +/* used by possessions identifier */ +void dump_ID_on() +{ + dump_ID_flag = TRUE; +} +/* currently unused, but here anyway */ +void dump_ID_off() +{ + dump_ID_flag = FALSE; +} + char * obj_typename(otyp) register int otyp; { char *buf = nextobuf(); @@ -543,16 +555,18 @@ case 3: Strcat(prefix, "thoroughly "); break; } Strcat(prefix, is_corrodeable(obj) ? "corroded " : "rotted "); } - if (obj->rknown && obj->oerodeproof) - Strcat(prefix, - iscrys ? "fixed " : - is_rustprone(obj) ? "rustproof " : - is_corrodeable(obj) ? "corrodeproof " : /* "stainless"? */ - is_flammable(obj) ? "fireproof " : ""); + if (obj->oerodeproof && (dump_ID_flag || obj->rknown)) + Sprintf(eos(prefix), "%s%s%s ", + obj->rknown? "" : "[", + iscrys ? "fixed" : + is_rustprone(obj) ? "rustproof" : + is_corrodeable(obj) ? "corrodeproof" : /* "stainless"? */ + is_flammable(obj) ? "fireproof" : "", + obj->rknown? "" : "]"); } char * doname(obj) register struct obj *obj; @@ -561,11 +575,160 @@ char prefix[PREFIX]; char tmpbuf[PREFIX+1]; /* when we have to add something at the start of prefix instead of the * end (Strcat is used on the end) */ - register char *bp = xname(obj); + register char *bp = xname(obj), *tmp; + + /* display ID in addition to appearance */ + boolean do_ID = dump_ID_flag && !objects[obj->otyp].oc_name_known; + boolean do_known = dump_ID_flag && !obj->known; + boolean do_dknown = dump_ID_flag && !obj->dknown; + boolean do_bknown = dump_ID_flag && !obj->bknown; + boolean do_rknown = dump_ID_flag && !obj->rknown; + + if(!dump_ID_flag) + ; /* early exit */ + else if(exist_artifact(obj->otyp, (tmp = ONAME(obj)))) { + if(do_dknown || do_known) { + if(!strncmp(tmp, "The ", 4) || !strncmp(tmp, "the ", 4)) + Sprintf(eos(bp), " [%s]", tmp); + else + Sprintf(eos(bp), " [the %s]", tmp); + } + else + ; /* if already known as an artifact, don't bother showing the base type */ + } + else if(obj->otyp == EGG && obj->corpsenm >= LOW_PM && + !(obj->known || mvitals[obj->corpsenm].mvflags & MV_KNOWS_EGG)) + Sprintf(bp, "[%s] egg%s", mons[obj->corpsenm].mname, obj->quan>1? "s" : ""); + + else if(do_ID || do_dknown) { + char *cp = nextobuf(); + + if(Role_if(PM_SAMURAI) && (tmp = (char*)Japanese_item_name(obj->otyp))) + Strcpy(cp, tmp); + + else if(obj->otyp == POT_WATER && (obj->blessed || obj->cursed)) + Sprintf(cp, "%sholy water", obj->blessed? "" : "un"); + else { + Strcpy(cp, OBJ_NAME(objects[obj->otyp])); + if(obj->oclass == GEM_CLASS) { + if(GemStone(obj->otyp) && obj->otyp != FLINT) Strcat(cp, " stone"); + if(obj->quan > 1) cp = makeplural(cp); + } + } + + /* ideous post-processing: try to merge the ID and appearance naturally + the cases are significant, to avoid matching fruit names. + general rules, barring bugs: + thing of foo [thing of actual] -> thing of foo [of actual] + (no such objects) + foo thing [thing of actual] -> foo thing [of actual] + eg. square amulet [of strangulation] + thing of foo [actual thing] -> thing of foo [of actual] + eg. scroll labeled DUAM XNAHT [of amnesia] + foo thing [actual thing] -> foo thing [actual] + eg. mud boots [speed boots] + thing [thing of actual] -> thing [of actual] + eg. bag [of holding] + thing [actual thing] -> [actual] thing + eg. [wax] candle + */ + switch(obj->oclass) { + case COIN_CLASS: + *cp = '\0'; + break; + case AMULET_CLASS: + if(obj->otyp == AMULET_VERSUS_POISON) cp += sizeof("amulet"); /* versus poison */ + else if(obj->otyp == FAKE_AMULET_OF_YENDOR) *strstr(cp, " of the Amulet of Yendor") = '\0'; /* cheap plastic imitation */ + else if(obj->otyp == AMULET_OF_YENDOR) *cp = '\0'; /* is its own description */ + else cp += sizeof("amulet"); + break; + case WEAPON_CLASS: + if((tmp = strstr(cp, " dagger"))) *tmp = '\0'; + else if((tmp = strstr(cp, " bow"))) *tmp = '\0'; + else if((tmp = strstr(cp, " arrow"))) *tmp = '\0'; + else if((tmp = strstr(cp, " short sword"))) *tmp = '\0'; + else if((tmp = strstr(cp, " broadsword"))) *tmp = '\0'; + else if((tmp = strstr(cp, " spear"))) *tmp = '\0'; + break; + case ARMOR_CLASS: + if(obj->otyp == DWARVISH_CLOAK) Strcpy(cp, "dwarvish"); + /* only remove "cloak" if unIDed is already "opera cloak" */ + else if(strstr(bp, "cloak")) { + if((tmp = strstr(cp, " cloak"))) *tmp = '\0'; /* elven */ + else if(strstr(cp, "cloak of ")) cp += sizeof("cloak"); /* other */ + } + else if(obj->otyp == LEATHER_GLOVES) Strcpy(cp, "leather"); + else if((tmp = strstr(cp, " gloves"))) *tmp = '\0'; /* other */ + else if((tmp = strstr(cp, " boots"))) *tmp = '\0'; + /* else if((tmp = strstr(cp, " boots"))) { + *tmp = '\0'; + memmove(cp + 3, cp, strlen(cp) + 1); + strncpy(cp, "of ", 3); + } foo boots [actual boots] -> foo boots [of actual] */ + else if((tmp = strstr(cp, " shoes"))) *tmp = '\0'; /* iron */ + else if(strstr(cp, "helm of ")) cp += sizeof("helm"); + else if(strstr(cp, "shield of ")) cp += sizeof("shield"); /* of reflection */ + else if((tmp = strstr(cp, " shield"))) *tmp = '\0'; + else if((tmp = strstr(cp, " ring mail"))) *tmp = '\0'; /* orcish */ + else if((tmp = strstr(cp, " chain mail"))) *tmp = '\0'; /* orcish */ + break; + case TOOL_CLASS: + /* thing [actual thing] -> [actual] thing */ + if((tmp = strstr(cp, " candle")) || + (tmp = strstr(cp, " horn")) || + (tmp = strstr(cp, " lamp")) || + (tmp = strstr(cp, " flute")) || + (tmp = strstr(cp, " harp")) || + (tmp = strstr(cp, " whistle"))) { + *tmp = '\0'; + memmove(cp + 1, cp, strlen(cp) + 1); + *cp = '['; + Strcat(cp, "] "); + bp = strprepend(bp, cp); + *cp = '\0'; + } + else if(strstr(cp, "horn of ")) cp += sizeof("horn"); /* of plenty */ + else if(obj->otyp == LEATHER_DRUM) Strcpy(cp, "leather"); + else if(obj->otyp == DRUM_OF_EARTHQUAKE) Strcpy(cp, "of earthquake"); + else if((tmp = strstr(cp, "bag of "))) cp += sizeof("bag"); + break; + case GEM_CLASS: + if(strstr(cp, "worthless piece")) Strcpy(cp, "worthless glass"); + break; + case VENOM_CLASS: + /* technically, this doesn't follow the rules... if anyone cares. */ + if((tmp = strstr(cp, " venom"))) *tmp = '\0'; + break; + } + /* end post-processing */ + + if(strlen(cp)) { + if(obj->oclass == POTION_CLASS || obj->oclass == SCROLL_CLASS + || (obj->oclass == SPBOOK_CLASS && obj->otyp != SPE_BOOK_OF_THE_DEAD) + || obj->oclass == WAND_CLASS || obj->oclass == RING_CLASS) + Sprintf(eos(bp), " [of %s]", cp); + else + Sprintf(eos(bp), " [%s]", cp); + } + } + else if (obj->otyp == TIN && do_known) { + if (obj->spe > 0) + Strcat(bp, " [of spinach]"); + else if (obj->corpsenm == NON_PM) + Strcat(bp, " [empty]"); + else if (vegetarian(&mons[obj->corpsenm])) + Sprintf(eos(bp), " [of %s]", mons[obj->corpsenm].mname); + else + Sprintf(eos(bp), " [of %s meat]", mons[obj->corpsenm].mname); + } + else if(obj->otyp == POT_WATER && + (obj->blessed || obj->cursed) && do_bknown) { + Sprintf(bp, "potion of [%sholy] water", obj->cursed? "un" : ""); + } /* When using xname, we want "poisoned arrow", and when using * doname, we want "poisoned +0 arrow". This kludge is about the only * way to do it, at least until someone overhauls xname() and doname(), * combining both into one function taking a parameter. @@ -587,21 +750,26 @@ #ifdef INVISIBLE_OBJECTS if (obj->oinvis) Strcat(prefix,"invisible "); #endif - if (obj->bknown && + if ((obj->bknown || do_bknown) && obj->oclass != COIN_CLASS && (obj->otyp != POT_WATER || !objects[POT_WATER].oc_name_known || (!obj->cursed && !obj->blessed))) { /* allow 'blessed clear potion' if we don't know it's holy water; * always allow "uncursed potion of water" */ - if (obj->cursed) - Strcat(prefix, "cursed "); - else if (obj->blessed) - Strcat(prefix, "blessed "); + if ((obj->bknown && (obj->blessed || obj->cursed) /* fall-through for uncursed */) + || (do_bknown + && !(obj->otyp == POT_WATER && (obj->blessed || obj->cursed)) + /* "[blessed] clear potion [of holy water]" is redundant */ )) + Sprintf(eos(prefix), "%s%s%s ", do_bknown? "[" : "", + obj->blessed? "blessed" : obj->cursed? "cursed" : "uncursed", + do_bknown? "]" : ""); + else if (do_bknown && obj->otyp == POT_WATER) + ; /* (un)holy water, skipped as above */ else if ((!obj->known || !objects[obj->otyp].oc_charged || (obj->oclass == ARMOR_CLASS || obj->oclass == RING_CLASS)) /* For most items with charges or +/-, if you know how many * charges are left or what the +/- is, then you must have @@ -632,14 +800,13 @@ case WEAPON_CLASS: if(ispoisoned) Strcat(prefix, "poisoned "); plus: add_erosion_words(obj, prefix); - if(obj->known) { - Strcat(prefix, sitoa(obj->spe)); - Strcat(prefix, " "); - } + if(obj->known || do_known) + Sprintf(eos(prefix), "%s%s%s ", + do_known? "[" : "", sitoa(obj->spe), do_known? "]" : ""); break; case ARMOR_CLASS: if(obj->owornmask & W_ARMOR) Strcat(bp, (obj == uskin) ? " (embedded in your skin)" : " (being worn)"); @@ -681,15 +848,21 @@ break; } if(objects[obj->otyp].oc_charged) goto charges; break; + case SPBOOK_CLASS: +#define MAX_SPELL_STUDY 3 /* spell.c */ + if(dump_ID_flag && obj->spestudied > MAX_SPELL_STUDY / 2) + Strcat(prefix, "[faint] "); + break; case WAND_CLASS: add_erosion_words(obj, prefix); charges: - if(obj->known) - Sprintf(eos(bp), " (%d:%d)", (int)obj->recharged, obj->spe); + if(obj->known || do_known) + Sprintf(eos(bp), " %s%d:%d%s", do_known? "[(" : "(", + (int)obj->recharged, obj->spe, do_known? ")]" : ")"); break; case POTION_CLASS: if (obj->otyp == POT_OIL && obj->lamplit) Strcat(bp, " (lit)"); break; @@ -700,16 +873,24 @@ if(obj->owornmask & W_RINGL) Strcat(bp, " (on left "); if(obj->owornmask & W_RING) { Strcat(bp, body_part(HAND)); Strcat(bp, ")"); } - if(obj->known && objects[obj->otyp].oc_charged) { - Strcat(prefix, sitoa(obj->spe)); - Strcat(prefix, " "); - } + if((obj->known || do_known) && objects[obj->otyp].oc_charged) + Sprintf(eos(prefix), "%s%s%s ", + do_known? "[" : "", sitoa(obj->spe), do_known? "]" : ""); break; case FOOD_CLASS: + /* eat.c: edibility_prompts() */ + if (dump_ID_flag && obj->otyp == CORPSE && obj->corpsenm != PM_ACID_BLOB && + obj->corpsenm != PM_LIZARD && obj->corpsenm != PM_LICHEN) { + long age = monstermoves - peek_at_iced_corpse_age(obj); + long bucmod = obj->cursed? 2 : obj->blessed? -2 : 0; + long mayberot = age / 10L + bucmod, surerot = age / 29L + bucmod; + if (surerot > 5L) Strcat(prefix, "[very rotten] "); + else if (mayberot > 5L) Strcat(prefix, "[rotten] "); + } if (obj->oeaten) Strcat(prefix, "partly eaten "); if (obj->otyp == CORPSE) { if (mons[obj->corpsenm].geno & G_UNIQ) { Sprintf(prefix, "%s%s ", @@ -720,14 +901,12 @@ } else { Strcat(prefix, mons[obj->corpsenm].mname); Strcat(prefix, " "); } } else if (obj->otyp == EGG) { -#if 0 /* corpses don't tell if they're stale either */ - if (obj->known && stale_egg(obj)) - Strcat(prefix, "stale "); -#endif + if (dump_ID_flag && stale_egg(obj)) + Strcat(prefix, "[stale] "); if (obj->corpsenm >= LOW_PM && (obj->known || mvitals[obj->corpsenm].mvflags & MV_KNOWS_EGG)) { Strcat(prefix, mons[obj->corpsenm].mname); Strcat(prefix, " "); @@ -775,19 +954,40 @@ quotedprice += contained_cost(obj, shkp, 0L, FALSE, TRUE); Sprintf(eos(bp), " (unpaid, %ld %s)", quotedprice, currency(quotedprice)); } if (!strncmp(prefix, "a ", 2) && - index(vowels, *(prefix+2) ? *(prefix+2) : *bp) + (index(vowels, prefix[2] ? prefix[2] : *bp) + || (dump_ID_flag && !strncmp(prefix+2, "[uncursed", 9))) && (*(prefix+2) || (strncmp(bp, "uranium", 7) && strncmp(bp, "unicorn", 7) && strncmp(bp, "eucalyptus", 10)))) { Strcpy(tmpbuf, prefix); Strcpy(prefix, "an "); Strcpy(prefix+3, tmpbuf+2); } + /* merge bracketed attribs + eg. [rustproof] [+1] -> [rustproof +1] */ + tmp = prefix; + while((tmp = strstr(tmp, "] ["))) { + *tmp = ' '; + memmove(tmp + 1, tmp + 3, strlen(tmp + 3) + 1); + } bp = strprepend(bp, prefix); + if(obj->otyp != SLIME_MOLD) { + tmp = bp; + while((tmp = strstr(tmp, "] ["))) { + *tmp = ' '; + memmove(tmp + 1, tmp + 3, strlen(tmp + 3) + 1); + } + /* turn [(n:n)] wand charges into [n:n] */ + if((tmp = strstr(bp, "[("))) { + char *tmp2 = strstr(tmp, ")]"); + memmove(tmp2, tmp2 + 1, strlen(tmp2 + 1) + 1); + memmove(tmp + 1, tmp + 2, strlen(tmp + 2) + 1); + } + } return(bp); } #endif /* OVL0 */ #ifdef OVLB