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

Annotation of early-roguelike/arogue7/weapons.c, Revision 1.1.1.1

1.1       rubenllo    1: /*
                      2:  * weapons.c - Functions for dealing with problems brought about by weapons
                      3:  *
                      4:  * Advanced Rogue
                      5:  * Copyright (C) 1984, 1985, 1986 Michael Morgan, Ken Dalka and AT&T
                      6:  * All rights reserved.
                      7:  *
                      8:  * Based on "Rogue: Exploring the Dungeons of Doom"
                      9:  * Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman
                     10:  * All rights reserved.
                     11:  *
                     12:  * See the file LICENSE.TXT for full copyright and licensing information.
                     13:  */
                     14:
                     15: /*
                     16:  * Functions for dealing with problems brought about by weapons
                     17:  *
                     18:  */
                     19:
                     20: #include "curses.h"
                     21: #include <ctype.h>
                     22: #include <string.h>
                     23: #include "rogue.h"
                     24:
                     25: void
                     26: boomerang(int ydelta, int xdelta, struct linked_list *item, struct thing *tp)
                     27: {
                     28:        register struct object *obj;
                     29:        struct thing midpoint;
                     30:        coord oldpos;
                     31:
                     32:        obj = OBJPTR(item);
                     33:        oldpos = obj->o_pos;
                     34:
                     35:        /*
                     36:         * make it appear to fly at the target
                     37:         */
                     38:        do_motion(obj, ydelta, xdelta, tp);
                     39:        hit_monster(unc(obj->o_pos), obj, tp);
                     40:
                     41:        /*
                     42:         * Now let's make it fly back to the wielder.  We need to
                     43:         * use midpoint to fool do_motion into thinking the action
                     44:         * starts there.  Do_motion only looks at the t_pos field.
                     45:         */
                     46:        midpoint.t_pos = obj->o_pos;    /* Simulate a new start position */
                     47:        do_motion(obj, -ydelta, -xdelta, &midpoint);
                     48:
                     49:        obj->o_pos = oldpos;
                     50: }
                     51: 
                     52: /*
                     53:  * do the actual motion on the screen done by an object traveling
                     54:  * across the room.  Note that we should not look at any field in
                     55:  * tp other than t_pos unless we change boomerang().
                     56:  */
                     57: void
                     58: do_motion(struct object *obj, int ydelta, int xdelta, struct thing *tp)
                     59: {
                     60:
                     61:        /*
                     62:        * Come fly with us ...
                     63:        */
                     64:        obj->o_pos = tp->t_pos;
                     65:        for (; ;) {
                     66:                register int ch;
                     67:                /*
                     68:                * Erase the old one
                     69:                */
                     70:                if (!ce(obj->o_pos, tp->t_pos) &&
                     71:                    cansee(unc(obj->o_pos)) &&
                     72:                    mvwinch(cw, obj->o_pos.y, obj->o_pos.x) != ' ') {
                     73:                        mvwaddch(cw, obj->o_pos.y, obj->o_pos.x, show(obj->o_pos.y, obj->o_pos.x));
                     74:                }
                     75:                /*
                     76:                * Get the new position
                     77:                */
                     78:                obj->o_pos.y += ydelta;
                     79:                obj->o_pos.x += xdelta;
                     80:                if (shoot_ok(ch = winat(obj->o_pos.y, obj->o_pos.x)) && ch != DOOR && !ce(obj->o_pos, hero)) {
                     81:                        /*
                     82:                        * It hasn't hit anything yet, so display it
                     83:                        * If it alright.
                     84:                        */
                     85:                        if (cansee(unc(obj->o_pos)) &&
                     86:                            mvwinch(cw, obj->o_pos.y, obj->o_pos.x) != ' ') {
                     87:                                mvwaddch(cw, obj->o_pos.y, obj->o_pos.x, obj->o_type);
                     88:                                draw(cw);
                     89:                        }
                     90:                        continue;
                     91:                }
                     92:
                     93:                /*
                     94:                 * Did we stop because of a monster or the hero?  If we did
                     95:                 * not, we want to move our position back one because we could
                     96:                 * not actually make it this far.
                     97:                 */
                     98:                if (!isalpha(ch) &&
                     99:                    !(obj->o_pos.y == hero.y && obj->o_pos.x == hero.x)) {
                    100:                        obj->o_pos.y -= ydelta;
                    101:                        obj->o_pos.x -= xdelta;
                    102:                }
                    103:
                    104:                break;
                    105:        }
                    106: }
                    107:
                    108: 
                    109: /*
                    110:  * fall:
                    111:  *     Drop an item someplace around here.
                    112:  */
                    113:
                    114: void
                    115: fall(struct linked_list *item, bool pr)
                    116: {
                    117:        register struct object *obj;
                    118:        register struct room *rp;
                    119:        register int i;
                    120:        struct object *tobj;
                    121:        struct linked_list *titem;
                    122:        coord *fpos;
                    123:
                    124:        obj = OBJPTR(item);
                    125:        /*
                    126:         * try to drop the item, look up to 3 squares away for now
                    127:         */
                    128:        for (i=1; i<4; i++) {
                    129:            if ((fpos = fallpos(&obj->o_pos, FALSE, i)) != NULL)
                    130:                break;
                    131:        }
                    132:
                    133:        if (fpos != NULL) {
                    134:                if (obj->o_group) { /* try to add groups together */
                    135:                    for(titem=lvl_obj; titem!=NULL; titem=next(titem)) {
                    136:                        tobj = OBJPTR(titem);
                    137:                        if (tobj->o_group == obj->o_group       &&
                    138:                            tobj->o_pos.y == fpos->y            &&
                    139:                            tobj->o_pos.x == fpos->x) {
                    140:                                tobj->o_count += obj->o_count;
                    141:                                o_discard(item);
                    142:                                return;
                    143:                        }
                    144:                    }
                    145:                }
                    146:                mvaddch(fpos->y, fpos->x, obj->o_type);
                    147:                obj->o_pos = *fpos;
                    148:                if ((rp = roomin(&hero)) != NULL &&
                    149:                    lit_room(rp)) {
                    150:                        light(&hero);
                    151:                        mvwaddch(cw, hero.y, hero.x, PLAYER);
                    152:                }
                    153:                attach(lvl_obj, item);
                    154:                return;
                    155:        }
                    156:        if (pr) {
                    157:            msg("The %s vanishes as it hits the ground.",
                    158:                weaps[obj->o_which].w_name);
                    159:        }
                    160:        o_discard(item);
                    161: }
                    162:
                    163: 
                    164: /*
                    165:  * Does the missile hit the monster
                    166:  */
                    167:
                    168: bool
                    169: hit_monster(int y, int x, struct object *obj, struct thing *tp)
                    170: {
                    171:        static coord mp;
                    172:
                    173:        mp.y = y;
                    174:        mp.x = x;
                    175:        if (tp == &player) {
                    176:                /* Make sure there is a monster where it landed */
                    177:                if (!isalpha(mvwinch(mw, y, x))) {
                    178:                        return(FALSE);
                    179:                }
                    180:
                    181:                /* Player hits monster */
                    182:                return(fight(&mp, obj, TRUE));
                    183:        } else {
                    184:                if (!ce(mp, hero)) {
                    185:                    /* Monster hits monster */
                    186:                    return(skirmish(tp, &mp, obj, TRUE));
                    187:                }
                    188:
                    189:                /* Monster hits player */
                    190:                return(attack(tp, obj, TRUE));
                    191:        }
                    192: }
                    193: 
                    194: /*
                    195:  * init_weapon:
                    196:  *     Set up the initial goodies for a weapon
                    197:  */
                    198:
                    199: void
                    200: init_weapon(struct object *weap, char type)
                    201: {
                    202:        register struct init_weps *iwp;
                    203:
                    204:        iwp = &weaps[type];
                    205:        strncpy(weap->o_damage, iwp->w_dam, sizeof(weap->o_damage));
                    206:        strncpy(weap->o_hurldmg, iwp->w_hrl, sizeof(weap->o_hurldmg));
                    207:        weap->o_launch = iwp->w_launch;
                    208:        weap->o_flags = iwp->w_flags;
                    209:        weap->o_weight = iwp->w_wght;
                    210:        if (weap->o_flags & ISMANY) {
                    211:                weap->o_count = rnd(8) + 8;
                    212:                weap->o_group = newgrp();
                    213:        } else {
                    214:                weap->o_count = 1;
                    215:        }
                    216: }
                    217: 
                    218: /*
                    219:  * missile:
                    220:  *     Fire a missile in a given direction
                    221:  */
                    222:
                    223: void
                    224: missile(int ydelta, int xdelta, struct linked_list *item, struct thing *tp)
                    225: {
                    226:        register struct object *obj;
                    227:        register struct linked_list *nitem;
                    228:        char ch;
                    229:
                    230:        /*
                    231:        * Get which thing we are hurling
                    232:        */
                    233:        if (item == NULL) {
                    234:                return;
                    235:        }
                    236:        obj = OBJPTR(item);
                    237:        if (obj->o_type == RELIC && obj->o_which == AXE_AKLAD) {
                    238:            boomerang(ydelta, xdelta, item, tp);
                    239:            return;
                    240:        }
                    241:
                    242:        if (!dropcheck(obj)) return;    /* Can we get rid of it? */
                    243:
                    244:        if(!(obj->o_flags & ISMISL)) {
                    245:            while (TRUE) {
                    246:                msg(terse ? "Really throw? (y or n): "
                    247:                          : "Do you really want to throw %s? (y or n): ",
                    248:                                inv_name(obj, TRUE));
                    249:                mpos = 0;
                    250:                ch = readchar();
                    251:                if (ch == 'n' || ch == ESCAPE) {
                    252:                    after = FALSE;
                    253:                    return;
                    254:                }
                    255:                if (ch == 'y')
                    256:                    break;
                    257:            }
                    258:        }
                    259:        /*
                    260:         * Get rid of the thing. If it is a non-multiple item object, or
                    261:         * if it is the last thing, just drop it. Otherwise, create a new
                    262:         * item with a count of one.
                    263:         */
                    264:        if (obj->o_count < 2) {
                    265:                detach(tp->t_pack, item);
                    266:                if (tp->t_pack == pack) {
                    267:                        inpack--;
                    268:                }
                    269:        }
                    270:        else {
                    271:                obj->o_count--;
                    272:                nitem = (struct linked_list *) new_item(sizeof *obj);
                    273:                obj = OBJPTR(nitem);
                    274:                *obj = *(OBJPTR(item));
                    275:                obj->o_count = 1;
                    276:                item = nitem;
                    277:        }
                    278:        updpack(FALSE, tp);
                    279:        do_motion(obj, ydelta, xdelta, tp);
                    280:        /*
                    281:        * AHA! Here it has hit something. If it is a wall or a door,
                    282:        * or if it misses (combat) the monster, put it on the floor
                    283:        */
                    284:        if (!hit_monster(unc(obj->o_pos), obj, tp)) {
                    285:                fall(item, TRUE);
                    286:        }
                    287:        mvwaddch(cw, hero.y, hero.x, PLAYER);
                    288: }
                    289: 
                    290: /*
                    291:  * num:
                    292:  *     Figure out the plus number for armor/weapons
                    293:  */
                    294:
                    295: char *
                    296: num(int n1, int n2)
                    297: {
                    298:        static char numbuf[LINELEN];
                    299:
                    300:        if (n1 == 0 && n2 == 0) {
                    301:                return "+0";
                    302:        }
                    303:        if (n2 == 0) {
                    304:                sprintf(numbuf, "%s%d", n1 < 0 ? "" : "+", n1);
                    305:        } else {
                    306:                sprintf(numbuf, "%s%d, %s%d", n1 < 0 ? "" : "+", n1, n2 < 0 ? "" : "+", n2);
                    307:        }
                    308:        return(numbuf);
                    309: }
                    310: 
                    311: /*
                    312:  * wield:
                    313:  *     Pull out a certain weapon
                    314:  */
                    315:
                    316: void
                    317: wield(void)
                    318: {
                    319:        register struct linked_list *item;
                    320:        register struct object *obj, *oweapon;
                    321:
                    322:        /*
                    323:         * It takes 2 movement periods to unwield a weapon and 2 movement
                    324:         * periods to wield a weapon.
                    325:         */
                    326:        if (player.t_action != C_WIELD) {
                    327:            player.t_action = C_WIELD;
                    328:            player.t_using = NULL;      /* Make sure this is NULL! */
                    329:            if (cur_weapon != NULL) {
                    330:                player.t_no_move = 2 * movement(&player);
                    331:                return;
                    332:            }
                    333:        }
                    334:
                    335:        if ((oweapon = cur_weapon) != NULL) {
                    336:            /* At this point we have waited at least 2 units */
                    337:            if (!dropcheck(cur_weapon)) {
                    338:                    cur_weapon = oweapon;
                    339:                    player.t_action = A_NIL;
                    340:                    return;
                    341:            }
                    342:            if (terse)
                    343:                addmsg("Was ");
                    344:            else
                    345:                addmsg("You were ");
                    346:            msg("wielding %s", inv_name(oweapon, TRUE));
                    347:        }
                    348:
                    349:        /* We we have something picked out? */
                    350:        if (player.t_using == NULL) {
                    351:            /* Now, what does he want to wield? */
                    352:            if ((item = get_item(pack, "wield", WIELDABLE, FALSE, FALSE)) == NULL) {
                    353:                    player.t_action = A_NIL;
                    354:                    after = FALSE;
                    355:                    return;
                    356:            }
                    357:            player.t_using = item;
                    358:            player.t_no_move = 2 * movement(&player);
                    359:            return;
                    360:        }
                    361:
                    362:        /* We have waited our time, let's wield the weapon */
                    363:        item = player.t_using;
                    364:        player.t_using = NULL;
                    365:        player.t_action = A_NIL;
                    366:
                    367:        obj = OBJPTR(item);
                    368:
                    369:        if (is_current(obj)) {
                    370:                msg("Item in use.");
                    371:                after = FALSE;
                    372:                return;
                    373:        }
                    374:        if (player.t_ctype != C_FIGHTER &&
                    375:            player.t_ctype != C_RANGER  &&
                    376:            player.t_ctype != C_PALADIN &&
                    377:            obj->o_type == WEAPON       &&
                    378:           (obj->o_which == TWOSWORD  ||
                    379:            (obj->o_which == BASWORD &&
                    380:             player.t_ctype != C_ASSASIN))) {
                    381:                msg("Only fighter types can wield a %s",
                    382:                    weaps[obj->o_which].w_name);
                    383:                return;
                    384:        }
                    385:        if (terse) {
                    386:                addmsg("W");
                    387:        } else {
                    388:                addmsg("You are now w");
                    389:        }
                    390:        msg("ielding %s", inv_name(obj, TRUE));
                    391:        cur_weapon = obj;
                    392: }
                    393:

CVSweb