|
|
1.1 root 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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.