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

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

CVSweb