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