# 2.11BSD#431 - /usr/src/games/rogue/spec_hit.c

##### Functions

    check_gold_seeker X
    check_imitator    X
    cough_up          X
    disappear         X
    drain_life        X
    drop_level        X
    flame_broil       X
    freeze            X
    get_dir           X
    gold_at           X
    imitating         X
    m_confuse         X
    rust              X
    seek_gold         X
    special_hit       X
    steal_gold        X
    steal_item        X
    sting             X
    try_to_cough      X

##### Variables

    less_hp           X

       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_gold_seeker defined in line 311; used 2 times

- in /usr/src/games/rogue/hit.c line 120
- in /usr/src/games/rogue/throw.c line 75

check_imitator defined in line 317; used 1 times

- in /usr/src/games/rogue/hit.c line 94

cough_up defined in line 202; used 1 times

- in /usr/src/games/rogue/hit.c line 268

disappear defined in line 185; used 2 times

- in line 128, 182

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

- in /usr/src/games/rogue/monster.c line 297

freeze defined in line 78; used 1 times

- in line 41

get_dir defined in line 469; used 1 times

- in line 463

gold_at defined in line 297; used 1 times

- in line 275

imitating defined in line 336; used 3 times

- in /usr/src/games/rogue/room.c line 122
- in /usr/src/games/rogue/throw.c line 155
- in /usr/src/games/rogue/zap.c line 94

m_confuse defined in line 421; used 1 times

- in /usr/src/games/rogue/monster.c line 290

rust defined in line 59; used 2 times

- in line 35
- in /usr/src/games/rogue/trap.c line 105

seek_gold defined in line 265; used 1 times

- in /usr/src/games/rogue/monster.c line 300

special_hit defined in line 28; used 1 times

- in /usr/src/games/rogue/hit.c line 83

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

- in line 227-238(4)

#### Defined variables

less_hp defined in line 19; used 3 times

- in line 408
- in /usr/src/games/rogue/level.c line 824-829(2)

sccsid defined in line 14; never used

Last modified: 1987-11-26 Generated: 2016-12-26 | Generated by src2html V0.67 page hit count: 2158 |