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

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

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

CVSweb