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
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
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
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
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
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
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*/