home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / HACKSRC.ZIP / POTION.C < prev    next >
C/C++ Source or Header  |  1985-10-16  |  9KB  |  387 lines

  1. /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
  2. /* potion.c - version 1.0.3 */
  3.  
  4. #include "hack.h"
  5. extern int float_down();
  6. extern char *nomovemsg;
  7. extern struct monst youmonst;
  8. extern struct monst *makemon();
  9.  
  10. dodrink() {
  11.     register struct obj *otmp,*objs;
  12.     register struct monst *mtmp;
  13.     register int unkn = 0, nothing = 0;
  14.  
  15.     otmp = getobj("!", "drink");
  16.     if(!otmp) return(0);
  17.     if(!strcmp(objects[otmp->otyp].oc_descr, "smoky") && !rn2(13)) {
  18.         ghost_from_bottle();
  19.         goto use_it;
  20.     }
  21.     switch(otmp->otyp){
  22.     case POT_RESTORE_STRENGTH:
  23.         unkn++;
  24.         pline("Wow!  This makes you feel great!");
  25.         if(u.ustr < u.ustrmax) {
  26.             u.ustr = u.ustrmax;
  27.             flags.botl = 1;
  28.         }
  29.         break;
  30.     case POT_BOOZE:
  31.         unkn++;
  32.         pline("Ooph!  This tastes like liquid fire!");
  33.         Confusion += d(3,8);
  34.         /* the whiskey makes us feel better */
  35.         if(u.uhp < u.uhpmax) losehp(-1, "bottle of whiskey");
  36.         if(!rn2(4)) {
  37.             pline("You pass out.");
  38.             multi = -rnd(15);
  39.             nomovemsg = "You awake with a headache.";
  40.         }
  41.         break;
  42.     case POT_INVISIBILITY:
  43.         if(Invis || See_invisible)
  44.           nothing++;
  45.         else {
  46.           if(!Blind)
  47.             pline("Gee!  All of a sudden, you can't see yourself.");
  48.           else
  49.             pline("You feel rather airy."), unkn++;
  50.           newsym(u.ux,u.uy);
  51.         }
  52.         Invis += rn1(15,31);
  53.         break;
  54.     case POT_FRUIT_JUICE:
  55.         pline("This tastes like fruit juice.");
  56.         lesshungry(20);
  57.         break;
  58.     case POT_HEALING:
  59.         pline("You begin to feel better.");
  60.         flags.botl = 1;
  61.         u.uhp += rnd(10);
  62.         if(u.uhp > u.uhpmax)
  63.             u.uhp = ++u.uhpmax;
  64.         if(Blind) Blind = 1;    /* see on next move */
  65.         if(Sick) Sick = 0;
  66.         break;
  67.     case POT_PARALYSIS:
  68.         if(Levitation)
  69.             pline("You are motionlessly suspended.");
  70.         else
  71.             pline("Your feet are frozen to the floor!");
  72.         nomul(-(rn1(10,25)));
  73.         break;
  74.     case POT_MONSTER_DETECTION:
  75.         if(!fmon) {
  76.             strange_feeling(otmp, "You feel threatened.");
  77.             return(1);
  78.         } else {
  79.             cls();
  80.             for(mtmp = fmon; mtmp; mtmp = mtmp->nmon)
  81.                 if(mtmp->mx > 0)
  82.                 at(mtmp->mx,mtmp->my,mtmp->data->mlet);
  83.             prme();
  84.             pline("You sense the presence of monsters.");
  85.             more();
  86.             docrt();
  87.         }
  88.         break;
  89.     case POT_OBJECT_DETECTION:
  90.         if(!fobj) {
  91.             strange_feeling(otmp, "You feel a pull downward.");
  92.             return(1);
  93.         } else {
  94.             for(objs = fobj; objs; objs = objs->nobj)
  95.             if(objs->ox != u.ux || objs->oy != u.uy)
  96.                 goto outobjmap;
  97.             pline("You sense the presence of objects close nearby.");
  98.             break;
  99.         outobjmap:
  100.             cls();
  101.             for(objs = fobj; objs; objs = objs->nobj)
  102.                 at(objs->ox,objs->oy,objs->olet);
  103.             prme();
  104.             pline("You sense the presence of objects.");
  105.             more();
  106.             docrt();
  107.         }
  108.         break;
  109.     case POT_SICKNESS:
  110.         pline("Yech! This stuff tastes like poison.");
  111.         if(Poison_resistance)
  112.     pline("(But in fact it was biologically contaminated orange juice.)");
  113.         losestr(rn1(4,3));
  114.         losehp(rnd(10), "contaminated potion");
  115.         break;
  116.     case POT_CONFUSION:
  117.         if(!Confusion)
  118.             pline("Huh, What?  Where am I?");
  119.         else
  120.             nothing++;
  121.         Confusion += rn1(7,16);
  122.         break;
  123.     case POT_GAIN_STRENGTH:
  124.         pline("Wow do you feel strong!");
  125.         if(u.ustr >= 118) break;    /* > 118 is impossible */
  126.         if(u.ustr > 17) u.ustr += rnd(118-u.ustr);
  127.         else u.ustr++;
  128.         if(u.ustr > u.ustrmax) u.ustrmax = u.ustr;
  129.         flags.botl = 1;
  130.         break;
  131.     case POT_SPEED:
  132.         if(Wounded_legs) {
  133.             heal_legs();
  134.             unkn++;
  135.             break;
  136.         }
  137.         if(!(Fast & ~INTRINSIC))
  138.             pline("You are suddenly moving much faster.");
  139.         else
  140.             pline("Your legs get new energy."), unkn++;
  141.         Fast += rn1(10,100);
  142.         break;
  143.     case POT_BLINDNESS:
  144.         if(!Blind)
  145.             pline("A cloud of darkness falls upon you.");
  146.         else
  147.             nothing++;
  148.         Blind += rn1(100,250);
  149.         seeoff(0);
  150.         break;
  151.     case POT_GAIN_LEVEL: 
  152.         pluslvl();
  153.         break;
  154.     case POT_EXTRA_HEALING:
  155.         pline("You feel much better.");
  156.         flags.botl = 1;
  157.         u.uhp += d(2,20)+1;
  158.         if(u.uhp > u.uhpmax)
  159.             u.uhp = (u.uhpmax += 2);
  160.         if(Blind) Blind = 1;
  161.         if(Sick) Sick = 0;
  162.         break;
  163.     case POT_LEVITATION:
  164.         if(!Levitation)
  165.             float_up();
  166.         else
  167.             nothing++;
  168.         Levitation += rnd(100);
  169.         u.uprops[PROP(RIN_LEVITATION)].p_tofn = float_down;
  170.         break;
  171.     default:
  172.         impossible("What a funny potion! (%u)", otmp->otyp);
  173.         return(0);
  174.     }
  175.     if(nothing) {
  176.         unkn++;
  177.         pline("You have a peculiar feeling for a moment, then it passes.");
  178.     }
  179.     if(otmp->dknown && !objects[otmp->otyp].oc_name_known) {
  180.         if(!unkn) {
  181.             objects[otmp->otyp].oc_name_known = 1;
  182.             more_experienced(0,10);
  183.         } else if(!objects[otmp->otyp].oc_uname)
  184.             docall(otmp);
  185.     }
  186. use_it:
  187.     useup(otmp);
  188.     return(1);
  189. }
  190.  
  191. pluslvl()
  192. {
  193.     register num;
  194.  
  195.     pline("You feel more experienced.");
  196.     num = rnd(10);
  197.     u.uhpmax += num;
  198.     u.uhp += num;
  199.     if(u.ulevel < 14) {
  200.         extern long newuexp();
  201.  
  202.         u.uexp = newuexp()+1;
  203.         pline("Welcome to experience level %u.", ++u.ulevel);
  204.     }
  205.     flags.botl = 1;
  206. }
  207.  
  208. strange_feeling(obj,txt)
  209. register struct obj *obj;
  210. register char *txt;
  211. {
  212.     if(flags.beginner)
  213.         pline("You have a strange feeling for a moment, then it passes.");
  214.     else
  215.         pline(txt);
  216.     if(!objects[obj->otyp].oc_name_known && !objects[obj->otyp].oc_uname)
  217.         docall(obj);
  218.     useup(obj);
  219. }
  220.  
  221. char *bottlenames[] = {
  222.     "bottle", "phial", "flagon", "carafe", "flask", "jar", "vial"
  223. };
  224.  
  225. potionhit(mon, obj)
  226. register struct monst *mon;
  227. register struct obj *obj;
  228. {
  229.     extern char *xname();
  230.     register char *botlnam = bottlenames[rn2(SIZE(bottlenames))];
  231.     boolean uclose, isyou = (mon == &youmonst);
  232.  
  233.     if(isyou) {
  234.         uclose = TRUE;
  235.         pline("The %s crashes on your head and breaks into shivers.",
  236.             botlnam);
  237.         losehp(rnd(2), "thrown potion");
  238.     } else {
  239.         uclose = (dist(mon->mx,mon->my) < 3);
  240.         /* perhaps 'E' and 'a' have no head? */
  241.         pline("The %s crashes on %s's head and breaks into shivers.",
  242.             botlnam, monnam(mon));
  243.         if(rn2(5) && mon->mhp > 1)
  244.             mon->mhp--;
  245.     }
  246.     pline("The %s evaporates.", xname(obj));
  247.  
  248.     if(!isyou && !rn2(3)) switch(obj->otyp) {
  249.  
  250.     case POT_RESTORE_STRENGTH:
  251.     case POT_GAIN_STRENGTH:
  252.     case POT_HEALING:
  253.     case POT_EXTRA_HEALING:
  254.         if(mon->mhp < mon->mhpmax) {
  255.             mon->mhp = mon->mhpmax;
  256.             pline("%s looks sound and hale again!", Monnam(mon));
  257.         }
  258.         break;
  259.     case POT_SICKNESS:
  260.         if(mon->mhpmax > 3)
  261.             mon->mhpmax /= 2;
  262.         if(mon->mhp > 2)
  263.             mon->mhp /= 2;
  264.         break;
  265.     case POT_CONFUSION:
  266.     case POT_BOOZE:
  267.         mon->mconf = 1;
  268.         break;
  269.     case POT_INVISIBILITY:
  270.         unpmon(mon);
  271.         mon->minvis = 1;
  272.         pmon(mon);
  273.         break;
  274.     case POT_PARALYSIS:
  275.         mon->mfroz = 1;
  276.         break;
  277.     case POT_SPEED:
  278.         mon->mspeed = MFAST;
  279.         break;
  280.     case POT_BLINDNESS:
  281.         mon->mblinded |= 64 + rn2(64);
  282.         break;
  283. /*    
  284.     case POT_GAIN_LEVEL:
  285.     case POT_LEVITATION:
  286.     case POT_FRUIT_JUICE:
  287.     case POT_MONSTER_DETECTION:
  288.     case POT_OBJECT_DETECTION:
  289.         break;
  290. */
  291.     }
  292.     if(uclose && rn2(5))
  293.         potionbreathe(obj);
  294.     obfree(obj, Null(obj));
  295. }
  296.  
  297. potionbreathe(obj)
  298. register struct obj *obj;
  299. {
  300.     switch(obj->otyp) {
  301.     case POT_RESTORE_STRENGTH:
  302.     case POT_GAIN_STRENGTH:
  303.         if(u.ustr < u.ustrmax) u.ustr++, flags.botl = 1;
  304.         break;
  305.     case POT_HEALING:
  306.     case POT_EXTRA_HEALING:
  307.         if(u.uhp < u.uhpmax) u.uhp++, flags.botl = 1;
  308.         break;
  309.     case POT_SICKNESS:
  310.         if(u.uhp <= 5) u.uhp = 1; else u.uhp -= 5;
  311.         flags.botl = 1;
  312.         break;
  313.     case POT_CONFUSION:
  314.     case POT_BOOZE:
  315.         if(!Confusion)
  316.             pline("You feel somewhat dizzy.");
  317.         Confusion += rnd(5);
  318.         break;
  319.     case POT_INVISIBILITY:
  320.         pline("For an instant you couldn't see your right hand.");
  321.         break;
  322.     case POT_PARALYSIS:
  323.         pline("Something seems to be holding you.");
  324.         nomul(-rnd(5));
  325.         break;
  326.     case POT_SPEED:
  327.         Fast += rnd(5);
  328.         pline("Your knees seem more flexible now.");
  329.         break;
  330.     case POT_BLINDNESS:
  331.         if(!Blind) pline("It suddenly gets dark.");
  332.         Blind += rnd(5);
  333.         seeoff(0);
  334.         break;
  335. /*    
  336.     case POT_GAIN_LEVEL:
  337.     case POT_LEVITATION:
  338.     case POT_FRUIT_JUICE:
  339.     case POT_MONSTER_DETECTION:
  340.     case POT_OBJECT_DETECTION:
  341.         break;
  342. */
  343.     }
  344.     /* note: no obfree() */
  345. }
  346.  
  347. /*
  348.  * -- rudimentary -- to do this correctly requires much more work
  349.  * -- all sharp weapons get one or more qualities derived from the potions
  350.  * -- texts on scrolls may be (partially) wiped out; do they become blank?
  351.  * --   or does their effect change, like under Confusion?
  352.  * -- all objects may be made invisible by POT_INVISIBILITY
  353.  * -- If the flask is small, can one dip a large object? Does it magically
  354.  * --   become a jug? Etc.
  355.  */
  356. dodip(){
  357.     register struct obj *potion, *obj;
  358.  
  359.     if(!(obj = getobj("#", "dip")))
  360.         return(0);
  361.     if(!(potion = getobj("!", "dip into")))
  362.         return(0);
  363.     pline("Interesting...");
  364.     if(obj->otyp == ARROW || obj->otyp == DART ||
  365.        obj->otyp == CROSSBOW_BOLT) {
  366.         if(potion->otyp == POT_SICKNESS) {
  367.             useup(potion);
  368.             if(obj->spe < 7) obj->spe++;    /* %% */
  369.         }
  370.     }
  371.     return(1);
  372. }
  373.  
  374. ghost_from_bottle(){
  375.     extern struct permonst pm_ghost;
  376.     register struct monst *mtmp;
  377.  
  378.     if(!(mtmp = makemon(PM_GHOST,u.ux,u.uy))){
  379.         pline("This bottle turns out to be empty.");
  380.         return;
  381.     }
  382.     mnexto(mtmp);
  383.     pline("As you open the bottle, an enormous ghost emerges!");
  384.     pline("You are frightened to death, and unable to move.");
  385.     nomul(-3);
  386. }
  387.