]> git.cameronkatri.com Git - bsdgames-darwin.git/blob - hack/hack.read.c
.Nm does not need a dummy argument ("") before punctuation or
[bsdgames-darwin.git] / hack / hack.read.c
1 /* $NetBSD: hack.read.c,v 1.7 2001/03/25 20:44:02 jsm Exp $ */
2
3 /*
4 * Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985.
5 */
6
7 #include <sys/cdefs.h>
8 #ifndef lint
9 __RCSID("$NetBSD: hack.read.c,v 1.7 2001/03/25 20:44:02 jsm Exp $");
10 #endif /* not lint */
11
12 #include <stdlib.h>
13 #include "hack.h"
14 #include "extern.h"
15
16 int
17 doread()
18 {
19 struct obj *scroll;
20 boolean confused = (Confusion != 0);
21 boolean known = FALSE;
22
23 scroll = getobj("?", "read");
24 if (!scroll)
25 return (0);
26 if (!scroll->dknown && Blind) {
27 pline("Being blind, you cannot read the formula on the scroll.");
28 return (0);
29 }
30 if (Blind)
31 pline("As you pronounce the formula on it, the scroll disappears.");
32 else
33 pline("As you read the scroll, it disappears.");
34 if (confused)
35 pline("Being confused, you mispronounce the magic words ... ");
36
37 switch (scroll->otyp) {
38 #ifdef MAIL
39 case SCR_MAIL:
40 readmail( /* scroll */ );
41 break;
42 #endif /* MAIL */
43 case SCR_ENCHANT_ARMOR:
44 {
45 struct obj *otmp = some_armor();
46 if (!otmp) {
47 strange_feeling(scroll, "Your skin glows then fades.");
48 return (1);
49 }
50 if (confused) {
51 pline("Your %s glows silver for a moment.",
52 objects[otmp->otyp].oc_name);
53 otmp->rustfree = 1;
54 break;
55 }
56 if (otmp->spe > 3 && rn2(otmp->spe)) {
57 pline("Your %s glows violently green for a while, then evaporates.",
58 objects[otmp->otyp].oc_name);
59 useup(otmp);
60 break;
61 }
62 pline("Your %s glows green for a moment.",
63 objects[otmp->otyp].oc_name);
64 otmp->cursed = 0;
65 otmp->spe++;
66 break;
67 }
68 case SCR_DESTROY_ARMOR:
69 if (confused) {
70 struct obj *otmp = some_armor();
71 if (!otmp) {
72 strange_feeling(scroll, "Your bones itch.");
73 return (1);
74 }
75 pline("Your %s glows purple for a moment.",
76 objects[otmp->otyp].oc_name);
77 otmp->rustfree = 0;
78 break;
79 }
80 if (uarm) {
81 pline("Your armor turns to dust and falls to the floor!");
82 useup(uarm);
83 } else if (uarmh) {
84 pline("Your helmet turns to dust and is blown away!");
85 useup(uarmh);
86 } else if (uarmg) {
87 pline("Your gloves vanish!");
88 useup(uarmg);
89 selftouch("You");
90 } else {
91 strange_feeling(scroll, "Your skin itches.");
92 return (1);
93 }
94 break;
95 case SCR_CONFUSE_MONSTER:
96 if (confused) {
97 pline("Your hands begin to glow purple.");
98 Confusion += rnd(100);
99 } else {
100 pline("Your hands begin to glow blue.");
101 u.umconf = 1;
102 }
103 break;
104 case SCR_SCARE_MONSTER:
105 {
106 int ct = 0;
107 struct monst *mtmp;
108
109 for (mtmp = fmon; mtmp; mtmp = mtmp->nmon)
110 if (cansee(mtmp->mx, mtmp->my)) {
111 if (confused)
112 mtmp->mflee = mtmp->mfroz =
113 mtmp->msleep = 0;
114 else
115 mtmp->mflee = 1;
116 ct++;
117 }
118 if (!ct) {
119 if (confused)
120 pline("You hear sad wailing in the distance.");
121 else
122 pline("You hear maniacal laughter in the distance.");
123 }
124 break;
125 }
126 case SCR_BLANK_PAPER:
127 if (confused)
128 pline("You see strange patterns on this scroll.");
129 else
130 pline("This scroll seems to be blank.");
131 break;
132 case SCR_REMOVE_CURSE:
133 {
134 struct obj *obj;
135 if (confused)
136 pline("You feel like you need some help.");
137 else
138 pline("You feel like someone is helping you.");
139 for (obj = invent; obj; obj = obj->nobj)
140 if (obj->owornmask)
141 obj->cursed = confused;
142 if (Punished && !confused) {
143 Punished = 0;
144 freeobj(uchain);
145 unpobj(uchain);
146 free((char *) uchain);
147 uball->spe = 0;
148 uball->owornmask &= ~W_BALL;
149 uchain = uball = (struct obj *) 0;
150 }
151 break;
152 }
153 case SCR_CREATE_MONSTER:
154 {
155 int cnt = 1;
156
157 if (!rn2(73))
158 cnt += rnd(4);
159 if (confused)
160 cnt += 12;
161 while (cnt--)
162 (void) makemon(confused ? PM_ACID_BLOB :
163 (struct permonst *) 0, u.ux, u.uy);
164 break;
165 }
166 case SCR_ENCHANT_WEAPON:
167 if (uwep && confused) {
168 pline("Your %s glows silver for a moment.",
169 objects[uwep->otyp].oc_name);
170 uwep->rustfree = 1;
171 } else if (!chwepon(scroll, 1)) /* tests for !uwep */
172 return (1);
173 break;
174 case SCR_DAMAGE_WEAPON:
175 if (uwep && confused) {
176 pline("Your %s glows purple for a moment.",
177 objects[uwep->otyp].oc_name);
178 uwep->rustfree = 0;
179 } else if (!chwepon(scroll, -1)) /* tests for !uwep */
180 return (1);
181 break;
182 case SCR_TAMING:
183 {
184 int i, j;
185 int bd = confused ? 5 : 1;
186 struct monst *mtmp;
187
188 for (i = -bd; i <= bd; i++)
189 for (j = -bd; j <= bd; j++)
190 if ((mtmp = m_at(u.ux + i, u.uy + j)) != NULL)
191 (void) tamedog(mtmp, (struct obj *) 0);
192 break;
193 }
194 case SCR_GENOCIDE:
195 {
196 char buf[BUFSZ];
197 struct monst *mtmp, *mtmp2;
198
199 pline("You have found a scroll of genocide!");
200 known = TRUE;
201 if (confused)
202 *buf = u.usym;
203 else
204 do {
205 pline("What monster do you want to genocide (Type the letter)? ");
206 getlin(buf);
207 } while (strlen(buf) != 1 || !monstersym(*buf));
208 if (!strchr(fut_geno, *buf))
209 charcat(fut_geno, *buf);
210 if (!strchr(genocided, *buf))
211 charcat(genocided, *buf);
212 else {
213 pline("Such monsters do not exist in this world.");
214 break;
215 }
216 for (mtmp = fmon; mtmp; mtmp = mtmp2) {
217 mtmp2 = mtmp->nmon;
218 if (mtmp->data->mlet == *buf)
219 mondead(mtmp);
220 }
221 pline("Wiped out all %c's.", *buf);
222 if (*buf == u.usym) {
223 killer = "scroll of genocide";
224 u.uhp = -1;
225 }
226 break;
227 }
228 case SCR_LIGHT:
229 if (!Blind)
230 known = TRUE;
231 litroom(!confused);
232 break;
233 case SCR_TELEPORTATION:
234 if (confused)
235 level_tele();
236 else {
237 #ifdef QUEST
238 int oux = u.ux, ouy = u.uy;
239 tele();
240 if (dist(oux, ouy) > 100)
241 known = TRUE;
242 #else /* QUEST */
243 int uroom = inroom(u.ux, u.uy);
244 tele();
245 if (uroom != inroom(u.ux, u.uy))
246 known = TRUE;
247 #endif /* QUEST */
248 }
249 break;
250 case SCR_GOLD_DETECTION:
251 /*
252 * Unfortunately this code has become slightly less elegant,
253 * now that gold and traps no longer are of the same type.
254 */
255 if (confused) {
256 struct trap *ttmp;
257
258 if (!ftrap) {
259 strange_feeling(scroll, "Your toes stop itching.");
260 return (1);
261 } else {
262 for (ttmp = ftrap; ttmp; ttmp = ttmp->ntrap)
263 if (ttmp->tx != u.ux || ttmp->ty != u.uy)
264 goto outtrapmap;
265 /*
266 * only under me - no separate display
267 * required
268 */
269 pline("Your toes itch!");
270 break;
271 outtrapmap:
272 cls();
273 for (ttmp = ftrap; ttmp; ttmp = ttmp->ntrap)
274 at(ttmp->tx, ttmp->ty, '$');
275 prme();
276 pline("You feel very greedy!");
277 }
278 } else {
279 struct gold *gtmp;
280
281 if (!fgold) {
282 strange_feeling(scroll, "You feel materially poor.");
283 return (1);
284 } else {
285 known = TRUE;
286 for (gtmp = fgold; gtmp; gtmp = gtmp->ngold)
287 if (gtmp->gx != u.ux || gtmp->gy != u.uy)
288 goto outgoldmap;
289 /*
290 * only under me - no separate display
291 * required
292 */
293 pline("You notice some gold between your feet.");
294 break;
295 outgoldmap:
296 cls();
297 for (gtmp = fgold; gtmp; gtmp = gtmp->ngold)
298 at(gtmp->gx, gtmp->gy, '$');
299 prme();
300 pline("You feel very greedy, and sense gold!");
301 }
302 }
303 /* common sequel */
304 more();
305 docrt();
306 break;
307 case SCR_FOOD_DETECTION:
308 {
309 int ct = 0, ctu = 0;
310 struct obj *obj;
311 char foodsym = confused ? POTION_SYM : FOOD_SYM;
312
313 for (obj = fobj; obj; obj = obj->nobj)
314 if (obj->olet == FOOD_SYM) {
315 if (obj->ox == u.ux && obj->oy == u.uy)
316 ctu++;
317 else
318 ct++;
319 }
320 if (!ct && !ctu) {
321 strange_feeling(scroll, "Your nose twitches.");
322 return (1);
323 } else if (!ct) {
324 known = TRUE;
325 pline("You smell %s close nearby.",
326 confused ? "something" : "food");
327
328 } else {
329 known = TRUE;
330 cls();
331 for (obj = fobj; obj; obj = obj->nobj)
332 if (obj->olet == foodsym)
333 at(obj->ox, obj->oy, FOOD_SYM);
334 prme();
335 pline("Your nose tingles and you smell %s!",
336 confused ? "something" : "food");
337 more();
338 docrt();
339 }
340 break;
341 }
342 case SCR_IDENTIFY:
343 /* known = TRUE; */
344 if (confused)
345 pline("You identify this as an identify scroll.");
346 else
347 pline("This is an identify scroll.");
348 useup(scroll);
349 objects[SCR_IDENTIFY].oc_name_known = 1;
350 if (!confused)
351 while (
352 !ggetobj("identify", identify, rn2(5) ? 1 : rn2(5))
353 && invent
354 );
355 return (1);
356 case SCR_MAGIC_MAPPING:
357 {
358 struct rm *lev;
359 int num, zx, zy;
360
361 known = TRUE;
362 pline("On this scroll %s a map!",
363 confused ? "was" : "is");
364 for (zy = 0; zy < ROWNO; zy++)
365 for (zx = 0; zx < COLNO; zx++) {
366 if (confused && rn2(7))
367 continue;
368 lev = &(levl[zx][zy]);
369 if ((num = lev->typ) == 0)
370 continue;
371 if (num == SCORR) {
372 lev->typ = CORR;
373 lev->scrsym = CORR_SYM;
374 } else if (num == SDOOR) {
375 lev->typ = DOOR;
376 lev->scrsym = '+';
377 /* do sth in doors ? */
378 } else if (lev->seen)
379 continue;
380 #ifndef QUEST
381 if (num != ROOM)
382 #endif /* QUEST */
383 {
384 lev->seen = lev->new = 1;
385 if (lev->scrsym == ' ' || !lev->scrsym)
386 newsym(zx, zy);
387 else
388 on_scr(zx, zy);
389 }
390 }
391 break;
392 }
393 case SCR_AMNESIA:
394 {
395 int zx, zy;
396
397 known = TRUE;
398 for (zx = 0; zx < COLNO; zx++)
399 for (zy = 0; zy < ROWNO; zy++)
400 if (!confused || rn2(7))
401 if (!cansee(zx, zy))
402 levl[zx][zy].seen = 0;
403 docrt();
404 pline("Thinking of Maud you forget everything else.");
405 break;
406 }
407 case SCR_FIRE:
408 {
409 int num = 0;
410 struct monst *mtmp;
411
412 known = TRUE;
413 if (confused) {
414 pline("The scroll catches fire and you burn your hands.");
415 losehp(1, "scroll of fire");
416 } else {
417 pline("The scroll erupts in a tower of flame!");
418 if (Fire_resistance)
419 pline("You are uninjured.");
420 else {
421 num = rnd(6);
422 u.uhpmax -= num;
423 losehp(num, "scroll of fire");
424 }
425 }
426 num = (2 * num + 1) / 3;
427 for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
428 if (dist(mtmp->mx, mtmp->my) < 3) {
429 mtmp->mhp -= num;
430 if (strchr("FY", mtmp->data->mlet))
431 mtmp->mhp -= 3 * num; /* this might well kill
432 * 'F's */
433 if (mtmp->mhp < 1) {
434 killed(mtmp);
435 break; /* primitive */
436 }
437 }
438 }
439 break;
440 }
441 case SCR_PUNISHMENT:
442 known = TRUE;
443 if (confused) {
444 pline("You feel guilty.");
445 break;
446 }
447 pline("You are being punished for your misbehaviour!");
448 if (Punished) {
449 pline("Your iron ball gets heavier.");
450 uball->owt += 15;
451 break;
452 }
453 Punished = INTRINSIC;
454 setworn(mkobj_at(CHAIN_SYM, u.ux, u.uy), W_CHAIN);
455 setworn(mkobj_at(BALL_SYM, u.ux, u.uy), W_BALL);
456 uball->spe = 1; /* special ball (see save) */
457 break;
458 default:
459 impossible("What weird language is this written in? (%u)",
460 scroll->otyp);
461 }
462 if (!objects[scroll->otyp].oc_name_known) {
463 if (known && !confused) {
464 objects[scroll->otyp].oc_name_known = 1;
465 more_experienced(0, 10);
466 } else if (!objects[scroll->otyp].oc_uname)
467 docall(scroll);
468 }
469 useup(scroll);
470 return (1);
471 }
472
473 int
474 identify(otmp) /* also called by newmail() */
475 struct obj *otmp;
476 {
477 objects[otmp->otyp].oc_name_known = 1;
478 otmp->known = otmp->dknown = 1;
479 prinv(otmp);
480 return (1);
481 }
482
483 void
484 litroom(on)
485 boolean on;
486 {
487 #ifndef QUEST
488 int num, zx, zy;
489 #endif
490
491 /* first produce the text (provided he is not blind) */
492 if (Blind)
493 goto do_it;
494 if (!on) {
495 if (u.uswallow || !xdnstair || levl[u.ux][u.uy].typ == CORR ||
496 !levl[u.ux][u.uy].lit) {
497 pline("It seems even darker in here than before.");
498 return;
499 } else
500 pline("It suddenly becomes dark in here.");
501 } else {
502 if (u.uswallow) {
503 pline("%s's stomach is lit.", Monnam(u.ustuck));
504 return;
505 }
506 if (!xdnstair) {
507 pline("Nothing Happens.");
508 return;
509 }
510 #ifdef QUEST
511 pline("The cave lights up around you, then fades.");
512 return;
513 #else /* QUEST */
514 if (levl[u.ux][u.uy].typ == CORR) {
515 pline("The corridor lights up around you, then fades.");
516 return;
517 } else if (levl[u.ux][u.uy].lit) {
518 pline("The light here seems better now.");
519 return;
520 } else
521 pline("The room is lit.");
522 #endif /* QUEST */
523 }
524
525 do_it:
526 #ifdef QUEST
527 return;
528 #else /* QUEST */
529 if (levl[u.ux][u.uy].lit == on)
530 return;
531 if (levl[u.ux][u.uy].typ == DOOR) {
532 if (IS_ROOM(levl[u.ux][u.uy + 1].typ))
533 zy = u.uy + 1;
534 else if (IS_ROOM(levl[u.ux][u.uy - 1].typ))
535 zy = u.uy - 1;
536 else
537 zy = u.uy;
538 if (IS_ROOM(levl[u.ux + 1][u.uy].typ))
539 zx = u.ux + 1;
540 else if (IS_ROOM(levl[u.ux - 1][u.uy].typ))
541 zx = u.ux - 1;
542 else
543 zx = u.ux;
544 } else {
545 zx = u.ux;
546 zy = u.uy;
547 }
548 for (seelx = u.ux; (num = levl[seelx - 1][zy].typ) != CORR && num != 0;
549 seelx--);
550 for (seehx = u.ux; (num = levl[seehx + 1][zy].typ) != CORR && num != 0;
551 seehx++);
552 for (seely = u.uy; (num = levl[zx][seely - 1].typ) != CORR && num != 0;
553 seely--);
554 for (seehy = u.uy; (num = levl[zx][seehy + 1].typ) != CORR && num != 0;
555 seehy++);
556 for (zy = seely; zy <= seehy; zy++)
557 for (zx = seelx; zx <= seehx; zx++) {
558 levl[zx][zy].lit = on;
559 if (!Blind && dist(zx, zy) > 2) {
560 if (on)
561 prl(zx, zy);
562 else
563 nosee(zx, zy);
564 }
565 }
566 if (!on)
567 seehx = 0;
568 #endif /* QUEST */
569 }
570
571 /* Test whether we may genocide all monsters with symbol ch */
572 int
573 monstersym(ch) /* arnold@ucsfcgl */
574 char ch;
575 {
576 const struct permonst *mp;
577
578 /*
579 * can't genocide certain monsters
580 */
581 if (strchr("12 &:", ch))
582 return FALSE;
583
584 if (ch == pm_eel.mlet)
585 return TRUE;
586 for (mp = mons; mp < &mons[CMNUM + 2]; mp++)
587 if (mp->mlet == ch)
588 return TRUE;
589 return FALSE;
590 }