sys/vfs/hammer2: Remove obsolete comments for unused/reserved ondisk fields
[dragonfly.git] / games / hack / hack.read.c
blob1bcdd7f76b042482b8ae20cd1c03a4863f2b15ff
1 /* $NetBSD: hack.read.c,v 1.11 2011/08/06 20:29:37 dholland Exp $ */
3 /*
4 * Copyright (c) 1985, Stichting Centrum voor Wiskunde en Informatica,
5 * Amsterdam
6 * All rights reserved.
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions are
10 * met:
12 * - Redistributions of source code must retain the above copyright notice,
13 * this list of conditions and the following disclaimer.
15 * - Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
19 * - Neither the name of the Stichting Centrum voor Wiskunde en
20 * Informatica, nor the names of its contributors may be used to endorse or
21 * promote products derived from this software without specific prior
22 * written permission.
24 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
25 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
26 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
27 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
28 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
29 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
30 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
31 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
32 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
33 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
34 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
38 * Copyright (c) 1982 Jay Fenlason <hack@gnu.org>
39 * All rights reserved.
41 * Redistribution and use in source and binary forms, with or without
42 * modification, are permitted provided that the following conditions
43 * are met:
44 * 1. Redistributions of source code must retain the above copyright
45 * notice, this list of conditions and the following disclaimer.
46 * 2. Redistributions in binary form must reproduce the above copyright
47 * notice, this list of conditions and the following disclaimer in the
48 * documentation and/or other materials provided with the distribution.
49 * 3. The name of the author may not be used to endorse or promote products
50 * derived from this software without specific prior written permission.
52 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
53 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
54 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
55 * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
56 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
57 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
58 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
59 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
60 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
61 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
64 #include <stdlib.h>
65 #include "hack.h"
66 #include "extern.h"
68 static int identify(struct obj *);
69 static int monstersym(int);
71 int
72 doread(void)
74 struct obj *scroll;
75 boolean confused = (Confusion != 0);
76 boolean known = FALSE;
78 scroll = getobj("?", "read");
79 if (!scroll)
80 return (0);
81 if (!scroll->dknown && Blind) {
82 pline("Being blind, you cannot read the formula on the scroll.");
83 return (0);
85 if (Blind)
86 pline("As you pronounce the formula on it, the scroll disappears.");
87 else
88 pline("As you read the scroll, it disappears.");
89 if (confused)
90 pline("Being confused, you mispronounce the magic words ... ");
92 switch (scroll->otyp) {
93 #ifdef MAIL
94 case SCR_MAIL:
95 readmail( /* scroll */ );
96 break;
97 #endif /* MAIL */
98 case SCR_ENCHANT_ARMOR:
100 struct obj *otmp = some_armor();
101 if (!otmp) {
102 strange_feeling(scroll, "Your skin glows then fades.");
103 return (1);
105 if (confused) {
106 pline("Your %s glows silver for a moment.",
107 objects[otmp->otyp].oc_name);
108 otmp->rustfree = 1;
109 break;
111 if (otmp->spe > 3 && rn2(otmp->spe)) {
112 pline("Your %s glows violently green for a while, then evaporates.",
113 objects[otmp->otyp].oc_name);
114 useup(otmp);
115 break;
117 pline("Your %s glows green for a moment.",
118 objects[otmp->otyp].oc_name);
119 otmp->cursed = 0;
120 otmp->spe++;
121 break;
123 case SCR_DESTROY_ARMOR:
124 if (confused) {
125 struct obj *otmp = some_armor();
126 if (!otmp) {
127 strange_feeling(scroll, "Your bones itch.");
128 return (1);
130 pline("Your %s glows purple for a moment.",
131 objects[otmp->otyp].oc_name);
132 otmp->rustfree = 0;
133 break;
135 if (uarm) {
136 pline("Your armor turns to dust and falls to the floor!");
137 useup(uarm);
138 } else if (uarmh) {
139 pline("Your helmet turns to dust and is blown away!");
140 useup(uarmh);
141 } else if (uarmg) {
142 pline("Your gloves vanish!");
143 useup(uarmg);
144 selftouch("You");
145 } else {
146 strange_feeling(scroll, "Your skin itches.");
147 return (1);
149 break;
150 case SCR_CONFUSE_MONSTER:
151 if (confused) {
152 pline("Your hands begin to glow purple.");
153 Confusion += rnd(100);
154 } else {
155 pline("Your hands begin to glow blue.");
156 u.umconf = 1;
158 break;
159 case SCR_SCARE_MONSTER:
161 int ct = 0;
162 struct monst *mtmp;
164 for (mtmp = fmon; mtmp; mtmp = mtmp->nmon)
165 if (cansee(mtmp->mx, mtmp->my)) {
166 if (confused)
167 mtmp->mflee = mtmp->mfroz =
168 mtmp->msleep = 0;
169 else
170 mtmp->mflee = 1;
171 ct++;
173 if (!ct) {
174 if (confused)
175 pline("You hear sad wailing in the distance.");
176 else
177 pline("You hear maniacal laughter in the distance.");
179 break;
181 case SCR_BLANK_PAPER:
182 if (confused)
183 pline("You see strange patterns on this scroll.");
184 else
185 pline("This scroll seems to be blank.");
186 break;
187 case SCR_REMOVE_CURSE:
189 struct obj *obj;
190 if (confused)
191 pline("You feel like you need some help.");
192 else
193 pline("You feel like someone is helping you.");
194 for (obj = invent; obj; obj = obj->nobj)
195 if (obj->owornmask)
196 obj->cursed = confused;
197 if (Punished && !confused) {
198 Punished = 0;
199 freeobj(uchain);
200 unpobj(uchain);
201 free(uchain);
202 uball->spe = 0;
203 uball->owornmask &= ~W_BALL;
204 uchain = uball = (struct obj *) 0;
206 break;
208 case SCR_CREATE_MONSTER:
210 int cnt = 1;
212 if (!rn2(73))
213 cnt += rnd(4);
214 if (confused)
215 cnt += 12;
216 while (cnt--)
217 (void) makemon(confused ? PM_ACID_BLOB :
218 (struct permonst *) 0, u.ux, u.uy);
219 break;
221 case SCR_ENCHANT_WEAPON:
222 if (uwep && confused) {
223 pline("Your %s glows silver for a moment.",
224 objects[uwep->otyp].oc_name);
225 uwep->rustfree = 1;
226 } else if (!chwepon(scroll, 1)) /* tests for !uwep */
227 return (1);
228 break;
229 case SCR_DAMAGE_WEAPON:
230 if (uwep && confused) {
231 pline("Your %s glows purple for a moment.",
232 objects[uwep->otyp].oc_name);
233 uwep->rustfree = 0;
234 } else if (!chwepon(scroll, -1)) /* tests for !uwep */
235 return (1);
236 break;
237 case SCR_TAMING:
239 int i, j;
240 int bd = confused ? 5 : 1;
241 struct monst *mtmp;
243 for (i = -bd; i <= bd; i++)
244 for (j = -bd; j <= bd; j++)
245 if ((mtmp = m_at(u.ux + i, u.uy + j)) != NULL)
246 (void) tamedog(mtmp, (struct obj *) 0);
247 break;
249 case SCR_GENOCIDE:
251 char buf[BUFSZ];
252 struct monst *mtmp, *mtmp2;
254 pline("You have found a scroll of genocide!");
255 known = TRUE;
256 if (confused)
257 *buf = u.usym;
258 else
259 do {
260 pline("What monster do you want to genocide (Type the letter)? ");
261 getlin(buf);
262 } while (strlen(buf) != 1 || !monstersym(*buf));
263 if (!strchr(fut_geno, *buf))
264 charcat(fut_geno, *buf);
265 if (!strchr(genocided, *buf))
266 charcat(genocided, *buf);
267 else {
268 pline("Such monsters do not exist in this world.");
269 break;
271 for (mtmp = fmon; mtmp; mtmp = mtmp2) {
272 mtmp2 = mtmp->nmon;
273 if (mtmp->data->mlet == *buf)
274 mondead(mtmp);
276 pline("Wiped out all %c's.", *buf);
277 if (*buf == u.usym) {
278 killer = "scroll of genocide";
279 u.uhp = -1;
281 break;
283 case SCR_LIGHT:
284 if (!Blind)
285 known = TRUE;
286 litroom(!confused);
287 break;
288 case SCR_TELEPORTATION:
289 if (confused)
290 level_tele();
291 else {
292 #ifdef QUEST
293 int oux = u.ux, ouy = u.uy;
294 tele();
295 if (dist(oux, ouy) > 100)
296 known = TRUE;
297 #else /* QUEST */
298 int uroom = inroom(u.ux, u.uy);
299 tele();
300 if (uroom != inroom(u.ux, u.uy))
301 known = TRUE;
302 #endif /* QUEST */
304 break;
305 case SCR_GOLD_DETECTION:
307 * Unfortunately this code has become slightly less elegant,
308 * now that gold and traps no longer are of the same type.
310 if (confused) {
311 struct trap *ttmp;
313 if (!ftrap) {
314 strange_feeling(scroll, "Your toes stop itching.");
315 return (1);
316 } else {
317 for (ttmp = ftrap; ttmp; ttmp = ttmp->ntrap)
318 if (ttmp->tx != u.ux || ttmp->ty != u.uy)
319 goto outtrapmap;
321 * only under me - no separate display
322 * required
324 pline("Your toes itch!");
325 break;
326 outtrapmap:
327 cls();
328 for (ttmp = ftrap; ttmp; ttmp = ttmp->ntrap)
329 at(ttmp->tx, ttmp->ty, '$');
330 prme();
331 pline("You feel very greedy!");
333 } else {
334 struct gold *gtmp;
336 if (!fgold) {
337 strange_feeling(scroll, "You feel materially poor.");
338 return (1);
339 } else {
340 known = TRUE;
341 for (gtmp = fgold; gtmp; gtmp = gtmp->ngold)
342 if (gtmp->gx != u.ux || gtmp->gy != u.uy)
343 goto outgoldmap;
345 * only under me - no separate display
346 * required
348 pline("You notice some gold between your feet.");
349 break;
350 outgoldmap:
351 cls();
352 for (gtmp = fgold; gtmp; gtmp = gtmp->ngold)
353 at(gtmp->gx, gtmp->gy, '$');
354 prme();
355 pline("You feel very greedy, and sense gold!");
358 /* common sequel */
359 more();
360 docrt();
361 break;
362 case SCR_FOOD_DETECTION:
364 int ct = 0, ctu = 0;
365 struct obj *obj;
366 char foodsym = confused ? POTION_SYM : FOOD_SYM;
368 for (obj = fobj; obj; obj = obj->nobj)
369 if (obj->olet == FOOD_SYM) {
370 if (obj->ox == u.ux && obj->oy == u.uy)
371 ctu++;
372 else
373 ct++;
375 if (!ct && !ctu) {
376 strange_feeling(scroll, "Your nose twitches.");
377 return (1);
378 } else if (!ct) {
379 known = TRUE;
380 pline("You smell %s close nearby.",
381 confused ? "something" : "food");
383 } else {
384 known = TRUE;
385 cls();
386 for (obj = fobj; obj; obj = obj->nobj)
387 if (obj->olet == foodsym)
388 at(obj->ox, obj->oy, FOOD_SYM);
389 prme();
390 pline("Your nose tingles and you smell %s!",
391 confused ? "something" : "food");
392 more();
393 docrt();
395 break;
397 case SCR_IDENTIFY:
398 /* known = TRUE; */
399 if (confused)
400 pline("You identify this as an identify scroll.");
401 else
402 pline("This is an identify scroll.");
403 useup(scroll);
404 objects[SCR_IDENTIFY].oc_name_known = 1;
405 if (!confused)
406 while (
407 !ggetobj("identify", identify, rn2(5) ? 1 : rn2(5))
408 && invent
410 return (1);
411 case SCR_MAGIC_MAPPING:
413 struct rm *lev;
414 int num, zx, zy;
416 known = TRUE;
417 pline("On this scroll %s a map!",
418 confused ? "was" : "is");
419 for (zy = 0; zy < ROWNO; zy++)
420 for (zx = 0; zx < COLNO; zx++) {
421 if (confused && rn2(7))
422 continue;
423 lev = &(levl[zx][zy]);
424 if ((num = lev->typ) == 0)
425 continue;
426 if (num == SCORR) {
427 lev->typ = CORR;
428 lev->scrsym = CORR_SYM;
429 } else if (num == SDOOR) {
430 lev->typ = DOOR;
431 lev->scrsym = '+';
432 /* do sth in doors ? */
433 } else if (lev->seen)
434 continue;
435 #ifndef QUEST
436 if (num != ROOM)
437 #endif /* QUEST */
439 lev->seen = lev->new = 1;
440 if (lev->scrsym == ' ' || !lev->scrsym)
441 newsym(zx, zy);
442 else
443 on_scr(zx, zy);
446 break;
448 case SCR_AMNESIA:
450 int zx, zy;
452 known = TRUE;
453 for (zx = 0; zx < COLNO; zx++)
454 for (zy = 0; zy < ROWNO; zy++)
455 if (!confused || rn2(7))
456 if (!cansee(zx, zy))
457 levl[zx][zy].seen = 0;
458 docrt();
459 pline("Thinking of Maud you forget everything else.");
460 break;
462 case SCR_FIRE:
464 int num = 0;
465 struct monst *mtmp;
467 known = TRUE;
468 if (confused) {
469 pline("The scroll catches fire and you burn your hands.");
470 losehp(1, "scroll of fire");
471 } else {
472 pline("The scroll erupts in a tower of flame!");
473 if (Fire_resistance)
474 pline("You are uninjured.");
475 else {
476 num = rnd(6);
477 u.uhpmax -= num;
478 losehp(num, "scroll of fire");
481 num = (2 * num + 1) / 3;
482 for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
483 if (dist(mtmp->mx, mtmp->my) < 3) {
484 mtmp->mhp -= num;
485 if (strchr("FY", mtmp->data->mlet))
486 mtmp->mhp -= 3 * num; /* this might well kill
487 * 'F's */
488 if (mtmp->mhp < 1) {
489 killed(mtmp);
490 break; /* primitive */
494 break;
496 case SCR_PUNISHMENT:
497 known = TRUE;
498 if (confused) {
499 pline("You feel guilty.");
500 break;
502 pline("You are being punished for your misbehaviour!");
503 if (Punished) {
504 pline("Your iron ball gets heavier.");
505 uball->owt += 15;
506 break;
508 Punished = INTRINSIC;
509 setworn(mkobj_at(CHAIN_SYM, u.ux, u.uy), W_CHAIN);
510 setworn(mkobj_at(BALL_SYM, u.ux, u.uy), W_BALL);
511 uball->spe = 1; /* special ball (see save) */
512 break;
513 default:
514 impossible("What weird language is this written in? (%u)",
515 scroll->otyp);
517 if (!objects[scroll->otyp].oc_name_known) {
518 if (known && !confused) {
519 objects[scroll->otyp].oc_name_known = 1;
520 more_experienced(0, 10);
521 } else if (!objects[scroll->otyp].oc_uname)
522 docall(scroll);
524 useup(scroll);
525 return (1);
528 static int
529 identify(struct obj *otmp) /* also called by newmail() */
531 objects[otmp->otyp].oc_name_known = 1;
532 otmp->known = otmp->dknown = 1;
533 prinv(otmp);
534 return (1);
537 void
538 litroom(boolean on)
540 #ifndef QUEST
541 int num, zx, zy;
542 #endif
544 /* first produce the text (provided he is not blind) */
545 if (Blind)
546 goto do_it;
547 if (!on) {
548 if (u.uswallow || !xdnstair || levl[u.ux][u.uy].typ == CORR ||
549 !levl[u.ux][u.uy].lit) {
550 pline("It seems even darker in here than before.");
551 return;
552 } else
553 pline("It suddenly becomes dark in here.");
554 } else {
555 if (u.uswallow) {
556 pline("%s's stomach is lit.", Monnam(u.ustuck));
557 return;
559 if (!xdnstair) {
560 pline("Nothing Happens.");
561 return;
563 #ifdef QUEST
564 pline("The cave lights up around you, then fades.");
565 return;
566 #else /* QUEST */
567 if (levl[u.ux][u.uy].typ == CORR) {
568 pline("The corridor lights up around you, then fades.");
569 return;
570 } else if (levl[u.ux][u.uy].lit) {
571 pline("The light here seems better now.");
572 return;
573 } else
574 pline("The room is lit.");
575 #endif /* QUEST */
578 do_it:
579 #ifdef QUEST
580 return;
581 #else /* QUEST */
582 if (levl[u.ux][u.uy].lit == on)
583 return;
584 if (levl[u.ux][u.uy].typ == DOOR) {
585 if (IS_ROOM(levl[u.ux][u.uy + 1].typ))
586 zy = u.uy + 1;
587 else if (IS_ROOM(levl[u.ux][u.uy - 1].typ))
588 zy = u.uy - 1;
589 else
590 zy = u.uy;
591 if (IS_ROOM(levl[u.ux + 1][u.uy].typ))
592 zx = u.ux + 1;
593 else if (IS_ROOM(levl[u.ux - 1][u.uy].typ))
594 zx = u.ux - 1;
595 else
596 zx = u.ux;
597 } else {
598 zx = u.ux;
599 zy = u.uy;
601 for (seelx = u.ux; (num = levl[seelx - 1][zy].typ) != CORR && num != 0;
602 seelx--);
603 for (seehx = u.ux; (num = levl[seehx + 1][zy].typ) != CORR && num != 0;
604 seehx++);
605 for (seely = u.uy; (num = levl[zx][seely - 1].typ) != CORR && num != 0;
606 seely--);
607 for (seehy = u.uy; (num = levl[zx][seehy + 1].typ) != CORR && num != 0;
608 seehy++);
609 for (zy = seely; zy <= seehy; zy++)
610 for (zx = seelx; zx <= seehx; zx++) {
611 levl[zx][zy].lit = on;
612 if (!Blind && dist(zx, zy) > 2) {
613 if (on)
614 prl(zx, zy);
615 else
616 nosee(zx, zy);
619 if (!on)
620 seehx = 0;
621 #endif /* QUEST */
624 /* Test whether we may genocide all monsters with symbol ch */
625 static int
626 monstersym(int ch) /* arnold@ucsfcgl */
628 const struct permonst *mp;
631 * can't genocide certain monsters
633 if (strchr("12 &:", ch))
634 return FALSE;
636 if (ch == pm_eel.mlet)
637 return TRUE;
638 for (mp = mons; mp < &mons[CMNUM + 2]; mp++)
639 if (mp->mlet == ch)
640 return TRUE;
641 return FALSE;