home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Source Code / C / Games / NetHack 3.1.3 / source / src / polyself.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-08-01  |  23.3 KB  |  936 lines  |  [TEXT/R*ch]

  1. /*    SCCS Id: @(#)polyself.c 3.1    93/06/24    */
  2. /*    Copyright (C) 1987, 1988, 1989 by Ken Arromdee */
  3. /* NetHack may be freely redistributed.  See license for details. */
  4.  
  5. /* Polymorph self routine. */
  6.  
  7. #include "hack.h"
  8.  
  9. #ifdef OVLB
  10. #ifdef POLYSELF
  11. static void NDECL(polyman);
  12. static void NDECL(break_armor);
  13. static void FDECL(drop_weapon,(int));
  14. static void NDECL(skinback);
  15. static void NDECL(uunstick);
  16. static int FDECL(armor_to_dragon,(int));
  17.  
  18. /* make a (new) human out of the player */
  19. static void
  20. polyman()
  21. {
  22.     boolean sticky = sticks(uasmon) && u.ustuck && !u.uswallow;
  23.  
  24.     if (u.umonnum != -1) {
  25.         u.acurr = u.macurr;    /* restore old attribs */
  26.         u.amax = u.mamax;
  27.         u.umonnum = -1;
  28.         flags.female = u.mfemale;
  29.     }
  30.     u.usym = S_HUMAN;
  31.     set_uasmon();
  32.  
  33.     u.mh = u.mhmax = 0;
  34.     u.mtimedone = 0;
  35.     skinback();
  36.     u.uundetected = 0;
  37.     newsym(u.ux,u.uy);
  38.  
  39.     if (sticky) uunstick();
  40.     find_ac();
  41.     if(!Levitation && !u.ustuck &&
  42.        (is_pool(u.ux,u.uy) || is_lava(u.ux,u.uy)))
  43.         spoteffects();
  44. }
  45. #endif /* POLYSELF */
  46.  
  47. void
  48. change_sex()
  49. {
  50.     flags.female = !flags.female;
  51.     max_rank_sz();
  52.     if (pl_character[0] == 'P')
  53.         Strcpy(pl_character+6, flags.female ? "ess" : "");
  54.     if (pl_character[0] == 'C')
  55.         Strcpy(pl_character+4, flags.female ? "woman" : "man");
  56. }
  57.  
  58. void
  59. newman()
  60. {
  61.     int tmp, tmp2;
  62.  
  63.     if (!rn2(10)) change_sex();
  64.  
  65.     tmp = u.uhpmax;
  66.     tmp2 = u.ulevel;
  67.     u.ulevel = u.ulevel-2+rn2(5);
  68.     if (u.ulevel > 127 || u.ulevel == 0) u.ulevel = 1;
  69.     if (u.ulevel > MAXULEV) u.ulevel = MAXULEV;
  70.  
  71.     adjabil(tmp2, (int)u.ulevel);
  72.  
  73.     /* random experience points for the new experience level */
  74.     u.uexp = rndexp();
  75. #ifndef LINT
  76.     u.uhpmax = (u.uhpmax-10)*(long)u.ulevel/tmp2 + 19 - rn2(19);
  77. #endif
  78. /* If it was u.uhpmax*u.ulevel/tmp+9-rn2(19), then a 1st level character
  79.    with 16 hp who polymorphed into a 3rd level one would have an average
  80.    of 48 hp.  */
  81. #ifdef LINT
  82.     u.uhp = u.uhp + tmp;
  83. #else
  84.     u.uhp = u.uhp * (long)u.uhpmax/tmp;
  85. #endif
  86.  
  87.     tmp = u.uenmax;
  88. #ifndef LINT
  89.     u.uenmax = u.uenmax * (long)u.ulevel/tmp2 + 9 - rn2(19);
  90. #endif
  91.     if (u.uenmax < 0) u.uenmax = 0;
  92. #ifndef LINT
  93.     u.uen = (tmp ? u.uen * (long)u.uenmax / tmp : u.uenmax);
  94. #endif
  95.  
  96.     redist_attr();
  97.     u.uhunger = rn1(500,500);
  98.     newuhs(FALSE);
  99.     if (Sick) make_sick(0L, FALSE);
  100.     Stoned = 0;
  101.     if (u.uhp <= 0 || u.uhpmax <= 0) {
  102. #ifdef POLYSELF
  103.         if(Polymorph_control) {
  104.             if (u.uhp <= 0) u.uhp = 1;
  105.             if (u.uhpmax <= 0) u.uhpmax = 1;
  106.         } else {
  107. #endif
  108.             Your("new form doesn't seem healthy enough to survive.");
  109.             killer_format = KILLED_BY_AN;
  110.             killer="unsuccessful polymorph";
  111.             done(DIED);
  112.             pline("Revived, you are in just as bad a shape as before.");
  113.             done(DIED);
  114. #ifdef POLYSELF
  115.         }
  116. #endif
  117.     }
  118. #ifdef POLYSELF
  119.     polyman();
  120. #endif
  121.     You("feel like a new %s!",
  122.         pl_character[0] == 'E' ? "elf" : flags.female ? "woman" : "man");
  123.     flags.botl = 1;
  124.     (void) encumber_msg();
  125. }
  126.  
  127. #ifdef POLYSELF
  128. void
  129. polyself()
  130. {
  131.     char buf[BUFSZ];
  132.     int mntmp = -1;
  133.     int tries=0;
  134.     boolean draconian = (uarm &&
  135.                 uarm->otyp >= GRAY_DRAGON_SCALE_MAIL &&
  136.                 uarm->otyp <= YELLOW_DRAGON_SCALES);
  137.  
  138.     boolean iswere = (u.ulycn > -1 || is_were(uasmon));
  139.     boolean isvamp = (u.usym == S_VAMPIRE || u.umonnum == PM_VAMPIRE_BAT);
  140.  
  141.     if(!Polymorph_control && !draconian && !iswere && !isvamp) {
  142.         if (rn2(20) > ACURR(A_CON)) {
  143.         You(shudder_for_moment);
  144.         losehp(rn2(30),"system shock", KILLED_BY_AN);
  145.         exercise(A_CON, FALSE);
  146.         return;
  147.         }
  148.     }
  149.  
  150.     if (Polymorph_control) {
  151.         do {
  152.             getlin("Become what kind of monster? [type the name]",
  153.                 buf);
  154.             mntmp = name_to_mon(buf);
  155.             if (mntmp < 0)
  156.                 pline("I've never heard of such monsters.");
  157.             /* Note:  humans are illegal as monsters, but an
  158.              * illegal monster forces newman(), which is what we
  159.              * want if they specified a human.... */
  160.             else if (!polyok(&mons[mntmp]) &&
  161.                 ((pl_character[0] == 'E') ? !is_elf(&mons[mntmp])
  162.                         : !is_human(&mons[mntmp])) )
  163.                 You("cannot polymorph into that.");
  164.             else break;
  165.         } while(++tries < 5);
  166.         if (tries==5) pline(thats_enough_tries);
  167.         /* allow skin merging, even when polymorph is controlled */
  168.         if (draconian &&
  169.             (mntmp == armor_to_dragon(uarm->otyp) || tries == 5))
  170.             goto do_merge;
  171.     } else if (draconian || iswere || isvamp) {
  172.         /* special changes that don't require polyok() */
  173.         if (draconian) {
  174.             do_merge:
  175.             mntmp = armor_to_dragon(uarm->otyp);
  176.             if (!(mons[mntmp].geno & G_GENOD)) {
  177.                 /* allow G_EXTINCT */
  178.                 You("merge with your scaly armor.");
  179.                 uskin = uarm;
  180.                 uarm = (struct obj *)0;
  181.             }
  182.         } else if (iswere) {
  183.             if (is_were(uasmon))
  184.                 mntmp = PM_HUMAN; /* Illegal; force newman() */
  185.             else
  186.                 mntmp = u.ulycn;
  187.         } else {
  188.             if (u.usym == S_VAMPIRE)
  189.                 mntmp = PM_VAMPIRE_BAT;
  190.             else
  191.                 mntmp = PM_VAMPIRE;
  192.         }
  193.         if (polymon(mntmp))
  194.             return;
  195.     }
  196.  
  197.     if (mntmp < 0) {
  198.         tries = 0;
  199.         do {
  200.             mntmp = rn2(PM_ARCHEOLOGIST);
  201.             /* All valid monsters are from 0 to PM_ARCHEOLOGIST-1 */
  202.         } while(!polyok(&mons[mntmp]) && tries++ < 200);
  203.     }
  204.  
  205.     /* The below polyok() fails either if everything is genocided, or if
  206.      * we deliberately chose something illegal to force newman().
  207.      */
  208.     if (!polyok(&mons[mntmp]) || !rn2(5))
  209.         newman();
  210.     else if(!polymon(mntmp)) return;
  211.  
  212.     if (!uarmg) selftouch("No longer petrify-resistant, you");
  213. }
  214.  
  215. /* (try to) make a mntmp monster out of the player */
  216. int
  217. polymon(mntmp)    /* returns 1 if polymorph successful */
  218. int    mntmp;
  219. {
  220.     boolean sticky = sticks(uasmon) && u.ustuck && !u.uswallow;
  221.     boolean dochange = FALSE;
  222.     int    tmp;
  223.  
  224.     if (mons[mntmp].geno & G_GENOD) {    /* allow G_EXTINCT */
  225.         You("feel rather %s-ish.",mons[mntmp].mname);
  226.         exercise(A_WIS, TRUE);
  227.         return(0);
  228.     }
  229.  
  230.     if (u.umonnum == -1) {
  231.         /* Human to monster; save human stats */
  232.         u.macurr = u.acurr;
  233.         u.mamax = u.amax;
  234.         u.mfemale = flags.female;
  235.     } else {
  236.         /* Monster to monster; restore human stats, to be
  237.          * immediately changed to provide stats for the new monster
  238.          */
  239.         u.acurr = u.macurr;
  240.         u.amax = u.mamax;
  241.         flags.female = u.mfemale;
  242.     }
  243.  
  244.     if (is_male(&mons[mntmp])) {
  245.         if(flags.female) dochange = TRUE;
  246.     } else if (is_female(&mons[mntmp])) {
  247.         if(!flags.female) dochange = TRUE;
  248.     } else if (!is_neuter(&mons[mntmp]) && mntmp != u.ulycn) {
  249.         if(!rn2(10)) dochange = TRUE;
  250.     }
  251.     if (dochange) {
  252.         flags.female = !flags.female;
  253.         You("%s %s %s!",
  254.             (u.umonnum != mntmp) ? "turn into a" : "feel like a new",
  255.             flags.female ? "female" : "male",
  256.             mons[mntmp].mname);
  257.     } else {
  258.         if (u.umonnum != mntmp)
  259.             You("turn into %s!", an(mons[mntmp].mname));
  260.         else
  261.             You("feel like a new %s!", mons[mntmp].mname);
  262.     }
  263.  
  264.     u.umonnum = mntmp;
  265.     u.usym = mons[mntmp].mlet;
  266.     set_uasmon();
  267.  
  268.     /* New stats for monster, to last only as long as polymorphed.
  269.      * Currently only strength gets changed.
  270.      */
  271.     if(strongmonst(&mons[mntmp])) ABASE(A_STR) = AMAX(A_STR) = 118;
  272.  
  273.     if (resists_ston(uasmon) && Stoned) { /* parnes@eniac.seas.upenn.edu */
  274.         Stoned = 0;
  275.         You("no longer seem to be petrifying.");
  276.     }
  277.     if (u.usym == S_FUNGUS && Sick) {
  278.         make_sick(0L, FALSE);
  279.         You("no longer feel sick.");
  280.     }
  281.  
  282.     if (u.usym == S_DRAGON && mntmp >= PM_GRAY_DRAGON)
  283.         u.mhmax = 8 * mons[mntmp].mlevel;
  284.     else if (is_golem(uasmon)) u.mhmax = golemhp(mntmp);
  285.     else {
  286.         /*
  287.         tmp = adj_lev(&mons[mntmp]);
  288.          * We can't do this, since there's no such thing as an
  289.          * "experience level of you as a monster" for a polymorphed
  290.          * character.
  291.          */
  292.         tmp = mons[mntmp].mlevel;
  293.         if (!tmp) u.mhmax = rnd(4);
  294.         else u.mhmax = d(tmp, 8);
  295.     }
  296.     u.mh = u.mhmax;
  297.  
  298.     u.mtimedone = rn1(500, 500);
  299.     if (u.ulevel < mons[mntmp].mlevel)
  300.     /* Low level characters can't become high level monsters for long */
  301. #ifdef DUMB
  302.         {
  303.         /* DRS/NS 2.2.6 messes up -- Peter Kendell */
  304.             int    mtd = u.mtimedone,
  305.                 ulv = u.ulevel,
  306.                 mlv = mons[mntmp].mlevel;
  307.  
  308.             u.mtimedone = mtd * ulv / mlv;
  309.         }
  310. #else
  311.         u.mtimedone = u.mtimedone * u.ulevel / mons[mntmp].mlevel;
  312. #endif
  313.  
  314.     if (uskin && mntmp != armor_to_dragon(uskin->otyp))
  315.         skinback();
  316.     break_armor();
  317.     drop_weapon(1);
  318.     if (hides_under(uasmon))
  319.         u.uundetected = OBJ_AT(u.ux, u.uy);
  320.     else
  321.         u.uundetected = 0;
  322.     newsym(u.ux,u.uy);        /* Change symbol */
  323.  
  324.     if (!sticky && !u.uswallow && u.ustuck && sticks(uasmon)) u.ustuck = 0;
  325.     else if (sticky && !sticks(uasmon)) uunstick();
  326.  
  327.     if (flags.verbose) {
  328.         static const char use_thec[] = "Use the command #%s to %s.";
  329.         static const char monsterc[] = "monster";
  330.         if (can_breathe(uasmon))
  331.         pline(use_thec,monsterc,"use your breath weapon");
  332.         if (attacktype(uasmon, AT_SPIT))
  333.         pline(use_thec,monsterc,"spit venom");
  334.         if (u.usym == S_NYMPH)
  335.         pline(use_thec,monsterc,"remove an iron ball");
  336.         if (u.usym == S_UMBER)
  337.         pline(use_thec,monsterc,"confuse monsters");
  338.         if (is_hider(uasmon))
  339.         pline(use_thec,monsterc,"hide");
  340.         if (is_were(uasmon))
  341.         pline(use_thec,monsterc,"summon help");
  342.         if (webmaker(uasmon))
  343.         pline(use_thec,monsterc,"spin a web");
  344.         if (u.umonnum == PM_GREMLIN)
  345.         pline(use_thec,monsterc,"multiply in a fountain");
  346.         if (u.usym == S_UNICORN)
  347.         pline(use_thec,monsterc,"use your horn");
  348.         if (u.umonnum == PM_MIND_FLAYER)
  349.         pline(use_thec,monsterc,"emit a mental blast");
  350.         if (uasmon->msound == MS_SHRIEK) /* worthless, actually */
  351.         pline(use_thec,monsterc,"shriek");
  352.         if ((lays_eggs(uasmon) || u.umonnum==PM_QUEEN_BEE) && flags.female)
  353.         pline(use_thec,"sit","lay an egg");
  354.     }
  355.     find_ac();
  356.     if((!Levitation && !u.ustuck && !is_flyer(uasmon) &&
  357.         (is_pool(u.ux,u.uy) || is_lava(u.ux,u.uy))) ||
  358.        (Underwater && !is_swimmer(uasmon)))
  359.         spoteffects();
  360.     if (passes_walls(uasmon) && u.utrap && u.utraptype == TT_INFLOOR) {
  361.         u.utrap = 0;
  362.         pline("The rock seems to no longer trap you.");
  363.     }
  364.     if ((amorphous(uasmon) || is_whirly(uasmon)) && Punished) {
  365.         You("slip out of the iron chain.");
  366.         unpunish();
  367.     }
  368.     flags.botl = 1;
  369.     vision_full_recalc = 1;
  370.     exercise(A_CON, FALSE);
  371.     exercise(A_WIS, TRUE);
  372.     (void) encumber_msg();
  373.     return(1);
  374. }
  375.  
  376. static void
  377. break_armor()
  378. {
  379.     register struct obj *otmp;
  380.  
  381.     if (breakarm(uasmon)) {
  382.     if ((otmp = uarm) != 0) {
  383.         if (donning(otmp)) cancel_don();
  384.         You("break out of your armor!");
  385.         exercise(A_STR, FALSE);
  386.         (void) Armor_gone();
  387.         useup(otmp);
  388.     }
  389.     if ((otmp = uarmc) != 0) {
  390.         if(otmp->oartifact) {
  391.         Your("cloak falls off!");
  392.         (void) Cloak_off();
  393.         dropx(otmp);
  394.         } else {
  395.         Your("cloak tears apart!");
  396.         (void) Cloak_off();
  397.         useup(otmp);
  398.         }
  399.     }
  400. #ifdef TOURIST
  401.     if (uarmu) {
  402.         Your("shirt rips to shreds!");
  403.         useup(uarmu);
  404.     }
  405. #endif
  406.     } else if (sliparm(uasmon)) {
  407.     if ((otmp = uarm) != 0) {
  408.         if (donning(otmp)) cancel_don();
  409.         Your("armor falls around you!");
  410.         (void) Armor_gone();
  411.         dropx(otmp);
  412.     }
  413.     if ((otmp = uarmc) != 0) {
  414.         if (is_whirly(uasmon))
  415.             Your("cloak falls, unsupported!");
  416.         else You("shrink out of your cloak!");
  417.         (void) Cloak_off();
  418.         dropx(otmp);
  419.     }
  420. #ifdef TOURIST
  421.     if ((otmp = uarmu) != 0) {
  422.         if (is_whirly(uasmon))
  423.             You("seep right through your shirt!");
  424.         else You("become much too small for your shirt!");
  425.         setworn((struct obj *)0, otmp->owornmask & W_ARMU);
  426.         dropx(otmp);
  427.     }
  428. #endif
  429.     }
  430.     if (nohands(uasmon) || verysmall(uasmon)) {
  431.     if ((otmp = uarmg) != 0) {
  432.         if (donning(otmp)) cancel_don();
  433.         /* Drop weapon along with gloves */
  434.         You("drop your gloves%s!", uwep ? " and weapon" : "");
  435.         drop_weapon(0);
  436.         (void) Gloves_off();
  437.         dropx(otmp);
  438.     }
  439.     if ((otmp = uarms) != 0) {
  440.         You("can no longer hold your shield!");
  441.         (void) Shield_off();
  442.         dropx(otmp);
  443.     }
  444.     if ((otmp = uarmh) != 0) {
  445.         if (donning(otmp)) cancel_don();
  446.         Your("helmet falls to the %s!", surface(u.ux, u.uy));
  447.         (void) Helmet_off();
  448.         dropx(otmp);
  449.     }
  450.     }
  451.     if (nohands(uasmon) || verysmall(uasmon) || slithy(uasmon) || 
  452.         u.usym == S_CENTAUR) {
  453.     if ((otmp = uarmf) != 0) {
  454.         if (donning(otmp)) cancel_don();
  455.         if (is_whirly(uasmon))
  456.         Your("boots fall away!");
  457.         else Your("boots %s off your feet!",
  458.             verysmall(uasmon) ? "slide" : "are pushed");
  459.         (void) Boots_off();
  460.         dropx(otmp);
  461.     }
  462.     }
  463. }
  464.  
  465. static void
  466. drop_weapon(alone)
  467. int alone;
  468. {
  469.      struct obj *otmp;
  470.      if ((otmp = uwep) != 0) {
  471.       /* !alone check below is currently superfluous but in the
  472.        * future it might not be so if there are monsters which cannot
  473.        * wear gloves but can wield weapons
  474.        */
  475.       if (!alone || cantwield(uasmon)) {
  476.            if (alone) You("find you must drop your weapon!");
  477.            uwepgone();
  478.            dropx(otmp);
  479.       }
  480.      }
  481. }
  482.  
  483. void
  484. rehumanize()
  485. {
  486.     polyman();
  487.     You("return to %sn form!", (pl_character[0] == 'E')? "elve" : "huma");
  488.  
  489.     if (u.uhp < 1)    done(DIED);
  490.     if (!uarmg) selftouch("No longer petrify-resistant, you");
  491.     nomul(0);
  492.  
  493.     flags.botl = 1;
  494.     vision_full_recalc = 1;
  495.     (void) encumber_msg();
  496. }
  497.  
  498. int
  499. dobreathe() {
  500.     if (Strangled) {
  501.         You("can't breathe.  Sorry.");
  502.         return(0);
  503.     }
  504.     if (!getdir(NULL)) return(0);
  505.     if (rn2(4))
  506.         You("produce a loud and noxious belch.");
  507.     else {
  508.         register struct attack *mattk;
  509.         register int i;
  510.  
  511.         for(i = 0; i < NATTK; i++) {
  512.         mattk = &(uasmon->mattk[i]);
  513.         if(mattk->aatyp == AT_BREA) break;
  514.         }
  515.         buzz((int) (20 + mattk->adtyp-1), (int)mattk->damn,
  516.         u.ux, u.uy, u.dx, u.dy);
  517.     }
  518.     return(1);
  519. }
  520.  
  521. int
  522. dospit() {
  523.     struct obj *otmp;
  524.  
  525.     if (!getdir(NULL)) return(0);
  526.     otmp = mksobj(u.umonnum==PM_COBRA ? BLINDING_VENOM : ACID_VENOM, TRUE, FALSE);
  527.     otmp->spe = 1; /* to indicate it's yours */
  528.     (void) throwit(otmp);
  529.     return(1);
  530. }
  531.  
  532. int
  533. doremove() {
  534.     if (!Punished) {
  535.         You("are not chained to anything!");
  536.         return(0);
  537.     }
  538.     unpunish();
  539.     return(1);
  540. }
  541.  
  542. int
  543. dospinweb()
  544. {
  545.     register struct trap *ttmp = t_at(u.ux,u.uy);
  546.  
  547.     if (Levitation || Is_airlevel(&u.uz)
  548.         || Underwater || Is_waterlevel(&u.uz)) {
  549.         You("must be on the ground to spin a web.");
  550.         return(0);
  551.     }
  552.     if (u.uswallow) {
  553.         You("release web fluid inside %s.", mon_nam(u.ustuck));
  554.         if (is_animal(u.ustuck->data)) {
  555.             expels(u.ustuck, u.ustuck->data, TRUE);
  556.             return(0);
  557.         }
  558.         if (is_whirly(u.ustuck->data)) {
  559.             int i;
  560.  
  561.             for (i = 0; i < NATTK; i++)
  562.                 if (u.ustuck->data->mattk[i].aatyp == AT_ENGL)
  563.                     break;
  564.             if (i == NATTK)
  565.                    impossible("Swallower has no engulfing attack?");
  566.             else {
  567.                 char sweep[30];
  568.  
  569.                 sweep[0] = '\0';
  570.                 switch(u.ustuck->data->mattk[i].adtyp) {
  571.                     case AD_FIRE:
  572.                         Strcpy(sweep, "ignites and ");
  573.                         break;
  574.                     case AD_ELEC:
  575.                         Strcpy(sweep, "fries and ");
  576.                         break;
  577.                     case AD_COLD:
  578.                         Strcpy(sweep,
  579.                               "freezes, shatters and ");
  580.                         break;
  581.                 }
  582.                 pline("The web %sis swept away!", sweep);
  583.             }
  584.             return(0);
  585.         }             /* default: a nasty jelly-like creature */
  586.         pline("The web dissolves into %s.", mon_nam(u.ustuck));
  587.         return(0);
  588.     }
  589.     if (u.utrap) {
  590.         You("cannot spin webs while stuck in a trap.");
  591.         return(0);
  592.     }
  593.     exercise(A_DEX, TRUE);
  594.     if (ttmp) switch (ttmp->ttyp) {
  595.         case PIT:
  596.         case SPIKED_PIT: You("spin a web, covering up the pit.");
  597.             deltrap(ttmp);
  598.             bury_objs(u.ux, u.uy);
  599.             if (Invisible) newsym(u.ux, u.uy);
  600.             return(1);
  601.         case SQKY_BOARD: pline("The squeaky board is muffled.");
  602.             deltrap(ttmp);
  603.             if (Invisible) newsym(u.ux, u.uy);
  604.             return(1);
  605.         case TELEP_TRAP:
  606.         case LEVEL_TELEP:
  607.         case MAGIC_PORTAL:
  608.             Your("webbing vanishes!");
  609.             return(0);
  610.         case WEB: You("make the web thicker.");
  611.             return(1);
  612.         case TRAPDOOR:
  613.             You("web over the trap door.");
  614.             deltrap(ttmp);
  615.             if (Invisible) newsym(u.ux, u.uy);
  616.             return 1;
  617.         case ARROW_TRAP:
  618.         case DART_TRAP:
  619.         case BEAR_TRAP:
  620.         case LANDMINE:
  621.         case SLP_GAS_TRAP:
  622.         case RUST_TRAP:
  623.         case MAGIC_TRAP:
  624.         case ANTI_MAGIC:
  625.         case POLY_TRAP:
  626.             You("have triggered a trap!");
  627.             dotrap(ttmp);
  628.             return(1);
  629.         default:
  630.             impossible("Webbing over trap type %d?", ttmp->ttyp);
  631.             return(0);
  632.     }
  633.     ttmp = maketrap(u.ux, u.uy, WEB);
  634.     if (ttmp) ttmp->tseen = 1;
  635.     if (Invisible) newsym(u.ux, u.uy);
  636.     return(1);
  637. }
  638.  
  639. int
  640. dosummon()
  641. {
  642.     You("call upon your brethren for help!");
  643.     exercise(A_WIS, TRUE);
  644.     if (!were_summon(uasmon,TRUE))
  645.         pline("But none arrive.");
  646.     return(1);
  647. }
  648.  
  649. int
  650. doconfuse()
  651. {
  652.     register struct monst *mtmp;
  653.     int looked = 0;
  654.     char qbuf[QBUFSZ];
  655.  
  656.     if (Blind) {
  657.         You("can't see anything to gaze at.");
  658.         return 0;
  659.     }
  660.     for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
  661.         if (canseemon(mtmp)) {
  662.         looked = 1;
  663.         if (Invis && !perceives(mtmp->data))
  664.             pline("%s seems not to notice your gaze.", Monnam(mtmp));
  665.         else if (mtmp->minvis && !See_invisible)
  666.             You("can't see where to gaze at %s.", Monnam(mtmp));
  667.         else if (mtmp->m_ap_type == M_AP_FURNITURE
  668.             || mtmp->m_ap_type == M_AP_OBJECT)
  669.             continue;
  670.         else if (flags.safe_dog && !Confusion && !Hallucination
  671.           && mtmp->mtame) {
  672.             if (mtmp->mnamelth)
  673.             You("avoid gazing at %s.", NAME(mtmp));
  674.             else
  675.             You("avoid gazing at your %s.",
  676.                         mtmp->data->mname);
  677.         } else {
  678.             if (flags.confirm && mtmp->mpeaceful && !Confusion
  679.                             && !Hallucination) {
  680.             Sprintf(qbuf, "Really confuse %s?", mon_nam(mtmp));
  681.             if (yn(qbuf) != 'y') continue;
  682.             setmangry(mtmp);
  683.             }
  684.             if (!mtmp->mcanmove || mtmp->mstun || mtmp->msleep ||
  685.                     !mtmp->mcansee || !haseyes(mtmp->data))
  686.             continue;
  687. #ifdef MUSE
  688.             if (!mon_reflects(mtmp, "Your gaze is reflected by %s %s."))
  689. #endif
  690.             if (!mtmp->mconf)
  691.             Your("gaze confuses %s!", mon_nam(mtmp));
  692.             else
  693.             pline("%s is getting more and more confused.",
  694.                             Monnam(mtmp));
  695.             mtmp->mconf = 1;
  696.             if ((mtmp->data==&mons[PM_FLOATING_EYE]) && !mtmp->mcan) {
  697.             You("are frozen by %s gaze!", 
  698.                              s_suffix(mon_nam(mtmp)));
  699.             nomul((u.ulevel > 6 || rn2(4)) ?
  700.                 -d((int)mtmp->m_lev+1,
  701.                     (int)mtmp->data->mattk[0].damd)
  702.                 : -200);
  703.             return 1;
  704.             }
  705.             if ((mtmp->data==&mons[PM_MEDUSA]) && !mtmp->mcan) {
  706.             pline("Gazing at the awake Medusa is not a very good idea.");
  707.             /* as if gazing at a sleeping anything is fruitful... */
  708.             You("turn to stone...");
  709.             done(STONING);
  710.             }
  711.         }
  712.         }
  713.     }
  714.     if (!looked) You("gaze at no place in particular.");
  715.     return 1;
  716. }
  717.  
  718. int
  719. dohide()
  720. {
  721.     if (u.uundetected || u.usym == S_MIMIC_DEF) {
  722.         You("are already hiding.");
  723.         return(0);
  724.     }
  725.     if (u.usym == S_MIMIC) {
  726.         u.usym = S_MIMIC_DEF;
  727.     } else {
  728.         u.uundetected = 1;
  729.     }
  730.     newsym(u.ux,u.uy);
  731.     return(1);
  732. }
  733.  
  734. int
  735. domindblast()
  736. {
  737.     struct monst *mtmp, *nmon;
  738.  
  739.     You("concentrate.");
  740.     if (rn2(3)) return 0;
  741.     pline("A wave of psychic energy pours out.");
  742.     for(mtmp=fmon; mtmp; mtmp = nmon) {
  743.         int u_sen;
  744.  
  745.         nmon = mtmp->nmon;
  746.         if (distu(mtmp->mx, mtmp->my) > BOLT_LIM * BOLT_LIM)
  747.             continue;
  748.         if(mtmp->mpeaceful)
  749.             continue;
  750.         u_sen = telepathic(mtmp->data) && !mtmp->mcansee;
  751.         if (u_sen || (telepathic(mtmp->data) && rn2(2)) || !rn2(10)) {
  752.             pline("You lock in on %s's %s.", mon_nam(mtmp),
  753.                 u_sen ? "telepathy" :
  754.                 telepathic(mtmp->data) ? "latent telepathy" :
  755.                 "mind");
  756.             mtmp->mhp -= rnd(15);
  757.             if (mtmp->mhp <= 0)
  758.                 killed(mtmp);
  759.         }
  760.     }
  761.     return 1;
  762. }
  763.  
  764. static void
  765. uunstick()
  766. {
  767.     pline("%s is no longer in your clutches.", Monnam(u.ustuck));
  768.     u.ustuck = 0;
  769. }
  770.  
  771. static void
  772. skinback()
  773. {
  774.     if (uskin) {
  775.         Your("skin returns to its original form.");
  776.         uarm = uskin;
  777.         uskin = (struct obj *)0;
  778.     }
  779. }
  780. #endif
  781.  
  782. #endif /* OVLB */
  783. #ifdef OVL1
  784. const char *
  785. body_part(part)
  786. int part;
  787. {
  788.     /* Note: it is assumed these will never be >22 characters long,
  789.      * plus the trailing null, after pluralizing (since sometimes a
  790.      * buffer is made a fixed size and must be able to hold it)
  791.      */
  792.     static NEARDATA const char *humanoid_parts[] = { "arm", "eye", "face", "finger",
  793.         "fingertip", "foot", "hand", "handed", "head", "leg",
  794.         "light headed", "neck", "spine", "toe" };
  795. #ifdef POLYSELF
  796.     static NEARDATA const char *jelly_parts[] = { "pseudopod", "dark spot", "front",
  797.         "pseudopod extension", "pseudopod extremity",
  798.         "pseudopod root", "grasp", "grasped", "cerebral area",
  799.         "lower pseudopod", "viscous", "middle", "surface",
  800.         "pseudopod extremity" },
  801.     *animal_parts[] = { "forelimb", "eye", "face", "foreclaw", "claw tip",
  802.         "rear claw", "foreclaw", "clawed", "head", "rear limb",
  803.         "light headed", "neck", "spine", "rear claw tip" },
  804.     *horse_parts[] = { "forelimb", "eye", "face", "forehoof", "hoof tip",
  805.         "rear hoof", "foreclaw", "hooved", "head", "rear limb",
  806.         "light headed", "neck", "backbone", "rear hoof tip" },
  807.     *sphere_parts[] = { "appendage", "optic nerve", "body", "tentacle",
  808.         "tentacle tip", "lower appendage", "tentacle", "tentacled",
  809.         "body", "lower tentacle", "rotational", "equator", "body",
  810.         "lower tentacle tip" },
  811.     *fungus_parts[] = { "mycelium", "visual area", "front", "hypha",
  812.         "hypha", "root", "strand", "stranded", "cap area",
  813.         "rhizome", "sporulated", "stalk", "root", "rhizome tip" },
  814.     *vortex_parts[] = { "region", "eye", "front", "minor current",
  815.         "minor current", "lower current", "swirl", "swirled",
  816.         "central core", "lower current", "addled", "center",
  817.         "currents", "edge" },
  818.     *snake_parts[] = { "vestigial limb", "eye", "face", "large scale",
  819.         "large scale tip", "rear region", "scale gap", "scale gapped",
  820.         "head", "rear region", "light headed", "neck", "length",
  821.         "rear scale" };
  822.  
  823.     if (humanoid(uasmon) && (part==ARM || part==FINGER || part==FINGERTIP
  824.         || part==HAND || part==HANDED)) return humanoid_parts[part];
  825.     if (u.usym==S_CENTAUR || u.usym==S_UNICORN) return horse_parts[part];
  826.     if (slithy(uasmon)) return snake_parts[part];
  827.     if (u.usym==S_EYE) return sphere_parts[part];
  828.     if (u.usym==S_JELLY || u.usym==S_PUDDING || u.usym==S_BLOB)
  829.         return jelly_parts[part];
  830.     if (u.usym==S_VORTEX || u.usym==S_ELEMENTAL) return vortex_parts[part];
  831.     if (u.usym==S_FUNGUS) return fungus_parts[part];
  832.     if (humanoid(uasmon)) return humanoid_parts[part];
  833.     return animal_parts[part];
  834. #else
  835.     return humanoid_parts[part];
  836. #endif
  837. }
  838.  
  839. #endif /* OVL1 */
  840. #ifdef OVL0
  841.  
  842. int
  843. poly_gender()
  844. {
  845. /* Returns gender of polymorphed player; 0/1=same meaning as flags.female,
  846.  * 2=none.
  847.  * Used in:
  848.  *    - Seduction by succubus/incubus
  849.  *    - Talking to nymphs (sounds.c)
  850.  * Not used in:
  851.  *    - Messages given by nymphs stealing armor (they can't steal from
  852.  *      incubi/succubi/nymphs, and nonhumanoids can't wear armor).
  853.  *    - Amulet of change (must refer to real gender no matter what
  854.  *      polymorphed into).
  855.  *    - Priest/Priestess, Caveman/Cavewoman (ditto)
  856.  *    - Polymorph self (only happens when human)
  857.  *    - Shopkeeper messages (since referred to as "creature" and not "sir"
  858.  *      or "lady" when polymorphed)
  859.  */
  860. #ifdef POLYSELF
  861.     if (!humanoid(uasmon)) return 2;
  862. #endif
  863.     return flags.female;
  864. }
  865.  
  866. #endif /* OVL0 */
  867. #ifdef OVLB
  868.  
  869. #if defined(POLYSELF)
  870. void
  871. ugolemeffects(damtype, dam)
  872. int damtype, dam;
  873. {
  874.     int heal = 0;
  875.     /* We won't bother with "slow"/"haste" since players do not
  876.      * have a monster-specific slow/haste so there is no way to
  877.      * restore the old velocity once they are back to human.
  878.      */
  879.     if (u.umonnum != PM_FLESH_GOLEM && u.umonnum != PM_IRON_GOLEM)
  880.         return;
  881.     switch (damtype) {
  882.         case AD_ELEC: if (u.umonnum == PM_IRON_GOLEM)
  883.                 heal = dam / 6; /* Approx 1 per die */
  884.             break;
  885.         case AD_FIRE: if (u.umonnum == PM_IRON_GOLEM)
  886.                 heal = dam;
  887.             break;
  888.     }
  889.     if (heal && (u.mh < u.mhmax)) {
  890.         u.mh += heal;
  891.         if (u.mh > u.mhmax) u.mh = u.mhmax;
  892.         flags.botl = 1;
  893.         pline("Strangely, you feel better than before.");
  894.         exercise(A_STR, TRUE);
  895.     }
  896. }
  897.  
  898. static int
  899. armor_to_dragon(atyp)
  900. int atyp;
  901. {
  902.     switch(atyp) {
  903.         case GRAY_DRAGON_SCALE_MAIL:
  904.         case GRAY_DRAGON_SCALES:
  905.         return PM_GRAY_DRAGON;
  906.         case RED_DRAGON_SCALE_MAIL:
  907.         case RED_DRAGON_SCALES:
  908.         return PM_RED_DRAGON;
  909.         case ORANGE_DRAGON_SCALE_MAIL:
  910.         case ORANGE_DRAGON_SCALES:
  911.         return PM_ORANGE_DRAGON;
  912.         case WHITE_DRAGON_SCALE_MAIL:
  913.         case WHITE_DRAGON_SCALES:
  914.         return PM_WHITE_DRAGON;
  915.         case BLACK_DRAGON_SCALE_MAIL:
  916.         case BLACK_DRAGON_SCALES:
  917.         return PM_BLACK_DRAGON;
  918.         case BLUE_DRAGON_SCALE_MAIL:
  919.         case BLUE_DRAGON_SCALES:
  920.         return PM_BLUE_DRAGON;
  921.         case GREEN_DRAGON_SCALE_MAIL:
  922.         case GREEN_DRAGON_SCALES:
  923.         return PM_GREEN_DRAGON;
  924.         case YELLOW_DRAGON_SCALE_MAIL:
  925.         case YELLOW_DRAGON_SCALES:
  926.         return PM_YELLOW_DRAGON;
  927.         default:
  928.         return -1;
  929.     }
  930. }
  931. #endif /* POLYSELF */
  932.  
  933. #endif /* OVLB */
  934.  
  935. /*polyself.c*/
  936.