|
|
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.