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