home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / games / volume2 / umoria / part05 / moria1.c < prev   
C/C++ Source or Header  |  1987-11-04  |  45KB  |  1,999 lines

  1. #include <stdio.h>
  2. #ifdef USG
  3. #include <string.h>
  4. #else
  5. #include <strings.h>
  6. #endif
  7.  
  8. #include "constants.h"
  9. #include "types.h"
  10. #include "externs.h"
  11.  
  12. #ifdef sun   /* correct SUN stupidity in the stdio.h file */
  13. char *sprintf();
  14. #endif
  15.  
  16. byteint de_statt();
  17. byteint in_statt();
  18.  
  19. /* global flags */
  20. extern int moria_flag;        /* Next level when true  */
  21. extern int search_flag;       /* Player is searching   */
  22. extern int teleport_flag;     /* Handle teleport traps  */
  23. extern int player_light;      /* Player carrying light */
  24. extern int cave_flag;         /* used in get_panel */
  25. extern int light_flag;        /* used in move_light */
  26.  
  27.  
  28. /* Changes stats up or down for magic items        -RAK-    */
  29. change_stat_factor(stat, amount, factor)
  30. byteint *stat;
  31. int amount, factor;
  32. {
  33.   int i, j, k;
  34.  
  35.   j = amount * factor;
  36.   k = abs(amount);
  37.   for (i = 0; i < k; i++)
  38.     if (j < 0) 
  39.       *stat = de_statt(*stat);
  40.     else
  41.       *stat = in_statt(*stat);
  42. }
  43.  
  44.  
  45. /* Changes speed of monsters relative to player        -RAK-    */
  46. /* Note: When the player is sped up or slowed down, I simply     */
  47. /*       change the speed of all the monsters.  This greatly     */
  48. /*       simplified the logic...                                 */
  49. change_speed(num)
  50. int num;
  51. {
  52.   int i;
  53.  
  54.   py.flags.speed += num;
  55.   i = muptr;
  56.   while (i > 0)
  57.     {
  58.       m_list[i].cspeed += num;
  59.       i = m_list[i].nptr;
  60.     }
  61. }
  62.  
  63.  
  64. /* Player bonuses                    -RAK-    */
  65. /* When an item is worn or taken off, this re-adjusts the player */
  66. /* bonuses.  Factor==1 : wear; Factor==-1 : removed                */
  67. py_bonuses(tobj, factor)
  68. treasure_type tobj;
  69. int factor;
  70. {
  71.   unsigned int item_flags;
  72.   int i, old_dis_ac;
  73.   struct flags *p_ptr;
  74.   struct misc *m_ptr;
  75.   treasure_type *i_ptr;
  76.  
  77.   p_ptr = &py.flags;
  78.   if (p_ptr->slow_digest) 
  79.     p_ptr->food_digested++;
  80.   if (p_ptr->regenerate) 
  81.     p_ptr->food_digested -= 3;
  82.   p_ptr->see_inv     = FALSE;
  83.   p_ptr->teleport    = FALSE;
  84.   p_ptr->free_act    = FALSE;
  85.   p_ptr->slow_digest = FALSE;
  86.   p_ptr->aggravate   = FALSE;
  87.   p_ptr->sustain_str = FALSE;
  88.   p_ptr->sustain_int = FALSE;
  89.   p_ptr->sustain_wis = FALSE;
  90.   p_ptr->sustain_con = FALSE;
  91.   p_ptr->sustain_dex = FALSE;
  92.   p_ptr->sustain_chr = FALSE;
  93.   p_ptr->fire_resist = FALSE;
  94.   p_ptr->acid_resist = FALSE;
  95.   p_ptr->cold_resist = FALSE;
  96.   p_ptr->regenerate  = FALSE;
  97.   p_ptr->lght_resist = FALSE;
  98.   p_ptr->ffall       = FALSE;
  99.  
  100.   if (0x00000001 & tobj.flags)
  101.     {
  102.       change_stat_factor(&py.stats.cstr, tobj.p1, factor);
  103.       change_stat_factor(&py.stats.str, tobj.p1, factor);
  104.       print_stat = (0x0001 | print_stat);
  105.     }
  106.   if (0x00000002 & tobj.flags)
  107.     {
  108.       change_stat_factor(&py.stats.cdex, tobj.p1, factor);
  109.       change_stat_factor(&py.stats.dex, tobj.p1, factor);
  110.       print_stat = (0x0002 | print_stat);
  111.     }
  112.   if (0x00000004 & tobj.flags)
  113.     {
  114.       change_stat_factor(&py.stats.ccon, tobj.p1, factor);
  115.       change_stat_factor(&py.stats.con, tobj.p1, factor);
  116.       print_stat = (0x0004 | print_stat);
  117.     }
  118.   if (0x00000008 & tobj.flags)
  119.     {
  120.       change_stat_factor(&py.stats.cint, tobj.p1, factor);
  121.       change_stat_factor(&py.stats.intel, tobj.p1, factor);
  122.       print_stat = (0x0008 | print_stat);
  123.     }
  124.   if (0x00000010 & tobj.flags)
  125.     {
  126.       change_stat_factor(&py.stats.cwis, tobj.p1, factor);
  127.       change_stat_factor(&py.stats.wis, tobj.p1, factor);
  128.       print_stat = (0x0010 | print_stat);
  129.     }
  130.   if (0x00000020 & tobj.flags)
  131.     {
  132.       change_stat_factor(&py.stats.cchr, tobj.p1, factor);
  133.       change_stat_factor(&py.stats.chr, tobj.p1, factor);
  134.       print_stat = (0x0020 | print_stat);
  135.     }
  136.   if (0x00000040 & tobj.flags)
  137.     {
  138.       py.misc.srh += (tobj.p1 * factor);
  139.       py.misc.fos -= (tobj.p1 * factor);
  140.     }
  141.   if (0x00000100 & tobj.flags)
  142.     py.misc.stl += 2*factor;
  143.   if (0x00001000 & tobj.flags)
  144.     {
  145.       i = tobj.p1*factor;
  146.       change_speed(-i);
  147.     }
  148.   if (0x08000000 & tobj.flags)
  149.     if (factor > 0) 
  150.       py.flags.blind += 1000;
  151.   if (0x10000000 & tobj.flags)
  152.     if (factor > 0) 
  153.       py.flags.afraid += 50;
  154.   if (0x40000000 & tobj.flags)
  155.     py.flags.see_infra += (tobj.p1 * factor);
  156.   m_ptr = &py.misc;
  157.   old_dis_ac = m_ptr->dis_ac;
  158.   m_ptr->ptohit  = tohit_adj();       /* Real To Hit   */
  159.   m_ptr->ptodam  = todam_adj();       /* Real To Dam   */
  160.   m_ptr->ptoac   = toac_adj();        /* Real To AC    */
  161.   m_ptr->pac     = 0;               /* Real AC       */
  162.   m_ptr->dis_th  = m_ptr->ptohit;  /* Display To Hit        */
  163.   m_ptr->dis_td  = m_ptr->ptodam;  /* Display To Dam        */
  164.   m_ptr->dis_ac  = 0;       /* Display To AC         */
  165.   m_ptr->dis_tac = m_ptr->ptoac;   /* Display AC            */
  166.   for (i = 22; i < INVEN_MAX-2; i++)
  167.     {
  168.       i_ptr = &inventory[i];
  169.       if (i_ptr->tval != 0) 
  170.     {
  171.       if ((0x80000000 & i_ptr->flags) == 0) 
  172.         {
  173.           m_ptr->pac += i_ptr->ac;
  174.           m_ptr->dis_ac += i_ptr->ac;
  175.         }
  176.       m_ptr->ptohit += i_ptr->tohit;
  177.       m_ptr->ptodam += i_ptr->todam;
  178.       m_ptr->ptoac  += i_ptr->toac;
  179.       if (index(i_ptr->name, '^') == 0) 
  180.         {
  181.           m_ptr->dis_th  += i_ptr->tohit;
  182.           m_ptr->dis_td  += i_ptr->todam;
  183.           m_ptr->dis_tac += i_ptr->toac;
  184.         }
  185.     }
  186.     }
  187.   m_ptr->dis_ac += m_ptr->dis_tac;
  188.  
  189.   /* Add in temporary spell increases    */
  190.   p_ptr = &py.flags;
  191.   if (p_ptr->invuln > 0) 
  192.     {
  193.       m_ptr->pac += 100;
  194.       m_ptr->dis_ac += 100;
  195.     }
  196.   if (p_ptr->blessed > 0) 
  197.     {
  198.       m_ptr->pac    += 2;
  199.       m_ptr->dis_ac += 2;
  200.     }
  201.   if (p_ptr->detect_inv > 0) 
  202.     p_ptr->see_inv = TRUE;
  203.   
  204.   if (old_dis_ac != m_ptr->dis_ac) 
  205.     print_stat = (0x0040 | print_stat);
  206.   
  207.   item_flags = 0;
  208.   for (i = 22; i < INVEN_MAX-2; i++)
  209.     {
  210.       i_ptr = &inventory[i];
  211.       item_flags |= i_ptr->flags;
  212.     }
  213.   if (0x00000080 & item_flags)
  214.     py.flags.slow_digest = TRUE;
  215.   if (0x00000200 & item_flags)
  216.     py.flags.aggravate = TRUE;
  217.   if (0x00000400 & item_flags)
  218.     py.flags.teleport = TRUE;
  219.   if (0x00000800 & item_flags)
  220.     py.flags.regenerate = TRUE;
  221.   if (0x00080000 & item_flags)
  222.     py.flags.fire_resist = TRUE;
  223.   if (0x00100000 & item_flags)
  224.     py.flags.acid_resist = TRUE;
  225.   if (0x00200000 & item_flags)
  226.     py.flags.cold_resist = TRUE;
  227.   if (0x00800000 & item_flags)
  228.     py.flags.free_act = TRUE;
  229.   if (0x01000000 & item_flags)
  230.     py.flags.see_inv = TRUE;
  231.   if (0x02000000 & item_flags)
  232.     py.flags.lght_resist = TRUE;
  233.   if (0x04000000 & item_flags)
  234.     py.flags.ffall = TRUE;
  235.  
  236.   for (i = 22; i < INVEN_MAX-2; i++)
  237.     {
  238.       i_ptr = &inventory[i];
  239.       if (0x00400000 & i_ptr->flags)
  240.     switch(i_ptr->p1)
  241.       {
  242.       case 1: py.flags.sustain_str = TRUE; break;
  243.       case 2: py.flags.sustain_int = TRUE; break;
  244.       case 3: py.flags.sustain_wis = TRUE; break;
  245.       case 4: py.flags.sustain_con = TRUE; break;
  246.       case 5: py.flags.sustain_dex = TRUE; break;
  247.       case 6: py.flags.sustain_chr = TRUE; break;
  248.       default: break;
  249.       }
  250.     }
  251.  
  252.   p_ptr = &py.flags;
  253.   if (p_ptr->slow_digest) 
  254.     p_ptr->food_digested--;
  255.   if (p_ptr->regenerate) 
  256.     p_ptr->food_digested += 3;
  257. }
  258.  
  259.  
  260. /* Returns a "*" for cursed items, a ")" for normal ones -RAK-    */
  261. /* NOTE: "*" returned only if item has been identified...        */
  262. char cur_char1(item_val)
  263. int item_val;
  264. {
  265.   treasure_type *i_ptr;
  266.  
  267.   i_ptr = &inventory[item_val];
  268.   if ((0x80000000 & i_ptr->flags) == 0) 
  269.     return(')');    /* Not cursed...                 */
  270.   else if (index(i_ptr->name, '^') != 0) 
  271.     return(')');    /* Cursed, but not identified    */
  272.   else
  273.     return('*');   /* Cursed and identified...      */
  274. }
  275.  
  276.  
  277. /* Returns a "*" for cursed items, a ")" for normal ones -RAK-    */
  278. char cur_char2(item_val)
  279. int item_val;
  280. {
  281.   treasure_type *i_ptr;
  282.  
  283.   i_ptr = &inventory[item_val];
  284.   if ((0x80000000 & i_ptr->flags) == 0) 
  285.     return(')');    /* Not cursed... */
  286.   else
  287.     return('*');   /* Cursed...     */
  288. }
  289.  
  290.  
  291. /* inventory functions, define some global variables here */
  292. int scr_state;
  293.  
  294. /* Displays inventory items from r1 to r2    -RAK-    */
  295. show_inven(r1, r2)
  296. int r1, r2;
  297. {
  298.   int i;
  299.   vtype tmp_val, out_val;
  300.  
  301.   if (r1 >= 0)                       /* R1 == 0 dummy call     */
  302.     {
  303.       for (i = r1; i <= r2; i++)             /* Print the items       */
  304.     {
  305.       objdes(tmp_val, i, TRUE);
  306.       (void) sprintf(out_val, "%c%c %s", i+97, cur_char1(i), tmp_val);
  307.       prt(out_val, i+1, 0);
  308.     }
  309.       if (r2 < 22)
  310.     prt("", r2+2, 0); /* Clear line after      */
  311.       scr_state = 1;                   /* Set state to 1        */
  312.     }
  313. }
  314.  
  315. /* Displays equipment items from r1 to end    -RAK-    */
  316. show_equip(r1)
  317. int r1;
  318. {
  319.   int i, j;
  320.   vtype prt1, prt2, out_val;
  321.   treasure_type *i_ptr;
  322.  
  323.   if (r1 >= equip_ctr)       /* Last item gone                */
  324.     prt("", equip_ctr+2, 0);
  325.   else if (r1 >= 0)          /* R1 == 0 dummy call             */
  326.     {
  327.       j = 0;
  328.       for (i = 22; i < INVEN_MAX; i++) /* Range of equipment        */
  329.     {
  330.       i_ptr = &inventory[i];
  331.       if (i_ptr->tval != 0) 
  332.         {
  333.           if (j >= r1) /* Display only given range    */
  334.         {
  335.           switch(i)          /* Get position          */
  336.             {
  337.             case 22:
  338.               (void) strcpy(prt1, " You are wielding   : "); break;
  339.             case 23:
  340.               (void) strcpy(prt1, " Worn on head       : "); break;
  341.             case 24:
  342.               (void) strcpy(prt1, " Worn around neck   : "); break;
  343.             case 25:
  344.               (void) strcpy(prt1, " Worn on body       : "); break;
  345.             case 26:
  346.               (void) strcpy(prt1, " Worn on arm        : "); break;
  347.             case 27:
  348.               (void) strcpy(prt1, " Worn on hands      : "); break;
  349.             case 28:
  350.               (void) strcpy(prt1, " Worn on right hand : "); break;
  351.             case 29:
  352.               (void) strcpy(prt1, " Worn on left hand  : "); break;
  353.             case 30:
  354.               (void) strcpy(prt1, " Worn on feet       : "); break;
  355.             case 31:
  356.               (void) strcpy(prt1, " Worn about body    : "); break;
  357.             case 32:
  358.               (void) strcpy(prt1, " Light source       : "); break;
  359.             case 33:
  360.               (void) strcpy(prt1, " Secondary weapon   : "); break;
  361.             default:
  362.               (void) strcpy(prt1, " Unknown value      : "); break;
  363.             }
  364.           objdes(prt2, i, TRUE);
  365.           (void) sprintf(out_val,
  366.                  "%c%c%s%s", j+97, cur_char2(i), prt1, prt2);
  367.           prt(out_val, j+2, 0);
  368.         }
  369.           j++;
  370.         }
  371.     }
  372.       prt("", j+2, 0);   /* Clear last line       */
  373.       scr_state = 2;   /* Set state of screen   */
  374.     }
  375. }
  376.  
  377. /* Remove item from equipment list        -RAK-    */
  378. int remove(item_val)
  379. int item_val;
  380. {
  381.   int i, j, typ;
  382.   vtype out_val, prt1, prt2;
  383.   int flag;
  384.   treasure_type *i_ptr;
  385.  
  386.   i = 0;
  387.   flag = FALSE;
  388.   typ  = inventory[item_val].tval;
  389.   do
  390.     {
  391.       i_ptr = &inventory[i];
  392.       if (typ > i_ptr->tval) 
  393.     {
  394.       for (j = inven_ctr-1; j >= i; j--)
  395.         inventory[j+1] = inventory[j];
  396.       inventory[i]  = inventory[item_val];
  397.       inven_ctr++;
  398.       equip_ctr--;
  399.       flag = TRUE;
  400.     }
  401.       i++;
  402.     }
  403.   while (!flag);
  404.   i--;
  405.   switch(typ)
  406.     {
  407.     case 10: case 11: case 12: case 20: case 21: case 22: case 23: case 25 :
  408.       (void) strcpy(prt1, "Was wielding ");
  409.       break;
  410.     case 15:
  411.       (void) strcpy(prt1, "Light source was ");
  412.       break;
  413.     default:
  414.       (void) strcpy(prt1, "Was wearing ");
  415.       break;
  416.     }
  417.   objdes(prt2, i, TRUE);
  418.   (void) sprintf(out_val, "%s%s (%c)", prt1, prt2, i+97);
  419.   msg_print(out_val);
  420.   inventory[item_val] = blank_treasure;
  421.   if (item_val != INVEN_AUX)      /* For secondary weapon  */
  422.     py_bonuses(inventory[i], -1);
  423.   return(i);
  424. }
  425.  
  426.  
  427. /* Unwear routine,  remove a piece of equipment    -RAK-    */
  428. unwear()
  429. {
  430.   int i, j, com_val;
  431.   int exit_flag, test_flag;
  432.   char command;
  433.   vtype out_val;
  434.  
  435.   if (scr_state == 1) 
  436.     {
  437.       clear_screen(0, 0);
  438.       show_equip(0);
  439.     }
  440.   exit_flag = FALSE;
  441.   do
  442.     {
  443.       (void) sprintf(out_val,
  444.           "(a-%c, * for equipment list, ESC to exit) Take off which one ?",
  445.           equip_ctr+96);
  446.       test_flag = FALSE;
  447.       msg_print(out_val);
  448.       do
  449.     {
  450.       inkey(&command);
  451.       com_val = (command);
  452.       switch(com_val)
  453.         {
  454.         case 0: case 27:
  455.           test_flag = TRUE;
  456.           exit_flag = TRUE;
  457.           break;
  458.         case 42:
  459.           clear_screen(1, 0);
  460.           show_equip(0);
  461.           break;
  462.         default:
  463.           com_val -= 97;
  464.           if ((com_val >= 0) &&
  465.           (com_val < equip_ctr)) 
  466.         test_flag = TRUE;
  467.           break;
  468.         }
  469.     }
  470.       while (!test_flag);
  471.       if (!exit_flag) 
  472.     {
  473.       reset_flag = FALSE;    /* Player turn   */
  474.       i = -1;
  475.       j = 21;
  476.       do
  477.         {
  478.           j++;
  479.           if (inventory[j].tval != 0) 
  480.         i++;
  481.         }
  482.       while (i != com_val);
  483.       if (0x80000000 & inventory[j].flags)
  484.         {
  485.           msg_print("Hmmm, it seems to be cursed...");
  486.           com_val = 0;
  487.         }
  488.       else
  489.         (void) remove(j);
  490.     }
  491.       if (scr_state == 0) 
  492.     exit_flag = TRUE;
  493.       else if (equip_ctr == 0) 
  494.     exit_flag = TRUE;
  495.       else if (inven_ctr > 21) 
  496.     exit_flag = TRUE;
  497.       else if (!exit_flag) 
  498.     show_equip(0);
  499.     }
  500.   while (!exit_flag);
  501.   if (scr_state != 0) 
  502.     if (equip_ctr == 0) 
  503.       clear_screen(0, 0);
  504.     else
  505.       prt("You are currently using -", 0, 0);
  506. }
  507.  
  508.  
  509. /* Wear routine, wear or wield an item        -RAK-    */
  510. wear()
  511. {
  512.   int com_val, i, j, k, tmp;
  513.   vtype out_val, prt1, prt2;
  514.   treasure_type unwear_obj;
  515.   int exit_flag, test_flag;
  516.   char command;
  517.   treasure_type *i_ptr;
  518.  
  519.   if (scr_state == 2) 
  520.     {
  521.       clear_screen(0, 0);
  522.       show_inven(0, inven_ctr-1);
  523.     }
  524.   exit_flag = FALSE;
  525.   do
  526.     {
  527.       (void) sprintf(out_val,
  528.          "(a-%c, * for equipment list, ESC to exit) Wear/Wield which one?",
  529.           inven_ctr+96);
  530.       test_flag = FALSE;
  531.       msg_print(out_val);
  532.       do
  533.     {
  534.       inkey(&command);
  535.       com_val = (command);
  536.       switch(com_val)
  537.         {
  538.         case 0: case 27:
  539.           test_flag = TRUE;
  540.           exit_flag = TRUE;
  541.           break;
  542.         case 42:
  543.           clear_screen(1, 0);
  544.           show_inven(0, inven_ctr-1);
  545.           break;
  546.         default:
  547.           com_val -= 97;
  548.           if ((com_val >= 0) &&
  549.           (com_val < inven_ctr)) 
  550.         test_flag = TRUE;
  551.           break;
  552.         }
  553.     }
  554.       while (!test_flag);
  555.       if (!exit_flag)     /* Main logic for wearing        */
  556.     {
  557.       reset_flag = FALSE;    /* Player turn   */
  558.       test_flag = TRUE;
  559.       switch(inventory[com_val].tval) /* Slot for equipment    */
  560.         {
  561.         case 10: i = 22; break;
  562.         case 11: i = 22; break;
  563.         case 12: i = 22; break;
  564.         case 15: i = 32; break;
  565.         case 20: i = 22; break;
  566.         case 21: i = 22; break;
  567.         case 22: i = 22; break;
  568.         case 23: i = 22; break;
  569.         case 25: i = 22; break;
  570.         case 30: i = 30; break;
  571.         case 31: i = 27; break;
  572.         case 32: i = 31; break;
  573.         case 33: i = 23; break;
  574.         case 34: i = 26; break;
  575.         case 35: i = 25; break;
  576.         case 36: i = 25; break;
  577.         case 40: i = 24; break;
  578.         case 45:
  579.           if (inventory[28].tval == 0)       /* Rings */
  580.             i = 28;
  581.           else
  582.             i = 29;
  583.           break;
  584.             default:
  585.           msg_print("I don't see how you can use that.");
  586.           test_flag = FALSE;
  587.           com_val = 0;
  588.           break;
  589.         }
  590.       if (test_flag) 
  591.         if (inventory[i].tval != 0) 
  592.           {
  593.         if (0x80000000 & inventory[i].flags)
  594.           {
  595.             objdes(prt1, i, FALSE);
  596.             (void) sprintf(out_val, "The %s you are ", prt1);
  597.             switch(i)
  598.               {
  599.               case 23: (void) strcat(out_val, "wielding "); break;
  600.               default: (void) strcat(out_val, "wearing "); break;
  601.               }
  602.             msg_print(strcat(out_val, "appears to be cursed."));
  603.             test_flag = FALSE;
  604.             com_val = 0;
  605.           }
  606.         else if (inven_ctr > 21) 
  607.           if (inventory[com_val].number > 1) 
  608.             if (inventory[com_val].subval < 512) 
  609.               {
  610.             msg_print("You will have to drop something first.");
  611.             test_flag = FALSE;
  612.             com_val = 0;
  613.               }
  614.           }
  615.       if (test_flag) 
  616.         {
  617.           unwear_obj = inventory[i];
  618.           inventory[i] = inventory[com_val];
  619.           i_ptr = &inventory[i];
  620.           /* Fix for torches       */
  621.           if ((i_ptr->subval > 255) && (i_ptr->subval < 512)) 
  622.         {
  623.           i_ptr->number = 1;
  624.           i_ptr->subval -= 255;
  625.         }
  626.           /* Fix for weight        */
  627.           inven_weight += i_ptr->weight*i_ptr->number;
  628.           inven_destroy(com_val);     /* Subtracts weight      */
  629.           equip_ctr++;
  630.           py_bonuses(inventory[i], 1);
  631.           if (unwear_obj.tval != 0) 
  632.         {
  633.           inventory[INVEN_MAX] = unwear_obj;
  634.           tmp = remove(INVEN_MAX);
  635.           if (tmp < com_val) 
  636.             com_val = tmp;
  637.         }
  638.           switch(i)
  639.         {
  640.         case 22: (void) strcpy(prt1, "You are wielding "); break;
  641.         case 32: (void) strcpy(prt1, "Your light source is "); break;
  642.         default: (void) strcpy(prt1, "You are wearing "); break;
  643.         }
  644.           objdes(prt2, i, TRUE);
  645.           j = -1;
  646.           k = 21;
  647.           do      /* Get the right letter of equipment     */
  648.         {
  649.           k++;
  650.           if (inventory[k].tval != 0) 
  651.             j++;
  652.         }
  653.           while (k != i);
  654.           (void) sprintf(out_val, "%s%s (%c%c",
  655.               prt1, prt2, j+97, cur_char2(i));
  656.           msg_print(out_val);
  657.           if ((i == 22) && (py.stats.cstr*15 < i_ptr->weight))
  658.         msg_print("You have trouble wielding such a heavy weapon.");
  659.         }
  660.     }
  661.       if (scr_state == 0) 
  662.     exit_flag = TRUE;
  663.       else if (inven_ctr == 0) 
  664.     exit_flag = TRUE;
  665.       else if (!exit_flag) 
  666.     show_inven(com_val, inven_ctr-1);
  667.     }
  668.   while (!exit_flag);
  669.   if (scr_state != 0)  prt("You are currently carrying -", 0, 0);
  670. }
  671.  
  672. /* Switch primary and secondary weapons        -RAK-    */
  673. switch_weapon()
  674. {
  675.   vtype prt1, prt2;
  676.   treasure_type tmp_obj;
  677.  
  678.   if (0x80000000 & inventory[22].flags)
  679.     {
  680.       objdes(prt1, 22, FALSE);
  681.       (void) sprintf(prt2,
  682.              "The %s you are wielding appears to be cursed.", prt1);
  683.       msg_print(prt2);
  684.     }
  685.   else
  686.     {
  687.       /* Switch weapons        */
  688.       reset_flag = FALSE;
  689.       tmp_obj = inventory[33];
  690.       inventory[33] = inventory[22];
  691.       inventory[22] = tmp_obj;
  692.       py_bonuses(inventory[33], -1);     /* Subtract bonuses      */
  693.       py_bonuses(inventory[22], 1);      /* Add bonuses           */
  694.       if (inventory[22].tval != 0) 
  695.     {
  696.       (void) strcpy(prt1, "Primary weapon   : ");
  697.       objdes(prt2, 22, TRUE);
  698.       msg_print(strcat(prt1, prt2));
  699.     }
  700.       if (inventory[33].tval != 0) 
  701.     {
  702.       (void) strcpy(prt1, "Secondary weapon : ");
  703.       objdes(prt2, 33, TRUE);
  704.       msg_print(strcat(prt1, prt2));
  705.     }
  706.     }
  707.   if (scr_state != 0) 
  708.     {
  709.       msg_print("");
  710.       clear_screen(0, 0);
  711.       prt("You are currently using -", 0, 0);
  712.       show_equip(0);
  713.     }
  714. }
  715.  
  716.  
  717. /* Comprehensive function block to handle all inventory    -RAK-    */
  718. /* and equipment routines.  Five kinds of calls can take place.  */
  719. /* Note that "?" is a special call for other routines to display */
  720. /* only a portion of the inventory, and take no other action.    */
  721. int inven_command(command, r1, r2)
  722. char command;
  723. int r1, r2;
  724. {
  725.   int com_val;
  726.   int exit_flag, test_flag;
  727.   int inven;
  728.  
  729.   /* Main logic for INVEN_COMMAND            -RAK-    */
  730.   inven = FALSE;
  731.   exit_flag = FALSE;
  732.   scr_state = 0;
  733.   do
  734.     {
  735.       switch(command)
  736.     {
  737.     case 'i':          /* Inventory     */
  738.       if (inven_ctr == 0) 
  739.         msg_print("You are not carrying anything.");
  740.       else if (scr_state != 1) 
  741.         {     /* Sets scr_state to 1           */
  742.           clear_screen(0, 0);
  743.           prt("You are currently carrying -", 0, 0);
  744.           show_inven(0, inven_ctr-1);
  745.         }
  746.       break;
  747.     case 'e':         /* Equipment     */
  748.       if (equip_ctr == 0) 
  749.         msg_print("You are not using any equipment.");
  750.       else if (scr_state != 2) 
  751.         {     /* Sets scr_state to 2           */
  752.           clear_screen(0, 0);
  753.           prt("You are currently using -", 0, 0);
  754.           show_equip(0);
  755.         }
  756.       break;
  757.     case 't':         /* Take off      */
  758.       if (equip_ctr == 0) 
  759.         msg_print("You are not using any equipment.");
  760.       else if (inven_ctr > 21) 
  761.         msg_print("You will have to drop something first.");
  762.       else
  763.         unwear();   /* May set scr_state to 2        */
  764.       break;
  765.     case 'w':         /* Wear/wield    */
  766.       if (inven_ctr == 0) 
  767.         msg_print("You are not carrying anything.");
  768.       else
  769.         wear();     /* May set scr_state to 1        */
  770.       break;
  771.     case 'x':
  772.       if (inventory[22].tval != 0) 
  773.         switch_weapon();
  774.       else if (inventory[33].tval != 0) 
  775.         switch_weapon();
  776.       else
  777.         msg_print("But you are wielding no weapons.");
  778.       break;
  779.       /* Special function for other routines                   */
  780.     case '?':  /* Displays part inven, returns  */
  781.       show_inven(r1, r2);
  782.       scr_state = 0;     /* Clear screen state    */
  783.       break;
  784.       /* Nonsense command                                      */
  785.     default:
  786.       break;
  787.     }
  788.       if (scr_state > 0) 
  789.     {
  790.       prt(
  791.     "<e>quip, <i>inven, <t>ake-off, <w>ear/wield, e<x>change, or ESC to exit.",
  792.       23, 1);
  793.       test_flag = FALSE;
  794.       do
  795.         {
  796.           inkey(&command);
  797.           com_val = (command);
  798.           switch(com_val)
  799.         {
  800.         case 0: case 27: case 32:
  801.           /* Exit from module      */
  802.           exit_flag = TRUE;
  803.           test_flag = TRUE;
  804.           break;
  805.         default:
  806.           switch(command)      /* Module commands       */
  807.             {
  808.             case 'e': test_flag = TRUE; break;
  809.             case 'i': test_flag = TRUE; break;
  810.             case 't': test_flag = TRUE; break;
  811.             case 'w': test_flag = TRUE; break;
  812.             case 'x': test_flag = TRUE; break;
  813.             case '?': break;      /* Trap special feature  */
  814.             default:  break; /* Nonsense command      */
  815.             }
  816.         }
  817.         }
  818.       while (!test_flag);
  819.       prt("", 23, 0);
  820.     }
  821.       else
  822.     exit_flag = TRUE;
  823.     }
  824.   while (!exit_flag);
  825.   if (scr_state > 0)          /* If true, must redraw screen   */
  826.     inven = TRUE;
  827.   return(inven);
  828. }
  829.  
  830.  
  831. /* Get the ID of an item and return the CTR value of it    -RAK-    */
  832. int get_item(com_val, pmt, redraw, i, j)
  833. int *com_val;
  834. char *pmt;
  835. int *redraw;
  836. int i, j;
  837. {
  838.   char command;
  839.   vtype out_val;
  840.   int test_flag;
  841.   int item;
  842.  
  843.   item = FALSE;
  844.   *com_val = 0;
  845.   if (inven_ctr > 0) 
  846.     {
  847.       (void) sprintf(out_val,
  848.              "(Items %c-%c, * for inventory list, ESC to exit) %s",
  849.           i+97, j+97, pmt);
  850.       test_flag = FALSE;
  851.       prt(out_val, 0, 0);
  852.       do
  853.     {
  854.       inkey(&command);
  855.       *com_val = (command);
  856.       switch(*com_val)
  857.         {
  858.         case 0: case 27:
  859.           test_flag = TRUE;
  860.           reset_flag = TRUE;
  861.           break;
  862.         case 42:
  863.           clear_screen(1, 0);
  864.           (void) inven_command('?', i, j);
  865.           *redraw = TRUE;
  866.           break;
  867.         default:
  868.           *com_val -= 97;
  869.           if ((*com_val >= i) &&
  870.           (*com_val <= j)) 
  871.         {
  872.           test_flag = TRUE;
  873.           item = TRUE;
  874.         }
  875.           break;
  876.         }
  877.     }
  878.       while (!test_flag);
  879.       erase_line(msg_line, msg_line);
  880.     }
  881.   else
  882.     msg_print("You are not carrying anything.");
  883.   return(item);
  884. }
  885.  
  886. /* I may have written the town level code, but I'm not exactly   */
  887. /* proud of it.  Adding the stores required some real slucky     */
  888. /* hooks which I have not had time to re-think.          -RAK-   */
  889.  
  890.  
  891. /* Calculates current boundaries                -RAK-    */
  892. panel_bounds()
  893. {
  894.   panel_row_min = panel_row*(SCREEN_HEIGHT/2);
  895.   panel_row_max = panel_row_min + SCREEN_HEIGHT - 1;
  896.   panel_row_prt = panel_row_min - 1;
  897.   panel_col_min = panel_col*(SCREEN_WIDTH/2);
  898.   panel_col_max = panel_col_min + SCREEN_WIDTH - 1;
  899. /* the value 13 puts one blank space between the stats and the map, leaving
  900.      the last column empty
  901.    the value 14 puts two blank spaces between the stats and the map, and
  902.      ends up printing in the last column
  903.    I think 14 gives a better display, but some curses wreak havoc when try to
  904.    print characters in the last column, hence the BUGGY_CURSES ifdef */
  905. #ifdef BUGGY_CURSES
  906.   panel_col_prt = panel_col_min - 13;
  907. #else
  908.   panel_col_prt = panel_col_min - 14;
  909. #endif
  910. }
  911.  
  912.  
  913. /* Given an row (y) and col (x), this routine detects  -RAK-    */
  914. /* when a move off the screen has occurred and figures new borders*/
  915. int get_panel(y, x)
  916. int y, x;
  917. {
  918.   int prow, pcol;
  919.   int panel;
  920.  
  921.   prow = panel_row;
  922.   pcol = panel_col;
  923.   if ((y < panel_row_min + 2) || (y > panel_row_max - 2)) 
  924.     {
  925.       prow = ((y - 2)/(SCREEN_HEIGHT/2));
  926.       if (prow > max_panel_rows) 
  927.     prow = max_panel_rows;
  928.     }
  929.   if ((x < panel_col_min + 3) || (x > panel_col_max - 3)) 
  930.     {
  931.       pcol = ((x - 3)/(SCREEN_WIDTH/2));
  932.       if (pcol > max_panel_cols) 
  933.     pcol = max_panel_cols;
  934.     }
  935.   if ((prow != panel_row) || (pcol != panel_col) || (!cave_flag)) 
  936.     {
  937.       panel_row = prow;
  938.       panel_col = pcol;
  939.       panel_bounds();
  940.       panel = TRUE;
  941.       cave_flag = TRUE;
  942.     }
  943.   else
  944.     panel = FALSE;
  945.   return(panel);
  946. }
  947.  
  948.  
  949. /* Tests a given point to see if it is within the screen -RAK-    */
  950. /* boundaries.                                                    */
  951. int panel_contains(y, x)
  952. int y, x;
  953. {
  954.   int panel;
  955.  
  956.   if ((y >= panel_row_min) && (y <= panel_row_max)) 
  957.     if ((x >= panel_col_min) && (x <= panel_col_max)) 
  958.       panel = TRUE;
  959.     else
  960.       panel = FALSE;
  961.   else
  962.     panel = FALSE;
  963.   return(panel);
  964. }
  965.  
  966.  
  967. /* Returns true if player has no light            -RAK-    */
  968. int no_light()
  969. {
  970.   int light;
  971.   cave_type *c_ptr;
  972.  
  973.   light = FALSE;
  974.   c_ptr = &cave[char_row][char_col];
  975.     if (!c_ptr->tl) 
  976.       if (!c_ptr->pl) 
  977.     light = TRUE;
  978.   return(light);
  979. }
  980.  
  981.  
  982. /* map rogue_like direction commands into numbers */
  983. int map_roguedir(comval)
  984. int *comval;
  985. {
  986.   switch(*comval)
  987.     {
  988.     case 'h':
  989.       *comval = '4';
  990.       return(4);
  991.       break;
  992.     case 'y':
  993.       *comval = '7';
  994.       return(7);
  995.       break;
  996.     case 'k':
  997.       *comval = '8';
  998.       return(8);
  999.       break;
  1000.     case 'u':
  1001.       *comval = '9';
  1002.       return(9);
  1003.       break;
  1004.     case 'l':
  1005.       *comval = '6';
  1006.       return(6);
  1007.       break;
  1008.     case 'n':
  1009.       *comval = '3';
  1010.       return(3);
  1011.       break;
  1012.     case 'j':
  1013.       *comval = '2';
  1014.       return(2);
  1015.       break;
  1016.     case 'b':
  1017.       *comval = '1';
  1018.       return(1);
  1019.       break;
  1020.     }
  1021.   return(*comval - 48);
  1022. }
  1023.       
  1024.  
  1025.  
  1026. /* Prompts for a direction                -RAK-    */
  1027. int get_dir(prompt, dir, com_val, y, x)
  1028. char *prompt;
  1029. int *dir, *com_val, *y, *x;
  1030. {
  1031.   int flag;
  1032.   char command;
  1033.   int res;
  1034.  
  1035.   flag = FALSE;
  1036.   do
  1037.     {
  1038.       if (get_com(prompt, &command)) 
  1039.     {
  1040.       *com_val = (command);
  1041.       if (key_bindings == ORIGINAL)
  1042.         *dir = *com_val - 48;
  1043.       else   /* rogue_like bindings */
  1044.         *dir = map_roguedir(com_val);
  1045.       /* Note that "5" is not a valid direction        */
  1046.       if ((*dir >= 1) && (*dir <= 9) && (*dir != 5))
  1047.         {
  1048.           (void) move(*dir, y, x);
  1049.           flag = TRUE;
  1050.           res = TRUE;
  1051.         }
  1052.     }
  1053.       else
  1054.     {
  1055.       reset_flag = TRUE;
  1056.       res = FALSE;
  1057.       flag = TRUE;
  1058.     }
  1059.     }
  1060.   while (!flag);
  1061.   return(res);
  1062. }
  1063.  
  1064.  
  1065.  
  1066. /* Moves creature record from one space to another    -RAK-    */
  1067. move_rec(y1, x1, y2, x2)
  1068. int y1, x1, y2, x2;
  1069. {
  1070.   if ((y1 != y2) || (x1 != x2)) 
  1071.     {
  1072.       cave[y2][x2].cptr = cave[y1][x1].cptr;
  1073.       cave[y1][x1].cptr = 0;
  1074.       }
  1075. }
  1076.  
  1077.  
  1078. find_light(y1, x1, y2, x2)
  1079. int y1, x1, y2, x2;
  1080. {
  1081.   int i, j, k, l;
  1082.  
  1083.   for (i = y1; i <= y2; i++)
  1084.     for (j = x1; j <= x2; j++)
  1085.       if ((cave[i][j].fval == 1) || (cave[i][j].fval == 2))
  1086.     {
  1087.       for (k = i-1; k <= i+1; k++)
  1088.         for (l = j-1; l <= j+1; l++)
  1089.           cave[k][l].pl = TRUE;
  1090.       cave[i][j].fval = 2;
  1091.     }
  1092. }
  1093.  
  1094.  
  1095. /* Room is lit, make it appear                -RAK-    */
  1096. light_room(y, x)
  1097. int y, x;
  1098. {
  1099.   int tmp1, tmp2;
  1100.   int start_row, start_col;
  1101.   int end_row, end_col;
  1102.   int i, j;
  1103.   int ypos, xpos;
  1104.   vtype floor_str, tmp_str;
  1105.   cave_type *c_ptr;
  1106.  
  1107.   tmp1 = (SCREEN_HEIGHT/2);
  1108.   tmp2 = (SCREEN_WIDTH /2);
  1109.   start_row = (y/tmp1)*tmp1;
  1110.   start_col = (x/tmp2)*tmp2;
  1111.   end_row = start_row + tmp1 - 1;
  1112.   end_col = start_col + tmp2 - 1;
  1113.   find_light(start_row, start_col, end_row, end_col);
  1114.   for (i = start_row; i <= end_row; i++)
  1115.     {
  1116.       floor_str[0] = '\0';
  1117.       ypos = i;
  1118.       for (j = start_col; j <= end_col; j++)
  1119.     {
  1120.       c_ptr = &cave[i][j];
  1121.       if ((c_ptr->pl) || (c_ptr->fm)) 
  1122.         {
  1123.           if (strlen(floor_str) == 0) 
  1124.         xpos = j;
  1125.           loc_symbol(i, j, tmp_str);
  1126.           tmp_str[1] = '\0';
  1127.           (void) strcat(floor_str, tmp_str);
  1128.         }
  1129.       else
  1130.         if (strlen(floor_str) > 0) 
  1131.           {
  1132.         print(floor_str, ypos, xpos);
  1133.         floor_str[0] = '\0';
  1134.           }
  1135.     }
  1136.       if (strlen(floor_str) > 0) 
  1137.     print(floor_str, ypos, xpos);
  1138.     }
  1139. }
  1140.  
  1141.  
  1142. /* Lights up given location                -RAK-    */
  1143. lite_spot(y, x)
  1144. int y, x;
  1145. {
  1146.   vtype spot_char;
  1147.   char temp[2];
  1148.  
  1149.   temp[1] = '\0';
  1150.   if (panel_contains(y, x)) 
  1151.     {
  1152.       loc_symbol(y, x, temp);
  1153.       (void) strcpy(spot_char, temp);
  1154.       print(spot_char, y, x);
  1155.       }
  1156. }
  1157.  
  1158.  
  1159. /* Blanks out given location                -RAK-    */
  1160. unlite_spot(y, x)
  1161. int y, x;
  1162. {
  1163.   if (panel_contains(y, x)) 
  1164.     print(" ", y, x);
  1165. }
  1166.  
  1167.  
  1168. /* Minimum of a maximum                -RAK-    */
  1169. int minmax(x, y, z)
  1170. int x, y, z;
  1171. {
  1172.   int max;
  1173.  
  1174.   max = ( y > x ? y : x) + 1;
  1175.   return((max > z ? z : max));
  1176. }
  1177.   
  1178. /* Maximum of a minimum                -RAK-    */
  1179. int maxmin(x, y, z)
  1180. int x, y, z;
  1181. {
  1182.   int min;
  1183.  
  1184.   min = (x > y ? y : x) - 1;
  1185.   return((min > z ? min : z));
  1186. }
  1187.  
  1188.  
  1189. /* Given two sets of points,  draw the block        */
  1190. draw_block(y1, x1, y2, x2)
  1191. int y1, x1, y2, x2;
  1192. {
  1193.   int i, j, xpos;
  1194.   int topp, bott, left, righ;
  1195.   int new_topp, new_bott, new_left, new_righ;
  1196.   vtype floor_str, save_str;
  1197.   char tmp_char[2];
  1198.   int flag;
  1199.   cave_type *c_ptr;
  1200.  
  1201.   tmp_char[1] = '\0';    /* This is supposed to be a one */
  1202.   /* From uppermost to bottom most lines player was on...  */
  1203.   /* Points are guaranteed to be on the screen (I hope...) */
  1204.   topp = maxmin(y1, y2, panel_row_min);
  1205.   bott = minmax(y1, y2, panel_row_max);
  1206.   left = maxmin(x1, x2, panel_col_min);
  1207.   righ = minmax(x1, x2, panel_col_max);
  1208.   new_topp = y2 - 1;     /* Margins for new things to appear*/
  1209.   new_bott = y2 + 1;
  1210.   new_left = x2 - 1;
  1211.   new_righ = x2 + 1;
  1212.   for (i = topp; i <= bott; i++)
  1213.     {
  1214.       floor_str[0] = '\0';    /* Null out print string         */
  1215.       xpos      = -1;
  1216.       save_str[0] = '\0';
  1217.       for (j = left; j <= righ; j++)   /* Leftmost to rightmost do*/
  1218.     {
  1219.       c_ptr = &cave[i][j];
  1220.       if ((c_ptr->pl) || (c_ptr->fm)) 
  1221.         if (((i==y1) && (j==x1)) || ((i==y2) && (j==x2))) 
  1222.           flag = TRUE;
  1223.         else
  1224.           flag = FALSE;
  1225.       else
  1226.         {
  1227.           flag = TRUE;
  1228.           if (((i >= new_topp) && (i <= new_bott)) &&
  1229.           ((j >= new_left) && (j <= new_righ))) 
  1230.         {
  1231.           if (c_ptr->tl) 
  1232.             if (((c_ptr->fval >= 10) && (c_ptr->fval <= 12)) ||
  1233.             (c_ptr->fval == 15))
  1234.               c_ptr->pl = TRUE;
  1235.             else if (c_ptr->tptr != 0) 
  1236.               if ((t_list[c_ptr->tptr].tval >= 102) &&
  1237.               (t_list[c_ptr->tptr].tval <= 110) &&
  1238.               (t_list[c_ptr->tptr].tval != 106))
  1239.             if (!c_ptr->fm) 
  1240.               c_ptr->fm = TRUE;
  1241.         }
  1242.         }
  1243.       if ((c_ptr->pl) || (c_ptr->tl) || (c_ptr->fm)) 
  1244.         loc_symbol(i, j, tmp_char);
  1245.       else
  1246.         tmp_char[0] = ' ';
  1247.       if (py.flags.image > 0) 
  1248.         if (randint(12) == 1) 
  1249.           tmp_char[0] = (randint(95) + 31);
  1250.       if (flag) 
  1251.         {
  1252.           if (xpos < 0)  xpos = j;
  1253.           if (strlen(save_str) > 0) 
  1254.         {
  1255.           (void) strcat(floor_str, save_str);
  1256.           save_str[0] = '\0';
  1257.         }
  1258.           (void) strcat(floor_str, tmp_char);
  1259.         }
  1260.       else if (xpos >= 0) 
  1261.         (void) strcat(save_str, tmp_char);
  1262.     }
  1263.       if (xpos >= 0) 
  1264.     {
  1265.       print(floor_str, i, xpos);
  1266.     }
  1267.     }
  1268. }
  1269.  
  1270.  
  1271. /* Normal movement                    */
  1272. sub1_move_light(y1, x1, y2, x2)
  1273. int y1, x1, y2, x2;
  1274. {
  1275.   int i, j;
  1276.   
  1277.   light_flag = TRUE;
  1278.   for (i = y1-1; i <= y1+1; i++)       /* Turn off lamp light   */
  1279.     for (j = x1-1; j <= x1+1; j++)
  1280.       cave[i][j].tl = FALSE;
  1281.   for (i = y2-1; i <= y2+1; i++)
  1282.     for (j = x2-1; j <= x2+1; j++)
  1283.       cave[i][j].tl = TRUE;
  1284.   draw_block(y1, x1, y2, x2);        /* Redraw area           */
  1285. }
  1286.  
  1287. /* When FIND_FLAG,  light only permanent features     */
  1288. sub2_move_light(y1, x1, y2, x2)
  1289. int y1, x1, y2, x2;
  1290. {
  1291.   int i, j, xpos;
  1292.   vtype floor_str, save_str;
  1293.   char tmp_char[2];
  1294.   int flag;
  1295.   cave_type *c_ptr;
  1296.  
  1297.   tmp_char[1] = '\0';
  1298.   if (light_flag) 
  1299.     {
  1300.       for (i = y1-1; i <= y1+1; i++)
  1301.     for (j = x1-1; j <= x1+1; j++)
  1302.       cave[i][j].tl = FALSE;
  1303.       draw_block(y1, x1, y1, x1);
  1304.       light_flag = FALSE;
  1305.     }
  1306.   for (i = y2-1; i <= y2+1; i++)
  1307.     {
  1308.       floor_str[0] = '\0';
  1309.       save_str[0] = '\0';
  1310.       xpos = 0;
  1311.       for (j = x2-1; j <= x2+1; j++)
  1312.     {
  1313.       c_ptr = &cave[i][j];
  1314.       flag = FALSE;
  1315.       if ((!c_ptr->fm) && (!c_ptr->pl))
  1316.         {
  1317.           tmp_char[0] = ' ';
  1318.           if (player_light) 
  1319.         if (((c_ptr->fval >= 10) && (c_ptr->fval <= 12)) ||
  1320.             (c_ptr->fval == 15))
  1321.           {
  1322.             c_ptr->pl = TRUE; /* Turn on perm light    */
  1323.             loc_symbol(i, j, tmp_char);
  1324.             flag = TRUE;
  1325.           }
  1326.         else
  1327.           if (c_ptr->tptr != 0) 
  1328.               if ((t_list[c_ptr->tptr].tval >= 102) &&
  1329.               (t_list[c_ptr->tptr].tval <= 110) &&
  1330.               (t_list[c_ptr->tptr].tval != 106))
  1331.               {
  1332.             c_ptr->fm = TRUE;     /* Turn on field marker  */
  1333.             loc_symbol(i, j, tmp_char);
  1334.             flag = TRUE;
  1335.               }
  1336.         }
  1337.       else
  1338.         loc_symbol(i, j, tmp_char);
  1339.       if (flag) 
  1340.         {
  1341.           if (xpos == 0)  xpos = j;
  1342.           if (strlen(save_str) > 0) 
  1343.         {
  1344.           (void) strcat(floor_str, save_str);
  1345.           save_str[0] = '\0';
  1346.         }
  1347.           (void) strcat(floor_str, tmp_char);
  1348.         }
  1349.       else if (xpos > 0) 
  1350.         (void) strcat(save_str, tmp_char);
  1351.     }
  1352.       if (xpos > 0) 
  1353.     {
  1354.       j = i;
  1355.       print(floor_str, j, xpos);
  1356.     }
  1357.     }
  1358. }
  1359.  
  1360. /* When blinded,  move only the player symbol...        */
  1361. sub3_move_light(y1, x1, y2, x2)
  1362. int y1, x1, y2, x2;
  1363. {
  1364.   int i, j;
  1365.  
  1366.   if (light_flag) 
  1367.     {
  1368.       for (i = y1-1; i <= y1+1; i++)
  1369.     for (j = x1-1; j <= x1+1; j++)
  1370.       cave[i][j].tl = FALSE;
  1371.       light_flag = FALSE;
  1372.     }
  1373.   print(" ", y1, x1);
  1374.   print("@", y2, x2);
  1375. }
  1376.  
  1377. /* With no light,  movement becomes involved...        */
  1378. sub4_move_light(y1, x1, y2, x2)
  1379. int y1, x1, y2, x2;
  1380. {
  1381.   int i, j;
  1382.  
  1383.   light_flag = TRUE;
  1384.   if (cave[y1][x1].tl) 
  1385.     {
  1386.       for (i = y1-1; i <= y1+1; i++)
  1387.     for (j = x1-1; j <= x1+1; j++)
  1388.       {
  1389.         cave[i][j].tl = FALSE;
  1390.         if (test_light(i, j)) 
  1391.           lite_spot(i, j);
  1392.         else
  1393.           unlite_spot(i, j);
  1394.       }
  1395.     }
  1396.   else if (test_light(y1, x1)) 
  1397.     lite_spot(y1, x1);
  1398.   else
  1399.     unlite_spot(y1, x1);
  1400.   print("@", y2, x2);
  1401. }
  1402.  
  1403. /* Package for moving the character's light about the screen     */
  1404. /* Three cases : Normal,  Finding, and Blind              -RAK-   */
  1405. move_light(y1, x1, y2, x2)
  1406. int y1, x1, y2, x2;
  1407. {
  1408.   if (py.flags.blind > 0) 
  1409.     sub3_move_light(y1, x1, y2, x2);
  1410.   else if (find_flag) 
  1411.     sub2_move_light(y1, x1, y2, x2);
  1412.   else if (!player_light) 
  1413.     sub4_move_light(y1, x1, y2, x2);
  1414.   else
  1415.     sub1_move_light(y1, x1, y2, x2);
  1416. }
  1417.  
  1418.  
  1419. /* Returns random co-ordinates                -RAK-    */
  1420. new_spot(y, x)
  1421. int *y, *x;
  1422. {
  1423.   do
  1424.     {
  1425.       *y = randint(cur_height) - 1;
  1426.       *x = randint(cur_width) - 1;
  1427.     }
  1428.   while ((!cave[*y][*x].fopen) || (cave[*y][*x].cptr != 0) ||
  1429.        (cave[*y][*x].tptr != 0));
  1430. }
  1431.  
  1432.  
  1433. /* Search Mode enhancement                -RAK-    */
  1434. search_on()
  1435. {
  1436.   search_flag = TRUE;
  1437.   change_speed(1);
  1438.   py.flags.status |= 0x00000100;
  1439.   prt_search();
  1440.   py.flags.food_digested++;
  1441. }
  1442.  
  1443. search_off()
  1444. {
  1445.   search_flag = FALSE;
  1446.   find_flag = FALSE;
  1447.   move_char(5);
  1448.   change_speed(-1);
  1449.   py.flags.status &= 0xFFFFFEFF;
  1450.   prt_search();
  1451.   py.flags.food_digested--;
  1452. }
  1453.  
  1454.  
  1455. /* Resting allows a player to safely restore his hp    -RAK-    */
  1456. rest()
  1457. {
  1458.   int rest_num;
  1459.   vtype rest_str;
  1460.  
  1461.   prt("Rest for how long? ", 0, 0);
  1462.   rest_num = 0;
  1463.   if (get_string(rest_str, 0, 19, 10))
  1464.     (void) sscanf(rest_str, "%d", &rest_num);
  1465.   if (rest_num > 0) 
  1466.     {
  1467.       if (search_flag) 
  1468.     search_off();
  1469.       py.flags.rest = rest_num;
  1470.       py.flags.status |= 0x00000200;
  1471.       prt_rest();
  1472.       py.flags.food_digested--;
  1473.       msg_print("Press ^C to wake up...");
  1474.       put_qio();
  1475.     }
  1476.   else
  1477.     erase_line(msg_line, msg_line);
  1478. }
  1479.  
  1480. rest_off()
  1481. {
  1482.   py.flags.rest = 0;
  1483.   py.flags.status &= 0xFFFFFDFF;
  1484.   erase_line(0, 0);
  1485.   prt_rest();
  1486.   py.flags.food_digested++;
  1487. }
  1488.  
  1489.  
  1490. /* Attacker's level and plusses,  defender's AC        -RAK-    */
  1491. int test_hit(bth, level, pth, ac)
  1492. int bth, level, pth, ac;
  1493. {
  1494.   int i;
  1495.   int test;
  1496.  
  1497.   if (search_flag) 
  1498.     search_off();
  1499.   if (py.flags.rest > 0) 
  1500.     rest_off();
  1501.   i = bth + level*BTH_LEV_ADJ + pth*BTH_PLUS_ADJ;
  1502.   /* pth could be less than 0 if player wielding weapon too heavy for him */
  1503.   if ((i > 0) && (randint(i) > ac))               /* Normal hit            */
  1504.     test = TRUE;
  1505.   else if (randint(20) == 1)           /* Always hit 1/20       */
  1506.     test = TRUE;
  1507.   else                                    /* Missed                */
  1508.     {
  1509.       if (i <= 0)
  1510.     msg_print("You have trouble swinging such a heavy weapon.");
  1511.       test = FALSE;
  1512.     }
  1513.   return(test);
  1514. }
  1515.  
  1516.  
  1517. /* Decreases players hit points and sets death flag if necessary*/
  1518. /*                                                       -RAK-   */
  1519. take_hit(damage, hit_from)
  1520. int damage;
  1521. char *hit_from;
  1522. {
  1523.   if (py.flags.invuln > 0)  damage = 0;
  1524.   py.misc.chp -= (double)damage;
  1525.   if (search_flag)  search_off();
  1526.   if (py.flags.rest > 0)  rest_off();
  1527.   flush();
  1528.   if (py.misc.chp <= -1) 
  1529.     {
  1530.       if (!death) 
  1531.     {             /* Hee,  hee... Ain't I mean?     */
  1532.       death = TRUE;
  1533.       (void) strcpy(died_from, hit_from);
  1534.       total_winner = FALSE;
  1535.     }
  1536.       moria_flag = TRUE;
  1537.     }
  1538.   else
  1539.     prt_chp();
  1540. }
  1541.  
  1542.  
  1543. /* Given speed,  returns number of moves this turn.    -RAK-    */
  1544. /* NOTE: Player must always move at least once per iteration,     */
  1545. /*       a slowed player is handled by moving monsters faster    */
  1546. int movement_rate(speed)
  1547. int speed;
  1548. {
  1549.   int rate;
  1550.  
  1551.   if (speed > 0) 
  1552.     if (py.flags.rest > 0) 
  1553.       rate = 1;
  1554.     else
  1555.       rate = speed;
  1556.   else
  1557.     {
  1558.       if ((turn % (abs(speed) + 2)) == 0) 
  1559.     rate = 1;
  1560.       else
  1561.     rate = 0;
  1562.     }
  1563.   return(rate);
  1564. }
  1565.  
  1566.  
  1567. /* Regenerate hit points                 -RAK-    */
  1568. regenhp(percent)
  1569. double percent;
  1570. {
  1571.   struct misc *p_ptr;
  1572.  
  1573.   p_ptr = &py.misc;
  1574.   p_ptr->chp += p_ptr->mhp*percent + PLAYER_REGEN_HPBASE;
  1575. }
  1576.  
  1577.  
  1578. /* Regenerate mana points                -RAK-    */
  1579. regenmana(percent)
  1580. double percent;
  1581. {
  1582.   struct misc *p_ptr;
  1583.   p_ptr = &py.misc;
  1584.   p_ptr->cmana += p_ptr->mana*percent + PLAYER_REGEN_MNBASE;
  1585. }
  1586.  
  1587.  
  1588. /* Change a trap from invisible to visible        -RAK-    */
  1589. /* Note: Secret doors are handled here                           */
  1590. change_trap(y, x)
  1591. int y, x;
  1592. {
  1593.   int k;
  1594.   cave_type *c_ptr;
  1595.  
  1596.   c_ptr = &cave[y][x];
  1597.   if ((t_list[c_ptr->tptr].tval == 101) || (t_list[c_ptr->tptr].tval == 109))
  1598.     {
  1599.       k = c_ptr->tptr;
  1600.       place_trap(y, x, 2, t_list[k].subval-1);
  1601.       pusht(k);
  1602.       lite_spot(y, x);
  1603.     }
  1604. }
  1605.  
  1606.  
  1607. /* Searches for hidden things...             -RAK-    */
  1608. search(y, x, chance)
  1609. int y, x, chance;
  1610. {
  1611.   int i, j;
  1612.   struct flags *p_ptr;
  1613.   cave_type *c_ptr;
  1614.   treasure_type *t_ptr;
  1615.   vtype tmp_str;
  1616.  
  1617.   p_ptr = &py.flags;
  1618.   if (p_ptr->confused+p_ptr->blind > 0) 
  1619.     chance /= 10.0;
  1620.   else if (no_light()) 
  1621.     chance /= 5.0;
  1622.   for (i = (y - 1); i <= (y + 1); i++)
  1623.     for (j = (x - 1); j <= (x + 1); j++)
  1624.       if (in_bounds(i, j)) 
  1625.     if ((i != y) || (j != x)) 
  1626.       if (randint(100) < chance) 
  1627.         {
  1628.           c_ptr = &cave[i][j];
  1629.           /* Search for hidden objects             */
  1630.           if (c_ptr->tptr != 0) 
  1631.         {
  1632.           t_ptr = &t_list[c_ptr->tptr];
  1633.           /* Trap on floor?                */
  1634.           if (t_ptr->tval == 101) 
  1635.             {
  1636.               (void) sprintf(tmp_str,"You have found %s.",t_ptr->name);
  1637.               msg_print(tmp_str);
  1638.               change_trap(i, j);
  1639.               find_flag = FALSE;
  1640.             }
  1641.           /* Secret door?                  */
  1642.           else if (t_ptr->tval == 109) 
  1643.             {
  1644.               msg_print("You have found a secret door.");
  1645.               c_ptr->fval = corr_floor2.ftval;
  1646.               change_trap(i, j);
  1647.               find_flag = FALSE;
  1648.             }
  1649.           /* Chest is trapped?             */
  1650.           else if (t_ptr->tval == 2) 
  1651.             {
  1652.               if (t_ptr->flags > 1) 
  1653.             if (index(t_ptr->name, '^') != 0) 
  1654.               {
  1655.                 known2(t_ptr->name);
  1656.                  msg_print("You have discovered a trap on the chest!");
  1657.               }
  1658.               else
  1659.             {
  1660.               msg_print("The chest is empty.");
  1661.               known2(t_ptr->name);
  1662.             }
  1663.             }
  1664.         }
  1665.         }
  1666. }
  1667.  
  1668.  
  1669. /* Turns off Find_flag if something interesting appears    -RAK-    */
  1670. /* BUG: Does not handle corridor/room corners, but I didn't want */
  1671. /*      to add a lot of checking for such a minor detail         */
  1672. area_affect(dir, y, x)
  1673. int dir, y, x;
  1674. {
  1675.   int z[3];
  1676.   int i, row, col;
  1677.   cave_type *c_ptr;
  1678.   monster_type *m_ptr;
  1679.  
  1680.   if (cave[y][x].fval == 4) 
  1681.     {
  1682.       i = 0;
  1683.       if (next_to4(y, x, 4, 5, 6) > 2) 
  1684.     find_flag = FALSE;
  1685.     }
  1686.   if ((find_flag) && (py.flags.blind < 1)) 
  1687.     {
  1688.       switch(dir)
  1689.     {
  1690.     case 1:
  1691.       z[0] = 4;
  1692.       z[1] = 1;
  1693.       z[2] = 3;
  1694.       break;
  1695.     case 2:
  1696.       z[0] = 4;
  1697.       z[1] = 2;
  1698.       z[2] = 6;
  1699.       break;
  1700.     case 3:
  1701.       z[0] = 2;
  1702.       z[1] = 3;
  1703.       z[2] = 6;
  1704.       break;
  1705.     case 4:
  1706.       z[0] = 8;
  1707.       z[1] = 4;
  1708.       z[2] = 2;
  1709.       break;
  1710.     case 6:
  1711.       z[0] = 2;
  1712.       z[1] = 6;
  1713.       z[2] = 8;
  1714.       break;
  1715.     case 7:
  1716.       z[0] = 8;
  1717.       z[1] = 7;
  1718.       z[2] = 4;
  1719.       break;
  1720.     case 8:
  1721.       z[0] = 4;
  1722.       z[1] = 8;
  1723.       z[2] = 6;
  1724.       break;
  1725.     case 9:
  1726.       z[0] = 8;
  1727.       z[1] = 9;
  1728.       z[2] = 6;
  1729.       break;
  1730.     }
  1731.       for (i = 0; i < 3; i++)
  1732.     {
  1733.       row = y;
  1734.       col = x;
  1735.       if (move(z[i], &row, &col)) 
  1736.         {
  1737.           c_ptr = &cave[row][col];
  1738.           /* Empty doorways        */
  1739.           if (c_ptr->fval == 5) 
  1740.         find_flag = FALSE;
  1741.           /* Objects player can see*/
  1742.           /* Including doors       */
  1743.           if (find_flag) 
  1744.         if (player_light) 
  1745.           {
  1746.             if (c_ptr->tptr != 0) 
  1747.               if ((t_list[c_ptr->tptr].tval != 101) &&
  1748.               (t_list[c_ptr->tptr].tval != 109))
  1749.             find_flag = FALSE;
  1750.           }
  1751.         else if ((c_ptr->tl) || (c_ptr->pl) || (c_ptr->fm)) 
  1752.           if (c_ptr->tptr != 0) 
  1753.             if ((t_list[c_ptr->tptr].tval != 101) &&
  1754.             (t_list[c_ptr->tptr].tval != 109))
  1755.               find_flag = FALSE;
  1756.           /* Creatures             */
  1757.           if (find_flag) 
  1758.         if ((c_ptr->tl) || (c_ptr->pl) || (player_light)) 
  1759.           if (c_ptr->cptr > 1) 
  1760.             {
  1761.               m_ptr = &m_list[c_ptr->cptr];
  1762.               if (m_ptr->ml) 
  1763.             find_flag = FALSE;
  1764.             }
  1765.         }
  1766.     }
  1767.     }
  1768. }
  1769.  
  1770.  
  1771. /* Picks new direction when in find mode         -RAK-    */
  1772. int pick_dir(dir)
  1773. int dir;
  1774. {
  1775.   int z[2];
  1776.   int i, y, x;
  1777.   int pick;
  1778.  
  1779.   if ((find_flag) && (next_to4(char_row, char_col, 4, 5, -1) == 2)) 
  1780.     {
  1781.       switch(dir)
  1782.     {
  1783.     case 1:
  1784.       z[0] = 2;
  1785.       z[1] = 4;
  1786.       break;
  1787.     case 2:
  1788.       z[0] = 4;
  1789.       z[1] = 6;
  1790.       break;
  1791.     case 3:
  1792.       z[0] = 2;
  1793.       z[1] = 6;
  1794.       break;
  1795.     case 4:
  1796.       z[0] = 2;
  1797.       z[1] = 8;
  1798.       break;
  1799.     case 6:
  1800.       z[0] = 2;
  1801.       z[1] = 8;
  1802.       break;
  1803.     case 7:
  1804.       z[0] = 4;
  1805.       z[1] = 8;
  1806.       break;
  1807.     case 8:
  1808.       z[0] = 4;
  1809.       z[1] = 6;
  1810.       break;
  1811.     case 9:
  1812.       z[0] = 6;
  1813.       z[1] = 8;
  1814.       break;
  1815.     }
  1816.       pick = FALSE;
  1817.       for (i = 0; i < 2; i++)
  1818.     {
  1819.       y = char_row;
  1820.       x = char_col;
  1821.       if (move(z[i], &y, &x)) 
  1822.         if (cave[y][x].fopen) 
  1823.           {
  1824.         pick = TRUE;
  1825.         global_com_val = z[i] + 48;
  1826.         }
  1827.     }
  1828.     }
  1829.   else
  1830.     {
  1831.       pick = FALSE;
  1832.     }
  1833.   return(pick);
  1834. }
  1835.  
  1836.  
  1837. /* AC gets worse                     -RAK-    */
  1838. /* Note: This routine affects magical AC bonuses so that stores   */
  1839. /*       can detect the damage.                                  */
  1840. int minus_ac(typ_dam)
  1841. int typ_dam;
  1842. {
  1843.   int i, j;
  1844.   int tmp[5];
  1845.   int minus;
  1846.   treasure_type *i_ptr;
  1847.   vtype out_val, tmp_str;
  1848.   
  1849.   i = 0;
  1850.   if (inventory[25].tval != 0) 
  1851.     {
  1852.       tmp[i] = 25;
  1853.       i++;
  1854.     }
  1855.   if (inventory[26].tval != 0) 
  1856.     {
  1857.       tmp[i] = 26;
  1858.       i++;
  1859.     }
  1860.   if (inventory[31].tval != 0) 
  1861.     {
  1862.       tmp[i] = 31;
  1863.       i++;
  1864.     }
  1865.   if (inventory[27].tval != 0) 
  1866.     {
  1867.       tmp[i] = 27;
  1868.       i++;
  1869.     }
  1870.   if (inventory[23].tval != 0) 
  1871.     {
  1872.       tmp[i] = 23;
  1873.       i++;
  1874.     }
  1875.   minus = FALSE;
  1876.   if (i > 0) 
  1877.     {
  1878.       j = tmp[randint(i) - 1];
  1879.       i_ptr = &inventory[j];
  1880.       if (i_ptr->flags & typ_dam)
  1881.     {
  1882.       objdes(tmp_str, j, FALSE);
  1883.       (void) sprintf(out_val, "Your %s resists damage!", tmp_str);
  1884.       msg_print(out_val);
  1885.       minus = TRUE;
  1886.     }
  1887.       else if ((i_ptr->ac+i_ptr->toac) > 0) 
  1888.     {
  1889.       objdes(tmp_str, j, FALSE);
  1890.       (void) sprintf(out_val, "Your %s is damaged!", tmp_str);
  1891.       msg_print(out_val);
  1892.       i_ptr->toac--;
  1893.       py_bonuses(blank_treasure, 0);
  1894.       minus = TRUE;
  1895.     }
  1896.     }
  1897.   return(minus);
  1898. }
  1899.  
  1900.  
  1901. /* Corrode the unsuspecting person's armor               -RAK-   */
  1902. corrode_gas(kb_str)
  1903. char *kb_str;
  1904. {
  1905.   int set_corrodes();
  1906.  
  1907.   if (!minus_ac((int)0x00100000)) 
  1908.     take_hit(randint(8), kb_str);
  1909.   print_stat |= 0x0040;
  1910.   if (inven_damage(set_corrodes, 5) > 0) 
  1911.     msg_print("There is an acrid smell coming from your pack.");
  1912. }
  1913.  
  1914.  
  1915. /* Poison gas the idiot...                -RAK-    */
  1916. poison_gas(dam, kb_str)
  1917. int dam;
  1918. char *kb_str;
  1919. {
  1920.   take_hit(dam, kb_str);
  1921.   print_stat |= 0x0040;
  1922.   py.flags.poisoned += 12 + randint(dam);
  1923. }
  1924.  
  1925.  
  1926. /* Burn the fool up...                    -RAK-    */
  1927. fire_dam(dam, kb_str)
  1928. int dam;
  1929. char *kb_str;
  1930. {
  1931.   int set_flammable();
  1932.  
  1933.   if (py.flags.fire_resist)
  1934.     dam /= 3;
  1935.   if (py.flags.resist_heat > 0) 
  1936.     dam /= 3;
  1937.   take_hit(dam, kb_str);
  1938.   print_stat |= 0x0080;
  1939.   if (inven_damage(set_flammable, 3) > 0) 
  1940.     msg_print("There is smoke coming from your pack!");
  1941. }
  1942.  
  1943.  
  1944. /* Freeze him to death...                -RAK-    */
  1945. cold_dam(dam, kb_str)
  1946. int dam;
  1947. char *kb_str;
  1948. {
  1949.   int set_frost_destroy();
  1950.  
  1951.   if (py.flags.cold_resist)
  1952.     dam /= 3;
  1953.   if (py.flags.resist_cold > 0) 
  1954.     dam /= 3;
  1955.   take_hit(dam, kb_str);
  1956.   print_stat |= 0x0080;
  1957.   if (inven_damage(set_frost_destroy, 5) > 0) 
  1958.     msg_print("Something shatters inside your pack!");
  1959. }
  1960.  
  1961.  
  1962. /* Lightning bolt the sucker away...            -RAK-    */
  1963. light_dam(dam, kb_str)
  1964. int dam;
  1965. char *kb_str;
  1966. {
  1967.   if (py.flags.lght_resist) 
  1968.     take_hit((dam / 3), kb_str);
  1969.   else
  1970.     take_hit(dam, kb_str);
  1971.   print_stat |= 0x0080;
  1972. }
  1973.  
  1974.  
  1975. /* Throw acid on the hapless victim            -RAK-    */
  1976. acid_dam(dam, kb_str)
  1977. int dam;
  1978. char *kb_str;
  1979. {
  1980.   int flag;
  1981.   int set_acid_affect();
  1982.  
  1983.   flag = 0;
  1984.   if (minus_ac((int)0x00100000)) 
  1985.     flag = 1;
  1986.   if (py.flags.acid_resist) 
  1987.     flag += 2;
  1988.   switch(flag)
  1989.     {
  1990.     case 0: take_hit(dam, kb_str);       break;
  1991.     case 1: take_hit((dam / 2), kb_str); break;
  1992.     case 2: take_hit((dam / 3), kb_str); break;
  1993.     case 3: take_hit((dam / 4), kb_str); break;
  1994.     }
  1995.   print_stat |= 0x00C0;
  1996.   if (inven_damage(set_acid_affect, 3) > 0) 
  1997.     msg_print("There is an acrid smell coming from your pack!");
  1998. }
  1999.