Home | History | Annotate | Line # | Download | only in hack
hack.read.c revision 1.9
      1  1.9  dholland /*	$NetBSD: hack.read.c,v 1.9 2009/06/07 18:30:39 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.9  dholland __RCSID("$NetBSD: hack.read.c,v 1.9 2009/06/07 18:30:39 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.4  christos int
     74  1.9  dholland doread(void)
     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.9  dholland identify(struct obj *otmp)		/* also called by newmail() */
    532  1.1       cgd {
    533  1.1       cgd 	objects[otmp->otyp].oc_name_known = 1;
    534  1.1       cgd 	otmp->known = otmp->dknown = 1;
    535  1.1       cgd 	prinv(otmp);
    536  1.4  christos 	return (1);
    537  1.1       cgd }
    538  1.1       cgd 
    539  1.4  christos void
    540  1.9  dholland litroom(boolean on)
    541  1.1       cgd {
    542  1.4  christos #ifndef QUEST
    543  1.4  christos 	int num, zx, zy;
    544  1.4  christos #endif
    545  1.1       cgd 
    546  1.1       cgd 	/* first produce the text (provided he is not blind) */
    547  1.4  christos 	if (Blind)
    548  1.4  christos 		goto do_it;
    549  1.4  christos 	if (!on) {
    550  1.4  christos 		if (u.uswallow || !xdnstair || levl[u.ux][u.uy].typ == CORR ||
    551  1.1       cgd 		    !levl[u.ux][u.uy].lit) {
    552  1.1       cgd 			pline("It seems even darker in here than before.");
    553  1.1       cgd 			return;
    554  1.1       cgd 		} else
    555  1.1       cgd 			pline("It suddenly becomes dark in here.");
    556  1.1       cgd 	} else {
    557  1.4  christos 		if (u.uswallow) {
    558  1.1       cgd 			pline("%s's stomach is lit.", Monnam(u.ustuck));
    559  1.1       cgd 			return;
    560  1.1       cgd 		}
    561  1.4  christos 		if (!xdnstair) {
    562  1.1       cgd 			pline("Nothing Happens.");
    563  1.1       cgd 			return;
    564  1.1       cgd 		}
    565  1.1       cgd #ifdef QUEST
    566  1.1       cgd 		pline("The cave lights up around you, then fades.");
    567  1.1       cgd 		return;
    568  1.4  christos #else	/* QUEST */
    569  1.4  christos 		if (levl[u.ux][u.uy].typ == CORR) {
    570  1.4  christos 			pline("The corridor lights up around you, then fades.");
    571  1.4  christos 			return;
    572  1.4  christos 		} else if (levl[u.ux][u.uy].lit) {
    573  1.4  christos 			pline("The light here seems better now.");
    574  1.4  christos 			return;
    575  1.1       cgd 		} else
    576  1.4  christos 			pline("The room is lit.");
    577  1.4  christos #endif	/* QUEST */
    578  1.1       cgd 	}
    579  1.1       cgd 
    580  1.1       cgd do_it:
    581  1.1       cgd #ifdef QUEST
    582  1.1       cgd 	return;
    583  1.4  christos #else	/* QUEST */
    584  1.4  christos 	if (levl[u.ux][u.uy].lit == on)
    585  1.1       cgd 		return;
    586  1.4  christos 	if (levl[u.ux][u.uy].typ == DOOR) {
    587  1.4  christos 		if (IS_ROOM(levl[u.ux][u.uy + 1].typ))
    588  1.4  christos 			zy = u.uy + 1;
    589  1.4  christos 		else if (IS_ROOM(levl[u.ux][u.uy - 1].typ))
    590  1.4  christos 			zy = u.uy - 1;
    591  1.4  christos 		else
    592  1.4  christos 			zy = u.uy;
    593  1.4  christos 		if (IS_ROOM(levl[u.ux + 1][u.uy].typ))
    594  1.4  christos 			zx = u.ux + 1;
    595  1.4  christos 		else if (IS_ROOM(levl[u.ux - 1][u.uy].typ))
    596  1.4  christos 			zx = u.ux - 1;
    597  1.4  christos 		else
    598  1.4  christos 			zx = u.ux;
    599  1.1       cgd 	} else {
    600  1.1       cgd 		zx = u.ux;
    601  1.1       cgd 		zy = u.uy;
    602  1.1       cgd 	}
    603  1.4  christos 	for (seelx = u.ux; (num = levl[seelx - 1][zy].typ) != CORR && num != 0;
    604  1.4  christos 	     seelx--);
    605  1.4  christos 	for (seehx = u.ux; (num = levl[seehx + 1][zy].typ) != CORR && num != 0;
    606  1.4  christos 	     seehx++);
    607  1.4  christos 	for (seely = u.uy; (num = levl[zx][seely - 1].typ) != CORR && num != 0;
    608  1.4  christos 	     seely--);
    609  1.4  christos 	for (seehy = u.uy; (num = levl[zx][seehy + 1].typ) != CORR && num != 0;
    610  1.4  christos 	     seehy++);
    611  1.4  christos 	for (zy = seely; zy <= seehy; zy++)
    612  1.4  christos 		for (zx = seelx; zx <= seehx; zx++) {
    613  1.1       cgd 			levl[zx][zy].lit = on;
    614  1.5     veego 			if (!Blind && dist(zx, zy) > 2) {
    615  1.4  christos 				if (on)
    616  1.4  christos 					prl(zx, zy);
    617  1.4  christos 				else
    618  1.4  christos 					nosee(zx, zy);
    619  1.5     veego 			}
    620  1.1       cgd 		}
    621  1.4  christos 	if (!on)
    622  1.4  christos 		seehx = 0;
    623  1.4  christos #endif	/* QUEST */
    624  1.1       cgd }
    625  1.1       cgd 
    626  1.1       cgd /* Test whether we may genocide all monsters with symbol  ch  */
    627  1.4  christos int
    628  1.9  dholland monstersym(int ch)		/* arnold@ucsfcgl */
    629  1.1       cgd {
    630  1.7       jsm 	const struct permonst *mp;
    631  1.1       cgd 
    632  1.1       cgd 	/*
    633  1.1       cgd 	 * can't genocide certain monsters
    634  1.1       cgd 	 */
    635  1.4  christos 	if (strchr("12 &:", ch))
    636  1.1       cgd 		return FALSE;
    637  1.1       cgd 
    638  1.1       cgd 	if (ch == pm_eel.mlet)
    639  1.1       cgd 		return TRUE;
    640  1.4  christos 	for (mp = mons; mp < &mons[CMNUM + 2]; mp++)
    641  1.1       cgd 		if (mp->mlet == ch)
    642  1.1       cgd 			return TRUE;
    643  1.1       cgd 	return FALSE;
    644  1.1       cgd }
    645