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