Annotation of early-roguelike/arogue5/wizard.c, Revision 1.1
1.1 ! rubenllo 1: /*
! 2: * Special wizard commands (some of which are also non-wizard commands
! 3: * under strange circumstances)
! 4: *
! 5: * Advanced Rogue
! 6: * Copyright (C) 1984, 1985 Michael Morgan, Ken Dalka and AT&T
! 7: * All rights reserved.
! 8: *
! 9: * Based on "Rogue: Exploring the Dungeons of Doom"
! 10: * Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman
! 11: * All rights reserved.
! 12: *
! 13: * See the file LICENSE.TXT for full copyright and licensing information.
! 14: */
! 15:
! 16: #include "curses.h"
! 17: #include <ctype.h>
! 18: #include <string.h>
! 19: #include <stdlib.h>
! 20: #include "rogue.h"
! 21:
! 22:
! 23: /*
! 24: * create_obj:
! 25: * Create any object for wizard, scroll, magician, or cleric
! 26: */
! 27: void
! 28: create_obj(bool prompt, int which_item, int which_type)
! 29: {
! 30: reg struct linked_list *item;
! 31: reg struct object *obj;
! 32: reg int wh;
! 33: reg char ch, newitem, newtype = 0, whc, msz, *pt;
! 34: WINDOW *thiswin;
! 35:
! 36: thiswin = cw;
! 37: if (prompt) {
! 38: bool nogood = TRUE;
! 39:
! 40: thiswin = hw;
! 41: wclear(hw);
! 42: wprintw(hw,"Item\t\t\tKey\n\n");
! 43: wprintw(hw,"%s\t\t\t%c\n%s\t\t\t%c\n",things[TYP_RING].mi_name,RING,
! 44: things[TYP_STICK].mi_name,STICK);
! 45: wprintw(hw,"%s\t\t\t%c\n%s\t\t\t%c\n",things[TYP_POTION].mi_name,POTION,
! 46: things[TYP_SCROLL].mi_name,SCROLL);
! 47: wprintw(hw,"%s\t\t\t%c\n%s\t\t\t%c\n",things[TYP_ARMOR].mi_name,ARMOR,
! 48: things[TYP_WEAPON].mi_name,WEAPON);
! 49: wprintw(hw,"%s\t%c\n",things[TYP_MM].mi_name,MM);
! 50: wprintw(hw,"%s\t\t\t%c\n",things[TYP_FOOD].mi_name,FOOD);
! 51: if (wizard) {
! 52: wprintw(hw,"%s\t\t%c\n",things[TYP_RELIC].mi_name,RELIC);
! 53: waddstr(hw,"monster\t\t\tm");
! 54: }
! 55: wprintw(hw,"\n\nWhat do you want to create? ");
! 56: draw(hw);
! 57: do {
! 58: ch = wgetch(hw);
! 59: if (ch == ESCAPE) {
! 60: restscr(cw);
! 61: return;
! 62: }
! 63: switch (ch) {
! 64: case RING:
! 65: case STICK:
! 66: case POTION:
! 67: case SCROLL:
! 68: case ARMOR:
! 69: case WEAPON:
! 70: case FOOD:
! 71: case MM:
! 72: nogood = FALSE;
! 73: break;
! 74: case RELIC:
! 75: case 'm':
! 76: if (wizard)
! 77: nogood = FALSE;
! 78: break;
! 79: default:
! 80: nogood = TRUE;
! 81: }
! 82: } while (nogood);
! 83: newitem = ch;
! 84: }
! 85: else
! 86: newitem = which_item;
! 87:
! 88: pt = "those";
! 89: msz = 0;
! 90: if(newitem == 'm') {
! 91: makemonster(TRUE); /* make monster and be done with it */
! 92: return;
! 93: }
! 94: if(newitem == GOLD)
! 95: pt = "gold";
! 96: /* else if(isatrap(newitem))
! 97: pt = "traps";
! 98: */
! 99: switch(newitem) {
! 100: case POTION: whc = TYP_POTION; msz = MAXPOTIONS;
! 101: when SCROLL: whc = TYP_SCROLL; msz = MAXSCROLLS;
! 102: when WEAPON: whc = TYP_WEAPON; msz = MAXWEAPONS;
! 103: when ARMOR: whc = TYP_ARMOR; msz = MAXARMORS;
! 104: when RING: whc = TYP_RING; msz = MAXRINGS;
! 105: when STICK: whc = TYP_STICK; msz = MAXSTICKS;
! 106: when MM: whc = TYP_MM; msz = MAXMM;
! 107: when RELIC: whc = TYP_RELIC; msz = MAXRELIC;
! 108: when FOOD:
! 109: whc = TYP_FOOD;
! 110: msz = MAXFOODS;
! 111: if (thiswin == hw)
! 112: restscr(cw);
! 113: mpos = 0;
! 114: otherwise:
! 115: if (thiswin == hw)
! 116: restscr(cw);
! 117: mpos = 0;
! 118: msg("Even wizards can't create %s !!",pt);
! 119: return;
! 120: }
! 121: if(msz == 1) { /* if only one type of item */
! 122: ch = 'a';
! 123: }
! 124: else if (prompt) {
! 125: register struct magic_item *wmi;
! 126: char wmn;
! 127: register int ii;
! 128: int old_prob;
! 129:
! 130: mpos = 0;
! 131: wmi = NULL;
! 132: wmn = 0;
! 133: switch(newitem) {
! 134: case POTION: wmi = &p_magic[0];
! 135: when SCROLL: wmi = &s_magic[0];
! 136: when RING: wmi = &r_magic[0];
! 137: when STICK: wmi = &ws_magic[0];
! 138: when MM: wmi = &m_magic[0];
! 139: when RELIC: wmi = &rel_magic[0];
! 140: when WEAPON: wmn = 1;
! 141: when ARMOR: wmn = 2;
! 142: }
! 143: wclear(hw);
! 144: thiswin = hw;
! 145: if (wmi != NULL) {
! 146: ii = old_prob = 0;
! 147: while (ii < msz) {
! 148: if(wmi->mi_prob == old_prob && wizard == FALSE) {
! 149: msz--; /* can't make a unique item */
! 150: }
! 151: else {
! 152: mvwaddch(hw,ii % 13,ii > 12 ? COLS/2 : 0, ii + 'a');
! 153: waddstr(hw,") ");
! 154: waddstr(hw,wmi->mi_name);
! 155: ii++;
! 156: }
! 157: old_prob = wmi->mi_prob;
! 158: wmi++;
! 159: }
! 160: }
! 161: else if (wmn != 0) {
! 162: for(ii = 0 ; ii < msz ; ii++) {
! 163: mvwaddch(hw,ii % 13,ii > 12 ? COLS/2 : 0, ii + 'a');
! 164: waddstr(hw,") ");
! 165: if(wmn == 1)
! 166: waddstr(hw,weaps[ii].w_name);
! 167: else
! 168: waddstr(hw,armors[ii].a_name);
! 169: }
! 170: }
! 171: sprintf(prbuf,"Which %s? ",things[whc].mi_name);
! 172: mvwaddstr(hw,LINES - 1, 0, prbuf);
! 173: draw(hw);
! 174: do {
! 175: ch = wgetch(hw);
! 176: if (ch == ESCAPE) {
! 177: restscr(cw);
! 178: msg("");
! 179: return;
! 180: }
! 181: } until (isalpha(ch));
! 182: if (thiswin == hw) /* restore screen if need be */
! 183: restscr(cw);
! 184: newtype = tolower(ch) - 'a';
! 185: if(newtype < 0 || newtype >= msz) { /* if an illegal value */
! 186: mpos = 0;
! 187: msg("There is no such %s",things[whc].mi_name);
! 188: return;
! 189: }
! 190: }
! 191: else
! 192: newtype = which_type;
! 193: item = new_item(sizeof *obj); /* get some memory */
! 194: obj = OBJPTR(item);
! 195: obj->o_type = newitem; /* store the new items */
! 196: obj->o_mark[0] = '\0';
! 197: obj->o_which = newtype;
! 198: obj->o_group = 0;
! 199: obj->contents = NULL;
! 200: obj->o_count = 1;
! 201: obj->o_flags = 0;
! 202: obj->o_dplus = obj->o_hplus = 0;
! 203: obj->o_weight = 0;
! 204: wh = obj->o_which;
! 205: mpos = 0;
! 206: if (!wizard) /* users get 0 to +3 */
! 207: whc = rnd(4);
! 208: else /* wizard gets to choose */
! 209: whc = getbless();
! 210: if (whc < 0)
! 211: obj->o_flags |= ISCURSED;
! 212: switch (obj->o_type) {
! 213: case WEAPON:
! 214: case ARMOR:
! 215: if (obj->o_type == WEAPON) {
! 216: init_weapon(obj, wh);
! 217: obj->o_hplus += whc;
! 218: obj->o_dplus += whc;
! 219: }
! 220: else { /* armor here */
! 221: obj->o_weight = armors[wh].a_wght;
! 222: obj->o_ac = armors[wh].a_class - whc;
! 223: }
! 224: when RING:
! 225: if (whc > 1 && r_magic[wh].mi_bless != 0)
! 226: obj->o_flags |= ISBLESSED;
! 227: r_know[wh] = TRUE;
! 228: switch(wh) {
! 229: case R_ADDSTR:
! 230: case R_ADDWISDOM:
! 231: case R_ADDINTEL:
! 232: case R_PROTECT:
! 233: case R_ADDHIT:
! 234: case R_ADDDAM:
! 235: case R_DIGEST:
! 236: obj->o_ac = whc + 1;
! 237: break;
! 238: default:
! 239: obj->o_ac = 0;
! 240: }
! 241: obj->o_weight = things[TYP_RING].mi_wght;
! 242: when MM:
! 243: if (whc > 1 && m_magic[wh].mi_bless != 0)
! 244: obj->o_flags |= ISBLESSED;
! 245: m_know[wh] = TRUE;
! 246: switch(wh) {
! 247: case MM_JUG:
! 248: switch(rnd(9)) {
! 249: case 0: obj->o_ac = P_PHASE;
! 250: when 1: obj->o_ac = P_CLEAR;
! 251: when 2: obj->o_ac = P_SEEINVIS;
! 252: when 3: obj->o_ac = P_HEALING;
! 253: when 4: obj->o_ac = P_MFIND;
! 254: when 5: obj->o_ac = P_TFIND;
! 255: when 6: obj->o_ac = P_HASTE;
! 256: when 7: obj->o_ac = P_RESTORE;
! 257: when 8: obj->o_ac = P_FLY;
! 258: }
! 259: when MM_OPEN:
! 260: case MM_HUNGER:
! 261: case MM_DRUMS:
! 262: case MM_DISAPPEAR:
! 263: case MM_CHOKE:
! 264: case MM_KEOGHTOM:
! 265: if (whc < 0)
! 266: whc = -whc; /* these cannot be negative */
! 267: obj->o_ac = (whc + 1) * 5;
! 268: break;
! 269: when MM_BRACERS:
! 270: obj->o_ac = whc * 2 + 1;
! 271: when MM_DISP:
! 272: obj->o_ac = 2;
! 273: when MM_PROTECT:
! 274: obj->o_ac = whc;
! 275: when MM_SKILLS:
! 276: if (wizard && whc != 0)
! 277: obj->o_ac = rnd(4);
! 278: else
! 279: obj->o_ac = player.t_ctype;
! 280: otherwise:
! 281: obj->o_ac = 0;
! 282: }
! 283: obj->o_weight = things[TYP_MM].mi_wght;
! 284: when STICK:
! 285: if (whc > 1 && ws_magic[wh].mi_bless != 0)
! 286: obj->o_flags |= ISBLESSED;
! 287: ws_know[wh] = TRUE;
! 288: fix_stick(obj);
! 289: when SCROLL:
! 290: if (whc > 1 && s_magic[wh].mi_bless != 0)
! 291: obj->o_flags |= ISBLESSED;
! 292: obj->o_weight = things[TYP_SCROLL].mi_wght;
! 293: s_know[wh] = TRUE;
! 294: when POTION:
! 295: if (whc > 1 && p_magic[wh].mi_bless != 0)
! 296: obj->o_flags |= ISBLESSED;
! 297: obj->o_weight = things[TYP_POTION].mi_wght;
! 298: p_know[wh] = TRUE;
! 299: when RELIC:
! 300: obj->o_weight = things[TYP_RELIC].mi_wght;
! 301: }
! 302: mpos = 0;
! 303: obj->o_flags |= ISKNOW;
! 304: if (add_pack(item, FALSE, NULL) == FALSE) {
! 305: obj->o_pos = hero;
! 306: fall(item, TRUE);
! 307: }
! 308: }
! 309:
! 310: /*
! 311: * getbless:
! 312: * Get a blessing for a wizards object
! 313: */
! 314: int
! 315: getbless(void)
! 316: {
! 317: reg char bless;
! 318:
! 319: msg("Blessing? (+,-,n)");
! 320: bless = readchar();
! 321: if (bless == '+')
! 322: return (rnd(3) + 2);
! 323: else if (bless == '-')
! 324: return (-rnd(3) - 1);
! 325: else
! 326: return (0);
! 327: }
! 328:
! 329: /*
! 330: * get a non-monster death type
! 331: */
! 332: int
! 333: getdeath(void)
! 334: {
! 335: register int i;
! 336: int which_death;
! 337: char label[80];
! 338:
! 339: clear();
! 340: for (i=0; i<DEATHNUM; i++) {
! 341: sprintf(label, "[%d] %s", i+1, deaths[i].name);
! 342: mvaddstr(i+2, 0, label);
! 343: }
! 344: mvaddstr(0, 0, "Which death? ");
! 345: refresh();
! 346:
! 347: /* Get the death */
! 348: for (;;) {
! 349: get_str(label, stdscr);
! 350: which_death = atoi(label);
! 351: if ((which_death < 1 || which_death > DEATHNUM)) {
! 352: mvaddstr(0, 0, "Please enter a number in the displayed range -- ");
! 353: refresh();
! 354: }
! 355: else break;
! 356: }
! 357: return(deaths[which_death-1].reason);
! 358: }
! 359:
! 360: /*
! 361: * make a monster for the wizard
! 362: */
! 363: short
! 364: makemonster(bool create)
! 365: {
! 366: register int i;
! 367: register short which_monst;
! 368: register int num_monst = NUMMONST, pres_monst=1, num_lines=2*(LINES-3);
! 369: char monst_name[40];
! 370:
! 371: /* Print out the monsters */
! 372: while (num_monst > 0) {
! 373: register int left_limit;
! 374:
! 375: if (num_monst < num_lines) left_limit = (num_monst+1)/2;
! 376: else left_limit = num_lines/2;
! 377:
! 378: wclear(hw);
! 379: touchwin(hw);
! 380:
! 381: /* Print left column */
! 382: wmove(hw, 2, 0);
! 383: for (i=0; i<left_limit; i++) {
! 384: sprintf(monst_name, "[%d] %s\n",
! 385: pres_monst, monsters[pres_monst].m_name);
! 386: waddstr(hw, monst_name);
! 387: pres_monst++;
! 388: }
! 389:
! 390: /* Print right column */
! 391: for (i=0; i<left_limit && pres_monst<=NUMMONST; i++) {
! 392: sprintf(monst_name, "[%d] %s",
! 393: pres_monst, monsters[pres_monst].m_name);
! 394: wmove(hw, i+2, COLS/2);
! 395: waddstr(hw, monst_name);
! 396: pres_monst++;
! 397: }
! 398:
! 399: if ((num_monst -= num_lines) > 0) {
! 400: mvwaddstr(hw, LINES-1, 0, morestr);
! 401: draw(hw);
! 402: wait_for(hw,' ');
! 403: }
! 404:
! 405: else {
! 406: mvwaddstr(hw, 0, 0, "Which monster");
! 407: if (!terse && create) waddstr(hw, " do you wish to create");
! 408: waddstr(hw, "? ");
! 409: draw(hw);
! 410: }
! 411: }
! 412:
! 413: get_monst:
! 414: get_str(monst_name, hw);
! 415: which_monst = atoi(monst_name);
! 416: if ((which_monst < 1 || which_monst > NUMMONST)) {
! 417: mvwaddstr(hw, 0, 0, "Please enter a number in the displayed range -- ");
! 418: draw(hw);
! 419: goto get_monst;
! 420: }
! 421: restscr(cw);
! 422: if (create) {
! 423: creat_mons (&player, which_monst, TRUE);
! 424: light(&hero);
! 425: }
! 426: touchwin(cw);
! 427: return(which_monst);
! 428: }
! 429:
! 430: /*
! 431: * passwd:
! 432: * see if user knows password
! 433: */
! 434:
! 435: bool
! 436: passwd(void)
! 437: {
! 438: register char *sp, c;
! 439: char buf[LINELEN];
! 440:
! 441: msg("Wizard's Password:");
! 442: mpos = 0;
! 443: sp = buf;
! 444: while ((c = readchar()) != '\n' && c != '\r' && c != '\033')
! 445: if (c == md_killchar())
! 446: sp = buf;
! 447: else if (c == md_erasechar() && sp > buf)
! 448: sp--;
! 449: else
! 450: *sp++ = c;
! 451: if (sp == buf)
! 452: return FALSE;
! 453: *sp = '\0';
! 454: return (strcmp(PASSWD, md_crypt(buf, "Si")) == 0);
! 455: }
! 456:
! 457:
! 458: /*
! 459: * teleport:
! 460: * Bamf the hero someplace else
! 461: */
! 462:
! 463: int
! 464: teleport(void)
! 465: {
! 466: register struct room *new_rp, *old_rp = roomin(&hero);
! 467: register int rm;
! 468: coord c;
! 469:
! 470: c = hero;
! 471: mvwaddch(cw, hero.y, hero.x, mvwinch(stdscr, hero.y, hero.x));
! 472: do
! 473: {
! 474: rm = rnd_room();
! 475: rnd_pos(&rooms[rm], &hero);
! 476: } until(winat(hero.y, hero.x) == FLOOR);
! 477: player.t_oldpos = c; /* Save last position */
! 478:
! 479: /* If hero gets moved, darken old room */
! 480: new_rp = &rooms[rm];
! 481: if (old_rp && old_rp != new_rp) {
! 482: old_rp->r_flags |= FORCEDARK; /* Fake darkness */
! 483: light(&c);
! 484: old_rp->r_flags &= ~FORCEDARK; /* Restore light state */
! 485: }
! 486:
! 487: /* Darken where we just came from */
! 488: else if (levtype == MAZELEV) light(&c);
! 489:
! 490: light(&hero);
! 491: mvwaddch(cw, hero.y, hero.x, PLAYER);
! 492:
! 493: /* Reset current room and position */
! 494: oldrp = new_rp; /* Used in look() */
! 495: player.t_oldpos = hero;
! 496:
! 497: /*
! 498: * turn off ISHELD in case teleportation was done while fighting
! 499: * something that holds you
! 500: */
! 501: if (on(player, ISHELD)) {
! 502: register struct linked_list *ip, *nip;
! 503: register struct thing *mp;
! 504:
! 505: turn_off(player, ISHELD);
! 506: hold_count = 0;
! 507: for (ip = mlist; ip; ip = nip) {
! 508: mp = THINGPTR(ip);
! 509: nip = next(ip);
! 510: if (on(*mp, DIDHOLD)) {
! 511: turn_off(*mp, DIDHOLD);
! 512: turn_on(*mp, CANHOLD);
! 513: }
! 514: turn_off(*mp, DIDSUFFOCATE); /* Suffocation -- see below */
! 515: }
! 516: }
! 517:
! 518: /* Make sure player does not suffocate */
! 519: extinguish(suffocate);
! 520:
! 521: count = 0;
! 522: running = FALSE;
! 523: md_flushinp();
! 524: return rm;
! 525: }
! 526:
! 527: /*
! 528: * whatis:
! 529: * What a certin object is
! 530: */
! 531:
! 532: void
! 533: whatis(struct linked_list *what)
! 534: {
! 535: register struct object *obj;
! 536: register struct linked_list *item;
! 537:
! 538: if (what == NULL) { /* do we need to ask which one? */
! 539: if ((item = get_item(pack, "identify", IDENTABLE)) == NULL)
! 540: return;
! 541: }
! 542: else
! 543: item = what;
! 544: obj = OBJPTR(item);
! 545: switch (obj->o_type) {
! 546: case SCROLL:
! 547: s_know[obj->o_which] = TRUE;
! 548: if (s_guess[obj->o_which]) {
! 549: free(s_guess[obj->o_which]);
! 550: s_guess[obj->o_which] = NULL;
! 551: }
! 552: when POTION:
! 553: p_know[obj->o_which] = TRUE;
! 554: if (p_guess[obj->o_which]) {
! 555: free(p_guess[obj->o_which]);
! 556: p_guess[obj->o_which] = NULL;
! 557: }
! 558: when STICK:
! 559: ws_know[obj->o_which] = TRUE;
! 560: if (ws_guess[obj->o_which]) {
! 561: free(ws_guess[obj->o_which]);
! 562: ws_guess[obj->o_which] = NULL;
! 563: }
! 564: when RING:
! 565: r_know[obj->o_which] = TRUE;
! 566: if (r_guess[obj->o_which]) {
! 567: free(r_guess[obj->o_which]);
! 568: r_guess[obj->o_which] = NULL;
! 569: }
! 570: when MM:
! 571: /* If it's an identified jug, identify its potion */
! 572: if (obj->o_which == MM_JUG && (obj->o_flags & ISKNOW)) {
! 573: if (obj->o_ac != JUG_EMPTY)
! 574: p_know[obj->o_ac] = TRUE;
! 575: break;
! 576: }
! 577:
! 578: m_know[obj->o_which] = TRUE;
! 579: if (m_guess[obj->o_which]) {
! 580: free(m_guess[obj->o_which]);
! 581: m_guess[obj->o_which] = NULL;
! 582: }
! 583: otherwise:
! 584: break;
! 585: }
! 586: obj->o_flags |= ISKNOW;
! 587: if (what == NULL)
! 588: msg(inv_name(obj, FALSE));
! 589: }
! 590:
CVSweb