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

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

1.1       rubenllo    1: /*
                      2:  * File with various monster functions in it
                      3:  *
                      4:  * @(#)monsters.c      4.24 (Berkeley) 4/6/82
                      5:  *
                      6:  * Rogue: Exploring the Dungeons of Doom
                      7:  * Copyright (C) 1980, 1981, 1982 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 <ctype.h>
                     16: #include "rogue.h"
                     17:
                     18: int exp_add(THING *tp);
                     19:
                     20: /*
                     21:  * List of monsters in rough order of vorpalness
                     22:  *
                     23:  * NOTE: This not initialized using strings so that xstr doesn't set up
                     24:  * the string not to be saved.  Otherwise genocide is lost through
                     25:  * saving a game.
                     26:  */
                     27: char lvl_mons[] =  {
                     28:     'K', 'J', 'B', 'S', 'H', 'E', 'A', 'O', 'Z', 'G', 'L', 'C', 'R',
                     29:     'Q', 'N', 'Y', 'T', 'W', 'F', 'I', 'X', 'U', 'M', 'V', 'P', 'D',
                     30:     '\0'
                     31: };
                     32:
                     33: char wand_mons[] = {
                     34:     'K', 'J', 'B', 'S', 'H', ' ', 'A', 'O', 'Z', 'G', ' ', 'C', 'R',
                     35:     'Q', ' ', 'Y', 'T', 'W', ' ', 'I', 'X', 'U', ' ', 'V', 'P', ' ',
                     36:     '\0'
                     37: };
                     38:
                     39: /*
                     40:  * randmonster:
                     41:  *     Pick a monster to show up.  The lower the level,
                     42:  *     the meaner the monster.
                     43:  */
                     44: char
                     45: randmonster(bool wander)
                     46: {
                     47:     register int d;
                     48:     register char *mons;
                     49:
                     50:     mons = wander ? wand_mons : lvl_mons;
                     51:     do
                     52:     {
                     53:        d = level + (rnd(10) - 5);
                     54:        if (d < 1)
                     55:            d = rnd(5) + 1;
                     56:        if (d > 26)
                     57:            d = rnd(5) + 22;
                     58:     } while (mons[--d] == ' ');
                     59:     return mons[d];
                     60: }
                     61:
                     62: /*
                     63:  * new_monster:
                     64:  *     Pick a new monster and add it to the list
                     65:  */
                     66: void
                     67: new_monster(THING *tp, char type, coord *cp)
                     68: {
                     69:     register struct monster *mp;
                     70:     register int lev_add;
                     71:
                     72:     if ((lev_add = level - AMULETLEVEL) < 0)
                     73:        lev_add = 0;
                     74:     attach(mlist, tp);
                     75:     tp->t_type = type;
                     76:     tp->t_disguise = type;
                     77:     tp->t_pos = *cp;
                     78:     tp->t_oldch = mvinch(cp->y, cp->x);
                     79:     tp->t_room = roomin(cp);
                     80:     moat(cp->y, cp->x) = tp;
                     81:     mp = &monsters[tp->t_type-'A'];
                     82:     tp->t_stats.s_lvl = mp->m_stats.s_lvl + lev_add;
                     83:     tp->t_stats.s_maxhp = tp->t_stats.s_hpt = roll(tp->t_stats.s_lvl, 8);
                     84:     tp->t_stats.s_arm = mp->m_stats.s_arm - lev_add;
                     85:     strncpy(tp->t_stats.s_dmg,mp->m_stats.s_dmg,16);
                     86:     tp->t_stats.s_str = mp->m_stats.s_str;
                     87:     tp->t_stats.s_exp = mp->m_stats.s_exp + lev_add * 10 + exp_add(tp);
                     88:     tp->t_flags = mp->m_flags;
                     89:     tp->t_turn = TRUE;
                     90:     tp->t_pack = NULL;
                     91:     if (ISWEARING(R_AGGR))
                     92:        runto(cp, &hero);
                     93:     if (type == 'M')
                     94:        switch (rnd(level > 25 ? 9 : 8))
                     95:        {
                     96:            case 0: tp->t_disguise = GOLD;
                     97:            when 1: tp->t_disguise = POTION;
                     98:            when 2: tp->t_disguise = SCROLL;
                     99:            when 3: tp->t_disguise = STAIRS;
                    100:            when 4: tp->t_disguise = WEAPON;
                    101:            when 5: tp->t_disguise = ARMOR;
                    102:            when 6: tp->t_disguise = RING;
                    103:            when 7: tp->t_disguise = STICK;
                    104:            when 8: tp->t_disguise = AMULET;
                    105:        }
                    106: }
                    107:
                    108: /*
                    109:  * expadd:
                    110:  *     Experience to add for this monster's level/hit points
                    111:  */
                    112: int
                    113: exp_add(THING *tp)
                    114: {
                    115:     register int mod;
                    116:
                    117:     if (tp->t_stats.s_lvl == 1)
                    118:        mod = tp->t_stats.s_maxhp / 8;
                    119:     else
                    120:        mod = tp->t_stats.s_maxhp / 6;
                    121:     if (tp->t_stats.s_lvl > 9)
                    122:        mod *= 20;
                    123:     else if (tp->t_stats.s_lvl > 6)
                    124:        mod *= 4;
                    125:     return mod;
                    126: }
                    127:
                    128: /*
                    129:  * wanderer:
                    130:  *     Create a new wandering monster and aim it at the player
                    131:  */
                    132: void
                    133: wanderer(void)
                    134: {
                    135:     register int i;
                    136:     register struct room *rp;
                    137:     register THING *tp;
                    138:     coord cp = {0,0};
                    139:     register int cnt = 0;
                    140:
                    141:     tp = new_item();
                    142:     do
                    143:     {
                    144:         /* Avoid endless loop when all rooms are filled with monsters
                    145:         * and the player room is not accessible to the monsters.
                    146:         */
                    147:        if (cnt++ >= 500)
                    148:        {
                    149:            discard(tp);
                    150:            return;
                    151:        }
                    152:        i = rnd_room();
                    153:        if ((rp = &rooms[i]) == proom)
                    154:            continue;
                    155:        rnd_pos(rp, &cp);
                    156:     } until (rp != proom && step_ok(winat(cp.y, cp.x)));
                    157:     new_monster(tp, randmonster(TRUE), &cp);
                    158:     runto(&tp->t_pos, &hero);
                    159: #ifdef WIZARD
                    160:     if (wizard)
                    161:        msg("started a wandering %s", monsters[tp->t_type-'A'].m_name);
                    162: #endif
                    163: }
                    164:
                    165: /*
                    166:  * wake_monster:
                    167:  *     What to do when the hero steps next to a monster
                    168:  */
                    169: THING *
                    170: wake_monster(int y, int x)
                    171: {
                    172:     register THING *tp;
                    173:     register struct room *rp;
                    174:     register char ch;
                    175:
                    176: #ifdef WIZARD
                    177:     if ((tp = moat(y, x)) == NULL)
                    178:        msg("can't find monster in wake_monster");
                    179: #else
                    180:     tp = moat(y, x);
                    181: #endif
                    182:     ch = tp->t_type;
                    183:     /*
                    184:      * Every time he sees mean monster, it might start chasing him
                    185:      */
                    186:     if (!on(*tp, ISRUN) && rnd(3) != 0 && on(*tp, ISMEAN) && !on(*tp, ISHELD)
                    187:        && !ISWEARING(R_STEALTH))
                    188:     {
                    189:        tp->t_dest = &hero;
                    190:        tp->t_flags |= ISRUN;
                    191:     }
                    192:     if (ch == 'U' && !on(player, ISBLIND) && !on(*tp, ISFOUND)
                    193:        && !on(*tp, ISCANC) && on(*tp, ISRUN))
                    194:     {
                    195:         rp = proom;
                    196:        if ((rp != NULL && !(rp->r_flags & ISDARK))
                    197:            || DISTANCE(y, x, hero.y, hero.x) < LAMPDIST)
                    198:        {
                    199:            tp->t_flags |= ISFOUND;
                    200:            if (!save(VS_MAGIC))
                    201:            {
                    202:                if (on(player, ISHUH))
                    203:                    lengthen(unconfuse, rnd(20) + HUHDURATION);
                    204:                else
                    205:                    fuse(unconfuse, 0, rnd(20) + HUHDURATION, AFTER);
                    206:                player.t_flags |= ISHUH;
                    207:                msg("the umber hulk's gaze has confused you");
                    208:            }
                    209:        }
                    210:     }
                    211:     /*
                    212:      * Let greedy ones guard gold
                    213:      */
                    214:     if (on(*tp, ISGREED) && !on(*tp, ISRUN))
                    215:     {
                    216:        tp->t_flags |= ISRUN;
                    217:        if (proom->r_goldval)
                    218:            tp->t_dest = &proom->r_gold;
                    219:        else
                    220:            tp->t_dest = &hero;
                    221:     }
                    222:     return tp;
                    223: }
                    224:
                    225: /*
                    226:  * genocide:
                    227:  *     Wipe one monster out of existence (for now...)
                    228:  */
                    229: void
                    230: genocide(void)
                    231: {
                    232:     register THING *mp;
                    233:     register char c;
                    234:     register int i;
                    235:     register THING *nmp;
                    236:
                    237:     addmsg("which monster");
                    238:     if (!terse)
                    239:        addmsg(" do you wish to wipe out");
                    240:     msg("? ");
                    241:     while (!isalpha(c = readchar()))
                    242:        if (c == ESCAPE)
                    243:            return;
                    244:        else
                    245:        {
                    246:            mpos = 0;
                    247:            msg("please specifiy a letter between 'A' and 'Z'");
                    248:        }
                    249:     mpos = 0;
                    250:     if (islower(c))
                    251:        c = toupper(c);
                    252:     for (mp = mlist; mp; mp = nmp)
                    253:     {
                    254:        nmp = next(mp);
                    255:        if (mp->t_type == c)
                    256:            remove_monster(&mp->t_pos, mp, FALSE);
                    257:     }
                    258:     for (i = 0; i < 26; i++)
                    259:        if (lvl_mons[i] == c)
                    260:        {
                    261:            lvl_mons[i] = ' ';
                    262:            wand_mons[i] = ' ';
                    263:            break;
                    264:        }
                    265:     if (!terse)
                    266:        addmsg("there will be ");
                    267:     msg("no more %ss", monsters[c - 'A'].m_name);
                    268: }
                    269:
                    270: /*
                    271:  * give_pack:
                    272:  *     Give a pack to a monster if it deserves one
                    273:  */
                    274: void
                    275: give_pack(THING *tp)
                    276: {
                    277:     if (rnd(100) < monsters[tp->t_type-'A'].m_carry)
                    278:        attach(tp->t_pack, new_thing());
                    279: }

CVSweb