Annotation of early-roguelike/arogue7/effects.c, Revision 1.1
1.1 ! rubenllo 1: /*
! 2: * effects.c - functions for dealing with appllying effects to monsters
! 3: *
! 4: * Advanced Rogue
! 5: * Copyright (C) 1984, 1985, 1986 Michael Morgan, Ken Dalka and AT&T
! 6: * All rights reserved.
! 7: *
! 8: * Based on "Rogue: Exploring the Dungeons of Doom"
! 9: * Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman
! 10: * All rights reserved.
! 11: *
! 12: * See the file LICENSE.TXT for full copyright and licensing information.
! 13: */
! 14:
! 15: #include <string.h>
! 16: #include "curses.h"
! 17: #include "rogue.h"
! 18:
! 19: /*
! 20: * effect:
! 21: * Check for effects of one thing hitting another thing. Return
! 22: * the reason code if the defender is killed. Otherwise return 0.
! 23: */
! 24: int
! 25: effect(struct thing *att, struct thing *def, struct object *weap, bool thrown,
! 26: bool see_att, bool see_def)
! 27: {
! 28: register bool att_player, def_player;
! 29: char attname[LINELEN+1], defname[LINELEN+1];
! 30:
! 31: /* See if the attacker or defender is the player */
! 32: att_player = (att == &player);
! 33: def_player = (def == &player);
! 34:
! 35: /*
! 36: * If the player could see the attacker or defender, they can't
! 37: * surprise anymore (don't bother checking if they could).
! 38: */
! 39: if (see_att) turn_off(*att, CANSURPRISE);
! 40: if (see_def) turn_off(*def, CANSURPRISE);
! 41:
! 42: /* What are the attacker and defender names? */
! 43: if (att_player) strcpy(attname, "you");
! 44: else {
! 45: if (see_att) strcpy(attname, monster_name(att));
! 46: else strcpy(attname, "something");
! 47: }
! 48:
! 49: if (def_player) strcpy(defname, "you");
! 50: else {
! 51: if (see_def) strcpy(defname, monster_name(def));
! 52: else strcpy(defname, "something");
! 53: }
! 54:
! 55: /*
! 56: * See what happens to the attacker first. We can skip this
! 57: * whole section, however, if the defender is the player.
! 58: * Nothing happens (yet) to anyone just for hitting the player.
! 59: */
! 60: if (!def_player) {
! 61: if (!thrown) { /* Some things require a direct hit. */
! 62: /*
! 63: * If the attacker hits a rusting monster, The weapon
! 64: * may be damaged
! 65: */
! 66: if (on(*def, CANRUST) && weap &&
! 67: weap->o_type != RELIC && (weap->o_flags & ISMETAL) &&
! 68: !(weap->o_flags & ISPROT)) {
! 69: if ((weap->o_hplus < 1 && weap->o_dplus < 1) ||
! 70: roll(1,20) < weap->o_hplus+weap->o_dplus+10) {
! 71: if (rnd(100) < 50) weap->o_hplus--;
! 72: else weap->o_dplus--;
! 73: if (att_player)
! 74: msg(terse ? "Your %s weakens!"
! 75: : "Your %s appears to be weaker now!",
! 76: weaps[weap->o_which].w_name);
! 77: }
! 78: }
! 79: }
! 80:
! 81: /* If the attacker hit something that shrieks, wake the dungeon */
! 82: if (on(*def, CANSHRIEK)) {
! 83: turn_off(*def, CANSHRIEK);
! 84: if (see_def)
! 85: msg("%s emits a piercing shriek.", prname(defname, TRUE));
! 86: else msg("You hear a piercing shriek.");
! 87: aggravate(TRUE, TRUE);
! 88: }
! 89:
! 90: /*
! 91: * does the creature explode when hit?
! 92: */
! 93: if (on(*def, CANEXPLODE)) {
! 94: if (see_def) msg("%s explodes!", prname(defname, TRUE));
! 95: else msg("You hear a tremendous explosion!");
! 96: explode(def);
! 97: if (pstats.s_hpt <= 0)
! 98: death(def->t_index);
! 99: }
! 100: }
! 101:
! 102: /*
! 103: * Now let's see what happens to the defender. Start out with
! 104: * the things that everyone can do. Then exit if the attacker
! 105: * is the player.
! 106: */
! 107: if (!thrown) {
! 108: /*
! 109: * Can the player confuse?
! 110: */
! 111: if (on(*att, CANHUH) && att_player) {
! 112: msg("Your hands stop glowing red.");
! 113: if (off(*def, ISCLEAR) &&
! 114: (off(*def, ISUNIQUE) || !save(VS_MAGIC, def, 0))) {
! 115: if (see_def) msg("%s appears confused.", prname(defname, TRUE));
! 116: turn_on(*def, ISHUH);
! 117: }
! 118: turn_off(*att, CANHUH);
! 119: }
! 120:
! 121: /* Return now if the attacker is the player. */
! 122: if (att_player) return(0);
! 123:
! 124: /*
! 125: * Some monsters may take half your hit points
! 126: */
! 127: if (on(*att, CANSUCK) && !save(VS_MAGIC, def, 0)) {
! 128: if (def->t_stats.s_hpt == 1) return(att->t_index); /* Killed! */
! 129: else {
! 130: def->t_stats.s_hpt /= 2;
! 131: if (def_player)
! 132: msg("You feel your life force being drawn from you.");
! 133: }
! 134: }
! 135:
! 136: /*
! 137: * If a hugging monster hits, it may SQUEEEEEEEZE.
! 138: */
! 139: if (on(*att, CANHUG)) {
! 140: if (roll(1,20) >= 18 || roll(1,20) >= 18) {
! 141: if (def_player)
! 142: msg("%s squeezes you against itself.",
! 143: prname(attname, TRUE));
! 144: else if (see_att)
! 145: msg("%s squeezes hard.", prname(attname, TRUE));
! 146:
! 147: if ((def->t_stats.s_hpt -= roll(2,8)) <= 0)
! 148: return(att->t_index);
! 149: }
! 150: }
! 151:
! 152: /*
! 153: * Some monsters have poisonous bites.
! 154: */
! 155: if (on(*att, CANPOISON) && !save(VS_POISON, def, 0)) {
! 156: if (def_player) {
! 157: if (ISWEARING(R_SUSABILITY))
! 158: msg(terse ? "Sting has no effect"
! 159: : "A sting momentarily weakens you");
! 160: else {
! 161: chg_str(-1);
! 162: msg(terse ? "A sting has weakened you" :
! 163: "You feel a sting in your arm and now feel weaker");
! 164: }
! 165: }
! 166: else {
! 167: /* Subtract a strength point and see if it kills it */
! 168: if (--def->t_stats.s_str <= 0) return(D_STRENGTH);
! 169: }
! 170: }
! 171:
! 172: /*
! 173: * Turning to stone:
! 174: */
! 175: if (on(*att, TOUCHSTONE)) {
! 176: if (def_player) turn_off(*att, TOUCHSTONE);
! 177: if (on(*def, CANINWALL)) {
! 178: if (def_player)
! 179: msg("%s's touch has no effect.", prname(attname, TRUE));
! 180: }
! 181: else {
! 182: if (!save(VS_PETRIFICATION, def, 0) && rnd(100) < 10) {
! 183: if (def_player) {
! 184: msg("Your body begins to solidify.");
! 185: msg("You are turned to stone !!! --More--");
! 186: wait_for(' ');
! 187: return(D_PETRIFY);
! 188: }
! 189: else {
! 190: /* The monster got stoned! */
! 191: turn_on(*def, ISSTONE);
! 192: turn_off(*def, ISRUN);
! 193: turn_off(*def, ISINVIS);
! 194: turn_off(*def, ISDISGUISE);
! 195: if (see_def)
! 196: msg("%s turns to stone.", prname(defname, TRUE));
! 197: else if (cansee(unc(def->t_pos)))
! 198: msg("A new statue appears!");
! 199: }
! 200: }
! 201: else if (def->t_action != A_FREEZE) {
! 202: if (def_player)
! 203: msg("%s's touch stiffens your limbs.",
! 204: prname(attname, TRUE));
! 205: else if (see_def)
! 206: msg("%s appears to freeze.", prname(defname, TRUE));
! 207:
! 208: def->t_no_move += movement(def) * STONETIME;
! 209: def->t_action = A_FREEZE;
! 210: }
! 211: }
! 212: }
! 213:
! 214: /*
! 215: * Wraiths might drain energy levels
! 216: */
! 217: if ((on(*att, CANDRAIN) || on(*att, DOUBLEDRAIN)) &&
! 218: !save(VS_POISON, def, 3-(att->t_stats.s_lvl/5))) {
! 219: if (def_player) {
! 220: lower_level(att->t_index);
! 221: if (on(*att, DOUBLEDRAIN)) lower_level(att->t_index);
! 222: turn_on(*att, DIDDRAIN);
! 223: }
! 224: else {
! 225: def->t_stats.s_hpt -= roll(1, 8);
! 226: def->t_stats.s_lvl--;
! 227: if (on(*att, DOUBLEDRAIN)) {
! 228: def->t_stats.s_hpt -= roll(1, 8);
! 229: def->t_stats.s_lvl--;
! 230: }
! 231: if (see_def)
! 232: msg("%s appears less skillfull.", prname(defname, TRUE));
! 233:
! 234: /* Did it kill it? */
! 235: if (def->t_stats.s_hpt <= 0 ||
! 236: def->t_stats.s_lvl <= 0)
! 237: return(att->t_index);
! 238: }
! 239: }
! 240:
! 241: /*
! 242: * Paralyzation:
! 243: */
! 244: if (on(*att, CANPARALYZE) && def->t_action != A_FREEZE) {
! 245: if (def_player) turn_off(*att, CANPARALYZE);
! 246: if (!save(VS_PARALYZATION, def, 0)) {
! 247: if (on(*def, CANINWALL)) {
! 248: if (def_player)
! 249: msg("%s's touch has no effect.", prname(attname, TRUE));
! 250: }
! 251: else {
! 252: if (def_player)
! 253: msg("%s's touch paralyzes you.", prname(attname, TRUE));
! 254: else if (see_def)
! 255: msg("%s appears to freeze.", prname(defname, TRUE));
! 256:
! 257: def->t_no_move += movement(def) * FREEZETIME;
! 258: def->t_action = A_FREEZE;
! 259: }
! 260: }
! 261: }
! 262:
! 263: /*
! 264: * Painful wounds make the defendant faint
! 265: */
! 266: if (on(*att, CANPAIN) && def->t_action != A_FREEZE) {
! 267: if (def_player) turn_off(*att, CANPAIN);
! 268: if (!ISWEARING(R_ALERT) && !save(VS_POISON, def, 0)) {
! 269: if (def_player)
! 270: msg("You faint from the painful wound");
! 271: else if (see_def)
! 272: msg("%s appears to faint.", prname(defname, TRUE));
! 273:
! 274: def->t_no_move += movement(def) * PAINTIME;
! 275: def->t_action = A_FREEZE;
! 276: }
! 277: }
! 278:
! 279: /*
! 280: * Some things currently affect only the player. Let's make
! 281: * a check here so we don't have to check for each thing.
! 282: */
! 283: if (def_player) {
! 284: /*
! 285: * Stinking monsters make the defender weaker (to hit). For now
! 286: * this will only affect the player. We may later add the HASSTINK
! 287: * effect to monsters, too.
! 288: */
! 289: if (on(*att, CANSTINK)) {
! 290: turn_off(*att, CANSTINK);
! 291: if (!save(VS_POISON, def, 0)) {
! 292: msg("The stench of %s sickens you.",
! 293: prname(attname, FALSE));
! 294: if (on(player, HASSTINK)) lengthen(unstink, STINKTIME);
! 295: else {
! 296: turn_on(player, HASSTINK);
! 297: fuse(unstink, NULL, STINKTIME, AFTER);
! 298: }
! 299: }
! 300: }
! 301:
! 302: /*
! 303: * Chilling monster reduces strength each time. This only
! 304: * affects the player for now because of its temporary nature.
! 305: */
! 306: if (on(*att, CANCHILL)) {
! 307: if (!ISWEARING(R_SUSABILITY) && !save(VS_POISON, def, 0)) {
! 308: msg("You cringe at %s's chilling touch.",
! 309: prname(attname, FALSE));
! 310: chg_str(-1);
! 311: if (lost_str++ == 0) {
! 312: int fuse_arg = 0;
! 313: fuse(res_strength, &fuse_arg, CHILLTIME, AFTER);
! 314: }
! 315: else lengthen(res_strength, CHILLTIME);
! 316: }
! 317: }
! 318:
! 319: /*
! 320: * Itching monsters reduce dexterity (temporarily). This only
! 321: * affects the player for now because of its temporary nature.
! 322: */
! 323: if (on(*att, CANITCH) && !save(VS_POISON, def, 0)) {
! 324: msg("The claws of %s scratch you.", prname(attname, FALSE));
! 325: if (ISWEARING(R_SUSABILITY)) {
! 326: msg("The scratch has no effect");
! 327: }
! 328: else {
! 329: add_abil[A_DEXTERITY](-1);
! 330: }
! 331: }
! 332:
! 333:
! 334: /*
! 335: * If a disease-carrying monster hits, there is a chance the
! 336: * defender will catch the disease. This only applies to the
! 337: * player for now because of the temporary nature.
! 338: */
! 339: if (on(*att, CANDISEASE) &&
! 340: (rnd(def->t_stats.s_const) < att->t_stats.s_lvl) &&
! 341: off(*def, HASDISEASE)) {
! 342: if (ISWEARING(R_HEALTH) ||
! 343: player.t_ctype == C_PALADIN ||
! 344: player.t_ctype == C_MONK) {
! 345: msg("The wound heals quickly.");
! 346: }
! 347: else {
! 348: turn_on(*def, HASDISEASE);
! 349: fuse(cure_disease, NULL, roll(HEALTIME,SICKTIME), AFTER);
! 350: msg(terse ? "You have been diseased."
! 351: : "You have contracted a disease!");
! 352: }
! 353: }
! 354:
! 355: /*
! 356: * If a rusting monster hits, you lose armor. This only applies to
! 357: * the player because monsters don't wear armor (for now).
! 358: */
! 359: if (on(*att, CANRUST)) {
! 360: if (cur_armor != NULL &&
! 361: cur_armor->o_which != LEATHER &&
! 362: cur_armor->o_which != STUDDED_LEATHER &&
! 363: cur_armor->o_which != PADDED_ARMOR &&
! 364: !(cur_armor->o_flags & ISPROT) &&
! 365: cur_armor->o_ac < def->t_stats.s_arm+1) {
! 366: msg(terse ? "Your armor weakens"
! 367: : "Your armor appears to be weaker now. Oh my!");
! 368: cur_armor->o_ac++;
! 369: }
! 370: if (cur_misc[WEAR_BRACERS] != NULL &&
! 371: cur_misc[WEAR_BRACERS]->o_ac > 0 &&
! 372: !(cur_misc[WEAR_BRACERS]->o_flags & ISPROT)) {
! 373: cur_misc[WEAR_BRACERS]->o_ac--;
! 374: if (cur_misc[WEAR_BRACERS]->o_ac == 0) {
! 375: register struct linked_list *item;
! 376:
! 377: for (item=pack; item!=NULL; item=next(item)) {
! 378: if (OBJPTR(item) == cur_misc[WEAR_BRACERS]) {
! 379: detach(pack, item);
! 380: o_discard(item);
! 381: break;
! 382: }
! 383: }
! 384: msg ("Your bracers crumble and fall off!");
! 385: cur_misc[WEAR_BRACERS] = NULL;
! 386: inpack--;
! 387: }
! 388: else {
! 389: msg("Your bracers weaken!");
! 390: }
! 391: }
! 392: }
! 393:
! 394: /*
! 395: * If can dissolve and hero has leather type armor. This
! 396: * also only applies to the player for now because of the
! 397: * armor.
! 398: */
! 399: if (on(*att, CANDISSOLVE) && cur_armor != NULL &&
! 400: (cur_armor->o_which == LEATHER ||
! 401: cur_armor->o_which == STUDDED_LEATHER ||
! 402: cur_armor->o_which == PADDED_ARMOR) &&
! 403: !(cur_armor->o_flags & ISPROT) &&
! 404: cur_armor->o_ac < def->t_stats.s_arm+1) {
! 405: msg(terse ? "Your armor dissolves"
! 406: : "Your armor appears to dissolve. Oh my!");
! 407: cur_armor->o_ac++;
! 408: }
! 409:
! 410: /*
! 411: * If an infesting monster hits you, you get a parasite or rot.
! 412: * This will only affect the player until we figure out how to
! 413: * make it affect monsters.
! 414: */
! 415: if (on(*att, CANINFEST) &&
! 416: rnd(def->t_stats.s_const) < att->t_stats.s_lvl) {
! 417: if (ISWEARING(R_HEALTH) ||
! 418: player.t_ctype == C_PALADIN ||
! 419: player.t_ctype == C_MONK) {
! 420: msg("The wound heals quickly.");
! 421: }
! 422: else {
! 423: turn_off(*att, CANINFEST);
! 424: msg(terse ? "You have been infested."
! 425: : "You have contracted a parasitic infestation!");
! 426: infest_dam++;
! 427: turn_on(*def, HASINFEST);
! 428: }
! 429: }
! 430:
! 431: /*
! 432: * Does it take wisdom away? This currently affects only
! 433: * the player because of its temporary nature.
! 434: */
! 435: if (on(*att, TAKEWISDOM) &&
! 436: !save(VS_MAGIC, def, 0) &&
! 437: !ISWEARING(R_SUSABILITY)) {
! 438: add_abil[A_WISDOM](-1);
! 439: }
! 440:
! 441: /*
! 442: * Does it take intelligence away? This currently affects
! 443: * only the player because of its temporary nature.
! 444: */
! 445: if (on(*att, TAKEINTEL) &&
! 446: !save(VS_MAGIC, &player, 0) &&
! 447: !ISWEARING(R_SUSABILITY)) {
! 448: add_abil[A_INTELLIGENCE](-1);
! 449: }
! 450:
! 451: /*
! 452: * Cause fear by touching. This currently affects only
! 453: * the player until we figure out how we want it to
! 454: * affect monsters.
! 455: */
! 456: if (on(*att, TOUCHFEAR)) {
! 457: turn_off(*att, TOUCHFEAR);
! 458: if (!ISWEARING(R_HEROISM) &&
! 459: !save(VS_WAND, def, 0) &&
! 460: !(on(*def, ISFLEE) && (def->t_dest == &att->t_pos))) {
! 461: turn_on(*def, ISFLEE);
! 462: def->t_dest = &att->t_pos;
! 463: msg("%s's touch terrifies you.", prname(attname, TRUE));
! 464:
! 465: /* It is okay to turn tail */
! 466: if (!def_player) def->t_oldpos = def->t_pos;
! 467: }
! 468: }
! 469:
! 470: /*
! 471: * Make the hero dance (as in otto's irresistable dance)
! 472: * This should be fairly easy to do to monsters, but
! 473: * we'll restrict it to players until we decide what to
! 474: * do about the temporary nature.
! 475: */
! 476: if (on(*att, CANDANCE) &&
! 477: !on(*def, ISDANCE) &&
! 478: def->t_action != A_FREEZE &&
! 479: !save(VS_MAGIC, def, -4)) {
! 480: turn_off(*att, CANDANCE);
! 481: turn_on(*def, ISDANCE);
! 482: msg("You begin to dance uncontrollably!");
! 483: fuse(undance, NULL, roll(2,4), AFTER);
! 484: }
! 485:
! 486: /*
! 487: * Suffocating our hero. Monsters don't get suffocated.
! 488: * That's too hard for now.
! 489: */
! 490: if (on(*att, CANSUFFOCATE) &&
! 491: !ISWEARING(R_FREEDOM) &&
! 492: rnd(100) < 25 &&
! 493: (find_slot(suffocate) == 0)) {
! 494: turn_on(*att, DIDSUFFOCATE);
! 495: msg("%s is beginning to suffocate you.", prname(attname, TRUE));
! 496: fuse(suffocate, NULL, roll(9,3), AFTER);
! 497: }
! 498:
! 499: /*
! 500: * some creatures stops the poor guy from moving.
! 501: * How can we do this to a monster?
! 502: */
! 503: if (on(*att,CANHOLD) && off(*att,DIDHOLD) && !ISWEARING(R_FREEDOM)){
! 504: turn_on(*def, ISHELD);
! 505: turn_on(*att, DIDHOLD);
! 506: hold_count++;
! 507: }
! 508:
! 509: /*
! 510: * Sucker will suck blood and run. This
! 511: * should be easy to have happen to a monster,
! 512: * but we have to decide how to handle the fleeing.
! 513: */
! 514: if (on(*att, CANDRAW)) {
! 515: turn_off(*att, CANDRAW);
! 516: turn_on(*att, ISFLEE);
! 517: msg("%s sates itself with your blood.", prname(attname, TRUE));
! 518: if ((def->t_stats.s_hpt -= 12) <= 0) return(att->t_index);
! 519:
! 520: /* It is okay to turn tail */
! 521: att->t_oldpos = att->t_pos;
! 522: }
! 523:
! 524: /*
! 525: * Bad smell will force a reduction in strength.
! 526: * This will happen only to the player because of
! 527: * the temporary nature.
! 528: */
! 529: if (on(*att, CANSMELL)) {
! 530: turn_off(*att, CANSMELL);
! 531: if (save(VS_MAGIC, def, 0) || ISWEARING(R_SUSABILITY))
! 532: msg("You smell an unpleasant odor.");
! 533: else {
! 534: int odor_str = -(rnd(6)+1);
! 535: int fuse_arg2 = 0;
! 536: msg("You are overcome by a foul odor.");
! 537: if (lost_str == 0) {
! 538: chg_str(odor_str);
! 539: fuse(res_strength, &fuse_arg2, SMELLTIME, AFTER);
! 540: lost_str -= odor_str;
! 541: }
! 542: else lengthen(res_strength, SMELLTIME);
! 543: }
! 544: }
! 545:
! 546: /*
! 547: * The monsters touch slows the defendant down.
! 548: */
! 549: if (on(*att, TOUCHSLOW)) {
! 550: turn_off(*att, TOUCHSLOW);
! 551: if (!save(VS_PARALYZATION, def, 0))
! 552: add_slow();
! 553: }
! 554:
! 555: /*
! 556: * Rotting only affects the player.
! 557: */
! 558: if (on(*att, CANROT)) {
! 559: if (!ISWEARING(R_HEALTH) &&
! 560: player.t_ctype != C_PALADIN &&
! 561: player.t_ctype != C_MONK &&
! 562: !save(VS_POISON, def, 0) &&
! 563: off(*def, DOROT)) {
! 564: turn_on(*def, DOROT);
! 565: msg("You feel your skin starting to rot away!");
! 566: }
! 567: }
! 568:
! 569: /*
! 570: * Monsters should be able to steal gold from anyone,
! 571: * but until this is rewritten, they will only steal
! 572: * from the player (tough break).
! 573: */
! 574: if (on(*att, STEALGOLD)) {
! 575: /*
! 576: * steal some gold
! 577: */
! 578: register long lastpurse;
! 579: register struct linked_list *item;
! 580: register struct object *obj;
! 581:
! 582: lastpurse = purse;
! 583: purse -= GOLDCALC + GOLDCALC;
! 584: if (!save(VS_MAGIC, def, att->t_stats.s_lvl/10)) {
! 585: if (on(*att, ISUNIQUE))
! 586: purse -= GOLDCALC + GOLDCALC + GOLDCALC + GOLDCALC;
! 587: purse -= GOLDCALC + GOLDCALC + GOLDCALC + GOLDCALC;
! 588: }
! 589: if (purse < 0)
! 590: purse = 0;
! 591: if (purse != lastpurse) {
! 592: msg("Your purse feels lighter");
! 593:
! 594: /* Give the gold to the thief */
! 595: for (item=att->t_pack; item != NULL; item=next(item)) {
! 596: obj = OBJPTR(item);
! 597: if (obj->o_type == GOLD) {
! 598: obj->o_count += lastpurse - purse;
! 599: break;
! 600: }
! 601: }
! 602:
! 603: /* Did we do it? */
! 604: if (item == NULL) { /* Then make some */
! 605: item = new_item(sizeof *obj);
! 606: obj = OBJPTR(item);
! 607: obj->o_type = GOLD;
! 608: obj->o_count = lastpurse - purse;
! 609: obj->o_hplus = obj->o_dplus = 0;
! 610: strncpy(obj->o_damage, "0d0", sizeof(obj->o_damage));
! 611: strncpy(obj->o_hurldmg, "0d0", sizeof(obj->o_hurldmg));
! 612: obj->o_ac = 11;
! 613: obj->contents = NULL;
! 614: obj->o_group = 0;
! 615: obj->o_flags = 0;
! 616: obj->o_mark[0] = '\0';
! 617: obj->o_pos = att->t_pos;
! 618:
! 619: attach(att->t_pack, item);
! 620: }
! 621: }
! 622:
! 623: turn_on(*att, ISFLEE);
! 624: turn_on(*att, ISINVIS);
! 625:
! 626: /* It is okay to turn tail */
! 627: att->t_oldpos = att->t_pos;
! 628: }
! 629: }
! 630:
! 631: /*
! 632: * Stealing happens last since the monster disappears
! 633: * after the act.
! 634: */
! 635: if (on(*att, STEALMAGIC)) {
! 636: register struct linked_list *list, *steal;
! 637: register struct object *obj;
! 638: register int nobj;
! 639:
! 640: /*
! 641: * steal a magic item, look through the pack
! 642: * and pick out one we like.
! 643: */
! 644: steal = NULL;
! 645: for (nobj = 0, list = def->t_pack; list != NULL; list = next(list))
! 646: {
! 647: obj = OBJPTR(list);
! 648: if (!is_current(obj) &&
! 649: list != def->t_using &&
! 650: obj->o_type != RELIC &&
! 651: is_magic(obj) &&
! 652: rnd(++nobj) == 0)
! 653: steal = list;
! 654: }
! 655: if (steal != NULL)
! 656: {
! 657: register struct object *obj;
! 658: struct linked_list *item;
! 659:
! 660: obj = OBJPTR(steal);
! 661: if (on(*att, ISUNIQUE))
! 662: monsters[att->t_index].m_normal = TRUE;
! 663: item = find_mons(att->t_pos.y, att->t_pos.x);
! 664:
! 665: killed(item, FALSE, FALSE, FALSE); /* Remove the attacker */
! 666:
! 667: if (obj->o_count > 1 && obj->o_group == 0) {
! 668: register int oc;
! 669:
! 670: oc = --(obj->o_count);
! 671: obj->o_count = 1;
! 672: if (def_player)
! 673: msg("%s stole %s!", prname(attname, TRUE),
! 674: inv_name(obj, TRUE));
! 675: obj->o_count = oc;
! 676: }
! 677: else {
! 678: if (def_player) {
! 679: msg("%s stole %s!", prname(attname, TRUE),
! 680: inv_name(obj, TRUE));
! 681:
! 682: /* If this is a relic, clear its holding field */
! 683: if (obj->o_type == RELIC)
! 684: cur_relic[obj->o_which] = 0;
! 685:
! 686: inpack--;
! 687: }
! 688:
! 689: detach(def->t_pack, steal);
! 690: o_discard(steal);
! 691: }
! 692:
! 693: updpack(FALSE, def);
! 694: }
! 695: }
! 696: }
! 697:
! 698: /* Didn't kill the defender */
! 699: return(0);
! 700: }
CVSweb