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