Annotation of early-roguelike/srogue/things.c, Revision 1.1
1.1 ! rubenllo 1: /*
! 2: * Contains functions for dealing with things like
! 3: * potions and scrolls
! 4: *
! 5: * @(#)things.c 9.0 (rdk) 7/17/84
! 6: *
! 7: * Super-Rogue
! 8: * Copyright (C) 1984 Robert D. Kindelberger
! 9: * All rights reserved.
! 10: *
! 11: * Based on "Rogue: Exploring the Dungeons of Doom"
! 12: * Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman
! 13: * All rights reserved.
! 14: *
! 15: * See the file LICENSE.TXT for full copyright and licensing information.
! 16: */
! 17:
! 18: #include <ctype.h>
! 19: #include <string.h>
! 20: #include "rogue.h"
! 21: #include "rogue.ext"
! 22:
! 23: void basic_init(struct object *cur);
! 24:
! 25: /*
! 26: * inv_name:
! 27: * Return the name of something as it would appear in an inventory.
! 28: */
! 29: char *
! 30: inv_name(struct object *obj, bool drop)
! 31: {
! 32: reg char *pb, *tn, *pl;
! 33: reg int wh, knowit;
! 34: char nm[3], *inm, *q;
! 35:
! 36: wh = obj->o_which;
! 37: knowit = FALSE;
! 38: if (obj->o_count > 1)
! 39: pl = "s";
! 40: else
! 41: pl = "";
! 42: if (obj->o_count > 1)
! 43: sprintf(nm, "%d", obj->o_count);
! 44: else
! 45: strcpy(nm, "A");
! 46: tn = obj->o_typname;
! 47: q = "";
! 48: switch(obj->o_type) {
! 49: case SCROLL:
! 50: sprintf(prbuf, "%s %s%s ", nm, tn, pl);
! 51: pb = &prbuf[strlen(prbuf)];
! 52: if (s_know[wh] || o_on(obj,ISPOST)) {
! 53: knowit = TRUE;
! 54: sprintf(pb, "of %s", s_magic[wh].mi_name);
! 55: }
! 56: else if (s_guess[wh])
! 57: sprintf(pb, "called %s", s_guess[wh]);
! 58: else
! 59: sprintf(pb, "titled '%s'", s_names[wh]);
! 60: when POTION:
! 61: sprintf(prbuf, "%s %s%s ", nm, tn, pl);
! 62: pb = &prbuf[strlen(prbuf)];
! 63: if (p_know[wh] || o_on(obj, ISPOST)) {
! 64: sprintf(pb, "of %s", p_magic[wh].mi_name);
! 65: knowit = TRUE;
! 66: if (p_know[wh]) {
! 67: pb = &prbuf[strlen(prbuf)];
! 68: sprintf(pb,"(%s)",p_colors[wh]);
! 69: }
! 70: }
! 71: else if (p_guess[wh])
! 72: sprintf(pb,"called %s(%s)", p_guess[wh],p_colors[wh]);
! 73: else if (obj->o_count == 1)
! 74: sprintf(prbuf,"%s%s %s %s%s", nm, vowelstr(p_colors[wh]),
! 75: p_colors[wh], tn, pl);
! 76: else
! 77: sprintf(prbuf,"%s %s %s%s", nm, p_colors[wh], tn, pl);
! 78: when FOOD:
! 79: if (wh == 1) {
! 80: if (obj->o_count == 1)
! 81: q = vowelstr(fruit);
! 82: sprintf(prbuf, "%s%s %.72s%s", nm, q, fruit, pl);
! 83: }
! 84: else {
! 85: if (obj->o_count == 1)
! 86: sprintf(prbuf, "Some %s", tn);
! 87: else
! 88: sprintf(prbuf, "%s rations of %s", nm, tn);
! 89: }
! 90: knowit = TRUE;
! 91: when WEAPON:
! 92: inm = w_magic[wh].mi_name;
! 93: strcpy(prbuf, nm);
! 94: if (obj->o_count == 1)
! 95: q = vowelstr(inm);
! 96: pb = &prbuf[strlen(prbuf)];
! 97: if (o_on(obj,ISKNOW | ISPOST)) {
! 98: knowit = TRUE;
! 99: sprintf(pb, " %s %s", num(obj->o_hplus, obj->o_dplus), inm);
! 100: }
! 101: else
! 102: sprintf(pb, "%s %s", q, inm);
! 103: strcat(prbuf, pl);
! 104: when ARMOR:
! 105: inm = a_magic[wh].mi_name;
! 106: if (o_on(obj,ISKNOW | ISPOST)) {
! 107: knowit = TRUE;
! 108: sprintf(prbuf, "%s %s",num(armors[wh].a_class - obj->o_ac, 0),
! 109: inm);
! 110: }
! 111: else
! 112: sprintf(prbuf, "%s", inm);
! 113: when AMULET:
! 114: strcpy(prbuf, "The Amulet of Yendor");
! 115: when STICK: {
! 116: struct rod *rd;
! 117:
! 118: rd = &ws_stuff[wh];
! 119: sprintf(prbuf, "A %s ", rd->ws_type);
! 120: pb = &prbuf[strlen(prbuf)];
! 121: if (ws_know[wh] || o_on(obj, ISPOST)) {
! 122: knowit = TRUE;
! 123: sprintf(pb,"of %s%s",ws_magic[wh].mi_name,charge_str(obj));
! 124: if (ws_know[wh]) {
! 125: pb = &prbuf[strlen(prbuf)];
! 126: sprintf(pb,"(%s)",rd->ws_made);
! 127: }
! 128: }
! 129: else if (ws_guess[wh])
! 130: sprintf(pb, "called %s(%s)", ws_guess[wh], rd->ws_made);
! 131: else
! 132: sprintf(prbuf, "A%s %s %s", vowelstr(rd->ws_made),
! 133: rd->ws_made, rd->ws_type);
! 134: }
! 135: when RING:
! 136: if (r_know[wh] || o_on(obj, ISPOST)) {
! 137: knowit = TRUE;
! 138: sprintf(prbuf, "A%s %s of %s", ring_num(obj), tn,
! 139: r_magic[wh].mi_name);
! 140: if (r_know[wh]) {
! 141: pb = &prbuf[strlen(prbuf)];
! 142: sprintf(pb,"(%s)", r_stones[wh]);
! 143: }
! 144: }
! 145: else if (r_guess[wh])
! 146: sprintf(prbuf,"A %s called %s(%s)",tn, r_guess[wh],
! 147: r_stones[wh]);
! 148: else
! 149: sprintf(prbuf,"A%s %s %s",vowelstr(r_stones[wh]),
! 150: r_stones[wh], tn);
! 151: otherwise:
! 152: sprintf(prbuf,"Something bizarre %s", unctrl(obj->o_type));
! 153: }
! 154: if (obj == cur_armor)
! 155: strcat(prbuf, " (being worn)");
! 156: if (obj == cur_weapon)
! 157: strcat(prbuf, " (weapon in hand)");
! 158: if (obj == cur_ring[LEFT])
! 159: strcat(prbuf, " (on left hand)");
! 160: else if (obj == cur_ring[RIGHT])
! 161: strcat(prbuf, " (on right hand)");
! 162: if (drop && isupper(prbuf[0]))
! 163: prbuf[0] = tolower(prbuf[0]);
! 164: else if (!drop && islower(*prbuf))
! 165: *prbuf = toupper(*prbuf);
! 166: if (o_on(obj, ISPROT))
! 167: strcat(prbuf, " [!]");
! 168: if (o_on(obj, ISPOST))
! 169: strcat(prbuf, " [$]");
! 170: if (knowit) {
! 171: if (o_on(obj, ISCURSED))
! 172: strcat(prbuf, " [-]");
! 173: else if (o_on(obj, ISBLESS))
! 174: strcat(prbuf, " [+]");
! 175: }
! 176: if (!drop)
! 177: strcat(prbuf, ".");
! 178: return prbuf;
! 179: }
! 180:
! 181: /*
! 182: * money:
! 183: * Add to characters purse
! 184: */
! 185: void
! 186: money(void)
! 187: {
! 188: reg struct room *rp;
! 189: reg struct linked_list *item;
! 190: reg struct thing *tp;
! 191:
! 192: rp = player.t_room;
! 193: if (rp != NULL && ce(hero, rp->r_gold)) {
! 194: msg("%d gold pieces.", rp->r_goldval);
! 195: purse += rp->r_goldval;
! 196: rp->r_goldval = 0;
! 197: cmov(rp->r_gold);
! 198: addch(FLOOR);
! 199: /*
! 200: * once gold is taken, all monsters will chase him
! 201: */
! 202: for (item = mlist; item != NULL; item = next(item)) {
! 203: tp = THINGPTR(item);
! 204: if (rnd(100) < 70 && tp->t_room == rp && !iswearing(R_STEALTH)
! 205: && ((tp->t_flags & (ISMEAN | ISGREED)) || rnd(1000) < 20))
! 206: runto(&tp->t_pos, &hero);
! 207: }
! 208: }
! 209: else
! 210: msg("That gold must have been counterfeit.");
! 211: }
! 212:
! 213:
! 214: /*
! 215: * drop:
! 216: * put something down
! 217: */
! 218: int
! 219: drop(struct linked_list *item)
! 220: {
! 221: reg char ch;
! 222: reg struct linked_list *ll, *nll;
! 223: reg struct object *op;
! 224:
! 225: if (item == NULL) {
! 226: ch = mvinch(hero.y, hero.x);
! 227: if (ch != FLOOR && ch != PASSAGE && ch != POOL) {
! 228: msg("There is something there already.");
! 229: after = FALSE;
! 230: return SOMTHERE;
! 231: }
! 232: if ((ll = get_item("drop", 0)) == NULL)
! 233: return FALSE;
! 234: }
! 235: else {
! 236: ll = item;
! 237: }
! 238: op = OBJPTR(ll);
! 239: if (!dropcheck(op))
! 240: return CANTDROP;
! 241: /*
! 242: * Take it out of the pack
! 243: */
! 244: if (op->o_count >= 2 && op->o_type != WEAPON) {
! 245: nll = new_item(sizeof *op);
! 246: op->o_count--;
! 247: op->o_vol = itemvol(op);
! 248: op = OBJPTR(nll);
! 249: *op = *(OBJPTR(ll));
! 250: op->o_count = 1;
! 251: op->o_vol = itemvol(op);
! 252: ll = nll;
! 253: }
! 254: else {
! 255: detach(pack, ll);
! 256: }
! 257: if (ch == POOL) {
! 258: msg("%s sinks out of sight.",inv_name(op, TRUE));
! 259: discard(ll);
! 260: }
! 261: else { /* put on dungeon floor */
! 262: if (levtype == POSTLEV) {
! 263: op->o_pos = hero; /* same place as hero */
! 264: fall(ll,FALSE);
! 265: if (item == NULL) /* if item wasn't sold */
! 266: msg("Thanks for your donation to the Fiend's flea market.");
! 267: }
! 268: else {
! 269: attach(lvl_obj, ll);
! 270: mvaddch(hero.y, hero.x, op->o_type);
! 271: op->o_pos = hero;
! 272: msg("Dropped %s", inv_name(op, TRUE));
! 273: }
! 274: }
! 275: updpack(); /* new pack weight */
! 276: return TRUE;
! 277: }
! 278:
! 279:
! 280: /*
! 281: * dropcheck:
! 282: * Do special checks for dropping or unweilding|unwearing|unringing
! 283: */
! 284: bool
! 285: dropcheck(struct object *op)
! 286: {
! 287: if (op == NULL)
! 288: return TRUE;
! 289: if (levtype == POSTLEV) {
! 290: if (o_on(op,ISCURSED) && o_on(op,ISKNOW)) {
! 291: msg("The trader does not accept shoddy merchandise.");
! 292: return FALSE;
! 293: }
! 294: else {
! 295: cur_null(op); /* update cur_weapon, etc */
! 296: return TRUE;
! 297: }
! 298: }
! 299: if (op != cur_armor && op != cur_weapon
! 300: && op != cur_ring[LEFT] && op != cur_ring[RIGHT])
! 301: return TRUE;
! 302: if (o_on(op,ISCURSED)) {
! 303: msg("You can't. It appears to be cursed.");
! 304: return FALSE;
! 305: }
! 306: if (op == cur_weapon)
! 307: cur_weapon = NULL;
! 308: else if (op == cur_armor) {
! 309: waste_time();
! 310: cur_armor = NULL;
! 311: }
! 312: else if (op == cur_ring[LEFT] || op == cur_ring[RIGHT])
! 313: toss_ring(op);
! 314: return TRUE;
! 315: }
! 316:
! 317:
! 318: /*
! 319: * new_thing:
! 320: * Return a new thing
! 321: */
! 322: struct linked_list *
! 323: new_thing(bool treas, int type, int which)
! 324: {
! 325: struct linked_list *item;
! 326: struct magic_item *mi;
! 327: struct object *cur;
! 328: int chance, whi;
! 329:
! 330: item = new_item(sizeof *cur);
! 331: cur = OBJPTR(item);
! 332: basic_init(cur);
! 333: if (type == DONTCARE) {
! 334: if (++no_food > 4 && !treas)
! 335: whi = TYP_FOOD;
! 336: else
! 337: whi = pick_one(things);
! 338: }
! 339: else {
! 340: whi = getindex(type);
! 341: }
! 342: mi = thnginfo[whi].mf_magic;
! 343: if (which == DONTCARE) {
! 344: which = 0;
! 345: if (mi != NULL)
! 346: which = pick_one(mi);
! 347: }
! 348: cur->o_typname = things[whi].mi_name;
! 349: cur->o_weight = things[whi].mi_wght;
! 350: switch (whi) {
! 351: case TYP_AMULET:
! 352: cur->o_type = AMULET;
! 353: cur->o_hplus = 500;
! 354: strcpy(cur->o_hurldmg,"80d8"); /* if thrown, WOW!!! */
! 355: cur->o_vol = itemvol(cur);
! 356: when TYP_POTION:
! 357: cur->o_type = POTION;
! 358: cur->o_which = which;
! 359: cur->o_count += extras();
! 360: cur->o_vol = itemvol(cur);
! 361: when TYP_SCROLL:
! 362: cur->o_type = SCROLL;
! 363: cur->o_which = which;
! 364: cur->o_count += extras();
! 365: cur->o_vol = itemvol(cur);
! 366: when TYP_FOOD:
! 367: no_food = 0;
! 368: initfood(cur);
! 369: when TYP_WEAPON:
! 370: cur->o_which = which;
! 371: init_weapon(cur, which);
! 372: if ((chance = rnd(100)) < 10) {
! 373: setoflg(cur,ISCURSED);
! 374: cur->o_hplus -= rnd(3)+1;
! 375: cur->o_dplus -= rnd(3)+1;
! 376: }
! 377: else if (chance < 15) {
! 378: cur->o_hplus += rnd(3)+1;
! 379: cur->o_dplus += rnd(3)+1;
! 380: }
! 381: when TYP_ARMOR:
! 382: cur->o_which = which;
! 383: initarmor(cur, which);
! 384: if ((chance = rnd(100)) < 20) {
! 385: setoflg(cur,ISCURSED);
! 386: cur->o_ac += rnd(3)+1;
! 387: }
! 388: else if (chance < 30)
! 389: cur->o_ac -= rnd(3)+1;
! 390: when TYP_RING:
! 391: cur->o_which = which;
! 392: init_ring(cur, FALSE);
! 393: when TYP_STICK:
! 394: default:
! 395: cur->o_which = which;
! 396: fix_stick(cur);
! 397: }
! 398: return item;
! 399: }
! 400:
! 401: /*
! 402: * basic_init:
! 403: * Set all params of an object to the basic values.
! 404: */
! 405: void
! 406: basic_init(struct object *cur)
! 407: {
! 408: cur->o_ac = 11;
! 409: cur->o_count = 1;
! 410: cur->o_launch = 0;
! 411: cur->o_typname = NULL;
! 412: cur->o_group = newgrp();
! 413: cur->o_weight = cur->o_vol = 0;
! 414: cur->o_hplus = cur->o_dplus = 0;
! 415: strcpy(cur->o_damage,"0d0");
! 416: strcpy(cur->o_hurldmg,"0d0");
! 417: cur->o_flags = cur->o_type = cur->o_which = 0;
! 418: }
! 419:
! 420: /*
! 421: * extras:
! 422: * Return the number of extra items to be created
! 423: */
! 424: int
! 425: extras(void)
! 426: {
! 427: reg int i;
! 428:
! 429: i = rnd(100);
! 430: if (i < 4) /* 4% for 2 more */
! 431: return 2;
! 432: else if (i < 11) /* 7% for 1 more */
! 433: return 1;
! 434: else /* otherwise no more */
! 435: return 0;
! 436: }
! 437:
! 438:
! 439: /*
! 440: * pick_one:
! 441: * Pick an item out of a list of nitems possible magic items
! 442: */
! 443: int
! 444: pick_one(struct magic_item *mag)
! 445: {
! 446: reg struct magic_item *start;
! 447: reg int i;
! 448:
! 449: start = mag;
! 450: for (i = rnd(1000); mag->mi_name != NULL; mag++) {
! 451: if (i < mag->mi_prob)
! 452: break;
! 453: if (mag->mi_name == NULL) {
! 454: if (author() || wizard) {
! 455: for (mag = start; mag->mi_name != NULL; mag++)
! 456: msg("%s: %d%%", mag->mi_name, mag->mi_prob);
! 457: }
! 458: mag = start;
! 459: }
! 460: }
! 461: return mag - start;
! 462: }
CVSweb