Home | History | Annotate | Line # | Download | only in hack
      1  1.11  dholland /*	$NetBSD: hack.read.c,v 1.11 2011/08/06 20:29:37 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.11  dholland __RCSID("$NetBSD: hack.read.c,v 1.11 2011/08/06 20:29:37 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.11  dholland 				free(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