Mercurial > hg > early-roguelike
comparison arogue7/wizard.c @ 125:adfa37e67084
Import Advanced Rogue 7.7 from the Roguelike Restoration Project (r1490)
author | John "Elwin" Edwards |
---|---|
date | Fri, 08 May 2015 15:24:40 -0400 |
parents | |
children | b786053d2f37 |
comparison
equal
deleted
inserted
replaced
124:d10fc4a065ac | 125:adfa37e67084 |
---|---|
1 /* | |
2 * wizard.c - Special wizard commands | |
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 * Special wizard commands (some of which are also non-wizard commands | |
17 * under strange circumstances) | |
18 */ | |
19 | |
20 #include "curses.h" | |
21 #include <ctype.h> | |
22 #include "rogue.h" | |
23 #ifdef PC7300 | |
24 #include "menu.h" | |
25 #endif | |
26 | |
27 | |
28 /* | |
29 * create_obj: | |
30 * Create any object for wizard, scroll, magician, or cleric | |
31 */ | |
32 create_obj(prompt, which_item, which_type) | |
33 bool prompt; | |
34 int which_item, which_type; | |
35 { | |
36 reg struct linked_list *item; | |
37 reg struct object *obj; | |
38 reg int wh; | |
39 reg char ch, newitem, newtype, whc, msz, *pt; | |
40 WINDOW *thiswin; | |
41 | |
42 thiswin = cw; | |
43 if (prompt) { | |
44 bool nogood = TRUE; | |
45 | |
46 thiswin = hw; | |
47 wclear(hw); | |
48 wprintw(hw,"Item\t\t\tKey\n\n"); | |
49 wprintw(hw,"%s\t\t\t%c\n%s\t\t\t%c\n",things[TYP_RING].mi_name,RING, | |
50 things[TYP_STICK].mi_name,STICK); | |
51 wprintw(hw,"%s\t\t\t%c\n%s\t\t\t%c\n",things[TYP_POTION].mi_name,POTION, | |
52 things[TYP_SCROLL].mi_name,SCROLL); | |
53 wprintw(hw,"%s\t\t\t%c\n%s\t\t\t%c\n",things[TYP_ARMOR].mi_name,ARMOR, | |
54 things[TYP_WEAPON].mi_name,WEAPON); | |
55 wprintw(hw,"%s\t%c\n",things[TYP_MM].mi_name,MM); | |
56 wprintw(hw,"%s\t\t\t%c\n",things[TYP_FOOD].mi_name,FOOD); | |
57 if (wizard) { | |
58 wprintw(hw,"%s\t\t%c\n",things[TYP_RELIC].mi_name,RELIC); | |
59 waddstr(hw,"monster\t\t\tm"); | |
60 } | |
61 wprintw(hw,"\n\nWhat do you want to create? "); | |
62 draw(hw); | |
63 do { | |
64 ch = wgetch(hw); | |
65 if (ch == ESCAPE) { | |
66 restscr(cw); | |
67 return; | |
68 } | |
69 switch (ch) { | |
70 case RING: | |
71 case STICK: | |
72 case POTION: | |
73 case SCROLL: | |
74 case ARMOR: | |
75 case WEAPON: | |
76 case FOOD: | |
77 case MM: | |
78 nogood = FALSE; | |
79 break; | |
80 case RELIC: | |
81 case 'm': | |
82 if (wizard) | |
83 nogood = FALSE; | |
84 break; | |
85 default: | |
86 nogood = TRUE; | |
87 } | |
88 } while (nogood); | |
89 newitem = ch; | |
90 } | |
91 else | |
92 newitem = which_item; | |
93 | |
94 pt = "those"; | |
95 msz = 0; | |
96 if(newitem == 'm') { | |
97 /* make monster and be done with it */ | |
98 wh = makemonster(TRUE, "Creation", "create"); | |
99 if (wh > 0) { | |
100 creat_mons (&player, wh, TRUE); | |
101 light(&hero); | |
102 } | |
103 return; | |
104 } | |
105 if(newitem == GOLD) | |
106 pt = "gold"; | |
107 /* else if(isatrap(newitem)) | |
108 pt = "traps"; | |
109 */ | |
110 switch(newitem) { | |
111 case POTION: whc = TYP_POTION; msz = MAXPOTIONS; | |
112 when SCROLL: whc = TYP_SCROLL; msz = MAXSCROLLS; | |
113 when WEAPON: whc = TYP_WEAPON; msz = MAXWEAPONS; | |
114 when ARMOR: whc = TYP_ARMOR; msz = MAXARMORS; | |
115 when RING: whc = TYP_RING; msz = MAXRINGS; | |
116 when STICK: whc = TYP_STICK; msz = MAXSTICKS; | |
117 when MM: whc = TYP_MM; msz = MAXMM; | |
118 when RELIC: whc = TYP_RELIC; msz = MAXRELIC; | |
119 when FOOD: whc = TYP_FOOD; msz = MAXFOODS; | |
120 otherwise: | |
121 if (thiswin == hw) | |
122 restscr(cw); | |
123 mpos = 0; | |
124 msg("Even wizards can't create %s !!",pt); | |
125 return; | |
126 } | |
127 if(msz == 1) { /* if only one type of item */ | |
128 ch = 'a'; | |
129 } | |
130 else if (prompt) { | |
131 register struct magic_item *wmi; | |
132 char wmn; | |
133 register int ii; | |
134 int old_prob; | |
135 | |
136 mpos = 0; | |
137 wmi = NULL; | |
138 wmn = 0; | |
139 switch(newitem) { | |
140 case POTION: wmi = &p_magic[0]; | |
141 when SCROLL: wmi = &s_magic[0]; | |
142 when RING: wmi = &r_magic[0]; | |
143 when STICK: wmi = &ws_magic[0]; | |
144 when MM: wmi = &m_magic[0]; | |
145 when RELIC: wmi = &rel_magic[0]; | |
146 when FOOD: wmi = &foods[0]; | |
147 when WEAPON: wmn = 1; | |
148 when ARMOR: wmn = 2; | |
149 } | |
150 wclear(hw); | |
151 thiswin = hw; | |
152 if (wmi != NULL) { | |
153 ii = old_prob = 0; | |
154 while (ii < msz) { | |
155 if(wmi->mi_prob == old_prob && wizard == FALSE) { | |
156 msz--; /* can't make a unique item */ | |
157 } | |
158 else { | |
159 mvwaddch(hw,ii % 13,ii > 12 ? cols/2 : 0, ii + 'a'); | |
160 waddstr(hw,") "); | |
161 waddstr(hw,wmi->mi_name); | |
162 ii++; | |
163 } | |
164 old_prob = wmi->mi_prob; | |
165 wmi++; | |
166 } | |
167 } | |
168 else if (wmn != 0) { | |
169 for(ii = 0 ; ii < msz ; ii++) { | |
170 mvwaddch(hw,ii % 13,ii > 12 ? cols/2 : 0, ii + 'a'); | |
171 waddstr(hw,") "); | |
172 if(wmn == 1) | |
173 waddstr(hw,weaps[ii].w_name); | |
174 else | |
175 waddstr(hw,armors[ii].a_name); | |
176 } | |
177 } | |
178 sprintf(prbuf,"Which %s? ",things[whc].mi_name); | |
179 mvwaddstr(hw,lines - 1, 0, prbuf); | |
180 draw(hw); | |
181 do { | |
182 ch = wgetch(hw); | |
183 if (ch == ESCAPE) { | |
184 restscr(cw); | |
185 msg(""); | |
186 return; | |
187 } | |
188 } until (isalpha(ch)); | |
189 if (thiswin == hw) /* restore screen if need be */ | |
190 restscr(cw); | |
191 newtype = tolower(ch) - 'a'; | |
192 if(newtype < 0 || newtype >= msz) { /* if an illegal value */ | |
193 mpos = 0; | |
194 msg("There is no such %s",things[whc].mi_name); | |
195 return; | |
196 } | |
197 } | |
198 else | |
199 newtype = which_type; | |
200 item = new_item(sizeof *obj); /* get some memory */ | |
201 obj = OBJPTR(item); | |
202 obj->o_type = newitem; /* store the new items */ | |
203 obj->o_mark[0] = '\0'; | |
204 obj->o_which = newtype; | |
205 obj->o_group = 0; | |
206 obj->contents = NULL; | |
207 obj->o_count = 1; | |
208 obj->o_flags = 0; | |
209 obj->o_dplus = obj->o_hplus = 0; | |
210 obj->o_weight = 0; | |
211 wh = obj->o_which; | |
212 mpos = 0; | |
213 if (!wizard) /* users get 0 to +3 */ | |
214 whc = rnd(4); | |
215 else /* wizard gets to choose */ | |
216 whc = getbless(); | |
217 if (whc < 0) | |
218 obj->o_flags |= ISCURSED; | |
219 switch (obj->o_type) { | |
220 case WEAPON: | |
221 case ARMOR: | |
222 if (obj->o_type == WEAPON) { | |
223 init_weapon(obj, wh); | |
224 obj->o_hplus += whc; | |
225 obj->o_dplus += whc; | |
226 } | |
227 else { /* armor here */ | |
228 obj->o_weight = armors[wh].a_wght; | |
229 obj->o_ac = armors[wh].a_class - whc; | |
230 } | |
231 when RING: | |
232 if (whc > 1 && r_magic[wh].mi_bless != 0) | |
233 obj->o_flags |= ISBLESSED; | |
234 r_know[wh] = TRUE; | |
235 switch(wh) { | |
236 case R_ADDSTR: | |
237 case R_ADDWISDOM: | |
238 case R_ADDINTEL: | |
239 case R_PROTECT: | |
240 case R_ADDHIT: | |
241 case R_ADDDAM: | |
242 case R_DIGEST: | |
243 obj->o_ac = whc + 1; | |
244 break; | |
245 default: | |
246 obj->o_ac = 0; | |
247 } | |
248 obj->o_weight = things[TYP_RING].mi_wght; | |
249 when MM: | |
250 if (whc > 1 && m_magic[wh].mi_bless != 0) | |
251 obj->o_flags |= ISBLESSED; | |
252 m_know[wh] = TRUE; | |
253 switch(wh) { | |
254 case MM_JUG: | |
255 switch(rnd(11)) { | |
256 case 0: obj->o_ac = P_PHASE; | |
257 when 1: obj->o_ac = P_CLEAR; | |
258 when 2: obj->o_ac = P_SEEINVIS; | |
259 when 3: obj->o_ac = P_HEALING; | |
260 when 4: obj->o_ac = P_MFIND; | |
261 when 5: obj->o_ac = P_TFIND; | |
262 when 6: obj->o_ac = P_HASTE; | |
263 when 7: obj->o_ac = P_RESTORE; | |
264 when 8: obj->o_ac = P_FLY; | |
265 when 9: obj->o_ac = P_SKILL; | |
266 when 10:obj->o_ac = P_FFIND; | |
267 } | |
268 when MM_OPEN: | |
269 case MM_HUNGER: | |
270 case MM_DRUMS: | |
271 case MM_DISAPPEAR: | |
272 case MM_CHOKE: | |
273 case MM_KEOGHTOM: | |
274 if (whc < 0) | |
275 whc = -whc; /* these cannot be negative */ | |
276 obj->o_ac = (whc + 1) * 5; | |
277 break; | |
278 when MM_BRACERS: | |
279 obj->o_ac = whc * 2 + 1; | |
280 when MM_DISP: | |
281 obj->o_ac = 2; | |
282 when MM_PROTECT: | |
283 obj->o_ac = whc; | |
284 when MM_SKILLS: | |
285 if (wizard && whc != 0) | |
286 obj->o_ac = rnd(NUM_CHARTYPES-1); | |
287 else | |
288 obj->o_ac = player.t_ctype; | |
289 otherwise: | |
290 obj->o_ac = 0; | |
291 } | |
292 obj->o_weight = things[TYP_MM].mi_wght; | |
293 when STICK: | |
294 if (whc > 1 && ws_magic[wh].mi_bless != 0) | |
295 obj->o_flags |= ISBLESSED; | |
296 ws_know[wh] = TRUE; | |
297 fix_stick(obj); | |
298 when SCROLL: | |
299 if (whc > 1 && s_magic[wh].mi_bless != 0) | |
300 obj->o_flags |= ISBLESSED; | |
301 obj->o_weight = things[TYP_SCROLL].mi_wght; | |
302 s_know[wh] = TRUE; | |
303 when POTION: | |
304 if (whc > 1 && p_magic[wh].mi_bless != 0) | |
305 obj->o_flags |= ISBLESSED; | |
306 obj->o_weight = things[TYP_POTION].mi_wght; | |
307 if (wh == P_ABIL) obj->o_kind = rnd(NUMABILITIES); | |
308 p_know[wh] = TRUE; | |
309 when RELIC: | |
310 obj->o_weight = things[TYP_RELIC].mi_wght; | |
311 switch (obj->o_which) { | |
312 case QUILL_NAGROM: obj->o_charges = QUILLCHARGES; | |
313 when EMORI_CLOAK: obj->o_charges = 1; | |
314 otherwise: break; | |
315 } | |
316 when FOOD: | |
317 obj->o_weight = things[TYP_FOOD].mi_wght; | |
318 } | |
319 mpos = 0; | |
320 obj->o_flags |= ISKNOW; | |
321 if (add_pack(item, FALSE, NULL) == FALSE) { | |
322 obj->o_pos = hero; | |
323 fall(item, TRUE); | |
324 } | |
325 } | |
326 | |
327 /* | |
328 * getbless: | |
329 * Get a blessing for a wizards object | |
330 */ | |
331 getbless() | |
332 { | |
333 reg char bless; | |
334 | |
335 msg("Blessing? (+,-,n)"); | |
336 bless = wgetch(msgw); | |
337 if (bless == '+') | |
338 return (rnd(3) + 2); | |
339 else if (bless == '-') | |
340 return (-rnd(3) - 1); | |
341 else | |
342 return (0); | |
343 } | |
344 | |
345 /* | |
346 * get a non-monster death type | |
347 */ | |
348 getdeath() | |
349 { | |
350 register int i; | |
351 int which_death; | |
352 char label[80]; | |
353 | |
354 clear(); | |
355 for (i=0; i<DEATHNUM; i++) { | |
356 sprintf(label, "[%d] %s", i+1, deaths[i].name); | |
357 mvaddstr(i+2, 0, label); | |
358 } | |
359 mvaddstr(0, 0, "Which death? "); | |
360 refresh(); | |
361 | |
362 /* Get the death */ | |
363 for (;;) { | |
364 get_str(label, stdscr); | |
365 which_death = atoi(label); | |
366 if ((which_death < 1 || which_death > DEATHNUM)) { | |
367 mvaddstr(0, 0, "Please enter a number in the displayed range -- "); | |
368 refresh(); | |
369 } | |
370 else break; | |
371 } | |
372 return(deaths[which_death-1].reason); | |
373 } | |
374 | |
375 #ifdef PC7300 | |
376 static menu_t Display; /* The menu structure */ | |
377 static mitem_t Dispitems[NUMMONST+1]; /* Info for each line */ | |
378 static char Displines[NUMMONST+1][LINELEN+1]; /* The lines themselves */ | |
379 #endif | |
380 | |
381 /* | |
382 * make a monster for the wizard | |
383 */ | |
384 makemonster(showall, label, action) | |
385 bool showall; /* showall -> show uniques and genocided creatures */ | |
386 char *label, *action; | |
387 { | |
388 #ifdef PC7300 | |
389 register int nextmonst; | |
390 #endif | |
391 register int i; | |
392 register short which_monst; | |
393 register int num_monst = NUMMONST, pres_monst=1, num_lines=2*(lines-3); | |
394 int max_monster; | |
395 char monst_name[40]; | |
396 | |
397 /* If we're not showing all, subtract out the UNIQUES and quartermaster */ | |
398 if (!showall) num_monst -= NUMUNIQUE + 1; | |
399 max_monster = num_monst; | |
400 | |
401 #ifdef PC7300 | |
402 nextmonst = 0; | |
403 for (i=1; i<=num_monst; i++) { | |
404 /* Only display existing monsters if we're not showing them all */ | |
405 if (showall || monsters[i].m_normal) { | |
406 strcpy(Displines[nextmonst], monsters[i]); | |
407 Dispitems[nextmonst].mi_name = Displines[nextmonst]; | |
408 Dispitems[nextmonst].mi_flags = 0; | |
409 Dispitems[nextmonst++].mi_val = i; | |
410 } | |
411 } | |
412 | |
413 /* Place an end marker for the items */ | |
414 Dispitems[nextmonst].mi_name = 0; | |
415 | |
416 /* Set up the main menu structure */ | |
417 Display.m_label = label; | |
418 Display.m_title = "Monster Listing"; | |
419 Display.m_prompt = "Select a monster or press Cancl."; | |
420 Display.m_curptr = '\0'; | |
421 Display.m_markptr = '\0'; | |
422 Display.m_flags = 0; | |
423 Display.m_selcnt = 1; | |
424 Display.m_items = Dispitems; | |
425 Display.m_curi = 0; | |
426 | |
427 /* | |
428 * Try to display the menu. If we don't have a local terminal, | |
429 * the call will fail and we will just continue with the | |
430 * normal mode. | |
431 */ | |
432 if (menu(&Display) >= 0) { | |
433 restscr(cw); | |
434 touchwin(cw); | |
435 return(Display.m_selcnt == 1 ? Display.m_curi->mi_val : -1); | |
436 } | |
437 #endif | |
438 | |
439 /* Print out the monsters */ | |
440 while (num_monst > 0) { | |
441 register left_limit; | |
442 | |
443 if (num_monst < num_lines) left_limit = (num_monst+1)/2; | |
444 else left_limit = num_lines/2; | |
445 | |
446 wclear(hw); | |
447 touchwin(hw); | |
448 | |
449 /* Print left column */ | |
450 wmove(hw, 2, 0); | |
451 for (i=0; i<left_limit; i++) { | |
452 sprintf(monst_name, "[%d] %c%s\n", | |
453 pres_monst, | |
454 (showall || monsters[pres_monst].m_normal) | |
455 ? ' ' | |
456 : '*', | |
457 monsters[pres_monst].m_name); | |
458 waddstr(hw, monst_name); | |
459 pres_monst++; | |
460 } | |
461 | |
462 /* Print right column */ | |
463 for (i=0; i<left_limit && pres_monst<=max_monster; i++) { | |
464 sprintf(monst_name, "[%d] %c%s", | |
465 pres_monst, | |
466 (showall || monsters[pres_monst].m_normal) | |
467 ? ' ' | |
468 : '*', | |
469 monsters[pres_monst].m_name); | |
470 wmove(hw, i+2, cols/2); | |
471 waddstr(hw, monst_name); | |
472 pres_monst++; | |
473 } | |
474 | |
475 if ((num_monst -= num_lines) > 0) { | |
476 mvwaddstr(hw, lines-1, 0, morestr); | |
477 draw(hw); | |
478 wait_for(' '); | |
479 } | |
480 | |
481 else { | |
482 mvwaddstr(hw, 0, 0, "Which monster"); | |
483 if (!terse) { | |
484 waddstr(hw, " do you wish to "); | |
485 waddstr(hw, action); | |
486 } | |
487 waddstr(hw, "? "); | |
488 draw(hw); | |
489 } | |
490 } | |
491 | |
492 get_monst: | |
493 get_str(monst_name, hw); | |
494 which_monst = atoi(monst_name); | |
495 if ((which_monst < 1 || which_monst > max_monster)) { | |
496 mvwaddstr(hw, 0, 0, "Please enter a number in the displayed range -- "); | |
497 draw(hw); | |
498 goto get_monst; | |
499 } | |
500 restscr(cw); | |
501 touchwin(cw); | |
502 return(which_monst); | |
503 } | |
504 | |
505 /* | |
506 * passwd: | |
507 * see if user knows password | |
508 */ | |
509 | |
510 passwd() | |
511 { | |
512 register char *sp, c; | |
513 char buf[LINELEN], *crypt(); | |
514 | |
515 msg("Wizard's Password:"); | |
516 mpos = 0; | |
517 sp = buf; | |
518 while ((c = readchar()) != '\n' && c != '\r' && c != '\033') | |
519 if (c == md_killchar()) | |
520 sp = buf; | |
521 else if (c == md_erasechar() && sp > buf) | |
522 sp--; | |
523 else | |
524 *sp++ = c; | |
525 if (sp == buf) | |
526 return FALSE; | |
527 *sp = '\0'; | |
528 return (strcmp(PASSWD, md_crypt(buf, "mT")) == 0); | |
529 } | |
530 | |
531 | |
532 /* | |
533 * teleport: | |
534 * Bamf the hero someplace else | |
535 */ | |
536 | |
537 teleport() | |
538 { | |
539 register struct room *new_rp, *old_rp = roomin(&hero); | |
540 register int rm, which; | |
541 coord old; | |
542 bool got_position = FALSE; | |
543 | |
544 /* Disrupt whatever the hero was doing */ | |
545 dsrpt_player(); | |
546 | |
547 /* | |
548 * If the hero wasn't doing something disruptable, NULL out his | |
549 * action anyway and let him know about it. We don't want him | |
550 * swinging or moving into his old place. | |
551 */ | |
552 if (player.t_action != A_NIL) { | |
553 player.t_action = A_NIL; | |
554 msg("You feel momentarily disoriented."); | |
555 } | |
556 | |
557 old = hero; | |
558 mvwaddch(cw, hero.y, hero.x, mvwinch(stdscr, hero.y, hero.x)); | |
559 if (ISWEARING(R_TELCONTROL) || wizard) { | |
560 got_position = move_hero(H_TELEPORT); | |
561 if (!got_position) | |
562 msg("Your attempt fails."); | |
563 else { | |
564 new_rp = roomin(&hero); | |
565 msg("You teleport successfully."); | |
566 } | |
567 } | |
568 if (!got_position) { | |
569 do { | |
570 rm = rnd_room(); | |
571 rnd_pos(&rooms[rm], &hero); | |
572 } until(winat(hero.y, hero.x) == FLOOR); | |
573 new_rp = &rooms[rm]; | |
574 } | |
575 player.t_oldpos = old; /* Save last position */ | |
576 | |
577 /* If hero gets moved, darken old room */ | |
578 if (old_rp && old_rp != new_rp) { | |
579 old_rp->r_flags |= FORCEDARK; /* Fake darkness */ | |
580 light(&old); | |
581 old_rp->r_flags &= ~FORCEDARK; /* Restore light state */ | |
582 } | |
583 | |
584 /* Darken where we just came from */ | |
585 else if (levtype == MAZELEV) light(&old); | |
586 | |
587 light(&hero); | |
588 mvwaddch(cw, hero.y, hero.x, PLAYER); | |
589 /* if entering a treasure room, wake everyone up......Surprise! */ | |
590 if (new_rp->r_flags & ISTREAS) | |
591 wake_room(new_rp); | |
592 | |
593 /* Reset current room and position */ | |
594 oldrp = new_rp; /* Used in look() */ | |
595 player.t_oldpos = hero; | |
596 /* | |
597 * make sure we set/unset the ISINWALL on a teleport | |
598 */ | |
599 which = winat(hero.y, hero.x); | |
600 if (isrock(which)) turn_on(player, ISINWALL); | |
601 else turn_off(player, ISINWALL); | |
602 | |
603 /* | |
604 * turn off ISHELD in case teleportation was done while fighting | |
605 * something that holds you | |
606 */ | |
607 if (on(player, ISHELD)) { | |
608 register struct linked_list *ip, *nip; | |
609 register struct thing *mp; | |
610 | |
611 turn_off(player, ISHELD); | |
612 hold_count = 0; | |
613 for (ip = mlist; ip; ip = nip) { | |
614 mp = THINGPTR(ip); | |
615 nip = next(ip); | |
616 if (on(*mp, DIDHOLD)) { | |
617 turn_off(*mp, DIDHOLD); | |
618 turn_on(*mp, CANHOLD); | |
619 } | |
620 turn_off(*mp, DIDSUFFOCATE); /* Suffocation -- see below */ | |
621 } | |
622 } | |
623 | |
624 /* Make sure player does not suffocate */ | |
625 extinguish(suffocate); | |
626 | |
627 count = 0; | |
628 running = FALSE; | |
629 md_flushinp(); | |
630 return rm; | |
631 } | |
632 | |
633 /* | |
634 * whatis: | |
635 * What a certin object is | |
636 */ | |
637 | |
638 whatis(what) | |
639 struct linked_list *what; | |
640 { | |
641 register struct object *obj; | |
642 register struct linked_list *item; | |
643 | |
644 if (what == NULL) { /* do we need to ask which one? */ | |
645 if ((item = get_item(pack, "identify", IDENTABLE, FALSE, FALSE))==NULL) | |
646 return; | |
647 } | |
648 else | |
649 item = what; | |
650 obj = OBJPTR(item); | |
651 switch (obj->o_type) { | |
652 case SCROLL: | |
653 s_know[obj->o_which] = TRUE; | |
654 if (s_guess[obj->o_which]) { | |
655 free(s_guess[obj->o_which]); | |
656 s_guess[obj->o_which] = NULL; | |
657 } | |
658 when POTION: | |
659 p_know[obj->o_which] = TRUE; | |
660 if (p_guess[obj->o_which]) { | |
661 free(p_guess[obj->o_which]); | |
662 p_guess[obj->o_which] = NULL; | |
663 } | |
664 when STICK: | |
665 ws_know[obj->o_which] = TRUE; | |
666 if (ws_guess[obj->o_which]) { | |
667 free(ws_guess[obj->o_which]); | |
668 ws_guess[obj->o_which] = NULL; | |
669 } | |
670 when RING: | |
671 r_know[obj->o_which] = TRUE; | |
672 if (r_guess[obj->o_which]) { | |
673 free(r_guess[obj->o_which]); | |
674 r_guess[obj->o_which] = NULL; | |
675 } | |
676 when MM: | |
677 /* If it's an identified jug, identify its potion */ | |
678 if (obj->o_which == MM_JUG && (obj->o_flags & ISKNOW)) { | |
679 if (obj->o_ac != JUG_EMPTY) | |
680 p_know[obj->o_ac] = TRUE; | |
681 break; | |
682 } | |
683 | |
684 m_know[obj->o_which] = TRUE; | |
685 if (m_guess[obj->o_which]) { | |
686 free(m_guess[obj->o_which]); | |
687 m_guess[obj->o_which] = NULL; | |
688 } | |
689 otherwise: | |
690 break; | |
691 } | |
692 obj->o_flags |= ISKNOW; | |
693 if (what == NULL) | |
694 msg(inv_name(obj, FALSE)); | |
695 } | |
696 |