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

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