[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     ! 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