|
|
1.1 ! root 1: /* ! 2: * special_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[] = "@(#)spec_hit.c 5.1 (Berkeley) 11/25/87"; ! 15: #endif /* not lint */ ! 16: ! 17: #include "rogue.h" ! 18: ! 19: short less_hp = 0; ! 20: boolean being_held; ! 21: ! 22: extern short cur_level, max_level, blind, levitate, ring_exp; ! 23: extern long level_points[]; ! 24: extern boolean detect_monster, mon_disappeared; ! 25: extern boolean sustain_strength, maintain_armor; ! 26: extern char *you_can_move_again; ! 27: ! 28: special_hit(monster) ! 29: object *monster; ! 30: { ! 31: if ((monster->m_flags & CONFUSED) && rand_percent(66)) { ! 32: return; ! 33: } ! 34: if (monster->m_flags & RUSTS) { ! 35: rust(monster); ! 36: } ! 37: if ((monster->m_flags & HOLDS) && !levitate) { ! 38: being_held = 1; ! 39: } ! 40: if (monster->m_flags & FREEZES) { ! 41: freeze(monster); ! 42: } ! 43: if (monster->m_flags & STINGS) { ! 44: sting(monster); ! 45: } ! 46: if (monster->m_flags & DRAINS_LIFE) { ! 47: drain_life(); ! 48: } ! 49: if (monster->m_flags & DROPS_LEVEL) { ! 50: drop_level(); ! 51: } ! 52: if (monster->m_flags & STEALS_GOLD) { ! 53: steal_gold(monster); ! 54: } else if (monster->m_flags & STEALS_ITEM) { ! 55: steal_item(monster); ! 56: } ! 57: } ! 58: ! 59: rust(monster) ! 60: object *monster; ! 61: { ! 62: if ((!rogue.armor) || (get_armor_class(rogue.armor) <= 1) || ! 63: (rogue.armor->which_kind == LEATHER)) { ! 64: return; ! 65: } ! 66: if ((rogue.armor->is_protected) || maintain_armor) { ! 67: if (monster && (!(monster->m_flags & RUST_VANISHED))) { ! 68: message("the rust vanishes instantly", 0); ! 69: monster->m_flags |= RUST_VANISHED; ! 70: } ! 71: } else { ! 72: rogue.armor->d_enchant--; ! 73: message("your armor weakens", 0); ! 74: print_stats(STAT_ARMOR); ! 75: } ! 76: } ! 77: ! 78: freeze(monster) ! 79: object *monster; ! 80: { ! 81: short freeze_percent = 99; ! 82: short i, n; ! 83: ! 84: if (rand_percent(12)) { ! 85: return; ! 86: } ! 87: freeze_percent -= (rogue.str_current+(rogue.str_current / 2)); ! 88: freeze_percent -= ((rogue.exp + ring_exp) * 4); ! 89: freeze_percent -= (get_armor_class(rogue.armor) * 5); ! 90: freeze_percent -= (rogue.hp_max / 3); ! 91: ! 92: if (freeze_percent > 10) { ! 93: monster->m_flags |= FREEZING_ROGUE; ! 94: message("you are frozen", 1); ! 95: ! 96: n = get_rand(4, 8); ! 97: for (i = 0; i < n; i++) { ! 98: mv_mons(); ! 99: } ! 100: if (rand_percent(freeze_percent)) { ! 101: for (i = 0; i < 50; i++) { ! 102: mv_mons(); ! 103: } ! 104: killed_by((object *)0, HYPOTHERMIA); ! 105: } ! 106: message(you_can_move_again, 1); ! 107: monster->m_flags &= (~FREEZING_ROGUE); ! 108: } ! 109: } ! 110: ! 111: steal_gold(monster) ! 112: object *monster; ! 113: { ! 114: int amount; ! 115: ! 116: if ((rogue.gold <= 0) || rand_percent(10)) { ! 117: return; ! 118: } ! 119: ! 120: amount = get_rand((cur_level * 10), (cur_level * 30)); ! 121: ! 122: if (amount > rogue.gold) { ! 123: amount = rogue.gold; ! 124: } ! 125: rogue.gold -= amount; ! 126: message("your purse feels lighter", 0); ! 127: print_stats(STAT_GOLD); ! 128: disappear(monster); ! 129: } ! 130: ! 131: steal_item(monster) ! 132: object *monster; ! 133: { ! 134: object *obj; ! 135: short i, n, t; ! 136: char desc[80]; ! 137: boolean has_something = 0; ! 138: ! 139: if (rand_percent(15)) { ! 140: return; ! 141: } ! 142: obj = rogue.pack.next_object; ! 143: ! 144: if (!obj) { ! 145: goto DSPR; ! 146: } ! 147: while (obj) { ! 148: if (!(obj->in_use_flags & BEING_USED)) { ! 149: has_something = 1; ! 150: break; ! 151: } ! 152: obj = obj->next_object; ! 153: } ! 154: if (!has_something) { ! 155: goto DSPR; ! 156: } ! 157: n = get_rand(0, MAX_PACK_COUNT); ! 158: obj = rogue.pack.next_object; ! 159: ! 160: for (i = 0; i <= n; i++) { ! 161: obj = obj->next_object; ! 162: while ((!obj) || (obj->in_use_flags & BEING_USED)) { ! 163: if (!obj) { ! 164: obj = rogue.pack.next_object; ! 165: } else { ! 166: obj = obj->next_object; ! 167: } ! 168: } ! 169: } ! 170: (void) strcpy(desc, "she stole "); ! 171: if (obj->what_is != WEAPON) { ! 172: t = obj->quantity; ! 173: obj->quantity = 1; ! 174: } ! 175: get_desc(obj, desc+10); ! 176: message(desc, 0); ! 177: ! 178: obj->quantity = ((obj->what_is != WEAPON) ? t : 1); ! 179: ! 180: vanish(obj, 0, &rogue.pack); ! 181: DSPR: ! 182: disappear(monster); ! 183: } ! 184: ! 185: disappear(monster) ! 186: object *monster; ! 187: { ! 188: short row, col; ! 189: ! 190: row = monster->row; ! 191: col = monster->col; ! 192: ! 193: dungeon[row][col] &= ~MONSTER; ! 194: if (rogue_can_see(row, col)) { ! 195: mvaddch(row, col, get_dungeon_char(row, col)); ! 196: } ! 197: take_from_pack(monster, &level_monsters); ! 198: free_object(monster); ! 199: mon_disappeared = 1; ! 200: } ! 201: ! 202: cough_up(monster) ! 203: object *monster; ! 204: { ! 205: object *obj; ! 206: short row, col, i, n; ! 207: ! 208: if (cur_level < max_level) { ! 209: return; ! 210: } ! 211: ! 212: if (monster->m_flags & STEALS_GOLD) { ! 213: obj = alloc_object(); ! 214: obj->what_is = GOLD; ! 215: obj->quantity = get_rand((cur_level * 15), (cur_level * 30)); ! 216: } else { ! 217: if (!rand_percent((int) monster->drop_percent)) { ! 218: return; ! 219: } ! 220: obj = gr_object(); ! 221: } ! 222: row = monster->row; ! 223: col = monster->col; ! 224: ! 225: for (n = 0; n <= 5; n++) { ! 226: for (i = -n; i <= n; i++) { ! 227: if (try_to_cough(row+n, col+i, obj)) { ! 228: return; ! 229: } ! 230: if (try_to_cough(row-n, col+i, obj)) { ! 231: return; ! 232: } ! 233: } ! 234: for (i = -n; i <= n; i++) { ! 235: if (try_to_cough(row+i, col-n, obj)) { ! 236: return; ! 237: } ! 238: if (try_to_cough(row+i, col+n, obj)) { ! 239: return; ! 240: } ! 241: } ! 242: } ! 243: free_object(obj); ! 244: } ! 245: ! 246: try_to_cough(row, col, obj) ! 247: short row, col; ! 248: object *obj; ! 249: { ! 250: if ((row < MIN_ROW) || (row > (DROWS-2)) || (col < 0) || (col>(DCOLS-1))) { ! 251: return(0); ! 252: } ! 253: if ((!(dungeon[row][col] & (OBJECT | STAIRS | TRAP))) && ! 254: (dungeon[row][col] & (TUNNEL | FLOOR | DOOR))) { ! 255: place_at(obj, row, col); ! 256: if (((row != rogue.row) || (col != rogue.col)) && ! 257: (!(dungeon[row][col] & MONSTER))) { ! 258: mvaddch(row, col, get_dungeon_char(row, col)); ! 259: } ! 260: return(1); ! 261: } ! 262: return(0); ! 263: } ! 264: ! 265: seek_gold(monster) ! 266: object *monster; ! 267: { ! 268: short i, j, rn, s; ! 269: ! 270: if ((rn = get_room_number(monster->row, monster->col)) < 0) { ! 271: return(0); ! 272: } ! 273: for (i = rooms[rn].top_row+1; i < rooms[rn].bottom_row; i++) { ! 274: for (j = rooms[rn].left_col+1; j < rooms[rn].right_col; j++) { ! 275: if ((gold_at(i, j)) && !(dungeon[i][j] & MONSTER)) { ! 276: monster->m_flags |= CAN_FLIT; ! 277: s = mon_can_go(monster, i, j); ! 278: monster->m_flags &= (~CAN_FLIT); ! 279: if (s) { ! 280: move_mon_to(monster, i, j); ! 281: monster->m_flags |= ASLEEP; ! 282: monster->m_flags &= (~(WAKENS | SEEKS_GOLD)); ! 283: return(1); ! 284: } ! 285: monster->m_flags &= (~SEEKS_GOLD); ! 286: monster->m_flags |= CAN_FLIT; ! 287: mv_1_monster(monster, i, j); ! 288: monster->m_flags &= (~CAN_FLIT); ! 289: monster->m_flags |= SEEKS_GOLD; ! 290: return(1); ! 291: } ! 292: } ! 293: } ! 294: return(0); ! 295: } ! 296: ! 297: gold_at(row, col) ! 298: short row, col; ! 299: { ! 300: if (dungeon[row][col] & OBJECT) { ! 301: object *obj; ! 302: ! 303: if ((obj = object_at(&level_objects, row, col)) && ! 304: (obj->what_is == GOLD)) { ! 305: return(1); ! 306: } ! 307: } ! 308: return(0); ! 309: } ! 310: ! 311: check_gold_seeker(monster) ! 312: object *monster; ! 313: { ! 314: monster->m_flags &= (~SEEKS_GOLD); ! 315: } ! 316: ! 317: check_imitator(monster) ! 318: object *monster; ! 319: { ! 320: char msg[80]; ! 321: ! 322: if (monster->m_flags & IMITATES) { ! 323: wake_up(monster); ! 324: if (!blind) { ! 325: mvaddch(monster->row, monster->col, ! 326: get_dungeon_char(monster->row, monster->col)); ! 327: check_message(); ! 328: sprintf(msg, "wait, that's a %s!", mon_name(monster)); ! 329: message(msg, 1); ! 330: } ! 331: return(1); ! 332: } ! 333: return(0); ! 334: } ! 335: ! 336: imitating(row, col) ! 337: register short row, col; ! 338: { ! 339: if (dungeon[row][col] & MONSTER) { ! 340: object *object_at(), *monster; ! 341: ! 342: if (monster = object_at(&level_monsters, row, col)) { ! 343: if (monster->m_flags & IMITATES) { ! 344: return(1); ! 345: } ! 346: } ! 347: } ! 348: return(0); ! 349: } ! 350: ! 351: sting(monster) ! 352: object *monster; ! 353: { ! 354: short sting_chance = 35; ! 355: char msg[80]; ! 356: ! 357: if ((rogue.str_current <= 3) || sustain_strength) { ! 358: return; ! 359: } ! 360: sting_chance += (6 * (6 - get_armor_class(rogue.armor))); ! 361: ! 362: if ((rogue.exp + ring_exp) > 8) { ! 363: sting_chance -= (6 * ((rogue.exp + ring_exp) - 8)); ! 364: } ! 365: if (rand_percent(sting_chance)) { ! 366: sprintf(msg, "the %s's bite has weakened you", ! 367: mon_name(monster)); ! 368: message(msg, 0); ! 369: rogue.str_current--; ! 370: print_stats(STAT_STRENGTH); ! 371: } ! 372: } ! 373: ! 374: drop_level() ! 375: { ! 376: int hp; ! 377: ! 378: if (rand_percent(80) || (rogue.exp <= 5)) { ! 379: return; ! 380: } ! 381: rogue.exp_points = level_points[rogue.exp-2] - get_rand(9, 29); ! 382: rogue.exp -= 2; ! 383: hp = hp_raise(); ! 384: if ((rogue.hp_current -= hp) <= 0) { ! 385: rogue.hp_current = 1; ! 386: } ! 387: if ((rogue.hp_max -= hp) <= 0) { ! 388: rogue.hp_max = 1; ! 389: } ! 390: add_exp(1, 0); ! 391: } ! 392: ! 393: drain_life() ! 394: { ! 395: short n; ! 396: ! 397: if (rand_percent(60) || (rogue.hp_max <= 30) || (rogue.hp_current < 10)) { ! 398: return; ! 399: } ! 400: n = get_rand(1, 3); /* 1 Hp, 2 Str, 3 both */ ! 401: ! 402: if ((n != 2) || (!sustain_strength)) { ! 403: message("you feel weaker", 0); ! 404: } ! 405: if (n != 2) { ! 406: rogue.hp_max--; ! 407: rogue.hp_current--; ! 408: less_hp++; ! 409: } ! 410: if (n != 1) { ! 411: if ((rogue.str_current > 3) && (!sustain_strength)) { ! 412: rogue.str_current--; ! 413: if (coin_toss()) { ! 414: rogue.str_max--; ! 415: } ! 416: } ! 417: } ! 418: print_stats((STAT_STRENGTH | STAT_HP)); ! 419: } ! 420: ! 421: m_confuse(monster) ! 422: object *monster; ! 423: { ! 424: char msg[80]; ! 425: ! 426: if (!rogue_can_see(monster->row, monster->col)) { ! 427: return(0); ! 428: } ! 429: if (rand_percent(45)) { ! 430: monster->m_flags &= (~CONFUSES); /* will not confuse the rogue */ ! 431: return(0); ! 432: } ! 433: if (rand_percent(55)) { ! 434: monster->m_flags &= (~CONFUSES); ! 435: sprintf(msg, "the gaze of the %s has confused you", mon_name(monster)); ! 436: message(msg, 1); ! 437: cnfs(); ! 438: return(1); ! 439: } ! 440: return(0); ! 441: } ! 442: ! 443: flame_broil(monster) ! 444: object *monster; ! 445: { ! 446: short row, col, dir; ! 447: ! 448: if ((!mon_sees(monster, rogue.row, rogue.col)) || coin_toss()) { ! 449: return(0); ! 450: } ! 451: row = rogue.row - monster->row; ! 452: col = rogue.col - monster->col; ! 453: if (row < 0) { ! 454: row = -row; ! 455: } ! 456: if (col < 0) { ! 457: col = -col; ! 458: } ! 459: if (((row != 0) && (col != 0) && (row != col)) || ! 460: ((row > 7) || (col > 7))) { ! 461: return(0); ! 462: } ! 463: dir = get_dir(monster->row, monster->col, row, col); ! 464: bounce(FIRE, dir, monster->row, monster->col, 0); ! 465: ! 466: return(1); ! 467: } ! 468: ! 469: get_dir(srow, scol, drow, dcol) ! 470: short srow, scol, drow, dcol; ! 471: { ! 472: if (srow == drow) { ! 473: if (scol < dcol) { ! 474: return(RIGHT); ! 475: } else { ! 476: return(LEFT); ! 477: } ! 478: } ! 479: if (scol == dcol) { ! 480: if (srow < drow) { ! 481: return(DOWN); ! 482: } else { ! 483: return(UPWARD); ! 484: } ! 485: } ! 486: if ((srow > drow) && (scol > dcol)) { ! 487: return(UPLEFT); ! 488: } ! 489: if ((srow < drow) && (scol < dcol)) { ! 490: return(DOWNRIGHT); ! 491: } ! 492: if ((srow < drow) && (scol > dcol)) { ! 493: return(DOWNLEFT); ! 494: } ! 495: /*if ((srow > drow) && (scol < dcol)) {*/ ! 496: return(UPRIGHT); ! 497: /*}*/ ! 498: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.