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

Annotation of early-roguelike/arogue7/actions.c, Revision 1.1.1.1

1.1       rubenllo    1: /*
                      2:  * actions.c  -  functions for dealing with monster actions
                      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 <ctype.h>
                     16: #include <limits.h>
                     17: #include "curses.h"
                     18: #include "rogue.h"
                     19: #define        MAXINT  INT_MAX
                     20: #define        MININT  INT_MIN
                     21:
                     22: void m_breathe(struct thing *tp);
                     23: void m_select(struct thing *th, bool flee);
                     24: void m_sonic(struct thing *tp);
                     25: void m_spell(struct thing *tp);
                     26: void m_summon(struct thing *tp);
                     27: bool m_use_it(struct thing *tp, bool flee, struct room *rer, struct room *ree);
                     28: bool m_use_pack(struct thing *monster, coord *monst_pos, coord *defend_pos,
                     29:            int dist, coord *shoot_dir);
                     30:
                     31: /*
                     32:  * Did we disrupt a spell?
                     33:  */
                     34: void
                     35: dsrpt_monster(struct thing *tp, bool always, bool see_him)
                     36: {
                     37:     switch (tp->t_action) {
                     38:     case A_SUMMON:
                     39:     case A_MISSILE:
                     40:     case A_SLOW:
                     41:        tp->t_action = A_NIL; /* Just make the old fellow start over again */
                     42:        tp->t_no_move = movement(tp);
                     43:        tp->t_using = NULL;/* Just to be on the safe side */
                     44:        turn_on(*tp, WASDISRUPTED);
                     45:        if (see_him)
                     46:            msg("%s's spell has been disrupted.",prname(monster_name(tp),TRUE));
                     47:        /*
                     48:         * maybe choose something else to do next time since player
                     49:         * is disrupting us
                     50:         */
                     51:        tp->t_summon *= 2;
                     52:        tp->t_cast /= 2;
                     53:        return;
                     54:     }
                     55:
                     56:     /* We may want to disrupt other actions, too */
                     57:     if (always) {
                     58:        tp->t_action = A_NIL; /* Just make the old fellow start over again */
                     59:        tp->t_no_move = movement(tp);
                     60:        tp->t_using = NULL;/* Just to be on the safe side */
                     61:     }
                     62: }
                     63: 
                     64: void
                     65: dsrpt_player(void)
                     66: {
                     67:     int which, action;
                     68:     struct linked_list *item;
                     69:     struct object *obj;
                     70:
                     71:     action = player.t_action;
                     72:     which = player.t_selection;
                     73:
                     74:     switch (action) {
                     75:     case C_CAST: /* Did we disrupt a spell? */
                     76:     case C_PRAY:
                     77:     case C_CHANT:
                     78:     {
                     79:        msg("Your %s was disrupted!", action == C_CAST ? "spell" : "prayer");
                     80:
                     81:        /* Charge him anyway */
                     82:        if (action == C_CAST)
                     83:            spell_power += magic_spells[which].s_cost;
                     84:        else if (action == C_PRAY)
                     85:            pray_time += cleric_spells[which].s_cost;
                     86:        else if (action == C_CHANT)
                     87:            chant_time += druid_spells[which].s_cost;
                     88:     }
                     89:     when C_COUNT: /* counting of gold? */
                     90:     {
                     91:        if (purse > 0) {
                     92:            msg("Your gold goes flying everywhere!");
                     93:            do {
                     94:                item = spec_item(GOLD, 0, 0, 0);
                     95:                obj = OBJPTR(item);
                     96:                obj->o_count = min(purse, rnd(10)+1);
                     97:                purse -= obj->o_count;
                     98:                obj->o_pos = hero;
                     99:                fall(item, FALSE);
                    100:            } while (purse > 0 && rnd(10) != 1);
                    101:        }
                    102:     }
                    103:     when C_EAT:
                    104:        msg("You gag on your food for a moment.");
                    105:        del_pack(player.t_using);
                    106:
                    107:     when A_PICKUP:
                    108:        msg("You drop what you are picking up!");
                    109:
                    110:     when C_SEARCH:     /* searching for traps and secret doors... */
                    111:        msg("Oww....You decide to stop searching.");
                    112:        count = 0;      /* don't search again */
                    113:
                    114:     when C_SETTRAP:
                    115:        msg("Oww....You can't get a trap set.");
                    116:
                    117:     when A_NIL:
                    118:     default:
                    119:        return;
                    120:     }
                    121:     player.t_no_move = movement(&player); /* disoriented for a while */
                    122:     player.t_action = A_NIL;
                    123:     player.t_selection = 0;
                    124:     player.t_using = NULL;
                    125: }
                    126:
                    127: /*
                    128:  * m_act:
                    129:  *     If the critter isn't doing anything, choose an action for it.
                    130:  *     Otherwise, let it perform its chosen action.
                    131:  */
                    132:
                    133: void
                    134: m_act(struct thing *tp)
                    135: {
                    136:     struct object *obj;
                    137:     bool flee; /* Are we scared? */
                    138:
                    139:     /* What are we planning to do? */
                    140:     switch (tp->t_action) {
                    141:        default:
                    142:            /* An unknown action! */
                    143:            msg("Unknown monster action (%d)", tp->t_action);
                    144:
                    145:            /* Fall through */
                    146:
                    147:        case A_NIL:
                    148:            /* If the monster is fairly intelligent and about to die, it
                    149:             * may turn tail and run.  But if we are a FRIENDLY creature
                    150:             * in the hero's service, don't run.
                    151:             */
                    152:            if (off(*tp, ISFLEE)                                        &&
                    153:                tp->t_stats.s_hpt < tp->maxstats.s_hpt                  &&
                    154:                tp->t_stats.s_hpt < max(10, tp->maxstats.s_hpt/6)       &&
                    155:                (off(*tp, ISFRIENDLY) || tp->t_dest != &hero)           &&
                    156:                rnd(25) < tp->t_stats.s_intel) {
                    157:                    turn_on(*tp, ISFLEE);
                    158:
                    159:                    /* It is okay to turn tail */
                    160:                    tp->t_oldpos = tp->t_pos;
                    161:                }
                    162:
                    163:            /* Should the monster run away? */
                    164:            flee = on(*tp, ISFLEE) ||
                    165:                ((tp->t_dest == &hero) && on(player, ISINWALL) &&
                    166:                 off(*tp, CANINWALL));
                    167:
                    168:            m_select(tp, flee); /* Select an action */
                    169:            return;
                    170:
                    171:        when A_ATTACK:
                    172:            /*
                    173:             * We're trying to attack the player or monster at t_newpos
                    174:             * if the prey moved, do nothing
                    175:             */
                    176:            obj = tp->t_using ? OBJPTR(tp->t_using) : NULL;
                    177:            if (ce(tp->t_newpos, hero)) {
                    178:                attack(tp, obj, FALSE);
                    179:            }
                    180:            else if (mvwinch(mw, tp->t_newpos.y, tp->t_newpos.x) &&
                    181:                     step_ok(tp->t_newpos.y, tp->t_newpos.x, FIGHTOK, tp)) {
                    182:                skirmish(tp, &tp->t_newpos, obj, FALSE);
                    183:            }
                    184:
                    185:        when A_SELL:
                    186:            /* Is the player still next to us? */
                    187:            if (ce(tp->t_newpos, hero)) sell(tp);
                    188:
                    189:            /* The darned player moved away */
                    190:            else if (off(player, ISBLIND) &&
                    191:                cansee(unc(tp->t_pos)) &&
                    192:                (off(*tp, ISINVIS)     || on(player, CANSEE)) &&
                    193:                (off(*tp, ISSHADOW)    || on(player, CANSEE)) &&
                    194:                (off(*tp, CANSURPRISE) || ISWEARING(R_ALERT)))
                    195:                msg("%s grunts with frustration",prname(monster_name(tp),TRUE));
                    196:
                    197:        when A_MOVE:
                    198:            /* Let's try to move */
                    199:            do_chase(tp);
                    200:
                    201:            /* If t_no_move > 0, we found that we have to fight! */
                    202:            if (tp->t_no_move > 0) return;
                    203:
                    204:        when A_BREATHE:
                    205:            /* Breathe on the critter */
                    206:            m_breathe(tp);
                    207:
                    208:        when A_SLOW:
                    209:            /* make him move slower */
                    210:            add_slow();
                    211:            turn_off(*tp, CANSLOW);
                    212:
                    213:        when A_MISSILE:
                    214:            /* Start up a magic missile spell */
                    215:            m_spell(tp);
                    216:
                    217:        when A_SONIC:
                    218:            /* Let out a sonic blast! */
                    219:            m_sonic(tp);
                    220:
                    221:        when A_THROW:
                    222:            /* We're throwing something (like an arrow) */
                    223:            missile(tp->t_newpos.y, tp->t_newpos.x, tp->t_using, tp);
                    224:
                    225:        when A_SUMMON:
                    226:            /* We're summoning help */
                    227:            m_summon(tp);
                    228:
                    229:        when A_USERELIC:
                    230:            /* Use our relic */
                    231:            m_use_relic(tp);
                    232:
                    233:        when A_USEWAND:
                    234:            /* use the wand we have */
                    235:            m_use_wand(tp);
                    236:     }
                    237:
                    238:     /* No action now */
                    239:     tp->t_action = A_NIL;
                    240:     tp->t_using = NULL;
                    241: }
                    242: 
                    243: /*
                    244:  * m_breathe:
                    245:  *     Breathe in the chosen direction.
                    246:  */
                    247:
                    248: void
                    249: m_breathe(struct thing *tp)
                    250: {
                    251:     register int damage;
                    252:     register char *breath = "";
                    253:
                    254:     damage = tp->t_stats.s_hpt;
                    255:     turn_off(*tp, CANSURPRISE);
                    256:
                    257:     /* Will it breathe at random */
                    258:     if (on(*tp, CANBRANDOM)) {
                    259:        /* Turn off random breath */
                    260:        turn_off(*tp, CANBRANDOM);
                    261:
                    262:        /* Select type of breath */
                    263:        switch (rnd(10)) {
                    264:            case 0: breath = "acid";
                    265:                    turn_on(*tp, NOACID);
                    266:            when 1: breath = "flame";
                    267:                    turn_on(*tp, NOFIRE);
                    268:            when 2: breath = "lightning bolt";
                    269:                    turn_on(*tp, NOBOLT);
                    270:            when 3: breath = "chlorine gas";
                    271:                    turn_on(*tp, NOGAS);
                    272:            when 4: breath = "ice";
                    273:                    turn_on(*tp, NOCOLD);
                    274:            when 5: breath = "nerve gas";
                    275:                    turn_on(*tp, NOPARALYZE);
                    276:            when 6: breath = "sleeping gas";
                    277:                    turn_on(*tp, NOSLEEP);
                    278:            when 7: breath = "slow gas";
                    279:                    turn_on(*tp, NOSLOW);
                    280:            when 8: breath = "confusion gas";
                    281:                    turn_on(*tp, ISCLEAR);
                    282:            when 9: breath = "fear gas";
                    283:                    turn_on(*tp, NOFEAR);
                    284:        }
                    285:     }
                    286:
                    287:     /* Or can it breathe acid? */
                    288:     else if (on(*tp, CANBACID)) {
                    289:        turn_off(*tp, CANBACID);
                    290:        breath = "acid";
                    291:     }
                    292:
                    293:     /* Or can it breathe fire */
                    294:     else if (on(*tp, CANBFIRE)) {
                    295:        turn_off(*tp, CANBFIRE);
                    296:        breath = "flame";
                    297:     }
                    298:
                    299:     /* Or can it breathe electricity? */
                    300:     else if (on(*tp, CANBBOLT)) {
                    301:        turn_off(*tp, CANBBOLT);
                    302:        breath = "lightning bolt";
                    303:     }
                    304:
                    305:     /* Or can it breathe gas? */
                    306:     else if (on(*tp, CANBGAS)) {
                    307:        turn_off(*tp, CANBGAS);
                    308:        breath = "chlorine gas";
                    309:     }
                    310:
                    311:     /* Or can it breathe ice? */
                    312:     else if (on(*tp, CANBICE)) {
                    313:        turn_off(*tp, CANBICE);
                    314:        breath = "ice";
                    315:     }
                    316:
                    317:     else if (on(*tp, CANBPGAS)) {
                    318:        turn_off(*tp, CANBPGAS);
                    319:        breath = "nerve gas";
                    320:     }
                    321:
                    322:     /* can it breathe sleeping gas */
                    323:     else if (on(*tp, CANBSGAS)) {
                    324:        turn_off(*tp, CANBSGAS);
                    325:        breath = "sleeping gas";
                    326:     }
                    327:
                    328:     /* can it breathe slow gas */
                    329:     else if (on(*tp, CANBSLGAS)) {
                    330:        turn_off(*tp, CANBSLGAS);
                    331:        breath = "slow gas";
                    332:     }
                    333:
                    334:     /* can it breathe confusion gas */
                    335:     else if (on(*tp, CANBCGAS)) {
                    336:        turn_off(*tp, CANBCGAS);
                    337:        breath = "confusion gas";
                    338:     }
                    339:
                    340:     /* can it breathe fear gas */
                    341:     else {
                    342:        turn_off(*tp, CANBFGAS);
                    343:        breath = "fear gas";
                    344:     }
                    345:
                    346:     /* Now breathe -- sets "monst_dead" if it kills someone */
                    347:     shoot_bolt(tp, tp->t_pos, tp->t_newpos, FALSE,
                    348:                    tp->t_index, breath, damage);
                    349:
                    350:     running = FALSE;
                    351:     if (fight_flush) md_flushinp();
                    352: }
                    353: 
                    354: /*
                    355:  * m_select:
                    356:  *     Select an action for the monster.
                    357:  * flee: True if running away or player is inaccessible in wall
                    358:  */
                    359:
                    360: void
                    361: m_select(struct thing *th, bool flee)
                    362: {
                    363:     register struct room *rer, *ree;   /* room of chaser, room of chasee */
                    364:     int dist = MININT;
                    365:     int mindist = MAXINT, maxdist = MININT;
                    366:     bool rundoor;                      /* TRUE means run to a door */
                    367:     char sch;
                    368:     coord *last_door=0,                        /* Door we just came from */
                    369:           this;                        /* Temporary destination for chaser */
                    370:
                    371:     rer = roomin(&th->t_pos);  /* Find room of chaser */
                    372:     ree = roomin(th->t_dest);  /* Find room of chasee */
                    373:
                    374:     /* First see if we want to use an ability or weapon */
                    375:     if (m_use_it(th, flee, rer, ree)) return;
                    376:
                    377:     /*
                    378:      * We don't count monsters on doors as inside rooms here because when
                    379:      * a monster is in a room and the player is not in that room, the
                    380:      * monster looks for the best door out.  If we counted doors as part
                    381:      * of the room, the monster would already be on the best door out;
                    382:      * so he would never move.
                    383:      */
                    384:     if ((sch = CCHAR( mvwinch(stdscr, th->t_pos.y, th->t_pos.x) )) == DOOR ||
                    385:        sch == SECRETDOOR || sch == PASSAGE) {
                    386:        rer = NULL;
                    387:     }
                    388:     this = *th->t_dest;
                    389:
                    390:     /*
                    391:      * If we are in a room heading for the player and the player is not
                    392:      * in the room with us, we run to the "best" door.
                    393:      * If we are in a room fleeing from the player, then we run to the
                    394:      * "best" door if he IS in the same room.
                    395:      *
                    396:      * Note:  We don't bother with doors in mazes or if we can walk
                    397:      * through walls.
                    398:      */
                    399:     if (rer != NULL && levtype != MAZELEV && off(*th, CANINWALL)) {
                    400:        if (flee) rundoor = (rer == ree);
                    401:        else rundoor = (rer != ree);
                    402:     }
                    403:     else rundoor = FALSE;
                    404:
                    405:     if (rundoor) {
                    406:        register struct linked_list *exitptr;   /* For looping through exits */
                    407:        coord *exit,                            /* A particular door */
                    408:              *entrance;                        /* Place just inside doorway */
                    409:        int exity, exitx;                       /* Door's coordinates */
                    410:        char dch='\0';                          /* Door character */
                    411:
                    412:        if (th->t_doorgoal)
                    413:            dch = CCHAR( mvwinch(stdscr, th->t_doorgoal->y, th->t_doorgoal->x) );
                    414:
                    415:        /* Do we have a valid goal? */
                    416:        if ((dch == PASSAGE || dch == DOOR) &&  /* A real door */
                    417:            (!flee || !ce(*th->t_doorgoal, *th->t_dest))) { /* Prey should not
                    418:                                                             * be at door if
                    419:                                                             * we are running
                    420:                                                             * away
                    421:                                                             */
                    422:            /* Make sure the player is not in the doorway, either */
                    423:            entrance = doorway(rer, th->t_doorgoal);
                    424:            if (!flee || entrance == NULL || !ce(*entrance, *th->t_dest)) {
                    425:                this = *th->t_doorgoal;
                    426:                dist = 0;       /* Indicate that we have our door */
                    427:            }
                    428:        }
                    429:
                    430:        /* Go through all the doors */
                    431:        else for (exitptr = rer->r_exit; exitptr; exitptr = next(exitptr)) {
                    432:            exit = DOORPTR(exitptr);
                    433:            exity = exit->y;
                    434:            exitx = exit->x;
                    435:
                    436:            /* Make sure it is a real door */
                    437:            dch = CCHAR( mvwinch(stdscr, exity, exitx) );
                    438:            if (dch == PASSAGE || dch == DOOR) {
                    439:                /* Don't count a door if we are fleeing from someone and
                    440:                 * he is standing on it.  Also, don't count it if he is
                    441:                 * standing in the doorway.
                    442:                 */
                    443:                if (flee) {
                    444:                    if (ce(*exit, *th->t_dest)) continue;
                    445:
                    446:                    entrance = doorway(rer, exit);
                    447:                    if (entrance != NULL && ce(*entrance, *th->t_dest))
                    448:                        continue;
                    449:                }
                    450:
                    451:                /* Were we just on this door? */
                    452:                if (ce(*exit, th->t_oldpos)) last_door = exit;
                    453:
                    454:                else {
                    455:                    dist = DISTANCE(th->t_dest->y, th->t_dest->x, exity, exitx);
                    456:
                    457:                    /* If fleeing, we want to maximize distance from door to
                    458:                     * what we flee, and minimize distance from door to us.
                    459:                     */
                    460:                    if (flee)
                    461:                       dist -= DISTANCE(th->t_pos.y, th->t_pos.x, exity, exitx);
                    462:
                    463:                    /* Maximize distance if fleeing, otherwise minimize it */
                    464:                    if ((flee && (dist > maxdist)) ||
                    465:                        (!flee && (dist < mindist))) {
                    466:                        th->t_doorgoal = exit;  /* Use this door */
                    467:                        this = *exit;
                    468:                        mindist = maxdist = dist;
                    469:                    }
                    470:                }
                    471:            }
                    472:        }
                    473:
                    474:        /* Could we not find a door? */
                    475:        if (dist == MININT) {
                    476:            /* If we were on a door, go ahead and use it */
                    477:            if (last_door) {
                    478:                th->t_doorgoal = last_door;
                    479:                this = th->t_oldpos;
                    480:                dist = 0;       /* Indicate that we found a door */
                    481:            }
                    482:            else th->t_doorgoal = NULL; /* No more door goal */
                    483:        }
                    484:
                    485:        /* Indicate that we do not want to flee from the door */
                    486:        if (dist != MININT) flee = FALSE;
                    487:     }
                    488:     else th->t_doorgoal = 0;   /* Not going to any door */
                    489:
                    490:     /* Now select someplace to go and start the action */
                    491:     chase(th, &this, rer, ree, flee);
                    492: }
                    493: 
                    494: /*
                    495:  * m_sonic:
                    496:  *     The monster is sounding a sonic blast.
                    497:  */
                    498:
                    499: void
                    500: m_sonic(struct thing *tp)
                    501: {
                    502:     register int damage;
                    503:     static struct object blast =
                    504:     {
                    505:        MISSILE, {0, 0}, "", 0, "", "150" , NULL, 0, 0, 0, 0
                    506:     };
                    507:
                    508:     turn_off(*tp, CANSONIC);
                    509:     turn_off(*tp, CANSURPRISE);
                    510:     do_motion(&blast, tp->t_newpos.y, tp->t_newpos.x, tp);
                    511:     damage = 150;
                    512:     if (save(VS_BREATH, &player, -3))
                    513:        damage /= 2;
                    514:     msg ("%s's sonic blast hits you", prname(monster_name(tp), TRUE));
                    515:     if ((pstats.s_hpt -= damage) <= 0)
                    516:        death(tp->t_index);
                    517:
                    518:     running = FALSE;
                    519:     if (fight_flush) md_flushinp();
                    520:     dsrpt_player();
                    521: }
                    522: 
                    523: /*
                    524:  * m_spell:
                    525:  *     The monster casts a spell.  Currently this is limited to
                    526:  *     magic missile.
                    527:  */
                    528: void
                    529: m_spell(struct thing *tp)
                    530: {
                    531:     static struct object missile =
                    532:     {
                    533:        MISSILE, {0, 0}, "", 0, "", "0d4 " , NULL, 0, WS_MISSILE, 100, 1
                    534:     };
                    535:
                    536:     sprintf(missile.o_hurldmg, "%dd4", tp->t_stats.s_lvl);
                    537:     do_motion(&missile, tp->t_newpos.y, tp->t_newpos.x, tp);
                    538:     hit_monster(unc(missile.o_pos), &missile, tp);
                    539:     turn_off(*tp, CANMISSILE);
                    540:     turn_off(*tp, CANSURPRISE);
                    541:
                    542:     running = FALSE;
                    543:     if (fight_flush) md_flushinp();
                    544: }
                    545: 
                    546: /*
                    547:  * m_summon:
                    548:  *     Summon aid.
                    549:  */
                    550:
                    551: void
                    552: m_summon(struct thing *tp)
                    553: {
                    554:     register char *helpname, *mname;
                    555:     int fail, numsum;
                    556:     register int which, i;
                    557:
                    558:     /* Let's make sure our prey is still here */
                    559:     if (!cansee(unc(tp->t_pos)) || fallpos(&hero, FALSE, 2) == NULL) return;
                    560:
                    561:     /*
                    562:      * Non-uniques can only summon once.  Uniques get fewer
                    563:      * creatures with each successive summoning. Also, the
                    564:      * probability of summoning goes down
                    565:      */
                    566:     if (off(*tp, ISUNIQUE))
                    567:            turn_off(*tp, CANSUMMON);
                    568:
                    569:     turn_off(*tp, CANSURPRISE);
                    570:     mname = monster_name(tp);
                    571:     helpname = monsters[tp->t_index].m_typesum;
                    572:     which = findmindex(helpname);
                    573:
                    574:     if ((off(*tp, ISINVIS)     || on(player, CANSEE)) &&
                    575:        (off(*tp, ISSHADOW)    || on(player, CANSEE)) &&
                    576:        (off(*tp, CANSURPRISE) || ISWEARING(R_ALERT))) {
                    577:        if (monsters[which].m_normal == FALSE) { /* genocided? */
                    578:            msg("%s appears dismayed", prname(mname, TRUE));
                    579:            monsters[tp->t_index].m_numsum = 0;
                    580:        }
                    581:        else {
                    582:            msg("%s summons %ss for help", prname(mname, TRUE), helpname);
                    583:        }
                    584:     }
                    585:     else {
                    586:        if (monsters[which].m_normal == FALSE) /* genocided? */
                    587:            monsters[tp->t_index].m_numsum = 0;
                    588:        else {
                    589:            msg("%ss seem to appear from nowhere!", helpname);
                    590:        }
                    591:     }
                    592:     numsum = monsters[tp->t_index].m_numsum;
                    593:     if (numsum && on(*tp, ISUNIQUE)) {   /* UNIQUEs summon less each time */
                    594:        monsters[tp->t_index].m_numsum--;
                    595:        tp->t_summon *= 2; /* cut probability in half */
                    596:     }
                    597:
                    598:     /*
                    599:      * try to make all the creatures around player but remember
                    600:      * if unsuccessful
                    601:      */
                    602:     for (i=0, fail=0; i<numsum; i++) {
                    603:         if (!creat_mons(&player, which, FALSE))
                    604:             fail++;    /* remember the failures */
                    605:     }
                    606:
                    607:     /*
                    608:      * try once again to make the buggers
                    609:      */
                    610:     for (i=0; i<fail; i++)
                    611:         creat_mons(tp, which, FALSE);
                    612:
                    613:     /* Now let the poor fellow see all the trouble */
                    614:     light(&hero);
                    615:     turn_on(*tp, HASSUMMONED);
                    616: }
                    617: 
                    618: /*
                    619:  * m_use_it:
                    620:  *     See if the monster (tp) has anything useful it can do
                    621:  *     (ie. an ability or a weapon) other than just move.
                    622:  */
                    623:
                    624: bool
                    625: m_use_it(struct thing *tp, bool flee, struct room *rer, struct room *ree)
                    626: {
                    627:     int dist;
                    628:     register coord *ee = tp->t_dest, *er = &tp->t_pos;
                    629:     coord *shoot_dir;
                    630:     struct linked_list *weapon;
                    631:     struct thing *prey;
                    632:     bool dest_player;  /* Are we after the player? */
                    633:
                    634:     /*
                    635:      * If we are fleeing, there's a chance, depending on our
                    636:      * intelligence, that we'll just run in terror.
                    637:      */
                    638:     if (flee && rnd(25) >= tp->t_stats.s_intel) return(FALSE);
                    639:
                    640:     /*
                    641:      * Make sure that we have a living destination, and record whether
                    642:      * it is the player.
                    643:      */
                    644:     if (ee != NULL) {
                    645:         if (ce(*ee, hero)) {
                    646:            dest_player = TRUE;
                    647:            prey = &player;
                    648:        }
                    649:        else {
                    650:            struct linked_list *item;
                    651:
                    652:            dest_player = FALSE;
                    653:
                    654:            /* What is the monster we're chasing? */
                    655:            item = find_mons(ee->y, ee->x);
                    656:            if (item != NULL) prey = THINGPTR(item);
                    657:            else return(FALSE);
                    658:        }
                    659:     }
                    660:     else return(FALSE);
                    661:
                    662:     /*
                    663:      * If we are friendly to the hero, we don't do anything.
                    664:      */
                    665:     if (on(*tp, ISFRIENDLY) && dest_player) return(FALSE);
                    666:
                    667:     /*
                    668:      * Also, for now, if our prey is in a wall, we won't do
                    669:      * anything.  The prey must be in the same room as we are OR
                    670:      * we must have a straight shot at him.  Note that
                    671:      * shoot_dir must get set before rer is checked so
                    672:      * that we get a valid value.
                    673:      */
                    674:     if (on(*prey, ISINWALL) ||
                    675:        ((shoot_dir = can_shoot(er, ee)) == NULL &&
                    676:        (rer == NULL || rer != ree)))
                    677:        return(FALSE);
                    678:
                    679:     /*
                    680:      * If we can't see the prey then forget it
                    681:      */
                    682:     if (on(*prey, ISINVIS) && off(*tp, CANSEE))
                    683:        return(FALSE);
                    684:
                    685:     /* How far are we from our prey? */
                    686:     dist = DISTANCE(er->y, er->x, ee->y, ee->x);
                    687:
                    688:     /*
                    689:      * Shall we summon aid so we don't have to get our hands dirty?
                    690:      * For now, we will only summon aid against the player.
                    691:      * We'll wait until he's within 2 dots of a missile length.
                    692:      */
                    693:     if (on(*tp, CANSUMMON) && dest_player                      &&
                    694:        dist < (BOLT_LENGTH+2)*(BOLT_LENGTH+2)                  &&
                    695:        rnd(tp->t_summon) < tp->t_stats.s_lvl                   &&
                    696:        monsters[tp->t_index].m_numsum > 0                      &&
                    697:        fallpos(&hero, FALSE, 2) != NULL) {
                    698:        tp->t_action = A_SUMMON;        /* We're going to summon help */
                    699:        tp->t_no_move = movement(tp); /* It takes time! */
                    700:        return(TRUE);
                    701:     }
                    702:
                    703:     /*
                    704:      * If the creature can cast a slow spell and if the prey is within
                    705:      * 2 dots of a missile fire, then see whether we will cast it.
                    706:      * if next to player, lessen chance because we don't like being
                    707:      * disrupted
                    708:      */
                    709:     if (on(*tp, CANSLOW) && dest_player                        &&
                    710:        dist < (BOLT_LENGTH+5)*(BOLT_LENGTH+5)          &&
                    711:        rnd(100) < (dist > 3 ? tp->t_cast : tp->t_cast/2)) {
                    712:            tp->t_action = A_SLOW;              /* We're going to slow him */
                    713:            tp->t_no_move = 3 * movement(tp);   /* Takes time! */
                    714:            debug("casting slow spell!");
                    715:            return(TRUE);
                    716:     }
                    717:
                    718:     /*
                    719:      * If we have a special magic item, we might use it.  We will restrict
                    720:      * this options to uniques with relics and creatures with wands for now.
                    721:      * Also check for the quartermaster. Don't want him shooting wands....
                    722:      */
                    723:     if ((on(*tp, ISUNIQUE) || on(*tp, CARRYSTICK)) &&
                    724:        off(*tp, CANSELL) && dest_player           &&
                    725:        m_use_pack(tp, er, ee, dist, shoot_dir)) {
                    726:            return(TRUE);
                    727:     }
                    728:
                    729:     /* From now on, we must have a direct shot at the prey */
                    730:     if (shoot_dir == NULL) return(FALSE);
                    731:
                    732:     /* We may use a sonic blast if we can, only on the player */
                    733:     if (on(*tp, CANSONIC)              &&
                    734:        dest_player                     &&
                    735:        (dist < BOLT_LENGTH*2)          &&
                    736:        (rnd(100) < tp->t_breathe)) {
                    737:        tp->t_newpos = *shoot_dir;      /* Save the direction */
                    738:        tp->t_action = A_SONIC; /* We're going to sonic blast */
                    739:        tp->t_no_move = 2 * movement(tp); /* Takes 2 movement periods */
                    740:     }
                    741:
                    742:     /* If we can breathe, we may do so */
                    743:     else if (on(*tp, CANBREATHE)               &&
                    744:         (dist < BOLT_LENGTH*BOLT_LENGTH)       &&
                    745:         (rnd(100) < tp->t_breathe)) {
                    746:            tp->t_newpos = *shoot_dir;  /* Save the direction */
                    747:            tp->t_action = A_BREATHE;   /* We're going to breathe */
                    748:            tp->t_no_move = movement(tp); /* It takes 1 movement period */
                    749:     }
                    750:
                    751:     /*
                    752:      * We may shoot missiles if we can
                    753:      * if next to player, lessen chance so we don't get disrupted as often
                    754:      */
                    755:     else if (on(*tp,CANMISSILE) &&
                    756:             rnd(100) < (dist > 3 ? tp->t_cast : tp->t_cast/2)){
                    757:            tp->t_newpos = *shoot_dir;  /* Save the direction */
                    758:            tp->t_action = A_MISSILE;   /* We're going to shoot MM's */
                    759:            tp->t_no_move = 3 * movement(tp); /* Takes time! */
                    760:     }
                    761:
                    762:     /*
                    763:      * If we can shoot or throw something, we might do so.
                    764:      * If next to player, then forget it
                    765:      */
                    766:     else if ((on(*tp,CANSHOOT)         || on(*tp,CARRYWEAPON) ||
                    767:              on(*tp,CARRYDAGGER)       || on(*tp, CARRYAXE))           &&
                    768:              dist > 3                                                  &&
                    769:              off(*tp, CANSELL)                                         &&
                    770:             (weapon = get_hurl(tp))) {
                    771:            tp->t_newpos = *shoot_dir;  /* Save the direction */
                    772:            tp->t_action = A_THROW;     /* We're going to throw something */
                    773:            tp->t_using = weapon;       /* Save our weapon */
                    774:            tp->t_no_move = 2 * movement(tp); /* Takes 2 movement periods */
                    775:     }
                    776:
                    777:     /* We couldn't find anything to do */
                    778:     else return(FALSE);
                    779:
                    780:     return(TRUE);
                    781:
                    782: }
                    783: 
                    784: /*
                    785:  * runners:
                    786:  *     Make all the awake monsters try to do something.
                    787:  * segments: Number of segments since last called
                    788:  */
                    789:
                    790: int
                    791: runners(int segments)
                    792: {
                    793:     register struct linked_list *item;
                    794:     register struct thing *tp = NULL;
                    795:     register int min_time = 20;        /* Minimum time until a monster can act */
                    796:
                    797:     /*
                    798:      * loop thru the list of running (wandering) monsters and see what
                    799:      * each one will do this time.
                    800:      *
                    801:      * Note: the special case that one of this buggers kills another.
                    802:      *      if this happens than we have to see if the monster killed
                    803:      *      himself or someone else. In case its himself we have to get next
                    804:      *      one immediately. If it wasn't we have to get next one at very
                    805:      *      end in case he killed the next one.
                    806:      */
                    807:
                    808:     for (item = mlist; item != NULL; item = next(item))        {
                    809:        tp = THINGPTR(item);
                    810:        turn_on(*tp, ISREADY);
                    811:     }
                    812:
                    813:     for (;;) {
                    814:
                    815:        for (item = mlist; item != NULL; item = next(item)) {
                    816:            tp = THINGPTR(item);
                    817:
                    818:            if (on(*tp, ISREADY))
                    819:                break;
                    820:        }
                    821:
                    822:        if (item == NULL)
                    823:            break;
                    824:
                    825:        turn_off(*tp, ISREADY);
                    826:
                    827:        /* If we are not awake, just skip us */
                    828:        if (off(*tp, ISRUN) && off(*tp, ISHELD)) continue;
                    829:
                    830:        /* See if it's our turn */
                    831:        tp->t_no_move -= segments;
                    832:        if (tp->t_no_move > 0) {
                    833:            if (tp->t_no_move < min_time) min_time = tp->t_no_move;
                    834:            continue;
                    835:        }
                    836:
                    837:        /* If we were frozen, we're moving now */
                    838:        if (tp->t_action == A_FREEZE) tp->t_action = A_NIL;
                    839:
                    840:        if (on(*tp, ISHELD)) {
                    841:            /* Make sure the action and using are nil */
                    842:            tp->t_action = A_NIL;
                    843:            tp->t_using = NULL;
                    844:
                    845:            /* Can we break free? */
                    846:            if (rnd(tp->t_stats.s_lvl) > 11) {
                    847:                turn_off(*tp, ISHELD);
                    848:                runto(tp, &hero);
                    849:                if (cansee(tp->t_pos.y, tp->t_pos.x))
                    850:                    msg("%s breaks free from the hold spell",
                    851:                        prname(monster_name(tp), TRUE));
                    852:            }
                    853:
                    854:            /* Too bad -- try again later */
                    855:            else tp->t_no_move = movement(tp);
                    856:        }
                    857:
                    858:        /* Heal the creature if it's not in the middle of some action */
                    859:        if (tp->t_action == A_NIL) doctor(tp);
                    860:
                    861:        while (off(*tp,ISELSEWHERE) &&
                    862:            off(*tp,ISDEAD) &&
                    863:               tp->t_no_move <= 0 && off(*tp, ISHELD) && on(*tp, ISRUN)) {
                    864:            /* Let's act (or choose an action if t_action = A_NIL) */
                    865:            m_act(tp);
                    866:        }
                    867:
                    868:        if (off(*tp,ISELSEWHERE) && off(*tp,ISDEAD)) {
                    869:            if (tp->t_no_move < min_time) min_time = tp->t_no_move;
                    870:            if (tp->t_quiet < 0) tp->t_quiet = 0;
                    871:        }
                    872:     }
                    873:     return(min_time);
                    874: }
                    875: 
                    876: /*
                    877:  * See if a monster has some magic it can use.  Return TRUE if so.
                    878:  * Only care about relics and wands for now.
                    879:  */
                    880: bool
                    881: m_use_pack(struct thing *monster, coord *monst_pos, coord *defend_pos,
                    882:            int dist, coord *shoot_dir)
                    883: {
                    884:     register struct object *obj;
                    885:     register struct linked_list *pitem, *relic, *stick;
                    886:     register int units = -1;
                    887:
                    888:     relic = stick = NULL;
                    889:
                    890:     for (pitem=monster->t_pack; pitem; pitem=next(pitem)) {
                    891:        obj = OBJPTR(pitem);
                    892:        if (obj->o_flags & ISCURSED) continue;
                    893:        if (obj->o_type == RELIC) {
                    894:            switch (obj->o_which) {
                    895:                case MING_STAFF:
                    896:                    if (shoot_dir != NULL) {
                    897:                        units = 2;      /* Use 2 time units */
                    898:                        relic = pitem;
                    899:                    }
                    900:
                    901:                when EMORI_CLOAK:
                    902:                    if (obj->o_charges != 0     &&
                    903:                        shoot_dir != NULL) {
                    904:                            units = 2;  /* Use 2 time units */
                    905:                            relic = pitem;
                    906:                    }
                    907:
                    908:                when ASMO_ROD:
                    909:                    /* The bolt must be able to reach the defendant */
                    910:                    if (shoot_dir != NULL                       &&
                    911:                        dist < BOLT_LENGTH * BOLT_LENGTH) {
                    912:                        units = 2;      /* Use 2 time units */
                    913:                        relic = pitem;
                    914:                    }
                    915:
                    916:                when BRIAN_MANDOLIN:
                    917:                    /* The defendant must be the player and within 4 spaces */
                    918:                    if (ce(*defend_pos, hero)           &&
                    919:                        dist < 25                       &&
                    920:                        player.t_action != A_FREEZE) {
                    921:                        units = 4;
                    922:                        relic = pitem;
                    923:                    }
                    924:
                    925:                when GERYON_HORN:
                    926:                    /* The defendant must be the player and within 5 spaces */
                    927:                    if (ce(*defend_pos, hero)                                &&
                    928:                        dist < 25                                            &&
                    929:                        (off(player,ISFLEE)|| player.t_dest!=&monster->t_pos)) {
                    930:                        units = 3;
                    931:                        relic = pitem;
                    932:                    }
                    933:            }
                    934:        }
                    935:        if (obj->o_type == STICK) {
                    936:            if (obj->o_charges < 1) continue;
                    937:            switch(obj->o_which) {
                    938:                case WS_ELECT:
                    939:                case WS_FIRE:
                    940:                case WS_COLD:
                    941:                    /* The bolt must be able to reach the defendant */
                    942:                    if (shoot_dir != NULL                       &&
                    943:                        dist < BOLT_LENGTH * BOLT_LENGTH) {
                    944:                            units = 3;
                    945:                            stick = pitem;
                    946:                    }
                    947:
                    948:                when WS_MISSILE:
                    949:                case WS_SLOW_M:
                    950:                case WS_CONFMON:
                    951:                case WS_PARALYZE:
                    952:                case WS_MDEG:
                    953:                case WS_FEAR:
                    954:                    if (shoot_dir != NULL) {
                    955:                        units = 3;
                    956:                        stick = pitem;
                    957:                    }
                    958:
                    959:                otherwise:
                    960:                    break;
                    961:            }
                    962:        }
                    963:     }
                    964:
                    965:     /* use relics in preference to all others */
                    966:     if (relic) debug("chance to use relic = %d%%", monster->t_artifact);
                    967:     if (stick) debug("chance to use stick = %d%%", monster->t_wand);
                    968:     if (relic && rnd(100) < monster->t_artifact)  {
                    969:        monster->t_action = A_USERELIC;
                    970:        pitem = relic;
                    971:     }
                    972:     else if (stick && rnd(100) < monster->t_wand) {
                    973:        /*
                    974:         * see if the monster will use the wand
                    975:         */
                    976:        pitem = stick;
                    977:        monster->t_action = A_USEWAND;
                    978:     }
                    979:     else {
                    980:        return(FALSE);
                    981:     }
                    982:
                    983:     monster->t_no_move = units * movement(monster);
                    984:     monster->t_using = pitem;
                    985:     monster->t_newpos = *shoot_dir;
                    986:     return(TRUE);
                    987: }

CVSweb