[BACK]Return to effects.c CVS log [TXT][DIR] Up to [contributed] / early-roguelike / xrogue

Annotation of early-roguelike/xrogue/effects.c, Revision 1.1.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