Annotation of early-roguelike/arogue5/wizard.c, Revision 1.1.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