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