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