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: }

Defined functions

check_imitator defined in line 317; used 1 times
cough_up defined in line 202; used 1 times
disappear defined in line 185; used 2 times
drain_life defined in line 393; used 1 times
  • in line 47
drop_level defined in line 374; used 1 times
  • in line 50
flame_broil defined in line 443; used 1 times
freeze defined in line 78; used 1 times
  • in line 41
get_dir defined in line 469; used 1 times
gold_at defined in line 297; used 1 times
m_confuse defined in line 421; used 1 times
rust defined in line 59; used 2 times
seek_gold defined in line 265; used 1 times
special_hit defined in line 28; used 1 times
steal_gold defined in line 111; used 1 times
  • in line 53
steal_item defined in line 131; used 1 times
  • in line 55
sting defined in line 351; used 1 times
  • in line 44
try_to_cough defined in line 246; used 4 times

Defined variables

less_hp defined in line 19; used 3 times
sccsid defined in line 14; never used
Last modified: 1987-11-26
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 4331
Valid CSS Valid XHTML 1.0 Strict