fix #H2559+2564 - using 'a' command to discover potion of oil (trunk only)
authornethack.rankin <nethack.rankin>
Tue, 10 Jan 2012 08:50:19 +0000 (08:50 +0000)
committernethack.rankin <nethack.rankin>
Tue, 10 Jan 2012 08:50:19 +0000 (08:50 +0000)
     From a bug report, if you used the apply command while
not carrying anything applicable except for unknown potion, you would get
"you don't have anything to apply" if that potion wasn't oil but an
inventory selection prompt (with '*' as the default since you wouldn't
have anything considered to be a likely candidate) if that potion was oil,
giving away information.

     This fix makes carrying any unknown potion yield the inventory
selection result, unless oil is already discovered and hero can see that
the unknown potion isn't oil.

doc/fixes35.0
src/apply.c

index f185bc4c5eda4f9be04929a75739b95a073aaecf..da378b1ddd1c614e7250b2b10b75dc1d470a672f 100644 (file)
@@ -401,6 +401,7 @@ autosearch finds and transforms secret doors and corridors even while blind,
 hangup save made during magic mapping or <foo> detection performed while
        underwater could put hero on top of the water after restore
 items conferring life drain resistance were affected by drain life spell
+'a'pply command could be used to recogniize undiscovered potions of oil
 
 
 Platform- and/or Interface-Specific Fixes
index 55b986efb8b6bb91ec990e9770569f8d605a1e25..dc2245cd14f96df0664934957db58a8372d11c97 100644 (file)
@@ -6,10 +6,6 @@
 
 extern boolean notonhead;      /* for long worms */
 
-static const char tools[] = { TOOL_CLASS, WEAPON_CLASS, WAND_CLASS, 0 };
-static const char tools_too[] = { ALL_CLASSES, TOOL_CLASS, POTION_CLASS,
-                                 WEAPON_CLASS, WAND_CLASS, GEM_CLASS, 0 };
-
 #ifdef TOURIST
 STATIC_DCL int FDECL(use_camera, (struct obj *));
 #endif
@@ -38,8 +34,8 @@ STATIC_DCL int FDECL(use_grapple, (struct obj *));
 STATIC_DCL int FDECL(do_break_wand, (struct obj *));
 STATIC_DCL boolean FDECL(figurine_location_checks,
                                (struct obj *, coord *, BOOLEAN_P));
-STATIC_DCL boolean NDECL(uhave_graystone);
 STATIC_DCL void FDECL(add_class, (char *, CHAR_P));
+STATIC_DCL void FDECL(setapplyclasses, (char *));
 
 #ifdef AMIGA
 void FDECL( amii_speaker, ( struct obj *, char *, int ) );
@@ -3069,28 +3065,56 @@ do_break_wand(obj)
     return 1;
 }
 
-STATIC_OVL boolean
-uhave_graystone()
-{
-       register struct obj *otmp;
-
-       for(otmp = invent; otmp; otmp = otmp->nobj)
-               if(is_graystone(otmp))
-                       return TRUE;
-       return FALSE;
-}
-
 STATIC_OVL void
 add_class(cl, class)
 char *cl;
 char class;
 {
        char tmp[2];
+
        tmp[0] = class;
        tmp[1] = '\0';
        Strcat(cl, tmp);
 }
 
+static const char tools[] = { TOOL_CLASS, WEAPON_CLASS, WAND_CLASS, 0 };
+
+/* augment tools[] if various items are carried */
+STATIC_OVL void
+setapplyclasses(class_list)
+char class_list[];
+{
+       register struct obj *otmp;
+       int otyp;
+       boolean knowoil, knowtouchstone, addpotions, addstones, addfood;
+
+       knowoil = objects[POT_OIL].oc_name_known;
+       knowtouchstone = objects[TOUCHSTONE].oc_name_known;
+       addpotions = addstones = addfood = FALSE;
+       for (otmp = invent; otmp; otmp = otmp->nobj) {
+           otyp = otmp->otyp;
+           if (otyp == POT_OIL ||
+               (otmp->oclass == POTION_CLASS &&
+                 (!otmp->dknown ||
+                   (!knowoil && !objects[otyp].oc_name_known))))
+               addpotions = TRUE;
+           if (otyp == TOUCHSTONE ||
+               (is_graystone(otmp) &&
+                 (!otmp->dknown ||
+                   (!knowtouchstone && !objects[otyp].oc_name_known))))
+               addstones = TRUE;
+           if (otyp == CREAM_PIE || otyp == EUCALYPTUS_LEAF)
+               addfood = TRUE;
+       }
+
+       class_list[0] = '\0';
+       if (addpotions || addstones) add_class(class_list, ALL_CLASSES);
+       Strcat(class_list, tools);
+       if (addpotions) add_class(class_list, POTION_CLASS);
+       if (addstones) add_class(class_list, GEM_CLASS);
+       if (addfood) add_class(class_list, FOOD_CLASS);
+}
+
 int
 doapply()
 {
@@ -3100,13 +3124,7 @@ doapply()
 
        if(check_capacity((char *)0)) return (0);
 
-       if (carrying(POT_OIL) || uhave_graystone())
-               Strcpy(class_list, tools_too);
-       else
-               Strcpy(class_list, tools);
-       if (carrying(CREAM_PIE) || carrying(EUCALYPTUS_LEAF))
-               add_class(class_list, FOOD_CLASS);
-
+       setapplyclasses(class_list);       /* tools[] */
        obj = getobj(class_list, "use or apply");
        if(!obj) return 0;