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

Defined functions

damage_for_strength defined in line 222; used 1 times
fight defined in line 285; used 2 times
get_damage defined in line 141; used 4 times
get_hit_chance defined in line 389; used 2 times
get_number defined in line 186; used 6 times
get_w_damage defined in line 167; used 1 times
get_weapon_damage defined in line 400; used 3 times
lget_number defined in line 199; used 3 times
mon_damage defined in line 252; used 6 times
mon_hit defined in line 26; used 1 times
rogue_damage defined in line 125; used 2 times
rogue_hit defined in line 87; used 2 times
s_con_mon defined in line 411; used 3 times
to_hit defined in line 213; used 4 times

Defined variables

fight_monster defined in line 19; used 17 times
hit_message defined in line 20; used 20 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: 4049
Valid CSS Valid XHTML 1.0 Strict