OSDN Git Service

import nethack-3.6.0
[jnethack/source.git] / src / were.c
1 /* NetHack 3.6  were.c  $NHDT-Date: 1432512763 2015/05/25 00:12:43 $  $NHDT-Branch: master $:$NHDT-Revision: 1.18 $ */
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
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 (!Deaf && !canseemon(mon)) {
20                 const char *howler;
21
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;
32                 }
33                 if (howler)
34                     You_hear("a %s howling at the moon.", howler);
35             }
36         }
37     } else if (!rn2(30) || Protection_from_shape_changers) {
38         new_were(mon); /* change back into human form */
39     }
40 }
41
42 int
43 counter_were(pm)
44 int pm;
45 {
46     switch (pm) {
47     case PM_WEREWOLF:
48         return (PM_HUMAN_WEREWOLF);
49     case PM_HUMAN_WEREWOLF:
50         return (PM_WEREWOLF);
51     case PM_WEREJACKAL:
52         return (PM_HUMAN_WEREJACKAL);
53     case PM_HUMAN_WEREJACKAL:
54         return (PM_WEREJACKAL);
55     case PM_WERERAT:
56         return (PM_HUMAN_WERERAT);
57     case PM_HUMAN_WERERAT:
58         return (PM_WERERAT);
59     default:
60         return NON_PM;
61     }
62 }
63
64 /* convert monsters similar to werecritters into appropriate werebeast */
65 int
66 were_beastie(pm)
67 int pm;
68 {
69     switch (pm) {
70     case PM_WERERAT:
71     case PM_SEWER_RAT:
72     case PM_GIANT_RAT:
73     case PM_RABID_RAT:
74         return PM_WERERAT;
75     case PM_WEREJACKAL:
76     case PM_JACKAL:
77     case PM_FOX:
78     case PM_COYOTE:
79         return PM_WEREJACKAL;
80     case PM_WEREWOLF:
81     case PM_WOLF:
82     case PM_WARG:
83     case PM_WINTER_WOLF:
84         return PM_WEREWOLF;
85     default:
86         break;
87     }
88     return NON_PM;
89 }
90
91 void
92 new_were(mon)
93 register struct monst *mon;
94 {
95     register int pm;
96
97     pm = counter_were(monsndx(mon->data));
98     if (pm < LOW_PM) {
99         impossible("unknown lycanthrope %s.", mon->data->mname);
100         return;
101     }
102
103     if (canseemon(mon) && !Hallucination)
104         pline("%s changes into a %s.", Monnam(mon),
105               is_human(&mons[pm]) ? "human" : mons[pm].mname + 4);
106
107     set_mon_data(mon, &mons[pm], 0);
108     if (mon->msleeping || !mon->mcanmove) {
109         /* transformation wakens and/or revitalizes */
110         mon->msleeping = 0;
111         mon->mfrozen = 0; /* not asleep or paralyzed */
112         mon->mcanmove = 1;
113     }
114     /* regenerate by 1/4 of the lost hit points */
115     mon->mhp += (mon->mhpmax - mon->mhp) / 4;
116     newsym(mon->mx, mon->my);
117     mon_break_armor(mon, FALSE);
118     possibly_unwield(mon, FALSE);
119 }
120
121 int were_summon(ptr, yours, visible,
122                 genbuf) /* were-creature (even you) summons a horde */
123 register struct permonst *ptr;
124 register boolean yours;
125 int *visible; /* number of visible helpers created */
126 char *genbuf;
127 {
128     register int i, typ, pm = monsndx(ptr);
129     register struct monst *mtmp;
130     int total = 0;
131
132     *visible = 0;
133     if (Protection_from_shape_changers && !yours)
134         return 0;
135     for (i = rnd(5); i > 0; i--) {
136         switch (pm) {
137         case PM_WERERAT:
138         case PM_HUMAN_WERERAT:
139             typ =
140                 rn2(3) ? PM_SEWER_RAT : rn2(3) ? PM_GIANT_RAT : PM_RABID_RAT;
141             if (genbuf)
142                 Strcpy(genbuf, "rat");
143             break;
144         case PM_WEREJACKAL:
145         case PM_HUMAN_WEREJACKAL:
146             typ = PM_JACKAL;
147             if (genbuf)
148                 Strcpy(genbuf, "jackal");
149             break;
150         case PM_WEREWOLF:
151         case PM_HUMAN_WEREWOLF:
152             typ = rn2(5) ? PM_WOLF : PM_WINTER_WOLF;
153             if (genbuf)
154                 Strcpy(genbuf, "wolf");
155             break;
156         default:
157             continue;
158         }
159         mtmp = makemon(&mons[typ], u.ux, u.uy, NO_MM_FLAGS);
160         if (mtmp) {
161             total++;
162             if (canseemon(mtmp))
163                 *visible += 1;
164         }
165         if (yours && mtmp)
166             (void) tamedog(mtmp, (struct obj *) 0);
167     }
168     return total;
169 }
170
171 void
172 you_were()
173 {
174     char qbuf[QBUFSZ];
175     boolean controllable_poly = Polymorph_control && !(Stunned || Unaware);
176
177     if (Unchanging || (u.umonnum == u.ulycn))
178         return;
179     if (controllable_poly) {
180         /* `+4' => skip "were" prefix to get name of beast */
181         Sprintf(qbuf, "Do you want to change into %s?",
182                 an(mons[u.ulycn].mname + 4));
183         if (yn(qbuf) == 'n')
184             return;
185     }
186     (void) polymon(u.ulycn);
187 }
188
189 void
190 you_unwere(purify)
191 boolean purify;
192 {
193     boolean controllable_poly = Polymorph_control && !(Stunned || Unaware);
194
195     if (purify) {
196         You_feel("purified.");
197         u.ulycn = NON_PM; /* cure lycanthropy */
198     }
199     if (!Unchanging && is_were(youmonst.data)
200         && (!controllable_poly || yn("Remain in beast form?") == 'n'))
201         rehumanize();
202 }
203
204 /*were.c*/