|
|
1.1 root 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 are permitted
9: * provided that: (1) source distributions retain this entire copyright
10: * notice and comment, and (2) distributions including binaries display
11: * the following acknowledgement: ``This product includes software
12: * developed by the University of California, Berkeley and its contributors''
13: * in the documentation or other materials provided with the distribution
14: * and in all advertising materials mentioning features or use of this
15: * software. Neither the name of the University nor the names of its
16: * contributors may be used to endorse or promote products derived
17: * from this software without specific prior written permission.
18: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
19: * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
20: * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
21: */
22:
23: #ifndef lint
24: static char sccsid[] = "@(#)hit.c 5.3 (Berkeley) 6/1/90";
25: #endif /* not lint */
26:
27: /*
28: * hit.c
29: *
30: * This source herein may be modified and/or distributed by anybody who
31: * so desires, with the following restrictions:
32: * 1.) No portion of this notice shall be removed.
33: * 2.) Credit shall not be taken for the creation of this source.
34: * 3.) This code is not to be traded, sold, or used for personal
35: * gain or profit.
36: *
37: */
38:
39: #include "rogue.h"
40:
41: object *fight_monster = 0;
42: char hit_message[80] = "";
43:
44: extern short halluc, blind, cur_level;
45: extern short add_strength, ring_exp, r_rings;
46: extern boolean being_held, interrupted, wizard, con_mon;
47:
48: mon_hit(monster)
49: register object *monster;
50: {
51: short damage, hit_chance;
52: char *mn;
53: float minus;
54:
55: if (fight_monster && (monster != fight_monster)) {
56: fight_monster = 0;
57: }
58: monster->trow = NO_ROOM;
59: if (cur_level >= (AMULET_LEVEL * 2)) {
60: hit_chance = 100;
61: } else {
62: hit_chance = monster->m_hit_chance;
63: hit_chance -= (((2 * rogue.exp) + (2 * ring_exp)) - r_rings);
64: }
65: if (wizard) {
66: hit_chance /= 2;
67: }
68: if (!fight_monster) {
69: interrupted = 1;
70: }
71: mn = mon_name(monster);
72:
73: if (!rand_percent(hit_chance)) {
74: if (!fight_monster) {
75: sprintf(hit_message + strlen(hit_message), "the %s misses", mn);
76: message(hit_message, 1);
77: hit_message[0] = 0;
78: }
79: return;
80: }
81: if (!fight_monster) {
82: sprintf(hit_message + strlen(hit_message), "the %s hit", mn);
83: message(hit_message, 1);
84: hit_message[0] = 0;
85: }
86: if (!(monster->m_flags & STATIONARY)) {
87: damage = get_damage(monster->m_damage, 1);
88: if (cur_level >= (AMULET_LEVEL * 2)) {
89: minus = (float) ((AMULET_LEVEL * 2) - cur_level);
90: } else {
91: minus = (float) get_armor_class(rogue.armor) * 3.00;
92: minus = minus/100.00 * (float) damage;
93: }
94: damage -= (short) minus;
95: } else {
96: damage = monster->stationary_damage++;
97: }
98: if (wizard) {
99: damage /= 3;
100: }
101: if (damage > 0) {
102: rogue_damage(damage, monster, 0);
103: }
104: if (monster->m_flags & SPECIAL_HIT) {
105: special_hit(monster);
106: }
107: }
108:
109: rogue_hit(monster, force_hit)
110: register object *monster;
111: boolean force_hit;
112: {
113: short damage, hit_chance;
114:
115: if (monster) {
116: if (check_imitator(monster)) {
117: return;
118: }
119: hit_chance = force_hit ? 100 : get_hit_chance(rogue.weapon);
120:
121: if (wizard) {
122: hit_chance *= 2;
123: }
124: if (!rand_percent(hit_chance)) {
125: if (!fight_monster) {
126: (void) strcpy(hit_message, "you miss ");
127: }
128: goto RET;
129: }
130: damage = get_weapon_damage(rogue.weapon);
131: if (wizard) {
132: damage *= 3;
133: }
134: if (con_mon) {
135: s_con_mon(monster);
136: }
137: if (mon_damage(monster, damage)) { /* still alive? */
138: if (!fight_monster) {
139: (void) strcpy(hit_message, "you hit ");
140: }
141: }
142: RET: check_gold_seeker(monster);
143: wake_up(monster);
144: }
145: }
146:
147: rogue_damage(d, monster, other)
148: short d;
149: object *monster;
150: short other;
151: {
152: if (d >= rogue.hp_current) {
153: rogue.hp_current = 0;
154: print_stats(STAT_HP);
155: killed_by(monster, other);
156: }
157: if (d > 0) {
158: rogue.hp_current -= d;
159: print_stats(STAT_HP);
160: }
161: }
162:
163: get_damage(ds, r)
164: char *ds;
165: boolean r;
166: {
167: register i = 0, j, n, d, total = 0;
168:
169: while (ds[i]) {
170: n = get_number(ds+i);
171: while (ds[i++] != 'd') ;
172: d = get_number(ds+i);
173: while ((ds[i] != '/') && ds[i]) i++;
174:
175: for (j = 0; j < n; j++) {
176: if (r) {
177: total += get_rand(1, d);
178: } else {
179: total += d;
180: }
181: }
182: if (ds[i] == '/') {
183: i++;
184: }
185: }
186: return(total);
187: }
188:
189: get_w_damage(obj)
190: object *obj;
191: {
192: char new_damage[12];
193: register to_hit, damage;
194: register i = 0;
195:
196: if ((!obj) || (obj->what_is != WEAPON)) {
197: return(-1);
198: }
199: to_hit = get_number(obj->damage) + obj->hit_enchant;
200: while (obj->damage[i++] != 'd') ;
201: damage = get_number(obj->damage + i) + obj->d_enchant;
202:
203: sprintf(new_damage, "%dd%d", to_hit, damage);
204:
205: return(get_damage(new_damage, 1));
206: }
207:
208: get_number(s)
209: register char *s;
210: {
211: register i = 0;
212: register total = 0;
213:
214: while ((s[i] >= '0') && (s[i] <= '9')) {
215: total = (10 * total) + (s[i] - '0');
216: i++;
217: }
218: return(total);
219: }
220:
221: long
222: lget_number(s)
223: char *s;
224: {
225: short i = 0;
226: long total = 0;
227:
228: while ((s[i] >= '0') && (s[i] <= '9')) {
229: total = (10 * total) + (s[i] - '0');
230: i++;
231: }
232: return(total);
233: }
234:
235: to_hit(obj)
236: object *obj;
237: {
238: if (!obj) {
239: return(1);
240: }
241: return(get_number(obj->damage) + obj->hit_enchant);
242: }
243:
244: damage_for_strength()
245: {
246: short strength;
247:
248: strength = rogue.str_current + add_strength;
249:
250: if (strength <= 6) {
251: return(strength-5);
252: }
253: if (strength <= 14) {
254: return(1);
255: }
256: if (strength <= 17) {
257: return(3);
258: }
259: if (strength <= 18) {
260: return(4);
261: }
262: if (strength <= 20) {
263: return(5);
264: }
265: if (strength <= 21) {
266: return(6);
267: }
268: if (strength <= 30) {
269: return(7);
270: }
271: return(8);
272: }
273:
274: mon_damage(monster, damage)
275: object *monster;
276: short damage;
277: {
278: char *mn;
279: short row, col;
280:
281: monster->hp_to_kill -= damage;
282:
283: if (monster->hp_to_kill <= 0) {
284: row = monster->row;
285: col = monster->col;
286: dungeon[row][col] &= ~MONSTER;
287: mvaddch(row, col, (int) get_dungeon_char(row, col));
288:
289: fight_monster = 0;
290: cough_up(monster);
291: mn = mon_name(monster);
292: sprintf(hit_message+strlen(hit_message), "defeated the %s", mn);
293: message(hit_message, 1);
294: hit_message[0] = 0;
295: add_exp(monster->kill_exp, 1);
296: take_from_pack(monster, &level_monsters);
297:
298: if (monster->m_flags & HOLDS) {
299: being_held = 0;
300: }
301: free_object(monster);
302: return(0);
303: }
304: return(1);
305: }
306:
307: fight(to_the_death)
308: boolean to_the_death;
309: {
310: short ch, c, d;
311: short row, col;
312: boolean first_miss = 1;
313: short possible_damage;
314: object *monster;
315:
316: while (!is_direction(ch = rgetchar(), &d)) {
317: sound_bell();
318: if (first_miss) {
319: message("direction?", 0);
320: first_miss = 0;
321: }
322: }
323: check_message();
324: if (ch == CANCEL) {
325: return;
326: }
327: row = rogue.row; col = rogue.col;
328: get_dir_rc(d, &row, &col, 0);
329:
330: c = mvinch(row, col);
331: if (((c < 'A') || (c > 'Z')) ||
332: (!can_move(rogue.row, rogue.col, row, col))) {
333: message("I see no monster there", 0);
334: return;
335: }
336: if (!(fight_monster = object_at(&level_monsters, row, col))) {
337: return;
338: }
339: if (!(fight_monster->m_flags & STATIONARY)) {
340: possible_damage = ((get_damage(fight_monster->m_damage, 0) * 2) / 3);
341: } else {
342: possible_damage = fight_monster->stationary_damage - 1;
343: }
344: while (fight_monster) {
345: (void) one_move_rogue(ch, 0);
346: if (((!to_the_death) && (rogue.hp_current <= possible_damage)) ||
347: interrupted || (!(dungeon[row][col] & MONSTER))) {
348: fight_monster = 0;
349: } else {
350: monster = object_at(&level_monsters, row, col);
351: if (monster != fight_monster) {
352: fight_monster = 0;
353: }
354: }
355: }
356: }
357:
358: get_dir_rc(dir, row, col, allow_off_screen)
359: short dir;
360: short *row, *col;
361: short allow_off_screen;
362: {
363: switch(dir) {
364: case LEFT:
365: if (allow_off_screen || (*col > 0)) {
366: (*col)--;
367: }
368: break;
369: case DOWN:
370: if (allow_off_screen || (*row < (DROWS-2))) {
371: (*row)++;
372: }
373: break;
374: case UPWARD:
375: if (allow_off_screen || (*row > MIN_ROW)) {
376: (*row)--;
377: }
378: break;
379: case RIGHT:
380: if (allow_off_screen || (*col < (DCOLS-1))) {
381: (*col)++;
382: }
383: break;
384: case UPLEFT:
385: if (allow_off_screen || ((*row > MIN_ROW) && (*col > 0))) {
386: (*row)--;
387: (*col)--;
388: }
389: break;
390: case UPRIGHT:
391: if (allow_off_screen || ((*row > MIN_ROW) && (*col < (DCOLS-1)))) {
392: (*row)--;
393: (*col)++;
394: }
395: break;
396: case DOWNRIGHT:
397: if (allow_off_screen || ((*row < (DROWS-2)) && (*col < (DCOLS-1)))) {
398: (*row)++;
399: (*col)++;
400: }
401: break;
402: case DOWNLEFT:
403: if (allow_off_screen || ((*row < (DROWS-2)) && (*col > 0))) {
404: (*row)++;
405: (*col)--;
406: }
407: break;
408: }
409: }
410:
411: get_hit_chance(weapon)
412: object *weapon;
413: {
414: short hit_chance;
415:
416: hit_chance = 40;
417: hit_chance += 3 * to_hit(weapon);
418: hit_chance += (((2 * rogue.exp) + (2 * ring_exp)) - r_rings);
419: return(hit_chance);
420: }
421:
422: get_weapon_damage(weapon)
423: object *weapon;
424: {
425: short damage;
426:
427: damage = get_w_damage(weapon);
428: damage += damage_for_strength();
429: damage += ((((rogue.exp + ring_exp) - r_rings) + 1) / 2);
430: return(damage);
431: }
432:
433: s_con_mon(monster)
434: object *monster;
435: {
436: if (con_mon) {
437: monster->m_flags |= CONFUSED;
438: monster->moves_confused += get_rand(12, 22);
439: message("the monster appears confused", 0);
440: con_mon = 0;
441: }
442: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.