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