home *** CD-ROM | disk | FTP | other *** search
/ Giga Games 1 / Giga Games.iso / net / hack / 2_3 / potion.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-06-20  |  14.2 KB  |  644 lines

  1. /*    SCCS Id: @(#)potion.c    2.3    88/02/11
  2. /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
  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. char *hcolor();
  10. #ifdef KAA
  11. char *xname();
  12. extern char pl_character[];
  13. #endif
  14. #ifdef FOUNTAINS
  15. extern int drinkfountain();
  16. extern int dipfountain();
  17. #endif
  18.  
  19. int    nothing, unkn;
  20.  
  21. dodrink() {
  22.     register struct obj *otmp;
  23.     register int    retval;
  24.  
  25. #ifdef FOUNTAINS
  26.  
  27.       /* Is there something to drink here, i.e., a fountain? */
  28.        if (IS_FOUNTAIN(levl[u.ux][u.uy].typ)) {
  29.       pline("Drink from the fountain? [ny] ");
  30.       if(readchar() == 'y') {
  31.         (void) drinkfountain();
  32.         return(0);
  33.       }
  34.        }   
  35.  
  36. #endif /* FOUNTAINS /**/
  37.  
  38.     nothing = unkn = 0;
  39.     otmp = getobj("!", "drink");
  40.     if(!otmp) return(0);
  41.     if(!strcmp(objects[otmp->otyp].oc_descr, "smoky") && !rn2(13)) {
  42.         ghost_from_bottle();
  43.         goto use_it;
  44.     }
  45.     if(!strcmp(objects[otmp->otyp].oc_descr, "glowing") && !rn2(13)) {
  46.         djinni_from_bottle();
  47.         goto use_it;
  48.     }
  49.     if((retval = peffects(otmp)) >= 0) return(retval);
  50.  
  51.     if(nothing) {
  52.         unkn++;
  53.         pline("You have a %s feeling for a moment, then it passes.",
  54.           Hallucination ? "normal" : "peculiar");
  55.     }
  56.     if(otmp->dknown && !objects[otmp->otyp].oc_name_known) {
  57.         if(!unkn) {
  58.             objects[otmp->otyp].oc_name_known = 1;
  59.             more_experienced(0,10);
  60.         } else if(!objects[otmp->otyp].oc_uname)
  61.             docall(otmp);
  62.     }
  63. use_it:
  64.     useup(otmp);
  65.     return(1);
  66. }
  67.  
  68. peffects(otmp)
  69.     register struct obj    *otmp;
  70. {
  71.     register struct obj    *objs;
  72.     register struct monst    *mtmp;
  73.  
  74.     switch(otmp->otyp){
  75.     case POT_RESTORE_STRENGTH:
  76. #ifdef SPELLS
  77.     case SPE_RESTORE_STRENGTH:
  78. #endif
  79.         unkn++;
  80.         pline("Wow!  This makes you feel great!");
  81.         if(u.ustr < u.ustrmax) {
  82.             u.ustr = u.ustrmax;
  83.             flags.botl = 1;
  84.         }
  85.         break;
  86. #ifdef KAA
  87.     case POT_HALLUCINATION:
  88.         if (Hallucination) nothing++;
  89.         else pline("Oh wow!  Everything looks so cosmic!");
  90.         Hallucination += rn1(100,750);
  91.         setsee();
  92.         break;
  93.     case POT_HOLY_WATER:
  94.         unkn++;
  95.         if(index("VWZ&",u.usym)) {
  96.             pline("This burns like acid!");
  97.             /* should never kill you, but... */
  98.             losehp(d(2,6), "potion of holy water");
  99.         } else {
  100.             pline("You feel full of awe.");
  101.             if (Sick) Sick=0;
  102.             if (HConfusion) HConfusion=0;
  103.         }
  104. #else
  105.     case POT_HOLY_WATER:
  106.     case POT_HALLUCINATION:
  107. #endif
  108.         break;
  109.     case POT_BOOZE:
  110.         unkn++;
  111.         pline("Ooph!  This tastes like liquid fire!");
  112.         HConfusion += d(3,8);
  113.         /* the whiskey makes us feel better */
  114.         if(u.uhp < u.uhpmax) losehp(-1, "bottle of whiskey");
  115.         if(!rn2(4)) {
  116.             pline("You pass out.");
  117.             multi = -rnd(15);
  118.             nomovemsg = "You awake with a headache.";
  119.         }
  120.         break;
  121.     case POT_INVISIBILITY:
  122. #ifdef SPELLS
  123.     case SPE_INVISIBILITY:
  124. #endif
  125.         if(Invis || See_invisible)
  126.           nothing++;
  127.         else {
  128.           if(!Blind)
  129.             pline("Gee!  All of a sudden, you can't see yourself.");
  130.           else
  131.             pline("You feel rather airy."), unkn++;
  132.           newsym(u.ux,u.uy);
  133.         }
  134.         HInvis += rn1(15,31);
  135.         break;
  136.     case POT_FRUIT_JUICE:
  137.         pline("This tastes like fruit juice.");
  138.         lesshungry(20);
  139.         break;
  140.     case POT_HEALING:
  141.         pline("You begin to feel better.");
  142.         healup(rnd(10), 1, 1, 1);
  143.         break;
  144.     case POT_PARALYSIS:
  145.         if(Levitation)
  146.             pline("You are motionlessly suspended.");
  147.         else
  148.             pline("Your feet are frozen to the floor!");
  149.         nomul(-(rn1(10,25)));
  150.         break;
  151.     case POT_MONSTER_DETECTION:
  152. #ifdef SPELLS
  153.     case SPE_DETECT_MONSTERS:
  154. #endif
  155.         if(!fmon) {
  156.             strange_feeling(otmp, "You feel threatened.");
  157.             return(1);
  158.         } else {
  159.             cls();
  160.             for(mtmp = fmon; mtmp; mtmp = mtmp->nmon)
  161.                 if(mtmp->mx > 0)
  162.                 at(mtmp->mx,mtmp->my,Hallucination ? rndmonsym() :
  163.                 mtmp->data->mlet);
  164.             prme();
  165.             pline("You sense the presence of monsters.");
  166.             more();
  167.             docrt();
  168.         }
  169.         break;
  170.     case POT_OBJECT_DETECTION:
  171. #ifdef SPELLS
  172.     case SPE_DETECT_TREASURE:
  173. #endif
  174.         if(!fobj) {
  175.             strange_feeling(otmp, "You feel a pull downward.");
  176.             return(1);
  177.         } else {
  178.             for(objs = fobj; objs; objs = objs->nobj)
  179.             if(objs->ox != u.ux || objs->oy != u.uy)
  180.                 goto outobjmap;
  181.             pline("You sense the presence of objects close nearby.");
  182.             break;
  183.         outobjmap:
  184.             cls();
  185.             for(objs = fobj; objs; objs = objs->nobj)
  186.                 at(objs->ox,objs->oy,Hallucination ? rndobjsym()
  187.                  : objs->olet);
  188.  
  189.             /* monster possessions added by GAN 12/16/86 */
  190.             for(mtmp = fmon ; mtmp ; mtmp = mtmp->nmon)
  191.                 if(mtmp->minvent)
  192.                     for(objs = mtmp->minvent; objs ;
  193.                         objs = objs->nobj)
  194.                         at(mtmp->mx,mtmp->my,objs->olet);
  195.             prme();
  196.             pline("You sense the presence of objects.");
  197.             more();
  198.             docrt();
  199.         }
  200.         break;
  201.     case POT_SICKNESS:
  202.         pline("Yech! This stuff tastes like poison.");
  203.         if(Poison_resistance)
  204.     pline("(But in fact it was biologically contaminated orange juice.)");
  205. #ifdef KAA
  206.         if (pl_character[0] == 'H')
  207.             pline("Fortunately you have been immunized!");
  208.         else {
  209. #endif
  210.             losestr((Poison_resistance) ? 1 : rn1(4,3));
  211.             if(!Poison_resistance)
  212.                 losehp(rnd(10), "contaminated potion");
  213. #ifdef KAA
  214.         }
  215. #endif
  216.         if(Hallucination) {
  217.             pline("You are shocked back to your senses!");
  218.             Hallucination=1;
  219.         }
  220.         break;
  221.     case POT_CONFUSION:
  222.         if(!Confusion)
  223.             if (Hallucination) {
  224.             pline("What a trippy feeling!");
  225.             unkn++;
  226.             } else
  227.             pline("Huh, What?  Where am I?");
  228.         else    nothing++;
  229.         HConfusion += rn1(7,16);
  230.         break;
  231.     case POT_GAIN_STRENGTH:
  232.         pline("Wow do you feel strong!");
  233.         gainstr(0);
  234.         break;
  235.     case POT_SPEED:
  236.         if(Wounded_legs) {
  237.             heal_legs();
  238.             unkn++;
  239.             break;
  240.         }        /* and fall through */
  241. #ifdef SPELLS
  242.     case SPE_HASTE_SELF:
  243. #endif
  244.         if(!(Fast & ~INTRINSIC))
  245.             pline("You are suddenly moving much faster.");
  246.         else
  247.             pline("Your legs get new energy."), unkn++;
  248.         Fast += rn1(10,100);
  249.         break;
  250.     case POT_BLINDNESS:
  251.         if(!Blind)
  252.             if (Hallucination)
  253.                 pline("Bummer!  Everything is dark!  Help!");
  254.             else 
  255.                 pline("A cloud of darkness falls upon you.");
  256.         else    nothing++;
  257.         Blinded += rn1(100,250);
  258.         seeoff(0);
  259.         break;
  260.     case POT_GAIN_LEVEL: 
  261.         pluslvl();
  262.         break;
  263.     case POT_EXTRA_HEALING:
  264.         pline("You feel much better.");
  265.         healup(d(2,20)+1, 2, 1, 1);
  266.         if(Hallucination) Hallucination = 1;
  267.         break;
  268.     case POT_LEVITATION:
  269. #ifdef SPELLS
  270.     case SPE_LEVITATION:
  271. #endif
  272.         if(!Levitation)
  273.             float_up();
  274.         else
  275.             nothing++;
  276.         Levitation += rnd(100);
  277.         u.uprops[PROP(RIN_LEVITATION)].p_tofn = float_down;
  278.         break;
  279.     case POT_GAIN_ENERGY:            /* M. Stephenson */
  280. #ifdef SPELLS
  281.         {    register int     num;
  282.             if(Confusion) {
  283.                 pline("You feel feverish.");
  284.                 unkn++;
  285.             } else
  286.                 pline("Magical energies course through your body.");
  287.             num = rnd(5) + 1;
  288.             u.uenmax += num;
  289.             u.uen += num;
  290.             flags.botl = 1;
  291.             break;
  292.         }
  293. #else
  294.         pline("This potion tastes weird!");
  295.         break;
  296. #endif
  297.     default:
  298.         impossible("What a funny potion! (%u)", otmp->otyp);
  299.         return(0);
  300.     }
  301.     return(-1);
  302. }
  303.  
  304. healup(nhp, nxtra, curesick, cureblind)
  305.     int    nhp, nxtra;
  306.     register boolean curesick, cureblind;
  307. {
  308. #ifdef KAA
  309.     if (u.mtimedone & nhp) {
  310.         u.mh += rnd(nhp);
  311.         if (u.mh > u.mhmax) u.mh = (u.mhmax + nxtra);
  312.     }
  313. #endif
  314.     if(nhp)    {
  315.         u.uhp += nhp;
  316.         if(u.uhp > u.uhpmax)    u.uhp = (u.uhpmax += nxtra);
  317.     }
  318.     if(Blind && cureblind)    Blinded = 1;    /* see on next move */
  319.     if(Sick && curesick)    Sick = 0;
  320.     flags.botl = 1;
  321.     return;
  322. }
  323.  
  324. pluslvl()
  325. {
  326.     register num;
  327.  
  328.     pline("You feel more experienced.");
  329.     num = rnd(10);
  330.     u.uhpmax += num;
  331.     u.uhp += num;
  332. #ifdef SPELLS
  333.     num = rnd(u.ulevel/2+1) + 1;        /* M. Stephenson */
  334.     u.uenmax += num;
  335.     u.uen += num;
  336. #endif
  337.     if(u.ulevel < 14) {
  338.         extern long newuexp();
  339.  
  340.         u.uexp = newuexp()+1;
  341.         pline("Welcome to experience level %u.", ++u.ulevel);
  342.     }
  343.     flags.botl = 1;
  344. }
  345.  
  346. strange_feeling(obj,txt)
  347. register struct obj *obj;
  348. register char *txt;
  349. {
  350.     if(flags.beginner)
  351.         pline("You have a %s feeling for a moment, then it passes.",
  352.         Hallucination ? "normal" : "strange");
  353.     else
  354.         pline(txt);
  355.     if(!objects[obj->otyp].oc_name_known && !objects[obj->otyp].oc_uname)
  356.         docall(obj);
  357.     useup(obj);
  358. }
  359.  
  360. char *bottlenames[] = {
  361.     "bottle", "phial", "flagon", "carafe", "flask", "jar", "vial"
  362. };
  363.  
  364. potionhit(mon, obj)
  365. register struct monst *mon;
  366. register struct obj *obj;
  367. {
  368.     extern char *xname();
  369.     register char *botlnam = bottlenames[rn2(SIZE(bottlenames))];
  370.     boolean uclose, isyou = (mon == &youmonst);
  371.  
  372.     if(isyou) {
  373.         uclose = TRUE;
  374.         pline("The %s crashes on your head and breaks into shivers.",
  375.             botlnam);
  376.         losehp(rnd(2), "thrown potion");
  377.     } else {
  378.         uclose = (dist(mon->mx,mon->my) < 3);
  379.         /* perhaps 'E' and 'a' have no head? */
  380.         pline("The %s crashes on %s's head and breaks into shivers.",
  381.             botlnam, monnam(mon));
  382.         if(rn2(5) && mon->mhp > 1)
  383.             mon->mhp--;
  384.     }
  385.     pline("The %s evaporates.", xname(obj));
  386.  
  387. #ifdef KAA
  388.     if(!isyou) switch (obj->otyp) {
  389. #else
  390.     if(!isyou && !rn2(3)) switch(obj->otyp) {
  391. #endif
  392.  
  393.     case POT_RESTORE_STRENGTH:
  394.     case POT_GAIN_STRENGTH:
  395.     case POT_HEALING:
  396.     case POT_EXTRA_HEALING:
  397.         if(mon->mhp < mon->mhpmax) {
  398.             mon->mhp = mon->mhpmax;
  399.             pline("%s looks sound and hale again!", Monnam(mon));
  400.         }
  401.         break;
  402.     case POT_SICKNESS:
  403.         if((mon->mhpmax > 3) && !resist(mon, '!', 0, NOTELL))
  404.             mon->mhpmax /= 2;
  405.         if((mon->mhp > 2) && !resist(mon, '!', 0, NOTELL))
  406.             mon->mhp /= 2;
  407. #ifdef KAA
  408.         pline("%s looks rather ill.", Monnam(mon));
  409. #endif
  410.         break;
  411.     case POT_CONFUSION:
  412.     case POT_BOOZE:
  413.         if(!resist(mon, '!', 0, NOTELL))  mon->mconf = 1;
  414.         break;
  415.     case POT_INVISIBILITY:
  416.         unpmon(mon);
  417.         mon->minvis = 1;
  418.         pmon(mon);
  419.         break;
  420.     case POT_PARALYSIS:
  421.         mon->mfroz = 1;
  422.         break;
  423.     case POT_SPEED:
  424.         mon->mspeed = MFAST;
  425.         break;
  426.     case POT_BLINDNESS:
  427.         mon->mblinded |= 64 + rn2(32) +
  428.                       rn2(32) * !resist(mon, '!', 0, NOTELL);
  429.         break;
  430. #ifdef KAA
  431.     case POT_HOLY_WATER:
  432.         if (index("ZVW &", mon->data->mlet)) {
  433.             pline("%s shrieks in pain!", Monnam(mon));
  434.             mon->mhp -= d(2,6);
  435.             if (mon->mhp <1) killed(mon);
  436.         }
  437.         break;
  438. #endif
  439. /*    
  440.     case POT_GAIN_LEVEL:
  441.     case POT_LEVITATION:
  442.     case POT_FRUIT_JUICE:
  443.     case POT_MONSTER_DETECTION:
  444.     case POT_OBJECT_DETECTION:
  445.         break;
  446. */
  447.     }
  448.     if(uclose && rn2(5))
  449.         potionbreathe(obj);
  450.     obfree(obj, Null(obj));
  451. }
  452.  
  453. potionbreathe(obj)
  454. register struct obj *obj;
  455. {
  456.     switch(obj->otyp) {
  457.     case POT_RESTORE_STRENGTH:
  458.     case POT_GAIN_STRENGTH:
  459.         if(u.ustr < u.ustrmax) u.ustr++, flags.botl = 1;
  460.         break;
  461.     case POT_HEALING:
  462.     case POT_EXTRA_HEALING:
  463.         if(u.uhp < u.uhpmax) u.uhp++, flags.botl = 1;
  464.         break;
  465.     case POT_SICKNESS:
  466.         if(u.uhp <= 5) u.uhp = 1; else u.uhp -= 5;
  467.         flags.botl = 1;
  468.         break;
  469.     case POT_HALLUCINATION:
  470. #ifdef KAA
  471.         pline("You have a vision for a moment.");
  472.         break;
  473. #endif
  474.     case POT_CONFUSION:
  475.     case POT_BOOZE:
  476.         if(!Confusion)
  477.             pline("You feel somewhat dizzy.");
  478.         HConfusion += rnd(5);
  479.         break;
  480.     case POT_INVISIBILITY:
  481.         pline("For an instant you could see through yourself!");
  482.         break;
  483.     case POT_PARALYSIS:
  484.         pline("Something seems to be holding you.");
  485.         nomul(-rnd(5));
  486.         break;
  487.     case POT_SPEED:
  488.         Fast += rnd(5);
  489.         pline("Your knees seem more flexible now.");
  490.         break;
  491.     case POT_BLINDNESS:
  492.         if(!Blind) pline("It suddenly gets dark.");
  493.         Blinded += rnd(5);
  494.         seeoff(0);
  495.         break;
  496. /*    
  497.     case POT_GAIN_LEVEL:
  498.     case POT_LEVITATION:
  499.     case POT_FRUIT_JUICE:
  500.     case POT_MONSTER_DETECTION:
  501.     case POT_OBJECT_DETECTION:
  502.         break;
  503. */
  504.     }
  505.     /* note: no obfree() */
  506. }
  507.  
  508. /*
  509.  * -- rudimentary -- to do this correctly requires much more work
  510.  * -- all sharp weapons get one or more qualities derived from the potions
  511.  * -- texts on scrolls may be (partially) wiped out; do they become blank?
  512.  * --   or does their effect change, like under Confusion?
  513.  * -- all objects may be made invisible by POT_INVISIBILITY
  514.  * -- If the flask is small, can one dip a large object? Does it magically
  515.  * --   become a jug? Etc.
  516.  */
  517. dodip(){
  518.     register struct obj *potion, *obj;
  519. #ifdef KAA
  520.     char *tmp;
  521. #endif
  522.  
  523.     if(!(obj = getobj("#", "dip")))
  524.         return(0);
  525. #ifdef FOUNTAINS
  526.     /* Is there something to dip into here, i.e., a fountain? */
  527.     if (levl[u.ux][u.uy].typ == FOUNTAIN) {
  528.         pline("Dip it in the fountain? [ny] ");
  529.         if(readchar() == 'y') {
  530.             dipfountain(obj);
  531.             return(1);
  532.         }
  533.     }
  534. #endif
  535.     if(!(potion = getobj("!", "dip into")))
  536.         return(0);
  537. #ifndef KAA
  538.     pline("Interesting...");
  539. #else
  540.     if(potion->otyp == POT_HOLY_WATER) {
  541.         if (obj->cursed) {
  542.             obj->cursed=0;
  543.             pline("Your %s %s.", aobjnam(obj,"softly glow"), 
  544.             Hallucination ? hcolor() : "amber");
  545.     poof:    useup(potion);
  546.             return(1);
  547.         } else if(obj->otyp >= ARROW && obj->otyp <= SPEAR) {
  548.             obj->dknown=1;
  549.             tmp = Hallucination ? hcolor() : "light blue";
  550.     /* dknown for weapons is meaningless, so it's free to be reused. */
  551.             pline("Your %s with a%s %s aura.", aobjnam(obj,"softly glow"),
  552.             index("aeiou",*tmp) ? "n" : "", tmp);
  553.             goto poof;
  554.         }
  555.     }
  556. #endif
  557.     if(obj->otyp == ARROW || obj->otyp == DART ||
  558.        obj->otyp == CROSSBOW_BOLT || obj->otyp == SHURIKEN) {
  559.         if(potion->otyp == POT_SICKNESS) {
  560.             char buf[BUFSZ];
  561.             useup(potion);
  562.             if(obj->spe < 7) obj->spe++;    /* %% */
  563.             sprintf(buf, xname(potion));
  564.             pline("The %s forms a coating on the %s.",
  565.                 buf, xname(obj));
  566.         }
  567.     }
  568. #ifdef HARD
  569.     else    if (!rn2(4)) useup(potion);
  570. #endif
  571. #ifdef KAA
  572.     pline("Interesting...");
  573. #endif
  574.     return(1);
  575. }
  576.  
  577. ghost_from_bottle(){
  578.     extern struct permonst pm_ghost;
  579.     register struct monst *mtmp;
  580.  
  581.     if(!(mtmp = makemon(PM_GHOST,u.ux,u.uy))){
  582.         pline("This bottle turns out to be empty.");
  583.         return;
  584.     }
  585.     mnexto(mtmp);
  586.     pline("As you open the bottle, an enormous ghost emerges!");
  587.     pline("You are frightened to death, and unable to move.");
  588.     nomul(-3);
  589. }
  590.  
  591. djinni_from_bottle(){
  592.     extern struct permonst pm_djinni;
  593.     register struct monst *mtmp;
  594.  
  595.     if(!(mtmp = makemon(PM_DJINNI,u.ux,u.uy))){
  596.         pline("It turns out to be empty.");
  597.         return;
  598.     }
  599.  
  600.     mtmp->isdjinni = 1;
  601.     mnexto(mtmp);
  602.     if (!Blind) {
  603.         pline("In a cloud of smoke, a djinni emerges!");
  604.         pline("%s speaks.", Monnam(mtmp));
  605.     } else {
  606.         pline("You smell fumes!");
  607.         pline("Something speaks.");
  608.     }
  609.  
  610.     switch (rn2(5)) {
  611.     case 0 : pline("'I am in your debt. I will grant one wish!'");
  612.         makewish();
  613.         mondied(mtmp);
  614.         break;
  615.     case 1 : pline("'Thank you for freeing me!'");
  616.         tamedog(mtmp, (struct obj *) 0);
  617.         break;
  618.     case 2 : pline("'You freed me!'");
  619.         mtmp->mpeaceful = 1;
  620.         break;
  621.     case 3 : pline("'It is about time!'");
  622.         pline("The djinni vanishes!");
  623.         mondied(mtmp);
  624.         break;
  625.     default: pline("You disturbed me fool!");
  626.         break;
  627.     }
  628. }
  629.  
  630. gainstr(inc)
  631. register int    inc;
  632. {
  633.     if (inc) u.ustr++;
  634.     else {
  635.              if (u.ustr < 18) u.ustr += (rn2(4) ? 1 : rnd(6) );
  636.          else if (u.ustr < 103) u.ustr += rnd(10);
  637.          else u.ustr++;
  638.            }
  639.  
  640.     if(u.ustr > 118)    u.ustr = 118;
  641.     if(u.ustr > u.ustrmax)    u.ustrmax = u.ustr;
  642.     flags.botl = 1;
  643. }
  644.