home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / games / volume1 / rogue / part02 / throw.c < prev   
C/C++ Source or Header  |  1987-05-12  |  6KB  |  288 lines

  1. /*
  2.  * throw.c
  3.  *
  4.  * This source herein may be modified and/or distributed by anybody who
  5.  * so desires, with the following restrictions:
  6.  *    1.)  No portion of this notice shall be removed.
  7.  *    2.)  Credit shall not be taken for the creation of this source.
  8.  *    3.)  This code is not to be traded, sold, or used for personal
  9.  *         gain or profit.
  10.  *
  11.  */
  12.  
  13. #ifndef CURSES
  14. #include <curses.h>
  15. #endif CURSES
  16. #include "rogue.h"
  17.  
  18. extern short cur_room;
  19. extern char *curse_message;
  20. extern char hit_message[];
  21.  
  22. throw()
  23. {
  24.     short wch;
  25.     boolean first_miss = 1;
  26.     object *weapon;
  27.     short dir, row, col;
  28.     object *monster;
  29.  
  30.     while (!is_direction(dir = rgetchar())) {
  31.         sound_bell();
  32.         if (first_miss) {
  33.             message("direction? ", 0);
  34.             first_miss = 0;
  35.         }
  36.     }
  37.     check_message();
  38.     if (dir == CANCEL) {
  39.         return;
  40.     }
  41.     if ((wch = pack_letter("throw what?", WEAPON)) == CANCEL) {
  42.         return;
  43.     }
  44.     check_message();
  45.  
  46.     if (!(weapon = get_letter_object(wch))) {
  47.         message("no such item.", 0);
  48.         return;
  49.     }
  50.     if ((weapon->in_use_flags & BEING_USED) && weapon->is_cursed) {
  51.         message(curse_message, 0);
  52.         return;
  53.     }
  54.     row = rogue.row; col = rogue.col;
  55.  
  56.     if ((weapon->in_use_flags & BEING_WIELDED) && (weapon->quantity <= 1)) {
  57.         unwield(rogue.weapon);
  58.     } else if (weapon->in_use_flags & BEING_WORN) {
  59.         mv_aquatars();
  60.         unwear(rogue.armor);
  61.         print_stats(STAT_ARMOR);
  62.     } else if (weapon->in_use_flags & ON_EITHER_HAND) {
  63.         un_put_on(weapon);
  64.     }
  65.     monster = get_thrown_at_monster(weapon, dir, &row, &col);
  66.     mvaddch(rogue.row, rogue.col, rogue.fchar);
  67.     refresh();
  68.  
  69.     if (rogue_can_see(row, col) && ((row != rogue.row) || (col != rogue.col))){
  70.         mvaddch(row, col, get_dungeon_char(row, col));
  71.     }
  72.     if (monster) {
  73.         wake_up(monster);
  74.         check_gold_seeker(monster);
  75.  
  76.         if (!throw_at_monster(monster, weapon)) {
  77.             flop_weapon(weapon, row, col);
  78.         }
  79.     } else {
  80.         flop_weapon(weapon, row, col);
  81.     }
  82.     vanish(weapon, 1, &rogue.pack);
  83. }
  84.  
  85. throw_at_monster(monster, weapon)
  86. object *monster, *weapon;
  87. {
  88.     short damage, hit_chance;
  89.     short t;
  90.  
  91.     hit_chance = get_hit_chance(weapon);
  92.     damage = get_weapon_damage(weapon);
  93.     if ((weapon->which_kind == ARROW) &&
  94.         (rogue.weapon && (rogue.weapon->which_kind == BOW))) {
  95.         damage += get_weapon_damage(rogue.weapon);
  96.         damage = ((damage * 2) / 3);
  97.         hit_chance += (hit_chance / 3);
  98.     } else if ((weapon->in_use_flags & BEING_WIELDED) &&
  99.         ((weapon->which_kind == DAGGER) ||
  100.         (weapon->which_kind == SHURIKEN) ||
  101.         (weapon->which_kind == DART))) {
  102.         damage = ((damage * 3) / 2);
  103.         hit_chance += (hit_chance / 3);
  104.     }
  105.     t = weapon->quantity;
  106.     weapon->quantity = 1;
  107.     sprintf(hit_message, "the %s", name_of(weapon));
  108.     weapon->quantity = t;
  109.  
  110.     if (!rand_percent(hit_chance)) {
  111.         (void) strcat(hit_message, "misses  ");
  112.         return(0);
  113.     }
  114.     (void) strcat(hit_message, "hit  ");
  115.     if ((weapon->what_is == WAND) && rand_percent(75)) {
  116.         zap_monster(monster, weapon->which_kind);
  117.     } else {
  118.         (void) mon_damage(monster, damage);
  119.     }
  120.     return(1);
  121. }
  122.  
  123. object *
  124. get_thrown_at_monster(obj, dir, row, col)
  125. object *obj;
  126. short dir;
  127. short *row, *col;
  128. {
  129.     short orow, ocol;
  130.     short i, ch;
  131.  
  132.     orow = *row; ocol = *col;
  133.  
  134.     ch = get_mask_char(obj->what_is);
  135.  
  136.     for (i = 0; i < 24; i++) {
  137.         get_dir_rc(dir, row, col, 0);
  138.         if ((dungeon[*row][*col] == NOTHING) ||
  139.                 ((dungeon[*row][*col] & (HORWALL | VERTWALL | HIDDEN)) &&
  140.                 (!(dungeon[*row][*col] & TRAP)))) {
  141.             *row = orow;
  142.             *col = ocol;
  143.             return(0);
  144.         }
  145.         if ((i != 0) && rogue_can_see(orow, ocol)) {
  146.             mvaddch(orow, ocol, get_dungeon_char(orow, ocol));
  147.         }
  148.         if (rogue_can_see(*row, *col)) {
  149.             if (!(dungeon[*row][*col] & MONSTER)) {
  150.                 mvaddch(*row, *col, ch);
  151.             }
  152.             refresh();
  153.         }
  154.         orow = *row; ocol = *col;
  155.         if (dungeon[*row][*col] & MONSTER) {
  156.             if (!imitating(*row, *col)) {
  157.                 return(object_at(&level_monsters, *row, *col));
  158.             }
  159.         }
  160.         if (dungeon[*row][*col] & TUNNEL) {
  161.             i += 2;
  162.         }
  163.     }
  164.     return(0);
  165. }
  166.  
  167. flop_weapon(weapon, row, col)
  168. object *weapon;
  169. short row, col;
  170. {
  171.     object *new_weapon, *monster;
  172.     short i = 0;
  173.     char msg[80];
  174.     boolean found = 0;
  175.     short mch, dch;
  176.     unsigned short mon;
  177.  
  178.     while ((i < 9) && dungeon[row][col] & ~(FLOOR | TUNNEL | DOOR | MONSTER)) {
  179.         rand_around(i++, &row, &col);
  180.         if ((row > (DROWS-2)) || (row < MIN_ROW) ||
  181.             (col > (DCOLS-1)) || (col < 0) || (!dungeon[row][col]) ||
  182.             (dungeon[row][col] & ~(FLOOR | TUNNEL | DOOR | MONSTER))) {
  183.             continue;
  184.         }
  185.         found = 1;
  186.         break;
  187.     }
  188.  
  189.     if (found || (i == 0)) {
  190.         new_weapon = alloc_object();
  191.         *new_weapon = *weapon;
  192.         new_weapon->in_use_flags = NOT_USED;
  193.         new_weapon->quantity = 1;
  194.         new_weapon->ichar = 'L';
  195.         place_at(new_weapon, row, col);
  196.         if (rogue_can_see(row, col) &&
  197.                 ((row != rogue.row) || (col != rogue.col))) {
  198.             mon = dungeon[row][col] & MONSTER;
  199.             dungeon[row][col] &= (~MONSTER);
  200.             dch = get_dungeon_char(row, col);
  201.             if (mon) {
  202.                 mch = mvinch(row, col);
  203.                 if (monster = object_at(&level_monsters, row, col)) {
  204.                     monster->trail_char = dch;
  205.                 }
  206.                 if ((mch < 'A') || (mch > 'Z')) {
  207.                     mvaddch(row, col, dch);
  208.                 }
  209.             } else {
  210.                 mvaddch(row, col, dch);
  211.             }
  212.             dungeon[row][col] |= mon;
  213.         }
  214.     } else {
  215.         short t;
  216.  
  217.         t = weapon->quantity;
  218.         weapon->quantity = 1;
  219.         sprintf(msg, "the %svanishes as it hits the ground",
  220.         name_of(weapon));
  221.         weapon->quantity = t;
  222.         message(msg, 0);
  223.     }
  224. }
  225.  
  226. rand_around(i, r, c)
  227. short i, *r, *c;
  228. {
  229.     static char* pos = "\010\007\001\003\004\005\002\006\0";
  230.     static short row, col;
  231.     short j;
  232.  
  233.     if (i == 0) {
  234.         short x, y, o, t;
  235.  
  236.         row = *r;
  237.         col = *c;
  238.  
  239.         o = get_rand(1, 8);
  240.  
  241.         for (j = 0; j < 5; j++) {
  242.             x = get_rand(0, 8);
  243.             y = (x + o) % 9;
  244.             t = pos[x];
  245.             pos[x] = pos[y];
  246.             pos[y] = t;
  247.         }
  248.     }
  249.     switch((short)pos[i]) {
  250.     case 0:
  251.         *r = row + 1;
  252.         *c = col + 1;
  253.         break;
  254.     case 1:
  255.         *r = row + 1;
  256.         *c = col - 1;
  257.         break;
  258.     case 2:
  259.         *r = row - 1;
  260.         *c = col + 1;
  261.         break;
  262.     case 3:
  263.         *r = row - 1;
  264.         *c = col - 1;
  265.         break;
  266.     case 4:
  267.         *r = row;
  268.         *c = col + 1;
  269.         break;
  270.     case 5:
  271.         *r = row + 1;
  272.         *c = col;
  273.         break;
  274.     case 6:
  275.         *r = row;
  276.         *c = col;
  277.         break;
  278.     case 7:
  279.         *r = row - 1;
  280.         *c = col;
  281.         break;
  282.     case 8:
  283.         *r = row;
  284.         *c = col - 1;
  285.         break;
  286.     }
  287. }
  288.