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

Annotation of early-roguelike/rogue5/monsters.c, Revision 1.1.1.1

1.1       rubenllo    1: /*
                      2:  * File with various monster functions in it
                      3:  *
                      4:  * @(#)monsters.c      4.46 (Berkeley) 02/05/99
                      5:  *
                      6:  * Rogue: Exploring the Dungeons of Doom
                      7:  * Copyright (C) 1980-1983, 1985, 1999 Michael Toy, Ken Arnold and Glenn Wichman
                      8:  * All rights reserved.
                      9:  *
                     10:  * See the file LICENSE.TXT for full copyright and licensing information.
                     11:  */
                     12:
                     13: #include <curses.h>
                     14: #include <string.h>
                     15: #include "rogue.h"
                     16: #include <ctype.h>
                     17:
                     18: /*
                     19:  * List of monsters in rough order of vorpalness
                     20:  */
                     21: static const int lvl_mons[] =  {
                     22:     'K', 'E', 'B', 'S', 'H', 'I', 'R', 'O', 'Z', 'L', 'C', 'Q', 'A',
                     23:     'N', 'Y', 'F', 'T', 'W', 'P', 'X', 'U', 'M', 'V', 'G', 'J', 'D'
                     24: };
                     25:
                     26: static const int wand_mons[] = {
                     27:     'K', 'E', 'B', 'S', 'H',   0, 'R', 'O', 'Z',   0, 'C', 'Q', 'A',
                     28:       0, 'Y',   0, 'T', 'W', 'P',   0, 'U', 'M', 'V', 'G', 'J',   0
                     29: };
                     30:
                     31: /*
                     32:  * randmonster:
                     33:  *     Pick a monster to show up.  The lower the level,
                     34:  *     the meaner the monster.
                     35:  */
                     36: int
                     37: randmonster(int wander)
                     38: {
                     39:     int d;
                     40:     const int *mons;
                     41:
                     42:     mons = (wander ? wand_mons : lvl_mons);
                     43:     do
                     44:     {
                     45:        d = level + (rnd(10) - 6);
                     46:        if (d < 0)
                     47:            d = rnd(5);
                     48:        if (d > 25)
                     49:            d = rnd(5) + 21;
                     50:     } while (mons[d] == 0);
                     51:     return mons[d];
                     52: }
                     53:
                     54: /*
                     55:  * new_monster:
                     56:  *     Pick a new monster and add it to the list
                     57:  */
                     58:
                     59: void
                     60: new_monster(THING *tp, int type, const coord *cp)
                     61: {
                     62:     struct monster *mp;
                     63:     int lev_add;
                     64:
                     65:     if ((lev_add = level - AMULETLEVEL) < 0)
                     66:        lev_add = 0;
                     67:     attach(mlist, tp);
                     68:     tp->t_type = type;
                     69:     tp->t_disguise = type;
                     70:     tp->t_pos = *cp;
                     71:     move(cp->y, cp->x);
                     72:     tp->t_oldch = CCHAR( inch() );
                     73:     tp->t_room = roomin(cp);
                     74:     moat(cp->y, cp->x) = tp;
                     75:     mp = &monsters[tp->t_type-'A'];
                     76:     tp->t_stats.s_lvl = mp->m_stats.s_lvl + lev_add;
                     77:     tp->t_stats.s_maxhp = tp->t_stats.s_hpt = roll(tp->t_stats.s_lvl, 8);
                     78:     tp->t_stats.s_arm = mp->m_stats.s_arm - lev_add;
                     79:     strcpy(tp->t_stats.s_dmg,mp->m_stats.s_dmg);
                     80:     tp->t_stats.s_str = mp->m_stats.s_str;
                     81:     tp->t_stats.s_exp = mp->m_stats.s_exp + lev_add * 10 + exp_add(tp);
                     82:     tp->t_flags = mp->m_flags;
                     83:     if (level > 29)
                     84:        tp->t_flags |= ISHASTE;
                     85:     tp->t_turn = TRUE;
                     86:     tp->t_pack = NULL;
                     87:     if (ISWEARING(R_AGGR))
                     88:        runto(cp);
                     89:     if (type == 'X')
                     90:        tp->t_disguise = rnd_thing();
                     91: }
                     92:
                     93: /*
                     94:  * expadd:
                     95:  *     Experience to add for this monster's level/hit points
                     96:  */
                     97: int
                     98: exp_add(const THING *tp)
                     99: {
                    100:     int mod;
                    101:
                    102:     if (tp->t_stats.s_lvl == 1)
                    103:        mod = tp->t_stats.s_maxhp / 8;
                    104:     else
                    105:        mod = tp->t_stats.s_maxhp / 6;
                    106:     if (tp->t_stats.s_lvl > 9)
                    107:        mod *= 20;
                    108:     else if (tp->t_stats.s_lvl > 6)
                    109:        mod *= 4;
                    110:     return mod;
                    111: }
                    112:
                    113: /*
                    114:  * wanderer:
                    115:  *     Create a new wandering monster and aim it at the player
                    116:  */
                    117:
                    118: void
                    119: wanderer(void)
                    120: {
                    121:     THING *tp;
                    122:     coord cp;
                    123:     int cnt = 0;
                    124:
                    125:     tp = new_item();
                    126:     do
                    127:     {
                    128:         /* Avoid endless loop when all rooms are filled with monsters
                    129:         * and the player room is not accessible to the monsters.
                    130:         */
                    131:        if (cnt++ >= 500)
                    132:        {
                    133:            discard(tp);
                    134:            return;
                    135:        }
                    136:        find_floor(NULL, &cp, FALSE, TRUE);
                    137:     } while (roomin(&cp) == proom && moat(cp.y, cp.x) == NULL);
                    138:     new_monster(tp, randmonster(TRUE), &cp);
                    139:     if (on(player, SEEMONST))
                    140:     {
                    141:        standout();
                    142:        if (!on(player, ISHALU))
                    143:            addch(tp->t_type);
                    144:        else
                    145:            addch(rnd(26) + 'A');
                    146:        standend();
                    147:     }
                    148:     runto(&tp->t_pos);
                    149: #ifdef MASTER
                    150:     if (wizard)
                    151:        msg("started a wandering %s", monsters[tp->t_type-'A'].m_name);
                    152: #endif
                    153: }
                    154:
                    155: /*
                    156:  * wake_monster:
                    157:  *     What to do when the hero steps next to a monster
                    158:  */
                    159: const THING *
                    160: wake_monster(int y, int x)
                    161: {
                    162:     THING *tp;
                    163:     struct room *rp;
                    164:        int ch;
                    165:     const char *mname;
                    166:
                    167:        if ((tp = moat(y, x)) == NULL) {
                    168: #ifdef MASTER
                    169:                msg("can't find monster in wake_monster");
                    170: #endif
                    171:                return NULL;
                    172:        }
                    173:
                    174:     ch = tp->t_type;
                    175:     /*
                    176:      * Every time he sees mean monster, it might start chasing him
                    177:      */
                    178:     if (!on(*tp, ISRUN) && rnd(3) != 0 && on(*tp, ISMEAN) && !on(*tp, ISHELD)
                    179:        && !ISWEARING(R_STEALTH) && !on(player, ISLEVIT))
                    180:     {
                    181:        tp->t_dest = &hero;
                    182:        tp->t_flags |= ISRUN;
                    183:     }
                    184:     if (ch == 'M' && !on(player, ISBLIND) && !on(player, ISHALU)
                    185:        && !on(*tp, ISFOUND) && !on(*tp, ISCANC) && on(*tp, ISRUN))
                    186:     {
                    187:         rp = proom;
                    188:        if ((rp != NULL && !(rp->r_flags & ISDARK))
                    189:            || dist(y, x, hero.y, hero.x) < LAMPDIST)
                    190:        {
                    191:            tp->t_flags |= ISFOUND;
                    192:            if (!save(VS_MAGIC))
                    193:            {
                    194:                if (on(player, ISHUH))
                    195:                    lengthen(unconfuse, spread(HUHDURATION));
                    196:                else
                    197:                    fuse(unconfuse, 0, spread(HUHDURATION), AFTER);
                    198:                player.t_flags |= ISHUH;
                    199:                mname = set_mname(tp);
                    200:                addmsg("%s", mname);
                    201:                if (strcmp(mname, "it") != 0)
                    202:                    addmsg("'");
                    203:                msg("s gaze has confused you");
                    204:            }
                    205:        }
                    206:     }
                    207:     /*
                    208:      * Let greedy ones guard gold
                    209:      */
                    210:     if (on(*tp, ISGREED) && !on(*tp, ISRUN))
                    211:     {
                    212:        tp->t_flags |= ISRUN;
                    213:        if (proom->r_goldval)
                    214:            tp->t_dest = &proom->r_gold;
                    215:        else
                    216:            tp->t_dest = &hero;
                    217:     }
                    218:     return tp;
                    219: }
                    220:
                    221: /*
                    222:  * give_pack:
                    223:  *     Give a pack to a monster if it deserves one
                    224:  */
                    225:
                    226: void
                    227: give_pack(THING *tp)
                    228: {
                    229:     if (level >= max_level && rnd(100) < monsters[tp->t_type-'A'].m_carry)
                    230:        attach(tp->t_pack, new_thing());
                    231: }
                    232:
                    233: /*
                    234:  * save_throw:
                    235:  *     See if a creature save against something
                    236:  */
                    237: int
                    238: save_throw(int which, const THING *tp)
                    239: {
                    240:     int need;
                    241:
                    242:     need = 14 + which - tp->t_stats.s_lvl / 2;
                    243:     return (roll(1, 20) >= need);
                    244: }
                    245:
                    246: /*
                    247:  * save:
                    248:  *     See if he saves against various nasty things
                    249:  */
                    250: int
                    251: save(int which)
                    252: {
                    253:     if (which == VS_MAGIC)
                    254:     {
                    255:        if (ISRING(LEFT, R_PROTECT))
                    256:            which -= cur_ring[LEFT]->o_arm;
                    257:        if (ISRING(RIGHT, R_PROTECT))
                    258:            which -= cur_ring[RIGHT]->o_arm;
                    259:     }
                    260:     return save_throw(which, &player);
                    261: }

CVSweb