home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / bsd_srcs / games / rogue / throw.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-04-08  |  7.8 KB  |  323 lines

  1. /*
  2.  * Copyright (c) 1988 The Regents of the University of California.
  3.  * All rights reserved.
  4.  *
  5.  * This code is derived from software contributed to Berkeley by
  6.  * Timothy C. Stoehr.
  7.  *
  8.  * Redistribution and use in source and binary forms, with or without
  9.  * modification, are permitted provided that the following conditions
  10.  * are met:
  11.  * 1. Redistributions of source code must retain the above copyright
  12.  *    notice, this list of conditions and the following disclaimer.
  13.  * 2. Redistributions in binary form must reproduce the above copyright
  14.  *    notice, this list of conditions and the following disclaimer in the
  15.  *    documentation and/or other materials provided with the distribution.
  16.  * 3. All advertising materials mentioning features or use of this software
  17.  *    must display the following acknowledgement:
  18.  *    This product includes software developed by the University of
  19.  *    California, Berkeley and its contributors.
  20.  * 4. Neither the name of the University nor the names of its contributors
  21.  *    may be used to endorse or promote products derived from this software
  22.  *    without specific prior written permission.
  23.  *
  24.  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  25.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  26.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  27.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  28.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  29.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  30.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  31.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  32.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  33.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  34.  * SUCH DAMAGE.
  35.  */
  36.  
  37. #ifndef lint
  38. static char sccsid[] = "@(#)throw.c    5.3 (Berkeley) 6/1/90";
  39. #endif /* not lint */
  40.  
  41. /*
  42.  * throw.c
  43.  *
  44.  * This source herein may be modified and/or distributed by anybody who
  45.  * so desires, with the following restrictions:
  46.  *    1.)  No portion of this notice shall be removed.
  47.  *    2.)  Credit shall not be taken for the creation of this source.
  48.  *    3.)  This code is not to be traded, sold, or used for personal
  49.  *         gain or profit.
  50.  *
  51.  */
  52.  
  53. #include "rogue.h"
  54.  
  55. extern short cur_room;
  56. extern char *curse_message;
  57. extern char hit_message[];
  58.  
  59. throw()
  60. {
  61.     short wch, d;
  62.     boolean first_miss = 1;
  63.     object *weapon;
  64.     short dir, row, col;
  65.     object *monster;
  66.  
  67.     while (!is_direction(dir = rgetchar(), &d)) {
  68.         sound_bell();
  69.         if (first_miss) {
  70.             message("direction? ", 0);
  71.             first_miss = 0;
  72.         }
  73.     }
  74.     check_message();
  75.     if (dir == CANCEL) {
  76.         return;
  77.     }
  78.     if ((wch = pack_letter("throw what?", WEAPON)) == CANCEL) {
  79.         return;
  80.     }
  81.     check_message();
  82.  
  83.     if (!(weapon = get_letter_object(wch))) {
  84.         message("no such item.", 0);
  85.         return;
  86.     }
  87.     if ((weapon->in_use_flags & BEING_USED) && weapon->is_cursed) {
  88.         message(curse_message, 0);
  89.         return;
  90.     }
  91.     row = rogue.row; col = rogue.col;
  92.  
  93.     if ((weapon->in_use_flags & BEING_WIELDED) && (weapon->quantity <= 1)) {
  94.         unwield(rogue.weapon);
  95.     } else if (weapon->in_use_flags & BEING_WORN) {
  96.         mv_aquatars();
  97.         unwear(rogue.armor);
  98.         print_stats(STAT_ARMOR);
  99.     } else if (weapon->in_use_flags & ON_EITHER_HAND) {
  100.         un_put_on(weapon);
  101.     }
  102.     monster = get_thrown_at_monster(weapon, d, &row, &col);
  103.     mvaddch(rogue.row, rogue.col, rogue.fchar);
  104.     refresh();
  105.  
  106.     if (rogue_can_see(row, col) && ((row != rogue.row) || (col != rogue.col))){
  107.         mvaddch(row, col, get_dungeon_char(row, col));
  108.     }
  109.     if (monster) {
  110.         wake_up(monster);
  111.         check_gold_seeker(monster);
  112.  
  113.         if (!throw_at_monster(monster, weapon)) {
  114.             flop_weapon(weapon, row, col);
  115.         }
  116.     } else {
  117.         flop_weapon(weapon, row, col);
  118.     }
  119.     vanish(weapon, 1, &rogue.pack);
  120. }
  121.  
  122. throw_at_monster(monster, weapon)
  123. object *monster, *weapon;
  124. {
  125.     short damage, hit_chance;
  126.     short t;
  127.  
  128.     hit_chance = get_hit_chance(weapon);
  129.     damage = get_weapon_damage(weapon);
  130.     if ((weapon->which_kind == ARROW) &&
  131.         (rogue.weapon && (rogue.weapon->which_kind == BOW))) {
  132.         damage += get_weapon_damage(rogue.weapon);
  133.         damage = ((damage * 2) / 3);
  134.         hit_chance += (hit_chance / 3);
  135.     } else if ((weapon->in_use_flags & BEING_WIELDED) &&
  136.         ((weapon->which_kind == DAGGER) ||
  137.         (weapon->which_kind == SHURIKEN) ||
  138.         (weapon->which_kind == DART))) {
  139.         damage = ((damage * 3) / 2);
  140.         hit_chance += (hit_chance / 3);
  141.     }
  142.     t = weapon->quantity;
  143.     weapon->quantity = 1;
  144.     sprintf(hit_message, "the %s", name_of(weapon));
  145.     weapon->quantity = t;
  146.  
  147.     if (!rand_percent(hit_chance)) {
  148.         (void) strcat(hit_message, "misses  ");
  149.         return(0);
  150.     }
  151.     s_con_mon(monster);
  152.     (void) strcat(hit_message, "hit  ");
  153.     (void) mon_damage(monster, damage);
  154.     return(1);
  155. }
  156.  
  157. object *
  158. get_thrown_at_monster(obj, dir, row, col)
  159. object *obj;
  160. short dir;
  161. short *row, *col;
  162. {
  163.     short orow, ocol;
  164.     short i, ch;
  165.  
  166.     orow = *row; ocol = *col;
  167.  
  168.     ch = get_mask_char(obj->what_is);
  169.  
  170.     for (i = 0; i < 24; i++) {
  171.         get_dir_rc(dir, row, col, 0);
  172.         if (    (((*col <= 0) || (*col >= DCOLS-1)) ||
  173.                 (dungeon[*row][*col] == NOTHING)) ||
  174.                 ((dungeon[*row][*col] & (HORWALL | VERTWALL | HIDDEN)) &&
  175.                     (!(dungeon[*row][*col] & TRAP)))) {
  176.             *row = orow;
  177.             *col = ocol;
  178.             return(0);
  179.         }
  180.         if ((i != 0) && rogue_can_see(orow, ocol)) {
  181.             mvaddch(orow, ocol, get_dungeon_char(orow, ocol));
  182.         }
  183.         if (rogue_can_see(*row, *col)) {
  184.             if (!(dungeon[*row][*col] & MONSTER)) {
  185.                 mvaddch(*row, *col, ch);
  186.             }
  187.             refresh();
  188.         }
  189.         orow = *row; ocol = *col;
  190.         if (dungeon[*row][*col] & MONSTER) {
  191.             if (!imitating(*row, *col)) {
  192.                 return(object_at(&level_monsters, *row, *col));
  193.             }
  194.         }
  195.         if (dungeon[*row][*col] & TUNNEL) {
  196.             i += 2;
  197.         }
  198.     }
  199.     return(0);
  200. }
  201.  
  202. flop_weapon(weapon, row, col)
  203. object *weapon;
  204. short row, col;
  205. {
  206.     object *new_weapon, *monster;
  207.     short i = 0;
  208.     char msg[80];
  209.     boolean found = 0;
  210.     short mch, dch;
  211.     unsigned short mon;
  212.  
  213.     while ((i < 9) && dungeon[row][col] & ~(FLOOR | TUNNEL | DOOR | MONSTER)) {
  214.         rand_around(i++, &row, &col);
  215.         if ((row > (DROWS-2)) || (row < MIN_ROW) ||
  216.             (col > (DCOLS-1)) || (col < 0) || (!dungeon[row][col]) ||
  217.             (dungeon[row][col] & ~(FLOOR | TUNNEL | DOOR | MONSTER))) {
  218.             continue;
  219.         }
  220.         found = 1;
  221.         break;
  222.     }
  223.  
  224.     if (found || (i == 0)) {
  225.         new_weapon = alloc_object();
  226.         *new_weapon = *weapon;
  227.         new_weapon->in_use_flags = NOT_USED;
  228.         new_weapon->quantity = 1;
  229.         new_weapon->ichar = 'L';
  230.         place_at(new_weapon, row, col);
  231.         if (rogue_can_see(row, col) &&
  232.                 ((row != rogue.row) || (col != rogue.col))) {
  233.             mon = dungeon[row][col] & MONSTER;
  234.             dungeon[row][col] &= (~MONSTER);
  235.             dch = get_dungeon_char(row, col);
  236.             if (mon) {
  237.                 mch = mvinch(row, col);
  238.                 if (monster = object_at(&level_monsters, row, col)) {
  239.                     monster->trail_char = dch;
  240.                 }
  241.                 if ((mch < 'A') || (mch > 'Z')) {
  242.                     mvaddch(row, col, dch);
  243.                 }
  244.             } else {
  245.                 mvaddch(row, col, dch);
  246.             }
  247.             dungeon[row][col] |= mon;
  248.         }
  249.     } else {
  250.         short t;
  251.  
  252.         t = weapon->quantity;
  253.         weapon->quantity = 1;
  254.         sprintf(msg, "the %svanishes as it hits the ground",
  255.         name_of(weapon));
  256.         weapon->quantity = t;
  257.         message(msg, 0);
  258.     }
  259. }
  260.  
  261. rand_around(i, r, c)
  262. short i, *r, *c;
  263. {
  264.     static char* pos = "\010\007\001\003\004\005\002\006\0";
  265.     static short row, col;
  266.     short j;
  267.  
  268.     if (i == 0) {
  269.         short x, y, o, t;
  270.  
  271.         row = *r;
  272.         col = *c;
  273.  
  274.         o = get_rand(1, 8);
  275.  
  276.         for (j = 0; j < 5; j++) {
  277.             x = get_rand(0, 8);
  278.             y = (x + o) % 9;
  279.             t = pos[x];
  280.             pos[x] = pos[y];
  281.             pos[y] = t;
  282.         }
  283.     }
  284.     switch((short)pos[i]) {
  285.     case 0:
  286.         *r = row + 1;
  287.         *c = col + 1;
  288.         break;
  289.     case 1:
  290.         *r = row + 1;
  291.         *c = col - 1;
  292.         break;
  293.     case 2:
  294.         *r = row - 1;
  295.         *c = col + 1;
  296.         break;
  297.     case 3:
  298.         *r = row - 1;
  299.         *c = col - 1;
  300.         break;
  301.     case 4:
  302.         *r = row;
  303.         *c = col + 1;
  304.         break;
  305.     case 5:
  306.         *r = row + 1;
  307.         *c = col;
  308.         break;
  309.     case 6:
  310.         *r = row;
  311.         *c = col;
  312.         break;
  313.     case 7:
  314.         *r = row - 1;
  315.         *c = col;
  316.         break;
  317.     case 8:
  318.         *r = row;
  319.         *c = col - 1;
  320.         break;
  321.     }
  322. }
  323.