1/*	SCCS Id: @(#)were.c	3.4	2002/11/07	*/
2/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
3/* NetHack may be freely redistributed.  See license for details. */
4
5#include "hack.h"
6
7#ifdef OVL0
8
9void
10were_change(mon)
11register struct monst *mon;
12{
13	if (!is_were(mon->data))
14	    return;
15
16	if (is_human(mon->data)) {
17	    if (!Protection_from_shape_changers &&
18		!rn2(night() ? (flags.moonphase == FULL_MOON ?  3 : 30)
19			     : (flags.moonphase == FULL_MOON ? 10 : 50))) {
20		new_were(mon);		/* change into animal form */
21		if (flags.soundok && !canseemon(mon)) {
22		    const char *howler;
23
24		    switch (monsndx(mon->data)) {
25		    case PM_WEREWOLF:	howler = "wolf";    break;
26		    case PM_WEREJACKAL: howler = "jackal";  break;
27		    default:		howler = (char *)0; break;
28		    }
29		    if (howler)
30			You_hear("a %s howling at the moon.", howler);
31		}
32	    }
33	} else if (!rn2(30) || Protection_from_shape_changers) {
34	    new_were(mon);		/* change back into human form */
35	}
36}
37
38#endif /* OVL0 */
39#ifdef OVLB
40
41STATIC_DCL int FDECL(counter_were,(int));
42
43STATIC_OVL int
44counter_were(pm)
45int pm;
46{
47	switch(pm) {
48	    case PM_WEREWOLF:	      return(PM_HUMAN_WEREWOLF);
49	    case PM_HUMAN_WEREWOLF:   return(PM_WEREWOLF);
50	    case PM_WEREJACKAL:	      return(PM_HUMAN_WEREJACKAL);
51	    case PM_HUMAN_WEREJACKAL: return(PM_WEREJACKAL);
52	    case PM_WERERAT:	      return(PM_HUMAN_WERERAT);
53	    case PM_HUMAN_WERERAT:    return(PM_WERERAT);
54	    default:		      return(0);
55	}
56}
57
58void
59new_were(mon)
60register struct monst *mon;
61{
62	register int pm;
63
64	pm = counter_were(monsndx(mon->data));
65	if(!pm) {
66	    impossible("unknown lycanthrope %s.", mon->data->mname);
67	    return;
68	}
69
70	if(canseemon(mon) && !Hallucination)
71	    pline("%s changes into a %s.", Monnam(mon),
72			is_human(&mons[pm]) ? "human" :
73			mons[pm].mname+4);
74
75	set_mon_data(mon, &mons[pm], 0);
76	if (mon->msleeping || !mon->mcanmove) {
77	    /* transformation wakens and/or revitalizes */
78	    mon->msleeping = 0;
79	    mon->mfrozen = 0;	/* not asleep or paralyzed */
80	    mon->mcanmove = 1;
81	}
82	/* regenerate by 1/4 of the lost hit points */
83	mon->mhp += (mon->mhpmax - mon->mhp) / 4;
84	newsym(mon->mx,mon->my);
85	mon_break_armor(mon, FALSE);
86	possibly_unwield(mon, FALSE);
87}
88
89int
90were_summon(ptr,yours,visible,genbuf)	/* were-creature (even you) summons a horde */
91register struct permonst *ptr;
92register boolean yours;
93int *visible;			/* number of visible helpers created */
94char *genbuf;
95{
96	register int i, typ, pm = monsndx(ptr);
97	register struct monst *mtmp;
98	int total = 0;
99
100	*visible = 0;
101	if(Protection_from_shape_changers && !yours)
102		return 0;
103	for(i = rnd(5); i > 0; i--) {
104	   switch(pm) {
105
106		case PM_WERERAT:
107		case PM_HUMAN_WERERAT:
108			typ = rn2(3) ? PM_SEWER_RAT : rn2(3) ? PM_GIANT_RAT : PM_RABID_RAT ;
109			if (genbuf) Strcpy(genbuf, "rat");
110			break;
111		case PM_WEREJACKAL:
112		case PM_HUMAN_WEREJACKAL:
113			typ = PM_JACKAL;
114			if (genbuf) Strcpy(genbuf, "jackal");
115			break;
116		case PM_WEREWOLF:
117		case PM_HUMAN_WEREWOLF:
118			typ = rn2(5) ? PM_WOLF : PM_WINTER_WOLF ;
119			if (genbuf) Strcpy(genbuf, "wolf");
120			break;
121		default:
122			continue;
123	    }
124	    mtmp = makemon(&mons[typ], u.ux, u.uy, NO_MM_FLAGS);
125	    if (mtmp) {
126		total++;
127		if (canseemon(mtmp)) *visible += 1;
128	    }
129	    if (yours && mtmp)
130		(void) tamedog(mtmp, (struct obj *) 0);
131	}
132	return total;
133}
134
135void
136you_were()
137{
138	char qbuf[QBUFSZ];
139
140	if (Unchanging || (u.umonnum == u.ulycn)) return;
141	if (Polymorph_control) {
142	    /* `+4' => skip "were" prefix to get name of beast */
143	    Sprintf(qbuf, "Do you want to change into %s? ",
144		    an(mons[u.ulycn].mname+4));
145	    if(yn(qbuf) == 'n') return;
146	}
147	(void) polymon(u.ulycn);
148}
149
150void
151you_unwere(purify)
152boolean purify;
153{
154	if (purify) {
155	    You_feel("purified.");
156	    u.ulycn = NON_PM;	/* cure lycanthropy */
157	}
158	if (!Unchanging && is_were(youmonst.data) &&
159		(!Polymorph_control || yn("Remain in beast form?") == 'n'))
160	    rehumanize();
161}
162
163#endif /* OVLB */
164
165/*were.c*/
166