Annotation of early-roguelike/arogue7/weapons.c, Revision 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