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

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

1.1       rubenllo    1: /*
                      2:  * Functions to implement the various sticks one might find
                      3:  * while wandering around the dungeon.
                      4:  *
                      5:  * @(#)sticks.c        4.22 (Berkeley) 5/19/82
                      6:  *
                      7:  * Rogue: Exploring the Dungeons of Doom
                      8:  * Copyright (C) 1980, 1981, 1982 Michael Toy, Ken Arnold and Glenn Wichman
                      9:  * All rights reserved.
                     10:  *
                     11:  * See the file LICENSE.TXT for full copyright and licensing information.
                     12:  */
                     13:
                     14: #include <curses.h>
                     15: #include <ctype.h>
                     16: #include <string.h>
                     17: #include "rogue.h"
                     18:
                     19: void drain(void);
                     20:
                     21: /*
                     22:  * fix_stick:
                     23:  *     Set up a new stick
                     24:  */
                     25: void
                     26: fix_stick(THING *cur)
                     27: {
                     28:     if (strcmp(ws_type[cur->o_which], "staff") == 0)
                     29:        strcpy(cur->o_damage,"2d3");
                     30:     else
                     31:        strcpy(cur->o_damage,"1d1");
                     32:     strcpy(cur->o_hurldmg,"1d1");
                     33:
                     34:     cur->o_charges = 3 + rnd(5);
                     35:     switch (cur->o_which)
                     36:     {
                     37:        case WS_HIT:
                     38:            cur->o_hplus = 100;
                     39:            cur->o_dplus = 3;
                     40:            strcpy(cur->o_damage,"1d8");
                     41:        when WS_LIGHT:
                     42:            cur->o_charges = 10 + rnd(10);
                     43:     }
                     44: }
                     45:
                     46: /*
                     47:  * do_zap:
                     48:  *     Perform a zap with a wand
                     49:  */
                     50: void
                     51: do_zap(void)
                     52: {
                     53:     register THING *obj, *tp;
                     54:     register int y, x;
                     55:     register char *name;
                     56:
                     57:     if ((obj = get_item("zap with", STICK)) == NULL)
                     58:        return;
                     59:     if (obj->o_type != STICK)
                     60:     {
                     61:        after = FALSE;
                     62:        msg("you can't zap with that!");
                     63:        return;
                     64:     }
                     65:     if (obj->o_charges == 0)
                     66:     {
                     67:        msg("nothing happens");
                     68:        return;
                     69:     }
                     70:     switch (obj->o_which)
                     71:     {
                     72:        case WS_LIGHT:
                     73:            /*
                     74:             * Reddy Kilowat wand.  Light up the room
                     75:             */
                     76:            ws_know[WS_LIGHT] = TRUE;
                     77:            if (proom->r_flags & ISGONE)
                     78:                msg("the corridor glows and then fades");
                     79:            else
                     80:            {
                     81:                proom->r_flags &= ~ISDARK;
                     82:                /*
                     83:                 * Light the room and put the player back up
                     84:                 */
                     85:                enter_room(&hero);
                     86:                addmsg("the room is lit");
                     87:                if (!terse)
                     88:                    addmsg(" by a shimmering blue light");
                     89:                endmsg();
                     90:            }
                     91:        when WS_DRAIN:
                     92:            /*
                     93:             * Take away 1/2 of hero's hit points, then take it away
                     94:             * evenly from the monsters in the room (or next to hero
                     95:             * if he is in a passage)
                     96:             */
                     97:            if (pstats.s_hpt < 2)
                     98:            {
                     99:                msg("you are too weak to use it");
                    100:                return;
                    101:            }
                    102:            else
                    103:                drain();
                    104:        when WS_POLYMORPH:
                    105:        case WS_TELAWAY:
                    106:        case WS_TELTO:
                    107:        case WS_CANCEL:
                    108:        {
                    109:            register char monster, oldch;
                    110:            register int rm;
                    111:
                    112:            y = hero.y;
                    113:            x = hero.x;
                    114:            while (step_ok(winat(y, x)))
                    115:            {
                    116:                y += delta.y;
                    117:                x += delta.x;
                    118:            }
                    119:            if ((tp = moat(y, x)) != NULL)
                    120:            {
                    121:                register char omonst;
                    122:
                    123:                omonst = monster = tp->t_type;
                    124:                if (monster == 'F')
                    125:                    player.t_flags &= ~ISHELD;
                    126:                if (obj->o_which == WS_POLYMORPH)
                    127:                {
                    128:                    register THING *pp;
                    129:
                    130:                    pp = tp->t_pack;
                    131:                    detach(mlist, tp);
                    132:                    if (see_monst(tp))
                    133:                        mvaddch(y, x, chat(y, x));
                    134:                    oldch = tp->t_oldch;
                    135:                    delta.y = y;
                    136:                    delta.x = x;
                    137:                    new_monster(tp, monster = rnd(26) + 'A', &delta);
                    138:                    if (see_monst(tp))
                    139:                        mvaddch(y, x, monster);
                    140:                    tp->t_oldch = oldch;
                    141:                    tp->t_pack = pp;
                    142:                    ws_know[WS_POLYMORPH] |= (monster != omonst);
                    143:                }
                    144:                else if (obj->o_which == WS_CANCEL)
                    145:                {
                    146:                    tp->t_flags |= ISCANC;
                    147:                    tp->t_flags &= ~(ISINVIS|CANHUH);
                    148:                    tp->t_disguise = tp->t_type;
                    149:                }
                    150:                else
                    151:                {
                    152:                    if (isupper(toascii(mvinch(y,x))))
                    153:                        mvaddch(y, x, tp->t_oldch);
                    154:                    if (obj->o_which == WS_TELAWAY)
                    155:                    {
                    156:                        do
                    157:                        {
                    158:                            rm = rnd_room();
                    159:                            rnd_pos(&rooms[rm], &tp->t_pos);
                    160:                        } until (winat(tp->t_pos.y, tp->t_pos.x) == FLOOR);
                    161:                        tp->t_room = roomin(&tp->t_pos);
                    162:                        tp->t_oldch = mvinch(tp->t_pos.y, tp->t_pos.x);
                    163:                        if (see_monst(tp))
                    164:                            mvaddch(tp->t_pos.y, tp->t_pos.x, tp->t_disguise);
                    165:                        else if (on(player, SEEMONST))
                    166:                        {
                    167:                            standout();
                    168:                            mvaddch(tp->t_pos.y, tp->t_pos.x, tp->t_disguise);
                    169:                            standend();
                    170:                        }
                    171:                    }
                    172:                    else
                    173:                    {
                    174:                        tp->t_pos.y = hero.y + delta.y;
                    175:                        tp->t_pos.x = hero.x + delta.x;
                    176:
                    177:                        if (tp->t_pos.y != y || tp->t_pos.x != x)
                    178:                            tp->t_oldch = mvinch(tp->t_pos.y, tp->t_pos.x);
                    179:                    }
                    180:                    moat(y, x) = NULL;
                    181:                    moat(tp->t_pos.y, tp->t_pos.x) = tp;
                    182:                    if (tp->t_type == 'F')
                    183:                        player.t_flags &= ~ISHELD;
                    184:                }
                    185:                tp->t_dest = &hero;
                    186:                tp->t_flags |= ISRUN;
                    187:            }
                    188:        }
                    189:        when WS_MISSILE:
                    190:        {
                    191:            THING bolt;
                    192:
                    193:            ws_know[WS_MISSILE] = TRUE;
                    194:            bolt.o_type = '*';
                    195:            strcpy(bolt.o_hurldmg,"1d4");
                    196:            bolt.o_hplus = 100;
                    197:            bolt.o_dplus = 1;
                    198:            bolt.o_flags = ISMISL;
                    199:            if (cur_weapon != NULL)
                    200:                bolt.o_launch = cur_weapon->o_which;
                    201:            do_motion(&bolt, delta.y, delta.x);
                    202:            if ((tp = moat(bolt.o_pos.y, bolt.o_pos.x)) != NULL && !save_throw(VS_MAGIC, tp))
                    203:                    hit_monster(unc(bolt.o_pos), &bolt);
                    204:            else if (terse)
                    205:                msg("missle vanishes");
                    206:            else
                    207:                msg("the missle vanishes with a puff of smoke");
                    208:        }
                    209:        when WS_HIT:
                    210:            delta.y += hero.y;
                    211:            delta.x += hero.x;
                    212:            if ((tp = moat(delta.y, delta.x)) != NULL)
                    213:            {
                    214:                if (rnd(20) == 0)
                    215:                {
                    216:                    strcpy(obj->o_damage,"3d8");
                    217:                    obj->o_dplus = 9;
                    218:                }
                    219:                else
                    220:                {
                    221:                    strcpy(obj->o_damage,"1d8");
                    222:                    obj->o_dplus = 3;
                    223:                }
                    224:                fight(&delta, tp->t_type, obj, FALSE);
                    225:            }
                    226:        when WS_HASTE_M:
                    227:        case WS_SLOW_M:
                    228:            y = hero.y;
                    229:            x = hero.x;
                    230:            while (step_ok(winat(y, x)))
                    231:            {
                    232:                y += delta.y;
                    233:                x += delta.x;
                    234:            }
                    235:            if ((tp = moat(y, x)) != NULL)
                    236:            {
                    237:                if (obj->o_which == WS_HASTE_M)
                    238:                {
                    239:                    if (on(*tp, ISSLOW))
                    240:                        tp->t_flags &= ~ISSLOW;
                    241:                    else
                    242:                        tp->t_flags |= ISHASTE;
                    243:                }
                    244:                else
                    245:                {
                    246:                    if (on(*tp, ISHASTE))
                    247:                        tp->t_flags &= ~ISHASTE;
                    248:                    else
                    249:                        tp->t_flags |= ISSLOW;
                    250:                    tp->t_turn = TRUE;
                    251:                }
                    252:                delta.y = y;
                    253:                delta.x = x;
                    254:                runto(&delta, &hero);
                    255:            }
                    256:        when WS_ELECT:
                    257:        case WS_FIRE:
                    258:        case WS_COLD:
                    259:            if (obj->o_which == WS_ELECT)
                    260:                name = "bolt";
                    261:            else if (obj->o_which == WS_FIRE)
                    262:                name = "flame";
                    263:            else
                    264:                name = "ice";
                    265:            fire_bolt(&hero, &delta, name);
                    266:            ws_know[obj->o_which] = TRUE;
                    267:        when WS_NOP:
                    268:        otherwise:
                    269:            msg("what a bizarre schtick!");
                    270:     }
                    271:     obj->o_charges--;
                    272: }
                    273:
                    274: /*
                    275:  * drain:
                    276:  *     Do drain hit points from player shtick
                    277:  */
                    278: void
                    279: drain(void)
                    280: {
                    281:     register THING *mp;
                    282:     register int cnt;
                    283:     register struct room *corp;
                    284:     register THING **dp;
                    285:     register bool inpass;
                    286:     static THING *drainee[40];
                    287:
                    288:     /*
                    289:      * First cnt how many things we need to spread the hit points among
                    290:      */
                    291:     cnt = 0;
                    292:     if (chat(hero.y, hero.x) == DOOR)
                    293:        corp = &passages[flat(hero.y, hero.x) & F_PNUM];
                    294:     else
                    295:        corp = NULL;
                    296:     inpass = (proom->r_flags & ISGONE);
                    297:     dp = drainee;
                    298:     for (mp = mlist; mp != NULL; mp = next(mp))
                    299:        if (mp->t_room == proom || mp->t_room == corp ||
                    300:            (inpass && chat(mp->t_pos.y, mp->t_pos.x) == DOOR &&
                    301:            &passages[flat(mp->t_pos.y, mp->t_pos.x) & F_PNUM] == proom))
                    302:                *dp++ = mp;
                    303:     if ((cnt = dp - drainee) == 0)
                    304:     {
                    305:        msg("you have a tingling feeling");
                    306:        return;
                    307:     }
                    308:     *dp = NULL;
                    309:     pstats.s_hpt /= 2;
                    310:     cnt = pstats.s_hpt / cnt;
                    311:     /*
                    312:      * Now zot all of the monsters
                    313:      */
                    314:     for (dp = drainee; *dp; dp++)
                    315:     {
                    316:        mp = *dp;
                    317:        if ((mp->t_stats.s_hpt -= cnt) <= 0)
                    318:            killed(mp, see_monst(mp));
                    319:        else
                    320:            runto(&mp->t_pos, &hero);
                    321:     }
                    322: }
                    323:
                    324: /*
                    325:  * fire_bolt:
                    326:  *     Fire a bolt in a given direction from a specific starting place
                    327:  */
                    328: void
                    329: fire_bolt(coord *start, coord *dir, char *name)
                    330: {
                    331:     register char dirch, ch;
                    332:     register THING *tp;
                    333:     register bool hit_hero, used, changed;
                    334:     register int i, j;
                    335:     coord pos;
                    336:     coord spotpos[BOLT_LENGTH];
                    337:     THING bolt;
                    338:
                    339:     bolt.o_type = WEAPON;
                    340:     bolt.o_which = FLAME;
                    341:     strcpy(bolt.o_hurldmg,"6d6");
                    342:     bolt.o_hplus = 100;
                    343:     bolt.o_dplus = 0;
                    344:     bolt.o_flags = 0;
                    345:     w_names[FLAME] = name;
                    346:     switch (dir->y + dir->x)
                    347:     {
                    348:        case 0: dirch = '/';
                    349:        when 1: case -1: dirch = (dir->y == 0 ? '-' : '|');
                    350:        when 2: case -2: dirch = '\\';
                    351:     }
                    352:     pos = *start;
                    353:     hit_hero = (start != &hero);
                    354:     used = FALSE;
                    355:     changed = FALSE;
                    356:     for (i = 0; i < BOLT_LENGTH && !used; i++)
                    357:     {
                    358:        pos.y += dir->y;
                    359:        pos.x += dir->x;
                    360:        ch = winat(pos.y, pos.x);
                    361:        spotpos[i] = pos;
                    362:        switch (ch)
                    363:        {
                    364:            case DOOR:
                    365:                /*
                    366:                 * this code is necessary if the hero is on a door
                    367:                 * and he fires at the wall the door is in, it would
                    368:                 * otherwise loop infinitely
                    369:                 * It is also needed if a dragon flames at the hero.
                    370:                 * If the hero is at a door, the dragon flame would bounce
                    371:                 * and could kill other monsters inadvertly.
                    372:                 */
                    373:                if (ce(hero, pos))
                    374:                    goto def;
                    375:                /* FALLTHROUGH */
                    376:
                    377:            case '|':
                    378:            case '-':
                    379:            case ' ':
                    380:                if (!changed)
                    381:                    hit_hero = !hit_hero;
                    382:                changed = FALSE;
                    383:                dir->y = -dir->y;
                    384:                dir->x = -dir->x;
                    385:                i--;
                    386:                msg("the %s bounces", name);
                    387:                break;
                    388:            default:
                    389: def:
                    390:                if (!hit_hero && (tp = moat(pos.y, pos.x)) != NULL)
                    391:                {
                    392:                    hit_hero = TRUE;
                    393:                    changed = !changed;
                    394:                    tp->t_oldch = chat(pos.y, pos.x);
                    395:                    if (!save_throw(VS_MAGIC, tp))
                    396:                    {
                    397:                        bolt.o_pos = pos;
                    398:                        used = TRUE;
                    399:                        if (tp->t_type == 'D' && strcmp(name, "flame") == 0)
                    400:                        {
                    401:                            addmsg("the flame bounces");
                    402:                            if (!terse)
                    403:                                msg("off the dragon");
                    404:                            endmsg();
                    405:                        }
                    406:                        else
                    407:                            hit_monster(unc(pos), &bolt);
                    408:                    }
                    409:                    else if (ch != 'M' || tp->t_disguise == 'M')
                    410:                    {
                    411:                        if (start == &hero)
                    412:                            runto(&pos, &hero);
                    413:                        if (terse)
                    414:                            msg("%s misses", name);
                    415:                        else
                    416:                            msg("the %s whizzes past the %s", name, monsters[ch-'A'].m_name);
                    417:                    }
                    418:                }
                    419:                else if (hit_hero && ce(pos, hero))
                    420:                {
                    421:                    hit_hero = FALSE;
                    422:                    changed = !changed;
                    423:                    if (!save(VS_MAGIC))
                    424:                    {
                    425:                        if ((pstats.s_hpt -= roll(6, 6)) <= 0)
                    426:                            if (start == &hero)
                    427:                                death('b');
                    428:                            else
                    429:                                death(moat(start->y, start->x)->t_type);
                    430:                        used = TRUE;
                    431:                        if (terse)
                    432:                            msg("the %s hits", name);
                    433:                        else
                    434:                            msg("you are hit by the %s", name);
                    435:                    }
                    436:                    else
                    437:                        msg("the %s whizzes by you", name);
                    438:                }
                    439:                mvaddch(pos.y, pos.x, dirch);
                    440:                refresh();
                    441:        }
                    442:     }
                    443:     for (j = 0; j < i; j++)
                    444:        mvaddch(spotpos[j].y, spotpos[j].x, chat(spotpos[j].y, spotpos[j].x));
                    445: }
                    446:
                    447: /*
                    448:  * charge_str:
                    449:  *     Return an appropriate string for a wand charge
                    450:  */
                    451: char *
                    452: charge_str(THING *obj)
                    453: {
                    454:     static char buf[20];
                    455:
                    456:     if (!(obj->o_flags & ISKNOW))
                    457:        buf[0] = '\0';
                    458:     else if (terse)
                    459:        sprintf(buf, " [%d]", obj->o_charges);
                    460:     else
                    461:        sprintf(buf, " [%d charges]", obj->o_charges);
                    462:     return buf;
                    463: }

CVSweb