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

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

CVSweb