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