NHDT->ANH, nethack->anethack, nhdat->anhdat
[aNetHack.git] / src / were.c
blobb2e29ff7b933baa65b0b933e852e8127addd0172
1 /* aNetHack 0.0.1 were.c $ANH-Date: 1432512763 2015/05/25 00:12:43 $ $ANH-Branch: master $:$ANH-Revision: 1.18 $ */
2 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
3 /* aNetHack may be freely redistributed. See license for details. */
5 #include "hack.h"
7 void
8 were_change(mon)
9 register struct monst *mon;
11 if (!is_were(mon->data))
12 return;
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 (!Deaf && !canseemon(mon)) {
20 const char *howler;
22 switch (monsndx(mon->data)) {
23 case PM_WEREWOLF:
24 howler = "wolf";
25 break;
26 case PM_WEREJACKAL:
27 howler = "jackal";
28 break;
29 default:
30 howler = (char *) 0;
31 break;
33 if (howler)
34 You_hear("a %s howling at the moon.", howler);
37 } else if (!rn2(30) || Protection_from_shape_changers) {
38 new_were(mon); /* change back into human form */
40 /* update innate intrinsics (mainly Drain_resistance) */
41 set_uasmon(); /* new_were() doesn't do this */
44 int
45 counter_were(pm)
46 int pm;
48 switch (pm) {
49 case PM_WEREWOLF:
50 return PM_HUMAN_WEREWOLF;
51 case PM_HUMAN_WEREWOLF:
52 return PM_WEREWOLF;
53 case PM_WEREJACKAL:
54 return PM_HUMAN_WEREJACKAL;
55 case PM_HUMAN_WEREJACKAL:
56 return PM_WEREJACKAL;
57 case PM_WERERAT:
58 return PM_HUMAN_WERERAT;
59 case PM_HUMAN_WERERAT:
60 return PM_WERERAT;
61 default:
62 return NON_PM;
66 /* convert monsters similar to werecritters into appropriate werebeast */
67 int
68 were_beastie(pm)
69 int pm;
71 switch (pm) {
72 case PM_WERERAT:
73 case PM_SEWER_RAT:
74 case PM_GIANT_RAT:
75 case PM_RABID_RAT:
76 return PM_WERERAT;
77 case PM_WEREJACKAL:
78 case PM_JACKAL:
79 case PM_FOX:
80 case PM_COYOTE:
81 return PM_WEREJACKAL;
82 case PM_WEREWOLF:
83 case PM_WOLF:
84 case PM_WARG:
85 case PM_WINTER_WOLF:
86 return PM_WEREWOLF;
87 default:
88 break;
90 return NON_PM;
93 void
94 new_were(mon)
95 register struct monst *mon;
97 register int pm;
99 pm = counter_were(monsndx(mon->data));
100 if (pm < LOW_PM) {
101 impossible("unknown lycanthrope %s.", mon->data->mname);
102 return;
105 if (canseemon(mon) && !Hallucination)
106 pline("%s changes into a %s.", Monnam(mon),
107 is_human(&mons[pm]) ? "human" : mons[pm].mname + 4);
109 set_mon_data(mon, &mons[pm], 0);
110 if (mon->msleeping || !mon->mcanmove) {
111 /* transformation wakens and/or revitalizes */
112 mon->msleeping = 0;
113 mon->mfrozen = 0; /* not asleep or paralyzed */
114 mon->mcanmove = 1;
116 /* regenerate by 1/4 of the lost hit points */
117 mon->mhp += (mon->mhpmax - mon->mhp) / 4;
118 newsym(mon->mx, mon->my);
119 mon_break_armor(mon, FALSE);
120 possibly_unwield(mon, FALSE);
123 /* were-creature (even you) summons a horde */
125 were_summon(ptr, yours, visible, genbuf)
126 struct permonst *ptr;
127 boolean yours;
128 int *visible; /* number of visible helpers created */
129 char *genbuf;
131 int i, typ, pm = monsndx(ptr);
132 struct monst *mtmp;
133 int total = 0;
135 *visible = 0;
136 if (Protection_from_shape_changers && !yours)
137 return 0;
138 for (i = rnd(5); i > 0; i--) {
139 switch (pm) {
140 case PM_WERERAT:
141 case PM_HUMAN_WERERAT:
142 typ = rn2(3) ? PM_SEWER_RAT
143 : rn2(3) ? PM_GIANT_RAT : PM_RABID_RAT;
144 if (genbuf)
145 Strcpy(genbuf, "rat");
146 break;
147 case PM_WEREJACKAL:
148 case PM_HUMAN_WEREJACKAL:
149 typ = rn2(7) ? PM_JACKAL : rn2(3) ? PM_COYOTE : PM_FOX;
150 if (genbuf)
151 Strcpy(genbuf, "jackal");
152 break;
153 case PM_WEREWOLF:
154 case PM_HUMAN_WEREWOLF:
155 typ = rn2(5) ? PM_WOLF : rn2(2) ? PM_WARG : PM_WINTER_WOLF;
156 if (genbuf)
157 Strcpy(genbuf, "wolf");
158 break;
159 default:
160 continue;
162 mtmp = makemon(&mons[typ], u.ux, u.uy, NO_MM_FLAGS);
163 if (mtmp) {
164 total++;
165 if (canseemon(mtmp))
166 *visible += 1;
168 if (yours && mtmp)
169 (void) tamedog(mtmp, (struct obj *) 0);
171 return total;
174 void
175 you_were()
177 char qbuf[QBUFSZ];
178 boolean controllable_poly = Polymorph_control && !(Stunned || Unaware);
180 if (Unchanging || u.umonnum == u.ulycn)
181 return;
182 if (controllable_poly) {
183 /* `+4' => skip "were" prefix to get name of beast */
184 Sprintf(qbuf, "Do you want to change into %s?",
185 an(mons[u.ulycn].mname + 4));
186 if (yn(qbuf) == 'n')
187 return;
189 (void) polymon(u.ulycn);
192 void
193 you_unwere(purify)
194 boolean purify;
196 boolean controllable_poly = Polymorph_control && !(Stunned || Unaware);
198 if (purify) {
199 You_feel("purified.");
200 set_ulycn(NON_PM); /* cure lycanthropy */
202 if (!Unchanging && is_were(youmonst.data)
203 && (!controllable_poly || yn("Remain in beast form?") == 'n'))
204 rehumanize();
207 /* lycanthropy is being caught or cured, but no shape change is involved */
208 void
209 set_ulycn(which)
210 int which;
212 u.ulycn = which;
213 /* add or remove lycanthrope's innate intrinsics (Drain_resistance) */
214 set_uasmon();
217 /*were.c*/