1 /*	SCCS Id: @(#)were.c	3.3	97/05/25	*/
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 
9 void
were_change(mon)10 were_change(mon)
11 register 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) {
22 		    const char *howler;
23 
24 		    switch (monsndx(mon->data)) {
25 		    case PM_HUMAN_WEREWOLF:	  howler = "wolf";    break;
26 		    case PM_HUMAN_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 
41 STATIC_DCL int FDECL(counter_were,(int));
42 
43 STATIC_OVL int
counter_were(pm)44 counter_were(pm)
45 int 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 
58 void
new_were(mon)59 new_were(mon)
60 register 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);
86 	possibly_unwield(mon);
87 }
88 
89 boolean
were_summon(ptr,yours)90 were_summon(ptr,yours)	/* were-creature (even you) summons a horde */
91 register struct permonst *ptr;
92 register boolean yours;
93 {
94 	register int i, typ, pm = monsndx(ptr);
95 	register struct monst *mtmp;
96 	boolean success = FALSE;
97 
98 	if(Protection_from_shape_changers && !yours)
99 		return FALSE;
100 	for(i = rnd(5); i > 0; i--) {
101 	   switch(pm) {
102 
103 		case PM_WERERAT:
104 		case PM_HUMAN_WERERAT:
105 			typ = rn2(3) ? PM_SEWER_RAT : rn2(3) ? PM_GIANT_RAT : PM_RABID_RAT ;
106 			break;
107 		case PM_WEREJACKAL:
108 		case PM_HUMAN_WEREJACKAL:
109 			typ = PM_JACKAL;
110 			break;
111 		case PM_WEREWOLF:
112 		case PM_HUMAN_WEREWOLF:
113 			typ = rn2(5) ? PM_WOLF : PM_WINTER_WOLF ;
114 			break;
115 		default:
116 			continue;
117 	    }
118 	    mtmp = makemon(&mons[typ], u.ux, u.uy, NO_MM_FLAGS);
119 	    if (mtmp) success = TRUE;
120 	    if (yours && mtmp)
121 		(void) tamedog(mtmp, (struct obj *) 0);
122 	}
123 	return success;
124 }
125 
126 void
you_were()127 you_were()
128 {
129 	char qbuf[QBUFSZ];
130 
131 	if (Unchanging || (u.umonnum == u.ulycn)) return;
132 	if (Polymorph_control) {
133 	    /* `+4' => skip "were" prefix to get name of beast */
134 	    Sprintf(qbuf, "Do you want to change into %s? ",
135 		    an(mons[u.ulycn].mname+4));
136 	    if(yn(qbuf) == 'n') return;
137 	}
138 	(void) polymon(u.ulycn);
139 }
140 
141 void
you_unwere(purify)142 you_unwere(purify)
143 boolean purify;
144 {
145 	if (purify) {
146 	    You_feel("purified.");
147 	    u.ulycn = NON_PM;	/* cure lycanthropy */
148 	}
149 	if (!Unchanging && is_were(youmonst.data) &&
150 		(!Polymorph_control || yn("Remain in beast form?") == 'n'))
151 	    rehumanize();
152 }
153 
154 #endif /* OVLB */
155 
156 /*were.c*/
157