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