Blindfold removal fix
[slashemextended.git] / src / polyself.c
blob9adf21135043ba909c73b7216af465779ac7bf1b
1 /* SCCS Id: @(#)polyself.c 3.4 2003/01/08 */
2 /* Copyright (C) 1987, 1988, 1989 by Ken Arromdee */
3 /* NetHack may be freely redistributed. See license for details. */
5 /*
6 * Polymorph self routine.
8 * Note: the light source handling code assumes that both youmonst.m_id
9 * and youmonst.mx will always remain 0 when it handles the case of the
10 * player polymorphed into a light-emitting monster.
13 #include "hack.h"
15 #ifdef OVLB
16 STATIC_DCL void polyman(const char *,const char *);
17 STATIC_DCL void break_armor(void);
18 STATIC_DCL void drop_weapon(int);
19 STATIC_DCL void uunstick(void);
20 STATIC_DCL int armor_to_dragon(int);
21 /*STATIC_DCL void newman(void);*/
22 STATIC_DCL void merge_with_armor(void);
24 /* Not Used
25 static void special_poly(void);
28 /* Assumes u.umonster is set up already */
29 /* Use u.umonster since we might be restoring and you may be polymorphed */
30 void
31 init_uasmon()
33 int i;
35 upermonst = mons[u.umonster];
37 /* Fix up the flags */
38 /* Default flags assume human, so replace with your race's flags */
40 upermonst.mflags1 &= ~(mons[PM_HUMAN].mflags1);
41 upermonst.mflags1 |= (mons[urace.malenum].mflags1);
43 upermonst.mflags2 &= ~(mons[PM_HUMAN].mflags2);
44 upermonst.mflags2 |= (mons[urace.malenum].mflags2);
46 upermonst.mflags3 &= ~(mons[PM_HUMAN].mflags3);
47 upermonst.mflags3 |= (mons[urace.malenum].mflags3);
49 /* Fix up the attacks */
50 for(i = 0; i < NATTK; i++) {
51 upermonst.mattk[i] = mons[urace.malenum].mattk[i];
54 set_uasmon();
57 /* update the youmonst.data structure pointer */
58 void
59 set_uasmon()
61 set_mon_data(&youmonst, ((u.umonnum == u.umonster) ?
62 &upermonst : &mons[u.umonnum]), 0);
64 bot_reconfig();
67 /* make a (new) human out of the player */
68 STATIC_OVL void
69 polyman(fmt, arg)
70 const char *fmt, *arg;
72 boolean sticky = sticks(youmonst.data) && u.ustuck && !u.uswallow,
73 was_mimicking = (youmonst.m_ap_type == M_AP_OBJECT);
74 boolean could_pass_walls = Passes_walls;
75 boolean was_blind = !!Blind;
77 if (Upolyd) {
78 /*u.acurr = u.macurr;*/ /* restore old attribs */
79 /*u.amax = u.mamax;*/ /* decided to take this out --Amy */
80 u.umonnum = u.umonster;
81 flags.female = u.mfemale;
84 set_uasmon();
86 u.mh = u.mhmax = 0;
87 u.mtimedone = 0;
88 skinback(FALSE);
89 u.uundetected = 0;
90 newsym(u.ux,u.uy);
92 if (sticky) uunstick();
93 find_ac();
94 if (was_mimicking) {
95 if (multi < 0) unmul("");
96 youmonst.m_ap_type = M_AP_NOTHING;
99 newsym(u.ux,u.uy);
102 You(fmt, arg);
103 /* check whether player foolishly genocided self while poly'd */
104 if ((mvitals[urole.malenum].mvflags & G_GENOD) ||
105 (urole.femalenum != NON_PM &&
106 (mvitals[urole.femalenum].mvflags & G_GENOD)) ||
107 (mvitals[urace.malenum].mvflags & G_GENOD) ||
108 (urace.femalenum != NON_PM &&
109 (mvitals[urace.femalenum].mvflags & G_GENOD))) {
110 /* intervening activity might have clobbered genocide info */
111 killer = delayed_killer;
112 if (!killer || !strstri(killer, "genocid")) {
113 killer_format = KILLED_BY;
114 killer = "self-genocide";
116 done(GENOCIDED);
119 if (u.twoweap && !could_twoweap(youmonst.data))
120 untwoweapon();
122 if (u.utraptype == TT_PIT) {
123 if (could_pass_walls) { /* player forms cannot pass walls */
124 u.utrap = rn1(6,2);
127 if (was_blind && !Blind) { /* reverting from eyeless */
128 Blinded = 1L;
129 make_blinded(0L, TRUE); /* remove blindness */
132 if(!Levitation && !u.ustuck &&
133 (is_waterypool(u.ux,u.uy) || is_watertunnel(u.ux,u.uy) || is_lava(u.ux,u.uy)))
134 spoteffects(TRUE);
136 see_monsters();
139 void
140 change_sex()
142 /* setting u.umonster for caveman/cavewoman or priest/priestess
143 swap unintentionally makes `Upolyd' appear to be true */
144 boolean already_polyd = (boolean) Upolyd;
146 /* Some monsters are always of one sex and their sex can't be changed */
147 /* succubi/incubi can change, but are handled below */
148 /* !already_polyd check necessary because is_male() and is_female()
149 are true if the player is a priest/priestess */
150 if (!already_polyd || (!is_male(youmonst.data) && !is_female(youmonst.data) && !is_neuter(youmonst.data)))
151 flags.female = !flags.female;
152 if (already_polyd) /* poly'd: also change saved sex */
153 u.mfemale = !u.mfemale;
154 max_rank_sz(); /* [this appears to be superfluous] */
155 if ((already_polyd ? u.mfemale : flags.female) && urole.name.f)
156 strcpy(pl_character, urole.name.f);
157 else
158 strcpy(pl_character, urole.name.m);
159 u.umonster = ((already_polyd ? u.mfemale : flags.female) && urole.femalenum != NON_PM) ?
160 urole.femalenum : urole.malenum;
162 if (!already_polyd) {
163 u.umonnum = u.umonster;
164 } else if (u.umonnum == PM_SUCCUBUS || u.umonnum == PM_INCUBUS) {
165 flags.female = !flags.female;
166 /* change monster type to match new sex */
167 u.umonnum = (u.umonnum == PM_SUCCUBUS) ? PM_INCUBUS : PM_SUCCUBUS;
169 set_uasmon();
172 void
173 newman()
175 int tmp, oldlvl;
177 if (Race_if(PM_DOPPELGANGER) || Role_if(PM_SHAPESHIFTER) ) {
178 if (!rn2(10)) change_sex();
179 } else {
180 tmp = u.uhpmax;
181 oldlvl = u.ulevel;
182 u.ulevel = u.ulevel + rn1(5, -2);
183 if (u.ulevel > 127 || u.ulevel < 1) { /* level went below 0? */
184 u.ulevel = oldlvl; /* restore old level in case they lifesave */
185 if (!Race_if(PM_UNGENOMOLD) && !Race_if(PM_MOULD) && !Race_if(PM_DEATHMOLD) && !Race_if(PM_WORM_THAT_WALKS) && !Race_if(PM_WARPER) && !Race_if(PM_MISSINGNO)) goto dead;
187 /* Moulds, including ungenomolds, are resistant to bad polymorphs but have uncurable polymorphitis. --Amy
188 They cannot suffer from system shock either. Since ungenomolds automatically genocide their own race
189 upon starting the game, their first polymorph _needs_ to be into a species other than ungenomold. */
191 if (u.ulevel > MAXULEV) u.ulevel = MAXULEV;
192 /* If your level goes down, your peak level goes down by
193 the same amount so that you can't simply use blessed
194 full healing to undo the decrease. But if your level
195 goes up, your peak level does *not* undergo the same
196 adjustment; you might end up losing out on the chance
197 to regain some levels previously lost to other causes. */
198 if (u.ulevel < oldlvl) u.ulevelmax -= (oldlvl - u.ulevel);
199 if (u.ulevelmax < u.ulevel) u.ulevelmax = u.ulevel;
201 if (!rn2(10)) change_sex();
203 adjabil(oldlvl, (int)u.ulevel);
204 reset_rndmonst(NON_PM); /* new monster generation criteria */
206 /* random experience points for the new experience level */
207 u.uexp = rndexp(FALSE);
209 /* u.uhpmax * u.ulevel / oldlvl: proportionate hit points to new level
210 * -10 and +10: don't apply proportionate HP to 10 of a starting
211 * character's hit points (since a starting character's hit points
212 * are not on the same scale with hit points obtained through level
213 * gain)
214 * 9 - rn2(19): random change of -9 to +9 hit points
216 #ifndef LINT
217 if (u.ulevel <= oldlvl) /* drain for gain exploit fixed by Amy */
218 u.uhpmax = ((u.uhpmax - 10) * (long)u.ulevel / oldlvl + 10) +
219 (9 - rn2(19));
221 else
222 u.uhpmax = (u.uhpmax + rnd(12));
224 #endif
226 #ifdef LINT
227 u.uhp = u.uhp + tmp;
228 #else
229 u.uhp = u.uhp * (long)u.uhpmax/tmp;
230 #endif
232 tmp = u.uenmax;
233 #ifndef LINT
234 if (u.ulevel <= oldlvl) /* drain for gain exploit fixed by Amy */
235 u.uenmax = u.uenmax * (long)u.ulevel / oldlvl + 9 - rn2(19);
237 else
238 u.uenmax = (u.uenmax + rnd(5));
240 #endif
241 if (u.uenmax < 0) u.uenmax = 0;
242 #ifndef LINT
243 u.uen = (tmp ? u.uen * (long)u.uenmax / tmp : u.uenmax);
244 #endif
247 redist_attr();
248 u.uhunger = rn1(750,750);
249 if (Sick) make_sick(0L, (char *) 0, FALSE, SICK_ALL);
250 Sick = 0;
251 Stoned = 0;
252 delayed_killer = 0;
253 if (Race_if(PM_DOPPELGANGER) || Race_if(PM_HEMI_DOPPELGANGER) || Role_if(PM_SHAPESHIFTER) ) {
254 if (u.uhp <= 10) u.uhp = 10;
255 if (u.uhpmax <= 10) u.uhpmax = 10;
256 if (u.uen <= u.ulevel) u.uen = u.ulevel;
257 if (u.uenmax <= u.ulevel) u.uenmax = u.ulevel;
259 if (u.uhp <= 0 || u.uhpmax <= 0) {
261 /* Amy edit: We allow polymorph traps and such stuff to generate as early as dungeon level 1. This can
262 * result in the player's attributes being redistributed, including possibly death, so we'll be nice and
263 * prevent such a death if the turn counter is below 1000. After all, we fixed that stupid drain for gain
264 * exploit and therefore this should not be abusable. If it is, I'll devise another fix :P */
266 if (Polymorph_control || Race_if(PM_MOULD) || Race_if(PM_DEATHMOLD) || Race_if(PM_MISSINGNO) || Race_if(PM_WORM_THAT_WALKS) || Race_if(PM_WARPER) || Race_if(PM_UNGENOMOLD) || u.polyprotected ) {
267 if (u.uhp <= 0) u.uhp = 1;
268 if (u.uhpmax <= 0) u.uhpmax = 1;
269 } else {
270 dead: /* we come directly here if their experience level went to 0 or less */
271 u.youaredead = 1;
272 Your("new form doesn't seem healthy enough to survive.");
273 killer_format = KILLED_BY_AN;
274 killer="unsuccessful polymorph";
275 done(DIED);
276 u.youaredead = 0;
277 newuhs(FALSE);
278 return; /* lifesaved */
281 newuhs(FALSE);
282 polyman("feel like a new %s!",
283 (flags.female && urace.individual.f) ? urace.individual.f :
284 (urace.individual.m) ? urace.individual.m : urace.noun);
285 u.cnd_newmancount++;
287 /* polyselfing into a new man is supposed to be the only way to reroll your areola diameter --Amy */
288 u.areoladiameter = 20;
289 if (rn2(10)) {
290 if (rn2(2)) {
291 u.areoladiameter += rnd(10);
292 while (!rn2(2)) {
293 u.areoladiameter++;
296 else {
297 u.areoladiameter -= rnd(10);
298 while (!rn2(2)) {
299 u.areoladiameter--;
303 if (u.areoladiameter < 1) u.areoladiameter = 1; /* fail safe */
304 if (u.areoladiameter > 30) u.areoladiameter = 30; /* fail safe */
306 use_skill(P_POLYMORPHING, rnd(5));
307 if (!Upolyd) u.polyformed = 0;
308 if (Slimed) {
309 Your("body transforms, but there is still slime on you.");
310 Slimed = 100;
312 flags.botl = 1;
313 vision_full_recalc = 1;
314 (void) encumber_msg();
315 see_monsters();
316 exprecalc();
319 void
320 polyself(forcecontrol)
321 boolean forcecontrol;
323 char buf[BUFSZ];
324 int old_light, new_light;
325 int mntmp = NON_PM;
326 int tries=0;
327 boolean draconian = (uarm &&
328 uarm->otyp >= GRAY_DRAGON_SCALE_MAIL &&
329 uarm->otyp <= YELLOW_DRAGON_SCALES);
330 boolean iswere = (u.ulycn >= LOW_PM || is_were(youmonst.data));
331 boolean isvamp = (is_vampire(youmonst.data) && !Race_if(PM_VAMGOYLE) && issoviet );
332 boolean was_floating = (Levitation || Flying);
333 boolean canhavesemicontrol = TRUE;
335 if (Race_if(PM_MISSINGNO)) {
336 reinitmissingno();
337 init_uasmon();
339 if (Upolyd) {
340 rehumanize();
341 return;
345 if (Unchanging) {
346 if (!wizard || !forcecontrol) return;
349 if (!CannotBeUnchanging && uarmh && uarmh->oartifact == ART_MUTATIONPREVENT && rn2(2)) {
350 if (!wizard || !forcecontrol) {
351 Your("hat prevents the polymorph!");
352 return;
356 if (Race_if(PM_MOULD) || Race_if(PM_TRANSFORMER) || Race_if(PM_POLYINITOR) || Race_if(PM_DESTABILIZER) || Race_if(PM_WORM_THAT_WALKS) || Race_if(PM_WARPER) || Race_if(PM_MISSINGNO) || Race_if(PM_UNGENOMOLD) || Race_if(PM_DEATHMOLD) || Race_if(PM_AK_THIEF_IS_DEAD_) ) {
357 canhavesemicontrol = FALSE;
360 if (Race_if(PM_PLAYER_SLIME)) { /* cannot polymorph at all - punishment for being slimed --Amy */
361 newman();
362 return;
364 if (Race_if(PM_INCORPOREALOID)) { /* cannot polymorph at all, because amateurhour wants it so --Amy */
365 return;
367 /* and you should be grateful, because in vanilla the game would just have ended... */
369 /* [Tom] I made the chance of dying from Con check only possible for
370 really weak people (it was out of 20) */
372 /* Amy edit: early polymorph traps shouldn't kill you by system shock either because that would suck */
374 if(!Polymorph_control && !(tech_inuse(T_POLYFORM) || tech_inuse(T_FUNGOISM) || u.fungalsandals || tech_inuse(T_BECOME_UNDEAD)) && !u.wormpolymorph && !forcecontrol && !draconian && !iswere &&
375 !(isvamp && issoviet) && !Race_if(PM_DOPPELGANGER) && !Role_if(PM_SHAPESHIFTER) && !Race_if(PM_HEMI_DOPPELGANGER)) {
376 if ( (rn2(12) > ACURR(A_CON) || !rn2(50)) && !u.polyprotected && !Race_if(PM_UNGENOMOLD) && !Race_if(PM_MOULD) && !Race_if(PM_DEATHMOLD) && !Race_if(PM_MISSINGNO) && !Race_if(PM_WORM_THAT_WALKS) && !Race_if(PM_WARPER) ) {
378 You("%s", shudder_for_moment);
379 losehp(rnd(30), "system shock", KILLED_BY_AN);
380 exercise(A_CON, FALSE);
381 return;
384 old_light = Upolyd ? emits_light(youmonst.data) : 0;
386 if (tech_inuse(T_POLYFORM) || u.castlecrushglitch) {
388 do {
389 mntmp = rn2(NUMMONS);
390 } while(( (notake(&mons[mntmp]) && rn2(4) ) || ((mons[mntmp].mlet == S_BAT) && rn2(2)) || ((mons[mntmp].mlet == S_EYE) && rn2(2) ) || ((mons[mntmp].mmove == 1) && rn2(4) ) || ((mons[mntmp].mmove == 2) && rn2(3) ) || ((mons[mntmp].mmove == 3) && rn2(2) ) || ((mons[mntmp].mmove == 4) && !rn2(3) ) || ( (mons[mntmp].mlevel < 10) && ((mons[mntmp].mlevel + 1) < rnd(u.ulevel)) ) || (!haseyes(&mons[mntmp]) && rn2(2) ) || ( is_nonmoving(&mons[mntmp]) && rn2(5) ) || ( is_eel(&mons[mntmp]) && rn2(5) ) || ( is_nonmoving(&mons[mntmp]) && rn2(20) ) || (is_jonadabmonster(&mons[mntmp]) && rn2(20)) || ( uncommon2(&mons[mntmp]) && !rn2(4) ) || ( uncommon3(&mons[mntmp]) && !rn2(3) ) || ( uncommon5(&mons[mntmp]) && !rn2(2) ) || ( uncommon7(&mons[mntmp]) && rn2(3) ) || ( uncommon10(&mons[mntmp]) && rn2(5) ) || ( is_eel(&mons[mntmp]) && rn2(20) ) ) );
392 if (polymon(mntmp)) u.polyformed = 1;
394 if (!uarmg || FingerlessGloves) selftouch("No longer petrify-resistant, you");
396 u.wormpolymorph = 0;
398 goto made_change;
401 if (tech_inuse(T_FUNGOISM) || u.fungalsandals) {
403 do {
404 mntmp = rn2(NUMMONS);
405 } while(( (notake(&mons[mntmp]) && rn2(4) ) || !polyok(&mons[mntmp]) || (mons[mntmp].mlet != S_FUNGUS) || ((mons[mntmp].mmove == 1) && rn2(4) ) || ((mons[mntmp].mmove == 2) && rn2(3) ) || ((mons[mntmp].mmove == 3) && rn2(2) ) || ((mons[mntmp].mmove == 4) && !rn2(3) ) || ( (mons[mntmp].mlevel < 10) && ((mons[mntmp].mlevel + 1) < rnd(u.ulevel)) ) || (!haseyes(&mons[mntmp]) && rn2(2) ) || ( is_nonmoving(&mons[mntmp]) && rn2(5) ) || ( is_eel(&mons[mntmp]) && rn2(5) ) || ( is_nonmoving(&mons[mntmp]) && rn2(20) ) || (is_jonadabmonster(&mons[mntmp]) && rn2(20)) || ( uncommon2(&mons[mntmp]) && !rn2(4) ) || ( uncommon3(&mons[mntmp]) && !rn2(3) ) || ( uncommon5(&mons[mntmp]) && !rn2(2) ) || ( uncommon7(&mons[mntmp]) && rn2(3) ) || ( uncommon10(&mons[mntmp]) && rn2(5) ) || ( is_eel(&mons[mntmp]) && rn2(20) ) ) );
407 if (polymon(mntmp)) u.polyformed = 1;
409 if (!uarmg || FingerlessGloves) selftouch("No longer petrify-resistant, you");
411 u.wormpolymorph = 0;
413 goto made_change;
416 if (tech_inuse(T_BECOME_UNDEAD)) {
418 do {
419 mntmp = rn2(NUMMONS);
420 } while(( (notake(&mons[mntmp]) && rn2(4) ) || !polyok(&mons[mntmp]) || (!(is_undead(&mons[mntmp])) ) || ((mons[mntmp].mmove == 1) && rn2(4) ) || ((mons[mntmp].mmove == 2) && rn2(3) ) || ((mons[mntmp].mmove == 3) && rn2(2) ) || ((mons[mntmp].mmove == 4) && !rn2(3) ) || ( (mons[mntmp].mlevel < 10) && ((mons[mntmp].mlevel + 1) < rnd(u.ulevel)) ) || (!haseyes(&mons[mntmp]) && rn2(2) ) || ( is_nonmoving(&mons[mntmp]) && rn2(5) ) || ( is_eel(&mons[mntmp]) && rn2(5) ) || ( is_nonmoving(&mons[mntmp]) && rn2(20) ) || (is_jonadabmonster(&mons[mntmp]) && rn2(20)) || ( uncommon2(&mons[mntmp]) && !rn2(4) ) || ( uncommon3(&mons[mntmp]) && !rn2(3) ) || ( uncommon5(&mons[mntmp]) && !rn2(2) ) || ( uncommon7(&mons[mntmp]) && rn2(3) ) || ( uncommon10(&mons[mntmp]) && rn2(5) ) || ( is_eel(&mons[mntmp]) && rn2(20) ) ) );
422 if (polymon(mntmp)) u.polyformed = 1;
424 if (!uarmg || FingerlessGloves) selftouch("No longer petrify-resistant, you");
426 u.wormpolymorph = 0;
428 goto made_change;
431 if (uamul && uamul->oartifact == ART_DIKKIN_S_DRAGON_TEETH && (yn("Do a completely random polymorph?") == 'y') ) {
433 do {
434 mntmp = rn2(NUMMONS);
435 } while(( (notake(&mons[mntmp]) && rn2(4) ) || ((mons[mntmp].mlet == S_BAT) && rn2(2)) || ((mons[mntmp].mlet == S_EYE) && rn2(2) ) || ((mons[mntmp].mmove == 1) && rn2(4) ) || ((mons[mntmp].mmove == 2) && rn2(3) ) || ((mons[mntmp].mmove == 3) && rn2(2) ) || ((mons[mntmp].mmove == 4) && !rn2(3) ) || ( (mons[mntmp].mlevel < 10) && ((mons[mntmp].mlevel + 1) < rnd(u.ulevel)) ) || (!haseyes(&mons[mntmp]) && rn2(2) ) || ( is_nonmoving(&mons[mntmp]) && rn2(5) ) || ( is_eel(&mons[mntmp]) && rn2(5) ) || ( is_nonmoving(&mons[mntmp]) && rn2(20) ) || (is_jonadabmonster(&mons[mntmp]) && rn2(20)) || ( uncommon2(&mons[mntmp]) && !rn2(4) ) || ( uncommon3(&mons[mntmp]) && !rn2(3) ) || ( uncommon5(&mons[mntmp]) && !rn2(2) ) || ( uncommon7(&mons[mntmp]) && rn2(3) ) || ( uncommon10(&mons[mntmp]) && rn2(5) ) || ( is_eel(&mons[mntmp]) && rn2(20) ) ) );
437 if (polymon(mntmp)) u.polyformed = 1;
439 u.polyformed = 1;
441 if (!uarmg || FingerlessGloves) selftouch("No longer petrify-resistant, you");
443 u.wormpolymorph = 0;
445 goto made_change;
448 if (Race_if(PM_WARPER) && !u.wormpolymorph) {
449 do {
450 /* randomly pick any monster, but reroll if it sucks too much --Amy */
451 mntmp = rn2(NUMMONS);
452 } while(( (notake(&mons[mntmp]) && rn2(4) ) || ((mons[mntmp].mlet == S_BAT) && rn2(2)) || ((mons[mntmp].mlet == S_EYE) && rn2(2) ) || ((mons[mntmp].mmove == 1) && rn2(4) ) || ((mons[mntmp].mmove == 2) && rn2(3) ) || ((mons[mntmp].mmove == 3) && rn2(2) ) || ((mons[mntmp].mmove == 4) && !rn2(3) ) || ( (mons[mntmp].mlevel < 10) && ((mons[mntmp].mlevel + 1) < rnd(u.ulevel)) ) || (!haseyes(&mons[mntmp]) && rn2(2) ) || ( is_nonmoving(&mons[mntmp]) && rn2(5) ) || ( is_eel(&mons[mntmp]) && rn2(5) ) || ( is_nonmoving(&mons[mntmp]) && rn2(20) ) || (is_jonadabmonster(&mons[mntmp]) && rn2(20)) || ( uncommon2(&mons[mntmp]) && !rn2(4) ) || ( uncommon3(&mons[mntmp]) && !rn2(3) ) || ( uncommon5(&mons[mntmp]) && !rn2(2) ) || ( uncommon7(&mons[mntmp]) && rn2(3) ) || ( uncommon10(&mons[mntmp]) && rn2(5) ) || ( is_eel(&mons[mntmp]) && rn2(20) ) ) );
456 else if (Race_if(PM_MISSINGNO)) {
458 mntmp = PM_POLYMORPHED_MISSINGNO;
460 } else if (Race_if(PM_DEATHMOLD)) {
461 /* since we added new tilde-class monsters... have to hardwire this --Amy */
462 int deathmolds = 14 + (u.ulevel / 2);
463 mntmp = PM_WHITE_MISSINGNO; /* fail safe */
464 switch (rnd(deathmolds)) {
465 case 1:
466 mntmp = PM_WHITE_MISSINGNO;
467 break;
468 case 2:
469 mntmp = PM_GRAY_MISSINGNO;
470 break;
471 case 3:
472 mntmp = PM_BLACK_MISSINGNO;
473 break;
474 case 4:
475 mntmp = PM_RED_MISSINGNO;
476 break;
477 case 5:
478 mntmp = PM_GREEN_MISSINGNO;
479 break;
480 case 6:
481 mntmp = PM_BROWN_MISSINGNO;
482 break;
483 case 7:
484 mntmp = PM_MAGENTA_MISSINGNO;
485 break;
486 case 8:
487 mntmp = PM_CYAN_MISSINGNO;
488 break;
489 case 9:
490 mntmp = PM_ORANGE_MISSINGNO;
491 break;
492 case 10:
493 mntmp = PM_BRIGHT_GREEN_MISSINGNO;
494 break;
495 case 11:
496 mntmp = PM_YELLOW_MISSINGNO;
497 break;
498 case 12:
499 mntmp = PM_BRIGHT_BLUE_MISSINGNO;
500 break;
501 case 13:
502 mntmp = PM_BRIGHT_MAGENTA_MISSINGNO;
503 break;
504 case 14:
505 mntmp = PM_BRIGHT_CYAN_MISSINGNO;
506 break;
507 case 15:
508 mntmp = PM_BEIGE_MISSINGNO;
509 break;
510 case 16:
511 mntmp = PM_SHADY_MISSINGNO;
512 break;
513 case 17:
514 mntmp = PM_DARK_MISSINGNO;
515 break;
516 case 18:
517 mntmp = PM_SCARLET_MISSINGNO;
518 break;
519 case 19:
520 mntmp = PM_VIRIDIAN_MISSINGNO;
521 break;
522 case 20:
523 mntmp = PM_UMBRA_MISSINGNO;
524 break;
525 case 21:
526 mntmp = PM_PURPLE_MISSINGNO;
527 break;
528 case 22:
529 mntmp = PM_STEEL_MISSINGNO;
530 break;
531 case 23:
532 mntmp = PM_VIVID_MISSINGNO;
533 break;
534 case 24:
535 mntmp = PM_POISONOUS_MISSINGNO;
536 break;
537 case 25:
538 mntmp = PM_TOPAZ_MISSINGNO;
539 break;
540 case 26:
541 mntmp = PM_ULTRAMARINE_MISSINGNO;
542 break;
543 case 27:
544 mntmp = PM_PINK_MISSINGNO;
545 break;
546 case 28:
547 mntmp = PM_AZURE_MISSINGNO;
548 break;
549 case 29:
550 mntmp = PM_MULTICOLORED_MISSINGNO;
551 break;
552 default:
553 impossible("wrong form for deathmold?");
554 mntmp = PM_WHITE_MISSINGNO; /* fall back to default one --Amy */
555 break;
558 else if ((Polymorph_control || forcecontrol) && !u.wormpolymorph && rn2(StrongPolymorph_control ? 5 : 3)) {
560 boolean hasfailed = FALSE;
561 boolean invalidpolymorph = FALSE;
563 do {
564 getlin("Become what kind of monster? [type the name]",
565 buf);
566 mntmp = name_to_mon(buf);
568 if (mntmp >= LOW_PM && !polyok(&mons[mntmp]) && !your_race(&mons[mntmp])) {
569 invalidpolymorph = TRUE;
570 /* mother fucker, if I'm in wizard mode I damn well can poly into invalid stuff! --Amy */
571 if (wizard && yn("Invalid polymorph form, do you want to force the polymorph to happen anyway?") == 'y') {
572 u.wormpolymorph = mntmp;
573 invalidpolymorph = FALSE;
577 if (mntmp < LOW_PM)
578 pline("I've never heard of such monsters.");
579 /* Note: humans are illegal as monsters, but an
580 * illegal monster forces newman(), which is what we
581 * want if they specified a human.... */
582 else if (invalidpolymorph)
583 You("cannot polymorph into that.");
585 /* taking on high-level forms sometimes fails, especially if your level is low --Amy */
586 else if (!forcecontrol && (rnd(50 - u.ulevel + mons[mntmp].mlevel) > 40 )) {
588 mntmp = LOW_PM - 1; hasfailed = TRUE; break; /* polymorph failed */
590 /* uncommon forms are difficult to polymorph into, because the usual reason why they're uncommon is
591 * that they are very powerful, so we need to reduce the player's chance of becoming one --Amy */
592 else if (!forcecontrol && ( (is_jonadabmonster(&mons[mntmp]) && rn2(20)) || ( uncommon2(&mons[mntmp]) && !rn2(4) ) || ( uncommon3(&mons[mntmp]) && !rn2(3) ) || ( uncommon5(&mons[mntmp]) && !rn2(2) ) || ( uncommon7(&mons[mntmp]) && rn2(3) ) || ( uncommon10(&mons[mntmp]) && rn2(5) ) || ( is_eel(&mons[mntmp]) && rn2(5)) ) ) {
593 mntmp = LOW_PM - 1; hasfailed = TRUE; break; /* polymorph failed */
595 else if (!forcecontrol && ((PlayerCannotUseSkills) && (rnd(StrongPolymorph_control ? 12 : 18) > 7) ) ) {
596 mntmp = LOW_PM - 1; hasfailed = TRUE; break; /* polymorph failed */
598 else if (!forcecontrol && (!(PlayerCannotUseSkills) && (rnd(StrongPolymorph_control ? 15 : 18) > (P_SKILL(P_POLYMORPHING) + 10) ) ) ) {
599 mntmp = LOW_PM - 1; hasfailed = TRUE; break; /* polymorph failed */
602 else break;
603 } while(++tries < 5);
605 if (tries==5) pline("%s", thats_enough_tries);
607 if (hasfailed && ((StrongPolymorph_control && rn2(10)) || (!StrongPolymorph_control && rn2(2)) ) ) {
608 boolean strongchoice = StrongPolymorph_control;
609 int whichchoice = 1;
611 int bschoice1 = LOW_PM - 1;
612 int bschoice2 = LOW_PM - 1;
613 int bschoice3 = LOW_PM - 1;
615 /* randomly pick an "ordinary" monster */
617 tries = 0;
618 do {
619 bschoice1 = rn1(SPECIAL_PM - LOW_PM, LOW_PM);
620 } while((!polyok(&mons[bschoice1]) || is_placeholder(&mons[bschoice1]) || (notake(&mons[bschoice1]) && rn2(4) ) || ((mons[bschoice1].mlet == S_BAT) && rn2(2)) || ((mons[bschoice1].mlet == S_EYE) && rn2(2) ) || ((mons[bschoice1].mmove == 1) && rn2(4) ) || ((mons[bschoice1].mmove == 2) && rn2(3) ) || ((mons[bschoice1].mmove == 3) && rn2(2) ) || ((mons[bschoice1].mmove == 4) && !rn2(3) ) || ( (mons[bschoice1].mlevel < 10) && ((mons[bschoice1].mlevel + 1) < rnd(u.ulevel)) ) || (!haseyes(&mons[bschoice1]) && rn2(2) ) || ( is_nonmoving(&mons[bschoice1]) && rn2(5) ) || (is_jonadabmonster(&mons[bschoice1]) && rn2(20)) || ( uncommon2(&mons[bschoice1]) && !rn2(4) ) || ( uncommon3(&mons[bschoice1]) && !rn2(3) ) || ( uncommon5(&mons[bschoice1]) && !rn2(2) ) || ( uncommon7(&mons[bschoice1]) && rn2(3) ) || ( uncommon10(&mons[bschoice1]) && rn2(5) ) || ( is_eel(&mons[bschoice1]) && rn2(5) ) ) );
622 tries = 0;
623 do {
624 bschoice2 = rn1(SPECIAL_PM - LOW_PM, LOW_PM);
625 } while((!polyok(&mons[bschoice2]) || is_placeholder(&mons[bschoice2]) || (notake(&mons[bschoice2]) && rn2(4) ) || ((mons[bschoice2].mlet == S_BAT) && rn2(2)) || ((mons[bschoice2].mlet == S_EYE) && rn2(2) ) || ((mons[bschoice2].mmove == 1) && rn2(4) ) || ((mons[bschoice2].mmove == 2) && rn2(3) ) || ((mons[bschoice2].mmove == 3) && rn2(2) ) || ((mons[bschoice2].mmove == 4) && !rn2(3) ) || ( (mons[bschoice2].mlevel < 10) && ((mons[bschoice2].mlevel + 1) < rnd(u.ulevel)) ) || (!haseyes(&mons[bschoice2]) && rn2(2) ) || ( is_nonmoving(&mons[bschoice2]) && rn2(5) ) || (is_jonadabmonster(&mons[bschoice2]) && rn2(20)) || ( uncommon2(&mons[bschoice2]) && !rn2(4) ) || ( uncommon3(&mons[bschoice2]) && !rn2(3) ) || ( uncommon5(&mons[bschoice2]) && !rn2(2) ) || ( uncommon7(&mons[bschoice2]) && rn2(3) ) || ( uncommon10(&mons[bschoice2]) && rn2(5) ) || ( is_eel(&mons[bschoice2]) && rn2(5) ) ) );
627 tries = 0;
628 do {
629 bschoice3 = rn1(SPECIAL_PM - LOW_PM, LOW_PM);
630 } while((!polyok(&mons[bschoice3]) || is_placeholder(&mons[bschoice3]) || (notake(&mons[bschoice3]) && rn2(4) ) || ((mons[bschoice3].mlet == S_BAT) && rn2(2)) || ((mons[bschoice3].mlet == S_EYE) && rn2(2) ) || ((mons[bschoice3].mmove == 1) && rn2(4) ) || ((mons[bschoice3].mmove == 2) && rn2(3) ) || ((mons[bschoice3].mmove == 3) && rn2(2) ) || ((mons[bschoice3].mmove == 4) && !rn2(3) ) || ( (mons[bschoice3].mlevel < 10) && ((mons[bschoice3].mlevel + 1) < rnd(u.ulevel)) ) || (!haseyes(&mons[bschoice3]) && rn2(2) ) || ( is_nonmoving(&mons[bschoice3]) && rn2(5) ) || (is_jonadabmonster(&mons[bschoice3]) && rn2(20)) || ( uncommon2(&mons[bschoice3]) && !rn2(4) ) || ( uncommon3(&mons[bschoice3]) && !rn2(3) ) || ( uncommon5(&mons[bschoice3]) && !rn2(2) ) || ( uncommon7(&mons[bschoice3]) && rn2(3) ) || ( uncommon10(&mons[bschoice3]) && rn2(5) ) || ( is_eel(&mons[bschoice3]) && rn2(5) ) ) );
632 if (StrongPolymorph_control) pline("Your controlled polymorph failed, but your limited ability to control polymorphs allows you to pick from these polymorph forms: %s, %s or %s.", mons[bschoice1].mname, mons[bschoice2].mname, mons[bschoice3].mname);
633 else pline("Your controlled polymorph failed, but your limited ability to control polymorphs allows you to pick from these polymorph forms: %s or %s.", mons[bschoice1].mname, mons[bschoice2].mname);
635 pline("Pick a polymorph form. The prompt will show you the stats of the monsters you can choose, and loop until you actually make a choice.");
637 controlchooseagain:
638 if (whichchoice < 2 || whichchoice > (StrongPolymorph_control ? 3 : 2)) {
639 corpsepager(bschoice1);
640 if (yn("Turn into this monster?") == 'y') {
641 mntmp = bschoice1;
642 goto controldone;
644 whichchoice++;
645 if (whichchoice > (StrongPolymorph_control ? 3 : 2)) whichchoice = 1;
646 goto controlchooseagain;
648 if (whichchoice == 2) {
649 corpsepager(bschoice2);
650 if (yn("Turn into this monster?") == 'y') {
651 mntmp = bschoice2;
652 goto controldone;
654 whichchoice++;
655 if (whichchoice > (StrongPolymorph_control ? 3 : 2)) whichchoice = 1;
656 goto controlchooseagain;
658 if (whichchoice == 3 && StrongPolymorph_control) {
659 corpsepager(bschoice3);
660 if (yn("Turn into this monster?") == 'y') {
661 mntmp = bschoice3;
662 goto controldone;
664 whichchoice++;
665 if (whichchoice > (StrongPolymorph_control ? 3 : 2)) whichchoice = 1;
666 goto controlchooseagain;
668 whichchoice = 0; /* fail safe */
669 goto controlchooseagain;
672 controldone:
674 /* allow skin merging, even when polymorph is controlled */
675 if (draconian &&
676 (mntmp == armor_to_dragon(uarm->otyp) || tries == 5))
677 goto do_merge;
678 } else if ((Race_if(PM_DOPPELGANGER) || Role_if(PM_SHAPESHIFTER) || Race_if(PM_HEMI_DOPPELGANGER)) && rn2(StrongPolymorph_control ? 10 : 5) && canhavesemicontrol) {
679 /* Not an experienced Doppelganger yet */
680 do {
681 /* Slightly different wording */
682 getlin("Attempt to become what kind of monster? [type the name]",
683 buf);
684 mntmp = name_to_mon(buf);
685 if (mntmp < LOW_PM)
686 pline("I've never heard of such monsters.");
687 /* Note: humans are illegal as monsters, but an
688 * illegal monster forces newman(), which is what we
689 * want if they specified a human.... */
690 else if (!polyok(&mons[mntmp]) && !your_race(&mons[mntmp]))
691 You("cannot polymorph into that.");
692 else if (!mvitals[mntmp].eaten) {
693 You("attempt an unfamiliar polymorph.");
694 if ((rn2(5) + u.ulevel) < mons[mntmp].mlevel)
695 mntmp = LOW_PM - 1; /* Didn't work for sure */
697 /* lower chance of success even if the form isn't too high-level --Amy */
698 else if (!forcecontrol && (rnd(50 - u.ulevel + mons[mntmp].mlevel) > 40 )) {
700 mntmp = LOW_PM - 1; break; /* polymorph failed */
702 /* lower chance if form is uncommon, see above --Amy */
704 else if ( (is_jonadabmonster(&mons[mntmp]) && rn2(20)) || ( uncommon2(&mons[mntmp]) && !rn2(4) ) || ( uncommon3(&mons[mntmp]) && !rn2(3) ) || ( uncommon5(&mons[mntmp]) && !rn2(2) ) || ( uncommon7(&mons[mntmp]) && rn2(3) ) || ( uncommon10(&mons[mntmp]) && rn2(5) ) || ( is_eel(&mons[mntmp]) && rn2(5)) ) {
705 mntmp = LOW_PM - 1; break; /* polymorph failed */
707 else if ((PlayerCannotUseSkills) && (rnd(StrongPolymorph_control ? 6 : 12) > 3) ) {
708 mntmp = LOW_PM - 1; break; /* polymorph failed */
710 else if (!(PlayerCannotUseSkills) && (rnd(StrongPolymorph_control ? 9 : 12) > (P_SKILL(P_POLYMORPHING) + 4) ) ) {
711 mntmp = LOW_PM - 1; break; /* polymorph failed */
714 /* Either way, give it a shot */
715 break;
718 /* even if you've eaten it, the polymorph can still fail --Amy */
719 else if (!forcecontrol && (rnd(50 - u.ulevel + mons[mntmp].mlevel) > 40 )) {
721 mntmp = LOW_PM - 1; break; /* polymorph failed */
724 else if ((PlayerCannotUseSkills) && (rnd(StrongPolymorph_control ? 6 : 12) > 3) ) {
725 mntmp = LOW_PM - 1; break; /* polymorph failed */
727 else if (!(PlayerCannotUseSkills) && (rnd(StrongPolymorph_control ? 9 : 12) > (P_SKILL(P_POLYMORPHING) + 4) ) ) {
728 mntmp = LOW_PM - 1; break; /* polymorph failed */
731 else break;
732 } while(++tries < 5);
733 if (tries==5) pline("%s", thats_enough_tries);
734 /* allow skin merging, even when polymorph is controlled */
735 if (draconian &&
736 (mntmp == armor_to_dragon(uarm->otyp) || tries == 5))
737 goto do_merge;
738 } else if ( !u.wormpolymorph && ((draconian && rn2(5)) || iswere || (isvamp && issoviet) )) { /* chance to poly into something else --Amy */
739 /* special changes that don't require polyok() */
740 if (draconian /*&& rn2(5)*/ ) {
741 do_merge:
742 mntmp = armor_to_dragon(uarm->otyp);
744 if (!(mvitals[mntmp].mvflags & G_GENOD)) {
745 /* Code that was here is now in merge_with_armor */
746 merge_with_armor();
748 } else if (iswere) {
749 if (is_were(youmonst.data))
750 mntmp = PM_HUMAN; /* Illegal; force newman() */
751 else
752 mntmp = u.ulycn;
753 } else if (isvamp && issoviet) {
754 /* Amy edit: vampire bats are ultra sucky polymorph forms... */
755 /* In Soviet Russia, vampires aren't allowed to polymorph into non-vampires. It's actually weird that
756 * the country isn't called Soviet Romania, where the vampires originally come from. And of course they
757 * don't take into account the fact that there's many many vampiric monsters in this game, not all of
758 * which deserve to always turn into such a godawfully weak form. */
759 if (u.umonnum != PM_VAMPIRE_BAT) {
760 mntmp = PM_VAMPIRE_BAT;
761 pline("Teper' vy bespoleznaya letuchaya mysh', kotoraya vsegda oglushena i dvizhetsya sluchaynym obrazom. Vse tol'ko potomu, chto sovetskiy tip ledyanykh glyb nastol'ko otstalyy i nikogda ne mozhet izmenit' chto-to ot vanili.");
762 } else
763 mntmp = PM_HUMAN; /* newman() */
765 /* if polymon fails, "you feel" message has been given
766 so don't follow up with another polymon or newman */
767 if (mntmp == PM_HUMAN && !Race_if(PM_UNGENOMOLD)) newman(); /* werecritter */
768 else (void) polymon(mntmp);
769 goto made_change; /* maybe not, but this is right anyway */
771 if (u.wormpolymorph) {
772 mntmp = u.wormpolymorph;
773 u.polyformed = 1;
776 if (!u.wormpolymorph && !Race_if(PM_WARPER) && !Race_if(PM_DEATHMOLD) && !Race_if(PM_MISSINGNO) && mntmp < LOW_PM) {
777 tries = 0;
778 do {
779 /* randomly pick an "ordinary" monster */
780 mntmp = rn1(SPECIAL_PM - LOW_PM, LOW_PM);
781 } while((!polyok(&mons[mntmp]) || is_placeholder(&mons[mntmp]) || (notake(&mons[mntmp]) && rn2(4) ) || ((mons[mntmp].mlet == S_BAT) && rn2(2)) || ((mons[mntmp].mlet == S_EYE) && rn2(2) ) || ((mons[mntmp].mmove == 1) && rn2(4) ) || ((mons[mntmp].mmove == 2) && rn2(3) ) || ((mons[mntmp].mmove == 3) && rn2(2) ) || ((mons[mntmp].mmove == 4) && !rn2(3) ) || ( (mons[mntmp].mlevel < 10) && ((mons[mntmp].mlevel + 1) < rnd(u.ulevel)) ) || (!haseyes(&mons[mntmp]) && rn2(2) ) || ( is_nonmoving(&mons[mntmp]) && rn2(5) ) || (is_jonadabmonster(&mons[mntmp]) && rn2(20)) || ( uncommon2(&mons[mntmp]) && !rn2(4) ) || ( uncommon3(&mons[mntmp]) && !rn2(3) ) || ( uncommon5(&mons[mntmp]) && !rn2(2) ) || ( uncommon7(&mons[mntmp]) && rn2(3) ) || ( uncommon10(&mons[mntmp]) && rn2(5) ) || ( is_eel(&mons[mntmp]) && rn2(5) ) || ( is_nonmoving(&mons[mntmp]) && rn2(20) && (Race_if(PM_UNGENOMOLD) || Race_if(PM_MOULD) || Race_if(PM_WORM_THAT_WALKS) || Race_if(PM_WARPER) ) ) || ( is_eel(&mons[mntmp]) && rn2(20) && (Race_if(PM_UNGENOMOLD) || Race_if(PM_MOULD) || Race_if(PM_WORM_THAT_WALKS) || Race_if(PM_WARPER) ) ) )
782 /* Polymorphing into a nonmoving monster can really ruin your day as an ungenomold character, so the chances
783 * of ending up as one are greatly reduced now. Eels are sucky polymorph forms too.
784 * And of course stuff that can't pick up items or is otherwise stunted should be more rare as well. --Amy */
785 && tries++ < 200);
788 /* The below polyok() fails either if everything is genocided, or if
789 * we deliberately chose something illegal to force newman().
791 /* WAC Doppelgangers go through a 1/20 check rather than 1/5 */
793 /* Amy edit: it's bullshit if you get newman() so often. If you polymorph, you should fucking polymorph
794 * most of the time! I've greatly reduced the odds that newman() is called */
796 if ( !u.wormpolymorph && !Race_if(PM_UNGENOMOLD) && !Race_if(PM_MISSINGNO) && !Race_if(PM_WARPER) && !Race_if(PM_DEATHMOLD) && (!polyok(&mons[mntmp]) ||
797 ((Race_if(PM_DOPPELGANGER) || Role_if(PM_SHAPESHIFTER) || Race_if(PM_HEMI_DOPPELGANGER)) ? (
798 ((u.ulevel < mons[mntmp].mlevel)
799 || !mvitals[mntmp].eaten
800 ) && !rn2(50)) : (Race_if(PM_MOULD) || Race_if(PM_WORM_THAT_WALKS) || Race_if(PM_WARPER)) ? !rn2(50) :
801 !rn2(20)) || (your_race(&mons[mntmp]) && !Race_if(PM_MOULD) && !Race_if(PM_TRANSFORMER) && !Race_if(PM_WORM_THAT_WALKS) && !Race_if(PM_WARPER) && rn2(5) ) ) ) /* polymorphitis races can always polymorph into everything, others can sometimes poly into their own race --Amy */
802 newman();
803 else if(!polymon(mntmp)) { u.wormpolymorph = 0; return; }
805 if (!uarmg || FingerlessGloves) selftouch("No longer petrify-resistant, you");
807 /* now that the polymorph has happened (or not), reset worm that walks variable */
808 u.wormpolymorph = 0;
810 made_change:
811 new_light = Upolyd ? emits_light(youmonst.data) : 0;
812 if (old_light != new_light) {
813 if (old_light)
814 del_light_source(LS_MONSTER, (void *)&youmonst);
815 if (new_light == 1) ++new_light; /* otherwise it's undetectable */
816 if (new_light)
817 new_light_source(u.ux, u.uy, new_light,
818 LS_MONSTER, (void *)&youmonst);
820 if (is_drowningpool(u.ux,u.uy) && !(is_crystalwater(u.ux,u.uy)) && was_floating && !(Levitation || Flying) &&
821 !breathless(youmonst.data) && !amphibious(youmonst.data) &&
822 !Swimming) drown();
825 /* (try to) make a mntmp monster out of the player */
827 polymon(mntmp) /* returns 1 if polymorph successful */
828 int mntmp;
830 int duratoincrease;
832 boolean sticky = sticks(youmonst.data) && u.ustuck && !u.uswallow,
833 was_blind = !!Blind, dochange = FALSE;
834 boolean could_pass_walls = Passes_walls;
835 int mlvl;
837 if (Race_if(PM_PLAYER_SLIME)) { /* cannot polymorph at all - punishment for being slimed --Amy */
838 newman();
839 return 0;
841 if (Race_if(PM_INCORPOREALOID)) { /* cannot polymorph at all, because amateurhour wants it so --Amy */
842 return 0;
845 if (mntmp < LOW_PM) { /* for some reason, this seems to happen sometimes. Dunno why. --Amy */
847 pline("Uh-oh... that polymorph didn't seem to work.");
848 return(0);
852 if (mntmp < NUMMONS) u.ughmemory = 0;
854 if (mvitals[mntmp].mvflags & G_GENOD) { /* allow G_EXTINCT */
855 You_feel("rather %s-ish.",mons[mntmp].mname);
856 exercise(A_WIS, TRUE);
857 return(0);
860 /* STEPHEN WHITE'S NEW CODE */
862 /* If your an Undead Slayer, you can't become undead! */
864 if (is_undead(&mons[mntmp]) && Role_if(PM_UNDEAD_SLAYER)) {
865 if (Polymorph_control) {
866 You("hear a voice boom out: \"How dare you take such a form!\"");
867 u.ualign.record -= 5;
868 #ifdef NOARTIFACTWISH
869 u.usacrifice = 0;
870 #endif
871 exercise(A_WIS, FALSE);
872 } else {
873 You("start to change into %s, but a voice booms out:", an(mons[mntmp].mname));
874 pline("\"No, I will not allow such a change!\"");
876 return(0);
879 /* KMH, conduct */
880 u.uconduct.polyselfs++;
881 if (uarm && uarm->oartifact == ART_RADAR_FELL_UP) increasesanity(rnz(5000));
883 if (!Upolyd) {
884 /* Human to monster; save human stats */
885 /*u.macurr = u.acurr;
886 u.mamax = u.amax;*/ /* edit by Amy - this was just stupid. Let the stats be interchangeable between forms! */
887 u.mfemale = flags.female;
888 } else {
889 /* Monster to monster; restore human stats, to be
890 * immediately changed to provide stats for the new monster
892 /*u.acurr = u.macurr;
893 u.amax = u.mamax;*/ /* see above - I really don't understand why polymorph forms would have their own attribute scores. I want my freaking xorn wizard form to get a benefit from eating cockatrice corpses after all! Dammit! --Amy */
894 flags.female = u.mfemale;
897 if (youmonst.m_ap_type) {
898 /* stop mimicking immediately */
899 if (multi < 0) unmul("");
900 } else if (mons[mntmp].mlet != S_MIMIC) {
901 /* as in polyman() */
902 youmonst.m_ap_type = M_AP_NOTHING;
904 if (is_male(&mons[mntmp])) {
905 if(flags.female) dochange = TRUE;
906 } else if (is_female(&mons[mntmp])) {
907 if(!flags.female) dochange = TRUE;
908 } else if (!is_neuter(&mons[mntmp]) && mntmp != u.ulycn) {
909 if(!rn2(10)) dochange = TRUE;
912 if (!u.ughmemory) {
913 if (dochange) {
914 flags.female = !flags.female;
915 You("%s %s%s!",
916 (u.umonnum != mntmp) ? "turn into a" : "feel like a new",
917 (is_male(&mons[mntmp]) || is_female(&mons[mntmp])) ? "" :
918 flags.female ? "female " : "male ",
919 mons[mntmp].mname);
920 } else {
921 if (u.umonnum != mntmp)
922 You("turn into %s!", an(mons[mntmp].mname));
923 else
924 You_feel("like a new %s!", mons[mntmp].mname);
926 } else pline("You transform!");
928 if (Stoned && poly_when_stoned(&mons[mntmp])) {
929 /* poly_when_stoned already checked stone golem genocide */
930 You("turn to stone!");
931 mntmp = PM_STONE_GOLEM;
932 Stoned = 0;
933 delayed_killer = 0;
936 if (PlayerCannotUseSkills) u.mtimedone = rnz(400);
937 else switch (P_SKILL(P_POLYMORPHING)) {
939 case P_BASIC: u.mtimedone = rnz(500); break;
940 case P_SKILLED: u.mtimedone = rnz(600); break;
941 case P_EXPERT: u.mtimedone = rnz(700); break;
942 case P_MASTER: u.mtimedone = rnz(800); break;
943 case P_GRAND_MASTER: u.mtimedone = rnz(900); break;
944 case P_SUPREME_MASTER: u.mtimedone = rnz(1000); break;
945 default: u.mtimedone = rnz(400); break;
949 if (!PlayerCannotUseSkills) {
951 if (P_SKILL(P_POLYMORPHING) >= P_BASIC) {
952 char nervbuf[QBUFSZ];
953 char thisisannoying = 0;
955 sprintf(nervbuf, "You have the polymorphing skill, which allows you to get a longer-lasting polymorph. Do you want a longer polymorph duration? (If you answer no, you just throw the bonus away.)");
956 thisisannoying = yn_function(nervbuf, ynqchars, 'y');
957 if (thisisannoying == 'n') {
958 u.mtimedone = rnz(400);
959 pline("You decided to opt for the regular polymorphing duration, disregarding the bonus that your polymorphing skill would have given you.");
961 else pline("Your polymorph duration was extended!");
966 u.umonnum = mntmp;
967 use_skill(P_POLYMORPHING, mons[mntmp].mlevel + 1 + rnd(5));
969 set_uasmon();
971 /* New stats for monster, to last only as long as polymorphed.
972 * Currently only strength gets changed.
974 /*if(strongmonst(&mons[mntmp])) ABASE(A_STR) = AMAX(A_STR) = STR18(100);*/
976 if (Stone_resistance && Stoned) { /* parnes@eniac.seas.upenn.edu */
977 Stoned = 0;
978 delayed_killer = 0;
979 You("no longer seem to be petrifying.");
981 if (Sick_resistance && Sick) {
982 make_sick(0L, (char *) 0, FALSE, SICK_ALL);
983 You("no longer feel sick.");
985 if (Slimed) {
986 if (flaming(youmonst.data)) {
987 pline_The("slime burns away!");
988 Slimed = 0L;
989 flags.botl = 1;
990 } else if (slime_on_touch(&mons[mntmp]) ) {
991 /* do it silently */
992 Slimed = 0L;
993 flags.botl = 1;
996 if (nohands(youmonst.data)) Glib = 0;
997 if (Passes_walls && u.utraptype == TT_PIT) {
998 u.utraptype = 0;
999 u.utrap = 0;
1000 vision_full_recalc = 1;
1004 mlvl = adj_lev(&mons[mntmp]);
1005 * We can't do the above, since there's no such thing as an
1006 * "experience level of you as a monster" for a polymorphed character.
1008 mlvl = ((mntmp == u.ulycn) ? u.ulevel : (int)mons[mntmp].mlevel);
1009 if (youmonst.data->mlet == S_DRAGON && mntmp >= PM_GRAY_DRAGON) {
1010 u.mhmax = In_endgame(&u.uz) ? (8*mlvl) : (4*mlvl + d(mlvl,4));
1011 } else if (mntmp == PM_SLICK_RUEA || mntmp == PM_DOUBLE_AURORA_BOMBER || mntmp == PM_SHEER_SPACER || mntmp == PM_CRITICALLY_INJURED_THIEF || mntmp == PM_CRITICALLY_INJURED_JEDI) {
1012 u.mhmax = 1;
1013 } else if (is_golem(youmonst.data)) {
1014 u.mhmax = golemhp(mntmp);
1015 } else {
1016 if (!mlvl) u.mhmax = rnd(4);
1017 else u.mhmax = d(mlvl, 8);
1018 if (is_home_elemental(&mons[mntmp])) u.mhmax *= 3;
1020 u.mhmax += rnz(u.ulevel);
1021 u.mhmax += rnz(u.ulevel);
1022 u.mhmax += rnz(ACURR(A_CON));
1023 if (u.ulevel >= 10) {
1024 u.mhmax += rnd(u.ulevel - 9 + mons[u.umonnum].mlevel );
1025 if (ACURR(A_CON) > 6) u.mhmax += ((u.ulevel + mons[u.umonnum].mlevel) * (ACURR(A_CON) / 7) );
1027 if (u.menoraget) u.mhmax += rnd(50);
1028 if (u.silverbellget) u.mhmax += rnd(50);
1029 if (u.bookofthedeadget) u.mhmax += rnd(50);
1030 if (u.chaoskeyget) u.mhmax += rnd(10);
1031 if (u.neutralkeyget) u.mhmax += rnd(10);
1032 if (u.lawfulkeyget) u.mhmax += rnd(10);
1034 u.mh = u.mhmax;
1036 if (u.ulevel < mlvl && !Race_if(PM_MOULD) && !Race_if(PM_DEATHMOLD) && !Race_if(PM_MISSINGNO)) {
1037 /* Low level characters can't become high level monsters for long */
1038 #ifdef DUMB
1039 /* DRS/NS 2.2.6 messes up -- Peter Kendell */
1040 int mtd = u.mtimedone, ulv = u.ulevel;
1042 u.mtimedone = mtd * ulv / mlvl;
1043 #else
1044 u.mtimedone = u.mtimedone * u.ulevel / mlvl;
1045 #endif
1048 /* very fast polymorph forms last for a shorter amount of time (nerf :P) --Amy */
1049 if (youmonst.data->mmove > 17) {
1050 u.mtimedone *= 17;
1051 u.mtimedone /= youmonst.data->mmove;
1053 boolean morereduction = 1;
1054 if (!PlayerCannotUseSkills) switch (P_SKILL(P_POLYMORPHING)) {
1056 case P_BASIC: if (!rn2(10)) morereduction = 0; break;
1057 case P_SKILLED: if (!rn2(8)) morereduction = 0; break;
1058 case P_EXPERT: if (!rn2(5)) morereduction = 0; break;
1059 case P_MASTER: if (!rn2(3)) morereduction = 0; break;
1060 case P_GRAND_MASTER: if (!rn2(2)) morereduction = 0; break;
1061 case P_SUPREME_MASTER: morereduction = 0; break;
1062 default: morereduction = 1; break;
1065 if (morereduction) {
1066 u.mtimedone *= 17;
1067 u.mtimedone /= youmonst.data->mmove;
1072 if (Race_if(PM_WARPER)) u.mtimedone /= 2;
1074 /* multiplicative bonuses come here, and shouldn't affect each other exponentially --Amy */
1076 duratoincrease = u.mtimedone;
1078 /* Moulds suck way too much. Let's allow them to stay polymorphed for a longer time. --Amy */
1079 /* Worms too. Their polymorph time depends on the monster's level though. */
1081 if ( (u.ulevel * 2) < mlvl && (Race_if(PM_MOULD) || Race_if(PM_DEATHMOLD) || Race_if(PM_MISSINGNO) || Race_if(PM_WORM_THAT_WALKS) ) ) {
1082 u.mtimedone += rnz((u.ulevel * 2) + 1);
1084 u.mtimedone += duratoincrease;
1087 if (uarmc && uarmc->oartifact == ART_LONG_LASTING_JOY) u.mtimedone += (duratoincrease * rnd(2));;
1089 if (ishaxor) u.mtimedone += duratoincrease;
1091 /* WAC Doppelgangers can stay much longer in a form they know well */
1092 if ((Race_if(PM_DOPPELGANGER) || Role_if(PM_SHAPESHIFTER) || Race_if(PM_HEMI_DOPPELGANGER)) && mvitals[mntmp].eaten) {
1093 u.mtimedone += duratoincrease;
1094 u.mtimedone += mvitals[mntmp].eaten;
1097 if (wizard && yn("Do you want to increase your polymorph duration by 10000 turns?") == 'y') u.mtimedone += 10000;
1099 if (uskin && mntmp != armor_to_dragon(uskin->otyp))
1100 skinback(FALSE);
1101 break_armor();
1102 drop_weapon(1);
1103 if (hides_under(youmonst.data) || (uarmh && itemhasappearance(uarmh, APP_SECRET_HELMET) ) || (!night() && uarmg && uarmg->oartifact == ART_NIGHTLY_HIGHWAY) || (uarmc && uarmc->oartifact == ART_JANA_S_EXTREME_HIDE_AND_SE) )
1104 u.uundetected = OBJ_AT(u.ux, u.uy);
1105 else if (youmonst.data->mlet == S_EEL)
1106 u.uundetected = is_waterypool(u.ux, u.uy);
1107 else
1108 u.uundetected = 0;
1110 if (u.utraptype == TT_PIT) {
1111 if (could_pass_walls && !Passes_walls) {
1112 u.utrap = rn1(6,2);
1113 } else if (!could_pass_walls && Passes_walls) {
1114 u.utrap = 0;
1117 if (was_blind && !Blind) { /* previous form was eyeless */
1118 Blinded = 1L;
1119 make_blinded(0L, TRUE); /* remove blindness */
1121 newsym(u.ux,u.uy); /* Change symbol */
1123 if (!sticky && !u.uswallow && u.ustuck && sticks(youmonst.data)) setustuck(0);
1124 else if (sticky && !sticks(youmonst.data)) uunstick();
1125 if (u.usteed) {
1126 if (touch_petrifies(u.usteed->data) && (PlayerCannotUseSkills || (P_SKILL(P_RIDING) < P_EXPERT)) && (!Stone_resistance || (!IntStone_resistance && !rn2(20)) ) && !(uarmg && !FingerlessGloves && uarmu && uarm && uarmc) && rnl(3)) {
1127 char buf[BUFSZ];
1129 pline("No longer petrifying-resistant, you touch %s.",
1130 mon_nam(u.usteed));
1131 sprintf(buf, "riding a petrifying monster");
1132 instapetrify(buf);
1134 if (!can_ride(u.usteed)) dismount_steed(DISMOUNT_POLY);
1137 if (flags.verbose) {
1138 static const char use_thec[] = "Use the command #%s to %s.";
1139 static const char monsterc[] = "monster";
1140 if (can_breathe(youmonst.data))
1141 pline(use_thec,monsterc,"use your breath weapon");
1142 if (attacktype(youmonst.data, AT_SPIT))
1143 pline(use_thec,monsterc,"spit venom");
1144 if (youmonst.data->mlet == S_NYMPH)
1145 pline(use_thec,monsterc,"remove an iron ball");
1146 if (attacktype(youmonst.data, AT_GAZE))
1147 pline(use_thec,monsterc,"gaze at monsters");
1148 if (is_hider(youmonst.data))
1149 pline(use_thec,monsterc,"hide");
1150 if (is_were(youmonst.data))
1151 pline(use_thec,monsterc,"summon help");
1152 if (webmaker(youmonst.data))
1153 pline(use_thec,monsterc,"spin a web");
1154 if (splittinggremlin(youmonst.data))
1155 pline(use_thec,monsterc,"multiply in a fountain");
1156 if (splittinglavagremlin(youmonst.data))
1157 pline(use_thec,monsterc,"multiply in a pool of lava");
1158 if (is_unicorn(youmonst.data))
1159 pline(use_thec,monsterc,"use your horn");
1160 if (is_mind_flayer(youmonst.data))
1161 pline(use_thec,monsterc,"emit a mental blast");
1162 if (youmonst.data->msound == MS_SHRIEK) /* worthless, actually */
1163 pline(use_thec,monsterc,"shriek");
1164 if (youmonst.data->msound == MS_FART_QUIET)
1165 pline(use_thec,monsterc,"fart");
1166 if (youmonst.data->msound == MS_FART_NORMAL)
1167 pline(use_thec,monsterc,"fart");
1168 if (youmonst.data->msound == MS_FART_LOUD)
1169 pline(use_thec,monsterc,"fart");
1170 if (lays_eggs(youmonst.data) && flags.female)
1171 pline(use_thec,"sit","lay an egg");
1172 if (youmonst.data->msound == MS_STENCH)
1173 pline(use_thec,monsterc,"spread the perfume");
1174 if (youmonst.data->msound == MS_CONVERT)
1175 pline(use_thec,monsterc,"preach");
1176 if (youmonst.data->msound == MS_HCALIEN)
1177 pline(use_thec,monsterc,"chant");
1178 if (youmonst.data->msound == MS_WHORE)
1179 pline(use_thec,monsterc,"talk sexily");
1180 if (youmonst.data->msound == MS_SUPERMAN)
1181 pline(use_thec,monsterc,"make superman taunts");
1182 if (youmonst.data->msound == MS_BONES)
1183 pline(use_thec,monsterc,"rattle");
1185 /* you now know what an egg of your type looks like */
1186 if (lays_eggs(youmonst.data)) {
1187 /* make queen bees recognize killer bee eggs */
1188 learn_egg_type(egg_type_from_parent(u.umonnum, TRUE));
1190 find_ac();
1191 if((!Levitation && !u.ustuck && !Flying &&
1192 (is_waterypool(u.ux,u.uy) || is_watertunnel(u.ux,u.uy) || is_lava(u.ux,u.uy))) ||
1193 (Underwater && !Swimming))
1194 spoteffects(TRUE);
1195 if (Passes_walls && u.utrap && u.utraptype == TT_INFLOOR) {
1196 u.utrap = 0;
1197 FunnyHallu ? pline("You get on an astral trip.") : pline_The("rock seems to no longer trap you.");
1198 } else if (likes_lava(youmonst.data) && u.utrap && u.utraptype == TT_LAVA) {
1199 u.utrap = 0;
1200 FunnyHallu ? pline("Fire all around you - how comfy!") : pline_The("lava now feels soothing.");
1202 if (amorphous(youmonst.data) || is_whirly(youmonst.data) || unsolid(youmonst.data)) {
1203 if (Punished && !(u.repunishcounter) ) {
1204 You("slip out of the iron chain.");
1205 unpunish();
1208 if (u.utrap && (u.utraptype == TT_WEB || u.utraptype == TT_BEARTRAP) &&
1209 (amorphous(youmonst.data) || is_whirly(youmonst.data) || unsolid(youmonst.data) ||
1210 (youmonst.data->msize <= MZ_SMALL && u.utraptype == TT_BEARTRAP))) {
1211 You("are no longer stuck in the %s.",
1212 u.utraptype == TT_WEB ? "web" : "bear trap");
1213 /* probably should burn webs too if PM_FIRE_ELEMENTAL */
1214 u.utrap = 0;
1216 if (webmaker(youmonst.data) && u.utrap && u.utraptype == TT_WEB) {
1217 You("orient yourself on the web.");
1218 u.utrap = 0;
1220 flags.botl = 1;
1221 vision_full_recalc = 1;
1222 see_monsters();
1223 exercise(A_CON, FALSE);
1224 exercise(A_WIS, TRUE);
1225 (void) encumber_msg();
1226 return(1);
1229 STATIC_OVL void
1230 break_armor()
1233 char buf[BUFSZ];
1235 register struct obj *otmp;
1236 boolean controlled_change = (Race_if(PM_DOPPELGANGER) || RngeArmorPreservation || Role_if(PM_SHAPESHIFTER) || Race_if(PM_HEMI_DOPPELGANGER) || Role_if(PM_LUNATIC) || Race_if(PM_AK_THIEF_IS_DEAD_) || (Race_if(PM_HUMAN_WEREWOLF) && u.umonnum == PM_WEREWOLF));
1238 if (!(PlayerCannotUseSkills)) {
1239 if (rnd(10) < P_SKILL(P_POLYMORPHING)) controlled_change = TRUE;
1243 boolean facelesskeep = 0;
1244 if (facelessprotection()) facelesskeep = TRUE; /* have to calculate this first, before any armor is removed --Amy */
1246 int controllingchance = 0;
1247 boolean armorkeep = 0;
1248 boolean cloakkeep = 0;
1249 boolean shirtkeep = 0;
1251 if (!(PlayerCannotUseSkills)) {
1252 switch (P_SKILL(P_POLYMORPHING)) {
1254 case P_BASIC: controllingchance = 1; break;
1255 case P_SKILLED: controllingchance = 2; break;
1256 case P_EXPERT: controllingchance = 3; break;
1257 case P_MASTER: controllingchance = 4; break;
1258 case P_GRAND_MASTER: controllingchance = 5; break;
1259 case P_SUPREME_MASTER: controllingchance = 6; break;
1260 default: controllingchance = 0; break;
1263 if (hugemonst(youmonst.data)) controllingchance *= 5;
1264 else if (verysmall(youmonst.data) || (youmonst.data->msize >= MZ_HUGE)) {
1265 controllingchance *= 15;
1266 controllingchance /= 2;
1268 else controllingchance *= 10;
1271 if (facelesskeep && (controllingchance < 100)) controllingchance = 100;
1273 if (uarm && !Race_if(PM_TRANSFORMER) && (rnd(100) < controllingchance)) {
1275 getlin ("Keep your torso armor on? [y/yes/no]",buf);
1276 (void) lcase (buf);
1277 if (!(strcmp (buf, "yes")) || !(strcmp (buf, "y")) || !(strcmp (buf, "ye")) || !(strcmp (buf, "ys"))) armorkeep = 1;
1280 if (uarm && uarm->stckcurse) armorkeep = 1;
1282 if (uarmc && !Race_if(PM_TRANSFORMER) && (rnd(100) < controllingchance)) {
1283 getlin ("Keep your cloak on? [y/yes/no]",buf);
1284 (void) lcase (buf);
1285 if (!(strcmp (buf, "yes")) || !(strcmp (buf, "y")) || !(strcmp (buf, "ye")) || !(strcmp (buf, "ys"))) cloakkeep = 1;
1288 if (uarmc && uarmc->stckcurse) cloakkeep = 1;
1290 if (uarmu && !Race_if(PM_TRANSFORMER) && (rnd(100) < controllingchance)) {
1291 getlin ("Keep your shirt on? [y/yes/no]",buf);
1292 (void) lcase (buf);
1293 if (!(strcmp (buf, "yes")) || !(strcmp (buf, "y")) || !(strcmp (buf, "ye")) || !(strcmp (buf, "ys"))) shirtkeep = 1;
1296 if (uarmu && uarmu->stckcurse) shirtkeep = 1;
1298 if (breakarm(youmonst.data) && !Race_if(PM_TRANSFORMER) ) {
1299 if (((otmp = uarm) != 0) && !(uarm && uarm->otyp == OSFA_CHAIN_MAIL) && !(uarm && uarm->oartifact == ART_WRONG_TURN) && !armorkeep) {
1300 if(otmp->oartifact || facelesskeep || (uarmf && uarmf->oartifact == ART_MALENA_S_LADYNESS) || (otmp->fakeartifact && rn2(2)) ) {
1301 if (donning(otmp)) cancel_don();
1302 Your("armor falls off!");
1303 (void) Armor_gone();
1304 dropx(otmp); /*WAC Drop instead of destroy*/
1305 } else if ((controlled_change) || (youmonst.data->msize == MZ_MEDIUM && !issoviet && rn2(20)) || (itemsurvivedestruction(otmp, 8) && !issoviet) || (Polymorph_control && !issoviet && !rn2(3)) || ((Fast || Very_fast) && !issoviet && !rn2(3)) || (StrongFast && !issoviet && !rn2(3)) || (otmp->blessed && !issoviet && !rn2(2)) || (StrongPolymorph_control && !issoviet && !rn2(3)) || (youmonst.data->msize == MZ_LARGE && !issoviet && rn2(5)) || (youmonst.data->msize == MZ_HUGE && !issoviet && rn2(3)) || (youmonst.data->msize > MZ_HUGE && !issoviet && rn2(2)) ) {
1306 if (donning(otmp)) cancel_don();
1308 if (!otmp->cursed) {
1309 You("quickly remove your armor as you start to change.");
1310 (void) Armor_gone();
1311 dropx(otmp); /*WAC Drop instead of destroy*/
1315 } else {
1316 if (donning(otmp)) cancel_don();
1317 if (!issoviet) You("break out of your armor!");
1318 else pline("I yeshche odin glupyy veshch' kusayet pyl'! Sovetskaya khochet etu igru, chtoby sosat' kak mozhno bol'she!");
1319 exercise(A_STR, FALSE);
1320 (void) Armor_gone();
1321 u.cnd_polybreak++;
1322 useup(otmp);
1325 if (!cloakkeep && !(uarmc && itemhasappearance(uarmc, APP_OSFA_CLOAK)) && (otmp = uarmc) != 0) {
1326 if(otmp->oartifact || facelesskeep || (uarmf && uarmf->oartifact == ART_MALENA_S_LADYNESS) || (otmp->fakeartifact && rn2(2)) ) {
1327 Your("%s falls off!", cloak_simple_name(otmp));
1328 (void) Cloak_off();
1329 dropx(otmp);
1330 } else if ((controlled_change) || (youmonst.data->msize == MZ_MEDIUM && !issoviet && rn2(20)) || (youmonst.data->msize == MZ_LARGE && !issoviet && rn2(5)) || (itemsurvivedestruction(otmp, 8) && !issoviet) || (Polymorph_control && !issoviet && !rn2(3)) || ((Fast || Very_fast) && !issoviet && !rn2(3)) || (StrongFast && !issoviet && !rn2(3)) || (otmp->blessed && !issoviet && !rn2(2)) || (StrongPolymorph_control && !issoviet && !rn2(3)) || (youmonst.data->msize == MZ_HUGE && !issoviet && rn2(3)) || (youmonst.data->msize > MZ_HUGE && !issoviet && rn2(2)) ) {
1332 if (!otmp->cursed) {
1334 You("remove your %s before you transform.",
1335 cloak_simple_name(otmp));
1336 (void) Cloak_off();
1337 dropx(otmp);
1340 } else {
1341 if (!issoviet) Your("%s tears apart!", cloak_simple_name(otmp));
1342 else pline("I yeshche odin glupyy veshch' kusayet pyl'! Sovetskaya khochet etu igru, chtoby sosat' kak mozhno bol'she!");
1343 (void) Cloak_off();
1344 u.cnd_polybreak++;
1345 useup(otmp);
1348 if (!shirtkeep && (otmp = uarmu) != 0) {
1350 if(otmp->oartifact || facelesskeep || (uarmf && uarmf->oartifact == ART_MALENA_S_LADYNESS) || (otmp->fakeartifact && rn2(2)) ) {
1351 Your("shirt falls off!");
1352 setworn((struct obj *)0, otmp->owornmask & W_ARMU);
1353 dropx(otmp);
1354 } else if ((controlled_change) || (youmonst.data->msize == MZ_MEDIUM && !issoviet && rn2(20)) || (youmonst.data->msize == MZ_LARGE && !issoviet && rn2(5)) || (itemsurvivedestruction(otmp, 8) && !issoviet) || (Polymorph_control && !issoviet && !rn2(3)) || ((Fast || Very_fast) && !issoviet && !rn2(3)) || (StrongFast && !issoviet && !rn2(3)) || (otmp->blessed && !issoviet && !rn2(2)) || (StrongPolymorph_control && !issoviet && !rn2(3)) || (youmonst.data->msize == MZ_HUGE && !issoviet && rn2(3)) || (youmonst.data->msize > MZ_HUGE && !issoviet && rn2(2)) ) {
1356 if (!otmp->cursed) {
1358 You("take off your shirt just before it starts to rip.");
1359 setworn((struct obj *)0, otmp->owornmask & W_ARMU);
1360 dropx(otmp);
1363 } else {
1364 if (!issoviet) Your("shirt rips to shreds!");
1365 else pline("I yeshche odin glupyy veshch' kusayet pyl'! Sovetskaya khochet etu igru, chtoby sosat' kak mozhno bol'she!");
1366 u.cnd_polybreak++;
1367 useup(uarmu);
1370 } else if (sliparm(youmonst.data) && !(uarm && uarm->oartifact == ART_GRADIATING_WORK) && !(uarm && uarm->otyp == OSFA_CHAIN_MAIL) && !(uarm && uarm->oartifact == ART_WRONG_TURN) && !Race_if(PM_TRANSFORMER) ) {
1371 if (((otmp = uarm) != 0) && !armorkeep && (racial_exception(&youmonst, otmp) < 1)) {
1372 if (donning(otmp)) cancel_don();
1373 Your("armor falls around you!");
1374 (void) Armor_gone();
1375 dropx(otmp);
1377 if (((otmp = uarmc) != 0) && !(uarmc && itemhasappearance(uarmc, APP_OSFA_CLOAK)) && !cloakkeep) {
1378 if (is_whirly(youmonst.data))
1379 Your("%s falls, unsupported!", cloak_simple_name(otmp));
1380 else You("shrink out of your %s!", cloak_simple_name(otmp));
1381 (void) Cloak_off();
1382 dropx(otmp);
1384 if (((otmp = uarmu) != 0) && !shirtkeep) {
1385 if (is_whirly(youmonst.data))
1386 You("seep right through your shirt!");
1387 else You("become much too small for your shirt!");
1388 setworn((struct obj *)0, otmp->owornmask & W_ARMU);
1389 dropx(otmp);
1392 if (has_horns(youmonst.data) && !Race_if(PM_TRANSFORMER) ) {
1393 if (((otmp = uarmh) != 0) && !uarmh->stckcurse) {
1394 if (is_flimsy(otmp) && !donning(otmp)) {
1395 char hornbuf[BUFSZ], yourbuf[BUFSZ];
1397 /* Future possiblities: This could damage/destroy helmet */
1398 sprintf(hornbuf, "horn%s", plur(num_horns(youmonst.data)));
1399 Your("%s %s through %s %s.", hornbuf, vtense(hornbuf, "pierce"),
1400 shk_your(yourbuf, otmp), xname(otmp));
1401 } else {
1402 if (donning(otmp)) cancel_don();
1403 Your("helmet falls to the %s!", surface(u.ux, u.uy));
1404 (void) Helmet_off();
1405 dropx(otmp);
1409 if ((otmp = uarmh) != 0 && !uarmh->stckcurse && !Race_if(PM_TRANSFORMER) && (is_mind_flayer(youmonst.data))) {
1410 if (!otmp->cursed || facelesskeep) {
1411 pline_The("%s is pushed from your head by your tentacles.", xname(otmp));
1412 (void) Helmet_off();
1413 } else if (otmp->oartifact || (otmp->fakeartifact && rn2(2)) || (controlled_change) || (itemsurvivedestruction(otmp, 8) && !issoviet) || (Polymorph_control && !issoviet && !rn2(3)) || ((Fast || Very_fast) && !issoviet && !rn2(3)) || (StrongFast && !issoviet && !rn2(3)) || (otmp->blessed && !issoviet && !rn2(2)) || (StrongPolymorph_control && !issoviet && !rn2(3)) ) {
1414 pline_The("%s is pushed from your head by your tentacles.", xname(otmp));
1415 (void) Helmet_off();
1416 } else if (!(uarmf && uarmf->oartifact == ART_MALENA_S_LADYNESS)) {
1417 Your("tentacles break through %s.", the(xname(otmp)));
1418 useup(uarmh);
1419 u.cnd_polybreak++;
1422 if (!Race_if(PM_TRANSFORMER) && (nohands(youmonst.data) || verysmall(youmonst.data))) {
1424 if (uarmg && !Race_if(PM_TRANSFORMER) && (rnd(100) < controllingchance)) {
1426 getlin ("Keep your gloves on? [y/yes/no]",buf);
1427 (void) lcase (buf);
1428 if (!(strcmp (buf, "yes")) || !(strcmp (buf, "y")) || !(strcmp (buf, "ye")) || !(strcmp (buf, "ys"))) goto glovesdone;
1432 /* It was really retarded that you would also drop the weapon, because drop_weapon() is already called
1433 someplace else and this was interfering with the "chance to keep stuff on" code. --Amy */
1434 if ((otmp = uarmg) != 0 && !uarmg->stckcurse) {
1435 if (donning(otmp)) cancel_don();
1436 You("drop your gloves!");
1437 (void) Gloves_off();
1438 dropx(otmp);
1440 glovesdone:
1442 if (uarms && !Race_if(PM_TRANSFORMER) && (rnd(100) < controllingchance)) {
1444 getlin ("Keep your shield on? [y/yes/no]",buf);
1445 (void) lcase (buf);
1446 if (!(strcmp (buf, "yes")) || !(strcmp (buf, "y")) || !(strcmp (buf, "ye")) || !(strcmp (buf, "ys"))) goto shielddone;
1450 if ((otmp = uarms) != 0 && !(uarms && uarms->oartifact == ART_CASTLE_CRUSH_GLITCH) && !uarms->stckcurse) {
1451 You("can no longer hold your shield!");
1452 (void) Shield_off();
1453 dropx(otmp);
1455 shielddone:
1457 if (uarmh && !Race_if(PM_TRANSFORMER) && (rnd(100) < controllingchance)) {
1459 getlin ("Keep your helmet on? [y/yes/no]",buf);
1460 (void) lcase (buf);
1461 if (!(strcmp (buf, "yes")) || !(strcmp (buf, "y")) || !(strcmp (buf, "ye")) || !(strcmp (buf, "ys"))) goto helmetdone;
1465 if ((otmp = uarmh) != 0 && !uarmh->stckcurse) {
1466 if (donning(otmp)) cancel_don();
1467 Your("helmet falls to the %s!", surface(u.ux, u.uy));
1468 (void) Helmet_off();
1469 dropx(otmp);
1472 helmetdone:
1473 if (!Race_if(PM_TRANSFORMER) && (nohands(youmonst.data) || verysmall(youmonst.data) ||
1474 slithy(youmonst.data) || youmonst.data->mlet == S_CENTAUR)) {
1476 if (uarmf && !Race_if(PM_TRANSFORMER) && (rnd(100) < controllingchance)) {
1478 getlin ("Keep your boots on? [y/yes/no]",buf);
1479 (void) lcase (buf);
1480 if (!(strcmp (buf, "yes")) || !(strcmp (buf, "y")) || !(strcmp (buf, "ye")) || !(strcmp (buf, "ys"))) goto bootsdone;
1484 if ((otmp = uarmf) != 0 && !(uarmf && uarmf->oartifact == ART_MALENA_S_LADYNESS) && !uarmf->stckcurse) {
1485 if (donning(otmp)) cancel_don();
1486 if (is_whirly(youmonst.data))
1487 Your("boots fall away!");
1488 else Your("boots %s off your feet!",
1489 verysmall(youmonst.data) ? "slide" : "are pushed");
1490 (void) Boots_off();
1491 dropx(otmp);
1493 bootsdone:
1498 STATIC_OVL void
1499 drop_weapon(alone)
1500 int alone;
1502 struct obj *otmp;
1503 struct obj *otmp2;
1505 char buf[BUFSZ];
1507 int controllingchance = 0;
1509 if (!(PlayerCannotUseSkills)) {
1510 switch (P_SKILL(P_POLYMORPHING)) {
1512 case P_BASIC: controllingchance = 1; break;
1513 case P_SKILLED: controllingchance = 2; break;
1514 case P_EXPERT: controllingchance = 3; break;
1515 case P_MASTER: controllingchance = 4; break;
1516 case P_GRAND_MASTER: controllingchance = 5; break;
1517 case P_SUPREME_MASTER: controllingchance = 6; break;
1518 default: controllingchance = 0; break;
1521 if (hugemonst(youmonst.data)) controllingchance *= 5;
1522 else if (verysmall(youmonst.data) || (youmonst.data->msize >= MZ_HUGE)) {
1523 controllingchance *= 15;
1524 controllingchance /= 2;
1526 else controllingchance *= 10;
1530 if ((otmp = uwep) != 0 && !uwep->stckcurse) {
1531 /* !alone check below is currently superfluous but in the
1532 * future it might not be so if there are monsters which cannot
1533 * wear gloves but can wield weapons
1535 if (!Race_if(PM_TRANSFORMER) && !autismweaponcheck(ART_FLAGELLATOR) && (!alone || cantwield(youmonst.data))) {
1536 struct obj *wep = uwep;
1538 if (alone) You("find you must drop your weapon%s!",
1539 u.twoweap ? "s" : "");
1540 otmp2 = u.twoweap ? uswapwep : 0;
1542 if (uwep && !Race_if(PM_TRANSFORMER) && (rnd(100) < controllingchance)) {
1544 getlin ("Keep wielding your weapon? [y/yes/no]",buf);
1545 (void) lcase (buf);
1546 if (!(strcmp (buf, "yes")) || !(strcmp (buf, "y")) || !(strcmp (buf, "ye")) || !(strcmp (buf, "ys"))) goto weapondone;
1549 uwepgone();
1551 if (canletgo(otmp, "poly-drop"))
1552 dropx(otmp);
1554 weapondone:
1556 if (otmp2 != 0) {
1557 uswapwepgone();
1558 if (canletgo(otmp2, "poly-drop"))
1559 dropx(otmp2);
1561 untwoweapon();
1562 } else if (!could_twoweap(youmonst.data)) {
1563 untwoweapon();
1565 } else if (cantwield(youmonst.data))
1566 untwoweapon();
1569 void
1570 rehumanize()
1572 boolean forced = (u.mh < 1);
1574 /* KMH, balance patch -- you can't revert back while unchanging */
1575 if (Unchanging && forced) {
1576 u.youaredead = 1;
1577 killer_format = NO_KILLER_PREFIX;
1578 killer = "killed while stuck in creature form";
1579 done(DIED);
1580 u.youaredead = 0;
1583 if (Race_if(PM_MISSINGNO)) {
1584 reinitmissingno();
1585 init_uasmon();
1588 if (emits_light(youmonst.data))
1589 del_light_source(LS_MONSTER, (void *)&youmonst);
1590 polyman("return to %s form!", urace.adj);
1591 u.polyformed = 0;
1593 u.ughmemory = 0;
1595 if (u.uhp < 1) {
1596 char kbuf[256];
1598 u.youaredead = 1;
1599 sprintf(kbuf, "reverting to unhealthy %s form", urace.adj);
1600 killer_format = KILLED_BY;
1601 killer = kbuf;
1602 done(DIED);
1603 u.youaredead = 0;
1606 if (forced || /*(!Race_if(PM_DOPPELGANGER) && */(rn2(20) > ACURR(A_CON)))/*)*/ {
1607 /* Exhaustion for "forced" rehumaization & must pass con chack for
1608 * non-doppelgangers
1609 * Don't penalize doppelgangers/polymorph running out */
1610 /* Amy edit - why give so many boosts to the already overpowered doppelgangers??? */
1612 /* WAC Polymorph Exhaustion 1/2 HP to prevent abuse */
1613 u.uhp = (u.uhp/2) + 1;
1616 /* SLASH'EM illogically made it so that whenever you unpolymorph, regardless of HOW, you get a massive penalty
1617 * by having your maximum hit points drained fiercely. But this is SLEX, a game that's supposed to be balanced,
1618 * so we only give that penalty if you're wimpy enough to allow your polymorphed HP to run out --Amy */
1620 /* In Soviet Russia, polymorphing is strictly forbidden. Everyone has to appear as what they actually are, because
1621 * otherwise they could be foreign agents trying to undermine the Kreml's supremacy. So the government troops will
1622 * do their best to punish anyone who's spotted polymorphing back to human form. */
1624 if (forced || issoviet) {
1625 int hitpointloss = rnd(10);
1626 if (hitpointloss > u.ulevel) hitpointloss = u.ulevel;
1628 if (u.uhpmax > hitpointloss) {
1629 u.uhpmax -= hitpointloss;
1630 if (u.uhp > u.uhpmax) u.uhp = u.uhpmax;
1631 if (issoviet) pline("Kha-kha-kha! Dumayesh', ty mog by byt' chlenom vooruzhennykh sil sosedney strany nezametno dlya nas?");
1632 else You("lost %d maximum hit points due to exhaustion.", hitpointloss);
1633 } else {
1634 u.youaredead = 1;
1635 You("had too little health left in your regular form and therefore you die!");
1636 killer_format = KILLED_BY;
1637 killer = "critical polymorph failure";
1638 done(DIED);
1639 u.youaredead = 0;
1643 if (!uarmg || FingerlessGloves) selftouch("No longer petrify-resistant, you");
1644 nomul(0, 0, FALSE);
1646 flags.botl = 1;
1647 vision_full_recalc = 1;
1648 (void) encumber_msg();
1652 /* WAC -- MUHAHAHAAHA - Gaze attacks!
1653 * Note - you can only gaze at one monster at a time, to keep this
1654 * from getting out of hand ;B Also costs 20 energy.
1655 * Amy edit: costs scale with level of your current form, since some gazes can be quite unbalanced...
1658 dogaze()
1660 coord cc;
1661 struct monst *mtmp;
1662 int gazecost = 24;
1663 int squeakamount = 0;
1664 gazecost += (Upolyd ? (mons[u.umonnum].mlevel * 4) : (u.ulevel * 4));
1666 if (!attacktype_fordmg(youmonst.data, AT_GAZE, AD_ANY)) {
1667 gazecost = 24;
1668 gazecost += (1 + mons[u.usymbiote.mnum].mlevel * 4);
1671 squeakamount = gazecost;
1672 /* we can now reduce the cost based on the player's squeaking skill --Amy */
1673 if (!PlayerCannotUseSkills && gazecost > 2) {
1674 switch (P_SKILL(P_SQUEAKING)) {
1675 case P_BASIC: gazecost *= 9; gazecost /= 10; break;
1676 case P_SKILLED: gazecost *= 8; gazecost /= 10; break;
1677 case P_EXPERT: gazecost *= 7; gazecost /= 10; break;
1678 case P_MASTER: gazecost *= 6; gazecost /= 10; break;
1679 case P_GRAND_MASTER: gazecost *= 5; gazecost /= 10; break;
1680 case P_SUPREME_MASTER: gazecost *= 4; gazecost /= 10; break;
1681 default: break;
1685 if (Blind) {
1686 You("can't see a thing!");
1687 if (flags.moreforced && !MessagesSuppressed) display_nhwindow(WIN_MESSAGE, TRUE); /* --More-- */
1688 return(0);
1690 if (u.uen < gazecost) {
1691 You("lack the energy to use your special gaze! Your current form's gaze attack costs %d mana!", gazecost);
1692 if (flags.moreforced && !MessagesSuppressed) display_nhwindow(WIN_MESSAGE, TRUE); /* --More-- */
1693 return(0);
1695 pline("Where do you wish to look?");
1696 cc.x = u.ux;
1697 cc.y = u.uy;
1698 getpos(&cc, TRUE, "the spot to look");
1700 if (cc.x == -10) return (0); /* user pressed esc */
1702 mtmp = m_at(cc.x, cc.y);
1704 if (!mtmp || !canseemon(mtmp)) {
1705 You("don't see a monster there!");
1706 return (0);
1710 if ((flags.safe_dog && !Confusion && !Hallucination
1711 && mtmp->mtame) || (flags.confirm && mtmp->mpeaceful
1712 && !Confusion && !Hallucination)) {
1713 char qbuf[QBUFSZ];
1715 sprintf(qbuf, "Really gaze at %s?", mon_nam(mtmp));
1716 if (yn(qbuf) != 'y') return (0);
1719 /* WUOT why the hell did they not become hostile if you were e.g. confused??? */
1720 if (mtmp->mpeaceful) setmangry(mtmp);
1722 u.uen -= gazecost;
1724 You("gaze at %s...", mon_nam(mtmp));
1726 if (practicantterror) {
1727 pline("%s booms: 'Don't look at other people like that. Now you have to pay a fine of 200 zorkmids and vow to not do it again.'", noroelaname());
1728 fineforpracticant(200, 0, 0);
1731 ranged_thorns(mtmp);
1733 while (squeakamount > 20) {
1734 use_skill(P_SQUEAKING, 1);
1735 squeakamount -= 20;
1737 use_skill(P_SQUEAKING, 1);
1739 if ((mtmp->data==&mons[PM_MEDUSA]) && !mtmp->mcan && (!Stone_resistance || (!IntStone_resistance && !rn2(20)) )) {
1740 pline("Gazing at the awake Medusa is not a very good idea.");
1741 /* as if gazing at a sleeping anything is fruitful... */
1742 /*You("turn to stone...");
1743 killer_format = KILLED_BY;
1744 killer = "deliberately gazing at Medusa's hideous countenance";
1745 done(STONING);*/
1746 You("start turning to stone...");
1747 if (!Stoned) {
1748 if (Hallucination && rn2(10)) pline("But you are already stoned.");
1749 else {
1750 Stoned = Race_if(PM_EROSATOR) ? 3 : 7;
1751 u.cnd_stoningcount++;
1752 delayed_killer = "gazing at Medusa";
1755 } else if (!mtmp->mcansee || mtmp->msleeping) {
1756 pline("But nothing happens.");
1757 return (1);
1758 } else if (Invis && !perceives(mtmp->data)) {
1759 pline("%s seems not to notice your gaze.", Monnam(mtmp));
1760 return (1);
1761 } else {
1762 register struct attack *mattk;
1763 register int i;
1765 for(i = 0; i < NATTK; i++) {
1766 mattk = &(youmonst.data->mattk[i]);
1767 if (mattk->aatyp == AT_GAZE) {
1768 damageum(mtmp, mattk);
1769 break;
1774 for(i = 0; i < NATTK; i++) {
1775 if (uactivesymbiosis && !PlayerCannotUseSkills && P_SKILL(P_SYMBIOSIS) >= P_SKILLED) {
1776 mattk = &(mons[u.usymbiote.mnum].mattk[i]);
1777 if (mattk->aatyp == AT_GAZE) {
1778 damageum(mtmp, mattk);
1779 break;
1785 return(1);
1789 dobreathe()
1791 struct attack *mattk;
1792 int energy = 0;
1793 int squeakamount = 0;
1795 if (Strangled) {
1796 You_cant("breathe. Sorry.");
1797 if (flags.moreforced && !MessagesSuppressed) display_nhwindow(WIN_MESSAGE, TRUE); /* --More-- */
1798 return(0);
1801 /* WAC -- no more belching. Use up energy instead */
1802 if (Race_if(PM_DOPPELGANGER) || Role_if(PM_SHAPESHIFTER) || Race_if(PM_HEMI_DOPPELGANGER)
1803 || (Role_if(PM_FLAME_MAGE) && u.umonnum == PM_RED_DRAGON)
1804 || (Role_if(PM_ACID_MAGE) && u.umonnum == PM_YELLOW_DRAGON)
1805 || (Role_if(PM_ELECTRIC_MAGE) && u.umonnum == PM_BLUE_DRAGON)
1806 || (Role_if(PM_POISON_MAGE) && u.umonnum == PM_GREEN_DRAGON)
1807 || (Role_if(PM_ICE_MAGE) && u.umonnum == PM_WHITE_DRAGON))
1808 energy = 15;
1809 else
1810 energy = 20; /* a bit more expensive --Amy */
1812 /* and make instakill breath attacks even more expensive to tone down abuse potential */
1813 mattk = attacktype_fordmg(youmonst.data, AT_BREA, AD_ANY);
1814 if (!mattk && uactivesymbiosis && !PlayerCannotUseSkills && P_SKILL(P_SYMBIOSIS) >= P_EXPERT) mattk = attacktype_fordmg(&mons[u.usymbiote.mnum], AT_BREA, AD_ANY);
1815 if (!mattk) {
1816 impossible("bad breath attack?"); /* mouthwash needed... */
1817 return(0); /* prevent you from using segfault breath --Amy */
1820 if ((mattk->adtyp != AD_MAGM) && (mattk->adtyp != AD_RBRE) && (mattk->adtyp != AD_FIRE) && (mattk->adtyp != AD_COLD) && (mattk->adtyp != AD_SLEE) && (mattk->adtyp != AD_DISN) && (mattk->adtyp != AD_ELEC) && (mattk->adtyp != AD_DRST) && (mattk->adtyp != AD_ACID) && (mattk->adtyp != AD_LITE) && (mattk->adtyp != AD_SPC2) ) energy = 30;
1822 if (mattk->adtyp == AD_DISN) energy = u.breathenhancetimer ? 66 : 100;
1823 else if (mattk->adtyp == AD_RBRE) energy = u.breathenhancetimer ? 20 : 30; /* can randomly be a disintegration beam */
1825 if (Race_if(PM_PLAYER_CERBERUS) && !Upolyd) energy *= 3;
1827 squeakamount = energy;
1828 /* squeaking skill can reduce the required amount; reduce it after setting up the variable for skill training */
1829 if (!PlayerCannotUseSkills && energy > 2) {
1830 switch (P_SKILL(P_SQUEAKING)) {
1831 case P_BASIC: energy *= 9; energy /= 10; break;
1832 case P_SKILLED: energy *= 8; energy /= 10; break;
1833 case P_EXPERT: energy *= 7; energy /= 10; break;
1834 case P_MASTER: energy *= 6; energy /= 10; break;
1835 case P_GRAND_MASTER: energy *= 5; energy /= 10; break;
1836 case P_SUPREME_MASTER: energy *= 4; energy /= 10; break;
1837 default: break;
1841 if (u.uen < energy) {
1842 You("don't have enough energy to breathe! You need at least %d mana!",energy);
1843 if (flags.moreforced && !MessagesSuppressed) display_nhwindow(WIN_MESSAGE, TRUE); /* --More-- */
1844 return(0);
1847 if (!getdir((char *)0)) return(0);
1849 u.uen -= energy;
1850 flags.botl = 1;
1852 mattk = attacktype_fordmg(youmonst.data, AT_BREA, AD_ANY);
1853 if (!mattk && uactivesymbiosis && !PlayerCannotUseSkills && P_SKILL(P_SYMBIOSIS) >= P_EXPERT) mattk = attacktype_fordmg(&mons[u.usymbiote.mnum], AT_BREA, AD_ANY);
1854 if (!mattk)
1855 impossible("bad breath attack?"); /* mouthwash needed... */
1856 else {
1857 /* Extra handling for AD_RBRE - player might poly into a crystal
1858 * golem. */
1859 uchar adtyp;
1860 adtyp = mattk->adtyp == AD_RBRE ? rnd(AD_SPC2) : mattk->adtyp;
1862 if ((mattk->adtyp != AD_MAGM) && (mattk->adtyp != AD_RBRE) && (mattk->adtyp != AD_FIRE) && (mattk->adtyp != AD_COLD) && (mattk->adtyp != AD_SLEE) && (mattk->adtyp != AD_DISN) && (mattk->adtyp != AD_ELEC) && (mattk->adtyp != AD_DRST) && (mattk->adtyp != AD_ACID) && (mattk->adtyp != AD_LITE) && (mattk->adtyp != AD_SPC2) ) adtyp = rnd(AD_SPC2);
1864 if (u.breathenhancetimer) {
1865 buzz((int) (20 + adtyp - 1), (rn2(2) ? ((int)mattk->damn * 3 / 2) : ((int)mattk->damd * 3 / 2) ), u.ux, u.uy, u.dx, u.dy);
1867 } else {
1868 buzz((int) (20 + adtyp - 1), (rn2(2) ? (int)mattk->damn : (int)mattk->damd ), u.ux, u.uy, u.dx, u.dy);
1872 if (Race_if(PM_PLAYER_CERBERUS) && !Upolyd) { /* breath three times for 3x the cost --Amy */
1873 if (u.breathenhancetimer) {
1874 buzz((int) (20 + adtyp - 1), (rn2(2) ? ((int)mattk->damn * 3 / 2) : ((int)mattk->damd * 3 / 2) ), u.ux, u.uy, u.dx, u.dy);
1875 } else {
1876 buzz((int) (20 + adtyp - 1), (rn2(2) ? (int)mattk->damn : (int)mattk->damd ), u.ux, u.uy, u.dx, u.dy);
1879 if (u.breathenhancetimer) {
1880 buzz((int) (20 + adtyp - 1), (rn2(2) ? ((int)mattk->damn * 3 / 2) : ((int)mattk->damd * 3 / 2) ), u.ux, u.uy, u.dx, u.dy);
1881 } else {
1882 buzz((int) (20 + adtyp - 1), (rn2(2) ? (int)mattk->damn : (int)mattk->damd ), u.ux, u.uy, u.dx, u.dy);
1887 while (squeakamount > 20) {
1888 use_skill(P_SQUEAKING, 1);
1889 squeakamount -= 20;
1891 use_skill(P_SQUEAKING, 1);
1892 return(1);
1896 dospit()
1898 struct obj *otmp;
1899 struct attack *mattk;
1900 int spitcost = 10;
1901 int squeakamount = 0;
1903 mattk = attacktype_fordmg(youmonst.data, AT_SPIT, AD_ANY);
1904 if (!mattk && uactivesymbiosis && !PlayerCannotUseSkills && P_SKILL(P_SYMBIOSIS) >= P_BASIC) mattk = attacktype_fordmg(&mons[u.usymbiote.mnum], AT_SPIT, AD_ANY);
1906 if (mattk && mattk->adtyp == AD_TCKL) spitcost = 30;
1907 if (mattk && mattk->adtyp == AD_DRLI) spitcost = 50;
1909 squeakamount = spitcost;
1911 if (!PlayerCannotUseSkills) {
1912 switch (P_SKILL(P_SQUEAKING)) {
1913 case P_BASIC: spitcost *= 9; spitcost /= 10; break;
1914 case P_SKILLED: spitcost *= 8; spitcost /= 10; break;
1915 case P_EXPERT: spitcost *= 7; spitcost /= 10; break;
1916 case P_MASTER: spitcost *= 6; spitcost /= 10; break;
1917 case P_GRAND_MASTER: spitcost *= 5; spitcost /= 10; break;
1918 case P_SUPREME_MASTER: spitcost *= 4; spitcost /= 10; break;
1919 default: break;
1922 if (spitcost < 3) spitcost = 3; /* fail safe */
1924 if (u.uen < spitcost) {
1925 You("lack the energy to spit - need at least %d mana!", spitcost);
1926 if (flags.moreforced && !MessagesSuppressed) display_nhwindow(WIN_MESSAGE, TRUE); /* --More-- */
1927 return(0);
1930 if (!getdir((char *)0)) return(0);
1932 u.uen -= spitcost;
1934 if (!mattk)
1935 impossible("bad spit attack?");
1936 else {
1937 switch (mattk->adtyp) {
1938 case AD_BLND:
1939 case AD_DRST:
1940 otmp = mksobj(BLINDING_VENOM, TRUE, FALSE, FALSE);
1941 break;
1942 case AD_DRLI:
1943 otmp = mksobj(FAERIE_FLOSS_RHING, TRUE, FALSE, FALSE);
1944 break;
1945 case AD_TCKL:
1946 otmp = mksobj(TAIL_SPIKES, TRUE, FALSE, FALSE);
1947 break;
1948 case AD_NAST:
1949 otmp = mksobj(SEGFAULT_VENOM, TRUE, FALSE, FALSE);
1950 break;
1951 default:
1952 pline("bad attack type in do_spit");
1953 /* fall through */
1954 case AD_ACID:
1955 otmp = mksobj(ACID_VENOM, TRUE, FALSE, FALSE);
1956 break;
1958 if (!otmp) return(0);
1959 otmp->quan = 1;
1960 otmp->owt = weight(otmp);
1961 /*otmp->spe = 1;*/ /* to indicate it's yours */
1962 throwit(otmp, 0L, FALSE, 0);
1964 while (squeakamount > 20) {
1965 use_skill(P_SQUEAKING, 1);
1966 squeakamount -= 20;
1968 use_skill(P_SQUEAKING, 1);
1969 return(1);
1973 doremove()
1975 if (!Punished) {
1976 You("are not chained to anything!");
1977 return(0);
1979 unpunish();
1980 return(1);
1984 dospinweb()
1986 register struct trap *ttmp = t_at(u.ux,u.uy);
1988 if (Levitation || Is_airlevel(&u.uz)
1989 || Underwater || Is_waterlevel(&u.uz)) {
1990 You("must be on the ground to spin a web.");
1991 return(0);
1993 if (u.uswallow) {
1994 You("release web fluid inside %s.", mon_nam(u.ustuck));
1995 if (is_animal(u.ustuck->data)) {
1996 expels(u.ustuck, u.ustuck->data, TRUE);
1997 return(0);
1999 if (is_whirly(u.ustuck->data)) {
2000 int i;
2002 for (i = 0; i < NATTK; i++)
2003 if (u.ustuck->data->mattk[i].aatyp == AT_ENGL)
2004 break;
2005 if (i == NATTK)
2006 impossible("Swallower has no engulfing attack?");
2007 else {
2008 char sweep[30];
2010 sweep[0] = '\0';
2011 switch(u.ustuck->data->mattk[i].adtyp) {
2012 case AD_FIRE:
2013 strcpy(sweep, "ignites and ");
2014 break;
2015 case AD_ELEC:
2016 strcpy(sweep, "fries and ");
2017 break;
2018 case AD_COLD:
2019 strcpy(sweep,
2020 "freezes, shatters and ");
2021 break;
2023 pline_The("web %sis swept away!", sweep);
2025 return(0);
2026 } /* default: a nasty jelly-like creature */
2027 pline_The("web dissolves into %s.", mon_nam(u.ustuck));
2028 return(0);
2030 if (u.utrap) {
2031 You("cannot spin webs while stuck in a trap.");
2032 return(0);
2034 exercise(A_DEX, TRUE);
2035 if (ttmp) switch (ttmp->ttyp) {
2036 case S_PRESSING_TRAP:
2037 You("enclose the s-pressing trap in a web.");
2038 deltrap(ttmp);
2039 newsym(u.ux, u.uy);
2040 return(1);
2041 case PIT:
2042 case SHIT_PIT:
2043 case MANA_PIT:
2044 case ANOXIC_PIT:
2045 case HYPOXIC_PIT:
2046 case ACID_PIT:
2047 case SPIKED_PIT: You("spin a web, covering up the pit.");
2048 deltrap(ttmp);
2049 bury_objs(u.ux, u.uy);
2050 newsym(u.ux, u.uy);
2051 return(1);
2052 case SQKY_BOARD: pline_The("squeaky board is muffled.");
2053 deltrap(ttmp);
2054 newsym(u.ux, u.uy);
2055 return(1);
2056 case TELEP_TRAP:
2057 case BEAMER_TRAP:
2058 case LEVEL_TELEP:
2059 case PHASEPORTER:
2060 case PHASE_BEAMER:
2061 case LEVEL_BEAMER:
2062 case NEXUS_TRAP:
2063 case MAGIC_PORTAL:
2064 Your("webbing vanishes!");
2065 return(0);
2066 case WEB: You("make the web thicker.");
2067 return(1);
2068 case HOLE:
2069 case TRAPDOOR:
2070 case SHAFT_TRAP:
2071 case CURRENT_SHAFT:
2072 You("web over the %s.",
2073 (ttmp->ttyp == TRAPDOOR) ? "trap door" : "hole");
2074 deltrap(ttmp);
2075 newsym(u.ux, u.uy);
2076 return 1;
2077 case ROLLING_BOULDER_TRAP:
2078 You("spin a web, jamming the trigger.");
2079 deltrap(ttmp);
2080 newsym(u.ux, u.uy);
2081 return(1);
2082 case ARROW_TRAP:
2083 case DART_TRAP:
2084 case BEAR_TRAP:
2085 case ROCKTRAP:
2086 case FIRE_TRAP:
2087 case ICE_TRAP:
2088 case SPEAR_TRAP:
2089 case MAGIC_BEAM_TRAP:
2090 case COLLAPSE_TRAP:
2091 case SHIT_TRAP:
2092 case ANIMATION_TRAP:
2093 case GLYPH_OF_WARDING:
2094 case LANDMINE:
2095 case SLP_GAS_TRAP:
2096 case RUST_TRAP:
2097 case MAGIC_TRAP:
2098 case ANTI_MAGIC:
2099 case POLY_TRAP:
2100 case SCYTHING_BLADE:
2101 case BOLT_TRAP:
2102 case ACID_POOL:
2103 case WATER_POOL:
2104 case POISON_GAS_TRAP:
2105 case SLOW_GAS_TRAP:
2106 case SHOCK_TRAP:
2107 case HEEL_TRAP:
2108 case VULN_TRAP:
2109 case LAVA_TRAP:
2110 case FLOOD_TRAP:
2111 case DISINTEGRATION_TRAP:
2112 case DEATH_TRAP:
2113 case PESTILENCE_TRAP:
2114 case FAMINE_TRAP:
2115 case DRAIN_TRAP:
2116 case ITEM_TELEP_TRAP:
2117 case GRAVITY_TRAP:
2118 case STONE_TO_FLESH_TRAP:
2119 case QUICKSAND_TRAP:
2120 case RELOCATION_TRAP:
2122 case NEST_TRAP:
2123 case BULLET_TRAP:
2124 case PARALYSIS_TRAP:
2125 case CYANIDE_TRAP:
2126 case LASER_TRAP:
2127 case GIANT_CHASM:
2128 case FART_TRAP:
2129 case CONFUSE_TRAP:
2130 case STUN_TRAP:
2131 case HALLUCINATION_TRAP:
2132 case PETRIFICATION_TRAP:
2133 case NUMBNESS_TRAP:
2134 case FREEZING_TRAP:
2135 case BURNING_TRAP:
2136 case FEAR_TRAP:
2137 case BLINDNESS_TRAP:
2138 case GLIB_TRAP:
2139 case SLIME_TRAP:
2140 case INERTIA_TRAP:
2141 case TIME_TRAP:
2142 case LYCANTHROPY_TRAP:
2143 case UNLIGHT_TRAP:
2144 case ELEMENTAL_TRAP:
2145 case ESCALATING_TRAP:
2146 case NEGATIVE_TRAP:
2147 case MANA_TRAP:
2148 case SIN_TRAP:
2149 case DESTROY_ARMOR_TRAP:
2150 case DIVINE_ANGER_TRAP:
2151 case GENETIC_TRAP:
2152 case MISSINGNO_TRAP:
2153 case CANCELLATION_TRAP:
2154 case HOSTILITY_TRAP:
2155 case BOSS_TRAP:
2156 case WISHING_TRAP:
2157 case FALLING_BOULDER_TRAP:
2158 case GLASS_ARROW_TRAP:
2159 case GLASS_BOLT_TRAP:
2160 case OUT_OF_MAGIC_TRAP:
2161 case PLASMA_TRAP:
2162 case BOMB_TRAP:
2163 case EARTHQUAKE_TRAP:
2164 case NOISE_TRAP:
2165 case GLUE_TRAP:
2166 case GUILLOTINE_TRAP:
2167 case BISECTION_TRAP:
2168 case VOLT_TRAP:
2169 case HORDE_TRAP:
2170 case IMMOBILITY_TRAP:
2171 case GREEN_GLYPH:
2172 case BLUE_GLYPH:
2173 case YELLOW_GLYPH:
2174 case ORANGE_GLYPH:
2175 case BLACK_GLYPH:
2176 case PURPLE_GLYPH:
2177 case FALLING_LOADSTONE_TRAP:
2178 case FALLING_NASTYSTONE_TRAP:
2179 case SUMMON_UNDEAD_TRAP:
2181 case SPINED_BALL_TRAP:
2182 case PENDULUM_TRAP:
2183 case TURN_TABLE:
2184 case SCENT_TRAP:
2185 case BANANA_TRAP:
2186 case FALLING_TUB_TRAP:
2187 case ALARM:
2188 case CALTROPS_TRAP:
2189 case BLADE_WIRE:
2190 case MAGNET_TRAP:
2191 case SLINGSHOT_TRAP:
2192 case CANNON_TRAP:
2193 case VENOM_SPRINKLER:
2194 case FUMAROLE:
2196 case LEG_TRAP:
2197 case ARTIFACT_JACKPOT_TRAP:
2198 case MAP_AMNESIA_TRAP:
2199 case SPREADING_TRAP:
2200 case ADJACENT_TRAP:
2201 case SUPERTHING_TRAP:
2202 case LEVITATION_TRAP:
2203 case BOWEL_CRAMPS_TRAP:
2204 case UNEQUIPPING_TRAP:
2205 case GOOD_ARTIFACT_TRAP:
2206 case GENDER_TRAP:
2207 case TRAP_OF_OPPOSITE_ALIGNMENT:
2208 case SINCOUNT_TRAP:
2209 case PET_TRAP:
2210 case PIERCING_BEAM_TRAP:
2211 case WRENCHING_TRAP:
2212 case TRACKER_TRAP:
2213 case NURSE_TRAP:
2214 case BACK_TO_START_TRAP:
2215 case NEMESIS_TRAP:
2216 case STREW_TRAP:
2217 case OUTTA_DEPTH_TRAP:
2218 case PUNISHMENT_TRAP:
2219 case BOON_TRAP:
2220 case FOUNTAIN_TRAP:
2221 case THRONE_TRAP:
2222 case ARABELLA_SPEAKER:
2223 case FEMMY_TRAP:
2224 case MADELEINE_TRAP:
2225 case MARLENA_TRAP:
2226 case SABRINA_TRAP:
2227 case TANJA_TRAP:
2228 case SONJA_TRAP:
2229 case RHEA_TRAP:
2230 case LARA_TRAP:
2231 case NADINE_TRAP:
2232 case LUISA_TRAP:
2233 case IRINA_TRAP:
2234 case LISELOTTE_TRAP:
2235 case GRETA_TRAP:
2236 case JANE_TRAP:
2237 case SUE_LYN_TRAP:
2238 case CHARLOTTE_TRAP:
2239 case HANNAH_TRAP:
2240 case LITTLE_MARIE_TRAP:
2241 case RUTH_TRAP:
2242 case MAGDALENA_TRAP:
2243 case MARLEEN_TRAP:
2244 case KLARA_TRAP:
2245 case FRIEDERIKE_TRAP:
2246 case NAOMI_TRAP:
2247 case UTE_TRAP:
2248 case JASIEEN_TRAP:
2249 case YASAMAN_TRAP:
2250 case MAY_BRITT_TRAP:
2251 case KSENIA_TRAP:
2252 case LYDIA_TRAP:
2253 case CONNY_TRAP:
2254 case KATIA_TRAP:
2255 case MARIYA_TRAP:
2256 case ELISE_TRAP:
2257 case RONJA_TRAP:
2258 case ARIANE_TRAP:
2259 case JOHANNA_TRAP:
2260 case INGE_TRAP:
2261 case ROSA_TRAP:
2262 case JANINA_TRAP:
2263 case KRISTIN_TRAP:
2264 case ANNA_TRAP:
2265 case RUEA_TRAP:
2266 case DORA_TRAP:
2267 case MARIKE_TRAP:
2268 case JETTE_TRAP:
2269 case INA_TRAP:
2270 case SING_TRAP:
2271 case VICTORIA_TRAP:
2272 case MELISSA_TRAP:
2273 case ANITA_TRAP:
2274 case HENRIETTA_TRAP:
2275 case VERENA_TRAP:
2276 case ARABELLA_TRAP:
2277 case NELLY_TRAP:
2278 case EVELINE_TRAP:
2279 case KARIN_TRAP:
2280 case JUEN_TRAP:
2281 case KRISTINA_TRAP:
2282 case ALMUT_TRAP:
2283 case JULIETTA_TRAP:
2284 case LOU_TRAP:
2285 case ANASTASIA_TRAP:
2286 case FILLER_TRAP:
2287 case TOXIC_VENOM_TRAP:
2288 case INSANITY_TRAP:
2289 case MADNESS_TRAP:
2290 case JESSICA_TRAP:
2291 case SOLVEJG_TRAP:
2292 case WENDY_TRAP:
2293 case KATHARINA_TRAP:
2294 case ELENA_TRAP:
2295 case THAI_TRAP:
2296 case ELIF_TRAP:
2297 case NADJA_TRAP:
2298 case SANDRA_TRAP:
2299 case NATALJE_TRAP:
2300 case JEANETTA_TRAP:
2301 case YVONNE_TRAP:
2302 case MAURAH_TRAP:
2303 case ANNEMARIE_TRAP:
2304 case JIL_TRAP:
2305 case JANA_TRAP:
2306 case KATRIN_TRAP:
2307 case GUDRUN_TRAP:
2308 case ELLA_TRAP:
2309 case MANUELA_TRAP:
2310 case JENNIFER_TRAP:
2311 case PATRICIA_TRAP:
2312 case ANTJE_TRAP:
2313 case ANTJE_TRAP_X:
2314 case KERSTIN_TRAP:
2315 case LAURA_TRAP:
2316 case LARISSA_TRAP:
2317 case NORA_TRAP:
2318 case NATALIA_TRAP:
2319 case SUSANNE_TRAP:
2320 case LISA_TRAP:
2321 case BRIDGHITTE_TRAP:
2322 case JULIA_TRAP:
2323 case NICOLE_TRAP:
2324 case RITA_TRAP:
2326 case ELEMENTAL_PORTAL:
2327 case GIRLINESS_TRAP:
2328 case FUMBLING_TRAP:
2329 case EGOMONSTER_TRAP:
2330 case FLOODING_TRAP:
2331 case MONSTER_CUBE:
2332 case CURSED_GRAVE:
2333 case DIMNESS_TRAP:
2334 case EVIL_ARTIFACT_TRAP:
2335 case RODNEY_TRAP:
2336 case CONTAMINATION_TRAP:
2338 case EVIL_HEEL_TRAP:
2339 case BAD_EQUIPMENT_TRAP:
2340 case TEMPOCONFLICT_TRAP:
2341 case TEMPOHUNGER_TRAP:
2342 case TELEPORTITIS_TRAP:
2343 case POLYMORPHITIS_TRAP:
2344 case PREMATURE_DEATH_TRAP:
2345 case LASTING_AMNESIA_TRAP:
2346 case RAGNAROK_TRAP:
2347 case SINGLE_DISENCHANT_TRAP:
2349 case SEVERE_DISENCHANT_TRAP:
2350 case PAIN_TRAP:
2351 case TECHCAP_TRAP:
2352 case TREMBLING_TRAP:
2353 case SPELL_MEMORY_TRAP:
2354 case SKILL_REDUCTION_TRAP:
2355 case SKILLCAP_TRAP:
2356 case PERMANENT_STAT_DAMAGE_TRAP:
2358 case HYBRID_TRAP:
2359 case SHAPECHANGE_TRAP:
2360 case MELTEM_TRAP:
2361 case MIGUC_TRAP:
2362 case DIRECTIVE_TRAP:
2363 case SATATUE_TRAP:
2364 case FARTING_WEB:
2365 case CATACLYSM_TRAP:
2366 case DATA_DELETE_TRAP:
2367 case ELDER_TENTACLING_TRAP:
2368 case FOOTERER_TRAP:
2370 case GRAVE_WALL_TRAP:
2371 case TUNNEL_TRAP:
2372 case FARMLAND_TRAP:
2373 case MOUNTAIN_TRAP:
2374 case WATER_TUNNEL_TRAP:
2375 case CRYSTAL_FLOOD_TRAP:
2376 case MOORLAND_TRAP:
2377 case URINE_TRAP:
2378 case SHIFTING_SAND_TRAP:
2379 case STYX_TRAP:
2380 case PENTAGRAM_TRAP:
2381 case SNOW_TRAP:
2382 case ASH_TRAP:
2383 case SAND_TRAP:
2384 case PAVEMENT_TRAP:
2385 case HIGHWAY_TRAP:
2386 case GRASSLAND_TRAP:
2387 case NETHER_MIST_TRAP:
2388 case STALACTITE_TRAP:
2389 case CRYPTFLOOR_TRAP:
2390 case BUBBLE_TRAP:
2391 case RAIN_CLOUD_TRAP:
2393 case ITEM_NASTIFICATION_TRAP:
2394 case SANITY_INCREASE_TRAP:
2395 case PSI_TRAP:
2396 case GAY_TRAP:
2398 case SARAH_TRAP:
2399 case CLAUDIA_TRAP:
2400 case LUDGERA_TRAP:
2401 case KATI_TRAP:
2403 case SKILL_MULTIPLY_TRAP:
2404 case TRAPWALK_TRAP:
2405 case CLUSTER_TRAP:
2406 case FIELD_TRAP:
2407 case MONICIDE_TRAP:
2408 case TRAP_CREATION_TRAP:
2409 case LEOLD_TRAP:
2410 case BURDEN_TRAP:
2411 case MAGIC_VACUUM_TRAP:
2412 case ANIMEBAND_TRAP:
2413 case PERFUME_TRAP:
2414 case COURT_TRAP:
2415 case ELDER_SCROLLS_TRAP:
2416 case JOKE_TRAP:
2417 case DUNGEON_LORDS_TRAP:
2418 case FORTYTWO_TRAP:
2419 case RANDOMIZE_TRAP:
2420 case EVILROOM_TRAP:
2421 case AOE_TRAP:
2422 case ELONA_TRAP:
2423 case RELIGION_TRAP:
2424 case STEAMBAND_TRAP:
2425 case HARDCORE_TRAP:
2426 case MACHINE_TRAP:
2427 case BEE_TRAP:
2428 case MIGO_TRAP:
2429 case ANGBAND_TRAP:
2430 case DNETHACK_TRAP:
2431 case EVIL_SPAWN_TRAP:
2432 case SHOE_TRAP:
2433 case INSIDE_TRAP:
2434 case DOOM_TRAP:
2435 case MILITARY_TRAP:
2436 case ILLUSION_TRAP:
2437 case DIABLO_TRAP:
2439 case WALL_TRAP:
2440 case MONSTER_GENERATOR:
2441 case POTION_DISPENSER:
2442 case SPACEWARS_SPAWN_TRAP:
2443 case TV_TROPES_TRAP:
2444 case SYMBIOTE_TRAP:
2445 case KILL_SYMBIOTE_TRAP:
2446 case SYMBIOTE_REPLACEMENT_TRAP:
2447 case SHUTDOWN_TRAP:
2448 case CORONA_TRAP:
2449 case UNPROOFING_TRAP:
2450 case VISIBILITY_TRAP:
2451 case FEMINISM_STONE_TRAP:
2452 case BRANCH_TELEPORTER:
2453 case BRANCH_BEAMER:
2454 case POISON_ARROW_TRAP:
2455 case POISON_BOLT_TRAP:
2456 case MACE_TRAP:
2457 case SHUEFT_TRAP:
2458 case MOTH_LARVAE_TRAP:
2459 case WORTHINESS_TRAP:
2460 case CONDUCT_TRAP:
2461 case STRIKETHROUGH_TRAP:
2462 case MULTIPLE_GATHER_TRAP:
2463 case VIVISECTION_TRAP:
2464 case INSTAFEMINISM_TRAP:
2466 case CALLING_OUT_TRAP:
2467 case FIELD_BREAK_TRAP:
2468 case TENTH_TRAP:
2469 case DEBT_TRAP:
2470 case INVERSION_TRAP:
2471 case WINCE_TRAP:
2472 case FUCK_OVER_TRAP:
2473 case U_HAVE_BEEN_TRAP:
2474 case PERSISTENT_FART_TRAP:
2475 case ATTACKING_HEEL_TRAP:
2476 case TRAP_TELEPORTER:
2477 case ALIGNMENT_TRASH_TRAP:
2478 case RESHUFFLE_TRAP:
2479 case MUSEHAND_TRAP:
2480 case DOGSIDE_TRAP:
2481 case BANKRUPT_TRAP:
2482 case FILLUP_TRAP:
2483 case AIRSTRIKE_TRAP:
2484 case DYNAMITE_TRAP:
2485 case MALEVOLENCE_TRAP:
2486 case LEAFLET_TRAP:
2487 case TENTADEEP_TRAP:
2488 case STATHALF_TRAP:
2489 case CUTSTAT_TRAP:
2490 case RARE_SPAWN_TRAP:
2491 case YOU_ARE_AN_IDIOT_TRAP:
2492 case NASTYCURSE_TRAP:
2493 case DAGGER_TRAP:
2494 case RAZOR_TRAP:
2495 case PHOSGENE_TRAP:
2496 case CHLOROFORM_TRAP:
2497 case CORROSION_TRAP:
2498 case FLAME_TRAP:
2499 case WITHER_TRAP:
2500 case VULNERATE_TRAP:
2502 case FALLING_ROCK_COLD:
2503 case RETURN_TRAP:
2504 case INTRINSIC_STEAL_TRAP:
2505 case SCORE_AXE_TRAP:
2506 case SCORE_DRAIN_TRAP:
2507 case SINGLE_UNIDENTIFY_TRAP:
2508 case UNLUCKY_TRAP:
2509 case ALIGNMENT_REDUCTION_TRAP:
2510 case MALIGNANT_TRAP:
2511 case STAT_DAMAGE_TRAP:
2512 case HALF_MEMORY_TRAP:
2513 case HALF_TRAINING_TRAP:
2514 case DEBUFF_TRAP:
2515 case TRIP_ONCE_TRAP:
2516 case NARCOLEPSY_TRAP:
2517 case MARTIAL_ARTS_TRAP:
2519 case INSTANASTY_TRAP:
2520 case SKILL_POINT_LOSS_TRAP:
2521 case PERFECT_MATCH_TRAP:
2522 case DUMBIE_LIGHTSABER_TRAP:
2523 case WRONG_STAIRS:
2524 case TECHSTOP_TRAP:
2525 case AMNESIA_SWITCH_TRAP:
2526 case SKILL_SWAP_TRAP:
2527 case SKILL_UPORDOWN_TRAP:
2528 case SKILL_RANDOMIZE_TRAP:
2529 You("have triggered a trap!");
2530 dotrap(ttmp, 0);
2531 return(1);
2532 case LOUDSPEAKER:
2533 case RMB_LOSS_TRAP:
2534 case SUPERSCROLLER_TRAP:
2535 case ACTIVE_SUPERSCROLLER_TRAP:
2536 case MENU_TRAP:
2537 case SPEED_TRAP:
2538 case SWARM_TRAP:
2539 case AUTOMATIC_SWITCHER:
2540 case DISPLAY_TRAP:
2541 case SPELL_LOSS_TRAP:
2542 case YELLOW_SPELL_TRAP:
2543 case AUTO_DESTRUCT_TRAP:
2544 case MEMORY_TRAP:
2545 case INVENTORY_TRAP:
2546 case BLACK_NG_WALL_TRAP:
2547 case UNKNOWN_TRAP:
2548 case TRAP_PERCENTS:
2549 case FREE_HAND_TRAP:
2550 case UNIDENTIFY_TRAP:
2551 case THIRST_TRAP:
2552 case LUCK_TRAP:
2553 case SHADES_OF_GREY_TRAP:
2554 case FAINT_TRAP:
2555 case CURSE_TRAP:
2556 case DIFFICULTY_TRAP:
2557 case SOUND_TRAP:
2558 case CASTER_TRAP:
2559 case WEAKNESS_TRAP:
2560 case ROT_THIRTEEN_TRAP:
2561 case BISHOP_TRAP:
2562 case UNINFORMATION_TRAP:
2563 case TIMERUN_TRAP:
2564 case SPELL_COOLDOWN_TRAP:
2565 case TURBODULL_TRAP:
2566 case REDDAM_TRAP:
2567 case REDINC_TRAP:
2568 case MULCH_TRAP:
2569 case INACCURACY_TRAP:
2570 case MONSTER_MULTISHOT_TRAP:
2571 case DO_YOU_HAVE_A_PIN_TRAP:
2572 case COSTLY_FAILURE_TRAP:
2573 case INVENTORY_SIZE_TRAP:
2574 case MEAN_BURDEN_TRAP:
2575 case CARRCAP_TRAP:
2576 case UMENG_TRAP:
2577 case AEFDE_TRAP:
2578 case EPVI_TRAP:
2579 case FUCKFUCKFUCK_TRAP:
2580 case OPTION_TRAP:
2581 case MISCOLOR_TRAP:
2582 case ONE_RAINBOW_TRAP:
2583 case COLORSHIFT_TRAP:
2584 case TOP_LINE_TRAP:
2585 case CAPS_TRAP:
2586 case UN_KNOWLEDGE_TRAP:
2587 case DARKHANCE_TRAP:
2588 case DSCHUEUEUET_TRAP:
2589 case NOPESKILL_TRAP:
2590 case REAL_LIE_TRAP:
2591 case ESCAPE_PAST_TRAP:
2592 case PETHATE_TRAP:
2593 case PET_LASHOUT_TRAP:
2594 case PETSTARVE_TRAP:
2595 case PETSCREW_TRAP:
2596 case TECH_LOSS_TRAP:
2597 case PROOFLOSS_TRAP:
2598 case UN_INVIS_TRAP:
2599 case DETECTATION_TRAP:
2600 case ARTIBLAST_TRAP:
2601 case REPEATING_NASTYCURSE_TRAP:
2602 case REALLY_BAD_TRAP:
2603 case COVID_TRAP:
2604 case GIANT_EXPLORER_TRAP:
2605 case TRAPWARP_TRAP:
2606 case YAWM_TRAP:
2607 case CRADLE_OF_CHAOS_TRAP:
2608 case TEZCATLIPOCA_TRAP:
2609 case ENTHUMESIS_TRAP:
2610 case MIKRAANESIS_TRAP:
2611 case GOTS_TOO_GOOD_TRAP:
2612 case KILLER_ROOM_TRAP:
2613 case NO_FUN_WALLS_TRAP:
2614 case BAD_PART_TRAP:
2615 case COMPLETELY_BAD_PART_TRAP:
2616 case EVIL_VARIANT_TRAP:
2617 case ALIGNMENT_TRAP:
2618 case CONFUSION_TRAP:
2619 case NUPESELL_TRAP:
2620 case DROP_TRAP:
2621 case DSTW_TRAP:
2622 case STATUS_TRAP:
2623 case STAIRS_TRAP:
2624 case INTRINSIC_LOSS_TRAP:
2625 case BLOOD_LOSS_TRAP:
2626 case BAD_EFFECT_TRAP:
2627 case MULTIPLY_TRAP:
2628 case AUTO_VULN_TRAP:
2629 case TELE_ITEMS_TRAP:
2630 case NASTINESS_TRAP:
2631 case RECURSION_TRAP:
2632 case RESPAWN_TRAP:
2633 case WARP_ZONE:
2634 case CAPTCHA_TRAP:
2635 case MIND_WIPE_TRAP:
2636 case THROWING_STAR_TRAP:
2637 case LOCK_TRAP:
2638 case MAGIC_CANCELLATION_TRAP:
2639 case FARLOOK_TRAP:
2640 case GATEWAY_FROM_HELL:
2641 case GROWING_TRAP:
2642 case COOLING_TRAP:
2643 case BAR_TRAP:
2644 case LOCKING_TRAP:
2645 case AIR_TRAP:
2646 case TERRAIN_TRAP:
2647 case ORANGE_SPELL_TRAP:
2648 case VIOLET_SPELL_TRAP:
2649 case TRAP_OF_LONGING:
2650 case CURSED_PART_TRAP:
2651 case QUAVERSAL_TRAP:
2652 case APPEARANCE_SHUFFLING_TRAP:
2653 case BROWN_SPELL_TRAP:
2654 case CHOICELESS_TRAP:
2655 case GOLDSPELL_TRAP:
2656 case DEPROVEMENT_TRAP:
2657 case INITIALIZATION_TRAP:
2658 case GUSHLUSH_TRAP:
2659 case SOILTYPE_TRAP:
2660 case DANGEROUS_TERRAIN_TRAP:
2661 case FALLOUT_TRAP:
2662 case MOJIBAKE_TRAP:
2663 case GRAVATION_TRAP:
2664 case UNCALLED_TRAP:
2665 case EXPLODING_DICE_TRAP:
2666 case PERMACURSE_TRAP:
2667 case SHROUDED_IDENTITY_TRAP:
2668 case FEELER_GAUGES_TRAP:
2669 case LONG_SCREWUP_TRAP:
2670 case WING_YELLOW_CHANGER:
2671 case LIFE_SAVING_TRAP:
2672 case CURSEUSE_TRAP:
2673 case CUT_NUTRITION_TRAP:
2674 case SKILL_LOSS_TRAP:
2675 case AUTOPILOT_TRAP:
2676 case FORCE_TRAP:
2677 case MONSTER_GLYPH_TRAP:
2678 case CHANGING_DIRECTIVE_TRAP:
2679 case CONTAINER_KABOOM_TRAP:
2680 case STEAL_DEGRADE_TRAP:
2681 case LEFT_INVENTORY_TRAP:
2682 case FLUCTUATING_SPEED_TRAP:
2683 case TARMUSTROKINGNORA_TRAP:
2684 case FAILURE_TRAP:
2685 case BRIGHT_CYAN_SPELL_TRAP:
2686 case FREQUENTATION_SPAWN_TRAP:
2687 case PET_AI_TRAP:
2688 case SATAN_TRAP:
2689 case REMEMBERANCE_TRAP:
2690 case POKELIE_TRAP:
2691 case AUTOPICKUP_TRAP:
2692 case DYWYPI_TRAP:
2693 case SILVER_SPELL_TRAP:
2694 case METAL_SPELL_TRAP:
2695 case PLATINUM_SPELL_TRAP:
2696 case MANLER_TRAP:
2697 case DOORNING_TRAP:
2698 case NOWNSIBLE_TRAP:
2699 case ELM_STREET_TRAP:
2700 case MONNOISE_TRAP:
2701 case RANG_CALL_TRAP:
2702 case RECURRING_SPELL_LOSS_TRAP:
2703 case ANTITRAINING_TRAP:
2704 case TECHOUT_TRAP:
2705 case STAT_DECAY_TRAP:
2706 case MOVEMORK_TRAP:
2708 case LOOTCUT_TRAP:
2709 case MONSTER_SPEED_TRAP:
2710 case SCALING_TRAP:
2711 case ENMITY_TRAP:
2712 case WHITE_SPELL_TRAP:
2713 case COMPLETE_GRAY_SPELL_TRAP:
2714 case QUASAR_TRAP:
2715 case MOMMA_TRAP:
2716 case HORROR_TRAP:
2717 case ARTIFICER_TRAP:
2718 case WEREFORM_TRAP:
2719 case NON_PRAYER_TRAP:
2720 case EVIL_PATCH_TRAP:
2721 case HARD_MODE_TRAP:
2722 case SECRET_ATTACK_TRAP:
2723 case EATER_TRAP:
2724 case COVETOUSNESS_TRAP:
2725 case NOT_SEEN_TRAP:
2726 case DARK_MODE_TRAP:
2727 case ANTISEARCH_TRAP:
2728 case HOMICIDE_TRAP:
2729 case NASTY_NATION_TRAP:
2730 case WAKEUP_CALL_TRAP:
2731 case GRAYOUT_TRAP:
2732 case GRAY_CENTER_TRAP:
2733 case CHECKERBOARD_TRAP:
2734 case CLOCKWISE_SPIN_TRAP:
2735 case COUNTERCLOCKWISE_SPIN_TRAP:
2736 case LAG_TRAP:
2737 case BLESSCURSE_TRAP:
2738 case DE_LIGHT_TRAP:
2739 case DISCHARGE_TRAP:
2740 case TRASHING_TRAP:
2741 case FILTERING_TRAP:
2742 case DEFORMATTING_TRAP:
2743 case FLICKER_STRIP_TRAP:
2744 case UNDRESSING_TRAP:
2745 case HYPERBLUEWALL_TRAP:
2746 case NOLITE_TRAP:
2747 case PARANOIA_TRAP:
2748 case FLEECESCRIPT_TRAP:
2749 case INTERRUPT_TRAP:
2750 case DUSTBIN_TRAP:
2751 case MANA_BATTERY_TRAP:
2752 case MONSTERFINGERS_TRAP:
2753 case MISCAST_TRAP:
2754 case MESSAGE_SUPPRESSION_TRAP:
2755 case STUCK_ANNOUNCEMENT_TRAP:
2756 case BLOODTHIRSTY_TRAP:
2757 case MAXIMUM_DAMAGE_TRAP:
2758 case LATENCY_TRAP:
2759 case STARLIT_TRAP:
2760 case KNOWLEDGE_TRAP:
2761 case HIGHSCORE_TRAP:
2762 case PINK_SPELL_TRAP:
2763 case GREEN_SPELL_TRAP:
2764 case EVC_TRAP:
2765 case UNDERLAYER_TRAP:
2766 case DAMAGE_METER_TRAP:
2767 case ARBITRARY_WEIGHT_TRAP:
2768 case FUCKED_INFO_TRAP:
2769 case BLACK_SPELL_TRAP:
2770 case CYAN_SPELL_TRAP:
2771 case HEAP_TRAP:
2772 case BLUE_SPELL_TRAP:
2773 case TRON_TRAP:
2774 case RED_SPELL_TRAP:
2775 case TOO_HEAVY_TRAP:
2776 case ELONGATION_TRAP:
2777 case WRAPOVER_TRAP:
2778 case DESTRUCTION_TRAP:
2779 case MELEE_PREFIX_TRAP:
2780 case AUTOMORE_TRAP:
2781 case UNFAIR_ATTACK_TRAP:
2783 case RECURRING_AMNESIA_TRAP:
2784 case BIGSCRIPT_TRAP:
2785 case BANK_TRAP:
2786 case ONLY_TRAP:
2787 case MAP_TRAP:
2788 case TECH_TRAP:
2789 case DISENCHANT_TRAP:
2790 case VERISIERT:
2791 case CHAOS_TRAP:
2792 case MUTENESS_TRAP:
2793 case NTLL_TRAP:
2794 case ENGRAVING_TRAP:
2795 case MAGIC_DEVICE_TRAP:
2796 case BOOK_TRAP:
2797 case LEVEL_TRAP:
2798 case QUIZ_TRAP:
2800 case METABOLIC_TRAP:
2801 case TRAP_OF_NO_RETURN:
2802 case EGOTRAP:
2803 case FAST_FORWARD_TRAP:
2804 case TRAP_OF_ROTTENNESS:
2805 case UNSKILLED_TRAP:
2806 case LOW_STATS_TRAP:
2807 case TRAINING_TRAP:
2808 case EXERCISE_TRAP:
2809 case LIMITATION_TRAP:
2810 case WEAK_SIGHT_TRAP:
2811 case RANDOM_MESSAGE_TRAP:
2813 case DESECRATION_TRAP:
2814 case STARVATION_TRAP:
2815 case DROPLESS_TRAP:
2816 case LOW_EFFECT_TRAP:
2817 case INVISIBLE_TRAP:
2818 case GHOST_WORLD_TRAP:
2819 case DEHYDRATION_TRAP:
2820 case HATE_TRAP:
2821 case SPACEWARS_TRAP:
2822 case TEMPORARY_RECURSION_TRAP:
2823 case TOTTER_TRAP:
2824 case NONINTRINSICAL_TRAP:
2825 case DROPCURSE_TRAP:
2826 case NAKEDNESS_TRAP:
2827 case ANTILEVEL_TRAP:
2828 case VENTILATOR:
2829 case STEALER_TRAP:
2830 case REBELLION_TRAP:
2831 case CRAP_TRAP:
2832 case MISFIRE_TRAP:
2833 case TRAP_OF_WALLS:
2834 case DISCONNECT_TRAP:
2835 case INTERFACE_SCREW_TRAP:
2836 case BOSSFIGHT_TRAP:
2837 case ENTIRE_LEVEL_TRAP:
2838 case BONES_TRAP:
2839 case AUTOCURSE_TRAP:
2840 case HIGHLEVEL_TRAP:
2841 case SPELL_FORGETTING_TRAP:
2842 case SOUND_EFFECT_TRAP:
2843 case KOP_CUBE:
2844 case BOSS_SPAWNER:
2845 case SANITY_TREBLE_TRAP:
2846 case STAT_DECREASE_TRAP:
2847 case SIMEOUT_TRAP:
2849 dotrap(ttmp, 0);
2850 return(1);
2851 default:
2852 impossible("Webbing over trap type %d?", ttmp->ttyp);
2853 return(0);
2855 else if (On_stairs(u.ux, u.uy)) {
2856 /* cop out: don't let them hide the stairs */
2857 Your("web fails to impede access to the %s.",
2858 (levl[u.ux][u.uy].typ == STAIRS) ? "stairs" : "ladder");
2859 return(1);
2862 ttmp = maketrap(u.ux, u.uy, WEB, 0, FALSE);
2863 if (ttmp && !ttmp->hiddentrap) {
2864 ttmp->tseen = 1;
2865 ttmp->madeby_u = 1;
2867 newsym(u.ux, u.uy);
2868 return(1);
2872 dosummon()
2874 int placeholder;
2875 int somanymana;
2876 somanymana = 10;
2877 int squeakamount = 0;
2879 if (u.ulycn == PM_WERESOLDIERANT) somanymana = 15;
2880 if (u.ulycn == PM_WEREWOLF) somanymana = 20;
2881 if (u.ulycn == PM_WEREPIRANHA) somanymana = 20;
2882 if (u.ulycn == PM_WEREEEL) somanymana = 25;
2883 if (u.ulycn == PM_WEREKRAKEN) somanymana = 45;
2884 if (u.ulycn == PM_WEREFLYFISH) somanymana = 45;
2885 if (u.ulycn == PM_WEREPANTHER) somanymana = 30;
2886 if (u.ulycn == PM_WERETIGER) somanymana = 30;
2887 if (u.ulycn == PM_WERESNAKE) somanymana = 20;
2888 if (u.ulycn == PM_WERECOW) somanymana = 20;
2889 if (u.ulycn == PM_WEREBEAR) somanymana = 75;
2890 if (u.ulycn == PM_WEREPHANT) somanymana = 75;
2891 if (u.ulycn == PM_WEREVORTEX) somanymana = 50;
2892 if (u.ulycn == PM_WERETROLL) somanymana = 50;
2893 if (u.ulycn == PM_WEREGIANT) somanymana = 50;
2894 if (u.ulycn == PM_WEREGHOST) somanymana = 30;
2895 if (u.ulycn == PM_WERECOCKATRICE) somanymana = 60;
2896 if (u.ulycn == PM_WERELICH) somanymana = 100;
2897 if (u.ulycn == PM_UN_IN_PROTECT_MODE) somanymana = 100;
2898 if (u.ulycn == PM_WEREDEMON) somanymana = 100;
2899 if (u.ulycn == PM_WEREMINDFLAYER) somanymana = 150;
2900 if (u.ulycn == PM_VORPAL_WERE_ALHOONTRICE_ZOMBIE) somanymana = 150;
2901 if (u.ulycn == PM_WEREJABBERWOCK) somanymana = 200;
2902 if (u.ulycn == PM_WEREWEDGESANDAL) somanymana = 80;
2903 if (u.ulycn == PM_WEREHUGGINGBOOT) somanymana = 120;
2904 if (u.ulycn == PM_WEREPEEPTOE) somanymana = 140;
2905 if (u.ulycn == PM_WERESEXYLEATHERPUMP) somanymana = 160;
2906 if (u.ulycn == PM_WEREBLOCKHEELEDCOMBATBOOT) somanymana = 160;
2907 if (u.ulycn == PM_WERECOMBATSTILETTO) somanymana = 200;
2908 if (u.ulycn == PM_WEREBEAUTIFULFUNNELHEELEDPUMP) somanymana = 240;
2909 if (u.ulycn == PM_WEREPROSTITUTESHOE) somanymana = 240;
2910 if (u.ulycn == PM_WERESTILETTOSANDAL) somanymana = 250;
2911 if (u.ulycn == PM_WEREUNFAIRSTILETTO) somanymana = 260;
2912 if (u.ulycn == PM_WEREWINTERSTILETTO) somanymana = 300;
2914 if (u.umonnum == PM_WERESOLDIERANT && somanymana < 15) somanymana = 15;
2915 if (u.umonnum == PM_WEREWOLF && somanymana < 20) somanymana = 20;
2916 if (u.umonnum == PM_WEREPIRANHA && somanymana < 20) somanymana = 20;
2917 if (u.umonnum == PM_WEREEEL && somanymana < 25) somanymana = 25;
2918 if (u.umonnum == PM_WEREKRAKEN && somanymana < 45) somanymana = 45;
2919 if (u.umonnum == PM_WEREFLYFISH && somanymana < 45) somanymana = 45;
2920 if (u.umonnum == PM_WEREPANTHER && somanymana < 30) somanymana = 30;
2921 if (u.umonnum == PM_WERETIGER && somanymana < 30) somanymana = 30;
2922 if (u.umonnum == PM_WERESNAKE && somanymana < 20) somanymana = 20;
2923 if (u.umonnum == PM_WERECOW && somanymana < 20) somanymana = 20;
2924 if (u.umonnum == PM_WEREBEAR && somanymana < 75) somanymana = 75;
2925 if (u.umonnum == PM_WEREPHANT && somanymana < 75) somanymana = 75;
2926 if (u.umonnum == PM_WEREVORTEX && somanymana < 50) somanymana = 50;
2927 if (u.umonnum == PM_WERETROLL && somanymana < 50) somanymana = 50;
2928 if (u.umonnum == PM_WEREGIANT && somanymana < 50) somanymana = 50;
2929 if (u.umonnum == PM_WEREGHOST && somanymana < 30) somanymana = 30;
2930 if (u.umonnum == PM_WERECOCKATRICE && somanymana < 60) somanymana = 60;
2931 if (u.umonnum == PM_WERELICH && somanymana < 100) somanymana = 100;
2932 if (u.umonnum == PM_UN_IN_PROTECT_MODE && somanymana < 100) somanymana = 100;
2933 if (u.umonnum == PM_WEREDEMON && somanymana < 100) somanymana = 100;
2934 if (u.umonnum == PM_WEREMINDFLAYER && somanymana < 150) somanymana = 150;
2935 if (u.umonnum == PM_VORPAL_WERE_ALHOONTRICE_ZOMBIE && somanymana < 150) somanymana = 150;
2936 if (u.umonnum == PM_WEREJABBERWOCK && somanymana < 200) somanymana = 200;
2937 if (u.umonnum == PM_WEREWEDGESANDAL && somanymana < 80) somanymana = 80;
2938 if (u.umonnum == PM_WEREHUGGINGBOOT && somanymana < 120) somanymana = 120;
2939 if (u.umonnum == PM_WEREPEEPTOE && somanymana < 140) somanymana = 140;
2940 if (u.umonnum == PM_WERESEXYLEATHERPUMP && somanymana < 160) somanymana = 160;
2941 if (u.umonnum == PM_WEREBLOCKHEELEDCOMBATBOOT && somanymana < 160) somanymana = 160;
2942 if (u.umonnum == PM_WERECOMBATSTILETTO && somanymana < 200) somanymana = 200;
2943 if (u.umonnum == PM_WEREBEAUTIFULFUNNELHEELEDPUMP && somanymana < 240) somanymana = 240;
2944 if (u.umonnum == PM_WEREPROSTITUTESHOE && somanymana < 240) somanymana = 240;
2945 if (u.umonnum == PM_WERESTILETTOSANDAL && somanymana < 250) somanymana = 250;
2946 if (u.umonnum == PM_WEREUNFAIRSTILETTO && somanymana < 260) somanymana = 260;
2947 if (u.umonnum == PM_WEREWINTERSTILETTO && somanymana < 300) somanymana = 300;
2949 squeakamount = somanymana;
2950 /* we can now use the squeaking skill to reduce the cost */
2952 if (!PlayerCannotUseSkills && somanymana > 2) {
2953 switch (P_SKILL(P_SQUEAKING)) {
2954 case P_BASIC: somanymana *= 9; somanymana /= 10; break;
2955 case P_SKILLED: somanymana *= 8; somanymana /= 10; break;
2956 case P_EXPERT: somanymana *= 7; somanymana /= 10; break;
2957 case P_MASTER: somanymana *= 6; somanymana /= 10; break;
2958 case P_GRAND_MASTER: somanymana *= 5; somanymana /= 10; break;
2959 case P_SUPREME_MASTER: somanymana *= 4; somanymana /= 10; break;
2960 default: break;
2964 if (u.uen < somanymana) {
2965 You("lack the energy to send forth a call for help! You need at least %d!",somanymana);
2966 return(0);
2968 u.uen -= somanymana;
2969 flags.botl = 1;
2971 You("call upon your brethren for help!");
2972 exercise(A_WIS, TRUE);
2973 if (!were_summon(youmonst.data, TRUE, &placeholder, (char *)0, FALSE))
2974 pline("But none arrive.");
2976 while (squeakamount > 40) {
2977 use_skill(P_SQUEAKING, 1);
2978 squeakamount -= 40;
2980 use_skill(P_SQUEAKING, 1);
2982 return(1);
2986 #if 0
2987 /* WAC supplanted by dogaze (). */
2989 dogaze()
2991 register struct monst *mtmp;
2992 int looked = 0;
2993 char qbuf[QBUFSZ];
2994 int i;
2995 uchar adtyp = 0;
2997 for (i = 0; i < NATTK; i++) {
2998 if(youmonst.data->mattk[i].aatyp == AT_GAZE) {
2999 adtyp = youmonst.data->mattk[i].adtyp;
3000 break;
3003 if (adtyp != AD_CONF && adtyp != AD_FIRE) {
3004 impossible("gaze attack %d?", adtyp);
3005 return 0;
3009 if (Blind) {
3010 You_cant("see anything to gaze at.");
3011 return 0;
3013 if (u.uen < 15) {
3014 You("lack the energy to use your special gaze! You need at least 15 points of mana!");
3015 return(0);
3017 u.uen -= 15;
3018 flags.botl = 1;
3020 for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
3021 if (DEADMONSTER(mtmp)) continue;
3022 if (canseemon(mtmp) && couldsee(mtmp->mx, mtmp->my)) {
3023 looked++;
3024 if (Invis && !perceives(mtmp->data))
3025 pline("%s seems not to notice your gaze.", Monnam(mtmp));
3026 else if ((mtmp->minvis && (!See_invisible || (!StrongSee_invisible && !mtmp->seeinvisble)) ) || mtmp->minvisreal)
3027 You_cant("see where to gaze at %s.", Monnam(mtmp));
3028 else if (mtmp->m_ap_type == M_AP_FURNITURE
3029 || mtmp->m_ap_type == M_AP_OBJECT) {
3030 looked--;
3031 continue;
3032 } else if (flags.safe_dog && !Confusion && !Hallucination
3033 && mtmp->mtame) {
3034 You("avoid gazing at %s.", y_monnam(mtmp));
3035 } else {
3036 if (flags.confirm && mtmp->mpeaceful && !Confusion
3037 && !Hallucination) {
3038 sprintf(qbuf, "Really %s %s?",
3039 (adtyp == AD_CONF) ? "confuse" : "attack",
3040 mon_nam(mtmp));
3041 if (yn(qbuf) != 'y') continue;
3042 setmangry(mtmp);
3044 if (!mtmp->mcanmove || mtmp->mstun || mtmp->msleeping ||
3045 !mtmp->mcansee || !haseyes(mtmp->data)) {
3046 looked--;
3047 continue;
3049 /* No reflection check for consistency with when a monster
3050 * gazes at *you*--only medusa gaze gets reflected then.
3052 if (adtyp == AD_CONF) {
3053 if (!mtmp->mconf)
3054 Your("gaze confuses %s!", mon_nam(mtmp));
3055 else
3056 pline("%s is getting more and more confused.",
3057 Monnam(mtmp));
3058 mtmp->mconf = 1;
3059 } else if (adtyp == AD_FIRE) {
3060 int dmg = d(2,6);
3061 You("attack %s with a fiery gaze!", mon_nam(mtmp));
3062 if (resists_fire(mtmp) && !player_will_pierce_resistance()) {
3063 pline_The("fire doesn't burn %s!", mon_nam(mtmp));
3064 dmg = 0;
3066 if(!rn2(33))
3067 (void) destroy_mitem(mtmp, SCROLL_CLASS, AD_FIRE);
3068 if(!rn2(33))
3069 (void) destroy_mitem(mtmp, POTION_CLASS, AD_FIRE);
3070 if(!rn2(33))
3071 (void) destroy_mitem(mtmp, SPBOOK_CLASS, AD_FIRE);
3072 if (dmg && !DEADMONSTER(mtmp)) mtmp->mhp -= dmg;
3073 if (mtmp->mhp <= 0) killed(mtmp);
3075 /* For consistency with passive() in uhitm.c, this only
3076 * affects you if the monster is still alive.
3078 if (!DEADMONSTER(mtmp) &&
3079 (mtmp->data==&mons[PM_FLOATING_EYE]) && !mtmp->mcan) {
3080 if (!Free_action) {
3081 You("are frozen by %s gaze!",
3082 s_suffix(mon_nam(mtmp)));
3083 nomul(-d((int)mtmp->m_lev+1, (int)mtmp->data->mattk[0].damd), "frozen by stupidly gazing at a floating eye", TRUE);
3084 return 1;
3085 } else
3086 You("stiffen momentarily under %s gaze.",
3087 s_suffix(mon_nam(mtmp)));
3089 /* Technically this one shouldn't affect you at all because
3090 * the Medusa gaze is an active monster attack that only
3091 * works on the monster's turn, but for it to *not* have an
3092 * effect would be too weird.
3094 if (!DEADMONSTER(mtmp) &&
3095 (mtmp->data==&mons[PM_MEDUSA]) && !mtmp->mcan) {
3096 pline(
3097 "Gazing at the awake %s is not a very good idea.",
3098 l_monnam(mtmp));
3099 /* as if gazing at a sleeping anything is fruitful... */
3100 /*You("turn to stone...");
3101 killer_format = KILLED_BY;
3102 killer = "deliberately meeting Medusa's gaze";
3103 done(STONING);*/
3104 You("start turning to stone...");
3105 if (!Stoned) {
3106 if (Hallucination && rn2(10)) pline("But you are already stoned.");
3107 else {
3108 Stoned = Race_if(PM_EROSATOR) ? 3 : 7;
3109 u.cnd_stoningcount++;
3110 delayed_killer = "deliberately meeting Medusa's gaze";
3117 if (!looked) You("gaze at no place in particular.");
3118 return 1;
3120 #endif
3124 dohide()
3126 boolean ismimic = youmonst.data->mlet == S_MIMIC;
3128 /* costs mana if you're mimicking, but not if you're merely hiding --Amy */
3129 int hidingcost = 25;
3131 if (!PlayerCannotUseSkills) {
3132 switch (P_SKILL(P_SQUEAKING)) {
3133 case P_BASIC: hidingcost = 24; break;
3134 case P_SKILLED: hidingcost = 23; break;
3135 case P_EXPERT: hidingcost = 22; break;
3136 case P_MASTER: hidingcost = 21; break;
3137 case P_GRAND_MASTER: hidingcost = 20; break;
3138 case P_SUPREME_MASTER: hidingcost = 19; break;
3139 default: break;
3143 if (u.uundetected || (ismimic && youmonst.m_ap_type != M_AP_NOTHING)) {
3144 You("are already hiding.");
3145 return(0);
3147 if (ismimic) {
3149 if (u.uen < hidingcost) {
3150 You("lack the required %d mana to mimic an object.", hidingcost);
3151 return(0);
3153 u.uen -= hidingcost;
3155 /* should bring up a dialog "what would you like to imitate?" */
3156 youmonst.m_ap_type = M_AP_OBJECT;
3157 youmonst.mappearance = STRANGE_OBJECT;
3159 use_skill(P_SQUEAKING, 2); /* trains squeaking only if you used mana */
3161 } else
3162 u.uundetected = 1;
3163 newsym(u.ux,u.uy);
3164 return(1);
3168 domindblast()
3170 struct monst *mtmp, *nmon;
3171 int mindblastcost = 10;
3173 if (!PlayerCannotUseSkills) {
3174 switch (P_SKILL(P_SQUEAKING)) {
3175 case P_BASIC: mindblastcost = 9 + rn2(2); break;
3176 case P_SKILLED: mindblastcost = 8 + rn2(3); break;
3177 case P_EXPERT: mindblastcost = 7 + rn2(4); break;
3178 case P_MASTER: mindblastcost = 6 + rn2(5); break;
3179 case P_GRAND_MASTER: mindblastcost = 5 + rn2(6); break;
3180 case P_SUPREME_MASTER: mindblastcost = 4 + rn2(7); break;
3181 default: break;
3185 if (u.uen < mindblastcost) {
3186 You("concentrate but lack the energy to maintain doing so. Wimp, you don't even have 10 mana to spare?!");
3187 return(0);
3189 u.uen -= mindblastcost;
3190 flags.botl = 1;
3192 pline("A wave of psychic energy pours out.");
3193 for(mtmp=fmon; mtmp; mtmp = nmon) {
3194 int u_sen;
3196 nmon = mtmp->nmon;
3197 if (DEADMONSTER(mtmp))
3198 continue;
3199 if (distu(mtmp->mx, mtmp->my) > BOLT_LIM * BOLT_LIM)
3200 continue;
3201 if(mtmp->mpeaceful)
3202 continue;
3203 u_sen = telepathic(mtmp->data) && !mtmp->mcansee;
3204 if (u_sen || (telepathic(mtmp->data) && rn2(3)) || !rn2(2)) {
3206 int mindblastdmg = rn1(4,4);
3207 if (powerfulimplants() && uimplant && uimplant->oartifact == ART_TSCHHKRZKRZ) mindblastdmg *= rn1(2, 2);
3209 You("lock in on %s %s.", s_suffix(mon_nam(mtmp)),
3210 u_sen ? "telepathy" :
3211 telepathic(mtmp->data) ? "latent telepathy" :
3212 "mind");
3213 mtmp->mhp -= mindblastdmg;
3214 if (mtmp->mhp <= 0)
3215 killed(mtmp);
3218 use_skill(P_SQUEAKING, 1);
3220 return 1;
3223 STATIC_OVL void
3224 uunstick()
3226 pline("%s is no longer in your clutches.", Monnam(u.ustuck));
3227 setustuck(0);
3230 void
3231 skinback(silently)
3232 boolean silently;
3234 if (uskin) {
3235 if (!silently) Your("skin returns to its original form.");
3236 uarm = uskin;
3237 uskin = (struct obj *)0;
3238 /* undo save/restore hack */
3239 uarm->owornmask &= ~I_SPECIAL;
3243 #endif /* OVLB */
3244 #ifdef OVL1
3246 const char *
3247 mbodypart(mon, part)
3248 struct monst *mon;
3249 int part;
3251 static NEARDATA const char
3252 *humanoid_parts[] = { "arm", "eye", "face", "finger",
3253 "fingertip", "foot", "hand", "handed", "head", "leg",
3254 "light headed", "neck", "spine", "toe", "hair",
3255 "blood", "lung", "nose", "stomach"},
3256 *jelly_parts[] = { "pseudopod", "dark spot", "front",
3257 "pseudopod extension", "pseudopod extremity",
3258 "pseudopod root", "grasp", "grasped", "cerebral area",
3259 "lower pseudopod", "viscous", "middle", "surface",
3260 "pseudopod extremity", "ripples", "juices",
3261 "surface", "sensor", "stomach" },
3262 *animal_parts[] = { "forelimb", "eye", "face", "foreclaw", "claw tip",
3263 "rear claw", "foreclaw", "clawed", "head", "rear limb",
3264 "light headed", "neck", "spine", "rear claw tip",
3265 "fur", "blood", "lung", "nose", "stomach" },
3266 *bird_parts[] = { "wing", "eye", "face", "wing", "wing tip",
3267 "foot", "wing", "winged", "head", "leg",
3268 "light headed", "neck", "spine", "toe",
3269 "feathers", "blood", "lung", "bill", "stomach" },
3270 *horse_parts[] = { "foreleg", "eye", "face", "forehoof", "hoof tip",
3271 "rear hoof", "foreclaw", "hooved", "head", "rear leg",
3272 "light headed", "neck", "backbone", "rear hoof tip",
3273 "mane", "blood", "lung", "nose", "stomach"},
3274 *sphere_parts[] = { "appendage", "optic nerve", "body", "tentacle",
3275 "tentacle tip", "lower appendage", "tentacle", "tentacled",
3276 "body", "lower tentacle", "rotational", "equator", "body",
3277 "lower tentacle tip", "cilia", "life force", "retina",
3278 "olfactory nerve", "interior" },
3279 *fungus_parts[] = { "mycelium", "visual area", "front", "hypha",
3280 "hypha", "root", "strand", "stranded", "cap area",
3281 "rhizome", "sporulated", "stalk", "root", "rhizome tip",
3282 "spores", "juices", "gill", "gill", "interior" },
3283 *vortex_parts[] = { "region", "eye", "front", "minor current",
3284 "minor current", "lower current", "swirl", "swirled",
3285 "central core", "lower current", "addled", "center",
3286 "currents", "edge", "currents", "life force",
3287 "center", "leading edge", "interior" },
3288 *snake_parts[] = { "vestigial limb", "eye", "face", "large scale",
3289 "large scale tip", "rear region", "scale gap", "scale gapped",
3290 "head", "rear region", "light headed", "neck", "length",
3291 "rear scale", "scales", "blood", "lung", "forked tongue", "stomach" },
3292 *wallmonst_parts[] = { "long wall", "center core", "top region", "wall extension",
3293 "wall extension", "bottom region", "wall extension", "extended", "central core", "tall wall",
3294 "misdirectional", "support column", "large column", "lower extension", "painting",
3295 "stone fragments", "inner segment", "front support", "middle wall"},
3296 *turret_parts[] = { "gun arm", "lens", "calculation region", "gun",
3297 "laser point", "foot", "laser gun", "gunned", "CPU", "pod",
3298 "frenzied", "support", "back", "mainframe", "combat inhibitor",
3299 "electrical energy", "RAM", "power", "armor"},
3300 *fish_parts[] = { "fin", "eye", "premaxillary", "pelvic axillary",
3301 "pelvic fin", "anal fin", "pectoral fin", "finned", "head", "peduncle",
3302 "played out", "gills", "dorsal fin", "caudal fin",
3303 "scales", "blood", "gill", "nostril", "stomach" };
3304 /* claw attacks are overloaded in mons[]; most humanoids with
3305 such attacks should still reference hands rather than claws */
3306 static const char not_claws[] = {
3307 S_HUMAN, S_MUMMY, S_ZOMBIE, S_ANGEL,
3308 S_NYMPH, S_LEPRECHAUN, S_QUANTMECH, S_VAMPIRE,
3309 S_ORC, S_GIANT, /* quest nemeses */
3310 '\0' /* string terminator; assert( S_xxx != 0 ); */
3312 struct permonst *mptr = mon->data;
3314 if (part == HAND || part == HANDED) { /* some special cases */
3315 if (mptr->mlet == S_DOG || mptr->mlet == S_FELINE ||
3316 mptr->mlet == S_YETI)
3317 return part == HAND ? "paw" : "pawed";
3318 if (humanoid(mptr) && attacktype(mptr, AT_CLAW) &&
3319 !index(not_claws, mptr->mlet) &&
3320 mptr != &mons[PM_STONE_GOLEM] &&
3321 mptr != &mons[PM_INCUBUS] && mptr != &mons[PM_SUCCUBUS])
3322 return part == HAND ? "claw" : "clawed";
3324 if ((mptr == &mons[PM_MUMAK] || mptr == &mons[PM_MASTODON]) &&
3325 part == NOSE)
3326 return "trunk";
3327 if (mptr == &mons[PM_SHARK] && part == HAIR)
3328 return "skin"; /* sharks don't have scales */
3329 if (mptr == &mons[PM_JELLYFISH] && (part == ARM || part == FINGER ||
3330 part == HAND || part == FOOT || part == TOE))
3331 return "tentacle";
3332 if (mptr == &mons[PM_FLOATING_EYE] && part == EYE)
3333 return "cornea";
3334 if (humanoid(mptr) &&
3335 (part == ARM || part == FINGER || part == FINGERTIP ||
3336 part == HAND || part == HANDED))
3337 return humanoid_parts[part];
3338 if (mptr->mlet == S_BAT)
3339 return bird_parts[part];
3340 if (mptr->mlet == S_CENTAUR || mptr->mlet == S_UNICORN ||
3341 (mptr == &mons[PM_ROTHE] && part != HAIR))
3342 return horse_parts[part];
3343 if (mptr->mlet == S_LIGHT) {
3344 if (part == HANDED) return "rayed";
3345 else if (part == ARM || part == FINGER ||
3346 part == FINGERTIP || part == HAND) return "ray";
3347 else return "beam";
3349 if (mptr->mlet == S_EEL && mptr != &mons[PM_JELLYFISH])
3350 return fish_parts[part];
3351 if (mptr->mlet == S_FLYFISH)
3352 return fish_parts[part];
3353 if (slithy(mptr) || (mptr->mlet == S_DRAGON && part == HAIR))
3354 return snake_parts[part];
3355 if (mptr->mlet == S_EYE || mptr->mlet == S_GRUE)
3356 return sphere_parts[part];
3357 if (mptr->mlet == S_JELLY || mptr->mlet == S_PUDDING ||
3358 mptr->mlet == S_BLOB || mptr == &mons[PM_JELLYFISH])
3359 return jelly_parts[part];
3360 if (mptr->mlet == S_VORTEX || mptr->mlet == S_ELEMENTAL)
3361 return vortex_parts[part];
3362 if (mptr->mlet == S_FUNGUS)
3363 return fungus_parts[part];
3364 if (mptr->mlet == S_WALLMONST)
3365 return wallmonst_parts[part];
3366 if (mptr->mlet == S_TURRET)
3367 return turret_parts[part];
3368 if (humanoid(mptr))
3369 return humanoid_parts[part];
3370 return animal_parts[part];
3373 const char *
3374 body_part(part)
3375 int part;
3377 return mbodypart(&youmonst, part);
3380 #endif /* OVL1 */
3381 #ifdef OVL0
3384 poly_gender()
3386 /* Returns gender of polymorphed player; 0/1=same meaning as flags.female,
3387 * 2=none.
3389 if (is_neuter(youmonst.data) || !humanoid(youmonst.data)) return 2;
3390 return flags.female;
3393 #endif /* OVL0 */
3394 #ifdef OVLB
3396 void
3397 ugolemeffects(damtype, dam)
3398 int damtype, dam;
3400 int heal = 0;
3401 /* We won't bother with "slow"/"haste" since players do not
3402 * have a monster-specific slow/haste so there is no way to
3403 * restore the old velocity once they are back to human.
3405 if (u.umonnum != PM_FLESH_GOLEM && u.umonnum != PM_IRON_GOLEM)
3406 return;
3407 switch (damtype) {
3408 case AD_ELEC: if (u.umonnum == PM_FLESH_GOLEM)
3409 heal = dam / 6; /* Approx 1 per die */
3410 break;
3411 case AD_FIRE: if (u.umonnum == PM_IRON_GOLEM)
3412 heal = dam;
3413 break;
3415 if (heal && (u.mh < u.mhmax)) {
3416 u.mh += heal;
3417 if (u.mh > u.mhmax) u.mh = u.mhmax;
3418 flags.botl = 1;
3419 pline("Strangely, you feel better than before.");
3420 exercise(A_STR, TRUE);
3424 STATIC_OVL int
3425 armor_to_dragon(atyp)
3426 int atyp;
3428 switch(atyp) {
3429 case GRAY_DRAGON_SCALE_MAIL:
3430 case GRAY_DRAGON_SCALES:
3431 return PM_GRAY_DRAGON;
3432 case SILVER_DRAGON_SCALE_MAIL:
3433 case SILVER_DRAGON_SCALES:
3434 return PM_SILVER_DRAGON;
3435 case MERCURIAL_DRAGON_SCALE_MAIL:
3436 case MERCURIAL_DRAGON_SCALES:
3437 return PM_MERCURIAL_DRAGON;
3438 case RAINBOW_DRAGON_SCALE_MAIL:
3439 case RAINBOW_DRAGON_SCALES:
3440 return PM_RAINBOW_DRAGON;
3441 case BLOOD_DRAGON_SCALE_MAIL:
3442 case BLOOD_DRAGON_SCALES:
3443 return PM_BLOOD_DRAGON;
3444 case PLAIN_DRAGON_SCALE_MAIL:
3445 case PLAIN_DRAGON_SCALES:
3446 return PM_PLAIN_DRAGON;
3447 case SKY_DRAGON_SCALE_MAIL:
3448 case SKY_DRAGON_SCALES:
3449 return PM_SKY_DRAGON;
3450 case WATER_DRAGON_SCALE_MAIL:
3451 case WATER_DRAGON_SCALES:
3452 return PM_WATER_DRAGON;
3453 case EVIL_DRAGON_SCALE_MAIL:
3454 case EVIL_DRAGON_SCALES:
3455 return PM_EVIL_DRAGON;
3456 case MAGIC_DRAGON_SCALE_MAIL:
3457 case MAGIC_DRAGON_SCALES:
3458 return PM_MAGIC_DRAGON;
3459 case SHIMMERING_DRAGON_SCALE_MAIL:
3460 case SHIMMERING_DRAGON_SCALES:
3461 return PM_SHIMMERING_DRAGON;
3462 case DEEP_DRAGON_SCALE_MAIL:
3463 case DEEP_DRAGON_SCALES:
3464 return PM_DEEP_DRAGON;
3465 case RED_DRAGON_SCALE_MAIL:
3466 case RED_DRAGON_SCALES:
3467 return PM_RED_DRAGON;
3468 case ORANGE_DRAGON_SCALE_MAIL:
3469 case ORANGE_DRAGON_SCALES:
3470 return PM_ORANGE_DRAGON;
3471 case WHITE_DRAGON_SCALE_MAIL:
3472 case WHITE_DRAGON_SCALES:
3473 return PM_WHITE_DRAGON;
3474 case BLACK_DRAGON_SCALE_MAIL:
3475 case BLACK_DRAGON_SCALES:
3476 return PM_BLACK_DRAGON;
3477 case BLUE_DRAGON_SCALE_MAIL:
3478 case BLUE_DRAGON_SCALES:
3479 return PM_BLUE_DRAGON;
3480 case DARK_DRAGON_SCALE_MAIL:
3481 case DARK_DRAGON_SCALES:
3482 return PM_DARK_DRAGON;
3483 case COPPER_DRAGON_SCALE_MAIL:
3484 case COPPER_DRAGON_SCALES:
3485 return PM_COPPER_DRAGON;
3486 case PLATINUM_DRAGON_SCALE_MAIL:
3487 case PLATINUM_DRAGON_SCALES:
3488 return PM_PLATINUM_DRAGON;
3489 case BRASS_DRAGON_SCALE_MAIL:
3490 case BRASS_DRAGON_SCALES:
3491 return PM_BRASS_DRAGON;
3492 case AMETHYST_DRAGON_SCALE_MAIL:
3493 case AMETHYST_DRAGON_SCALES:
3494 return PM_AMETHYST_DRAGON;
3495 case PURPLE_DRAGON_SCALE_MAIL:
3496 case PURPLE_DRAGON_SCALES:
3497 return PM_PURPLE_DRAGON;
3498 case DIAMOND_DRAGON_SCALE_MAIL:
3499 case DIAMOND_DRAGON_SCALES:
3500 return PM_DIAMOND_DRAGON;
3501 case EMERALD_DRAGON_SCALE_MAIL:
3502 case EMERALD_DRAGON_SCALES:
3503 return PM_EMERALD_DRAGON;
3504 case SAPPHIRE_DRAGON_SCALE_MAIL:
3505 case SAPPHIRE_DRAGON_SCALES:
3506 return PM_SAPPHIRE_DRAGON;
3507 case RUBY_DRAGON_SCALE_MAIL:
3508 case RUBY_DRAGON_SCALES:
3509 return PM_RUBY_DRAGON;
3510 case GREEN_DRAGON_SCALE_MAIL:
3511 case GREEN_DRAGON_SCALES:
3512 return PM_GREEN_DRAGON;
3513 case GOLDEN_DRAGON_SCALE_MAIL:
3514 case GOLDEN_DRAGON_SCALES:
3515 return PM_GOLDEN_DRAGON;
3516 case FEMINISM_DRAGON_SCALE_MAIL:
3517 case FEMINISM_DRAGON_SCALES:
3518 return PM_FEMINISM_DRAGON;
3519 case MAIDRAGON_SCALE_MAIL:
3520 case MAIDRAGON_SCALES:
3521 return PM_MAIDRAGON;
3522 case CANCEL_DRAGON_SCALE_MAIL:
3523 case CANCEL_DRAGON_SCALES:
3524 return PM_CANCEL_DRAGON;
3525 case NEGATIVE_DRAGON_SCALE_MAIL:
3526 case NEGATIVE_DRAGON_SCALES:
3527 return PM_NEGATIVE_DRAGON;
3528 case CORONA_DRAGON_SCALE_MAIL:
3529 case CORONA_DRAGON_SCALES:
3530 return PM_CORONA_DRAGON;
3531 case CONTRO_DRAGON_SCALE_MAIL:
3532 case CONTRO_DRAGON_SCALES:
3533 return PM_CONTRO_DRAGON;
3534 case NOPE_DRAGON_SCALE_MAIL:
3535 case NOPE_DRAGON_SCALES:
3536 return PM_NOPE_DRAGON;
3537 case CRYSTALLINE_DRAGON_SCALE_MAIL:
3538 case CRYSTALLINE_DRAGON_SCALES:
3539 return PM_CRYSTALLINE_DRAGON;
3540 case MYSTERY_DRAGON_SCALE_MAIL:
3541 case MYSTERY_DRAGON_SCALES:
3542 return PM_MYSTERY_DRAGON;
3543 case HEROIC_DRAGON_SCALE_MAIL:
3544 case HEROIC_DRAGON_SCALES:
3545 return PM_HEROIC_DRAGON;
3546 case STONE_DRAGON_SCALE_MAIL:
3547 case STONE_DRAGON_SCALES:
3548 return PM_STONE_DRAGON;
3549 case CYAN_DRAGON_SCALE_MAIL:
3550 case CYAN_DRAGON_SCALES:
3551 return PM_CYAN_DRAGON;
3552 case PSYCHIC_DRAGON_SCALE_MAIL:
3553 case PSYCHIC_DRAGON_SCALES:
3554 return PM_PSYCHIC_DRAGON;
3555 case YELLOW_DRAGON_SCALE_MAIL:
3556 case YELLOW_DRAGON_SCALES:
3557 return PM_YELLOW_DRAGON;
3558 default:
3559 return -1;
3563 static struct {
3564 int mon;
3565 int reqtime;
3566 boolean merge;
3567 } draconic;
3569 STATIC_PTR
3571 mage_transform() /* called each move during transformation process */
3573 if (--draconic.reqtime)
3574 return 1;
3575 if (draconic.merge)
3576 merge_with_armor();
3577 polymon(draconic.mon);
3579 /* put it on a timer, because it was just silly that you'd be able to shake off cursed items indefinitely. --Amy */
3581 u.dragonpolymorphtime = rnz(2000);
3582 pline("You have to wait %d turns until you can use the ability to polymorph into a dragon again.", u.dragonpolymorphtime);
3584 /* If you need to get rid of cursed stuff more often than once every rnz(2000) turns, you should maybe consider
3585 * changing your playstyle and not putting every unidentified piece of equipment on :P */
3587 return 0;
3591 polyatwill() /* Polymorph under conscious control (#youpoly) */
3593 #define EN_DOPP 20 /* This is the "base cost" for a polymorph
3594 * Actual cost is this base cost + 5 * monster level
3595 * of the final form you actually assume.
3596 * Energy will be taken first, then you will get
3597 * more hungry if you do not have enough energy.
3599 #define EN_BABY_DRAGON 20
3600 #define EN_ADULT_DRAGON 50
3602 int squeakamount = 0;
3603 int somanymana = 10;
3605 boolean scales = ((uarm && uarm->otyp == RED_DRAGON_SCALES
3606 && Role_if(PM_FLAME_MAGE)) ||
3607 (uarm && uarm->otyp == BLUE_DRAGON_SCALES
3608 && Role_if(PM_ELECTRIC_MAGE)) ||
3609 (uarm && uarm->otyp == GREEN_DRAGON_SCALES
3610 && Role_if(PM_POISON_MAGE)) ||
3611 (uarm && uarm->otyp == YELLOW_DRAGON_SCALES
3612 && Role_if(PM_ACID_MAGE)) ||
3613 (uarm && uarm->otyp == WHITE_DRAGON_SCALES
3614 && Role_if(PM_ICE_MAGE)));
3615 boolean scale_mail = ((uarm && uarm->otyp == RED_DRAGON_SCALE_MAIL
3616 && Role_if(PM_FLAME_MAGE)) ||
3617 (uarm && uarm->otyp == BLUE_DRAGON_SCALE_MAIL
3618 && Role_if(PM_ELECTRIC_MAGE)) ||
3619 (uarm && uarm->otyp == GREEN_DRAGON_SCALE_MAIL
3620 && Role_if(PM_POISON_MAGE)) ||
3621 (uarm && uarm->otyp == YELLOW_DRAGON_SCALE_MAIL
3622 && Role_if(PM_ACID_MAGE)) ||
3623 (uarm && uarm->otyp == WHITE_DRAGON_SCALE_MAIL
3624 && Role_if(PM_ICE_MAGE)));
3626 /* KMH, balance patch -- new intrinsic */
3627 if (Unchanging) {
3628 pline("You cannot change your form.");
3629 return 0;
3632 /* First, if in correct polymorphed form, rehumanize (for free)
3633 * Omit Lycanthropes, who need to spend energy to change back and forth
3634 * Amy edit: yeah sure, for free. You probably do not believe. Of course you need to pay for that too!
3636 if (Upolyd && !u.dragonpolymorphtime && !Race_if(PM_UNGENOMOLD) && (Race_if(PM_DOPPELGANGER) || Role_if(PM_SHAPESHIFTER) ||
3637 (Role_if(PM_FLAME_MAGE) && (u.umonnum == PM_RED_DRAGON ||
3638 u.umonnum == PM_BABY_RED_DRAGON)) ||
3639 (Role_if(PM_ACID_MAGE) && (u.umonnum == PM_YELLOW_DRAGON ||
3640 u.umonnum == PM_BABY_YELLOW_DRAGON)) ||
3641 (Role_if(PM_ELECTRIC_MAGE) && (u.umonnum == PM_BLUE_DRAGON ||
3642 u.umonnum == PM_BABY_BLUE_DRAGON)) ||
3643 (Role_if(PM_POISON_MAGE) && (u.umonnum == PM_GREEN_DRAGON ||
3644 u.umonnum == PM_BABY_GREEN_DRAGON)) ||
3645 (Role_if(PM_ICE_MAGE) && (u.umonnum == PM_WHITE_DRAGON ||
3646 u.umonnum == PM_BABY_WHITE_DRAGON)))) {
3647 if (yn("Turn back into your normal form?") == 'y') {
3649 u.dragonpolymorphtime = rnz(2000);
3650 pline("You have to wait %d turns until you can use the ability to polymorph into a dragon again.", u.dragonpolymorphtime);
3651 rehumanize();
3652 return 1;
3657 if ((Role_if(PM_ICE_MAGE) || Role_if(PM_FLAME_MAGE) || Role_if(PM_ACID_MAGE) || Role_if(PM_ELECTRIC_MAGE) || Role_if(PM_POISON_MAGE)) && !u.dragonpolymorphtime && (u.ulevel > 6 || scale_mail) && (yn("Transform into your draconic form?") == 'y')) {
3658 /* [ALI]
3659 * I've rewritten the logic here to fix the failure messages,
3660 * but the requirements for polymorphing into the two dragon
3661 * forms remains the same:
3663 * Polymorph into adult dragon form if one of:
3665 * - Wearing scale mail (no charge).
3666 * - Wearing scales and experience level 7 and
3667 * energy level 11 or more (charge is 10).
3668 * - Not wearing scales or scale mail and experience level 14 and
3669 * energy level 16 or more (charge is 15).
3671 * Polymorph into baby dragon form if one of:
3673 * - Wearing scales and experience level 7 and
3674 * energy level 10 or less (no charge).
3675 * - Not wearing scales or scale mail and experience level 14 and
3676 * energy level 11-15 (charge is 10).
3677 * - Not wearing scales or scale mail and experience level 7-13 and
3678 * energy level 11 or more (charge is 10).
3680 * Fail if one of:
3682 * - Not wearing scales or scale mail and experience level 7 and
3683 * energy level 10 or less (not enough energy).
3684 * - Not wearing scale mail and experience level 6 or less
3685 * (not experienced enough).
3687 * The transformation takes a few turns. If interrupted during this
3688 * period then the ritual must be begun again from the beginning.
3689 * We deliberately don't say what form the ritual takes since it
3690 * is unaffected by blindness, confusion, stun etc.
3692 /*if (yn("Transform into your draconic form?") == 'n')
3693 return 0;
3694 else*/ if (!scales && !scale_mail && u.uen <= EN_BABY_DRAGON) {
3695 You("don't have the energy to polymorph. You need at least %d!",EN_BABY_DRAGON);
3696 return 0;
3697 } else {
3698 /* Check if you can do the adult form */
3699 if (u.ulevel > 13 && u.uen > EN_ADULT_DRAGON ||
3700 scales && u.uen > EN_BABY_DRAGON || scale_mail) {
3701 /* If you have scales, energy cost is less */
3702 /* If you have scale mail, there is no cost! */
3703 if (!scale_mail) {
3704 if (scales) u.uen -= EN_BABY_DRAGON;
3705 else u.uen -= EN_ADULT_DRAGON;
3708 draconic.mon = Role_if(PM_ACID_MAGE) ? PM_YELLOW_DRAGON : Role_if(PM_FLAME_MAGE) ?
3709 PM_RED_DRAGON : Role_if(PM_ICE_MAGE) ? PM_WHITE_DRAGON : Role_if(PM_POISON_MAGE) ? PM_GREEN_DRAGON : PM_BLUE_DRAGON;
3710 draconic.merge = scales || scale_mail;
3711 /* Otherwise use the baby form */
3712 } else {
3713 if (!scales) u.uen -= EN_BABY_DRAGON;
3715 draconic.mon = Role_if(PM_ACID_MAGE) ? PM_BABY_YELLOW_DRAGON : Role_if(PM_FLAME_MAGE) ?
3716 PM_BABY_RED_DRAGON : Role_if(PM_ICE_MAGE) ? PM_BABY_WHITE_DRAGON : Role_if(PM_POISON_MAGE) ? PM_BABY_GREEN_DRAGON : PM_BABY_BLUE_DRAGON;
3717 draconic.merge = scales;
3719 draconic.reqtime = 2;
3720 if (mvitals[draconic.mon].mvflags & G_GENOD)
3721 draconic.merge = FALSE;
3722 set_occupation(mage_transform,
3723 "transforming into your draconic form", 0);
3724 You("begin the transformation ritual.");
3725 return 1;
3728 /* Moulds and ungenomolds _must_ be able to polymorph at will. Otherwise they would just suck. --Amy */
3730 if (Race_if(PM_DOPPELGANGER) || Role_if(PM_SHAPESHIFTER) || Race_if(PM_HEMI_DOPPELGANGER) || Race_if(PM_MOULD) || Race_if(PM_DEATHMOLD) || Race_if(PM_UNGENOMOLD) || Race_if(PM_WARPER)) {
3732 if (!u.youpolyamount) {
3733 pline("You have no free polymorphs left!");
3734 return 0;
3737 pline("You have %d free polymorphs left.", u.youpolyamount);
3739 if (yn("Polymorph at will?") == 'n')
3740 return 0;
3741 else if (u.uen < EN_DOPP) {
3742 You("don't have the energy to polymorph! You need at least %d!",EN_DOPP);
3743 return 0;
3744 } else {
3746 if (!(uwep && uwep->oartifact == ART_SCHWILILILILI_MORPH && rn2(2))) u.youpolyamount--;
3747 u.uen -= EN_DOPP;
3748 if (multi >= 0) {
3749 if (occupation) stop_occupation();
3750 else nomul(0, 0, FALSE);
3752 polyself(FALSE);
3753 if (Upolyd) { /* You actually polymorphed */
3754 u.uen -= 5 * mons[u.umonnum].mlevel;
3755 if (u.uen < 0) {
3756 morehungry(-u.uen);
3757 u.uen = 0;
3760 return 1;
3762 } else if ( (Race_if(PM_HUMAN_WEREWOLF) || Race_if(PM_AK_THIEF_IS_DEAD_) || Role_if(PM_LUNATIC) ) && !u.werepolymorphtime &&
3763 (!Upolyd || u.umonnum == u.ulycn)) {
3765 if (u.ulycn == PM_WERESOLDIERANT) somanymana = 15;
3766 if (u.ulycn == PM_WEREWOLF) somanymana = 20;
3767 if (u.ulycn == PM_WEREPIRANHA) somanymana = 20;
3768 if (u.ulycn == PM_WEREEEL) somanymana = 25;
3769 if (u.ulycn == PM_WEREKRAKEN) somanymana = 45;
3770 if (u.ulycn == PM_WEREFLYFISH) somanymana = 45;
3771 if (u.ulycn == PM_WEREPANTHER) somanymana = 30;
3772 if (u.ulycn == PM_WERETIGER) somanymana = 30;
3773 if (u.ulycn == PM_WERESNAKE) somanymana = 20;
3774 if (u.ulycn == PM_WERECOW) somanymana = 20;
3775 if (u.ulycn == PM_WEREBEAR) somanymana = 75;
3776 if (u.ulycn == PM_WEREPHANT) somanymana = 75;
3777 if (u.ulycn == PM_WEREVORTEX) somanymana = 50;
3778 if (u.ulycn == PM_WERETROLL) somanymana = 50;
3779 if (u.ulycn == PM_WEREGIANT) somanymana = 50;
3780 if (u.ulycn == PM_WEREGHOST) somanymana = 30;
3781 if (u.ulycn == PM_WERECOCKATRICE) somanymana = 60;
3782 if (u.ulycn == PM_WERELICH) somanymana = 100;
3783 if (u.ulycn == PM_UN_IN_PROTECT_MODE) somanymana = 100;
3784 if (u.ulycn == PM_WEREDEMON) somanymana = 100;
3785 if (u.ulycn == PM_WEREMINDFLAYER) somanymana = 150;
3786 if (u.ulycn == PM_VORPAL_WERE_ALHOONTRICE_ZOMBIE) somanymana = 150;
3787 if (u.ulycn == PM_WEREJABBERWOCK) somanymana = 200;
3788 if (u.ulycn == PM_WEREWEDGESANDAL) somanymana = 80;
3789 if (u.ulycn == PM_WEREHUGGINGBOOT) somanymana = 120;
3790 if (u.ulycn == PM_WEREPEEPTOE) somanymana = 140;
3791 if (u.ulycn == PM_WERESEXYLEATHERPUMP) somanymana = 160;
3792 if (u.ulycn == PM_WEREBLOCKHEELEDCOMBATBOOT) somanymana = 160;
3793 if (u.ulycn == PM_WERECOMBATSTILETTO) somanymana = 200;
3794 if (u.ulycn == PM_WEREBEAUTIFULFUNNELHEELEDPUMP) somanymana = 240;
3795 if (u.ulycn == PM_WEREPROSTITUTESHOE) somanymana = 240;
3796 if (u.ulycn == PM_WERESTILETTOSANDAL) somanymana = 250;
3797 if (u.ulycn == PM_WEREUNFAIRSTILETTO) somanymana = 260;
3798 if (u.ulycn == PM_WEREWINTERSTILETTO) somanymana = 300;
3800 squeakamount = somanymana;
3801 /* we can now use the squeaking skill to reduce the cost */
3803 if (!PlayerCannotUseSkills && somanymana > 2) {
3804 switch (P_SKILL(P_SQUEAKING)) {
3805 case P_BASIC: somanymana *= 9; somanymana /= 10; break;
3806 case P_SKILLED: somanymana *= 8; somanymana /= 10; break;
3807 case P_EXPERT: somanymana *= 7; somanymana /= 10; break;
3808 case P_MASTER: somanymana *= 6; somanymana /= 10; break;
3809 case P_GRAND_MASTER: somanymana *= 5; somanymana /= 10; break;
3810 case P_SUPREME_MASTER: somanymana *= 4; somanymana /= 10; break;
3811 default: break;
3815 if (yn("Change lycanthropic form?") == 'n')
3816 return 0;
3817 else if (u.ulycn == NON_PM) {
3818 /* Very serious */
3819 You("are no longer a lycanthrope!");
3820 } else if (u.ulevel <= 2) {
3821 You("can't invoke the change at will yet.");
3822 return 0;
3823 } else if (u.uen < somanymana) {
3824 You("don't have the energy to change form! You need at least %d!", somanymana);
3825 return 0;
3826 } else {
3827 /* Committed to the change now */
3828 u.uen -= somanymana;
3829 u.werepolymorphtime = rnz(2000);
3830 pline("You have to wait %d turns until you can use the ability to polymorph into a werecreature again.", u.werepolymorphtime);
3831 if (!Upolyd) {
3832 if (multi >= 0) {
3833 if (occupation) stop_occupation();
3834 else nomul(0, 0, FALSE);
3836 you_were();
3837 } else {
3838 if (!Race_if(PM_UNGENOMOLD)) rehumanize();
3839 else polyself(FALSE);
3842 while (squeakamount > 40) {
3843 use_skill(P_SQUEAKING, 1);
3844 squeakamount -= 40;
3846 use_skill(P_SQUEAKING, 1);
3848 return 1;
3850 } else {
3851 pline("You can't polymorph at will%s.",
3852 ((Role_if(PM_FLAME_MAGE) || Role_if(PM_ELECTRIC_MAGE) || Role_if(PM_POISON_MAGE) || Role_if(PM_LUNATIC) || Role_if(PM_ACID_MAGE) || Role_if(PM_ICE_MAGE) || Race_if(PM_HUMAN_WEREWOLF) || Race_if(PM_AK_THIEF_IS_DEAD_) || Race_if(PM_DOPPELGANGER) || Role_if(PM_SHAPESHIFTER) || Race_if(PM_HEMI_DOPPELGANGER)) ?
3853 " yet" : ""));
3854 return 0;
3857 flags.botl = 1;
3858 return 1;
3861 /* doing stuff like putting on armor when you can't, or opening a door without hands, should have a bigger chance
3862 * of success if you're highly skilled at polymorphing. This function is used in many places --Amy */
3863 boolean
3864 polyskillchance()
3866 register int percentualchance = 0;
3867 register int enchantplant = 0;
3869 if (!PlayerCannotUseSkills) {
3870 switch (P_SKILL(P_POLYMORPHING)) {
3872 case P_BASIC: percentualchance = 15; break;
3873 case P_SKILLED: percentualchance = 30; break;
3874 case P_EXPERT: percentualchance = 45; break;
3875 case P_MASTER: percentualchance = 60; break;
3876 case P_GRAND_MASTER: percentualchance = 75; break;
3877 case P_SUPREME_MASTER: percentualchance = 90; break;
3878 default: percentualchance = 0; break;
3882 if (rn2(100) < percentualchance) return TRUE;
3884 else if (powerfulimplants() && uimplant && objects[uimplant->otyp].oc_charged && uimplant->spe > 0 ) {
3885 enchantplant = uimplant->spe;
3886 while (enchantplant > 0) {
3887 if (!rn2(10)) return TRUE;
3888 enchantplant--;
3889 if (enchantplant < 0) enchantplant = 0; /* fail safe, should never happen */
3893 /* if we get here, always return false because you didn't succeed on any of the "can perform the action anyway" checks */
3894 return FALSE;
3897 /* are you eligible for the "handless" effects of implants? If you don't have hands and aren't a transformer, yes.
3898 * But some other races are handicapped enough that I decide they deserve this bonus too. --Amy */
3899 boolean
3900 powerfulimplants()
3902 if (nohands(youmonst.data) && !Race_if(PM_TRANSFORMER)) return TRUE;
3903 if (Race_if(PM_WEAPON_BUG) && !Upolyd) return TRUE; /* the movement restriction is a big handicap */
3904 if (Race_if(PM_JELLY) && !Upolyd) return TRUE; /* permablind and can't pick up items */
3905 if (Race_if(PM_OCTOPODE)) return TRUE; /* can't wear armor, even while polymorphed! */
3906 if (Race_if(PM_SATRE) && !Upolyd) return TRUE; /* equipment restrictions */
3907 if (Race_if(PM_ELONA_SNAIL) && !Upolyd) return TRUE; /* equipment restrictions */
3908 if (Race_if(PM_HUMAN_WRAITH)) return TRUE; /* loses maxHP permanently when equipping stuff */
3909 if (Race_if(PM_PLAYER_GLORKUM)) return TRUE; /* is so weird that it always gets the bonus */
3910 if (tech_inuse(T_IMPLANTED_SYMBIOSIS) && uactivesymbiosis && uimplant) return TRUE;
3911 if (uarm && uarm->oartifact == ART_KUSE_MUSE) return TRUE;
3913 return FALSE;
3916 /* are you eligible for getting your symbiote's resistances? depends on your symbiosis skill level --Amy
3917 * this function ensures that your symbiote exists, otherwise it returns FALSE */
3918 boolean
3919 powerfulsymbiosis()
3921 if (!uactivesymbiosis) return FALSE;
3923 if (!PlayerCannotUseSkills) {
3924 if (P_SKILL(P_SYMBIOSIS) >= P_MASTER) return TRUE;
3925 if (Role_if(PM_SYMBIANT) && (P_SKILL(P_SYMBIOSIS) >= P_EXPERT)) return TRUE;
3928 return FALSE;
3931 static void
3932 merge_with_armor()
3934 /* This function does hides the armor being worn
3935 * It currently assumes that you are changing into a dragon
3936 * Should check that monster being morphed into is not genocided
3937 * see do_merge above for correct use
3939 if ((Race_if(PM_DOPPELGANGER) || Role_if(PM_SHAPESHIFTER) || Race_if(PM_HEMI_DOPPELGANGER)) && !uarm->cursed && uarmu &&
3940 !uarmu->cursed) {
3941 struct obj *otmp = uarmu;
3942 You("quickly remove your shirt as you start to change.");
3943 setworn((struct obj *)0, otmp->owornmask & W_ARMU);
3944 dropx(otmp);
3946 You("merge with your scaly armor.");
3947 uskin = uarm;
3948 uarm = (struct obj *)0;
3949 /* save/restore hack */
3950 uskin->owornmask |= I_SPECIAL;
3954 #if 0 /* What the f*** is this for? -- KMH */
3955 static void
3956 special_poly()
3958 char buf[BUFSZ];
3959 int old_light, new_light;
3960 int mntmp = NON_PM;
3961 int tries=0;
3963 old_light = (u.umonnum >= LOW_PM) ? emits_light(youmonst.data) : 0;
3964 do {
3965 getlin("Become what kind of monster? [type the name]", buf);
3966 mntmp = name_to_mon(buf);
3967 if (mntmp < LOW_PM)
3968 pline("I've never heard of such monsters.");
3969 /* Note: humans are illegal as monsters, but an
3970 * illegal monster forces newman(), which is what we
3971 * want if they specified a human.... */
3973 /* [Tom] gnomes are polyok, so this doesn't apply for
3974 player gnomes */
3975 /* WAC but we want to catch player gnomes and not
3976 so add an extra check */
3977 else if (!polyok(&mons[mntmp]) &&
3978 (Role_elven ? !is_elf(&mons[mntmp]) :
3979 Role_if(PM_DWARF) ? !is_gnome(&mons[mntmp]) :
3980 /* WAC
3981 * should always fail (for now) gnome check
3982 * unless gnomes become not polyok. Then, it'll
3983 * still work ;B
3985 Role_if(PM_GNOME) ? !is_gnome(&mons[mntmp]) :
3986 !is_human(&mons[mntmp])))
3987 You("cannot polymorph into that.");
3988 else if (!mvitals[mntmp].eaten && (rn2((u.ulevel + 25)) < 20)) {
3989 You("don't have the knowledge to polymorph into that.");
3990 return; /* Nice try */
3991 } else {
3992 You("attempt an unfamiliar polymorph.");
3993 break;
3995 } while(++tries < 5);
3996 if (tries==5) {
3997 pline(thats_enough_tries);
3998 return;
3999 } else if (polymon(mntmp)) {
4000 /* same as made_change above */
4001 new_light = (u.umonnum >= LOW_PM) ? emits_light(youmonst.data) : 0;
4002 if (old_light != new_light) {
4003 if (old_light)
4004 del_light_source(LS_MONSTER, (void *)&youmonst);
4005 if (new_light == 1) ++new_light; /* otherwise it's undetectable */
4006 if (new_light)
4007 new_light_source(u.ux, u.uy, new_light,
4008 LS_MONSTER, (void *)&youmonst);
4011 return;
4013 #endif
4016 #endif /* OVLB */
4018 /*polyself.c*/