1 /* SCCS Id: @(#)spell.c 3.4 2003/01/17 */
2 /* Copyright (c) M. Stephenson 1988 */
3 /* NetHack may be freely redistributed. See license for details. */
9 static NEARDATA
int delay
; /* moves left for this spell */
10 static NEARDATA
int end_delay
; /* when to stop studying */
11 static NEARDATA
struct obj
*book
; /* last/current book being xscribed */
13 /* spellmenu arguments; 0 thru n-1 used as spl_book[] index when swapping */
14 #define SPELLMENU_CAST (-2)
15 #define SPELLMENU_VIEW (-1)
17 #define KEEN 10000 /* memory increase reading the book */
18 #define DUNADAN_KEEN 5000 /* memory increase reading the book */
19 #define CAST_BOOST 500 /* memory increase for successful casting */
20 #define DUNADAN_CAST_BOOST 250 /* memory increase for successful casting */
21 #define MAX_KNOW 200000 /* Absolute Max timeout */
22 #define MAX_CAN_STUDY 190000 /* Can study while timeout is less than */
24 #define MAX_STUDY_TIME 300 /* Max time for one study session */
25 #define MAX_SPELL_STUDY 30 /* Uses before spellbook crumbles */
27 #define spellknow(spell) spl_book[spell].sp_know
28 #define spellmemorize(spell) spl_book[spell].sp_memorize
30 static NEARDATA
const char revivables
[] = { ALLOW_FLOOROBJ
, FOOD_CLASS
, 0 };
32 static const char all_count
[] = { ALLOW_COUNT
, ALL_CLASSES
, 0 };
33 static const char allnoncount
[] = { ALL_CLASSES
, 0 };
35 #define spellev(spell) spl_book[spell].sp_lev
36 #define spellid(spell) spl_book[spell].sp_id
37 #define spellname(spell) OBJ_NAME(objects[spellid(spell)])
38 #define spellet(spell) \
39 ((char)((spell < 26) ? ('a' + spell) : \
40 (spell < 52) ? ('A' + spell - 26) : \
41 (spell < 78) ? ('0' + spell - 52) : \
42 (spell < 104) ? ('a' + spell - 78) : \
43 (spell < 130) ? ('A' + spell - 104) : \
44 (spell < 156) ? ('0' + spell - 130) : 0 ))
46 STATIC_DCL
int spell_let_to_idx(CHAR_P
);
47 STATIC_DCL boolean
cursed_book(struct obj
*bp
);
48 STATIC_DCL boolean
confused_book(struct obj
*);
49 STATIC_DCL
void deadbook(struct obj
*);
50 STATIC_PTR
int learn(void);
51 STATIC_DCL
void do_reset_learn(void);
52 STATIC_DCL boolean
getspell(int *, BOOLEAN_P
);
53 STATIC_DCL boolean
dospellmenu(const char *,int,int *, int);
54 STATIC_DCL
int percent_success(int);
55 STATIC_DCL
void cast_protection(void);
56 STATIC_DCL
void cast_reflection(void);
57 STATIC_DCL
void spell_backfire(int);
58 STATIC_DCL
const char *spelltypemnemonic(int);
59 static int spell_dash(void);
60 STATIC_DCL
void boostknow(int, int);
61 STATIC_DCL
void drainknow(int, int);
62 STATIC_DCL
void incrnknow(int, BOOLEAN_P
);
65 spell_known(int sbook_id
)
70 while (spl_book
[i
].sp_id
!= NO_SPELL
&& i
< MAXSPELL
) {
71 if (spl_book
[i
].sp_id
== sbook_id
) return(TRUE
);
79 /* The roles[] table lists the role-specific values for tuning
84 * Arc are aware of magic through historical research
85 * Bar abhor magic (Conan finds it "interferes with his animal instincts")
86 * Cav are ignorant to magic
87 * Hea are very aware of healing magic through medical research
88 * Kni are moderately aware of healing from Paladin training
89 * Mon use magic to attack and defend in lieu of weapons and armor
90 * Pri are very aware of healing magic through theological research
91 * Ran avoid magic, preferring to fight unseen and unheard
92 * Rog are moderately aware of magic through trickery
93 * Sam have limited magical awareness, prefering meditation to conjuring
94 * Tou are aware of magic from all the great films they have seen
95 * Val have limited magical awareness, prefering fighting
96 * Wiz are trained mages
98 * The arms penalty is lessened for trained fighters Bar, Kni, Ran,
100 * the penalty is its metal interference, not encumbrance.
101 * The `spelspec' is a single spell which is fundamentally easier
102 * for that role to cast.
104 * spelspec, spelsbon:
105 * Arc map masters (SPE_MAGIC_MAPPING)
106 * Bar fugue/berserker (SPE_HASTE_SELF)
107 * Cav born to dig (SPE_DIG)
108 * Hea to heal (SPE_CURE_SICKNESS)
109 * Kni to turn back evil (SPE_TURN_UNDEAD)
110 * Mon to preserve their abilities (SPE_RESTORE_ABILITY)
111 * Pri to bless (SPE_REMOVE_CURSE)
112 * Ran to hide (SPE_INVISIBILITY)
113 * Rog to find loot (SPE_DETECT_TREASURE)
114 * Sam to be At One (SPE_CLAIRVOYANCE)
115 * Tou to smile (SPE_CHARM_MONSTER)
116 * Val control lightning (SPE_LIGHTNING)
117 * Wiz all really, but SPE_MAGIC_MISSILE is their party trick
118 * Yeo guard doors (SPE_KNOCK)
120 * See percent_success() below for more comments.
122 * uarmbon, uarmsbon, uarmhbon, uarmgbon, uarmfbon:
123 * Fighters find body armour & shield a little less limiting.
124 * Headgear, Gauntlets and Footwear are not role-specific (but
125 * still have an effect, except helm of brilliance, which is designed
126 * to permit magic-use).
129 #define uarmhbon 3 /* Metal helmets interfere with the mind */
130 #define uarmgbon 5 /* Casting channels through the hands */
131 #define uarmfbon 1 /* All metal interferes to some degree */
133 /* since the spellbook itself doesn't blow up, don't say just "explodes" */
134 static const char explodes
[] = "radiates explosive energy";
136 /* convert an alnum into a number in the range 0..61, or -1 if not an alnum */
138 spell_let_to_idx(ilet
)
144 if (indx
>= 0 && indx
< 26) return indx
;
146 if (indx
>= 0 && indx
< 26) return indx
+ 26;
148 if (indx
>= 0 && indx
< 10) return indx
+ 52;
153 undo_barfloodC(x
, y
, roomcnt
)
157 if (levl
[x
][y
].typ
!= IRONBARS
)
162 /* Get rid of bars at x, y */
163 levl
[x
][y
].typ
= ROOM
;
164 blockorunblock_point(x
,y
);
168 /* TRUE: book should be destroyed by caller */
173 int lev
= objects
[bp
->otyp
].oc_level
;
177 You_feel("a wrenching sensation.");
178 if (PlayerHearsSoundEffects
) pline(issoviet
? "Tam net nikakoy zashchity. Tam net nikakoy nadezhdy. Yedinstvennoye, chto yest'? Uverennost' v tom, chto vy, igrok, budet umeret' uzhasnoy i muchitel'noy smert'yu." : "SCHRING!");
179 tele(); /* teleport him */
182 You_feel("threatened.");
186 /* [Tom] lowered this (used to be 100,250) */
187 make_blinded(Blinded
+ rn1(50,25),TRUE
);
193 pline("These runes were just too much to comprehend.");
194 make_confused(HConfusion
+ rn1(7,16),FALSE
);
197 pline_The("book was coated with contact poison!");
199 if (uarmg
->oerodeproof
|| (Race_if(PM_CHIQUAI
) && rn2(4)) || (uarmg
->oartifact
&& rn2(4)) || (objects
[uarmg
->otyp
].oc_material
== MT_GREEN_STEEL
&& rn2(2)) || !is_corrodeable(uarmg
)) {
200 Your("gloves seem unaffected.");
201 } else if (uarmg
->oeroded2
< MAX_ERODE
) {
202 if (uarmg
->greased
) {
203 grease_protect(uarmg
, "gloves", &youmonst
);
204 } else if (!rn2(2) || !(uarmf
&& uarmf
->oartifact
== ART_LUISA_S_IRRESISTIBLE_CHARM
) ) {
205 Your("gloves corrode%s!",
206 uarmg
->oeroded2
+1 == MAX_ERODE
?
207 " completely" : uarmg
->oeroded2
?
212 Your("gloves %s completely corroded.",
213 Blind
? "feel" : "look");
216 /* temp disable in_use; death should not destroy the book */
218 losestr(StrongPoison_resistance
? 1 : Poison_resistance
? rno(3) : rnd(5), TRUE
);
219 losehp(rnd(Poison_resistance
? 6 : 10),
220 "contact-poisoned spellbook", KILLED_BY_AN
);
224 if(Antimagic
&& !Race_if(PM_KUTAR
) && rn2(StrongAntimagic
? 20 : 5) ) {
225 shieldeff(u
.ux
, u
.uy
);
226 pline_The("book %s, but you are unharmed!", explodes
);
228 pline("As you read the book, it %s in your %s!",
229 explodes
, body_part(FACE
));
230 losehp(2*rnd(10)+5, "exploding rune", KILLED_BY_AN
);
237 return (bp
->spe
< 0) ? TRUE
: FALSE
;
240 /* study while confused: returns TRUE if the book is destroyed */
242 confused_book(spellbook
)
243 struct obj
*spellbook
;
245 boolean gone
= FALSE
;
247 if (!rn2(50) && spellbook
->otyp
!= SPE_BOOK_OF_THE_DEAD
) {
248 spellbook
->in_use
= TRUE
; /* in case called from learn */
249 pline("Being confused you have difficulties in controlling your actions.");
250 display_nhwindow(WIN_MESSAGE
, FALSE
);
251 You("accidentally tear the spellbook to pieces.");
252 if (!objects
[spellbook
->otyp
].oc_name_known
&&
253 !objects
[spellbook
->otyp
].oc_uname
)
255 if (carried(spellbook
)) useup(spellbook
);
256 else useupf(spellbook
, 1L);
259 You("find yourself reading the %s line over and over again.",
260 spellbook
== book
? "next" : "first");
266 do_lockfloodg(x
, y
, poolcnt
)
270 register struct monst
*mtmp
;
271 register struct trap
*ttmp
;
272 int randomamount
= 0;
273 int randomx
, randomy
;
274 if (!rn2(25)) randomamount
+= rnz(2);
275 if (!rn2(125)) randomamount
+= rnz(5);
276 if (!rn2(625)) randomamount
+= rnz(20);
277 if (!rn2(3125)) randomamount
+= rnz(50);
279 if (!rn2(25)) randomamount
+= rnz(2);
280 if (!rn2(125)) randomamount
+= rnz(5);
281 if (!rn2(625)) randomamount
+= rnz(20);
282 if (!rn2(3125)) randomamount
+= rnz(50);
284 if (rn2(5)) randomamount
= 0;
286 while (randomamount
) {
288 randomx
= rn1(COLNO
-3,2);
289 randomy
= rn2(ROWNO
);
290 if (isok(randomx
, randomy
) && ((levl
[randomx
][randomy
].wall_info
& W_NONDIGGABLE
) == 0) && (levl
[randomx
][randomy
].typ
== ROOM
|| levl
[randomx
][randomy
].typ
== CORR
|| (levl
[randomx
][randomy
].typ
== DOOR
&& levl
[randomx
][randomy
].doormask
== D_NODOOR
) ) ) {
292 if (rn2(3)) doorlockX(randomx
, randomy
, TRUE
);
294 if (levl
[randomx
][randomy
].typ
!= DOOR
) levl
[randomx
][randomy
].typ
= STONE
;
295 else levl
[randomx
][randomy
].typ
= CROSSWALL
;
296 blockorunblock_point(randomx
,randomy
);
297 if (!(levl
[randomx
][randomy
].wall_info
& W_EASYGROWTH
)) levl
[randomx
][randomy
].wall_info
|= W_HARDGROWTH
;
298 del_engr_at(randomx
, randomy
);
300 if ((mtmp
= m_at(randomx
, randomy
)) != 0) {
301 (void) minliquid(mtmp
);
303 newsym(randomx
,randomy
);
309 if (rn2(3)) doorlockX(x
, y
, TRUE
);
311 if ((rn2(1 + distmin(u
.ux
, u
.uy
, x
, y
))) ||
312 (sobj_at(BOULDER
, x
, y
)) || (levl
[x
][y
].wall_info
& W_NONDIGGABLE
) != 0 || (levl
[x
][y
].typ
!= CORR
&& levl
[x
][y
].typ
!= ROOM
&& (levl
[x
][y
].typ
!= DOOR
|| levl
[x
][y
].doormask
!= D_NODOOR
) ))
317 if (!((*(int *)poolcnt
) && (x
== u
.ux
) && (y
== u
.uy
))) {
318 /* Put a wall at x, y */
319 if (levl
[x
][y
].typ
!= DOOR
) levl
[x
][y
].typ
= STONE
;
320 else levl
[x
][y
].typ
= CROSSWALL
;
321 blockorunblock_point(x
,y
);
322 if (!(levl
[x
][y
].wall_info
& W_EASYGROWTH
)) levl
[x
][y
].wall_info
|= W_HARDGROWTH
;
325 if ((mtmp
= m_at(x
, y
)) != 0) {
326 (void) minliquid(mtmp
);
330 } else if ((x
== u
.ux
) && (y
== u
.uy
)) {
337 do_treefloodg(x
, y
, poolcnt
)
341 register struct monst
*mtmp
;
342 register struct trap
*ttmp
;
343 int randomamount
= 0;
344 int randomx
, randomy
;
345 if (!rn2(25)) randomamount
+= rnz(2);
346 if (!rn2(125)) randomamount
+= rnz(5);
347 if (!rn2(625)) randomamount
+= rnz(20);
348 if (!rn2(3125)) randomamount
+= rnz(50);
350 if (!rn2(25)) randomamount
+= rnz(2);
351 if (!rn2(125)) randomamount
+= rnz(5);
352 if (!rn2(625)) randomamount
+= rnz(20);
353 if (!rn2(3125)) randomamount
+= rnz(50);
355 if (rn2(5)) randomamount
= 0;
357 while (randomamount
) {
359 randomx
= rn1(COLNO
-3,2);
360 randomy
= rn2(ROWNO
);
361 if (isok(randomx
, randomy
) && (levl
[randomx
][randomy
].typ
== ROOM
|| levl
[randomx
][randomy
].typ
== CORR
) ) {
362 levl
[randomx
][randomy
].typ
= TREE
;
363 blockorunblock_point(randomx
,randomy
);
364 if (!(levl
[randomx
][randomy
].wall_info
& W_EASYGROWTH
)) levl
[randomx
][randomy
].wall_info
|= W_HARDGROWTH
;
365 del_engr_at(randomx
, randomy
);
367 if ((mtmp
= m_at(randomx
, randomy
)) != 0) {
368 (void) minliquid(mtmp
);
370 newsym(randomx
,randomy
);
375 if ((rn2(1 + distmin(u
.ux
, u
.uy
, x
, y
))) ||
376 (sobj_at(BOULDER
, x
, y
)) || (levl
[x
][y
].typ
!= ROOM
&& levl
[x
][y
].typ
!= CORR
) || MON_AT(x
, y
) )
381 if (!((*(int *)poolcnt
) && (x
== u
.ux
) && (y
== u
.uy
))) {
382 /* Put a pool at x, y */
383 levl
[x
][y
].typ
= TREE
;
384 blockorunblock_point(x
,y
);
385 if (!(levl
[x
][y
].wall_info
& W_EASYGROWTH
)) levl
[x
][y
].wall_info
|= W_HARDGROWTH
;
388 if ((mtmp
= m_at(x
, y
)) != 0) {
389 (void) minliquid(mtmp
);
393 } else if ((x
== u
.ux
) && (y
== u
.uy
)) {
400 do_gravefloodg(x
, y
, poolcnt
)
404 register struct monst
*mtmp
;
405 register struct trap
*ttmp
;
406 int randomamount
= 0;
407 int randomx
, randomy
;
408 if (!rn2(25)) randomamount
+= rnz(2);
409 if (!rn2(125)) randomamount
+= rnz(5);
410 if (!rn2(625)) randomamount
+= rnz(20);
411 if (!rn2(3125)) randomamount
+= rnz(50);
413 if (!rn2(25)) randomamount
+= rnz(2);
414 if (!rn2(125)) randomamount
+= rnz(5);
415 if (!rn2(625)) randomamount
+= rnz(20);
416 if (!rn2(3125)) randomamount
+= rnz(50);
418 if (rn2(5)) randomamount
= 0;
420 while (randomamount
) {
422 randomx
= rn1(COLNO
-3,2);
423 randomy
= rn2(ROWNO
);
424 if (isok(randomx
, randomy
) && (levl
[randomx
][randomy
].typ
== ROOM
|| levl
[randomx
][randomy
].typ
== CORR
) ) {
425 levl
[randomx
][randomy
].typ
= GRAVEWALL
;
426 blockorunblock_point(randomx
,randomy
);
427 if (!(levl
[randomx
][randomy
].wall_info
& W_EASYGROWTH
)) levl
[randomx
][randomy
].wall_info
|= W_HARDGROWTH
;
428 del_engr_at(randomx
, randomy
);
430 if ((mtmp
= m_at(randomx
, randomy
)) != 0) {
431 (void) minliquid(mtmp
);
433 newsym(randomx
,randomy
);
438 if ((rn2(1 + distmin(u
.ux
, u
.uy
, x
, y
))) ||
439 (sobj_at(BOULDER
, x
, y
)) || (levl
[x
][y
].typ
!= ROOM
&& levl
[x
][y
].typ
!= CORR
) || MON_AT(x
, y
) )
444 if (!((*(int *)poolcnt
) && (x
== u
.ux
) && (y
== u
.uy
))) {
445 /* Put a pool at x, y */
446 levl
[x
][y
].typ
= GRAVEWALL
;
447 blockorunblock_point(x
,y
);
448 if (!(levl
[x
][y
].wall_info
& W_EASYGROWTH
)) levl
[x
][y
].wall_info
|= W_HARDGROWTH
;
451 if ((mtmp
= m_at(x
, y
)) != 0) {
452 (void) minliquid(mtmp
);
456 } else if ((x
== u
.ux
) && (y
== u
.uy
)) {
463 do_tunnelfloodg(x
, y
, poolcnt
)
467 register struct monst
*mtmp
;
468 register struct trap
*ttmp
;
469 int randomamount
= 0;
470 int randomx
, randomy
;
471 if (!rn2(25)) randomamount
+= rnz(2);
472 if (!rn2(125)) randomamount
+= rnz(5);
473 if (!rn2(625)) randomamount
+= rnz(20);
474 if (!rn2(3125)) randomamount
+= rnz(50);
476 if (!rn2(25)) randomamount
+= rnz(2);
477 if (!rn2(125)) randomamount
+= rnz(5);
478 if (!rn2(625)) randomamount
+= rnz(20);
479 if (!rn2(3125)) randomamount
+= rnz(50);
481 if (rn2(5)) randomamount
= 0;
483 while (randomamount
) {
485 randomx
= rn1(COLNO
-3,2);
486 randomy
= rn2(ROWNO
);
487 if (isok(randomx
, randomy
) && (levl
[randomx
][randomy
].typ
== ROOM
|| levl
[randomx
][randomy
].typ
== CORR
) ) {
488 levl
[randomx
][randomy
].typ
= TUNNELWALL
;
489 blockorunblock_point(randomx
,randomy
);
490 if (!(levl
[randomx
][randomy
].wall_info
& W_EASYGROWTH
)) levl
[randomx
][randomy
].wall_info
|= W_HARDGROWTH
;
491 del_engr_at(randomx
, randomy
);
493 if ((mtmp
= m_at(randomx
, randomy
)) != 0) {
494 (void) minliquid(mtmp
);
496 newsym(randomx
,randomy
);
501 if ((rn2(1 + distmin(u
.ux
, u
.uy
, x
, y
))) ||
502 (sobj_at(BOULDER
, x
, y
)) || (levl
[x
][y
].typ
!= ROOM
&& levl
[x
][y
].typ
!= CORR
) || MON_AT(x
, y
) )
507 if (!((*(int *)poolcnt
) && (x
== u
.ux
) && (y
== u
.uy
))) {
508 /* Put a pool at x, y */
509 levl
[x
][y
].typ
= TUNNELWALL
;
510 blockorunblock_point(x
,y
);
511 if (!(levl
[x
][y
].wall_info
& W_EASYGROWTH
)) levl
[x
][y
].wall_info
|= W_HARDGROWTH
;
514 if ((mtmp
= m_at(x
, y
)) != 0) {
515 (void) minliquid(mtmp
);
519 } else if ((x
== u
.ux
) && (y
== u
.uy
)) {
526 do_farmfloodg(x
, y
, poolcnt
)
530 register struct monst
*mtmp
;
531 register struct trap
*ttmp
;
532 int randomamount
= 0;
533 int randomx
, randomy
;
534 if (!rn2(25)) randomamount
+= rnz(2);
535 if (!rn2(125)) randomamount
+= rnz(5);
536 if (!rn2(625)) randomamount
+= rnz(20);
537 if (!rn2(3125)) randomamount
+= rnz(50);
539 if (!rn2(25)) randomamount
+= rnz(2);
540 if (!rn2(125)) randomamount
+= rnz(5);
541 if (!rn2(625)) randomamount
+= rnz(20);
542 if (!rn2(3125)) randomamount
+= rnz(50);
544 if (rn2(5)) randomamount
= 0;
546 while (randomamount
) {
548 randomx
= rn1(COLNO
-3,2);
549 randomy
= rn2(ROWNO
);
550 if (isok(randomx
, randomy
) && (levl
[randomx
][randomy
].typ
== ROOM
|| levl
[randomx
][randomy
].typ
== CORR
) ) {
551 levl
[randomx
][randomy
].typ
= FARMLAND
;
552 blockorunblock_point(randomx
,randomy
);
553 if (!(levl
[randomx
][randomy
].wall_info
& W_EASYGROWTH
)) levl
[randomx
][randomy
].wall_info
|= W_HARDGROWTH
;
554 del_engr_at(randomx
, randomy
);
556 if ((mtmp
= m_at(randomx
, randomy
)) != 0) {
557 (void) minliquid(mtmp
);
559 newsym(randomx
,randomy
);
564 if ((rn2(1 + distmin(u
.ux
, u
.uy
, x
, y
))) ||
565 (sobj_at(BOULDER
, x
, y
)) || (levl
[x
][y
].typ
!= ROOM
&& levl
[x
][y
].typ
!= CORR
) || MON_AT(x
, y
) )
570 if (!((*(int *)poolcnt
) && (x
== u
.ux
) && (y
== u
.uy
))) {
571 /* Put a pool at x, y */
572 levl
[x
][y
].typ
= FARMLAND
;
573 blockorunblock_point(x
,y
);
574 if (!(levl
[x
][y
].wall_info
& W_EASYGROWTH
)) levl
[x
][y
].wall_info
|= W_HARDGROWTH
;
577 if ((mtmp
= m_at(x
, y
)) != 0) {
578 (void) minliquid(mtmp
);
582 } else if ((x
== u
.ux
) && (y
== u
.uy
)) {
589 do_mountainfloodg(x
, y
, poolcnt
)
593 register struct monst
*mtmp
;
594 register struct trap
*ttmp
;
595 int randomamount
= 0;
596 int randomx
, randomy
;
597 if (!rn2(25)) randomamount
+= rnz(2);
598 if (!rn2(125)) randomamount
+= rnz(5);
599 if (!rn2(625)) randomamount
+= rnz(20);
600 if (!rn2(3125)) randomamount
+= rnz(50);
602 if (!rn2(25)) randomamount
+= rnz(2);
603 if (!rn2(125)) randomamount
+= rnz(5);
604 if (!rn2(625)) randomamount
+= rnz(20);
605 if (!rn2(3125)) randomamount
+= rnz(50);
607 if (rn2(5)) randomamount
= 0;
609 while (randomamount
) {
611 randomx
= rn1(COLNO
-3,2);
612 randomy
= rn2(ROWNO
);
613 if (isok(randomx
, randomy
) && (levl
[randomx
][randomy
].typ
== ROOM
|| levl
[randomx
][randomy
].typ
== CORR
) ) {
614 levl
[randomx
][randomy
].typ
= MOUNTAIN
;
615 blockorunblock_point(randomx
,randomy
);
616 if (!(levl
[randomx
][randomy
].wall_info
& W_EASYGROWTH
)) levl
[randomx
][randomy
].wall_info
|= W_HARDGROWTH
;
617 del_engr_at(randomx
, randomy
);
619 if ((mtmp
= m_at(randomx
, randomy
)) != 0) {
620 (void) minliquid(mtmp
);
622 newsym(randomx
,randomy
);
627 if ((rn2(1 + distmin(u
.ux
, u
.uy
, x
, y
))) ||
628 (sobj_at(BOULDER
, x
, y
)) || (levl
[x
][y
].typ
!= ROOM
&& levl
[x
][y
].typ
!= CORR
) || MON_AT(x
, y
) )
633 if (!((*(int *)poolcnt
) && (x
== u
.ux
) && (y
== u
.uy
))) {
634 /* Put a pool at x, y */
635 levl
[x
][y
].typ
= MOUNTAIN
;
636 blockorunblock_point(x
,y
);
637 if (!(levl
[x
][y
].wall_info
& W_EASYGROWTH
)) levl
[x
][y
].wall_info
|= W_HARDGROWTH
;
640 if ((mtmp
= m_at(x
, y
)) != 0) {
641 (void) minliquid(mtmp
);
645 } else if ((x
== u
.ux
) && (y
== u
.uy
)) {
652 do_watertunnelfloodg(x
, y
, poolcnt
)
656 register struct monst
*mtmp
;
657 register struct trap
*ttmp
;
658 int randomamount
= 0;
659 int randomx
, randomy
;
660 if (!rn2(25)) randomamount
+= rnz(2);
661 if (!rn2(125)) randomamount
+= rnz(5);
662 if (!rn2(625)) randomamount
+= rnz(20);
663 if (!rn2(3125)) randomamount
+= rnz(50);
665 if (!rn2(25)) randomamount
+= rnz(2);
666 if (!rn2(125)) randomamount
+= rnz(5);
667 if (!rn2(625)) randomamount
+= rnz(20);
668 if (!rn2(3125)) randomamount
+= rnz(50);
670 if (rn2(5)) randomamount
= 0;
672 while (randomamount
) {
674 randomx
= rn1(COLNO
-3,2);
675 randomy
= rn2(ROWNO
);
676 if (isok(randomx
, randomy
) && (levl
[randomx
][randomy
].typ
== ROOM
|| levl
[randomx
][randomy
].typ
== CORR
) ) {
677 levl
[randomx
][randomy
].typ
= WATERTUNNEL
;
678 blockorunblock_point(randomx
,randomy
);
679 if (!(levl
[randomx
][randomy
].wall_info
& W_EASYGROWTH
)) levl
[randomx
][randomy
].wall_info
|= W_HARDGROWTH
;
680 del_engr_at(randomx
, randomy
);
682 if ((mtmp
= m_at(randomx
, randomy
)) != 0) {
683 (void) minliquid(mtmp
);
685 newsym(randomx
,randomy
);
690 if ((rn2(1 + distmin(u
.ux
, u
.uy
, x
, y
))) ||
691 (sobj_at(BOULDER
, x
, y
)) || (levl
[x
][y
].typ
!= ROOM
&& levl
[x
][y
].typ
!= CORR
) || MON_AT(x
, y
) )
696 if (!((*(int *)poolcnt
) && (x
== u
.ux
) && (y
== u
.uy
))) {
697 /* Put a pool at x, y */
698 levl
[x
][y
].typ
= WATERTUNNEL
;
699 blockorunblock_point(x
,y
);
700 if (!(levl
[x
][y
].wall_info
& W_EASYGROWTH
)) levl
[x
][y
].wall_info
|= W_HARDGROWTH
;
703 if ((mtmp
= m_at(x
, y
)) != 0) {
704 (void) minliquid(mtmp
);
708 } else if ((x
== u
.ux
) && (y
== u
.uy
)) {
715 do_icefloodg(x
, y
, poolcnt
)
719 register struct monst
*mtmp
;
720 register struct trap
*ttmp
;
721 int randomamount
= 0;
722 int randomx
, randomy
;
723 if (!rn2(25)) randomamount
+= rnz(2);
724 if (!rn2(125)) randomamount
+= rnz(5);
725 if (!rn2(625)) randomamount
+= rnz(20);
726 if (!rn2(3125)) randomamount
+= rnz(50);
728 if (!rn2(25)) randomamount
+= rnz(2);
729 if (!rn2(125)) randomamount
+= rnz(5);
730 if (!rn2(625)) randomamount
+= rnz(20);
731 if (!rn2(3125)) randomamount
+= rnz(50);
733 if (rn2(5)) randomamount
= 0;
735 while (randomamount
) {
737 randomx
= rn1(COLNO
-3,2);
738 randomy
= rn2(ROWNO
);
739 if (isok(randomx
, randomy
) && (levl
[randomx
][randomy
].typ
== ROOM
|| levl
[randomx
][randomy
].typ
== CORR
) ) {
740 levl
[randomx
][randomy
].typ
= ICE
;
741 del_engr_at(randomx
, randomy
);
743 if ((mtmp
= m_at(randomx
, randomy
)) != 0) {
744 (void) minliquid(mtmp
);
746 newsym(randomx
,randomy
);
751 if ((rn2(1 + distmin(u
.ux
, u
.uy
, x
, y
))) ||
752 (sobj_at(BOULDER
, x
, y
)) || (levl
[x
][y
].typ
!= ROOM
&& levl
[x
][y
].typ
!= CORR
) || MON_AT(x
, y
) )
757 if (!((*(int *)poolcnt
) && (x
== u
.ux
) && (y
== u
.uy
))) {
758 /* Put a pool at x, y */
759 levl
[x
][y
].typ
= ICE
;
762 if ((mtmp
= m_at(x
, y
)) != 0) {
763 (void) minliquid(mtmp
);
767 } else if ((x
== u
.ux
) && (y
== u
.uy
)) {
774 do_crystalwaterfloodg(x
, y
, poolcnt
)
778 register struct monst
*mtmp
;
779 register struct trap
*ttmp
;
780 int randomamount
= 0;
781 int randomx
, randomy
;
782 if (!rn2(25)) randomamount
+= rnz(2);
783 if (!rn2(125)) randomamount
+= rnz(5);
784 if (!rn2(625)) randomamount
+= rnz(20);
785 if (!rn2(3125)) randomamount
+= rnz(50);
787 if (!rn2(25)) randomamount
+= rnz(2);
788 if (!rn2(125)) randomamount
+= rnz(5);
789 if (!rn2(625)) randomamount
+= rnz(20);
790 if (!rn2(3125)) randomamount
+= rnz(50);
792 if (rn2(5)) randomamount
= 0;
794 while (randomamount
) {
796 randomx
= rn1(COLNO
-3,2);
797 randomy
= rn2(ROWNO
);
798 if (isok(randomx
, randomy
) && (levl
[randomx
][randomy
].typ
== ROOM
|| levl
[randomx
][randomy
].typ
== CORR
) ) {
799 levl
[randomx
][randomy
].typ
= CRYSTALWATER
;
800 del_engr_at(randomx
, randomy
);
802 if ((mtmp
= m_at(randomx
, randomy
)) != 0) {
803 (void) minliquid(mtmp
);
805 newsym(randomx
,randomy
);
810 if ((rn2(1 + distmin(u
.ux
, u
.uy
, x
, y
))) ||
811 (sobj_at(BOULDER
, x
, y
)) || (levl
[x
][y
].typ
!= ROOM
&& levl
[x
][y
].typ
!= CORR
) || MON_AT(x
, y
) )
816 if (!((*(int *)poolcnt
) && (x
== u
.ux
) && (y
== u
.uy
))) {
817 /* Put a pool at x, y */
818 levl
[x
][y
].typ
= CRYSTALWATER
;
821 if ((mtmp
= m_at(x
, y
)) != 0) {
822 (void) minliquid(mtmp
);
826 } else if ((x
== u
.ux
) && (y
== u
.uy
)) {
834 do_moorfloodg(x
, y
, poolcnt
)
838 register struct monst
*mtmp
;
839 register struct trap
*ttmp
;
840 int randomamount
= 0;
841 int randomx
, randomy
;
842 if (!rn2(25)) randomamount
+= rnz(2);
843 if (!rn2(125)) randomamount
+= rnz(5);
844 if (!rn2(625)) randomamount
+= rnz(20);
845 if (!rn2(3125)) randomamount
+= rnz(50);
847 if (!rn2(25)) randomamount
+= rnz(2);
848 if (!rn2(125)) randomamount
+= rnz(5);
849 if (!rn2(625)) randomamount
+= rnz(20);
850 if (!rn2(3125)) randomamount
+= rnz(50);
852 if (rn2(5)) randomamount
= 0;
854 while (randomamount
) {
856 randomx
= rn1(COLNO
-3,2);
857 randomy
= rn2(ROWNO
);
858 if (isok(randomx
, randomy
) && (levl
[randomx
][randomy
].typ
== ROOM
|| levl
[randomx
][randomy
].typ
== CORR
) ) {
859 levl
[randomx
][randomy
].typ
= MOORLAND
;
860 del_engr_at(randomx
, randomy
);
862 if ((mtmp
= m_at(randomx
, randomy
)) != 0) {
863 (void) minliquid(mtmp
);
865 newsym(randomx
,randomy
);
870 if ((rn2(1 + distmin(u
.ux
, u
.uy
, x
, y
))) ||
871 (sobj_at(BOULDER
, x
, y
)) || (levl
[x
][y
].typ
!= ROOM
&& levl
[x
][y
].typ
!= CORR
) || MON_AT(x
, y
) )
876 if (!((*(int *)poolcnt
) && (x
== u
.ux
) && (y
== u
.uy
))) {
877 /* Put a pool at x, y */
878 levl
[x
][y
].typ
= MOORLAND
;
881 if ((mtmp
= m_at(x
, y
)) != 0) {
882 (void) minliquid(mtmp
);
886 } else if ((x
== u
.ux
) && (y
== u
.uy
)) {
893 do_urinefloodg(x
, y
, poolcnt
)
897 register struct monst
*mtmp
;
898 register struct trap
*ttmp
;
899 int randomamount
= 0;
900 int randomx
, randomy
;
901 if (!rn2(25)) randomamount
+= rnz(2);
902 if (!rn2(125)) randomamount
+= rnz(5);
903 if (!rn2(625)) randomamount
+= rnz(20);
904 if (!rn2(3125)) randomamount
+= rnz(50);
906 if (!rn2(25)) randomamount
+= rnz(2);
907 if (!rn2(125)) randomamount
+= rnz(5);
908 if (!rn2(625)) randomamount
+= rnz(20);
909 if (!rn2(3125)) randomamount
+= rnz(50);
911 if (rn2(5)) randomamount
= 0;
913 while (randomamount
) {
915 randomx
= rn1(COLNO
-3,2);
916 randomy
= rn2(ROWNO
);
917 if (isok(randomx
, randomy
) && (levl
[randomx
][randomy
].typ
== ROOM
|| levl
[randomx
][randomy
].typ
== CORR
) ) {
918 levl
[randomx
][randomy
].typ
= URINELAKE
;
919 del_engr_at(randomx
, randomy
);
921 if ((mtmp
= m_at(randomx
, randomy
)) != 0) {
922 (void) minliquid(mtmp
);
924 newsym(randomx
,randomy
);
929 if ((rn2(1 + distmin(u
.ux
, u
.uy
, x
, y
))) ||
930 (sobj_at(BOULDER
, x
, y
)) || (levl
[x
][y
].typ
!= ROOM
&& levl
[x
][y
].typ
!= CORR
) || MON_AT(x
, y
) )
935 if (!((*(int *)poolcnt
) && (x
== u
.ux
) && (y
== u
.uy
))) {
936 /* Put a pool at x, y */
937 levl
[x
][y
].typ
= URINELAKE
;
940 if ((mtmp
= m_at(x
, y
)) != 0) {
941 (void) minliquid(mtmp
);
945 } else if ((x
== u
.ux
) && (y
== u
.uy
)) {
952 do_shiftingsandfloodg(x
, y
, poolcnt
)
956 register struct monst
*mtmp
;
957 register struct trap
*ttmp
;
958 int randomamount
= 0;
959 int randomx
, randomy
;
960 if (!rn2(25)) randomamount
+= rnz(2);
961 if (!rn2(125)) randomamount
+= rnz(5);
962 if (!rn2(625)) randomamount
+= rnz(20);
963 if (!rn2(3125)) randomamount
+= rnz(50);
965 if (!rn2(25)) randomamount
+= rnz(2);
966 if (!rn2(125)) randomamount
+= rnz(5);
967 if (!rn2(625)) randomamount
+= rnz(20);
968 if (!rn2(3125)) randomamount
+= rnz(50);
970 if (rn2(5)) randomamount
= 0;
972 while (randomamount
) {
974 randomx
= rn1(COLNO
-3,2);
975 randomy
= rn2(ROWNO
);
976 if (isok(randomx
, randomy
) && (levl
[randomx
][randomy
].typ
== ROOM
|| levl
[randomx
][randomy
].typ
== CORR
) ) {
977 levl
[randomx
][randomy
].typ
= SHIFTINGSAND
;
978 del_engr_at(randomx
, randomy
);
980 if ((mtmp
= m_at(randomx
, randomy
)) != 0) {
981 (void) minliquid(mtmp
);
983 newsym(randomx
,randomy
);
988 if ((rn2(1 + distmin(u
.ux
, u
.uy
, x
, y
))) ||
989 (sobj_at(BOULDER
, x
, y
)) || (levl
[x
][y
].typ
!= ROOM
&& levl
[x
][y
].typ
!= CORR
) || MON_AT(x
, y
) )
994 if (!((*(int *)poolcnt
) && (x
== u
.ux
) && (y
== u
.uy
))) {
995 /* Put a pool at x, y */
996 levl
[x
][y
].typ
= SHIFTINGSAND
;
999 if ((mtmp
= m_at(x
, y
)) != 0) {
1000 (void) minliquid(mtmp
);
1004 } else if ((x
== u
.ux
) && (y
== u
.uy
)) {
1005 (*(int *)poolcnt
)--;
1011 do_styxfloodg(x
, y
, poolcnt
)
1015 register struct monst
*mtmp
;
1016 register struct trap
*ttmp
;
1017 int randomamount
= 0;
1018 int randomx
, randomy
;
1019 if (!rn2(25)) randomamount
+= rnz(2);
1020 if (!rn2(125)) randomamount
+= rnz(5);
1021 if (!rn2(625)) randomamount
+= rnz(20);
1022 if (!rn2(3125)) randomamount
+= rnz(50);
1024 if (!rn2(25)) randomamount
+= rnz(2);
1025 if (!rn2(125)) randomamount
+= rnz(5);
1026 if (!rn2(625)) randomamount
+= rnz(20);
1027 if (!rn2(3125)) randomamount
+= rnz(50);
1029 if (rn2(5)) randomamount
= 0;
1031 while (randomamount
) {
1033 randomx
= rn1(COLNO
-3,2);
1034 randomy
= rn2(ROWNO
);
1035 if (isok(randomx
, randomy
) && (levl
[randomx
][randomy
].typ
== ROOM
|| levl
[randomx
][randomy
].typ
== CORR
) ) {
1036 levl
[randomx
][randomy
].typ
= STYXRIVER
;
1037 del_engr_at(randomx
, randomy
);
1039 if ((mtmp
= m_at(randomx
, randomy
)) != 0) {
1040 (void) minliquid(mtmp
);
1042 newsym(randomx
,randomy
);
1047 if ((rn2(1 + distmin(u
.ux
, u
.uy
, x
, y
))) ||
1048 (sobj_at(BOULDER
, x
, y
)) || (levl
[x
][y
].typ
!= ROOM
&& levl
[x
][y
].typ
!= CORR
) || MON_AT(x
, y
) )
1051 (*(int *)poolcnt
)++;
1053 if (!((*(int *)poolcnt
) && (x
== u
.ux
) && (y
== u
.uy
))) {
1054 /* Put a pool at x, y */
1055 levl
[x
][y
].typ
= STYXRIVER
;
1058 if ((mtmp
= m_at(x
, y
)) != 0) {
1059 (void) minliquid(mtmp
);
1063 } else if ((x
== u
.ux
) && (y
== u
.uy
)) {
1064 (*(int *)poolcnt
)--;
1070 do_snowfloodg(x
, y
, poolcnt
)
1074 register struct monst
*mtmp
;
1075 register struct trap
*ttmp
;
1076 int randomamount
= 0;
1077 int randomx
, randomy
;
1078 if (!rn2(25)) randomamount
+= rnz(2);
1079 if (!rn2(125)) randomamount
+= rnz(5);
1080 if (!rn2(625)) randomamount
+= rnz(20);
1081 if (!rn2(3125)) randomamount
+= rnz(50);
1083 if (!rn2(25)) randomamount
+= rnz(2);
1084 if (!rn2(125)) randomamount
+= rnz(5);
1085 if (!rn2(625)) randomamount
+= rnz(20);
1086 if (!rn2(3125)) randomamount
+= rnz(50);
1088 if (rn2(5)) randomamount
= 0;
1090 while (randomamount
) {
1092 randomx
= rn1(COLNO
-3,2);
1093 randomy
= rn2(ROWNO
);
1094 if (isok(randomx
, randomy
) && (levl
[randomx
][randomy
].typ
== ROOM
|| levl
[randomx
][randomy
].typ
== CORR
) ) {
1095 levl
[randomx
][randomy
].typ
= SNOW
;
1096 del_engr_at(randomx
, randomy
);
1098 if ((mtmp
= m_at(randomx
, randomy
)) != 0) {
1099 (void) minliquid(mtmp
);
1101 newsym(randomx
,randomy
);
1106 if ((rn2(1 + distmin(u
.ux
, u
.uy
, x
, y
))) ||
1107 (sobj_at(BOULDER
, x
, y
)) || (levl
[x
][y
].typ
!= ROOM
&& levl
[x
][y
].typ
!= CORR
) || MON_AT(x
, y
) )
1110 (*(int *)poolcnt
)++;
1112 if (!((*(int *)poolcnt
) && (x
== u
.ux
) && (y
== u
.uy
))) {
1113 /* Put a pool at x, y */
1114 levl
[x
][y
].typ
= SNOW
;
1117 if ((mtmp
= m_at(x
, y
)) != 0) {
1118 (void) minliquid(mtmp
);
1122 } else if ((x
== u
.ux
) && (y
== u
.uy
)) {
1123 (*(int *)poolcnt
)--;
1129 do_ashfloodg(x
, y
, poolcnt
)
1133 register struct monst
*mtmp
;
1134 register struct trap
*ttmp
;
1135 int randomamount
= 0;
1136 int randomx
, randomy
;
1137 if (!rn2(25)) randomamount
+= rnz(2);
1138 if (!rn2(125)) randomamount
+= rnz(5);
1139 if (!rn2(625)) randomamount
+= rnz(20);
1140 if (!rn2(3125)) randomamount
+= rnz(50);
1142 if (!rn2(25)) randomamount
+= rnz(2);
1143 if (!rn2(125)) randomamount
+= rnz(5);
1144 if (!rn2(625)) randomamount
+= rnz(20);
1145 if (!rn2(3125)) randomamount
+= rnz(50);
1147 if (rn2(5)) randomamount
= 0;
1149 while (randomamount
) {
1151 randomx
= rn1(COLNO
-3,2);
1152 randomy
= rn2(ROWNO
);
1153 if (isok(randomx
, randomy
) && (levl
[randomx
][randomy
].typ
== ROOM
|| levl
[randomx
][randomy
].typ
== CORR
) ) {
1154 levl
[randomx
][randomy
].typ
= ASH
;
1155 del_engr_at(randomx
, randomy
);
1157 if ((mtmp
= m_at(randomx
, randomy
)) != 0) {
1158 (void) minliquid(mtmp
);
1160 newsym(randomx
,randomy
);
1165 if ((rn2(1 + distmin(u
.ux
, u
.uy
, x
, y
))) ||
1166 (sobj_at(BOULDER
, x
, y
)) || (levl
[x
][y
].typ
!= ROOM
&& levl
[x
][y
].typ
!= CORR
) || MON_AT(x
, y
) )
1169 (*(int *)poolcnt
)++;
1171 if (!((*(int *)poolcnt
) && (x
== u
.ux
) && (y
== u
.uy
))) {
1172 /* Put a pool at x, y */
1173 levl
[x
][y
].typ
= ASH
;
1176 if ((mtmp
= m_at(x
, y
)) != 0) {
1177 (void) minliquid(mtmp
);
1181 } else if ((x
== u
.ux
) && (y
== u
.uy
)) {
1182 (*(int *)poolcnt
)--;
1188 do_sandfloodg(x
, y
, poolcnt
)
1192 register struct monst
*mtmp
;
1193 register struct trap
*ttmp
;
1194 int randomamount
= 0;
1195 int randomx
, randomy
;
1196 if (!rn2(25)) randomamount
+= rnz(2);
1197 if (!rn2(125)) randomamount
+= rnz(5);
1198 if (!rn2(625)) randomamount
+= rnz(20);
1199 if (!rn2(3125)) randomamount
+= rnz(50);
1201 if (!rn2(25)) randomamount
+= rnz(2);
1202 if (!rn2(125)) randomamount
+= rnz(5);
1203 if (!rn2(625)) randomamount
+= rnz(20);
1204 if (!rn2(3125)) randomamount
+= rnz(50);
1206 if (rn2(5)) randomamount
= 0;
1208 while (randomamount
) {
1210 randomx
= rn1(COLNO
-3,2);
1211 randomy
= rn2(ROWNO
);
1212 if (isok(randomx
, randomy
) && (levl
[randomx
][randomy
].typ
== ROOM
|| levl
[randomx
][randomy
].typ
== CORR
) ) {
1213 levl
[randomx
][randomy
].typ
= SAND
;
1214 del_engr_at(randomx
, randomy
);
1216 if ((mtmp
= m_at(randomx
, randomy
)) != 0) {
1217 (void) minliquid(mtmp
);
1219 newsym(randomx
,randomy
);
1224 if ((rn2(1 + distmin(u
.ux
, u
.uy
, x
, y
))) ||
1225 (sobj_at(BOULDER
, x
, y
)) || (levl
[x
][y
].typ
!= ROOM
&& levl
[x
][y
].typ
!= CORR
) || MON_AT(x
, y
) )
1228 (*(int *)poolcnt
)++;
1230 if (!((*(int *)poolcnt
) && (x
== u
.ux
) && (y
== u
.uy
))) {
1231 /* Put a pool at x, y */
1232 levl
[x
][y
].typ
= SAND
;
1235 if ((mtmp
= m_at(x
, y
)) != 0) {
1236 (void) minliquid(mtmp
);
1240 } else if ((x
== u
.ux
) && (y
== u
.uy
)) {
1241 (*(int *)poolcnt
)--;
1247 do_pavementfloodg(x
, y
, poolcnt
)
1251 register struct monst
*mtmp
;
1252 register struct trap
*ttmp
;
1253 int randomamount
= 0;
1254 int randomx
, randomy
;
1255 if (!rn2(25)) randomamount
+= rnz(2);
1256 if (!rn2(125)) randomamount
+= rnz(5);
1257 if (!rn2(625)) randomamount
+= rnz(20);
1258 if (!rn2(3125)) randomamount
+= rnz(50);
1260 if (!rn2(25)) randomamount
+= rnz(2);
1261 if (!rn2(125)) randomamount
+= rnz(5);
1262 if (!rn2(625)) randomamount
+= rnz(20);
1263 if (!rn2(3125)) randomamount
+= rnz(50);
1265 if (rn2(5)) randomamount
= 0;
1267 while (randomamount
) {
1269 randomx
= rn1(COLNO
-3,2);
1270 randomy
= rn2(ROWNO
);
1271 if (isok(randomx
, randomy
) && (levl
[randomx
][randomy
].typ
== ROOM
|| levl
[randomx
][randomy
].typ
== CORR
) ) {
1272 levl
[randomx
][randomy
].typ
= PAVEDFLOOR
;
1273 del_engr_at(randomx
, randomy
);
1275 if ((mtmp
= m_at(randomx
, randomy
)) != 0) {
1276 (void) minliquid(mtmp
);
1278 newsym(randomx
,randomy
);
1283 if ((rn2(1 + distmin(u
.ux
, u
.uy
, x
, y
))) ||
1284 (sobj_at(BOULDER
, x
, y
)) || (levl
[x
][y
].typ
!= ROOM
&& levl
[x
][y
].typ
!= CORR
) || MON_AT(x
, y
) )
1287 (*(int *)poolcnt
)++;
1289 if (!((*(int *)poolcnt
) && (x
== u
.ux
) && (y
== u
.uy
))) {
1290 /* Put a pool at x, y */
1291 levl
[x
][y
].typ
= PAVEDFLOOR
;
1294 if ((mtmp
= m_at(x
, y
)) != 0) {
1295 (void) minliquid(mtmp
);
1299 } else if ((x
== u
.ux
) && (y
== u
.uy
)) {
1300 (*(int *)poolcnt
)--;
1306 do_highwayfloodg(x
, y
, poolcnt
)
1310 register struct monst
*mtmp
;
1311 register struct trap
*ttmp
;
1312 int randomamount
= 0;
1313 int randomx
, randomy
;
1314 if (!rn2(25)) randomamount
+= rnz(2);
1315 if (!rn2(125)) randomamount
+= rnz(5);
1316 if (!rn2(625)) randomamount
+= rnz(20);
1317 if (!rn2(3125)) randomamount
+= rnz(50);
1319 if (!rn2(25)) randomamount
+= rnz(2);
1320 if (!rn2(125)) randomamount
+= rnz(5);
1321 if (!rn2(625)) randomamount
+= rnz(20);
1322 if (!rn2(3125)) randomamount
+= rnz(50);
1324 if (rn2(5)) randomamount
= 0;
1326 while (randomamount
) {
1328 randomx
= rn1(COLNO
-3,2);
1329 randomy
= rn2(ROWNO
);
1330 if (isok(randomx
, randomy
) && (levl
[randomx
][randomy
].typ
== ROOM
|| levl
[randomx
][randomy
].typ
== CORR
) ) {
1331 levl
[randomx
][randomy
].typ
= HIGHWAY
;
1332 del_engr_at(randomx
, randomy
);
1334 if ((mtmp
= m_at(randomx
, randomy
)) != 0) {
1335 (void) minliquid(mtmp
);
1337 newsym(randomx
,randomy
);
1342 if ((rn2(1 + distmin(u
.ux
, u
.uy
, x
, y
))) ||
1343 (sobj_at(BOULDER
, x
, y
)) || (levl
[x
][y
].typ
!= ROOM
&& levl
[x
][y
].typ
!= CORR
) || MON_AT(x
, y
) )
1346 (*(int *)poolcnt
)++;
1348 if (!((*(int *)poolcnt
) && (x
== u
.ux
) && (y
== u
.uy
))) {
1349 /* Put a pool at x, y */
1350 levl
[x
][y
].typ
= HIGHWAY
;
1353 if ((mtmp
= m_at(x
, y
)) != 0) {
1354 (void) minliquid(mtmp
);
1358 } else if ((x
== u
.ux
) && (y
== u
.uy
)) {
1359 (*(int *)poolcnt
)--;
1365 do_grassfloodg(x
, y
, poolcnt
)
1369 register struct monst
*mtmp
;
1370 register struct trap
*ttmp
;
1371 int randomamount
= 0;
1372 int randomx
, randomy
;
1373 if (!rn2(25)) randomamount
+= rnz(2);
1374 if (!rn2(125)) randomamount
+= rnz(5);
1375 if (!rn2(625)) randomamount
+= rnz(20);
1376 if (!rn2(3125)) randomamount
+= rnz(50);
1378 if (!rn2(25)) randomamount
+= rnz(2);
1379 if (!rn2(125)) randomamount
+= rnz(5);
1380 if (!rn2(625)) randomamount
+= rnz(20);
1381 if (!rn2(3125)) randomamount
+= rnz(50);
1383 if (rn2(5)) randomamount
= 0;
1385 while (randomamount
) {
1387 randomx
= rn1(COLNO
-3,2);
1388 randomy
= rn2(ROWNO
);
1389 if (isok(randomx
, randomy
) && (levl
[randomx
][randomy
].typ
== ROOM
|| levl
[randomx
][randomy
].typ
== CORR
) ) {
1390 levl
[randomx
][randomy
].typ
= GRASSLAND
;
1391 del_engr_at(randomx
, randomy
);
1393 if ((mtmp
= m_at(randomx
, randomy
)) != 0) {
1394 (void) minliquid(mtmp
);
1396 newsym(randomx
,randomy
);
1401 if ((rn2(1 + distmin(u
.ux
, u
.uy
, x
, y
))) ||
1402 (sobj_at(BOULDER
, x
, y
)) || (levl
[x
][y
].typ
!= ROOM
&& levl
[x
][y
].typ
!= CORR
) || MON_AT(x
, y
) )
1405 (*(int *)poolcnt
)++;
1407 if (!((*(int *)poolcnt
) && (x
== u
.ux
) && (y
== u
.uy
))) {
1408 /* Put a pool at x, y */
1409 levl
[x
][y
].typ
= GRASSLAND
;
1412 if ((mtmp
= m_at(x
, y
)) != 0) {
1413 (void) minliquid(mtmp
);
1417 } else if ((x
== u
.ux
) && (y
== u
.uy
)) {
1418 (*(int *)poolcnt
)--;
1424 do_nethermistfloodg(x
, y
, poolcnt
)
1428 register struct monst
*mtmp
;
1429 register struct trap
*ttmp
;
1430 int randomamount
= 0;
1431 int randomx
, randomy
;
1432 if (!rn2(25)) randomamount
+= rnz(2);
1433 if (!rn2(125)) randomamount
+= rnz(5);
1434 if (!rn2(625)) randomamount
+= rnz(20);
1435 if (!rn2(3125)) randomamount
+= rnz(50);
1437 if (!rn2(25)) randomamount
+= rnz(2);
1438 if (!rn2(125)) randomamount
+= rnz(5);
1439 if (!rn2(625)) randomamount
+= rnz(20);
1440 if (!rn2(3125)) randomamount
+= rnz(50);
1442 if (rn2(5)) randomamount
= 0;
1444 while (randomamount
) {
1446 randomx
= rn1(COLNO
-3,2);
1447 randomy
= rn2(ROWNO
);
1448 if (isok(randomx
, randomy
) && (levl
[randomx
][randomy
].typ
== ROOM
|| levl
[randomx
][randomy
].typ
== CORR
) ) {
1449 levl
[randomx
][randomy
].typ
= NETHERMIST
;
1450 del_engr_at(randomx
, randomy
);
1452 if ((mtmp
= m_at(randomx
, randomy
)) != 0) {
1453 (void) minliquid(mtmp
);
1455 newsym(randomx
,randomy
);
1460 if ((rn2(1 + distmin(u
.ux
, u
.uy
, x
, y
))) ||
1461 (sobj_at(BOULDER
, x
, y
)) || (levl
[x
][y
].typ
!= ROOM
&& levl
[x
][y
].typ
!= CORR
) || MON_AT(x
, y
) )
1464 (*(int *)poolcnt
)++;
1466 if (!((*(int *)poolcnt
) && (x
== u
.ux
) && (y
== u
.uy
))) {
1467 /* Put a pool at x, y */
1468 levl
[x
][y
].typ
= NETHERMIST
;
1471 if ((mtmp
= m_at(x
, y
)) != 0) {
1472 (void) minliquid(mtmp
);
1476 } else if ((x
== u
.ux
) && (y
== u
.uy
)) {
1477 (*(int *)poolcnt
)--;
1483 do_stalactitefloodg(x
, y
, poolcnt
)
1487 register struct monst
*mtmp
;
1488 register struct trap
*ttmp
;
1489 int randomamount
= 0;
1490 int randomx
, randomy
;
1491 if (!rn2(25)) randomamount
+= rnz(2);
1492 if (!rn2(125)) randomamount
+= rnz(5);
1493 if (!rn2(625)) randomamount
+= rnz(20);
1494 if (!rn2(3125)) randomamount
+= rnz(50);
1496 if (!rn2(25)) randomamount
+= rnz(2);
1497 if (!rn2(125)) randomamount
+= rnz(5);
1498 if (!rn2(625)) randomamount
+= rnz(20);
1499 if (!rn2(3125)) randomamount
+= rnz(50);
1501 if (rn2(5)) randomamount
= 0;
1503 while (randomamount
) {
1505 randomx
= rn1(COLNO
-3,2);
1506 randomy
= rn2(ROWNO
);
1507 if (isok(randomx
, randomy
) && (levl
[randomx
][randomy
].typ
== ROOM
|| levl
[randomx
][randomy
].typ
== CORR
) ) {
1508 levl
[randomx
][randomy
].typ
= STALACTITE
;
1509 del_engr_at(randomx
, randomy
);
1511 if ((mtmp
= m_at(randomx
, randomy
)) != 0) {
1512 (void) minliquid(mtmp
);
1514 newsym(randomx
,randomy
);
1519 if ((rn2(1 + distmin(u
.ux
, u
.uy
, x
, y
))) ||
1520 (sobj_at(BOULDER
, x
, y
)) || (levl
[x
][y
].typ
!= ROOM
&& levl
[x
][y
].typ
!= CORR
) || MON_AT(x
, y
) )
1523 (*(int *)poolcnt
)++;
1525 if (!((*(int *)poolcnt
) && (x
== u
.ux
) && (y
== u
.uy
))) {
1526 /* Put a pool at x, y */
1527 levl
[x
][y
].typ
= STALACTITE
;
1530 if ((mtmp
= m_at(x
, y
)) != 0) {
1531 (void) minliquid(mtmp
);
1535 } else if ((x
== u
.ux
) && (y
== u
.uy
)) {
1536 (*(int *)poolcnt
)--;
1542 do_cryptfloodg(x
, y
, poolcnt
)
1546 register struct monst
*mtmp
;
1547 register struct trap
*ttmp
;
1548 int randomamount
= 0;
1549 int randomx
, randomy
;
1550 if (!rn2(25)) randomamount
+= rnz(2);
1551 if (!rn2(125)) randomamount
+= rnz(5);
1552 if (!rn2(625)) randomamount
+= rnz(20);
1553 if (!rn2(3125)) randomamount
+= rnz(50);
1555 if (!rn2(25)) randomamount
+= rnz(2);
1556 if (!rn2(125)) randomamount
+= rnz(5);
1557 if (!rn2(625)) randomamount
+= rnz(20);
1558 if (!rn2(3125)) randomamount
+= rnz(50);
1560 if (rn2(5)) randomamount
= 0;
1562 while (randomamount
) {
1564 randomx
= rn1(COLNO
-3,2);
1565 randomy
= rn2(ROWNO
);
1566 if (isok(randomx
, randomy
) && (levl
[randomx
][randomy
].typ
== ROOM
|| levl
[randomx
][randomy
].typ
== CORR
) ) {
1567 levl
[randomx
][randomy
].typ
= CRYPTFLOOR
;
1568 del_engr_at(randomx
, randomy
);
1570 if ((mtmp
= m_at(randomx
, randomy
)) != 0) {
1571 (void) minliquid(mtmp
);
1573 newsym(randomx
,randomy
);
1578 if ((rn2(1 + distmin(u
.ux
, u
.uy
, x
, y
))) ||
1579 (sobj_at(BOULDER
, x
, y
)) || (levl
[x
][y
].typ
!= ROOM
&& levl
[x
][y
].typ
!= CORR
) || MON_AT(x
, y
) )
1582 (*(int *)poolcnt
)++;
1584 if (!((*(int *)poolcnt
) && (x
== u
.ux
) && (y
== u
.uy
))) {
1585 /* Put a pool at x, y */
1586 levl
[x
][y
].typ
= CRYPTFLOOR
;
1589 if ((mtmp
= m_at(x
, y
)) != 0) {
1590 (void) minliquid(mtmp
);
1594 } else if ((x
== u
.ux
) && (y
== u
.uy
)) {
1595 (*(int *)poolcnt
)--;
1601 do_bubblefloodg(x
, y
, poolcnt
)
1605 register struct monst
*mtmp
;
1606 register struct trap
*ttmp
;
1607 int randomamount
= 0;
1608 int randomx
, randomy
;
1609 if (!rn2(25)) randomamount
+= rnz(2);
1610 if (!rn2(125)) randomamount
+= rnz(5);
1611 if (!rn2(625)) randomamount
+= rnz(20);
1612 if (!rn2(3125)) randomamount
+= rnz(50);
1614 if (!rn2(25)) randomamount
+= rnz(2);
1615 if (!rn2(125)) randomamount
+= rnz(5);
1616 if (!rn2(625)) randomamount
+= rnz(20);
1617 if (!rn2(3125)) randomamount
+= rnz(50);
1619 if (rn2(5)) randomamount
= 0;
1621 while (randomamount
) {
1623 randomx
= rn1(COLNO
-3,2);
1624 randomy
= rn2(ROWNO
);
1625 if (isok(randomx
, randomy
) && (levl
[randomx
][randomy
].typ
== ROOM
|| levl
[randomx
][randomy
].typ
== CORR
) ) {
1626 levl
[randomx
][randomy
].typ
= BUBBLES
;
1627 blockorunblock_point(randomx
,randomy
);
1628 del_engr_at(randomx
, randomy
);
1630 if ((mtmp
= m_at(randomx
, randomy
)) != 0) {
1631 (void) minliquid(mtmp
);
1633 newsym(randomx
,randomy
);
1638 if ((rn2(1 + distmin(u
.ux
, u
.uy
, x
, y
))) ||
1639 (sobj_at(BOULDER
, x
, y
)) || (levl
[x
][y
].typ
!= ROOM
&& levl
[x
][y
].typ
!= CORR
) || MON_AT(x
, y
) )
1642 (*(int *)poolcnt
)++;
1644 if (!((*(int *)poolcnt
) && (x
== u
.ux
) && (y
== u
.uy
))) {
1645 /* Put a pool at x, y */
1646 levl
[x
][y
].typ
= BUBBLES
;
1647 blockorunblock_point(x
,y
);
1650 if ((mtmp
= m_at(x
, y
)) != 0) {
1651 (void) minliquid(mtmp
);
1655 } else if ((x
== u
.ux
) && (y
== u
.uy
)) {
1656 (*(int *)poolcnt
)--;
1662 do_raincloudfloodg(x
, y
, poolcnt
)
1666 register struct monst
*mtmp
;
1667 register struct trap
*ttmp
;
1668 int randomamount
= 0;
1669 int randomx
, randomy
;
1670 if (!rn2(25)) randomamount
+= rnz(2);
1671 if (!rn2(125)) randomamount
+= rnz(5);
1672 if (!rn2(625)) randomamount
+= rnz(20);
1673 if (!rn2(3125)) randomamount
+= rnz(50);
1675 if (!rn2(25)) randomamount
+= rnz(2);
1676 if (!rn2(125)) randomamount
+= rnz(5);
1677 if (!rn2(625)) randomamount
+= rnz(20);
1678 if (!rn2(3125)) randomamount
+= rnz(50);
1680 if (rn2(5)) randomamount
= 0;
1682 while (randomamount
) {
1684 randomx
= rn1(COLNO
-3,2);
1685 randomy
= rn2(ROWNO
);
1686 if (isok(randomx
, randomy
) && (levl
[randomx
][randomy
].typ
== ROOM
|| levl
[randomx
][randomy
].typ
== CORR
) ) {
1687 levl
[randomx
][randomy
].typ
= RAINCLOUD
;
1688 blockorunblock_point(randomx
,randomy
);
1689 del_engr_at(randomx
, randomy
);
1691 if ((mtmp
= m_at(randomx
, randomy
)) != 0) {
1692 (void) minliquid(mtmp
);
1694 newsym(randomx
,randomy
);
1699 if ((rn2(1 + distmin(u
.ux
, u
.uy
, x
, y
))) ||
1700 (sobj_at(BOULDER
, x
, y
)) || (levl
[x
][y
].typ
!= ROOM
&& levl
[x
][y
].typ
!= CORR
) || MON_AT(x
, y
) )
1703 (*(int *)poolcnt
)++;
1705 if (!((*(int *)poolcnt
) && (x
== u
.ux
) && (y
== u
.uy
))) {
1706 /* Put a pool at x, y */
1707 levl
[x
][y
].typ
= RAINCLOUD
;
1708 blockorunblock_point(x
,y
);
1711 if ((mtmp
= m_at(x
, y
)) != 0) {
1712 (void) minliquid(mtmp
);
1716 } else if ((x
== u
.ux
) && (y
== u
.uy
)) {
1717 (*(int *)poolcnt
)--;
1723 do_cloudfloodg(x
, y
, poolcnt
)
1727 register struct monst
*mtmp
;
1728 register struct trap
*ttmp
;
1729 int randomamount
= 0;
1730 int randomx
, randomy
;
1731 if (!rn2(25)) randomamount
+= rnz(2);
1732 if (!rn2(125)) randomamount
+= rnz(5);
1733 if (!rn2(625)) randomamount
+= rnz(20);
1734 if (!rn2(3125)) randomamount
+= rnz(50);
1736 if (!rn2(25)) randomamount
+= rnz(2);
1737 if (!rn2(125)) randomamount
+= rnz(5);
1738 if (!rn2(625)) randomamount
+= rnz(20);
1739 if (!rn2(3125)) randomamount
+= rnz(50);
1741 if (rn2(5)) randomamount
= 0;
1743 while (randomamount
) {
1745 randomx
= rn1(COLNO
-3,2);
1746 randomy
= rn2(ROWNO
);
1747 if (isok(randomx
, randomy
) && (levl
[randomx
][randomy
].typ
== ROOM
|| levl
[randomx
][randomy
].typ
== CORR
) ) {
1748 levl
[randomx
][randomy
].typ
= CLOUD
;
1749 blockorunblock_point(randomx
,randomy
);
1750 del_engr_at(randomx
, randomy
);
1752 if ((mtmp
= m_at(randomx
, randomy
)) != 0) {
1753 (void) minliquid(mtmp
);
1755 newsym(randomx
,randomy
);
1760 if ((rn2(1 + distmin(u
.ux
, u
.uy
, x
, y
))) ||
1761 (sobj_at(BOULDER
, x
, y
)) || (levl
[x
][y
].typ
!= ROOM
&& levl
[x
][y
].typ
!= CORR
) || MON_AT(x
, y
) )
1764 (*(int *)poolcnt
)++;
1766 if (!((*(int *)poolcnt
) && (x
== u
.ux
) && (y
== u
.uy
))) {
1767 /* Put a pool at x, y */
1768 levl
[x
][y
].typ
= CLOUD
;
1769 blockorunblock_point(x
,y
);
1772 if ((mtmp
= m_at(x
, y
)) != 0) {
1773 (void) minliquid(mtmp
);
1777 } else if ((x
== u
.ux
) && (y
== u
.uy
)) {
1778 (*(int *)poolcnt
)--;
1784 do_terrainfloodg(x
, y
, poolcnt
)
1788 register struct monst
*mtmp
;
1789 register struct trap
*ttmp
;
1790 int randomamount
= 0;
1791 int randomx
, randomy
;
1792 if (!rn2(25)) randomamount
+= rnz(2);
1793 if (!rn2(125)) randomamount
+= rnz(5);
1794 if (!rn2(625)) randomamount
+= rnz(20);
1795 if (!rn2(3125)) randomamount
+= rnz(50);
1797 if (!rn2(25)) randomamount
+= rnz(2);
1798 if (!rn2(125)) randomamount
+= rnz(5);
1799 if (!rn2(625)) randomamount
+= rnz(20);
1800 if (!rn2(3125)) randomamount
+= rnz(50);
1802 if (rn2(7)) randomamount
= 0;
1804 while (randomamount
) {
1806 randomx
= rn1(COLNO
-3,2);
1807 randomy
= rn2(ROWNO
);
1808 if (isok(randomx
, randomy
) && (levl
[randomx
][randomy
].typ
== ROOM
|| levl
[randomx
][randomy
].typ
== CORR
) ) {
1809 levl
[randomx
][randomy
].typ
= randomwalltype();
1810 blockorunblock_point(randomx
,randomy
);
1811 if (!(levl
[randomx
][randomy
].wall_info
& W_EASYGROWTH
)) levl
[randomx
][randomy
].wall_info
|= W_HARDGROWTH
;
1812 del_engr_at(randomx
, randomy
);
1814 if ((mtmp
= m_at(randomx
, randomy
)) != 0) {
1815 (void) minliquid(mtmp
);
1817 newsym(randomx
,randomy
);
1822 if ((rn2(1 + distmin(u
.ux
, u
.uy
, x
, y
))) ||
1823 (sobj_at(BOULDER
, x
, y
)) || (levl
[x
][y
].typ
!= ROOM
&& levl
[x
][y
].typ
!= CORR
) || MON_AT(x
, y
) )
1826 (*(int *)poolcnt
)++;
1828 if (!((*(int *)poolcnt
) && (x
== u
.ux
) && (y
== u
.uy
))) {
1829 /* Put a pool at x, y */
1830 levl
[x
][y
].typ
= randomwalltype();
1831 blockorunblock_point(x
,y
);
1832 if (!(levl
[x
][y
].wall_info
& W_EASYGROWTH
)) levl
[x
][y
].wall_info
|= W_HARDGROWTH
;
1835 if ((mtmp
= m_at(x
, y
)) != 0) {
1836 (void) minliquid(mtmp
);
1840 } else if ((x
== u
.ux
) && (y
== u
.uy
)) {
1841 (*(int *)poolcnt
)--;
1847 do_barfloodg(x
, y
, poolcnt
)
1851 register struct monst
*mtmp
;
1852 register struct trap
*ttmp
;
1853 int randomamount
= 0;
1854 int randomx
, randomy
;
1855 if (!rn2(25)) randomamount
+= rnz(2);
1856 if (!rn2(125)) randomamount
+= rnz(5);
1857 if (!rn2(625)) randomamount
+= rnz(20);
1858 if (!rn2(3125)) randomamount
+= rnz(50);
1860 if (!rn2(25)) randomamount
+= rnz(2);
1861 if (!rn2(125)) randomamount
+= rnz(5);
1862 if (!rn2(625)) randomamount
+= rnz(20);
1863 if (!rn2(3125)) randomamount
+= rnz(50);
1865 if (rn2(5)) randomamount
= 0;
1867 while (randomamount
) {
1869 randomx
= rn1(COLNO
-3,2);
1870 randomy
= rn2(ROWNO
);
1871 if (isok(randomx
, randomy
) && (levl
[randomx
][randomy
].typ
== ROOM
|| levl
[randomx
][randomy
].typ
== CORR
) ) {
1872 levl
[randomx
][randomy
].typ
= IRONBARS
;
1873 blockorunblock_point(randomx
,randomy
);
1874 del_engr_at(randomx
, randomy
);
1876 if ((mtmp
= m_at(randomx
, randomy
)) != 0) {
1877 (void) minliquid(mtmp
);
1879 newsym(randomx
,randomy
);
1884 if ((rn2(1 + distmin(u
.ux
, u
.uy
, x
, y
))) ||
1885 (sobj_at(BOULDER
, x
, y
)) || (levl
[x
][y
].typ
!= ROOM
&& levl
[x
][y
].typ
!= CORR
) || MON_AT(x
, y
) )
1888 (*(int *)poolcnt
)++;
1890 if (!((*(int *)poolcnt
) && (x
== u
.ux
) && (y
== u
.uy
))) {
1891 /* Put a pool at x, y */
1892 levl
[x
][y
].typ
= IRONBARS
;
1893 blockorunblock_point(x
,y
);
1896 if ((mtmp
= m_at(x
, y
)) != 0) {
1897 (void) minliquid(mtmp
);
1901 } else if ((x
== u
.ux
) && (y
== u
.uy
)) {
1902 (*(int *)poolcnt
)--;
1908 do_lavafloodg(x
, y
, poolcnt
)
1912 register struct monst
*mtmp
;
1913 register struct trap
*ttmp
;
1915 if (/*nexttodoor(x, y) || */(rn2(1 + distmin(u
.ux
, u
.uy
, x
, y
))) ||
1916 (sobj_at(BOULDER
, x
, y
)) || (levl
[x
][y
].typ
!= ROOM
&& levl
[x
][y
].typ
!= CORR
) || MON_AT(x
, y
))
1919 (*(int *)poolcnt
)++;
1921 if (!((*(int *)poolcnt
) && (x
== u
.ux
) && (y
== u
.uy
))) {
1922 /* Put a pool at x, y */
1923 levl
[x
][y
].typ
= LAVAPOOL
;
1926 if ((mtmp
= m_at(x
, y
)) != 0) {
1927 (void) minliquid(mtmp
);
1931 } else if ((x
== u
.ux
) && (y
== u
.uy
)) {
1932 (*(int *)poolcnt
)--;
1938 do_floodg(x
, y
, poolcnt
)
1942 register struct monst
*mtmp
;
1943 register struct trap
*ttmp
;
1945 if (/*nexttodoor(x, y) || */(rn2(1 + distmin(u
.ux
, u
.uy
, x
, y
))) ||
1946 (sobj_at(BOULDER
, x
, y
)) || (levl
[x
][y
].typ
!= ROOM
&& levl
[x
][y
].typ
!= CORR
) || MON_AT(x
, y
))
1949 (*(int *)poolcnt
)++;
1951 if (!((*(int *)poolcnt
) && (x
== u
.ux
) && (y
== u
.uy
))) {
1952 /* Put a pool at x, y */
1953 levl
[x
][y
].typ
= POOL
;
1955 water_damage(level
.objects
[x
][y
], FALSE
, TRUE
);
1957 if ((mtmp
= m_at(x
, y
)) != 0) {
1958 (void) minliquid(mtmp
);
1962 } else if ((x
== u
.ux
) && (y
== u
.uy
)) {
1963 (*(int *)poolcnt
)--;
1968 /* special effects for The Book of the Dead */
1973 struct monst
*mtmp
, *mtmp2
;
1976 You("turn the pages of the Book of the Dead...");
1977 makeknown(SPE_BOOK_OF_THE_DEAD
);
1979 if (!u
.bellimbued
) {
1980 pline("But nothing happens. You faintly recall that this book will be an enigma to you until you finally imbue a certain 'silver bell'.");
1984 /* KMH -- Need ->known to avoid "_a_ Book of the Dead" */
1986 if(invocation_pos(u
.ux
, u
.uy
) && !On_stairs(u
.ux
, u
.uy
)) {
1987 register struct obj
*otmp
;
1988 register boolean arti1_primed
= FALSE
, arti2_primed
= FALSE
,
1989 arti_cursed
= FALSE
;
1991 /* If your book becomes prime cursed or worse, the game should still be winnable --Amy */
1992 if(book2
->cursed
&& rn2(2)) {
1993 pline_The("runes appear scrambled. You can't read them!");
1997 if(!u
.uhave
.bell
|| !u
.uhave
.menorah
) {
1998 pline("A chill runs down your %s.", body_part(SPINE
));
1999 if(!u
.uhave
.bell
) You_hear("a faint chime...");
2000 if(!u
.uhave
.menorah
) pline("Vlad's doppelganger is amused.");
2004 for(otmp
= invent
; otmp
; otmp
= otmp
->nobj
) {
2005 if(otmp
->otyp
== CANDELABRUM_OF_INVOCATION
&&
2006 otmp
->spe
== 7 && otmp
->lamplit
) {
2007 if(!otmp
->cursed
|| !issoviet
) arti1_primed
= TRUE
;
2008 else arti_cursed
= TRUE
;
2010 if(otmp
->otyp
== BELL_OF_OPENING
&&
2011 (moves
- otmp
->age
) < 50L) { /* you rang it recently */
2012 if(!otmp
->cursed
|| !issoviet
) arti2_primed
= TRUE
;
2013 else arti_cursed
= TRUE
;
2017 if(arti_cursed
&& issoviet
) { /* Nyah-nyah! --Amy */
2018 pline_The("invocation fails!");
2019 pline("At least one of your artifacts is cursed...");
2020 pline("Teper' vy bol'she ne mozhete pobezhdat' v igre, vy sovershenno glupyy igrok. Vy nikogda ne smozhete podnyat' proklyatiye, i on nikogda ne budet rabotat', poka kniga proklyata kha-kha-kha-kha-kha-kha BWAR KHAR KHAR!");
2021 } else if(arti1_primed
&& arti2_primed
) {
2022 unsigned soon
= (unsigned) d(2,6); /* time til next intervene() */
2024 /* successful invocation */
2026 u
.uevent
.invoked
= 1;
2027 /* in case you haven't killed the Wizard yet, behave as if
2029 u
.uevent
.udemigod
= 1; /* wizdead() */
2030 if (!u
.udg_cnt
|| u
.udg_cnt
> soon
) u
.udg_cnt
= soon
;
2031 } else { /* at least one artifact not prepared properly */
2032 You("have a feeling that %s is amiss...", something
);
2038 /* when not an invocation situation */
2039 if (book2
->cursed
) {
2042 You("raised the dead!");
2043 /* first maybe place a dangerous adversary */
2044 if (!rn2(3) && ((mtmp
= makemon(&mons
[PM_MASTER_LICH
],
2045 u
.ux
, u
.uy
, NO_MINVENT
)) != 0 ||
2046 (mtmp
= makemon(&mons
[PM_NALFESHNEE
],
2047 u
.ux
, u
.uy
, NO_MINVENT
)) != 0)) {
2048 mtmp
->mpeaceful
= 0;
2049 mtmp
->mfrenzied
= 1;
2052 /* next handle the affect on things you're carrying */
2053 (void) unturn_dead(&youmonst
);
2054 /* last place some monsters around you */
2057 mkundead(&mm
, TRUE
, NO_MINVENT
|MM_ANGRY
|MM_FRENZIED
, TRUE
);
2060 } else if(book2
->blessed
) {
2061 for(mtmp
= fmon
; mtmp
; mtmp
= mtmp2
) {
2062 mtmp2
= mtmp
->nmon
; /* tamedog() changes chain */
2063 if (DEADMONSTER(mtmp
)) continue;
2065 if ((is_undead(mtmp
->data
) || mtmp
->egotype_undead
) && !mtmp
->mfrenzied
&& cansee(mtmp
->mx
, mtmp
->my
)) {
2066 mtmp
->mpeaceful
= TRUE
;
2067 if(sgn(mtmp
->data
->maligntyp
) == sgn(u
.ualign
.type
)
2068 && distu(mtmp
->mx
, mtmp
->my
) < 4)
2070 if (mtmp
->mtame
< 20)
2073 (void) tamedog(mtmp
, (struct obj
*)0, FALSE
);
2074 else monflee(mtmp
, rnd(10), FALSE
, TRUE
);
2077 /* Amy edit: infinite command undead would be way overpowered */
2082 Your("ancestors are annoyed with you!");
2085 pline_The("headstones in the cemetery begin to move!");
2088 pline("Oh my! Your name appears in the book!");
2099 char splname
[BUFSZ
];
2100 boolean costly
= TRUE
;
2102 if (!book
|| !(carried(book
) ||
2103 (book
->where
== OBJ_FLOOR
&&
2104 book
->ox
== u
.ux
&& book
->oy
== u
.uy
))) {
2105 /* maybe it was stolen or polymorphed? */
2109 /* JDS: lenses give 50% faster reading; 33% smaller read time */
2110 if (delay
< end_delay
&& ublindf
&& ublindf
->otyp
== LENSES
&& rn2(2))
2112 if (delay
< end_delay
&& ublindf
&& ublindf
->otyp
== RADIOGLASSES
&& rn2(2))
2114 if (delay
< end_delay
&& ublindf
&& ublindf
->otyp
== SHIELD_PATE_GLASSES
&& rn2(2))
2116 if (delay
< end_delay
&& ublindf
&& ublindf
->otyp
== BOSS_VISOR
&& rn2(2))
2119 if (Confusion
&& (book
->otyp
!= SPE_BOOK_OF_THE_DEAD
) && !(Conf_resist
&& rn2(StrongConf_resist
? 25 : 5)) && !rn2((Role_if(PM_LIBRARIAN
) || Role_if(PM_PSYKER
)) ? 500 : 50) ) { /* became confused while learning */
2121 (void) confused_book(book
);
2122 book
= 0; /* no longer studying */
2123 if ((delay
- end_delay
) < 0) {
2126 register int actualdelay
;
2127 actualdelay
= rno(-(delay
- end_delay
));
2128 if (!isstunfish
&& (actualdelay
> 0)) actualdelay
= isqrt(actualdelay
); /* a lot of reduction --Amy */
2130 nomul(-(actualdelay
), "reading a confusing book", TRUE
); /* remaining delay is uninterrupted */
2131 } else { /* soviet mode */
2132 nomul((delay
- end_delay
), "reading a confusing book", TRUE
);
2133 pline("Vy tol'ko chto podpisal svoy smertnyy prigovor, potomu chto sovetskaya ne zabotitsya o igrovoy balans. Ne dazhe nebol'shoye nemnogo.");
2140 if (delay
< end_delay
) { /* not if (delay++), so at end delay == 0 */
2142 if (delay
) return(1); /* still busy, Amy edit: to me it looks like the original code is not working correctly,
2143 * since "delay" can become 0 here and if you get interrupted, you lose a charge again! */
2145 exercise(A_WIS
, TRUE
); /* you're studying. */
2146 booktype
= book
->otyp
;
2147 if(booktype
== SPE_BOOK_OF_THE_DEAD
) {
2152 if(booktype
== SPE_BLADE_ANGER
) {
2153 impossible("player trying to read spellbook of blade anger");
2156 if(booktype
== SPE_BEAMSWORD
) {
2157 impossible("player trying to read spellbook of beamsword");
2160 if(booktype
== SPE_DRAINING_ARROW
) {
2161 impossible("player trying to read spellbook of draining arrow");
2164 if(booktype
== SPE_MENSTRUATION
) {
2165 impossible("player trying to read spellbook of menstruation");
2169 sprintf(splname
, objects
[booktype
].oc_name_known
?
2170 "\"%s\"" : "the \"%s\" spell",
2171 OBJ_NAME(objects
[booktype
]) );
2172 for (i
= 0; i
< MAXSPELL
; i
++) {
2173 if (spellid(i
) == booktype
) {
2174 if (book
->spestudied
> MAX_SPELL_STUDY
) {
2175 pline("This spellbook is too faint to be read anymore.");
2176 book
->otyp
= booktype
= SPE_BLANK_PAPER
;
2177 } else if (spellknow(i
) <= MAX_CAN_STUDY
) {
2178 Your("knowledge of that spell is keener.");
2180 if (book
->oartifact
== ART_SECRET_BOOK_OF_VENOM
) {
2181 You("gain the secret knowledge of venom mixing!");
2182 learntech_or_leveltech(T_VENOM_MIXING
, FROMOUTSIDE
, 1);
2185 if (book
->oartifact
== ART_DOLCEVAIN
) {
2186 u
.thornspell
+= rnz(1000);
2187 You("grow a thorny hide!");
2190 if (book
->oartifact
== ART_KING_IN_YELLOW
) {
2192 kiypm
= dprince(rn2((int)A_LAWFUL
+2) - 1);
2193 if (kiypm
>= PM_ORCUS
&& kiypm
<= PM_DEMOGORGON
) u
.conclusiocount
++;
2194 if (kiypm
&& (kiypm
!= NON_PM
)) {
2195 (void) makemon(&mons
[kiypm
], u
.ux
, u
.uy
, MM_ANGRY
|MM_FRENZIED
);
2196 pline("An angry demon is summoned!");
2200 if (book
->oartifact
== ART_IWA_ERWI
) {
2203 if (objects
[SPE_DEFUSING
].oc_level
< 8) objects
[SPE_DEFUSING
].oc_level
++;
2205 if (objects
[SPE_DEFUSING
].oc_level
> 1) objects
[SPE_DEFUSING
].oc_level
--;
2208 for (iwaerwi
= 0; iwaerwi
< MAXSPELL
&& spellid(iwaerwi
) != NO_SPELL
; iwaerwi
++) {
2209 if (spellid(iwaerwi
) == SPE_DEFUSING
) {
2210 spl_book
[iwaerwi
].sp_lev
= objects
[SPE_DEFUSING
].oc_level
;
2214 pline("The level of the defusing spell has changed!");
2217 use_skill(P_MEMORIZATION
, spellev(i
));
2218 if (!rn2(3)) u
.uenmax
++;
2219 u
.cnd_spellbookcount
++;
2220 incrnknow(i
, FALSE
);
2221 if (book
->oartifact
== ART_YOU_CAN_HURT
) {
2222 losehp( (u
.uhpmax
/ 2) + 2, "being hurt by a spellbook", KILLED_BY
);
2223 boostknow(i
, 50000);
2224 You("can hurt, but the spell will last for a generous time.");
2226 if (book
->oartifact
== ART_BACKLASHPROTECT
) {
2227 boostknow(i
, 40000);
2228 pline_The("spell has a lot of memory now.");
2230 if (book
->oartifact
== ART_HEALING_RAIN_OBTAINED
) {
2231 wonderspell(SPE_HEALING_RAIN
);
2233 if (book
->oartifact
== ART_MULTIPLY_ME
) {
2234 boostknow(i
, Role_if(PM_OCCULT_MASTER
) ? 40000 : 10000);
2235 pline_The("spell memory bonus was multiplied!");
2237 if (book
->oartifact
== ART_PAGAN_POETRY
) {
2238 u
.superspecialspell
= booktype
;
2239 pline_The("spell is your super special spell now.");
2241 if (book
->oartifact
== ART_LESSEE_DAT
&& Role_if(PM_ELECTRIC_MAGE
)) {
2242 if (P_MAX_SKILL(P_ELEMENTAL_SPELL
) == P_ISRESTRICTED
) {
2243 unrestrict_weapon_skill(P_ELEMENTAL_SPELL
);
2244 pline("You can now learn the elemental spells skill.");
2245 } else if (P_MAX_SKILL(P_ELEMENTAL_SPELL
) == P_UNSKILLED
) {
2246 unrestrict_weapon_skill(P_ELEMENTAL_SPELL
);
2247 P_MAX_SKILL(P_ELEMENTAL_SPELL
) = P_BASIC
;
2248 pline("You can now learn the elemental spells skill.");
2249 } else if (rn2(2) && P_MAX_SKILL(P_ELEMENTAL_SPELL
) == P_BASIC
) {
2250 P_MAX_SKILL(P_ELEMENTAL_SPELL
) = P_SKILLED
;
2251 pline("Your knowledge of the elemental spells skill increases.");
2252 } else if (!rn2(4) && P_MAX_SKILL(P_ELEMENTAL_SPELL
) == P_SKILLED
) {
2253 P_MAX_SKILL(P_ELEMENTAL_SPELL
) = P_EXPERT
;
2254 pline("Your knowledge of the elemental spells skill increases.");
2255 } else if (!rn2(10) && P_MAX_SKILL(P_ELEMENTAL_SPELL
) == P_EXPERT
) {
2256 P_MAX_SKILL(P_ELEMENTAL_SPELL
) = P_MASTER
;
2257 pline("Your knowledge of the elemental spells skill increases.");
2258 } else if (!rn2(100) && P_MAX_SKILL(P_ELEMENTAL_SPELL
) == P_MASTER
) {
2259 P_MAX_SKILL(P_ELEMENTAL_SPELL
) = P_GRAND_MASTER
;
2260 pline("Your knowledge of the elemental spells skill increases.");
2261 } else if (!rn2(200) && P_MAX_SKILL(P_ELEMENTAL_SPELL
) == P_GRAND_MASTER
) {
2262 P_MAX_SKILL(P_ELEMENTAL_SPELL
) = P_SUPREME_MASTER
;
2263 pline("Your knowledge of the elemental spells skill increases.");
2266 if (u
.emynluincomplete
) boostknow(i
, 1000);
2267 if (uarmc
&& uarmc
->oartifact
== ART_READ_UP_ON_IT
) boostknow(i
, 20000);
2268 if (uarmg
&& itemhasappearance(uarmg
, APP_RUNIC_GLOVES
) && !rn2(2) ) incrnknow(i
, FALSE
);
2269 if (Role_if(PM_MAHOU_SHOUJO
)) incrnknow(i
, FALSE
);
2272 if (!PlayerCannotUseSkills
&& P_SKILL(P_MEMORIZATION
) >= P_BASIC
) {
2274 char nervbuf
[QBUFSZ
];
2275 char thisisannoying
= 0;
2277 if (!u
.youhavememorized
) {
2278 u
.youhavememorized
= TRUE
;
2279 if (!iflags
.memorizationknown
) pline("You have the memorization skill, which allows you to gain extra spell memory for newly learned spells. Whenever you learn a spell, you are asked whether you want to use the skill to boost the new spell's memory. In the case of doubt you should ALWAYS ANSWER YES. If you answer no, you just throw the bonus away. (Exception is if you want a forgotten spell, but you only ever need one of those normally.)");
2282 if (!iflags
.memorizationknown
) sprintf(nervbuf
, "Memorize this spell to add more spell memory? In the case of doubt you should always answer yes, unless you want the bonus to go to waste.");
2283 else sprintf(nervbuf
, "Memorize this spell to add more spell memory?");
2284 thisisannoying
= yn_function(nervbuf
, ynqchars
, 'y');
2285 if (thisisannoying
!= 'n') {
2288 switch (P_SKILL(P_MEMORIZATION
)) {
2289 case P_BASIC
: memoboost
= 2; break;
2290 case P_SKILLED
: memoboost
= 4; break;
2291 case P_EXPERT
: memoboost
= 6; break;
2292 case P_MASTER
: memoboost
= 8; break;
2293 case P_GRAND_MASTER
: memoboost
= 10; break;
2294 case P_SUPREME_MASTER
: memoboost
= 12; break;
2296 boostknow(i
, memoboost
* 1000);
2297 spl_book
[i
].sp_memorize
= TRUE
;
2298 pline("Spell memory increased! You gained %d%% extra spell memory.", memoboost
* 10);
2300 spl_book
[i
].sp_memorize
= FALSE
;
2301 pline("You decided to throw away the spell memory bonus. The spell was set to non-memorization mode. If you did that by mistake, you should open the spell menu and turn memorization for this spell back on so that it properly benefits from memorization skill.");
2307 boostknow(i
, end_delay
* ((book
->spe
> 0) ? 20 : 10));
2309 use_skill(spell_skilltype(book
->otyp
), end_delay
/ ((book
->spe
> 0) ? 10 : 20));
2311 exercise(A_WIS
, TRUE
); /* extra study */
2312 } else { /* MAX_CAN_STUDY < spellknow(i) <= MAX_SPELL_STUDY */
2313 You("know %s quite well already.", splname
);
2316 /* make book become known even when spell is already
2317 known, in case amnesia made you forget the book */
2318 makeknown((int)booktype
);
2320 } else if (spellid(i
) == NO_SPELL
) {
2321 spl_book
[i
].sp_id
= booktype
;
2322 spl_book
[i
].sp_lev
= objects
[booktype
].oc_level
;
2323 spl_book
[i
].sp_memorize
= TRUE
;
2324 use_skill(P_MEMORIZATION
, spellev(i
));
2325 if (!rn2(3)) u
.uenmax
++;
2326 u
.cnd_spellbookcount
++;
2328 if (u
.emynluincomplete
) boostknow(i
, 1000);
2329 if (uarmc
&& uarmc
->oartifact
== ART_READ_UP_ON_IT
) boostknow(i
, 20000);
2330 if (uarmg
&& itemhasappearance(uarmg
, APP_RUNIC_GLOVES
) && !rn2(2) ) incrnknow(i
, TRUE
);
2331 if (Role_if(PM_MAHOU_SHOUJO
)) incrnknow(i
, TRUE
);
2333 You("have keen knowledge of the spell.");
2334 You(i
> 0 ? "add %s to your repertoire." : "learn %s.",
2336 if (book
->oartifact
== ART_SECRET_BOOK_OF_VENOM
) {
2337 You("gain the secret knowledge of venom mixing!");
2338 learntech_or_leveltech(T_VENOM_MIXING
, FROMOUTSIDE
, 1);
2340 if (book
->oartifact
== ART_DOLCEVAIN
) {
2341 u
.thornspell
+= rnz(1000);
2342 You("grow a thorny hide!");
2344 if (book
->oartifact
== ART_KING_IN_YELLOW
) {
2346 kiypm
= dprince(rn2((int)A_LAWFUL
+2) - 1);
2347 if (kiypm
>= PM_ORCUS
&& kiypm
<= PM_DEMOGORGON
) u
.conclusiocount
++;
2348 if (kiypm
&& (kiypm
!= NON_PM
)) {
2349 (void) makemon(&mons
[kiypm
], u
.ux
, u
.uy
, MM_ANGRY
|MM_FRENZIED
);
2350 pline("An angry demon is summoned!");
2353 if (book
->oartifact
== ART_YOU_CAN_HURT
) {
2354 losehp( (u
.uhpmax
/ 2) + 2, "being hurt by a spellbook", KILLED_BY
);
2355 boostknow(i
, 50000);
2356 You("can hurt, but the spell will last for a generous time.");
2358 if (book
->oartifact
== ART_HEALING_RAIN_OBTAINED
) {
2359 wonderspell(SPE_HEALING_RAIN
);
2361 if (book
->oartifact
== ART_BACKLASHPROTECT
) {
2362 boostknow(i
, 40000);
2363 pline_The("spell has a lot of memory now.");
2365 if (book
->oartifact
== ART_MULTIPLY_ME
) {
2366 boostknow(i
, Role_if(PM_OCCULT_MASTER
) ? 40000 : 10000);
2367 pline_The("spell memory bonus was multiplied!");
2369 if (book
->oartifact
== ART_PAGAN_POETRY
) {
2370 u
.superspecialspell
= booktype
;
2371 pline_The("spell is your super special spell now.");
2374 if (book
->oartifact
== ART_LESSEE_DAT
&& Role_if(PM_ELECTRIC_MAGE
)) {
2375 if (P_MAX_SKILL(P_ELEMENTAL_SPELL
) == P_ISRESTRICTED
) {
2376 unrestrict_weapon_skill(P_ELEMENTAL_SPELL
);
2377 pline("You can now learn the elemental spells skill.");
2378 } else if (P_MAX_SKILL(P_ELEMENTAL_SPELL
) == P_UNSKILLED
) {
2379 unrestrict_weapon_skill(P_ELEMENTAL_SPELL
);
2380 P_MAX_SKILL(P_ELEMENTAL_SPELL
) = P_BASIC
;
2381 pline("You can now learn the elemental spells skill.");
2382 } else if (rn2(2) && P_MAX_SKILL(P_ELEMENTAL_SPELL
) == P_BASIC
) {
2383 P_MAX_SKILL(P_ELEMENTAL_SPELL
) = P_SKILLED
;
2384 pline("Your knowledge of the elemental spells skill increases.");
2385 } else if (!rn2(4) && P_MAX_SKILL(P_ELEMENTAL_SPELL
) == P_SKILLED
) {
2386 P_MAX_SKILL(P_ELEMENTAL_SPELL
) = P_EXPERT
;
2387 pline("Your knowledge of the elemental spells skill increases.");
2388 } else if (!rn2(10) && P_MAX_SKILL(P_ELEMENTAL_SPELL
) == P_EXPERT
) {
2389 P_MAX_SKILL(P_ELEMENTAL_SPELL
) = P_MASTER
;
2390 pline("Your knowledge of the elemental spells skill increases.");
2391 } else if (!rn2(100) && P_MAX_SKILL(P_ELEMENTAL_SPELL
) == P_MASTER
) {
2392 P_MAX_SKILL(P_ELEMENTAL_SPELL
) = P_GRAND_MASTER
;
2393 pline("Your knowledge of the elemental spells skill increases.");
2394 } else if (!rn2(200) && P_MAX_SKILL(P_ELEMENTAL_SPELL
) == P_GRAND_MASTER
) {
2395 P_MAX_SKILL(P_ELEMENTAL_SPELL
) = P_SUPREME_MASTER
;
2396 pline("Your knowledge of the elemental spells skill increases.");
2400 if (book
->oartifact
== ART_IWA_ERWI
) {
2403 if (objects
[SPE_DEFUSING
].oc_level
< 8) objects
[SPE_DEFUSING
].oc_level
++;
2405 if (objects
[SPE_DEFUSING
].oc_level
> 1) objects
[SPE_DEFUSING
].oc_level
--;
2407 for (iwaerwi
= 0; iwaerwi
< MAXSPELL
&& spellid(iwaerwi
) != NO_SPELL
; iwaerwi
++) {
2408 if (spellid(iwaerwi
) == SPE_DEFUSING
) {
2409 spl_book
[iwaerwi
].sp_lev
= objects
[SPE_DEFUSING
].oc_level
;
2412 pline("The level of the defusing spell has changed!");
2414 if (booktype
== SPE_FORBIDDEN_KNOWLEDGE
) {
2416 if (flags
.soundok
) You_hear("a thunderous growling and rumbling...");
2417 if (PlayerHearsSoundEffects
) pline(issoviet
? "Pozdravlyayu, teper' vashe bozhestvo ochen' zol. Pochemu ty ne molish'sya? Eto mozhet byt' prosto privesti svoyu zhizn' do kontsa, a zatem vy mozhete svernut' luchshe, nesovetskimi kharakter nakonets-to! SDELAY ETO SEYCHAS!" : "Grrrrrrr! Grummel! Wummmmmm!");
2420 makeknown((int)booktype
);
2421 if (booktype
== SPE_AMNESIA
) {
2423 forget(ALL_MAP
, FALSE
);
2426 if (!PlayerCannotUseSkills
&& P_SKILL(P_MEMORIZATION
) >= P_BASIC
) {
2428 char nervbuf
[QBUFSZ
];
2429 char thisisannoying
= 0;
2431 if (!u
.youhavememorized
) {
2432 u
.youhavememorized
= TRUE
;
2433 if (!iflags
.memorizationknown
) pline("You have the memorization skill, which allows you to gain extra spell memory for newly learned spells. Whenever you learn a spell, you are asked whether you want to use the skill to boost the new spell's memory. In the case of doubt you should ALWAYS ANSWER YES. If you answer no, you just throw the bonus away. (Exception is if you want a forgotten spell, but you only ever need one of those normally.)");
2436 if (!iflags
.memorizationknown
) sprintf(nervbuf
, "Memorize this spell to add more spell memory? In the case of doubt you should always answer yes, unless you want the bonus to go to waste.");
2437 else sprintf(nervbuf
, "Memorize this spell to add more spell memory?");
2438 thisisannoying
= yn_function(nervbuf
, ynqchars
, 'y');
2439 if (thisisannoying
!= 'n') {
2442 switch (P_SKILL(P_MEMORIZATION
)) {
2443 case P_BASIC
: memoboost
= 2; break;
2444 case P_SKILLED
: memoboost
= 4; break;
2445 case P_EXPERT
: memoboost
= 6; break;
2446 case P_MASTER
: memoboost
= 8; break;
2447 case P_GRAND_MASTER
: memoboost
= 10; break;
2448 case P_SUPREME_MASTER
: memoboost
= 12; break;
2450 boostknow(i
, memoboost
* 1000);
2451 spl_book
[i
].sp_memorize
= TRUE
;
2452 pline("Spell memory increased! You gained %d%% extra spell memory.", memoboost
* 10);
2454 spl_book
[i
].sp_memorize
= FALSE
;
2455 pline("You decided to throw away the spell memory bonus. The spell was set to non-memorization mode. If you did that by mistake, you should open the spell menu and turn memorization for this spell back on so that it properly benefits from memorization skill.");
2463 if (i
== MAXSPELL
) impossible("Too many spells memorized!");
2465 if ( (book
->cursed
|| book
->spe
< 1) && !(uimplant
&& uimplant
->oartifact
== ART_DOMPFINATION
) && !Role_if(PM_LIBRARIAN
) && !Role_if(PM_PSYKER
) && !(booktype
== SPE_BOOK_OF_THE_DEAD
) ) { /* maybe a demon cursed it */
2466 if (cursed_book(book
)) {
2467 if (carried(book
)) useup(book
);
2468 else useupf(book
, 1L);
2469 pline_The("book falls apart.");
2474 if (costly
) check_unpaid(book
);
2480 study_book(spellbook
)
2481 register struct obj
*spellbook
;
2483 register int booktype
= spellbook
->otyp
;
2484 register boolean confused
= ((Confusion
!= 0) && !(Conf_resist
&& (StrongConf_resist
? rn2(3) : !rn2(3)) ));
2485 boolean too_hard
= FALSE
;
2487 if (delay
&& !confused
&& spellbook
== book
&&
2488 /* handle the sequence: start reading, get interrupted,
2489 have book become erased somehow, resume reading it */
2490 booktype
!= SPE_BLANK_PAPER
) {
2491 You("continue your efforts to memorize the spell.");
2492 if (AutoDestruct
|| u
.uprops
[AUTO_DESTRUCT
].extrinsic
|| (uarmf
&& uarmf
->oartifact
== ART_KHOR_S_REQUIRED_IDEA
) || have_autodestructstone() || (uchain
&& uchain
->oartifact
== ART_SIYID
) ) learn();
2494 /* KMH -- Simplified this code */
2495 if (booktype
== SPE_BLANK_PAPER
) {
2496 pline("This spellbook is all blank.");
2497 makeknown(booktype
);
2501 if (ACURR(A_INT
) == 1 && !rn2(4)) {
2503 check_unpaid_usage(spellbook
, TRUE
);
2504 pline("%s", generate_garbage_string());
2509 if (rn2(2)) line
= getrumor(-1, buflin
, TRUE
);
2510 else line
= getrumor(0, buflin
, TRUE
);
2511 if (!*line
) line
= "Slash'EM rumors file closed for renovation.";
2515 pline("%s", generate_garbage_string());
2517 consume_obj_charge(spellbook
, FALSE
); /* even if you have good devices skill --Amy */
2519 if (!rn2(2)) pline("%s", generate_garbage_string());
2522 pline("%s", generate_garbage_string());
2524 spellbook
->in_use
= FALSE
;
2529 if (spellbook
->spe
> 0 && confused
&& rn2((Role_if(PM_LIBRARIAN
) || Role_if(PM_PSYKER
)) ? 2 : 10) ) {
2530 check_unpaid_usage(spellbook
, TRUE
);
2532 int nochargechange
= 10;
2533 if (!(PlayerCannotUseSkills
)) {
2534 switch (P_SKILL(P_DEVICES
)) {
2536 case P_BASIC
: nochargechange
= 9; break;
2537 case P_SKILLED
: nochargechange
= 8; break;
2538 case P_EXPERT
: nochargechange
= 7; break;
2539 case P_MASTER
: nochargechange
= 6; break;
2540 case P_GRAND_MASTER
: nochargechange
= 5; break;
2541 case P_SUPREME_MASTER
: nochargechange
= 4; break;
2545 if (nochargechange
>= rnd(10)) consume_obj_charge(spellbook
, FALSE
);
2547 use_skill(P_DEVICES
,1);
2548 if (Race_if(PM_FAWN
)) {
2549 use_skill(P_DEVICES
,1);
2551 if (Race_if(PM_SATRE
)) {
2552 use_skill(P_DEVICES
,1);
2553 use_skill(P_DEVICES
,1);
2556 pline_The("words on the page seem to glow faintly purple.");
2557 You_cant("quite make them out.");
2559 } else if (spellbook
->spe
== 0) spellbook
->spe
--;
2561 switch (objects
[booktype
].oc_level
) {
2564 delay
= -objects
[booktype
].oc_delay
;
2568 delay
= -(objects
[booktype
].oc_level
- 1) *
2569 objects
[booktype
].oc_delay
;
2573 delay
= -objects
[booktype
].oc_level
*
2574 objects
[booktype
].oc_delay
;
2577 delay
= -8 * objects
[booktype
].oc_delay
;
2580 delay
= -12 * objects
[booktype
].oc_delay
;
2583 impossible("Unknown spellbook level %d, book %d;",
2584 objects
[booktype
].oc_level
, booktype
);
2588 /* Memorization skill by Amy: reduces the time required to read a spellbook, but not below 1 (obviously) */
2589 if (!PlayerCannotUseSkills
&& (delay
< -1) && P_SKILL(P_MEMORIZATION
) >= P_BASIC
) {
2591 int memreduction
= 100;
2593 switch (P_SKILL(P_MEMORIZATION
)) {
2594 case P_BASIC
: memreduction
= 80; break;
2595 case P_SKILLED
: memreduction
= 60; break;
2596 case P_EXPERT
: memreduction
= 40; break;
2597 case P_MASTER
: memreduction
= 20; break;
2598 case P_GRAND_MASTER
: memreduction
= 10; break;
2599 case P_SUPREME_MASTER
: memreduction
= 5; break;
2602 delay
*= memreduction
;
2604 if (delay
> -1) delay
= -1; /* fail safe */
2608 if (StrongBlind_resistance
&& delay
< -1) {
2610 if (delay
> -1) delay
= -1; /* fail safe */
2613 /* Books are often wiser than their readers (Rus.) */
2614 spellbook
->in_use
= TRUE
;
2615 if (!spellbook
->blessed
&&
2616 spellbook
->otyp
!= SPE_BOOK_OF_THE_DEAD
) {
2617 if ( ((spellbook
->cursed
&& rn2(4)) || (spellbook
->spe
< 1 && rn2(3)) ) && !Role_if(PM_LIBRARIAN
) && !Role_if(PM_PSYKER
) && booktype
!= SPE_BOOK_OF_THE_DEAD
) {
2620 /* uncursed - chance to fail */
2621 int read_ability
= ACURR(A_INT
) + 4 + GushLevel
/2
2622 - 2*objects
[booktype
].oc_level
2623 + ((ublindf
&& (ublindf
->otyp
== LENSES
|| ublindf
->otyp
== RADIOGLASSES
|| ublindf
->otyp
== SHIELD_PATE_GLASSES
|| ublindf
->otyp
== BOSS_VISOR
)) ? 2 : 0);
2624 /* only wizards know if a spell is too difficult */
2625 /* Amy edit: others may randomly know it sometimes */
2626 if ((Role_if(PM_WIZARD
) || !rn2(4)) && read_ability
< 20 &&
2627 !confused
&& ((spellbook
->spe
< 1) || spellbook
->cursed
)) {
2630 "This spellbook is %sdifficult to comprehend. Continue?",
2631 (read_ability
< 5 ? "extremely" : read_ability
< 12 ? "very " : ""));
2632 if (yn(qbuf
) != 'y') {
2633 spellbook
->in_use
= FALSE
;
2637 /* its up to random luck now */
2638 if (rnd(20) > read_ability
) {
2644 if ( (too_hard
|| rn2(2)) && !(booktype
== SPE_BOOK_OF_THE_DEAD
) && ( (spellbook
->cursed
&& !Role_if(PM_LIBRARIAN
) && !Role_if(PM_PSYKER
) ) || ((spellbook
->spe
< 1) && !(booktype
== SPE_BOOK_OF_THE_DEAD
) ) )) {
2645 boolean gone
= cursed_book(spellbook
);
2650 register int actualdelay
;
2651 actualdelay
= rno(-(delay
));
2652 if (!isstunfish
&& (actualdelay
> 1)) actualdelay
= isqrt(actualdelay
); /* a lot of reduction */
2654 nomul(-(actualdelay
), "reading a cursed book", TRUE
); /* study time */
2655 } else { /* soviet mode */
2656 nomul((delay
), "reading a cursed book", TRUE
);
2657 pline("Vy tol'ko chto podpisal svoy smertnyy prigovor, potomu chto sovetskaya ne zabotitsya o igrovoy balans. Ne dazhe nebol'shoye nemnogo.");
2662 if(gone
|| (spellbook
->spe
< 0) || !rn2(5)) {
2663 if (!gone
&& !(booktype
== SPE_BOOK_OF_THE_DEAD
)) pline_The("spellbook crumbles to dust!");
2664 else if (!(booktype
== SPE_BOOK_OF_THE_DEAD
)) pline_The("spellbook has been destroyed.");
2665 if (!objects
[spellbook
->otyp
].oc_name_known
&&
2666 !objects
[spellbook
->otyp
].oc_uname
)
2668 if (carried(spellbook
)) useup(spellbook
);
2669 else useupf(spellbook
, 1L);
2671 spellbook
->in_use
= FALSE
;
2673 } else if (confused
&& !(Conf_resist
&& rn2(StrongConf_resist
? 25 : 5)) && !rn2((Role_if(PM_LIBRARIAN
) || Role_if(PM_PSYKER
)) ? 250 : 50) && spellbook
->otyp
!= SPE_BOOK_OF_THE_DEAD
) {
2674 if (!confused_book(spellbook
)) {
2675 spellbook
->in_use
= FALSE
;
2679 register int actualdelay
;
2680 actualdelay
= rno(-(delay
));
2681 if (actualdelay
> 1) actualdelay
= isqrt(actualdelay
); /* a lot of reduction */
2683 nomul(-(actualdelay
), "reading a book while confused", TRUE
);
2685 } else { /* soviet mode */
2686 nomul((delay
), "reading a book while confused", TRUE
);
2687 pline("Vy tol'ko chto podpisal svoy smertnyy prigovor, potomu chto sovetskaya ne zabotitsya o igrovoy balans. Ne dazhe nebol'shoye nemnogo.");
2693 spellbook
->in_use
= FALSE
;
2695 /* The glowing words make studying easier */
2696 if (spellbook
->otyp
!= SPE_BOOK_OF_THE_DEAD
) {
2698 if (spellbook
->spe
> 0) {
2699 check_unpaid_usage(spellbook
, TRUE
);
2701 int nochargechange
= 10;
2702 if (!(PlayerCannotUseSkills
)) {
2703 switch (P_SKILL(P_DEVICES
)) {
2705 case P_BASIC
: nochargechange
= 9; break;
2706 case P_SKILLED
: nochargechange
= 8; break;
2707 case P_EXPERT
: nochargechange
= 7; break;
2708 case P_MASTER
: nochargechange
= 6; break;
2709 case P_GRAND_MASTER
: nochargechange
= 5; break;
2710 case P_SUPREME_MASTER
: nochargechange
= 4; break;
2714 if (nochargechange
>= rnd(10)) consume_obj_charge(spellbook
, FALSE
);
2716 use_skill(P_DEVICES
,1);
2717 if (Race_if(PM_FAWN
)) {
2718 use_skill(P_DEVICES
,1);
2720 if (Race_if(PM_SATRE
)) {
2721 use_skill(P_DEVICES
,1);
2722 use_skill(P_DEVICES
,1);
2724 if (Role_if(PM_LIBRARIAN
)) {
2725 use_skill(P_DEVICES
,1);
2728 pline_The("words on the page seem to glow faintly.");
2733 end_delay
= 0; /* Changed if multi != 0 */
2736 pline("Delay: %i", delay
);
2739 /* Count == practice reading :) */
2742 if (multi
+ 1 > MAX_STUDY_TIME
) multi
= MAX_STUDY_TIME
- 1;
2743 sprintf(qbuf
, "Study for at least %i turns?", (multi
+1));
2744 if (ynq(qbuf
) != 'y') {
2748 if ((--multi
) > (-delay
)) end_delay
= multi
+ delay
;
2751 pline("end_delay: %i", end_delay
);
2755 You("begin to %s the runes.",
2756 spellbook
->otyp
== SPE_BOOK_OF_THE_DEAD
? "recite" :
2761 set_occupation(learn
, "studying", 0);
2765 /* a spellbook has been destroyed or the character has changed levels;
2766 the stored address for the current book is no longer valid */
2768 book_disappears(obj
)
2771 if (obj
== book
) book
= (struct obj
*)0;
2774 /* renaming an object usually results in it having a different address;
2775 so the sequence start reading, get interrupted, name the book, resume
2776 reading would read the "new" book from scratch */
2778 book_substitution(old_obj
, new_obj
)
2779 struct obj
*old_obj
, *new_obj
;
2781 if (old_obj
== book
) book
= new_obj
;
2790 /* called from moveloop() */
2795 if (Keen_memory
&& !rn2(StrongKeen_memory
? 3 : 5)) /* sync this with cyan spells, see below! --Amy */
2798 if (uarm
&& uarm
->oartifact
== ART_COPE_OF_THE_ELDRITCH_KNIGH
&& rn2(2)) return;
2800 if (uarms
&& uarms
->oartifact
== ART_UNUSUAL_ENCH
&& !rn2(5)) return;
2802 /* the spell color trap that causes your memory to decrease when casting shouldn't be too awfully harsh... --Amy
2803 * ATTENTION: cyan spells reduces memory when casting, please keep that synchronized!!! */
2804 if (SpellColorCyan
&& rn2(10))
2808 * The time relative to the hero (a pass through move
2809 * loop) causes all spell knowledge to be decremented.
2810 * The hero's speed, rest status, conscious status etc.
2811 * does not alter the loss of memory.
2813 for (i
= 0; i
< MAXSPELL
&& spellid(i
) != NO_SPELL
; i
++)
2814 if (spellknow(i
) ) {
2816 if (!(uarmc
&& itemhasappearance(uarmc
, APP_GUILD_CLOAK
) ) && !tech_inuse(T_SPELL_SPAM
) ) {
2818 /* 10000 turns is nothing compared to the length of the game; have it last longer, please! --Amy */
2819 if (spellmemorize(i
) && !rn2(2)) continue;
2821 /* higher spell retention means your char is more of a caster and should therefore benefit --Amy */
2822 if (spellmemorize(i
) && (rnd(urole
.spelrete
+ 100) > 100) ) continue;
2824 /* higher intelligence was doing nothing??? come on! --Amy */
2825 if (spellmemorize(i
) && ACURR(A_INT
) > 14) {
2826 int intelsave
= ACURR(A_INT
) - 14;
2827 if (intelsave
> rn2(66)) continue;
2830 /* Memorization skill by Amy: if the spell is set to memorization mode, have a skill-based chance here
2831 * that on any given turn the spell memory will not decrease.
2832 * cyan spells uses the same calculation below, any changes need to go into that function as well */
2834 if (!PlayerCannotUseSkills
&& spellmemorize(i
) && P_SKILL(P_MEMORIZATION
) >= P_BASIC
) {
2836 int savememochance
= 0;
2838 switch (P_SKILL(P_MEMORIZATION
)) {
2839 case P_BASIC
: savememochance
= 1; break;
2840 case P_SKILLED
: savememochance
= 2; break;
2841 case P_EXPERT
: savememochance
= 3; break;
2842 case P_MASTER
: savememochance
= 4; break;
2843 case P_GRAND_MASTER
: savememochance
= 5; break;
2844 case P_SUPREME_MASTER
: savememochance
= 6; break;
2847 if (savememochance
> rn2(10)) continue;
2851 if (!PlayerCannotUseSkills
&& spellmemorize(i
) && P_SKILL(spell_skilltype(spellid(i
))) >= P_BASIC
) {
2853 int savememochance
= 0;
2855 switch (P_SKILL(spell_skilltype(spellid(i
)))) {
2856 case P_BASIC
: savememochance
= 1; break;
2857 case P_SKILLED
: savememochance
= 2; break;
2858 case P_EXPERT
: savememochance
= 3; break;
2859 case P_MASTER
: savememochance
= 4; break;
2860 case P_GRAND_MASTER
: savememochance
= 5; break;
2861 case P_SUPREME_MASTER
: savememochance
= 6; break;
2864 if (savememochance
> rn2(20)) continue;
2871 if (SpellForgetting
|| u
.uprops
[SPELL_FORGETTING
].extrinsic
|| have_spellforgettingstone()) {
2872 if (spellknow(i
)) decrnknow(i
);
2873 if (spellknow(i
)) decrnknow(i
);
2874 if (spellknow(i
)) decrnknow(i
);
2875 if (spellknow(i
)) decrnknow(i
);
2876 if (spellknow(i
)) decrnknow(i
);
2877 if (spellknow(i
)) decrnknow(i
);
2878 if (spellknow(i
)) decrnknow(i
);
2879 if (spellknow(i
)) decrnknow(i
);
2880 if (spellknow(i
)) decrnknow(i
);
2883 /* In Soviet Russia, people do not use magic very often, and so they definitely don't need any of those
2884 * completely superfluous messages telling them about spell memory. They already trashed the actual spell
2885 * memory display in the menu, so why the heck would they suddenly want to get messages about it? Hell no,
2886 * they prefer to suddenly discover their cure sickness spell was forgotten just as they're about to
2887 * cure that green slime effect on level 66 of Gehennom, after investing 500 hours into their character. --Amy */
2889 if (!issoviet
&& !SpellColorCyan
&& !(SpellForgetting
|| u
.uprops
[SPELL_FORGETTING
].extrinsic
|| have_spellforgettingstone()) && !(SpellLoss
|| u
.uprops
[SPELLS_LOST
].extrinsic
|| have_spelllossstone()) && spellknow(i
) == 1000) pline("Your %s spell is beginning to fade from your memory.", spellname(i
));
2890 if (!issoviet
&& !SpellColorCyan
&& !(SpellForgetting
|| u
.uprops
[SPELL_FORGETTING
].extrinsic
|| have_spellforgettingstone()) && !(SpellLoss
|| u
.uprops
[SPELLS_LOST
].extrinsic
|| have_spelllossstone()) && spellknow(i
) == 100) pline("You are about to forget the %s spell.", spellname(i
));
2891 if (!issoviet
&& !SpellColorCyan
&& !(SpellForgetting
|| u
.uprops
[SPELL_FORGETTING
].extrinsic
|| have_spellforgettingstone()) && !(SpellLoss
|| u
.uprops
[SPELLS_LOST
].extrinsic
|| have_spelllossstone()) && spellknow(i
) == 0) pline("You no longer know how to cast the %s spell.", spellname(i
));
2893 if (spellknow(i
) && uarmc
&& itemhasappearance(uarmc
, APP_FORGETFUL_CLOAK
) ) {
2895 if (!issoviet
&& !SpellColorCyan
&& !(SpellForgetting
|| u
.uprops
[SPELL_FORGETTING
].extrinsic
|| have_spellforgettingstone()) && !(SpellLoss
|| u
.uprops
[SPELLS_LOST
].extrinsic
|| have_spelllossstone()) && spellknow(i
) == 1000) pline("Your %s spell is beginning to fade from your memory.", spellname(i
));
2896 if (!issoviet
&& !SpellColorCyan
&& !(SpellForgetting
|| u
.uprops
[SPELL_FORGETTING
].extrinsic
|| have_spellforgettingstone()) && !(SpellLoss
|| u
.uprops
[SPELLS_LOST
].extrinsic
|| have_spelllossstone()) && spellknow(i
) == 100) pline("You are about to forget the %s spell.", spellname(i
));
2897 if (!issoviet
&& !SpellColorCyan
&& !(SpellForgetting
|| u
.uprops
[SPELL_FORGETTING
].extrinsic
|| have_spellforgettingstone()) && !(SpellLoss
|| u
.uprops
[SPELLS_LOST
].extrinsic
|| have_spelllossstone()) && spellknow(i
) == 0) pline("You no longer know how to cast the %s spell.", spellname(i
));
2901 if (spellknow(i
) && RngeForgetting
) {
2903 if (!issoviet
&& !SpellColorCyan
&& !(SpellForgetting
|| u
.uprops
[SPELL_FORGETTING
].extrinsic
|| have_spellforgettingstone()) && !(SpellLoss
|| u
.uprops
[SPELLS_LOST
].extrinsic
|| have_spelllossstone()) && spellknow(i
) == 1000) pline("Your %s spell is beginning to fade from your memory.", spellname(i
));
2904 if (!issoviet
&& !SpellColorCyan
&& !(SpellForgetting
|| u
.uprops
[SPELL_FORGETTING
].extrinsic
|| have_spellforgettingstone()) && !(SpellLoss
|| u
.uprops
[SPELLS_LOST
].extrinsic
|| have_spelllossstone()) && spellknow(i
) == 100) pline("You are about to forget the %s spell.", spellname(i
));
2905 if (!issoviet
&& !SpellColorCyan
&& !(SpellForgetting
|| u
.uprops
[SPELL_FORGETTING
].extrinsic
|| have_spellforgettingstone()) && !(SpellLoss
|| u
.uprops
[SPELLS_LOST
].extrinsic
|| have_spelllossstone()) && spellknow(i
) == 0) pline("You no longer know how to cast the %s spell.", spellname(i
));
2914 * Return TRUE if a spell was picked, with the spell index in the return
2915 * parameter. Otherwise return FALSE.
2918 getspell(spell_no
, goldspellpossible
)
2920 boolean goldspellpossible
;
2922 int nspells
, idx
, n
, thisone
, choicenumber
;
2923 char ilet
, lets
[BUFSZ
], qbuf
[QBUFSZ
];
2925 if (spellid(0) == NO_SPELL
) {
2926 You("don't know any spells right now.");
2930 if ((Goldspells
|| u
.uprops
[GOLDSPELLS
].extrinsic
|| have_goldspellstone()) && goldspellpossible
&& rn2(10)) {
2932 for (n
= 0; n
< MAXSPELL
&& spellid(n
) != NO_SPELL
; n
++)
2937 for (n
= 0; n
< MAXSPELL
&& spellid(n
) != NO_SPELL
; n
++) {
2938 if (!choicenumber
|| (!rn2(choicenumber
+ 1)) ) {
2944 if (choicenumber
> 0 && thisone
>= 0) {
2945 pline("You cast %s.", spellname(thisone
));
2946 spelleffects(thisone
, FALSE
);
2947 if (SpellColorPlatinum
&& u
.uen
< 0) {
2948 u
.uenmax
-= (0 - u
.uen
);
2950 u
.uhpmax
-= (0 - u
.uenmax
);
2951 if (u
.uhpmax
< 1) u
.uhpmax
= 1;
2953 u
.mhmax
-= (0 - u
.uenmax
);
2954 if (u
.mhmax
< 1) u
.mhmax
= 1;
2956 losehp((0 - u
.uenmax
) * 10, "overcasting a spell", KILLED_BY
);
2960 if (u
.uenmax
< 0) u
.uenmax
= 0;
2962 TimerunBug
+= 1; /* ugh, ugly hack --Amy */
2966 /* we somehow didn't choose a spell */
2967 pline("You fail to cast a spell.");
2968 TimerunBug
+= 1; /* ugh, ugly hack --Amy */
2972 if (flags
.menu_style
== MENU_TRADITIONAL
) {
2973 /* we know there is at least 1 known spell */
2974 for (nspells
= 1; nspells
< MAXSPELL
2975 && spellid(nspells
) != NO_SPELL
; nspells
++)
2978 if (nspells
== 1) strcpy(lets
, "a");
2979 else if (nspells
< 27) sprintf(lets
, "a-%c", 'a' + nspells
- 1);
2980 else if (nspells
== 27) sprintf(lets
, "a-z A");
2981 else if (nspells
< 53)
2982 sprintf(lets
, "a-z A-%c", 'A' + nspells
- 27);
2983 else if (nspells
== 53) sprintf(lets
, "a-z A-Z 0");
2984 else if (nspells
< 78)
2985 sprintf(lets
, "a-z A-Z 0-%c", '0' + nspells
- 53);
2986 else sprintf(lets
, "a-z A-Z 0-9");
2989 sprintf(qbuf
, "Cast which spell? [%s ?]", lets
);
2990 if ((ilet
= yn_function(qbuf
, (char *)0, '\0')) == '?')
2993 if (index(quitchars
, ilet
))
2996 idx
= spell_let_to_idx(ilet
);
2997 if (idx
>= 0 && idx
< nspells
) {
3001 You("don't know that spell.");
3004 if (SpellColorPink
) return dospellmenu("Your spells are pink.", SPELLMENU_CAST
, spell_no
, 0);
3005 else if (SpellColorBrightCyan
) return dospellmenu("Your spells are bright cyan.", SPELLMENU_CAST
, spell_no
, 0);
3006 else if (SpellColorCyan
) return dospellmenu("Your spells are cyan.", SPELLMENU_CAST
, spell_no
, 0);
3007 else if (SpellColorBlack
) return dospellmenu("Your spells are black.", SPELLMENU_CAST
, spell_no
, 0);
3008 else if (SpellColorOrange
) return dospellmenu("Your spells are orange.", SPELLMENU_CAST
, spell_no
, 0);
3009 else if (SpellColorRed
) return dospellmenu("Your spells are red.", SPELLMENU_CAST
, spell_no
, 0);
3010 else if (SpellColorPlatinum
) return dospellmenu("Your spells are platinum.", SPELLMENU_CAST
, spell_no
, 0);
3011 else if (SpellColorSilver
) return dospellmenu("Your spells are silver.", SPELLMENU_CAST
, spell_no
, 0);
3012 else if (SpellColorMetal
) return dospellmenu("Your spells are metal.", SPELLMENU_CAST
, spell_no
, 0);
3013 else if (SpellColorGreen
) return dospellmenu("Your spells are green.", SPELLMENU_CAST
, spell_no
, 0);
3014 else if (SpellColorBlue
) return dospellmenu("Your spells are blue.", SPELLMENU_CAST
, spell_no
, 0);
3015 else if (SpellColorGray
) return dospellmenu("Your spells are completely gray.", SPELLMENU_CAST
, spell_no
, 0);
3016 else if (SpellColorBrown
) return dospellmenu("Your spells are brown.", SPELLMENU_CAST
, spell_no
, 0);
3017 else if (SpellColorWhite
) return dospellmenu("Your spells are white.", SPELLMENU_CAST
, spell_no
, 0);
3018 else if (SpellColorViolet
) return dospellmenu("Your spells are violet.", SPELLMENU_CAST
, spell_no
, 0);
3019 else if (SpellColorYellow
) return dospellmenu("Your spells are yellow.", SPELLMENU_CAST
, spell_no
, 0);
3020 else return dospellmenu("Choose which spell to cast", SPELLMENU_CAST
, spell_no
, 0);
3024 /* the 'Z' command -- cast a spell */
3032 /* Amy note: use autismweaponcheck and not uwep here!!! after all, this is a *negative* effect */
3034 if (u
.antimagicshell
|| (uarmh
&& uarmh
->otyp
== HELM_OF_ANTI_MAGIC
) || (RngeAntimagicA
&& (moves
% 10 == 0)) || (RngeAntimagicB
&& (moves
% 5 == 0)) || (RngeAntimagicC
&& (moves
% 2 == 0)) || (RngeAntimagicD
) || (uarmc
&& uarmc
->oartifact
== ART_SHELLY
&& (moves
% 3 == 0)) || (uarmc
&& uarmc
->oartifact
== ART_BLACK_VEIL_OF_BLACKNESS
) || (uarmc
&& uarmc
->oartifact
== ART_ARABELLA_S_WAND_BOOSTER
) || (uarmu
&& uarmu
->oartifact
== ART_ANTIMAGIC_SHELL
) || autismweaponcheck(ART_LONG_SWORD_OF_ETERNITY
) || autismweaponcheck(ART_HEAVY_CROSSBOW_OF_ETERNITY
) || (uarmu
&& uarmu
->oartifact
== ART_ANTIMAGIC_FIELD
) || (Role_if(PM_UNBELIEVER
) && !(uwep
&& uwep
->oartifact
== ART_MAGE_STAFF_OF_ETERNITY
) ) || autismweaponcheck(ART_ARK_OF_THE_COVENANT
) || (uarmc
&& uarmc
->oartifact
== ART_SPELL_WARDED_WRAPPINGS_OF_
) || autismweaponcheck(ART_ANTIMAGICBANE
) ) {
3036 pline("Your anti-magic shell prevents spellcasting.");
3037 if (flags
.moreforced
&& !MessagesSuppressed
) display_nhwindow(WIN_MESSAGE
, TRUE
); /* --More-- */
3041 if (getspell(&spell_no
, TRUE
)) {
3043 /* Spellbinder allows you to cast several spells in one turn, but not the same spell twice --Amy */
3045 if (u
.spellbinder
) {
3046 if ((spell_no
== u
.spellbinder1
) || (spell_no
== u
.spellbinder2
) || (spell_no
== u
.spellbinder3
) || (spell_no
== u
.spellbinder4
) || (spell_no
== u
.spellbinder5
) || (spell_no
== u
.spellbinder6
) || (spell_no
== u
.spellbinder7
)) {
3047 pline("You already bound the same spell in this turn, and therefore it fails!");
3050 if (u
.spellbinder1
== -1) u
.spellbinder1
= spell_no
;
3051 else if (u
.spellbinder2
== -1) u
.spellbinder2
= spell_no
;
3052 else if (u
.spellbinder3
== -1) u
.spellbinder3
= spell_no
;
3053 else if (u
.spellbinder4
== -1) u
.spellbinder4
= spell_no
;
3054 else if (u
.spellbinder5
== -1) u
.spellbinder5
= spell_no
;
3055 else if (u
.spellbinder6
== -1) u
.spellbinder6
= spell_no
;
3056 else if (u
.spellbinder7
== -1) u
.spellbinder7
= spell_no
;
3059 whatreturn
= spelleffects(spell_no
, FALSE
);
3061 if (SpellColorPlatinum
&& u
.uen
< 0) {
3062 u
.uenmax
-= (0 - u
.uen
);
3064 u
.uhpmax
-= (0 - u
.uenmax
);
3065 if (u
.uhpmax
< 1) u
.uhpmax
= 1;
3067 u
.mhmax
-= (0 - u
.uenmax
);
3068 if (u
.mhmax
< 1) u
.mhmax
= 1;
3070 losehp((0 - u
.uenmax
) * 10, "overcasting a spell", KILLED_BY
);
3074 if (u
.uenmax
< 0) u
.uenmax
= 0;
3076 else if (u
.uen
< 0) {
3077 int manafiredamage
= abs(u
.uen
);
3079 losehp(manafiredamage
, "mana fire", KILLED_BY
);
3080 You("took %d points of damage from mana fire.", manafiredamage
);
3093 boolean willcastinertiaspell
= FALSE
;
3095 pline("You control the %s spell flow.", spellname(u
.inertiacontrolspellno
));
3097 if (flags
.inertiaconfirm
) {
3098 getlin ("Cast it? [y/yes/no/q/quit]",buf
);
3100 if (!(strcmp (buf
, "yes")) || !(strcmp (buf
, "y")) || !(strcmp (buf
, "ye")) || !(strcmp (buf
, "ys"))) willcastinertiaspell
= TRUE
;
3101 if (!(strcmp (buf
, "q")) || !(strcmp (buf
, "quit"))) {
3102 You("ended inertia control prematurely.");
3103 u
.inertiacontrol
= 0;
3104 u
.inertiacontrolspell
= -1;
3105 u
.inertiacontrolspellno
= -1;
3109 c
= yn_function("Cast it?", ynqchars
, 'n');
3110 if (c
== 'y') willcastinertiaspell
= TRUE
;
3111 else if (c
== 'q') {
3112 You("ended inertia control prematurely.");
3113 u
.inertiacontrol
= 0;
3114 u
.inertiacontrolspell
= -1;
3115 u
.inertiacontrolspellno
= -1;
3120 if (willcastinertiaspell
) {
3122 if (spellid(u
.inertiacontrolspellno
) != u
.inertiacontrolspell
) {
3123 pline("The inertia controlled spell is no longer in place, and therefore cannot be auto-casted!");
3124 u
.inertiacontrol
= 0;
3125 u
.inertiacontrolspell
= -1;
3126 u
.inertiacontrolspellno
= -1;
3129 spelleffects(u
.inertiacontrolspellno
, FALSE
);
3131 if (SpellColorPlatinum
&& u
.uen
< 0) {
3132 u
.uenmax
-= (0 - u
.uen
);
3134 u
.uhpmax
-= (0 - u
.uenmax
);
3135 if (u
.uhpmax
< 1) u
.uhpmax
= 1;
3137 u
.mhmax
-= (0 - u
.uenmax
);
3138 if (u
.mhmax
< 1) u
.mhmax
= 1;
3140 losehp((0 - u
.uenmax
) * 10, "overcasting a spell", KILLED_BY
);
3144 if (u
.uenmax
< 0) u
.uenmax
= 0;
3150 STATIC_OVL
const char*
3151 spelltypemnemonic(int skill
)
3154 case P_ATTACK_SPELL
:
3156 case P_HEALING_SPELL
:
3158 case P_DIVINATION_SPELL
:
3160 case P_ENCHANTMENT_SPELL
:
3162 case P_PROTECTION_SPELL
:
3166 case P_OCCULT_SPELL
:
3168 case P_ELEMENTAL_SPELL
:
3172 case P_MATTER_SPELL
:
3175 impossible("Unknown spell skill, %d;", skill
);
3181 spell_skilltype(booktype
)
3184 return (objects
[booktype
].oc_skill
);
3192 int natac
= u
.uac
- u
.uspellprot
;
3195 /* loglev=log2(u.ulevel)+1 (1..5) */
3201 /* The more u.uspellprot you already have, the less you get,
3202 * and the better your natural ac, the less you get.
3204 * LEVEL AC SPELLPROT from sucessive SPE_PROTECTION casts
3205 * 1 10 0, 1, 2, 3, 4
3208 * 2-3 10 0, 2, 4, 5, 6, 7, 8
3209 * 2-3 0 0, 2, 4, 5, 6
3210 * 2-3 -10 0, 2, 3, 4
3211 * 4-7 10 0, 3, 6, 8, 9, 10, 11, 12
3212 * 4-7 0 0, 3, 5, 7, 8, 9
3213 * 4-7 -10 0, 3, 5, 6
3214 * 7-15 -10 0, 3, 5, 6
3215 * 8-15 10 0, 4, 7, 10, 12, 13, 14, 15, 16
3216 * 8-15 0 0, 4, 7, 9, 10, 11, 12
3217 * 8-15 -10 0, 4, 6, 7, 8
3218 * 16-30 10 0, 5, 9, 12, 14, 16, 17, 18, 19, 20
3219 * 16-30 0 0, 5, 9, 11, 13, 14, 15
3220 * 16-30 -10 0, 5, 8, 9, 10
3222 gain
= loglev
- (int)u
.uspellprot
/ (4 - min(3,(10 - natac
)/10));
3223 if (Race_if(PM_MAYMES
)) gain
*= 2;
3227 const char *hgolden
= hcolor(NH_GOLDEN
);
3230 pline_The("%s haze around you becomes more dense.",
3233 pline_The("%s around you begins to shimmer with %s haze.",
3234 /*[ what about being inside solid rock while polyd? ]*/
3235 (Underwater
|| Is_waterlevel(&u
.uz
)) ? "water" : "air",
3238 u
.uspellprot
+= gain
;
3240 (!(PlayerCannotUseSkills
) && P_SKILL(spell_skilltype(SPE_PROTECTION
)) >= P_EXPERT
) ? 20 : 10;
3242 if (Race_if(PM_MAYMES
)) {
3247 u
.usptime
= u
.uspmtime
;
3251 Your("skin feels warm for a moment.");
3260 pline("The shimmering globe around you becomes slightly brighter.");
3262 You_feel("slightly more smooth.");
3265 pline("A shimmering globe appears around you!");
3267 You_feel("smooth.");
3269 incr_itimeout(&HReflecting
, rn1(10, HReflecting
? 4 : 30));
3273 /* attempting to cast a forgotten spell will cause disorientation */
3275 spell_backfire(spell
)
3278 long duration
= (long)((spellev(spell
) + 1) * 3); /* 6..24 */
3280 /* prior to 3.4.1, the only effect was confusion; it still predominates */
3281 if (!obsidianprotection()) switch (rn2(17)) {
3285 case 3: make_confused(HConfusion
+ duration
, FALSE
); /* 40% */
3289 case 6: make_confused(HConfusion
+ (2L * duration
/ 3L), FALSE
); /* 30% */
3290 make_stunned(HStun
+ (duration
/ 3L), FALSE
);
3293 case 8: make_stunned(HStun
+ (2L * duration
/ 3L), FALSE
); /* 20% */
3294 make_confused(HConfusion
+ (duration
/ 3L), FALSE
);
3296 case 9: make_stunned(HStun
+ duration
, FALSE
); /* 10% */
3298 case 10: make_numbed(HNumbed
+ duration
, FALSE
); /* 10% */
3300 case 11: make_frozen(HFrozen
+ duration
, FALSE
); /* 10% */
3302 case 12: make_burned(HBurned
+ duration
, FALSE
); /* 10% */
3304 case 13: make_feared(HFeared
+ duration
, FALSE
); /* 10% */
3306 case 14: make_blinded(Blinded
+ duration
, FALSE
); /* 10% */
3308 case 15: make_hallucinated(HHallucination
+ duration
, FALSE
, 0L); /* 10% */
3310 case 16: make_dimmed(HDimmed
+ duration
, FALSE
); /* 10% */
3317 spelleffects(spell
, atme
)
3321 int energy
, damage
, chance
, n
, intell
;
3323 int skill
, role_skill
;
3324 boolean confused
= ((Confusion
!= 0) && !(Conf_resist
&& (StrongConf_resist
? rn2(3) : !rn2(3)) ) );
3327 int confusionchance
= 0;
3330 * Find the skill the hero has in a spell type category.
3331 * See spell_skilltype for categories.
3333 skill
= spell_skilltype(spellid(spell
));
3334 role_skill
= P_SKILL(skill
);
3335 if (PlayerCannotUseSkills
) role_skill
= P_ISRESTRICTED
;
3338 * Spell casting no longer affects knowledge of the spell. A
3339 * decrement of spell knowledge is done every turn.
3341 if (spellknow(spell
) <= 0) {
3343 /* overhaul by Amy: forgotten spells are no longer free, they cost Pw now and can fail or backfire
3344 * higher-level spells cost less mana to cast, THIS IS NOT AN ERROR, it's because those will also generally
3345 * have a higher fail rate, because I want there to be no easy answer for the question of "which is the best
3346 * spell to turn into a forgotten spell?" - low-level ones will have a low fail rate but cost much Pw,
3347 * high-level ones will have a high fail rate (unless you're a pretty good spellcaster) but cost little Pw */
3349 forgottencost
= ((9 - spellev(spell
)) * 5);
3350 if (u
.uhave
.amulet
&& u
.amuletcompletelyimbued
&& !u
.freeplaymode
) {
3351 You_feel("the amulet draining your energy away.");
3352 forgottencost
+= rnd(2*forgottencost
);
3354 if (u
.uen
< forgottencost
) {
3356 pline("You are exhausted, and fail to invoke the forgotten spell due to the amulet draining all your energy away.");
3360 if (u
.uen
< forgottencost
) {
3361 You("don't have enough energy to cast that spell. The required amount was %d.", forgottencost
);
3362 if (flags
.moreforced
&& !MessagesSuppressed
) display_nhwindow(WIN_MESSAGE
, TRUE
); /* --More-- */
3365 u
.uen
-= forgottencost
;
3367 Your("knowledge of this spell is twisted.");
3369 if (rnd(100) > (percent_success(spell
))) {
3370 pline("The attempt to invoke the forgotten spell failed.");
3372 pline("In fact, you've screwed up badly enough for it to backfire...");
3378 pline("It invokes nightmarish images in your mind...");
3379 u
.cnd_forgottenspellcount
++;
3380 spell_backfire(spell
);
3385 } else if (spellknow(spell
) <= 100) {
3386 You("strain to recall the spell.");
3387 } else if (spellknow(spell
) <= 1000) {
3388 Your("knowledge of this spell is growing faint.");
3390 energy
= manacost(spellid(spell
));
3391 if (SpellColorYellow
) energy
*= 2;
3392 if (SpellColorWhite
) energy
*= 4;
3398 if (StrongWinceState
) {
3404 if (u
.martialstyle
== MARTIALSTYLE_MUAYTHAI
) {
3408 if (ACURR(A_WIS
) == 2) {
3412 if (ACURR(A_WIS
) == 1) {
3417 /* inertia control and spellbinder make spells a bit more expensive... --Amy */
3418 if (u
.inertiacontrol
) {
3422 if (u
.spellbinder
) {
3426 /* if you have both active, it's even more expensive */
3427 if (u
.spellbinder
&& u
.inertiacontrol
) {
3432 /* only being easier to cast is not good enough for the "special spell", since you can't have a failure rate
3433 * lower than 0%. Reduce cost of casting the special spell to 80%! --Amy */
3434 if (spellid(spell
) == urole
.spelspec
) { if (rn2(10)) energy
+= 1; energy
*= 4; energy
/= 5; }
3435 if (spellid(spell
) == u
.superspecialspell
) { if (rn2(10)) energy
+= 1; energy
*= 4; energy
/= 5; }
3437 if (tech_inuse(T_SPELL_SPAM
) && rn2(10)) {
3438 energy
+= 1; energy
*= 9; energy
/= 10;
3441 /* slight mana cost decrease if you're very skilled, to make skill matter more --Amy */
3442 if (role_skill
== P_SKILLED
) { if (rn2(10)) energy
+= 1; energy
*= 19; energy
/= 20;}
3443 if (role_skill
== P_EXPERT
) { if (rn2(10)) energy
+= 1; energy
*= 18; energy
/= 20;}
3444 if (role_skill
== P_MASTER
) { if (rn2(10)) energy
+= 1; energy
*= 17; energy
/= 20;}
3445 if (role_skill
== P_GRAND_MASTER
) { if (rn2(10)) energy
+= 1; energy
*= 16; energy
/= 20;}
3446 if (role_skill
== P_SUPREME_MASTER
) { if (rn2(10)) energy
+= 1; energy
*= 15; energy
/= 20;}
3448 if (Role_if(PM_MAHOU_SHOUJO
) && energy
> 1) { /* Casting any sort of magic uses half power for them */
3449 if (rn2(10)) energy
+= 1;
3453 if (uarmh
&& uarmh
->oartifact
== ART_FULLY_WORKING_AT_HALF_MAXI
) {
3454 if (rn2(10)) energy
+= 1;
3458 if (uwep
&& uwep
->oartifact
== ART_MANA_METER_BOOSTER
) {
3459 if (rn2(10)) energy
+= 1;
3464 if (uarmc
&& uarmc
->oartifact
== ART_ZIRATHA_S_CASTING_LEGEND
) {
3465 if (rn2(10)) energy
+= 1;
3470 if (uarmg
&& itemhasappearance(uarmg
, APP_UNCANNY_GLOVES
)) {
3475 if (uleft
&& uleft
->oartifact
== ART_HENRIETTA_S_MAGICAL_AID
) {
3476 if (rn2(10)) energy
+= 1;
3481 if (Race_if(PM_BACTERIA
)) {
3482 if (rn2(10)) energy
+= 1;
3487 if (Upolyd
&& dmgtype(youmonst
.data
, AD_SPEL
) ) {
3488 if (rn2(10)) energy
+= 1;
3492 if (Upolyd
&& dmgtype(youmonst
.data
, AD_CLRC
) ) {
3493 if (rn2(10)) energy
+= 1;
3497 if (Upolyd
&& dmgtype(youmonst
.data
, AD_CAST
) ) {
3498 if (rn2(10)) energy
+= 1;
3503 if (uarmc
&& uarmc
->oartifact
== ART_GAGARIN_S_TRANSLATOR
) {
3504 if (rn2(10)) energy
+= 1;
3509 if (uright
&& uright
->oartifact
== ART_HENRIETTA_S_MAGICAL_AID
) {
3510 if (rn2(10)) energy
+= 1;
3514 if (Role_if(PM_ELEMENTALIST
) && skill
== P_ELEMENTAL_SPELL
) {
3515 if (rn2(10)) energy
+= 1;
3520 if ((uarmg
&& itemhasappearance(uarmg
, APP_OCCULTISM_GLOVES
)) && skill
== P_OCCULT_SPELL
) {
3521 if (rn2(10)) energy
+= 1;
3526 if (Race_if(PM_MANSTER
) && energy
> 1) {
3527 if (rn2(10)) energy
+= 1;
3532 if (powerfulimplants() && uimplant
&& uimplant
->oartifact
== ART_DOMPFINATION
) {
3533 if (rn2(10)) energy
+= 1;
3538 if (Role_if(PM_MAHOU_SHOUJO
) && (energy
> 1) && uarmc
&& itemhasappearance(uarmc
, APP_WEEB_CLOAK
) ) {
3539 if (rn2(10)) energy
+= 1;
3544 /* Fail safe. Spellcasting should never become too inexpensive. --Amy */
3545 if (energy
< 2) energy
= rn2(10) ? 2 : 1;
3547 if (u
.uhunger
<= 10 && spellid(spell
) != SPE_DETECT_FOOD
&& spellid(spell
) != SPE_SATISFY_HUNGER
&& spellid(spell
) != SPE_KEEP_SATIATION
) {
3548 You("are too hungry to cast that spell.");
3549 if (flags
.moreforced
&& !MessagesSuppressed
) display_nhwindow(WIN_MESSAGE
, TRUE
); /* --More-- */
3551 } else if (ACURR(A_STR
) < 4 && !(Role_if(PM_CELLAR_CHILD
) && uwep
&& (weapon_type(uwep
) == P_QUARTERSTAFF
)) ) {
3552 You("lack the strength to cast spells.");
3553 if (flags
.moreforced
&& !MessagesSuppressed
) display_nhwindow(WIN_MESSAGE
, TRUE
); /* --More-- */
3555 } else if(check_capacity(
3556 "Your concentration falters while carrying so much stuff.")) {
3557 if (flags
.moreforced
&& !MessagesSuppressed
) display_nhwindow(WIN_MESSAGE
, TRUE
); /* --More-- */
3559 } else if (!freehandX() && !(uwep
&& uwep
->oartifact
== ART_MAGE_STAFF_OF_ETERNITY
) && !(Role_if(PM_CELLAR_CHILD
) && uwep
&& (weapon_type(uwep
) == P_QUARTERSTAFF
)) ) {
3560 Your("arms are not free to cast!");
3561 if (flags
.moreforced
&& !MessagesSuppressed
) display_nhwindow(WIN_MESSAGE
, TRUE
); /* --More-- */
3563 } else if (u
.spellcooldown
> 0) {
3564 pline("Spell cooldown. Wait %d more turns.", u
.spellcooldown
);
3565 if (flags
.moreforced
&& !MessagesSuppressed
) display_nhwindow(WIN_MESSAGE
, TRUE
); /* --More-- */
3567 } else if ((Muteness
|| u
.uprops
[MUTENESS
].extrinsic
|| have_mutenessstone() || (uarmh
&& uarmh
->oartifact
== ART_CLELIA_S_TONGUE_BREAKER
) ) && rn2(10)) {
3568 pline("You're muted, and fail to cast the spell!");
3569 if (flags
.moreforced
&& !MessagesSuppressed
) display_nhwindow(WIN_MESSAGE
, TRUE
); /* --More-- */
3570 u
.uen
-= rnd(20); /* arbitrary; you're supposed to still be able to cast a little sometimes --Amy */
3571 if (u
.uen
< 0) u
.uen
= 0;
3573 } else if (tech_inuse(T_SILENT_OCEAN
)) {
3574 pline("The silent ocean prevents you from spellcasting.");
3575 if (flags
.moreforced
&& !MessagesSuppressed
) display_nhwindow(WIN_MESSAGE
, TRUE
); /* --More-- */
3577 } else if (isevilvariant
&& (Strangled
|| is_silent(youmonst
.data
) || !has_head(youmonst
.data
) || youmonst
.data
->msound
== MS_BUZZ
|| youmonst
.data
->msound
== MS_BURBLE
|| youmonst
.data
->msound
== MS_GURGLE
|| youmonst
.data
->msound
== MS_MUTE
)) {
3578 pline("You're unable to chant any magical formula!");
3579 if (flags
.moreforced
&& !MessagesSuppressed
) display_nhwindow(WIN_MESSAGE
, TRUE
); /* --More-- */
3583 /* Casting any sort of magic as a mahou shoujo or naga does not cause hunger */
3584 /* Amy edit: but if you're satiated, you always use the standard amount of nutrition. That way, hungerless casting
3585 * does not rob you of the ability to get out of satiated status by repeatedly casting spells. */
3587 if ((!Role_if(PM_MAHOU_SHOUJO
) && !Race_if(PM_HUMANLIKE_NAGA
) && (spellid(spell
) != SPE_DETECT_FOOD
) && (spellid(spell
) != SPE_SATISFY_HUNGER
) && (spellid(spell
) != SPE_KEEP_SATIATION
) ) || u
.uhunger
> 2500 ) {
3590 /* If hero is a wizard, their current intelligence
3591 * (bonuses + temporary + current)
3592 * affects hunger reduction in casting a spell.
3593 * 1. int = 17-18 no reduction
3594 * 2. int = 16 1/4 hungr
3595 * 3. int = 15 1/2 hungr
3596 * 4. int = 1-14 normal reduction
3597 * The reason for this is:
3598 * a) Intelligence affects the amount of exertion
3600 * b) Wizards have spent their life at magic and
3601 * understand quite well how to cast spells.
3603 intell
= acurr(A_INT
);
3604 if (!Role_if(PM_WIZARD
)) intell
= 10;
3605 if (u
.uhunger
> 2500) intell
= 10;
3607 case 25: case 24: case 23: case 22:
3608 case 21: case 20: case 19: case 18:
3609 case 17: hungr
= 0; break;
3610 case 16: hungr
/= 4; break;
3611 case 15: hungr
/= 2; break;
3614 /* if you're supposed to get hungry, then it shouldn't be reduced to zero --Amy */
3615 if (hungr
< 1) hungr
= 1;
3619 /* don't put player (quite) into fainting from
3620 * casting a spell, particularly since they might
3621 * not even be hungry at the beginning; however,
3622 * this is low enough that they must eat before
3623 * casting anything else except detect food
3626 if (u
.uhave
.amulet
&& u
.amuletcompletelyimbued
&& !u
.freeplaymode
) {
3627 /* casting while you have the fully imbued amulet always causes extra hunger no matter what --Amy
3628 * but a non-imbued one doesn't increase hunger cost */
3629 hungr
+= rnd(2*energy
);
3632 if (hungr
> u
.uhunger
-3)
3633 hungr
= u
.uhunger
-3;
3634 if (energy
> u
.uen
) {
3635 if (SpellColorPlatinum
) {
3636 You("overcast the spell. Magic reaction hurts you!");
3640 if (role_skill
>= P_SKILLED
|| Race_if(PM_BACTERIA
)) You("don't have enough energy to cast that spell.");
3641 else You("don't have enough energy to cast that spell. The required amount was %d.",energy
);
3642 if (flags
.moreforced
&& !MessagesSuppressed
) display_nhwindow(WIN_MESSAGE
, TRUE
); /* --More-- */
3643 /* WAC/ALI Experts can override with HP/hunger loss */
3644 if ((role_skill
>= P_SKILLED
|| Race_if(PM_BACTERIA
)) && (u
.uhpmax
> (energy
/ 5)) && (yn("Continue? Doing so may damage your maximum health.") == 'y')) {
3646 hungr
+= energy
* 2;
3647 if (hungr
> u
.uhunger
- 1)
3648 hungr
= u
.uhunger
- 1;
3650 if (energy
> 4 && (!Race_if(PM_BACTERIA
) || !rn2(2))) {
3651 /* otherwise, skilled godmode at 0% fail equals instawin. --Amy */
3652 pline("Your maximum health was reduced by %d.", energy
/ 5);
3653 u
.uhpmax
-= (energy
/ 5);
3660 u
.uhp
-= (energy
/ 5);
3666 } else if (energy
< 5 && (!Race_if(PM_BACTERIA
) || !rn2(2))) {
3667 pline("Your maximum health was reduced by 1.");
3684 losehp(energy
,"spellcasting exhaustion", KILLED_BY
);
3685 if (role_skill
< P_EXPERT
) exercise(A_WIS
, FALSE
);
3688 if (role_skill
>= P_SKILLED
|| Race_if(PM_BACTERIA
)) pline("The required amount was %d.",energy
);
3695 /* come on, you should be able to cast using less nutrition if your skill is higher! --Amy */
3697 if ((hungr
> 0) && (u
.uhunger
<= 2500)) { /* But only if you're not satiated (see above) */
3699 if (!PlayerCannotUseSkills
) {
3700 if ( role_skill
== P_BASIC
) {hungr
*= 85; hungr
/= 100;}
3701 if ( role_skill
== P_SKILLED
) {hungr
*= 70; hungr
/= 100;}
3702 if ( role_skill
== P_EXPERT
) {hungr
*= 55; hungr
/= 100;}
3703 if ( role_skill
== P_MASTER
) {hungr
*= 40; hungr
/= 100;}
3704 if ( role_skill
== P_GRAND_MASTER
) {hungr
*= 25; hungr
/= 100;}
3705 if ( role_skill
== P_SUPREME_MASTER
) {hungr
*= 10; hungr
/= 100;}
3708 /* casting it often (and thereby keeping it in memory) should also reduce hunger... */
3709 if ( spellknow(spell
) >= 10000) {hungr
*= 9; hungr
/= 10;}
3710 if ( spellknow(spell
) >= 20000) {hungr
*= 9; hungr
/= 10;}
3711 if ( spellknow(spell
) >= 30000) {hungr
*= 9; hungr
/= 10;}
3712 if ( spellknow(spell
) >= 40000) {hungr
*= 9; hungr
/= 10;}
3713 if ( spellknow(spell
) >= 50000) {hungr
*= 9; hungr
/= 10;}
3714 if ( spellknow(spell
) >= 60000) {hungr
*= 9; hungr
/= 10;}
3715 if ( spellknow(spell
) >= 70000) {hungr
*= 9; hungr
/= 10;}
3717 if (uarmh
&& uarmh
->oartifact
== ART_APOTHEOSIS_VEIL
) hungr
/= 2;
3719 /* higher XL should help, reducing it to 40% of the normal value at max XL --Amy */
3720 if (u
.ulevel
> 10) {
3721 hungr
*= (100 - ((u
.ulevel
- 10) * 3));
3725 if (boost_power_value()) {
3726 hungr
*= (100 - (boost_power_value() * 3) );
3730 if (hungr
< 1) hungr
= 1;
3733 if (SpellColorBlue
) hungr
+= 100;
3735 if (hungr
< 0) hungr
= 0; /* fail safe */
3739 if (SpellColorGray
) {
3741 You("chant the magical formula...");
3742 nomul(-2, "casting a completely gray spell", TRUE
);
3746 if (spellid(spell
) == SPE_PARTICLE_CANNON
) {
3748 nomul(-6, "shooting the particle cannon", FALSE
);
3752 if (MiscastBug
|| u
.uprops
[MISCAST_BUG
].extrinsic
|| have_miscastingstone()) {
3756 if (SpellColorRed
&& !rn2(3)) {
3758 int lcount
= rnd(monster_difficulty() ) + 1;
3760 if (!obsidianprotection()) switch (rn2(11)) {
3761 case 0: make_sick(Sick
? Sick
/2L + 1L : (long)rn1(ACURR(A_CON
),20),
3762 "red spell sickness", TRUE
, SICK_NONVOMITABLE
);
3764 case 1: make_blinded(Blinded
+ lcount
, TRUE
);
3766 case 2: if (!Confusion
)
3767 You("suddenly feel %s.", FunnyHallu
? "trippy" : "confused");
3768 make_confused(HConfusion
+ lcount
, TRUE
);
3770 case 3: make_stunned(HStun
+ lcount
, TRUE
);
3772 case 4: make_numbed(HNumbed
+ lcount
, TRUE
);
3774 case 5: make_frozen(HFrozen
+ lcount
, TRUE
);
3776 case 6: make_burned(HBurned
+ lcount
, TRUE
);
3778 case 7: (void) adjattrib(rn2(A_MAX
), -1, FALSE
, TRUE
);
3780 case 8: (void) make_hallucinated(HHallucination
+ lcount
, TRUE
, 0L);
3782 case 9: make_feared(HFeared
+ lcount
, TRUE
);
3784 case 10: make_dimmed(HDimmed
+ lcount
, TRUE
);
3790 if (SpellColorBrown
&& !(t_at(u
.ux
, u
.uy
)) ) {
3791 register struct trap
*shittrap
;
3792 shittrap
= maketrap(u
.ux
, u
.uy
, SHIT_TRAP
, 0, FALSE
);
3793 if (shittrap
&& !(shittrap
->hiddentrap
)) {
3794 shittrap
->tseen
= 1;
3798 if (SpellCooldownBug
|| u
.uprops
[SPELL_COOLDOWN_BUG
].extrinsic
|| have_spellcooldownstone()) {
3799 if (!u
.spellcooldown
) {
3800 u
.spellcooldown
= SpellCooldownXtra
? rnz(100) : rnz(10);
3801 Your("spellcasting has been put on a timer of %d turns.", u
.spellcooldown
);
3805 if (SpellColorPink
) {
3806 pline("%s", fauxmessage());
3807 u
.cnd_plineamount
++;
3810 if (SpellColorViolet
) pushplayer(TRUE
);
3812 if (SpellColorGreen
) {
3813 register int zx
, zy
;
3814 for(zx
= 0; zx
< COLNO
; zx
++) for(zy
= 0; zy
< ROWNO
; zy
++) {
3815 /* Zonk all memory of this location. */
3816 levl
[zx
][zy
].seenv
= 0;
3817 levl
[zx
][zy
].waslit
= 0;
3818 clear_memory_glyph(zx
, zy
, S_stone
);
3826 chance
= percent_success(spell
);
3828 pline("You try to cast a spell in confusion.");
3830 /* Amy addition: very high skill may allow you to get spells off even while confused */
3831 if (!PlayerCannotUseSkills
) {
3832 confusionchance
= 0;
3833 if ( role_skill
== P_SKILLED
) confusionchance
= 25;
3834 if ( role_skill
== P_EXPERT
) confusionchance
= 50;
3835 if ( role_skill
== P_MASTER
) confusionchance
= 75;
3836 if ( role_skill
== P_GRAND_MASTER
) confusionchance
= 90;
3837 if ( role_skill
== P_SUPREME_MASTER
) confusionchance
= 100;
3841 if (isevilvariant
&& youmonst
.data
->msound
== MS_JAPANESE
) {
3842 if (strstri(spellname(spell
), "r") != 0) {
3844 register int confusedcost
;
3846 pline("You can't spell the letter 'r', and therefore fail to cast the spell correctly.");
3847 u
.cnd_spellfailcount
++;
3848 if (flags
.moreforced
&& !MessagesSuppressed
) display_nhwindow(WIN_MESSAGE
, TRUE
); /* --More-- */
3849 if (!rn2(100)) { /* evil patch idea by Amy: failure effect */
3850 pline("In fact, you cast the spell incorrectly in a way that causes bad stuff to happen...");
3853 if (SpellColorSilver
) u
.seesilverspell
= 0;
3855 if (FailuresAreCostly
) confusedcost
= energy
;
3856 else confusedcost
= ((energy
* 50 / ((role_skill
== P_SUPREME_MASTER
) ? 240 : (role_skill
== P_GRAND_MASTER
) ? 220 : (role_skill
== P_MASTER
) ? 200 : (role_skill
== P_EXPERT
) ? 180 : (role_skill
== P_SKILLED
) ? 160 : (role_skill
== P_BASIC
) ? 140 : 120)) + 1);
3858 u
.uen
-= confusedcost
;
3860 if (SpellColorOrange
) losehp(confusedcost
, "casting an orange spell while confused", KILLED_BY
);
3868 if ( (confused
&& spellid(spell
) != SPE_CURE_CONFUSION
&& spellid(spell
) != SPE_CURE_RANDOM_STATUS
&& (confusionchance
< rnd(100)) && (!StrongConf_resist
|| !rn2(3)) && rn2(Conf_resist
? 5 : 10) ) || (rnd(100) > chance
)) {
3870 register int confusedcost
;
3872 if (!issoviet
) pline("You fail to cast the spell correctly.");
3873 else pline("HA HA HA HA HA, tip bloka l'da sdelal vy ne zaklinaniye!");
3874 u
.cnd_spellfailcount
++;
3875 if (flags
.moreforced
&& !MessagesSuppressed
) display_nhwindow(WIN_MESSAGE
, TRUE
); /* --More-- */
3876 if (!rn2(100)) { /* evil patch idea by Amy: failure effect */
3877 pline("In fact, you cast the spell incorrectly in a way that causes bad stuff to happen...");
3881 if (SpellColorSilver
) u
.seesilverspell
= 0;
3884 if (iflags
.usealleg
) alleg_aura(u
.ux
, u
.uy
, P_ATTACK_SPELL
-1);
3887 /* Higher spellcasting skills mean failure takes less mana. --Amy */
3889 if (FailuresAreCostly
) confusedcost
= energy
;
3890 else confusedcost
= ((energy
* 50 / ((role_skill
== P_SUPREME_MASTER
) ? 240 : (role_skill
== P_GRAND_MASTER
) ? 220 : (role_skill
== P_MASTER
) ? 200 : (role_skill
== P_EXPERT
) ? 180 : (role_skill
== P_SKILLED
) ? 160 : (role_skill
== P_BASIC
) ? 140 : 120)) + 1);
3892 u
.uen
-= confusedcost
;
3894 if (SpellColorOrange
) losehp(confusedcost
, "casting an orange spell while confused", KILLED_BY
);
3900 if (u
.tremblingamount
) {
3901 int tremblechance
= (u
.tremblingamount
* 5 / 2);
3902 if (rn2(100) < rnd(tremblechance
)) {
3906 You("screw up while casting the spell...");
3907 if (flags
.moreforced
&& !MessagesSuppressed
) display_nhwindow(WIN_MESSAGE
, TRUE
); /* --More-- */
3908 u
.cnd_spellfailcount
++;
3911 pline("In fact, you screwed up so badly that bad stuff happens...");
3915 if (SpellColorSilver
) u
.seesilverspell
= 0;
3917 if (FailuresAreCostly
) confusedcost
= energy
;
3918 else confusedcost
= ((energy
* 50 / ((role_skill
== P_SUPREME_MASTER
) ? 240 : (role_skill
== P_GRAND_MASTER
) ? 220 : (role_skill
== P_MASTER
) ? 200 : (role_skill
== P_EXPERT
) ? 180 : (role_skill
== P_SKILLED
) ? 160 : (role_skill
== P_BASIC
) ? 140 : 120)) + 1);
3920 u
.uen
-= confusedcost
;
3922 if (SpellColorOrange
) losehp(confusedcost
, "casting an orange spell while trembling", KILLED_BY
);
3930 /* Players could cheat if they had just barely enough mana for casting a spell without the increased drain.
3931 * They'd just need to keep trying until the extra mana costs are randomly very low.
3932 * Prevent players from abusing this by calculating the extra drain _after_ the other checks. --Amy */
3933 if (u
.uhave
.amulet
&& u
.amuletcompletelyimbued
&& !u
.freeplaymode
) {
3934 You_feel("the amulet draining your energy away.");
3935 energy
+= rnd(2*energy
);
3940 if (SpellColorOrange
) losehp(energy
, "casting an orange spell with too little health", KILLED_BY
);
3942 if (SpellColorSilver
) u
.seesilverspell
= 1;
3944 /* And if the amulet drained it below zero, set it to zero and just make the spell fail now. */
3945 if (u
.uhave
.amulet
&& !u
.freeplaymode
&& u
.amuletcompletelyimbued
&& u
.uen
< 0) {
3946 pline("You are exhausted, and fail to cast the spell due to the amulet draining all your energy away.");
3947 u
.cnd_spellfailcount
++;
3948 if (flags
.moreforced
&& !MessagesSuppressed
) display_nhwindow(WIN_MESSAGE
, TRUE
); /* --More-- */
3950 if (SpellColorSilver
) u
.seesilverspell
= 0;
3954 u
.cnd_spellcastcount
++;
3956 if (uarmg
&& uarmg
->oartifact
== ART_WHOOSHZHOOSH
) {
3957 incr_itimeout(&HFast
, rn1(15, 5));
3960 u
.umemorizationturns
+= spellev(spell
);
3961 if (u
.umemorizationturns
>= 100) {
3962 u
.umemorizationturns
-= 100;
3963 use_skill(P_MEMORIZATION
, 1);
3966 /* if your INT is low, have a very slight chance of increasing it --Amy */
3967 if (ABASE(A_INT
) < 10) {
3968 int intellchance
= 500;
3969 switch (ABASE(A_INT
)) {
3970 case 1: intellchance
= 300; break;
3971 case 2: intellchance
= 400; break;
3972 case 3: intellchance
= 500; break;
3973 case 4: intellchance
= 600; break;
3974 case 5: intellchance
= 700; break;
3975 case 6: intellchance
= 800; break;
3976 case 7: intellchance
= 900; break;
3977 case 8: intellchance
= 1000; break;
3978 case 9: intellchance
= 1000; break;
3979 default: intellchance
= 1000; break;
3982 /* make it depend on spell level... */
3984 intellchance
/= (8 + spellev(spell
));
3986 if (!rn2(intellchance
)) (void) adjattrib(A_INT
, 1, FALSE
, TRUE
);
3989 if (uwep
&& is_lightsaber(uwep
) && (uwep
->lamplit
|| Role_if(PM_SHADOW_JEDI
)) ) {
3992 if (spellev(spell
) > rn2(8)) {
3993 mightbooststat(A_INT
);
3996 if (u
.unimanturns
>= 3) {
3998 use_skill(P_NIMAN
, 1);
4001 if (uwep
&& tech_inuse(T_ENERGY_TRANSFER
)) {
4002 uwep
->age
+= energy
;
4003 if (uwep
->otyp
== ORANGE_LIGHTSABER
) uwep
->age
+= (energy
* rnd(2));
4004 if (uwep
->oartifact
== ART_DESANN_S_WRATH
) uwep
->age
+= (energy
* rnd(2));
4005 pline("Your lightsaber is charged a bit.");
4009 if (uwep
&& uwep
->oartifact
== ART_NEVERMAN
) {
4012 if (spellev(spell
) > rn2(8)) {
4013 mightbooststat(A_INT
);
4016 if (u
.unimanturns
>= 3) {
4018 use_skill(P_NIMAN
, 1);
4022 if (Role_if(PM_MAHOU_SHOUJO
)) { /* Casting any sort of magic causes all monsters on a level to
4023 become alert of your location, due to mahou shoujo always announcing their attacks. */
4026 verbalize("%s!",spellname(spell
) );
4030 if (Race_if(PM_RELEASIER
)) {
4031 verbalize("%s", !rn2(3) ? "Kjear! Hahahahaha!" : !rn2(2) ? "Aa-hu!" : "Hiarwigo!");
4034 if (SpellColorBrightCyan
) {
4038 reset_rndmonst(NON_PM
);
4039 (void) makemon((struct permonst
*)0, 0, 0, MM_ANGRY
|MM_FRENZIED
);
4045 /* you can't hold perfectly still while performing the casting motion; occasionally scuff engraving --Amy
4046 * but less than if you tried to use melee attacks */
4047 if (!rn2(5)) u_wipe_engr(1);
4050 exercise(A_WIS
, TRUE
);
4052 /* pseudo is a temporary "false" object containing the spell stats. */
4053 pseudo
= mksobj(spellid(spell
), FALSE
, 2, FALSE
);
4055 pline("The spell failed spontaneously!");
4056 if (flags
.moreforced
&& !MessagesSuppressed
) display_nhwindow(WIN_MESSAGE
, TRUE
); /* --More-- */
4059 if (pseudo
->otyp
== GOLD_PIECE
) pseudo
->otyp
= spellid(spell
); /* minimalist fix */
4060 pseudo
->blessed
= pseudo
->cursed
= 0;
4061 pseudo
->quan
= 20L; /* do not let useup get it */
4063 /* WAC -- If skilled enough, will act like a blessed version */
4064 if (role_skill
>= P_SKILLED
&& issoviet
) { /* made it depend on skill level --Amy */
4065 if (!rn2(10) && role_skill
== P_SKILLED
) pseudo
->blessed
= 1;
4066 if (!rn2(8) && role_skill
== P_EXPERT
) pseudo
->blessed
= 1;
4067 if (!rn2(6) && role_skill
== P_MASTER
) pseudo
->blessed
= 1;
4068 if (!rn2(5) && role_skill
== P_GRAND_MASTER
) pseudo
->blessed
= 1;
4069 if (!rn2(4) && role_skill
== P_SUPREME_MASTER
) pseudo
->blessed
= 1;
4073 if (iflags
.usealleg
) alleg_aura(u
.ux
, u
.uy
, skill
);
4075 switch(pseudo
->otyp
) {
4077 * At first spells act as expected. As the hero increases in skill
4078 * with the appropriate spell type, some spells increase in their
4079 * effects, e.g. more damage, further distance, and so on, without
4080 * additional cost to the spellcaster.
4082 case SPE_MAGIC_MISSILE
:
4084 case SPE_CONE_OF_COLD
:
4086 case SPE_ACID_STREAM
:
4087 case SPE_SOLAR_BEAM
:
4089 case SPE_POISON_BLAST
:
4090 if (tech_inuse(T_SIGIL_TEMPEST
)) {
4093 } /* else fall through... */
4094 /* these spells are all duplicates of wand effects */
4095 case SPE_FORCE_BOLT
:
4096 case SPE_MAGIC_BOLT
:
4097 case SPE_WATER_BOLT
:
4099 case SPE_CALL_THE_ELEMENTS
:
4102 case SPE_SNIPER_BEAM
:
4103 case SPE_BLINDING_RAY
:
4104 case SPE_ENERGY_BOLT
:
4105 case SPE_GRAVITY_BEAM
:
4106 case SPE_BUBBLEBEAM
:
4107 case SPE_DREAM_EATER
:
4108 case SPE_GOOD_NIGHT
:
4114 case SPE_NETHER_BEAM
:
4115 case SPE_AURORA_BEAM
:
4116 case SPE_CHLOROFORM
:
4119 case SPE_LOCK_MANIPULATION
:
4120 case SPE_SLOW_MONSTER
:
4121 case SPE_RANDOM_SPEED
:
4123 case SPE_CLONE_MONSTER
:
4124 case SPE_WIZARD_LOCK
:
4127 case SPE_GIANT_FOOT
:
4128 case SPE_BUBBLING_HOLE
:
4130 case SPE_NERVE_POISON
:
4131 case SPE_BLOOD_STREAM
:
4132 case SPE_SHINING_WAVE
:
4133 case SPE_ARMOR_SMASH
:
4134 case SPE_STRANGLING
:
4135 case SPE_PARTICLE_CANNON
:
4136 case SPE_BATTERING_RAM
:
4137 case SPE_WATER_FLAME
:
4138 case SPE_TURN_UNDEAD
:
4140 case SPE_CHAOS_BOLT
:
4141 case SPE_HELLISH_BOLT
:
4144 case SPE_TELEPORT_AWAY
:
4145 case SPE_CANCELLATION
:
4147 case SPE_FINGER_OF_DEATH
:
4148 case SPE_LIGHT_AREA
:
4150 case SPE_DETECT_UNSEEN
:
4152 case SPE_EXTRA_HEALING
:
4153 case SPE_FULL_HEALING
:
4154 case SPE_DRAIN_LIFE
:
4156 case SPE_STONE_TO_FLESH
:
4158 case SPE_MAKE_VISIBLE
:
4159 case SPE_STUN_MONSTER
:
4160 case SPE_DISINTEGRATION
:
4161 case SPE_DISINTEGRATION_BEAM
:
4162 case SPE_CHROMATIC_BEAM
:
4163 case SPE_CONVERGE_BREATH
:
4164 case SPE_ELEMENTAL_BEAM
:
4165 case SPE_NATURE_BEAM
:
4169 case SPE_DEFENSIVE_FIREBALL
:
4170 case SPE_HYPER_BEAM
:
4173 if (pseudo
->otyp
== SPE_ULTRA_P
) {
4181 incr_itimeout(&HLevitation
, rn1(30, 10));
4182 spoteffects(FALSE
); /* for sinks */
4185 if (pseudo
->otyp
== SPE_DEFENSIVE_FIREBALL
) {
4186 boolean fireballfail
= FALSE
;
4189 for (i
= -bd
; i
<= bd
; i
++) for(j
= -bd
; j
<= bd
; j
++) {
4190 if (!isok(u
.ux
+ i
, u
.uy
+ j
)) continue;
4191 if ((mtmp
= m_at(u
.ux
+ i
, u
.uy
+ j
)) != 0) {
4192 if (!mtmp
->mpeaceful
&& !mtmp
->mtame
) {
4193 fireballfail
= TRUE
;
4199 You("are interrupted!");
4204 if (pseudo
->otyp
== SPE_BATTERING_RAM
) {
4205 if (u
.battertimer
) {
4206 You("need to wait %d more turns to ready the ram. Battering ram can be used again at turn %ld.", u
.battertimer
, (moves
+ u
.battertimer
));
4213 if (pseudo
->otyp
== SPE_PARTICLE_CANNON
) {
4215 You("need to wait %d more turns to refill your gauge. The particle cannon can be used again at turn %ld.", u
.gaugetimer
, (moves
+ u
.gaugetimer
));
4222 if (pseudo
->otyp
== SPE_CONVERGE_BREATH
) {
4224 You("need to wait %d more turns to refill your gauge. Converge breath can be used again at turn %ld.", u
.gaugetimer
, (moves
+ u
.gaugetimer
));
4231 if (practicantterror
&& pseudo
&& pseudo
->otyp
== SPE_FINGER_OF_DEATH
&& !u
.pract_fodzap
) {
4232 pline("%s thunders: 'Well wait, I'll shut down your evil spellcasting. Also, for actually casting an unforgivable curse, you have to pay 25000 zorkmids. If you keep misbehaving like that I'll show you some unforgivable curses, I tell you...'", noroelaname());
4233 Muteness
+= rnz(5000);
4234 fineforpracticant(25000, 0, 0);
4235 u
.pract_fodzap
= TRUE
;
4238 if (pseudo
->otyp
== SPE_BLOOD_STREAM
) {
4240 if (Upolyd
&& u
.mh
< 5) {
4241 losehp(10000, "forcibly bleeding out", KILLED_BY
);
4242 } else if (!Upolyd
&& u
.uhp
< 5) {
4243 losehp(10000, "forcibly bleeding out", KILLED_BY
);
4246 if (Upolyd
) u
.mh
-= ((u
.mh
/ 5) + 1);
4247 else u
.uhp
-= ((u
.uhp
/ 5) + 1);
4250 u
.mh
-= ((u
.mhmax
/ 5) + 1);
4251 if (u
.mh
< 0) losehp(10000, "forcibly bleeding out", KILLED_BY
);
4253 u
.uhp
-= ((u
.uhpmax
/ 5) + 1);
4254 if (u
.uhp
< 0) losehp(10000, "forcibly bleeding out", KILLED_BY
);
4259 if (!(objects
[pseudo
->otyp
].oc_dir
== NODIR
)) {
4260 if (atme
) u
.dx
= u
.dy
= u
.dz
= 0;
4262 magicalenergychoice
:
4263 if (!getdir((char *)0)) {
4264 /* getdir cancelled, re-use previous direction */
4266 /* Amy edit: this is absolute bullshit behavior, because it's very easy to mistype. It should
4267 * NEVER direct the zap at yourself unless you specifically told it so, but the vanilla behavior
4268 * means that knowing finger of death means death to interface screw can happen at any time.
4269 * I've made magic resistance work too, see zap.c, but those that don't have magic resistance
4270 * shall not be screwed over either. Screw you, programmers. And while you're at it,
4271 * read up on game design and specifically interface design! :P --Amy */
4273 if (yn("Do you really want to input no direction?") == 'y')
4274 pline_The("magical energy is released!");
4276 goto magicalenergychoice
;
4279 if (u
.dx
== 0 && u
.dy
== 0) {
4280 You("would have hit yourself, but to reduce YASD potential the blast goes in a random direction.");
4285 if(!u
.dx
&& !u
.dy
&& !u
.dz
) {
4286 if ((damage
= zapyourself(pseudo
, TRUE
)) != 0) {
4288 sprintf(buf
, "zapped %sself with a spell", uhim());
4289 losehp(damage
, buf
, NO_KILLER_PREFIX
);
4291 } else weffects(pseudo
);
4292 } else weffects(pseudo
);
4293 update_inventory(); /* spell may modify inventory */
4294 if (pseudo
->otyp
== SPE_TELEPORT_AWAY
|| pseudo
->otyp
== SPE_POLYMORPH
|| pseudo
->otyp
== SPE_MUTATION
|| pseudo
->otyp
== SPE_CANCELLATION
) {
4296 pline("The magical energy goes out of control!");
4300 if (pseudo
->otyp
== SPE_VANISHING
) {
4302 pline("The magical energy goes out of control!");
4306 if (pseudo
->otyp
== SPE_WATER_BOLT
) {
4307 make_confused(HConfusion
+ 5, TRUE
);
4308 make_stunned(HStun
+ 5, TRUE
);
4310 pline("The spell backfires!");
4313 if (!(InterfaceScrewed
|| u
.uprops
[INTERFACE_SCREW
].extrinsic
|| have_interfacescrewstone())) (void) doredraw();
4315 if (pseudo
->otyp
== SPE_WIND
) {
4317 pline("The winds hurt you!");
4318 losehp(rnd(10), "winds", KILLED_BY
);
4319 if (In_sokoban(&u
.uz
) && !playercancheatinsoko()) {
4321 pline("You cheater!");
4322 if (evilfriday
) u
.ugangr
++;
4325 if (pseudo
->otyp
== SPE_CHAOS_BOLT
) {
4327 pline("The magical energy goes out of control!");
4328 make_hallucinated(HHallucination
+ rnd(20), FALSE
, 0L);
4329 if (!rn2(10)) set_itimeout(&HeavyHallu
, HHallucination
);
4330 if (!rn2(2)) u
.halresdeactivated
= rnz(50);
4333 if (pseudo
->otyp
== SPE_HELLISH_BOLT
) {
4335 pline("The magical energy goes out of control!");
4336 make_hallucinated(HHallucination
+ rnd(100), FALSE
, 0L);
4337 if (!rn2(5)) set_itimeout(&HeavyHallu
, HHallucination
);
4338 if (rn2(3)) u
.halresdeactivated
= rnz(200);
4342 /* these are all duplicates of scroll effects */
4343 case SPE_REMOVE_CURSE
:
4344 case SPE_CONFUSE_MONSTER
:
4345 case SPE_DETECT_FOOD
:
4346 case SPE_CAUSE_FEAR
:
4348 /* high skill yields effect equivalent to blessed scroll */
4349 if (role_skill
>= P_SKILLED
) pseudo
->blessed
= 1;
4352 case SPE_CHARM_MONSTER
:
4353 case SPE_MAGIC_MAPPING
:
4354 case SPE_CREATE_MONSTER
:
4356 case SPE_DESTROY_ARMOR
:
4357 case SPE_COMMAND_UNDEAD
:
4358 case SPE_SUMMON_UNDEAD
:
4359 if (rn2(5) || !issoviet
) pseudo
->blessed
= 0;
4360 (void) seffects(pseudo
);
4363 pseudo
->blessed
= 0;
4364 (void) seffects(pseudo
);
4367 case SPE_ENCHANT_WEAPON
:
4368 case SPE_ENCHANT_ARMOR
:
4369 if (role_skill
>= P_SUPREME_MASTER
) n
= 7;
4370 else if (role_skill
>= P_GRAND_MASTER
) n
= 8;
4371 else if (role_skill
>= P_MASTER
) n
= 9;
4372 else if (role_skill
>= P_EXPERT
) n
= 10;
4373 else if (role_skill
>= P_SKILLED
) n
= 11;
4374 else if (role_skill
>= P_BASIC
) n
= 12;
4375 else n
= 14; /* Unskilled or restricted */
4377 pseudo
->blessed
= 0;
4378 (void) seffects(pseudo
);
4381 pline("The strain from casting such a powerful spell drains your maximum mana.");
4383 pline("Casting such a powerful spell from hitpoints causes strong backlash.");
4384 badeffect(); badeffect(); badeffect(); badeffect(); badeffect();
4387 Your("enchantment failed!");
4390 case SPE_ENTRAPPING
:
4392 trap_detectX((struct obj
*)0);
4393 exercise(A_WIS
, TRUE
);
4396 pline("The spell backlashes!");
4401 /* these are all duplicates of potion effects */
4402 case SPE_HASTE_SELF
:
4403 case SPE_DETECT_TREASURE
:
4404 case SPE_DETECT_MONSTERS
:
4405 case SPE_LEVITATION
:
4406 case SPE_RESTORE_ABILITY
:
4407 case SPE_BANISHING_FEAR
:
4409 /* high skill yields effect equivalent to blessed potion */
4410 if (role_skill
>= P_SKILLED
) pseudo
->blessed
= 1;
4413 case SPE_INVISIBILITY
:
4414 if (rn2(5) || !issoviet
) pseudo
->blessed
= 0;
4415 (void) peffects(pseudo
);
4417 case SPE_CURE_BLINDNESS
:
4418 if (HeavyBlind
) break;
4419 if (Blinded
> (rn1(Role_if(PM_HEALER
) ? 200 : 100, 20))) {
4420 int effreduction
= rnd(Blinded
/ 2);
4421 if (effreduction
> 0) {
4422 u
.ucreamed
-= effreduction
;
4423 if ((int)(u
.ucreamed
) < 0) u
.ucreamed
= 0; /* fail safe */
4424 Blinded
-= effreduction
;
4425 Your("blindness counter is reduced.");
4427 if (!Role_if(PM_HEALER
) && !rn2(500)) {
4428 pline("The spell backlashes!");
4432 healup(0, 0, FALSE
, TRUE
);
4437 forget(1 + rn2(5), FALSE
);
4439 case SPE_AGGRAVATE_MONSTER
:
4440 You_feel("that monsters are aware of your presence.");
4441 if (PlayerHearsSoundEffects
) pline(issoviet
? "Dazhe sovetskaya Pyat' Lo obostryayetsya v vashem nizkom igrovom masterstve." : "Woaaaaaah!");
4444 case SPE_CURSE_ITEMS
:
4445 You_feel("as if you need some help.");
4446 if (PlayerHearsSoundEffects
) pline(issoviet
? "Vashe der'mo tol'ko chto proklinal." : "Woaaaaaa-AAAH!");
4450 case SPE_ORE_MINING
:
4454 boolean alreadydone
= 0;
4455 for (i
= -1; i
<= 1; i
++) for(j
= -1; j
<= 1; j
++) {
4456 if (!isok(u
.ux
+ i
, u
.uy
+ j
)) continue;
4457 if (alreadydone
) continue;
4458 if (levl
[u
.ux
+ i
][u
.uy
+ j
].typ
== STALACTITE
) {
4459 levl
[u
.ux
+ i
][u
.uy
+ j
].typ
= CORR
;
4461 if (!rn2(3)) { /* 80% chance of glass, 20% of precious gems */
4462 if (rn2(5)) mksobj_at(rnd_class(JADE
+1, LUCKSTONE
-1), u
.ux
+ i
, u
.uy
+ j
, TRUE
, FALSE
, FALSE
);
4463 else mksobj_at(rnd_class(DILITHIUM_CRYSTAL
, JADE
), u
.ux
+ i
, u
.uy
+ j
, TRUE
, FALSE
, FALSE
);
4464 pline("A stalactite turns into gems!");
4467 if (practicantterror
&& !u
.pract_oremining
) {
4468 pline("%s booms: 'Didn't you hear? Mining my ore is forbidden! That's 1000 zorkmids, and you still have one minute to get away from my ore, got it?'", noroelaname());
4469 fineforpracticant(1000, 0, 0);
4470 u
.pract_oremining
= TRUE
;
4475 pline("A stalactite shatters!");
4480 alreadydone
= TRUE
; /* why the HELL does the break statement not go out of the loop */
4481 break; /* only raze one stalactite if there are several --Amy */
4489 if (!(InterfaceScrewed
|| u
.uprops
[INTERFACE_SCREW
].extrinsic
|| have_interfacescrewstone())) (void)doredraw();
4493 case SPE_BOILER_KABOOM
:
4497 for (i
= -1; i
<= 1; i
++) for(j
= -1; j
<= 1; j
++) {
4499 if (!isok(u
.ux
+ i
, u
.uy
+ j
)) continue;
4500 if (levl
[u
.ux
+ i
][u
.uy
+ j
].typ
== RAINCLOUD
) {
4502 levl
[u
.ux
+ i
][u
.uy
+ j
].typ
= CORR
;
4503 explode(u
.ux
+ i
, u
.uy
+ j
, ZT_FIRE
, rnd(boosted_ulevel(1) * 3), WAND_CLASS
, EXPL_FIERY
);
4511 if (!(InterfaceScrewed
|| u
.uprops
[INTERFACE_SCREW
].extrinsic
|| have_interfacescrewstone())) (void)doredraw();
4518 boolean defogged
= 0;
4520 for (i
= -1; i
<= 1; i
++) for(j
= -1; j
<= 1; j
++) {
4522 if (!isok(u
.ux
+ i
, u
.uy
+ j
)) continue;
4523 if (levl
[u
.ux
+ i
][u
.uy
+ j
].typ
== NETHERMIST
) {
4525 levl
[u
.ux
+ i
][u
.uy
+ j
].typ
= CORR
;
4534 if (defogged
) pline("It is not foggy any longer.");
4536 pline("Nothing happens.");
4537 if (FailureEffects
|| u
.uprops
[FAILURE_EFFECTS
].extrinsic
|| have_failurestone()) {
4538 pline("Oh wait, actually something bad happens...");
4545 if (!(InterfaceScrewed
|| u
.uprops
[INTERFACE_SCREW
].extrinsic
|| have_interfacescrewstone())) (void)doredraw();
4549 case SPE_SWAP_POSITION
:
4551 u
.swappositioncount
= 4;
4552 pline("The next monster you move into will be displaced.");
4556 case SPE_SHUFFLE_MONSTER
:
4559 int hasshuffled
= 0;
4561 register struct monst
*nexusmon
, *nextmon
;
4563 for(nexusmon
= fmon
; nexusmon
; nexusmon
= nextmon
) {
4564 nextmon
= nexusmon
->nmon
; /* trap might kill mon */
4565 if (DEADMONSTER(nexusmon
)) continue;
4566 if (u
.usteed
&& nexusmon
== u
.usteed
) continue;
4568 if (!monnear(nexusmon
, u
.ux
, u
.uy
)) continue;
4569 if (nexusmon
->mtrapped
) {
4570 /* no longer in previous trap (affects mintrap) */
4571 nexusmon
->mtrapped
= 0;
4572 fill_pit(nexusmon
->mx
, nexusmon
->my
);
4575 if (pushmonster(nexusmon
)) hasshuffled
++;
4576 if (pushmonster(nexusmon
)) hasshuffled
++;
4580 if (hasshuffled
&& !(InterfaceScrewed
|| u
.uprops
[INTERFACE_SCREW
].extrinsic
|| have_interfacescrewstone())) doredraw();
4582 if (!hasshuffled
) pline("No monsters were shuffled!");
4583 else if (hasshuffled
<= 2) pline("A monster was shuffled!");
4584 else pline("Several monsters were shuffled!");
4590 case SPE_PET_SYRINGE
:
4594 register struct monst
*nexusmon
, *nextmon
;
4598 for(nexusmon
= fmon
; nexusmon
; nexusmon
= nextmon
) {
4599 nextmon
= nexusmon
->nmon
; /* trap might kill mon */
4600 if (DEADMONSTER(nexusmon
)) continue;
4602 if (!monnear(nexusmon
, u
.ux
, u
.uy
)) continue;
4603 if (!nexusmon
->mtame
) continue;
4605 healamount
= d(15, 10 + spell_damage_bonus(SPE_PET_SYRINGE
) );
4606 nexusmon
->mhp
+= healamount
;
4608 if (nexusmon
->mhp
> nexusmon
->mhpmax
) nexusmon
->mhp
= nexusmon
->mhpmax
;
4610 if (nexusmon
->bleedout
&& nexusmon
->bleedout
<= healamount
) {
4611 nexusmon
->bleedout
= 0;
4612 pline("%s's bleeding stops.", Monnam(nexusmon
));
4613 } else if (nexusmon
->bleedout
) {
4614 nexusmon
->bleedout
-= healamount
;
4615 if (nexusmon
->bleedout
< 0) nexusmon
->bleedout
= 0; /* should never happen */
4616 pline("%s's bleeding diminishes.", Monnam(nexusmon
));
4619 abuse_dog(nexusmon
);
4621 pline("%s received the syringe and is healthy again.", Monnam(nexusmon
));
4622 verb
= growl_sound(nexusmon
);
4623 pline("%s %s.", Monnam(nexusmon
), vtense((char *)0, verb
));
4631 case SPE_BUC_KNOWLEDGE
:
4633 if (CannotSelectItemsInPrompts
) break;
4634 pline("Choose an item for BUC identification.");
4636 otmp
= getobj(allnoncount
, "know the BUC of");
4638 if (yn("Really exit with no object selected?") == 'y')
4639 pline("You just wasted the opportunity to determine an item's BUC.");
4640 else goto bucchoice
;
4641 pline("You decide not to determine an item's BUC after all.");
4645 if (!otmp
->bknown
&& (u
.bucskill
< 2 || !rn2(u
.bucskill
)) ) {
4647 if (u
.bucskill
> 250) u
.bucskill
= 250;
4650 otmp
->bknown
= TRUE
;
4651 if (otmp
->blessed
|| otmp
->cursed
) pline("Your %s flashes %s.", doname(otmp
), hcolor(otmp
->blessed
? NH_AMBER
: NH_BLACK
));
4658 You("preach some religious sermon.");
4663 case SPE_RESIST_PARALYSIS
:
4665 if(!(HDiscount_action
& INTRINSIC
)) {
4666 You("gain paralysis resistance!");
4667 incr_itimeout(&HDiscount_action
, HDiscount_action
? (rnd(10) + spell_damage_bonus(spellid(spell
))) : (rn1(100, 50) + spell_damage_bonus(spellid(spell
))*10));
4669 pline("%s", nothing_happens
); /* Already have as intrinsic */
4670 if (FailureEffects
|| u
.uprops
[FAILURE_EFFECTS
].extrinsic
|| have_failurestone()) {
4671 pline("Oh wait, actually something bad happens...");
4678 case SPE_KEEP_SATIATION
:
4680 if(!(HFull_nutrient
& INTRINSIC
)) {
4681 Your("nutrition consumption slows down!");
4682 incr_itimeout(&HFull_nutrient
, HFull_nutrient
? (rnd(10) + spell_damage_bonus(spellid(spell
))) : (rn1(100, 50) + spell_damage_bonus(spellid(spell
))*10));
4684 pline("%s", nothing_happens
); /* Already have as intrinsic */
4685 if (FailureEffects
|| u
.uprops
[FAILURE_EFFECTS
].extrinsic
|| have_failurestone()) {
4686 pline("Oh wait, actually something bad happens...");
4694 if (isok(u
.ux
, u
.uy
)) {
4695 levl
[u
.ux
][u
.uy
].lit
= TRUE
;
4696 pline("A light shines on your location.");
4698 if (isok(u
.ux
, u
.uy
+ 1)) {
4699 levl
[u
.ux
][u
.uy
+ 1].lit
= TRUE
;
4701 if (isok(u
.ux
, u
.uy
- 1)) {
4702 levl
[u
.ux
][u
.uy
- 1].lit
= TRUE
;
4704 if (isok(u
.ux
+ 1, u
.uy
)) {
4705 levl
[u
.ux
+ 1][u
.uy
].lit
= TRUE
;
4707 if (isok(u
.ux
- 1, u
.uy
)) {
4708 levl
[u
.ux
- 1][u
.uy
].lit
= TRUE
;
4712 case SPE_TECH_BOOST
:
4714 if(!(HTechnicality
& INTRINSIC
)) {
4715 Your("techniques become stronger!");
4716 incr_itimeout(&HTechnicality
, HTechnicality
? (rnd(10) + spell_damage_bonus(spellid(spell
))) : (rn1(100, 50) + spell_damage_bonus(spellid(spell
))*10));
4718 pline("%s", nothing_happens
); /* Already have as intrinsic */
4719 if (FailureEffects
|| u
.uprops
[FAILURE_EFFECTS
].extrinsic
|| have_failurestone()) {
4720 pline("Oh wait, actually something bad happens...");
4727 case SPE_MAGIC_CONTROL
:
4729 if(!(HControlMagic
& INTRINSIC
)) {
4730 You("feel more capable of controlling your magic!");
4731 incr_itimeout(&HControlMagic
, HControlMagic
? (rnd(10) + spell_damage_bonus(spellid(spell
))) : (rn1(100, 50) + spell_damage_bonus(spellid(spell
))*10));
4733 pline("%s", nothing_happens
); /* Already have as intrinsic */
4734 if (FailureEffects
|| u
.uprops
[FAILURE_EFFECTS
].extrinsic
|| have_failurestone()) {
4735 pline("Oh wait, actually something bad happens...");
4742 case SPE_ASTRAL_VIEW
:
4744 if(!(HAstral_vision
& INTRINSIC
)) {
4745 You("can see through walls!");
4746 incr_itimeout(&HAstral_vision
, HAstral_vision
? 1 : (5 + spell_damage_bonus(spellid(spell
)) ) );
4748 pline("%s", nothing_happens
); /* Already have as intrinsic */
4749 if (FailureEffects
|| u
.uprops
[FAILURE_EFFECTS
].extrinsic
|| have_failurestone()) {
4750 pline("Oh wait, actually something bad happens...");
4757 case SPE_CAROTINE_INJECTION
:
4760 You("don't have enough health to cast this!");
4763 if (Upolyd
&& u
.mh
< 6) {
4764 You("don't have enough health to cast this!");
4769 losehp(5, "carotine injection", KILLED_BY
);
4771 if(!(HBlind_resistance
& INTRINSIC
)) {
4772 You("feel able to see freely!");
4773 incr_itimeout(&HBlind_resistance
, HBlind_resistance
? (rnd(10) + spell_damage_bonus(spellid(spell
))) : (rnd(100) + spell_damage_bonus(spellid(spell
))*20));
4775 pline("%s", nothing_happens
); /* Already have as intrinsic */
4776 if (FailureEffects
|| u
.uprops
[FAILURE_EFFECTS
].extrinsic
|| have_failurestone()) {
4777 pline("Oh wait, actually something bad happens...");
4784 case SPE_DOWNER_TRIP
:
4786 u
.uprops
[DEAC_FEAR_RES
].intrinsic
+= rnz(250);
4787 make_feared(HFeared
+ rnz(250), TRUE
);
4789 if(!(HHalluc_resistance
& INTRINSIC
)) {
4790 You("feel like you're on a bad trip that lacks fleecy colors!");
4791 incr_itimeout(&HHalluc_resistance
, HHalluc_resistance
? (rnd(100) + spell_damage_bonus(spellid(spell
))) : (rnd(200) + spell_damage_bonus(spellid(spell
))*50));
4793 pline("%s", nothing_happens
); /* Already have as intrinsic */
4794 if (FailureEffects
|| u
.uprops
[FAILURE_EFFECTS
].extrinsic
|| have_failurestone()) {
4795 pline("Oh wait, actually something bad happens...");
4802 case SPE_CONTINGENCY
:
4804 u
.contingencyturns
= 50 + (spell_damage_bonus(spellid(spell
)) * 3);
4805 You("sign up a contract with the reaper.");
4809 case SPE_RANDOM_DETECTION
:
4813 trap_detectX((struct obj
*)0);
4816 You("fail to detect anything.");
4819 object_detect(pseudo
, 0);
4822 monster_detect(pseudo
, 0);
4826 exercise(A_WIS
, TRUE
);
4829 pline("The spell backlashes!");
4835 case SPE_AULE_SMITHING
:
4837 if (CannotSelectItemsInPrompts
) break;
4838 pline("Choose an item for erosionproofing.");
4840 otmp
= getobj(allnoncount
, "fooproof");
4842 if (yn("Really exit with no object selected?") == 'y')
4843 pline("You just wasted the opportunity to fooproof an item.");
4844 else goto aulechoice
;
4845 pline("You decide not to erosionproof any item after all.");
4849 otmp
->oerodeproof
= TRUE
;
4850 pline("Success! Your item is erosionproof now.");
4851 if (otmp
&& objects
[(otmp
)->otyp
].oc_material
== MT_CELESTIUM
&& !stack_too_big(otmp
)) {
4852 if (!otmp
->cursed
) bless(otmp
);
4853 else uncurse(otmp
, FALSE
);
4860 u
.horsehopturns
= 50 + rnd(50 + (spell_damage_bonus(spellid(spell
)) * 5) );
4861 pline("You can jump while riding!");
4869 register struct monst
*nexusmon
, *nextmon
;
4871 for(nexusmon
= fmon
; nexusmon
; nexusmon
= nextmon
) {
4872 nextmon
= nexusmon
->nmon
; /* trap might kill mon */
4873 if (DEADMONSTER(nexusmon
)) continue;
4875 if (!sensemon(nexusmon
) && !canseemon(nexusmon
)) continue;
4878 if (nexusmon
->mhp
<= 0) {
4879 xkilled(nexusmon
, 0);
4880 pline("%s lost the last line and dies!", Monnam(nexusmon
));
4883 pline("%s loses a line!", Monnam(nexusmon
));
4884 wakeup(nexusmon
); /* monster becomes hostile */
4893 case SPE_TACTICAL_NUKE
:
4895 if (Upolyd
) losehp((u
.mhmax
/ 10) + 1, "tactical nuke", KILLED_BY_AN
);
4896 else losehp((u
.uhpmax
/ 10) + 1, "tactical nuke", KILLED_BY_AN
);
4897 pline("Rrrrroommmmmm - the nuke hits you and all monsters in view.");
4901 register struct monst
*nexusmon
, *nextmon
;
4903 for(nexusmon
= fmon
; nexusmon
; nexusmon
= nextmon
) {
4904 nextmon
= nexusmon
->nmon
; /* trap might kill mon */
4905 if (DEADMONSTER(nexusmon
)) continue;
4907 if (!sensemon(nexusmon
) && !canseemon(nexusmon
)) continue;
4909 nexusmon
->mhp
-= ((nexusmon
->mhp
/ 10) + 1);
4910 if (nexusmon
->mhp
<= 0) {
4911 xkilled(nexusmon
, 0);
4912 pline("%s dies to the nuke!", Monnam(nexusmon
));
4915 pline("%s is hurt by the nuke!", Monnam(nexusmon
));
4916 wakeup(nexusmon
); /* monster becomes hostile */
4927 if (u
.ragnarokspelltimeout
) {
4928 pline("Nothing happens.");
4929 if (FailureEffects
|| u
.uprops
[FAILURE_EFFECTS
].extrinsic
|| have_failurestone()) {
4930 pline("Oh wait, actually something bad happens...");
4936 if (evilfriday
) evilragnarok(TRUE
,level_difficulty());
4937 u
.ragnarokspelltimeout
+= 1000; /* can't use it again for a while */
4941 case SPE_IMPACT_GUNFIRE
:
4944 You("need to wait %d more turns to refill your gauge. Impact Gunfire can be used again at turn %ld.", u
.gaugetimer
, (moves
+ u
.gaugetimer
));
4951 register struct obj
*opbullet
;
4956 ctx
= u
.ux
, cty
= u
.uy
;
4959 struct monst
*psychmonst
;
4961 opbullet
= carrying(PISTOL_BULLET
);
4962 if (!opbullet
) opbullet
= carrying(SILVER_PISTOL_BULLET
);
4963 if (!opbullet
) opbullet
= carrying(LEAD_PISTOL_BULLET
);
4964 if (!opbullet
) opbullet
= carrying(ANTIMATTER_PISTOL_BULLET
);
4966 pline("There are no pistol bullets, and therefore you can't shoot!");
4970 opdamage
= d(8, 12) + (spell_damage_bonus(spellid(spell
)) * 6);
4973 if (opbullet
->spe
> 0) opbonus
= opbullet
->spe
;
4975 if (opbullet
->quan
> 1) {
4977 opbullet
->owt
= weight(opbullet
);
4979 else useup(opbullet
);
4983 if (opdamage
> 1) opdamage
= rnd(opdamage
);
4984 opdamage
+= (opbonus
* rnd(25));
4986 if (!getdir((char *)0)) return(0);
4987 if (!u
.dx
&& !u
.dy
) {
4988 You("can't direct that at yourself.");
4992 for(i
= 0; i
< 8; i
++) {
4993 if (!isok(ctx
+ u
.dx
, cty
+ u
.dy
)) break;
4994 if (levl
[ctx
+ u
.dx
][cty
+ u
.dy
].typ
< POOL
) break;
4999 psychmonst
= m_at(ctx
, cty
);
5002 pline("Pouchschieau! Your projectile blasts %s!", mon_nam(psychmonst
));
5003 if (noncorporeal(psychmonst
->data
)) { /* ghosts are hard to hit... */
5004 if (opdamage
> 1) opdamage
/= 2;
5005 pline("%s resists the attack!", Monnam(psychmonst
));
5006 /* but isn't immune --Amy */
5008 psychmonst
->mhp
-= opdamage
;
5009 if (psychmonst
->mhp
< 1) {
5010 pline("%s is blown to bits.", Monnam(psychmonst
));
5011 xkilled(psychmonst
,0);
5013 wakeup(psychmonst
); /* make them hostile */
5014 if (psychmonst
->mcanmove
) {
5015 psychmonst
->mcanmove
= 0;
5016 psychmonst
->mfrozen
= 2;
5017 pline("%s is paralyzed.", Monnam(psychmonst
));
5029 case SPE_ONE_POINT_SHOOT
:
5032 You("need to wait %d more turns to refill your gauge. One Point Shoot can be used again at turn %ld.", u
.gaugetimer
, (moves
+ u
.gaugetimer
));
5039 register struct obj
*opbullet
;
5044 struct monst
*psychmonst
;
5046 opbullet
= carrying(PISTOL_BULLET
);
5047 if (!opbullet
) opbullet
= carrying(SILVER_PISTOL_BULLET
);
5048 if (!opbullet
) opbullet
= carrying(LEAD_PISTOL_BULLET
);
5049 if (!opbullet
) opbullet
= carrying(ANTIMATTER_PISTOL_BULLET
);
5051 pline("There are no pistol bullets, and therefore you can't shoot!");
5055 opdamage
= d(6, 12) + (spell_damage_bonus(spellid(spell
)) * 5);
5057 pline("Select the target monster");
5060 getpos(&cc
, TRUE
, "the spot to shoot");
5061 if (cc
.x
== -10) break; /* user pressed esc */
5062 psychmonst
= m_at(cc
.x
, cc
.y
);
5064 if (!psychmonst
|| (!canseemon(psychmonst
) && !canspotmon(psychmonst
))) {
5065 You("don't see a monster there!");
5069 /* there should be a valid target now, so use up a bullet */
5071 if (opbullet
->spe
> 0) opbonus
= opbullet
->spe
;
5073 if (opbullet
->quan
> 1) {
5075 opbullet
->owt
= weight(opbullet
);
5077 else useup(opbullet
);
5081 if (opdamage
> 1) opdamage
= rnd(opdamage
);
5082 opdamage
+= (opbonus
* rnd(20));
5086 pline("PEW PEW PEW! %s is shot by your gun!", Monnam(psychmonst
));
5087 if (noncorporeal(psychmonst
->data
)) { /* ghosts are hard to hit... */
5088 if (opdamage
> 1) opdamage
/= 2;
5089 pline("%s resists the attack!", Monnam(psychmonst
));
5090 /* but isn't immune --Amy */
5092 psychmonst
->mhp
-= opdamage
;
5093 if (psychmonst
->mhp
< 1) {
5094 pline("%s resonates and breaks up.", Monnam(psychmonst
));
5095 xkilled(psychmonst
,0);
5096 } else wakeup(psychmonst
); /* make them hostile */
5106 if (u
.returntimer
) {
5108 pline_The("air around you gradually loses power.");
5109 break; /* be lenient, damage Pw only if you're not already returning --Amy */
5113 if (u
.uenmax
< 0) u
.uenmax
= 0;
5114 if (u
.uen
> u
.uenmax
) u
.uen
= u
.uenmax
;
5120 case SPE_GROUND_STOMP
:
5123 You("are unable to use ground stomp while confused.");
5127 You("smash something the ground."); /* This is NOT a misspelling!!! --Amy */
5131 register struct monst
*nexusmon
, *nextmon
;
5133 for(nexusmon
= fmon
; nexusmon
; nexusmon
= nextmon
) {
5134 nextmon
= nexusmon
->nmon
; /* trap might kill mon */
5135 if (DEADMONSTER(nexusmon
)) continue;
5136 if (!monnear(nexusmon
, u
.ux
, u
.uy
)) continue;
5138 if (!sensemon(nexusmon
) && !canseemon(nexusmon
)) continue;
5140 nexusmon
->mhp
-= (d(10, 10 + (spell_damage_bonus(spellid(spell
)) * 5) ) + rnd(boosted_ulevel(1) * 5));
5141 if (nexusmon
->mhp
<= 0) {
5142 xkilled(nexusmon
, 0);
5143 pline("%s is crushed flat!", Monnam(nexusmon
));
5146 pline("%s is hit by debris!", Monnam(nexusmon
));
5147 wakeup(nexusmon
); /* monster becomes hostile */
5154 make_confused(HConfusion
+ rn1(50,75), FALSE
);
5155 set_itimeout(&HeavyConfusion
, HConfusion
);
5156 u
.uprops
[DEAC_CONF_RES
].intrinsic
+= rn1(50,75);
5164 int successrate
= 0;
5166 if (!(PlayerCannotUseSkills
) && P_SKILL(P_OCCULT_SPELL
) >= P_UNSKILLED
) {
5168 switch (P_SKILL(P_OCCULT_SPELL
)) {
5169 case P_BASIC
: successrate
= 25; break;
5170 case P_SKILLED
: successrate
= 40; break;
5171 case P_EXPERT
: successrate
= 50; break;
5172 case P_MASTER
: successrate
= 60; break;
5173 case P_GRAND_MASTER
: successrate
= 80; break;
5174 case P_SUPREME_MASTER
: successrate
= 100; break;
5175 default: successrate
= 10; break;
5181 pline("Unfortunately, no one seems to follow any directives you're giving.");
5185 if (!PlayerCannotUseSkills
&& P_SKILL(P_RIDING
) >= P_SKILLED
&& rnd(75) <= successrate
) {
5187 pline("Currently your steed has %d%% chance of being targetted by monsters.", u
.steedhitchance
);
5188 if (yn("Change it?") == 'y') {
5190 int lowerbound
, higherbound
;
5194 switch (P_SKILL(P_RIDING
)) {
5207 case P_GRAND_MASTER
:
5211 case P_SUPREME_MASTER
:
5221 pline("You can set the chance to values between %d%% and %d%% (inclusive).", lowerbound
, higherbound
);
5222 if (lowerbound
<= 1 && yn("Set the chance to 1%%?") == 'y') {
5223 u
.steedhitchance
= 1;
5224 pline("The chance that attacks target your steed is 1%% now.");
5225 } else if (lowerbound
<= 3 && yn("Set the chance to 3%%?") == 'y') {
5226 u
.steedhitchance
= 3;
5227 pline("The chance that attacks target your steed is 3%% now.");
5228 } else if (lowerbound
<= 5 && yn("Set the chance to 5%%?") == 'y') {
5229 u
.steedhitchance
= 5;
5230 pline("The chance that attacks target your steed is 5%% now.");
5231 } else if (lowerbound
<= 10 && yn("Set the chance to 10%%?") == 'y') {
5232 u
.steedhitchance
= 10;
5233 pline("The chance that attacks target your steed is 10%% now.");
5234 } else if (lowerbound
<= 20 && yn("Set the chance to 20%%?") == 'y') {
5235 u
.steedhitchance
= 20;
5236 pline("The chance that attacks target your steed is 20%% now.");
5237 } else if (yn("Set the chance to 25%%?") == 'y') {
5238 u
.steedhitchance
= 25;
5239 pline("The chance that attacks target your steed is 25%% now.");
5240 } else if (higherbound
>= 33 && yn("Set the chance to 33%%?") == 'y') {
5241 u
.steedhitchance
= 33;
5242 pline("The chance that attacks target your steed is 33%% now.");
5243 } else if (higherbound
>= 50 && yn("Set the chance to 50%%?") == 'y') {
5244 u
.steedhitchance
= 50;
5245 pline("The chance that attacks target your steed is 50%% now.");
5246 } else if (higherbound
>= 75 && yn("Set the chance to 75%%?") == 'y') {
5247 u
.steedhitchance
= 75;
5248 pline("The chance that attacks target your steed is 75%% now.");
5249 } else if (higherbound
>= 90 && yn("Set the chance to 90%%?") == 'y') {
5250 u
.steedhitchance
= 90;
5251 pline("The chance that attacks target your steed is 90%% now.");
5252 } else if (higherbound
>= 100 && yn("Set the chance to 100%%?") == 'y') {
5253 u
.steedhitchance
= 100;
5254 pline("The chance that attacks target your steed is 100%% now.");
5255 } else pline("The chance that attacks target your steed remains %d%%.", u
.steedhitchance
);
5261 if (rnd(20) <= successrate
) {
5263 pline("Currently your pets can%s pick up items.", u
.petcollectitems
? "" : "'t");
5264 if (yn("Change it?") == 'y') {
5265 if (u
.petcollectitems
) u
.petcollectitems
= 0;
5266 else u
.petcollectitems
= 1;
5267 pline("Your pets can%s pick up items now.", u
.petcollectitems
? "" : "'t");
5272 if (rnd(45) <= successrate
) {
5274 pline("Currently your pets can%s attack%s monsters.", (u
.petattackenemies
> 0) ? "" : "'t", u
.petattackenemies
== 2 ? " both hostile and peaceful" : u
.petattackenemies
== 1 ? " only hostile" : u
.petattackenemies
== -1 ? " or be attacked by" : "");
5275 if (yn("Change it?") == 'y') {
5276 pline("You got the following options: make the pet attack everything, make it attack only hostile monsters, or prevent it from attacking anything (with the choice that it may or may not still be attacked by hostiles).");
5277 if (yn("Do you want your pets to attack everything?") == 'y') {
5278 u
.petattackenemies
= 2;
5279 pline("Your pets can attack all monsters now.");
5280 } else if (yn("Do you want your pets to only attack hostile creatures?") == 'y') {
5281 u
.petattackenemies
= 1;
5282 pline("Your pets can attack hostile monsters now, but will leave peaceful ones alone.");
5283 } else if (yn("Do you want your pets to not attack any monsters, but still be attacked by them?") == 'y') {
5284 u
.petattackenemies
= 0;
5285 pline("Your pets can't attack monsters now.");
5286 } else if (yn("Do you want your pets to not attack any monsters, and also not be attacked by them anymore?") == 'y') {
5287 u
.petattackenemies
= -1;
5288 pline("Your pets can't attack monsters now and also won't be attacked by monsters.");
5294 if (rnd(75) <= successrate
) {
5296 pline("Currently your pets can%s eat food off the floor.", u
.petcaneat
? "" : "'t");
5297 if (yn("Change it?") == 'y') {
5298 if (u
.petcaneat
) u
.petcaneat
= 0;
5299 else u
.petcaneat
= 1;
5300 pline("Your pets can%s eat food off the floor now.", u
.petcaneat
? "" : "'t");
5305 if (rnd(120) <= successrate
) {
5307 pline("Currently your pets can%s try to follow you.", u
.petcanfollow
? "" : "'t");
5308 if (yn("Change it?") == 'y') {
5309 if (u
.petcanfollow
) u
.petcanfollow
= 0;
5310 else u
.petcanfollow
= 1;
5311 pline("Your pets can%s try to follow you now.", u
.petcanfollow
? "" : "'t");
5320 case SPE_POWDER_SPRAY
:
5322 You("spray the powder.");
5326 register struct monst
*nexusmon
, *nextmon
;
5328 for(nexusmon
= fmon
; nexusmon
; nexusmon
= nextmon
) {
5329 nextmon
= nexusmon
->nmon
; /* trap might kill mon */
5330 if (DEADMONSTER(nexusmon
)) continue;
5332 if (!monnear(nexusmon
, u
.ux
, u
.uy
)) continue;
5333 if (resist(nexusmon
, SPBOOK_CLASS
, 0, NOTELL
)) continue;
5334 if (resists_poison(nexusmon
) && !player_will_pierce_resistance()) continue;
5336 nexusmon
->mhp
-= rn1(10, 6);
5337 if (!rn2(500) && !resists_poison(nexusmon
)) {
5338 pline("The poison was deadly...");
5340 xkilled(nexusmon
, 0);
5341 } else if (nexusmon
->mhp
<= 0) {
5342 xkilled(nexusmon
, 0);
5343 pline("%s is poisoned to death!", Monnam(nexusmon
));
5346 pline("%s is poisoned!", Monnam(nexusmon
));
5347 wakeup(nexusmon
); /* monster becomes hostile */
5357 throwstorm(pseudo
, 2 + spell_damage_bonus(SPE_FIREWORKS
), 2, 2);
5361 case SPE_AIMBOT_LIGHTNING
:
5367 pline("Select the target square");
5370 getpos(&cc
, TRUE
, "the spot to aim lightning from");
5371 if (cc
.x
== -10) break; /* user pressed esc */
5373 if (!couldsee(cc
.x
, cc
.y
)) {
5374 You("can't see the location, and therefore nothing happens!");
5380 if (dirx
== 0 && diry
== 0) { /* fail safe; yeah I know this biases it towards diagonal :P --Amy */
5381 dirx
= rn2(2) ? 1 : -1;
5382 diry
= rn2(2) ? 1 : -1;
5384 if (dirx
!= 0 || diry
!= 0) {
5385 buzz(15, 8 + (spell_damage_bonus(SPE_AIMBOT_LIGHTNING
) * rnd(2)), cc
.x
, cc
.y
, dirx
, diry
);
5392 case SPE_ENHANCE_BREATH
:
5394 u
.breathenhancetimer
= 100 + (spell_damage_bonus(SPE_ENHANCE_BREATH
) * 10);
5395 Your("breath is magically enhanced!");
5399 case SPE_GOUGE_DICK
:
5402 pline("This spell has no effect if you're not engulfed.");
5405 pline("You ram into %s with your %spenis.", mon_nam(u
.ustuck
), flags
.female
? "nonexistant " : "");
5406 if (u
.ustuck
->mpeaceful
&& !(u
.ustuck
->mtame
)) u
.ustuck
->mpeaceful
= 0; /* monster becomes hostile */
5407 u
.ustuck
->mhp
-= d(flags
.female
? 2 : 5, 5 + spell_damage_bonus(SPE_GOUGE_DICK
) + rno(boosted_ulevel(1)));
5408 u
.ustuck
->mcanmove
= 0;
5409 u
.ustuck
->mfrozen
= rn1(5,5);
5410 u
.ustuck
->mstrategy
&= ~STRAT_WAITFORU
;
5412 if (u
.ustuck
->mhp
<= 0) {
5413 xkilled(u
.ustuck
, 0);
5414 pline("The monster that engulfed you is stabbed to death!");
5416 else pline("%s is severely hurt!", Monnam(u
.ustuck
));
5420 case SPE_BODYFLUID_STRENGTHENING
:
5422 u
.bodyfluideffect
= 10 + spell_damage_bonus(SPE_BODYFLUID_STRENGTHENING
);
5423 Your("body is covered with protective acid!");
5427 case SPE_PURIFICATION
:
5431 for (i
= -1; i
<= 1; i
++) for(j
= -1; j
<= 1; j
++) {
5432 if (!isok(u
.ux
+ i
, u
.uy
+ j
)) continue;
5433 if (i
== 0 && j
== 0) continue; /* don't target the square you're on --Amy */
5434 if (levl
[u
.ux
+ i
][u
.uy
+ j
].typ
== STYXRIVER
) {
5435 levl
[u
.ux
+ i
][u
.uy
+ j
].typ
= MOAT
;
5436 Norep("A styx river turns into a moat!");
5441 if (!(InterfaceScrewed
|| u
.uprops
[INTERFACE_SCREW
].extrinsic
|| have_interfacescrewstone())) (void)doredraw();
5445 case SPE_ADD_SPELL_MEMORY
:
5447 if (spellid(0) == NO_SPELL
) { /* should never happen, but I put it here just in case --Amy */
5448 You("don't know any spells, and therefore you cannot add spell memory to them either.");
5452 pline("Choose a spell to add spell memory.");
5454 if (!addsomespellmemory()) {
5455 if (yn("Really exit with no spell selected?") == 'y')
5456 pline("You just wasted the opportunity to add memory to a spell.");
5457 else goto addspmagain
;
5469 pline("You are teleported by nexus forces!");
5474 pline("You are pushed around by nexus forces!");
5479 if (!playerlevelportdisabled() ) {
5480 make_stunned(HStun
+ 2, FALSE
); /* to suppress teleport control that you might have */
5482 if (!u
.levelporting
) {
5484 nomul(-2, "being levelported", FALSE
); /* because it's not called until you get another turn... */
5494 int reducedstat
= rn2(A_MAX
);
5495 if(ABASE(reducedstat
) <= ATTRABSMIN(reducedstat
)) {
5496 pline("Your health was damaged!");
5498 if (u
.uhp
> u
.uhpmax
) u
.uhp
= u
.uhpmax
;
5501 killer
= "nexus scrambling";
5502 killer_format
= KILLED_BY
;
5508 ABASE(reducedstat
) -= 1;
5509 AMAX(reducedstat
) -= 1;
5511 pline("Your attributes were damaged!");
5520 pline("The spell backfires!");
5526 case SPE_ANTI_TELEPORTATION
:
5528 u
.antitelespelltimeout
= rnd(100 + (spell_damage_bonus(SPE_ANTI_TELEPORTATION
) * 10));
5529 You("erect an anti-teleportation barrier!");
5534 if (!Fumbling
) pline("You start fumbling.");
5535 HFumbling
= FROMOUTSIDE
| rnd(5);
5536 set_itimeout(&HFumbling
, 2);
5537 u
.fumbleduration
+= rnz(1000);
5539 case SPE_REMOVE_BLESSING
:
5543 You_feel("the power of the Force against you!");
5545 You_feel("like you need some help.");
5546 if (PlayerHearsSoundEffects
) pline(issoviet
? "Vashe der'mo tol'ko chto proklinal." : "Woaaaaaa-AAAH!");
5548 register struct obj
*obj
, *obj2
;
5549 for (obj
= invent
; obj
; obj
= obj2
) {
5551 if (obj
->blessed
&& !stack_too_big(obj
) ) unbless(obj
);
5556 case SPE_CORRODE_METAL
:
5559 pline("You are covered by %s particles!",NH_GREEN
);
5561 register struct obj
*obj
, *obj2
;
5562 for (obj
= invent
; obj
; obj
= obj2
) {
5564 rust_dmg(obj
, xname(obj
), 3, TRUE
, &youmonst
);
5569 case SPE_DETECT_ARMOR_ENCHANTMENT
:
5572 pline("You detect the enchantment status of your armor!");
5574 register struct obj
*obj
, *obj2
;
5575 for (obj
= invent
; obj
; obj
= obj2
) {
5578 if (obj
->oclass
== ARMOR_CLASS
&& !obj
->known
&& (obj
->shirtmessage
% 3 == 0) ) {
5588 case SPE_METAL_GUARD
:
5590 if (u
.metalguard
) pline("%s", nothing_happens
);
5592 u
.metalguard
= TRUE
;
5593 You("activate your metal guard!");
5598 case SPE_MAGIC_WHISTLING
:
5601 register struct monst
*whismtmp
, *whisnextmon
;
5603 You("try to whistle your pets here...");
5605 for(whismtmp
= fmon
; whismtmp
; whismtmp
= whisnextmon
) {
5606 whisnextmon
= whismtmp
->nmon
; /* trap might kill mon */
5607 if (DEADMONSTER(whismtmp
)) continue;
5608 if (evilfriday
&& level
.flags
.noteleport
) continue;
5609 if (whismtmp
== u
.usteed
) continue;
5610 if (whismtmp
->mtame
) {
5611 if (whismtmp
->mtrapped
) {
5612 /* no longer in previous trap (affects mintrap) */
5613 whismtmp
->mtrapped
= 0;
5614 fill_pit(whismtmp
->mx
, whismtmp
->my
);
5617 if (mintrap(whismtmp
) == 2) change_luck(-1);
5623 case SPE_GAIN_SPACT
:
5625 if (u
.uhpmax
< 101) {
5626 pline("You don't have enough health to control the powers of this spell!");
5629 if (Upolyd
&& u
.mhmax
< 101) {
5630 pline("You don't have enough health to control the powers of this spell!");
5634 u
.uhpmax
-= rnd(100);
5635 if (u
.uhp
> u
.uhpmax
) u
.uhp
= u
.uhpmax
;
5637 u
.mhmax
-= rnd(100);
5638 if (u
.mh
> u
.mhmax
) u
.mh
= u
.mhmax
;
5642 int wondertech
= rnd(MAXTECH
-1);
5643 learntech_or_leveltech(wondertech
, FROMOUTSIDE
, 1);
5644 You("learn how to perform a new technique!");
5650 case SPE_ATTUNE_MAGIC
:
5653 pline("Your mana increases.");
5655 } else switch (rnd(30)) {
5658 HTeleport_control
+= 2;
5664 register struct obj
*acqo
;
5666 acqo
= mkobj_at(SPBOOK_CLASS
, u
.ux
, u
.uy
, FALSE
, FALSE
);
5668 acqo
->bknown
= acqo
->known
= TRUE
;
5669 pline("A book appeared at your %s!", makeplural(body_part(FOOT
)));
5671 pline("Nothing happens...");
5672 if (FailureEffects
|| u
.uprops
[FAILURE_EFFECTS
].extrinsic
|| have_failurestone()) {
5673 pline("Oh wait, actually something bad happens...");
5680 (void) monster_detect((struct obj
*)0, 0);
5681 exercise(A_WIS
, TRUE
);
5684 trap_detect((struct obj
*)0);
5687 object_detect((struct obj
*)0, 0);
5691 boolean havegifts
= u
.ugifts
;
5693 if (!havegifts
) u
.ugifts
++;
5695 register struct obj
*acqo
;
5697 acqo
= mk_artifact((struct obj
*)0, !rn2(3) ? A_CHAOTIC
: rn2(2) ? A_NEUTRAL
: A_LAWFUL
, TRUE
);
5700 int acqoskill
= get_obj_skill(acqo
, TRUE
);
5702 if (P_MAX_SKILL(acqoskill
) == P_ISRESTRICTED
) {
5703 unrestrict_weapon_skill(acqoskill
);
5704 } else if (P_MAX_SKILL(acqoskill
) == P_UNSKILLED
) {
5705 unrestrict_weapon_skill(acqoskill
);
5706 P_MAX_SKILL(acqoskill
) = P_BASIC
;
5707 } else if (rn2(2) && P_MAX_SKILL(acqoskill
) == P_BASIC
) {
5708 P_MAX_SKILL(acqoskill
) = P_SKILLED
;
5709 } else if (!rn2(4) && P_MAX_SKILL(acqoskill
) == P_SKILLED
) {
5710 P_MAX_SKILL(acqoskill
) = P_EXPERT
;
5711 } else if (!rn2(10) && P_MAX_SKILL(acqoskill
) == P_EXPERT
) {
5712 P_MAX_SKILL(acqoskill
) = P_MASTER
;
5713 } else if (!rn2(100) && P_MAX_SKILL(acqoskill
) == P_MASTER
) {
5714 P_MAX_SKILL(acqoskill
) = P_GRAND_MASTER
;
5715 } else if (!rn2(200) && P_MAX_SKILL(acqoskill
) == P_GRAND_MASTER
) {
5716 P_MAX_SKILL(acqoskill
) = P_SUPREME_MASTER
;
5718 if (Race_if(PM_RUSMOT
)) {
5719 if (P_MAX_SKILL(acqoskill
) == P_ISRESTRICTED
) {
5720 unrestrict_weapon_skill(acqoskill
);
5721 } else if (P_MAX_SKILL(acqoskill
) == P_UNSKILLED
) {
5722 unrestrict_weapon_skill(acqoskill
);
5723 P_MAX_SKILL(acqoskill
) = P_BASIC
;
5724 } else if (rn2(2) && P_MAX_SKILL(acqoskill
) == P_BASIC
) {
5725 P_MAX_SKILL(acqoskill
) = P_SKILLED
;
5726 } else if (!rn2(4) && P_MAX_SKILL(acqoskill
) == P_SKILLED
) {
5727 P_MAX_SKILL(acqoskill
) = P_EXPERT
;
5728 } else if (!rn2(10) && P_MAX_SKILL(acqoskill
) == P_EXPERT
) {
5729 P_MAX_SKILL(acqoskill
) = P_MASTER
;
5730 } else if (!rn2(100) && P_MAX_SKILL(acqoskill
) == P_MASTER
) {
5731 P_MAX_SKILL(acqoskill
) = P_GRAND_MASTER
;
5732 } else if (!rn2(200) && P_MAX_SKILL(acqoskill
) == P_GRAND_MASTER
) {
5733 P_MAX_SKILL(acqoskill
) = P_SUPREME_MASTER
;
5737 discover_artifact(acqo
->oartifact
);
5739 if (!havegifts
) u
.ugifts
--;
5740 pline("An artifact appeared beneath you!");
5744 else pline("Opportunity knocked, but nobody was home. Bummer.");
5750 pline("The RNG decides to curse-weld an item to you.");
5751 bad_artifact_xtra();
5755 int aggroamount
= rnd(6);
5756 if (isfriday
) aggroamount
*= 2;
5758 reset_rndmonst(NON_PM
);
5759 while (aggroamount
) {
5760 u
.cnd_aggravateamount
++;
5761 makemon((struct permonst
*)0, u
.ux
, u
.uy
, MM_ANGRY
|MM_FRENZIED
);
5763 if (aggroamount
< 0) aggroamount
= 0;
5766 pline("Several monsters come out of a portal.");
5772 pline("Your body suddenly becomes all stiff!");
5773 if (isstunfish
) nomul(-rnz(15), "paralyzed by a pentagram", TRUE
);
5774 else nomul(-rnd(15), "paralyzed by a pentagram", TRUE
);
5778 pline("The dungeon is getting more chaotic!");
5780 int madepoolPEP
= 0;
5781 do_clear_areaX(u
.ux
, u
.uy
, 12, do_terrainfloodg
, (void *)&madepoolPEP
);
5786 You_feel("powered up!");
5791 pline("Suddenly, you gain a new companion!");
5792 (void) make_familiar((struct obj
*)0, u
.ux
, u
.uy
, FALSE
, FALSE
);
5797 if (Aggravate_monster
) {
5799 reset_rndmonst(NON_PM
);
5806 int randsp
, randmnst
, randmnsx
;
5807 struct permonst
*randmonstforspawn
;
5815 randsp
= (rn2(14) + 2);
5816 if (!rn2(10)) randsp
*= 2;
5817 if (!rn2(100)) randsp
*= 3;
5818 if (!rn2(1000)) randsp
*= 5;
5819 if (!rn2(10000)) randsp
*= 10;
5820 randmnst
= (rn2(187) + 1);
5821 randmnsx
= (rn2(100) + 1);
5823 pline("You suddenly feel a surge of tension!");
5825 for (i
= 0; i
< randsp
; i
++) {
5826 /* This function will fill the map with a random amount of monsters of one class. --Amy */
5828 if (!enexto(&dd
, u
.ux
, u
.uy
, (struct permonst
*)0) ) continue;
5831 (void) makemon(mkclass(S_ANT
,0), cx
, cy
, MM_ADJACENTOK
);
5832 else if (randmnst
< 9)
5833 (void) makemon(mkclass(S_BLOB
,0), cx
, cy
, MM_ADJACENTOK
);
5834 else if (randmnst
< 11)
5835 (void) makemon(mkclass(S_COCKATRICE
,0), cx
, cy
, MM_ADJACENTOK
);
5836 else if (randmnst
< 15)
5837 (void) makemon(mkclass(S_DOG
,0), cx
, cy
, MM_ADJACENTOK
);
5838 else if (randmnst
< 18)
5839 (void) makemon(mkclass(S_EYE
,0), cx
, cy
, MM_ADJACENTOK
);
5840 else if (randmnst
< 22)
5841 (void) makemon(mkclass(S_FELINE
,0), cx
, cy
, MM_ADJACENTOK
);
5842 else if (randmnst
< 24)
5843 (void) makemon(mkclass(S_GREMLIN
,0), cx
, cy
, MM_ADJACENTOK
);
5844 else if (randmnst
< 29)
5845 (void) makemon(mkclass(S_HUMANOID
,0), cx
, cy
, MM_ADJACENTOK
);
5846 else if (randmnst
< 33)
5847 (void) makemon(mkclass(S_IMP
,0), cx
, cy
, MM_ADJACENTOK
);
5848 else if (randmnst
< 36)
5849 (void) makemon(mkclass(S_JELLY
,0), cx
, cy
, MM_ADJACENTOK
);
5850 else if (randmnst
< 41)
5851 (void) makemon(mkclass(S_KOBOLD
,0), cx
, cy
, MM_ADJACENTOK
);
5852 else if (randmnst
< 44)
5853 (void) makemon(mkclass(S_LEPRECHAUN
,0), cx
, cy
, MM_ADJACENTOK
);
5854 else if (randmnst
< 47)
5855 (void) makemon(mkclass(S_MIMIC
,0), cx
, cy
, MM_ADJACENTOK
);
5856 else if (randmnst
< 50)
5857 (void) makemon(mkclass(S_NYMPH
,0), cx
, cy
, MM_ADJACENTOK
);
5858 else if (randmnst
< 54)
5859 (void) makemon(mkclass(S_ORC
,0), cx
, cy
, MM_ADJACENTOK
);
5860 else if (randmnst
< 55)
5861 (void) makemon(mkclass(S_PIERCER
,0), cx
, cy
, MM_ADJACENTOK
);
5862 else if (randmnst
< 58)
5863 (void) makemon(mkclass(S_QUADRUPED
,0), cx
, cy
, MM_ADJACENTOK
);
5864 else if (randmnst
< 62)
5865 (void) makemon(mkclass(S_RODENT
,0), cx
, cy
, MM_ADJACENTOK
);
5866 else if (randmnst
< 65)
5867 (void) makemon(mkclass(S_SPIDER
,0), cx
, cy
, MM_ADJACENTOK
);
5868 else if (randmnst
< 66)
5869 (void) makemon(mkclass(S_TRAPPER
,0), cx
, cy
, MM_ADJACENTOK
);
5870 else if (randmnst
< 69)
5871 (void) makemon(mkclass(S_UNICORN
,0), cx
, cy
, MM_ADJACENTOK
);
5872 else if (randmnst
< 71)
5873 (void) makemon(mkclass(S_VORTEX
,0), cx
, cy
, MM_ADJACENTOK
);
5874 else if (randmnst
< 73)
5875 (void) makemon(mkclass(S_WORM
,0), cx
, cy
, MM_ADJACENTOK
);
5876 else if (randmnst
< 75)
5877 (void) makemon(mkclass(S_XAN
,0), cx
, cy
, MM_ADJACENTOK
);
5878 else if (randmnst
< 76)
5879 (void) makemon(mkclass(S_LIGHT
,0), cx
, cy
, MM_ADJACENTOK
);
5880 else if (randmnst
< 77)
5881 (void) makemon(mkclass(S_ZOUTHERN
,0), cx
, cy
, MM_ADJACENTOK
);
5882 else if (randmnst
< 78)
5883 (void) makemon(mkclass(S_ANGEL
,0), cx
, cy
, MM_ADJACENTOK
);
5884 else if (randmnst
< 81)
5885 (void) makemon(mkclass(S_BAT
,0), cx
, cy
, MM_ADJACENTOK
);
5886 else if (randmnst
< 83)
5887 (void) makemon(mkclass(S_CENTAUR
,0), cx
, cy
, MM_ADJACENTOK
);
5888 else if (randmnst
< 86)
5889 (void) makemon(mkclass(S_DRAGON
,0), cx
, cy
, MM_ADJACENTOK
);
5890 else if (randmnst
< 89)
5891 (void) makemon(mkclass(S_ELEMENTAL
,0), cx
, cy
, MM_ADJACENTOK
);
5892 else if (randmnst
< 94)
5893 (void) makemon(mkclass(S_FUNGUS
,0), cx
, cy
, MM_ADJACENTOK
);
5894 else if (randmnst
< 99)
5895 (void) makemon(mkclass(S_GNOME
,0), cx
, cy
, MM_ADJACENTOK
);
5896 else if (randmnst
< 102)
5897 (void) makemon(mkclass(S_GIANT
,0), cx
, cy
, MM_ADJACENTOK
);
5898 else if (randmnst
< 103)
5899 (void) makemon(mkclass(S_JABBERWOCK
,0), cx
, cy
, MM_ADJACENTOK
);
5900 else if (randmnst
< 104)
5901 (void) makemon(mkclass(S_KOP
,0), cx
, cy
, MM_ADJACENTOK
);
5902 else if (randmnst
< 105)
5903 (void) makemon(mkclass(S_LICH
,0), cx
, cy
, MM_ADJACENTOK
);
5904 else if (randmnst
< 108)
5905 (void) makemon(mkclass(S_MUMMY
,0), cx
, cy
, MM_ADJACENTOK
);
5906 else if (randmnst
< 110)
5907 (void) makemon(mkclass(S_NAGA
,0), cx
, cy
, MM_ADJACENTOK
);
5908 else if (randmnst
< 113)
5909 (void) makemon(mkclass(S_OGRE
,0), cx
, cy
, MM_ADJACENTOK
);
5910 else if (randmnst
< 115)
5911 (void) makemon(mkclass(S_PUDDING
,0), cx
, cy
, MM_ADJACENTOK
);
5912 else if (randmnst
< 116)
5913 (void) makemon(mkclass(S_QUANTMECH
,0), cx
, cy
, MM_ADJACENTOK
);
5914 else if (randmnst
< 118)
5915 (void) makemon(mkclass(S_RUSTMONST
,0), cx
, cy
, MM_ADJACENTOK
);
5916 else if (randmnst
< 121)
5917 (void) makemon(mkclass(S_SNAKE
,0), cx
, cy
, MM_ADJACENTOK
);
5918 else if (randmnst
< 123)
5919 (void) makemon(mkclass(S_TROLL
,0), cx
, cy
, MM_ADJACENTOK
);
5920 else if (randmnst
< 124)
5921 (void) makemon(mkclass(S_UMBER
,0), cx
, cy
, MM_ADJACENTOK
);
5922 else if (randmnst
< 125)
5923 (void) makemon(mkclass(S_VAMPIRE
,0), cx
, cy
, MM_ADJACENTOK
);
5924 else if (randmnst
< 127)
5925 (void) makemon(mkclass(S_WRAITH
,0), cx
, cy
, MM_ADJACENTOK
);
5926 else if (randmnst
< 128)
5927 (void) makemon(mkclass(S_XORN
,0), cx
, cy
, MM_ADJACENTOK
);
5928 else if (randmnst
< 130)
5929 (void) makemon(mkclass(S_YETI
,0), cx
, cy
, MM_ADJACENTOK
);
5930 else if (randmnst
< 135)
5931 (void) makemon(mkclass(S_ZOMBIE
,0), cx
, cy
, MM_ADJACENTOK
);
5932 else if (randmnst
< 145)
5933 (void) makemon(mkclass(S_HUMAN
,0), cx
, cy
, MM_ADJACENTOK
);
5934 else if (randmnst
< 147)
5935 (void) makemon(mkclass(S_GHOST
,0), cx
, cy
, MM_ADJACENTOK
);
5936 else if (randmnst
< 149)
5937 (void) makemon(mkclass(S_GOLEM
,0), cx
, cy
, MM_ADJACENTOK
);
5938 else if (randmnst
< 152)
5939 (void) makemon(mkclass(S_DEMON
,0), cx
, cy
, MM_ADJACENTOK
);
5940 else if (randmnst
< 155)
5941 (void) makemon(mkclass(S_EEL
,0), cx
, cy
, MM_ADJACENTOK
);
5942 else if (randmnst
< 160)
5943 (void) makemon(mkclass(S_LIZARD
,0), cx
, cy
, MM_ADJACENTOK
);
5944 else if (randmnst
< 162)
5945 (void) makemon(mkclass(S_BAD_FOOD
,0), cx
, cy
, MM_ADJACENTOK
);
5946 else if (randmnst
< 165)
5947 (void) makemon(mkclass(S_BAD_COINS
,0), cx
, cy
, MM_ADJACENTOK
);
5948 else if (randmnst
< 166) {
5950 (void) makemon(mkclass(S_HUMAN
,0), cx
, cy
, MM_ADJACENTOK
);
5952 (void) makemon(mkclass(S_NEMESE
,0), cx
, cy
, MM_ADJACENTOK
);
5954 else if (randmnst
< 171)
5955 (void) makemon(mkclass(S_GRUE
,0), cx
, cy
, MM_ADJACENTOK
);
5956 else if (randmnst
< 176)
5957 (void) makemon(mkclass(S_WALLMONST
,0), cx
, cy
, MM_ADJACENTOK
);
5958 else if (randmnst
< 180)
5959 (void) makemon(mkclass(S_RUBMONST
,0), cx
, cy
, MM_ADJACENTOK
);
5960 else if (randmnst
< 181) {
5962 (void) makemon(mkclass(S_HUMAN
,0), cx
, cy
, MM_ADJACENTOK
);
5964 (void) makemon(mkclass(S_ARCHFIEND
,0), cx
, cy
, MM_ADJACENTOK
);
5966 else if (randmnst
< 186)
5967 (void) makemon(mkclass(S_TURRET
,0), cx
, cy
, MM_ADJACENTOK
);
5968 else if (randmnst
< 187)
5969 (void) makemon(mkclass(S_FLYFISH
,0), cx
, cy
, MM_ADJACENTOK
);
5971 (void) makemon((struct permonst
*)0, cx
, cy
, MM_ADJACENTOK
);
5979 randsp
= (rn2(14) + 2);
5980 if (!rn2(10)) randsp
*= 2;
5981 if (!rn2(100)) randsp
*= 3;
5982 if (!rn2(1000)) randsp
*= 5;
5983 if (!rn2(10000)) randsp
*= 10;
5984 randmonstforspawn
= rndmonst();
5986 You_feel("the arrival of monsters!");
5988 for (i
= 0; i
< randsp
; i
++) {
5990 if (!enexto(&cc
, u
.ux
, u
.uy
, (struct permonst
*)0) ) continue;
5992 (void) makemon(randmonstforspawn
, cx
, cy
, MM_ADJACENTOK
);
5999 randsp
= (rn2(14) + 2);
6000 if (!rn2(10)) randsp
*= 2;
6001 if (!rn2(100)) randsp
*= 3;
6002 if (!rn2(1000)) randsp
*= 5;
6003 if (!rn2(10000)) randsp
*= 10;
6004 monstercolor
= rnd(15);
6006 You_feel("a colorful sensation!");
6008 for (i
= 0; i
< randsp
; i
++) {
6010 if (!enexto(&cc
, u
.ux
, u
.uy
, (struct permonst
*)0) ) continue;
6012 (void) makemon(colormon(monstercolor
), cx
, cy
, MM_ADJACENTOK
);
6019 randsp
= (rn2(14) + 2);
6020 if (!rn2(10)) randsp
*= 2;
6021 if (!rn2(100)) randsp
*= 3;
6022 if (!rn2(1000)) randsp
*= 5;
6023 if (!rn2(10000)) randsp
*= 10;
6024 monstercolor
= rnd(434);
6026 You_feel("that a group has arrived!");
6028 for (i
= 0; i
< randsp
; i
++) {
6030 if (!enexto(&cc
, u
.ux
, u
.uy
, (struct permonst
*)0) ) continue;
6032 (void) makemon(specialtensmon(monstercolor
), cx
, cy
, MM_ADJACENTOK
);
6043 if (u
.uhunger
< 1500) {
6044 pline("Your %s fills.", body_part(STOMACH
));
6046 u
.uhs
= 1; /* NOT_HUNGRY */
6049 pline("Nothing happens...");
6050 if (FailureEffects
|| u
.uprops
[FAILURE_EFFECTS
].extrinsic
|| have_failurestone()) {
6051 pline("Oh wait, actually something bad happens...");
6057 if (u
.ualign
.record
< -1) {
6058 adjalign(-(u
.ualign
.record
/ 2));
6059 You_feel("partially absolved.");
6063 You_feel("appropriately %s.", align_str(u
.ualign
.type
));
6069 int nastytrapdur
= (Role_if(PM_GRADUATE
) ? 6 : Role_if(PM_GEEK
) ? 12 : 24);
6070 if (!nastytrapdur
) nastytrapdur
= 24; /* fail safe */
6071 int blackngdur
= (Role_if(PM_GRADUATE
) ? 2000 : Role_if(PM_GEEK
) ? 1000 : 500);
6072 if (!blackngdur
) blackngdur
= 500; /* fail safe */
6074 pline("Your mana increases.");
6076 /* nasty trap effect - no extra message because, well, nastiness! --Amy */
6077 randomnastytrapeffect(rnz(nastytrapdur
* (monster_difficulty() + 1)), (blackngdur
- (monster_difficulty() * 3)));
6084 adjattrib(i
, 1, 0, TRUE
);
6085 adjattrib(i
, 1, 0, TRUE
);
6086 adjattrib(i
, 1, 0, TRUE
);
6087 adjattrib(i
, 1, 0, TRUE
);
6088 adjattrib(i
, 1, 0, TRUE
);
6092 Your("intrinsics change.");
6093 intrinsicgainorloss(0);
6097 struct obj
*pseudogram
;
6098 pseudogram
= mksobj(SCR_ITEM_GENOCIDE
, FALSE
, 2, FALSE
);
6100 pline("Nothing happens...");
6101 if (FailureEffects
|| u
.uprops
[FAILURE_EFFECTS
].extrinsic
|| have_failurestone()) {
6102 pline("Oh wait, actually something bad happens...");
6107 if (pseudogram
->otyp
== GOLD_PIECE
) pseudogram
->otyp
= SCR_ITEM_GENOCIDE
;
6108 (void) seffects(pseudogram
);
6109 obfree(pseudogram
, (struct obj
*)0); /* now, get rid of it */
6115 doubleskilltraining();
6118 if (!(HAggravate_monster
& INTRINSIC
) && !(HAggravate_monster
& TIMEOUT
)) {
6120 int maxtrainingamount
= 0;
6121 int skillnumber
= 0;
6122 int actualskillselection
= 0;
6123 int amountofpossibleskills
= 1;
6126 for (i
= 0; i
< P_NUM_SKILLS
; i
++) {
6127 if (P_SKILL(i
) != P_ISRESTRICTED
) continue;
6129 if (P_ADVANCE(i
) > 0 && P_ADVANCE(i
) >= maxtrainingamount
) {
6130 if (P_ADVANCE(i
) > maxtrainingamount
) {
6131 amountofpossibleskills
= 1;
6133 maxtrainingamount
= P_ADVANCE(i
);
6134 } else if (!rn2(amountofpossibleskills
+ 1)) {
6135 amountofpossibleskills
++;
6138 amountofpossibleskills
++;
6143 if (skillnumber
> 0 && maxtrainingamount
> 0) {
6144 unrestrict_weapon_skill(skillnumber
);
6146 register int maxcap
= P_BASIC
;
6151 if (maxtrainingamount
>= 20 && !rn2(2)) {
6153 if (maxtrainingamount
>= 160 && !rn2(2)) {
6154 maxcap
= P_GRAND_MASTER
;
6155 if (maxtrainingamount
>= 540 && !rn2(2)) {
6156 maxcap
= P_SUPREME_MASTER
;
6163 P_MAX_SKILL(skillnumber
) = maxcap
;
6164 pline("You can now learn the %s skill, with a new cap of %s.", wpskillname(skillnumber
), maxcap
== P_SUPREME_MASTER
? "supreme master" : maxcap
== P_GRAND_MASTER
? "grand master" : maxcap
== P_MASTER
? "master" : maxcap
== P_EXPERT
? "expert" : maxcap
== P_SKILLED
? "skilled" : "basic");
6166 pline("Nothing happens...");
6167 if (FailureEffects
|| u
.uprops
[FAILURE_EFFECTS
].extrinsic
|| have_failurestone()) {
6168 pline("Oh wait, actually something bad happens...");
6175 if (HAggravate_monster
& INTRINSIC
) {
6176 HAggravate_monster
&= ~INTRINSIC
;
6177 You_feel("more acceptable!");
6179 if (HAggravate_monster
& TIMEOUT
) {
6180 HAggravate_monster
&= ~TIMEOUT
;
6181 You_feel("more acceptable!");
6187 reset_rndmonst(NON_PM
);
6189 register struct permonst
*ptrZ
;
6195 if (attempts
&& (attempts
% 10000 == 0)) u
.mondiffhack
++;
6196 if (!rn2(2000)) reset_rndmonst(NON_PM
);
6198 } while ( (!ptrZ
|| (ptrZ
&& !(ptrZ
->geno
& G_UNIQ
))) && attempts
< 50000);
6200 if (ptrZ
&& ptrZ
->geno
& G_UNIQ
) {
6201 if (wizard
) pline("monster generation: %s", ptrZ
->mname
);
6202 (void) makemon(ptrZ
, u
.ux
, u
.uy
, MM_ANGRY
);
6215 pline("Boss monsters appear from nowhere!");
6224 if (evilfriday
) evilragnarok(TRUE
,level_difficulty());
6229 u
.heavyaggravation
= 1;
6230 DifficultyIncreased
+= 1;
6231 HighlevelStatus
+= 1;
6232 EntireLevelMode
+= 1;
6234 (void) makemon(mkclass(S_NEMESE
,0), u
.ux
, u
.uy
, MM_ANGRY
|MM_FRENZIED
);
6237 u
.heavyaggravation
= 0;
6248 boolean canbeinawall
= FALSE
;
6249 if (!rn2(Passes_walls
? 5 : 25)) canbeinawall
= TRUE
;
6250 register struct trap
*ttmp
;
6251 for (tryct
= 0; tryct
< 2000; tryct
++) {
6255 if (isok(x
, y
) && ((levl
[x
][y
].typ
> DBWALL
) || canbeinawall
) && !(t_at(x
, y
)) ) {
6256 ttmp
= maketrap(x
, y
, rndtrap(), 0, TRUE
);
6259 ttmp
->hiddentrap
= 1;
6265 You_feel("in grave danger...");
6272 if (!uinsymbiosis
) {
6273 getrandomsymbiote(FALSE
, FALSE
);
6274 pline("Suddenly you have a symbiote!");
6276 u
.usymbiote
.mhpmax
+= rnd(10);
6277 maybe_evolve_symbiote();
6278 if (u
.usymbiote
.mhpmax
> 500) u
.usymbiote
.mhpmax
= 500;
6280 Your("symbiote seems much stronger now.");
6285 You_feel("decontaminated.");
6288 pline("Wow! This makes you feel good!");
6292 for (ii
= 0; ii
< A_MAX
; ii
++) {
6294 if (i
== A_STR
&& u
.uhs
>= 3) --lim
; /* WEAK */
6295 if (ABASE(i
) < lim
) {
6300 if(++i
>= A_MAX
) i
= 0;
6306 boostknownskillcap();
6309 impossible("undefined pentagram effect");
6315 if (!rn2(7)) badeffect();
6319 case SPE_THRONE_GAMBLE
:
6324 (void) adjattrib(rn2(A_MAX
), -rno(5), FALSE
, TRUE
);
6325 losehp(rnd(10), "cursed throne", KILLED_BY_AN
);
6328 (void) adjattrib(rn2(A_MAX
), 1, FALSE
, TRUE
);
6331 pline("A%s electric shock shoots through your body!",
6332 (Shock_resistance
) ? "n" : " massive");
6333 if (!ShockImmunity
) losehp(StrongShock_resistance
? rnd(2) : Shock_resistance
? rnd(6) : rnd(30),
6334 "electric chair", KILLED_BY_AN
);
6335 exercise(A_CON
, FALSE
);
6338 You_feel("much, much better!");
6340 if (u
.mh
>= (u
.mhmax
- 5)) u
.mhmax
+= 4;
6343 if(u
.uhp
>= (u
.uhpmax
- 5)) u
.uhpmax
+= 4;
6346 u
.usymbiote
.mhpmax
+= 4;
6347 maybe_evolve_symbiote();
6348 if (u
.usymbiote
.mhpmax
> 500) u
.usymbiote
.mhpmax
= 500;
6350 make_blinded(0L,TRUE
);
6351 make_sick(0L, (char *) 0, FALSE
, SICK_ALL
);
6360 /* no wishes --Amy */
6361 You_feel("your luck is changing.");
6367 register int cnt
= rnd(10);
6369 if (Aggravate_monster
) {
6371 reset_rndmonst(NON_PM
);
6374 pline("A voice echoes:");
6375 verbalize("Thy audience hath been summoned, %s!",
6376 flags
.female
? "Dame" : "Sire");
6378 (void) makemon(courtmon(), u
.ux
, u
.uy
, NO_MM_FLAGS
);
6385 pline("A voice echoes:");
6386 verbalize("By thy Imperious order, %s...",
6387 flags
.female
? "Dame" : "Sire");
6388 do_genocide(5); /* REALLY|ONTHRONE, see do_genocide() */
6391 pline("A voice echoes:");
6392 verbalize("A curse upon thee for sitting upon this most holy throne!");
6394 make_blinded(Blinded
+ rn1(100,250),TRUE
);
6398 if (Luck
< 0 || (HSee_invisible
& INTRINSIC
)) {
6399 if (level
.flags
.nommap
) {
6401 "A terrible drone fills your head!");
6402 make_confused(HConfusion
+ rnd(30),
6405 pline("An image forms in your mind.");
6409 Your("vision becomes clear.");
6410 HSee_invisible
|= FROMOUTSIDE
;
6416 You_feel("threatened.");
6420 You_feel("a wrenching sensation.");
6421 if (PlayerHearsSoundEffects
) pline(issoviet
? "Tam net nikakoy zashchity. Tam net nikakoy nadezhdy. Yedinstvennoye, chto yest'? Uverennost' v tom, chto vy, igrok, budet umeret' uzhasnoy i muchitel'noy smert'yu." : "SCHRING!");
6422 tele(); /* teleport him */
6426 You("are granted an insight!");
6428 /* rn2(5) agrees w/seffects() */
6429 identify_pack(rn2(5), 0, 0);
6433 Your("mind turns into a pretzel!");
6434 make_confused(HConfusion
+ rn1(7,16),FALSE
);
6437 You("are granted some new skills!"); /* new effect that unrestricts skills --Amy */
6438 unrestrictskillchoice();
6442 pline("A voice echoes:");
6443 verbalize("Thou be cursed!");
6447 pline("A voice echoes:");
6448 verbalize("Thou shall be punished!");
6452 You_feel("like someone has touched your forehead...");
6454 int skillimprove
= randomgoodskill();
6456 if (P_MAX_SKILL(skillimprove
) == P_ISRESTRICTED
) {
6457 unrestrict_weapon_skill(skillimprove
);
6458 pline("You can now learn the %s skill.", wpskillname(skillimprove
));
6459 } else if (P_MAX_SKILL(skillimprove
) == P_UNSKILLED
) {
6460 unrestrict_weapon_skill(skillimprove
);
6461 P_MAX_SKILL(skillimprove
) = P_BASIC
;
6462 pline("You can now learn the %s skill.", wpskillname(skillimprove
));
6463 } else if (rn2(2) && P_MAX_SKILL(skillimprove
) == P_BASIC
) {
6464 P_MAX_SKILL(skillimprove
) = P_SKILLED
;
6465 pline("Your knowledge of the %s skill increases.", wpskillname(skillimprove
));
6466 } else if (!rn2(4) && P_MAX_SKILL(skillimprove
) == P_SKILLED
) {
6467 P_MAX_SKILL(skillimprove
) = P_EXPERT
;
6468 pline("Your knowledge of the %s skill increases.", wpskillname(skillimprove
));
6469 } else if (!rn2(10) && P_MAX_SKILL(skillimprove
) == P_EXPERT
) {
6470 P_MAX_SKILL(skillimprove
) = P_MASTER
;
6471 pline("Your knowledge of the %s skill increases.", wpskillname(skillimprove
));
6472 } else if (!rn2(100) && P_MAX_SKILL(skillimprove
) == P_MASTER
) {
6473 P_MAX_SKILL(skillimprove
) = P_GRAND_MASTER
;
6474 pline("Your knowledge of the %s skill increases.", wpskillname(skillimprove
));
6475 } else if (!rn2(200) && P_MAX_SKILL(skillimprove
) == P_GRAND_MASTER
) {
6476 P_MAX_SKILL(skillimprove
) = P_SUPREME_MASTER
;
6477 pline("Your knowledge of the %s skill increases.", wpskillname(skillimprove
));
6478 } else gainlevelmaybe();
6480 if (Race_if(PM_RUSMOT
)) {
6481 if (P_MAX_SKILL(skillimprove
) == P_ISRESTRICTED
) {
6482 unrestrict_weapon_skill(skillimprove
);
6483 pline("You can now learn the %s skill.", wpskillname(skillimprove
));
6484 } else if (P_MAX_SKILL(skillimprove
) == P_UNSKILLED
) {
6485 unrestrict_weapon_skill(skillimprove
);
6486 P_MAX_SKILL(skillimprove
) = P_BASIC
;
6487 pline("You can now learn the %s skill.", wpskillname(skillimprove
));
6488 } else if (rn2(2) && P_MAX_SKILL(skillimprove
) == P_BASIC
) {
6489 P_MAX_SKILL(skillimprove
) = P_SKILLED
;
6490 pline("Your knowledge of the %s skill increases.", wpskillname(skillimprove
));
6491 } else if (!rn2(4) && P_MAX_SKILL(skillimprove
) == P_SKILLED
) {
6492 P_MAX_SKILL(skillimprove
) = P_EXPERT
;
6493 pline("Your knowledge of the %s skill increases.", wpskillname(skillimprove
));
6494 } else if (!rn2(10) && P_MAX_SKILL(skillimprove
) == P_EXPERT
) {
6495 P_MAX_SKILL(skillimprove
) = P_MASTER
;
6496 pline("Your knowledge of the %s skill increases.", wpskillname(skillimprove
));
6497 } else if (!rn2(100) && P_MAX_SKILL(skillimprove
) == P_MASTER
) {
6498 P_MAX_SKILL(skillimprove
) = P_GRAND_MASTER
;
6499 pline("Your knowledge of the %s skill increases.", wpskillname(skillimprove
));
6500 } else if (!rn2(200) && P_MAX_SKILL(skillimprove
) == P_GRAND_MASTER
) {
6501 P_MAX_SKILL(skillimprove
) = P_SUPREME_MASTER
;
6502 pline("Your knowledge of the %s skill increases.", wpskillname(skillimprove
));
6510 {register int cnt
= rnd(10);
6511 struct permonst
*randmonstforspawn
= rndmonst();
6513 if (Aggravate_monster
) {
6515 reset_rndmonst(NON_PM
);
6519 (void) makemon(randmonstforspawn
, u
.ux
, u
.uy
, NO_MM_FLAGS
);
6523 pline("A voice echoes:");
6524 verbalize("Leave me alone, stupid %s", randmonstforspawn
->mname
);
6528 {register int cnt
= rnd(10);
6529 int randmonstforspawn
= rnd(68);
6530 if (randmonstforspawn
== 35) randmonstforspawn
= 53;
6532 if (Aggravate_monster
) {
6534 reset_rndmonst(NON_PM
);
6538 (void) makemon(mkclass(randmonstforspawn
,0), u
.ux
, u
.uy
, NO_MM_FLAGS
);
6542 pline("A voice echoes:");
6543 verbalize("Oh, please help me! A horrible %s stole my sword! I'm nothing without it.", monexplain
[randmonstforspawn
]);
6548 if (CannotSelectItemsInPrompts
) break;
6549 pline("You may fully identify an object!");
6550 register struct obj
*idobj
;
6553 idobj
= getobj(allnoncount
, "secure identify");
6556 if (yn("Really exit with no object selected?") == 'y')
6557 pline("You just wasted the opportunity to secure identify your objects.");
6558 else goto secureidchoice
;
6559 pline("A feeling of loss comes over you.");
6563 makeknown(idobj
->otyp
);
6564 if (idobj
->oartifact
) discover_artifact((int)idobj
->oartifact
);
6565 idobj
->known
= idobj
->dknown
= idobj
->bknown
= idobj
->rknown
= 1;
6566 if (idobj
->otyp
== EGG
&& idobj
->corpsenm
!= NON_PM
)
6567 learn_egg_type(idobj
->corpsenm
);
6568 prinv((char *)0, idobj
, 0L);
6574 int nastytrapdur
= (Role_if(PM_GRADUATE
) ? 6 : Role_if(PM_GEEK
) ? 12 : 24);
6575 if (!nastytrapdur
) nastytrapdur
= 24; /* fail safe */
6576 int blackngdur
= (Role_if(PM_GRADUATE
) ? 2000 : Role_if(PM_GEEK
) ? 1000 : 500);
6577 if (!blackngdur
) blackngdur
= 500; /* fail safe */
6578 randomnastytrapeffect(rnz(nastytrapdur
* (monster_difficulty() + 1)), (blackngdur
- (monster_difficulty() * 3)));
6579 You_feel("uncomfortable.");
6584 pline("Whoops... suddenly you feel hungry.");
6587 pline("Suddenly you feel a healing touch!");
6591 poisoned("throne", rn2(6) /* A_STR ... A_CHA*/, "poisoned throne", 30);
6595 int thronegold
= rnd(200);
6596 u
.ugold
+= thronegold
;
6597 pline("Some coins come loose! You pick up %d zorkmids.", thronegold
);
6603 if (Aggravate_monster
) {
6605 reset_rndmonst(NON_PM
);
6608 pline("A voice echoes:");
6609 verbalize("Thou hath been summoned to appear before royalty, %s!", playeraliasname
);
6610 (void) makemon(specialtensmon(rn2(2) ? 105 : 106), u
.ux
, u
.uy
, MM_ANGRY
); /* M2_LORD, M2_PRINCE */
6622 if (u
.uhp
> u
.uhpmax
) u
.uhp
= u
.uhpmax
;
6623 You_feel("a health boost!");
6626 pline("A pretty ethereal woman appears and offers: 'For only 10000 zorkmids, I will give you a very rare trinket!");
6627 if (u
.ugold
< 10000) {
6628 pline("But you don't have enough money! Frustrated, she places a terrible curse on you and disappears.");
6629 randomfeminismtrap(rnz( (level_difficulty() + 2) * rnd(50)));
6632 char femhandlebuf
[BUFSZ
];
6633 getlin ("Do you want to buy her goods? [y/yes/no]",femhandlebuf
);
6634 (void) lcase (femhandlebuf
);
6635 if (!(strcmp (femhandlebuf
, "yes")) || !(strcmp (femhandlebuf
, "y")) || !(strcmp (femhandlebuf
, "ye")) || !(strcmp (femhandlebuf
, "ys"))) {
6637 register struct obj
*acqo
;
6638 acqo
= mksobj(makegreatitem(), TRUE
, TRUE
, FALSE
);
6641 verbalize("Thanks a lot! You'll find your prize on the ground.");
6643 verbalize("Oh sorry, I must have misplaced it. Here you have your money back. Maybe next time I'll have something for you.");
6647 verbalize("You will regret that decision!");
6648 randomfeminismtrap(rnz( (level_difficulty() + 2) * rnd(50)));
6654 pline("A shady merchant appears and offers: 'Sale! Sale! I'm selling you this useful item for 2000 zorkmids!");
6655 if (u
.ugold
< 2000) {
6656 pline("But you don't have enough money! The merchant disappears.");
6659 char femhandlebuf
[BUFSZ
];
6660 getlin ("Do you want to buy his item? [y/yes/no]",femhandlebuf
);
6661 (void) lcase (femhandlebuf
);
6662 if (!(strcmp (femhandlebuf
, "yes")) || !(strcmp (femhandlebuf
, "y")) || !(strcmp (femhandlebuf
, "ye")) || !(strcmp (femhandlebuf
, "ys"))) {
6664 register struct obj
*acqo
;
6665 acqo
= mksobj(usefulitem(), TRUE
, TRUE
, FALSE
);
6668 verbalize("Thank you! I've dropped the item at your feet.");
6670 verbalize("Nyah-nyah, thanks for the money, sucker!");
6673 verbalize("Are you sure? Well, it's your decision. I'll find someone else to sell it to, then.");
6679 struct obj
*stupidstone
;
6680 stupidstone
= mksobj_at(rnd_class(RIGHT_MOUSE_BUTTON_STONE
,NASTY_STONE
), u
.ux
, u
.uy
, TRUE
, FALSE
, FALSE
);
6682 stupidstone
->quan
= 1L;
6683 stupidstone
->owt
= weight(stupidstone
);
6684 if (!Blind
) stupidstone
->dknown
= 1;
6686 pline("%s lands in your knapsack!", Doname2(stupidstone
));
6687 (void) pickup_object(stupidstone
, 1L, TRUE
, TRUE
);
6693 (void) mksobj_at(rnd_class(DILITHIUM_CRYSTAL
, ROCK
), u
.ux
, u
.uy
, TRUE
, TRUE
, FALSE
);
6694 pline("Some stones come loose!");
6697 default: impossible("throne effect");
6701 if (is_prince(youmonst
.data
))
6702 You_feel("very comfortable here.");
6704 You_feel("somehow out of place...");
6707 if (!rn2(7)) badeffect();
6711 case SPE_COMBAT_COMMAND
:
6713 verbalize(!rn2(3) ? "Bohhh!" : rn2(2) ? "Wouuh!" : "Bohhohh!");
6714 if (u
.combatcommand
) u
.combatcommand
+= rnd(10);
6715 else u
.combatcommand
= (rn1(50, 50) + spell_damage_bonus(spellid(spell
)) * 5 );
6721 if(!(HDefusing
& INTRINSIC
)) {
6722 You("can disarm traps more effectively!");
6723 incr_itimeout(&HDefusing
, HDefusing
? (rnd(10) + spell_damage_bonus(spellid(spell
))) : (rn1(100, 50) + spell_damage_bonus(spellid(spell
))*10));
6725 pline("%s", nothing_happens
); /* Already have as intrinsic */
6726 if (FailureEffects
|| u
.uprops
[FAILURE_EFFECTS
].extrinsic
|| have_failurestone()) {
6727 pline("Oh wait, actually something bad happens...");
6734 case SPE_REDEMPTION
:
6737 register struct obj
*redeemobj
;
6738 for (redeemobj
= fobj
; redeemobj
; redeemobj
= redeemobj
->nobj
) {
6739 if (redeemobj
->otyp
== CORPSE
) {
6740 if (redeemobj
->timed
) {
6741 (void) stop_timer(MOLDY_CORPSE
, (void *)redeemobj
);
6742 (void) stop_timer(REVIVE_MON
, (void *)redeemobj
);
6744 if (!(redeemobj
->timed
)) {
6745 (void) start_timer(250, TIMER_OBJECT
, ROT_CORPSE
, (void *)redeemobj
);
6746 pline("A corpse has been redeemed!");
6755 case SPE_MAGIC_SHIELD
:
6757 u
.magicshield
+= (u
.magicshield
? rnd(10) : 40 + (spell_damage_bonus(spellid(spell
)) * 10) );
6758 pline("You activate your magic shield!");
6764 if (u
.berserktime
) {
6765 pline("Bad idea - you are already berserk! Things turn into an unrecognizable blur.");
6766 make_hallucinated(HHallucination
+ rnd(50) + HStun
+ HConfusion
, FALSE
, 0L);
6767 set_itimeout(&HeavyHallu
, HHallucination
);
6771 u
.berserktime
= 7 + spell_damage_bonus(spellid(spell
));
6772 pline("Raaaaaargh! You fly into a berserk rage!");
6776 case SPE_RAIN_CLOUD
:
6779 struct monst
*rainedmon
;
6780 for (i
= -1; i
<= 1; i
++) for(j
= -1; j
<= 1; j
++) {
6781 if (!isok(u
.ux
+ i
, u
.uy
+ j
)) continue;
6782 if (levl
[u
.ux
+ i
][u
.uy
+ j
].typ
== LAVAPOOL
) {
6783 levl
[u
.ux
+ i
][u
.uy
+ j
].typ
= WATER
;
6784 pline("The lava turns into water!");
6786 if ( (rainedmon
= m_at(u
.ux
+ i
, u
.uy
+ j
)) != 0) {
6787 if (dmgtype(rainedmon
->data
, AD_FIRE
) || dmgtype(rainedmon
->data
, AD_BURN
) || dmgtype(rainedmon
->data
, AD_LAVA
)) {
6789 rainedmon
->mhp
-= rnd(20 + (spell_damage_bonus(spellid(spell
)) * 3) );
6790 pline("%s is damaged by the raindrops!", Monnam(rainedmon
));
6791 if (rainedmon
->mhp
<= 0) {
6792 pline("%s is killed!", Monnam(rainedmon
));
6793 xkilled(rainedmon
, 0);
6801 if (!inertiaprotection()) {
6802 u
.uprops
[DEAC_FAST
].intrinsic
+= (( rnd(10) + rnd(monster_difficulty() + 1) ) * 3);
6803 pline(u
.inertia
? "You slow down even more due to the rain." : "You slow down greatly due to the rain.");
6804 u
.inertia
+= (rnd(10) + rnd(monster_difficulty() + 1));
6807 if (!(InterfaceScrewed
|| u
.uprops
[INTERFACE_SCREW
].extrinsic
|| have_interfacescrewstone())) (void)doredraw();
6811 case SPE_DRY_UP_FOUNTAIN
:
6814 for (i
= -1; i
<= 1; i
++) for(j
= -1; j
<= 1; j
++) {
6815 if (!isok(u
.ux
+ i
, u
.uy
+ j
)) continue;
6816 if (levl
[u
.ux
+ i
][u
.uy
+ j
].typ
== FOUNTAIN
) {
6817 levl
[u
.ux
+ i
][u
.uy
+ j
].typ
= CORR
;
6818 levl
[u
.ux
+ i
][u
.uy
+ j
].looted
= 0;
6819 levl
[u
.ux
+ i
][u
.uy
+ j
].blessedftn
= 0;
6820 pline("The fountain dries up!");
6821 level
.flags
.nfountains
--;
6826 if (!(InterfaceScrewed
|| u
.uprops
[INTERFACE_SCREW
].extrinsic
|| have_interfacescrewstone())) (void)doredraw();
6830 case SPE_TAKE_SELFIE
:
6832 pline("You take a selfie.");
6833 nomul(-(2 + rn2(4)), "taking a selfie", TRUE
);
6836 make_blinded(Blinded
+ rnd(50), FALSE
);
6837 pline("You are blinded by the flash!");
6845 struct monst
*rainedmon
;
6847 if (Is_waterlevel(&u
.uz
)) {
6848 pline("The water foams violently for a moment.");
6852 for (i
= -1; i
<= 1; i
++) for(j
= -1; j
<= 1; j
++) {
6853 if (!isok(u
.ux
+ i
, u
.uy
+ j
)) continue;
6854 if (levl
[u
.ux
+ i
][u
.uy
+ j
].typ
== WATER
|| levl
[u
.ux
+ i
][u
.uy
+ j
].typ
== POOL
|| levl
[u
.ux
+ i
][u
.uy
+ j
].typ
== MOAT
) {
6855 levl
[u
.ux
+ i
][u
.uy
+ j
].typ
= ROOM
;
6856 pline("The water evaporizes!");
6857 if ( (rainedmon
= m_at(u
.ux
+ i
, u
.uy
+ j
)) != 0) {
6858 rainedmon
->mhp
/= 2;
6859 if (rainedmon
->mpeaceful
&& !(rainedmon
->mtame
)) {
6860 rainedmon
->mpeaceful
= 0;
6861 pline("%s gets angry.", Monnam(rainedmon
));
6863 pline("%s is damaged by the vapors!", Monnam(rainedmon
));
6865 rainedmon
->mcanmove
= 0;
6866 rainedmon
->mfrozen
= rnd(20);
6867 rainedmon
->mstrategy
&= ~STRAT_WAITFORU
;
6868 pline("%s is paralyzed!", Monnam(rainedmon
));
6870 if (rainedmon
->mhp
<= 0) {
6871 pline("%s is killed!", Monnam(rainedmon
));
6872 xkilled(rainedmon
, 0);
6879 pline("The vapors burn you!");
6880 make_burned(HBurned
+ rnd(200), FALSE
);
6881 set_itimeout(&HeavyBurned
, HBurned
);
6883 if (!(InterfaceScrewed
|| u
.uprops
[INTERFACE_SCREW
].extrinsic
|| have_interfacescrewstone())) (void)doredraw();
6887 case SPE_NEXUS_FIELD
:
6889 register struct monst
*nexusmon
, *nextmon
;
6891 for(nexusmon
= fmon
; nexusmon
; nexusmon
= nextmon
) {
6892 nextmon
= nexusmon
->nmon
; /* trap might kill mon */
6893 if (DEADMONSTER(nexusmon
)) continue;
6894 if (nexusmon
== u
.usteed
) continue;
6895 if (resist(nexusmon
, SPBOOK_CLASS
, 0, NOTELL
)) continue;
6897 if (!monnear(nexusmon
, u
.ux
, u
.uy
)) continue;
6898 if (nexusmon
->mtrapped
) {
6899 /* no longer in previous trap (affects mintrap) */
6900 nexusmon
->mtrapped
= 0;
6901 fill_pit(nexusmon
->mx
, nexusmon
->my
);
6903 pline("%s is beamed away!", Monnam(nexusmon
));
6904 wakeup(nexusmon
); /* monster becomes hostile */
6905 rloc(nexusmon
, FALSE
);
6910 register int statloss
= rn2(A_MAX
);
6912 ABASE(statloss
) -= rnd(2);
6913 if (ABASE(statloss
) < ATTRABSMIN(statloss
)) ABASE(statloss
) = ATTRABSMIN(statloss
);
6914 AMAX(statloss
) = ABASE(statloss
);
6915 pline("You are hit by nexus forces!");
6916 poisontell(statloss
);
6922 case SPE_TUNNELIZATION
:
6924 register struct monst
*nexusmon
, *nextmon
;
6926 for(nexusmon
= fmon
; nexusmon
; nexusmon
= nextmon
) {
6927 nextmon
= nexusmon
->nmon
; /* trap might kill mon */
6928 if (DEADMONSTER(nexusmon
)) continue;
6929 if (levl
[nexusmon
->mx
][nexusmon
->my
].typ
>= STONE
&& levl
[nexusmon
->mx
][nexusmon
->my
].typ
<= ROCKWALL
) {
6930 if ((levl
[nexusmon
->mx
][nexusmon
->my
].wall_info
& W_NONDIGGABLE
) == 0 && !(*in_rooms(nexusmon
->mx
,nexusmon
->my
,SHOPBASE
))) {
6931 levl
[nexusmon
->mx
][nexusmon
->my
].typ
= CORR
;
6932 blockorunblock_point(nexusmon
->mx
,nexusmon
->my
);
6933 if (!(levl
[nexusmon
->mx
][nexusmon
->my
].wall_info
& W_HARDGROWTH
)) levl
[nexusmon
->mx
][nexusmon
->my
].wall_info
|= W_EASYGROWTH
;
6934 newsym(nexusmon
->mx
,nexusmon
->my
);
6937 pline("%s wails out in pain!", Monnam(nexusmon
));
6938 nexusmon
->mhp
-= rnz(nexusmon
->mhp
/ 2);
6939 if (nexusmon
->mhp
<= 0) {
6940 xkilled(nexusmon
, 0);
6941 pline("%s is killed!", Monnam(nexusmon
));
6942 } else wakeup(nexusmon
); /* monster becomes hostile */
6948 pline("You feel bad for tunneling, and are also blinded by heaps of earth flying around.");
6950 if (rn2(5)) u
.tunnelized
+= rnd(20);
6951 else u
.tunnelized
+= rnd(100);
6952 make_blinded(Blinded
+ u
.tunnelized
, FALSE
);
6953 set_itimeout(&HeavyBlind
, Blinded
);
6954 if (!(InterfaceScrewed
|| u
.uprops
[INTERFACE_SCREW
].extrinsic
|| have_interfacescrewstone())) (void)doredraw();
6958 case SPE_APPLY_NAIL_POLISH
:
6960 if (u
.nailpolish
>= 10) {
6961 pline("All of your nails are polished already! Nothing happens.");
6964 pline("You begin applying nail polish.");
6966 nomul(-(rnd(4)), "applying nail polish", TRUE
);
6967 nomovemsg
= "You finish polishing your nails.";
6974 pline("You are not holding a weapon!");
6978 /* enchanting again while it's already active sets a new timeout and does not add to the old one --Amy */
6979 u
.enchantspell
= (5 + spell_damage_bonus(spellid(spell
)));
6980 pline("You enchant your weapon.");
6986 register struct monst
*frostmon
, *nxtmon
;
6988 for(frostmon
= fmon
; frostmon
; frostmon
= nxtmon
) {
6989 nxtmon
= frostmon
->nmon
; /* trap might kill mon */
6990 if (DEADMONSTER(frostmon
)) continue;
6991 if (resist(frostmon
, SPBOOK_CLASS
, 0, NOTELL
)) continue;
6993 if (!monnear(frostmon
, u
.ux
, u
.uy
)) continue;
6994 mon_adjust_speed(frostmon
, -1, (struct obj
*)0);
6995 m_dowear(frostmon
, FALSE
); /* might want speed boots */
7002 case SPE_THUNDER_WAVE
:
7004 register struct monst
*frostmon
, *nxtmon
;
7006 for(frostmon
= fmon
; frostmon
; frostmon
= nxtmon
) {
7007 nxtmon
= frostmon
->nmon
; /* trap might kill mon */
7008 if (DEADMONSTER(frostmon
)) continue;
7009 if (!monnear(frostmon
, u
.ux
, u
.uy
)) continue;
7011 if (frostmon
->mpeaceful
&& !frostmon
->mtame
) {
7012 pline("%s gets angry.", Monnam(frostmon
) );
7013 frostmon
->mpeaceful
= 0; /* monster becomes hostile */
7016 if (!resists_elec(frostmon
) && !(dmgtype(frostmon
->data
, AD_PLYS
)) && !resist(frostmon
, SPBOOK_CLASS
, 0, NOTELL
) && !rn2(10)) {
7018 if (canseemon(frostmon
) ) {
7019 pline("%s is paralyzed! It might be unable to move!", Monnam(frostmon
) );
7021 frostmon
->mcanmove
= 0;
7022 frostmon
->mfrozen
= rnd(5);
7023 frostmon
->mstrategy
&= ~STRAT_WAITFORU
;
7027 if (!resists_elec(frostmon
)) {
7029 frostmon
->mhp
-= rnd(10 + (spell_damage_bonus(spellid(spell
)) * 2) );
7030 pline("%s is shocked!", Monnam(frostmon
));
7031 if (frostmon
->mhp
<= 0) {
7032 pline("%s is killed!", Monnam(frostmon
));
7033 xkilled(frostmon
, 0);
7043 case SPE_POWER_FAILURE
:
7049 for(i
= -bd
; i
<= bd
; i
++) for(j
= -bd
; j
<= bd
; j
++) {
7050 if (!isok(u
.ux
+ i
, u
.uy
+ j
)) continue;
7051 if ((mtmp
= m_at(u
.ux
+ i
, u
.uy
+ j
)) != 0) {
7052 if (dmgtype(mtmp
->data
, AD_ELEC
) || dmgtype(mtmp
->data
, AD_MALK
)) {
7054 mtmp
->mhp
-= rnd(40 + (spell_damage_bonus(spellid(spell
)) * 10) );
7055 pline("%s's power is down!", Monnam(mtmp
));
7056 if (rn2(3) && !mtmp
->mstun
) {
7058 pline("%s is numbed!", Monnam(mtmp
));
7060 if (rn2(3) && !mtmp
->mblinded
) {
7061 mtmp
->mblinded
= rnd(10);
7062 pline("%s is blinded!", Monnam(mtmp
));
7064 if (mtmp
->mhp
<= 0) {
7065 pline("%s is killed!", Monnam(mtmp
));
7073 for (i
= -2; i
<= 2; i
++) for(j
= -2; j
<= 2; j
++) {
7074 if (!isok(u
.ux
+ i
, u
.uy
+ j
)) continue;
7075 if (levl
[u
.ux
+ i
][u
.uy
+ j
].typ
== IRONBARS
&& !rn2(1000) ) {
7076 levl
[u
.ux
+ i
][u
.uy
+ j
].typ
= CLOUD
;
7077 pline("The iron bars break apart and leave behind a cloud!");
7083 u
.powerfailure
+= rnd(100);
7084 if (!(InterfaceScrewed
|| u
.uprops
[INTERFACE_SCREW
].extrinsic
|| have_interfacescrewstone())) (void)doredraw();
7088 case SPE_ANGER_PEACEFUL_MONSTER
:
7090 register struct monst
*frostmon
, *nxtmon
;
7092 for(frostmon
= fmon
; frostmon
; frostmon
= nxtmon
) {
7093 nxtmon
= frostmon
->nmon
; /* trap might kill mon */
7094 if (DEADMONSTER(frostmon
)) continue;
7095 if (!monnear(frostmon
, u
.ux
, u
.uy
)) continue;
7103 case SPE_CURE_MONSTER
:
7105 register struct monst
*frostmon
, *nxtmon
;
7107 for(frostmon
= fmon
; frostmon
; frostmon
= nxtmon
) {
7108 nxtmon
= frostmon
->nmon
; /* trap might kill mon */
7109 if (DEADMONSTER(frostmon
)) continue;
7110 if (!monnear(frostmon
, u
.ux
, u
.uy
)) continue;
7111 if (rn2(2)) continue;
7112 frostmon
->mfrozen
= 0;
7113 frostmon
->msleeping
= 0;
7114 frostmon
->masleep
= 0;
7115 frostmon
->mcanmove
= 1;
7116 frostmon
->mflee
= 0;
7117 frostmon
->mcansee
= 1;
7118 frostmon
->mblinded
= 0;
7119 frostmon
->mstun
= 0;
7120 frostmon
->mconf
= 0;
7121 pline("%s is cured.", Monnam(frostmon
));
7124 if (u
.usteed
&& rn2(2)) {
7125 u
.usteed
->mfrozen
= 0;
7126 u
.usteed
->msleeping
= 0;
7127 u
.usteed
->masleep
= 0;
7128 u
.usteed
->mcanmove
= 1;
7129 u
.usteed
->mflee
= 0;
7130 u
.usteed
->mcansee
= 1;
7131 u
.usteed
->mblinded
= 0;
7132 u
.usteed
->mstun
= 0;
7133 u
.usteed
->mconf
= 0;
7134 pline("%s is cured.", Monnam(u
.usteed
));
7143 pline("You throw up a thorny skin!");
7144 u
.thornspell
= 10 + (spell_damage_bonus(spellid(spell
)) * 2);
7145 /* casting it repeatedly will not give you a longer duration --Amy */
7149 case SPE_MANA_BATTERY
:
7152 register struct obj
*mbobj
, *mbobj2
;
7153 for (mbobj
= invent
; mbobj
; mbobj
= mbobj2
) {
7154 mbobj2
= mbobj
->nobj
;
7156 if (mbobj
->oclass
== WAND_CLASS
) {
7157 if (mbobj
->spe
> 1) u
.uen
+= (mbobj
->spe
* 10);
7158 if (u
.uen
> u
.uenmax
) u
.uen
= u
.uenmax
;
7164 pline("Your wands are consumed to restore your mana.");
7168 case SPE_UNTAME_MONSTER
:
7170 register struct monst
*frostmon
, *nxtmon
;
7172 for(frostmon
= fmon
; frostmon
; frostmon
= nxtmon
) {
7173 nxtmon
= frostmon
->nmon
; /* trap might kill mon */
7174 if (DEADMONSTER(frostmon
)) continue;
7175 if (!monnear(frostmon
, u
.ux
, u
.uy
)) continue;
7177 if (frostmon
->mtame
) frostmon
->mtame
= 0;
7183 case SPE_CODE_EDITING
:
7186 register struct obj
*codeobj
, *nextobj
;
7187 for (codeobj
= fobj
; codeobj
; codeobj
= nextobj
) {
7188 nextobj
= codeobj
->nobj
;
7189 if (codeobj
->otyp
!= CORPSE
) continue;
7190 if (codeobj
->where
!= OBJ_FLOOR
) continue;
7191 if (obj_resists(codeobj
, 0, 50)) continue; /* no easy removal of rider corpses! --Amy */
7192 explode(codeobj
->ox
, codeobj
->oy
, ZT_SPELL(ZT_FIRE
), mons
[codeobj
->corpsenm
].mlevel
* rnz(5), SCROLL_CLASS
, EXPL_FIERY
);
7194 if (codeobj
) delobj(codeobj
);
7200 case SPE_ELEMENTAL_MINION
:
7203 pline("You sacrifice some of your %s to create an elemental being.", body_part(BLOOD
));
7205 if (u
.uhp
> u
.uhpmax
) u
.uhp
= u
.uhpmax
;
7208 killer
= "summoning an elemental with too little health";
7209 killer_format
= KILLED_BY
;
7215 if (u
.mh
> u
.mhmax
) u
.mh
= u
.mhmax
;
7218 /* make good shit, after all you pay with max health for this spell */
7220 if (!rn2(3)) u
.heavyaggravation
= 1;
7221 if (!rn2(20)) DifficultyIncreased
+= 1;
7222 if (!rn2(20)) HighlevelStatus
+= 1;
7224 register struct monst
*elemental
;
7225 elemental
= makemon(mkclass(S_ELEMENTAL
,0), u
.ux
, u
.uy
, MM_NOSPECIALS
);
7227 if (!resist(elemental
, SPBOOK_CLASS
, 0, NOTELL
)) {
7228 elemental
= tamedog(elemental
, (struct obj
*) 0, FALSE
);
7229 if (elemental
) You("dominate %s!", mon_nam(elemental
));
7230 } else if (!resist(elemental
, SPBOOK_CLASS
, 0, NOTELL
)) {
7231 elemental
= tamedog(elemental
, (struct obj
*) 0, FALSE
);
7232 if (elemental
) You("dominate %s!", mon_nam(elemental
));
7233 } else if (!resist(elemental
, SPBOOK_CLASS
, 0, TELL
)) {
7234 elemental
= tamedog(elemental
, (struct obj
*) 0, FALSE
);
7235 if (elemental
) You("dominate %s!", mon_nam(elemental
));
7236 } else if ((rnd(30 - ACURR(A_CHA
))) < 4) {
7237 elemental
= tamedog(elemental
, (struct obj
*) 0, FALSE
);
7238 if (elemental
) You("dominate %s!", mon_nam(elemental
));
7243 u
.heavyaggravation
= 0;
7244 if (DifficultyIncreased
> 0) DifficultyIncreased
--;
7245 if (HighlevelStatus
> 0) HighlevelStatus
--;
7251 case SPE_HYPERSPACE_SUMMON
:
7254 pline("You sacrifice some of your %s and magical energy to create vortices.", body_part(BLOOD
));
7256 if (u
.uhp
> u
.uhpmax
) u
.uhp
= u
.uhpmax
;
7259 killer
= "summoning vortices with too little health";
7260 killer_format
= KILLED_BY
;
7266 if (u
.mh
> u
.mhmax
) u
.mh
= u
.mhmax
;
7270 if (u
.uenmax
< 0) u
.uenmax
= 0;
7271 if (u
.uen
> u
.uenmax
) u
.uen
= u
.uenmax
;
7275 if (spell_damage_bonus(spellid(spell
)) > 0) ammount
+= spell_damage_bonus(spellid(spell
));
7277 /* make good shit, after all you pay with max health and pw for this spell */
7279 if (!rn2(2)) u
.heavyaggravation
= 1;
7280 if (!rn2(7)) DifficultyIncreased
+= 1;
7281 if (!rn2(7)) HighlevelStatus
+= 1;
7283 register struct monst
*vortex
;
7284 while (ammount
> 0) {
7285 vortex
= makemon(mkclass(S_VORTEX
,0), u
.ux
, u
.uy
, MM_NOSPECIALS
);
7287 if (!resist(vortex
, SPBOOK_CLASS
, 0, NOTELL
)) {
7288 vortex
= tamedog(vortex
, (struct obj
*) 0, FALSE
);
7289 if (vortex
) You("dominate %s!", mon_nam(vortex
));
7290 } else if (!resist(vortex
, SPBOOK_CLASS
, 0, NOTELL
)) {
7291 vortex
= tamedog(vortex
, (struct obj
*) 0, FALSE
);
7292 if (vortex
) You("dominate %s!", mon_nam(vortex
));
7293 } else if (!resist(vortex
, SPBOOK_CLASS
, 0, NOTELL
)) {
7294 vortex
= tamedog(vortex
, (struct obj
*) 0, FALSE
);
7295 if (vortex
) You("dominate %s!", mon_nam(vortex
));
7296 } else if (!resist(vortex
, SPBOOK_CLASS
, 0, NOTELL
)) {
7297 vortex
= tamedog(vortex
, (struct obj
*) 0, FALSE
);
7298 if (vortex
) You("dominate %s!", mon_nam(vortex
));
7299 } else if (!resist(vortex
, SPBOOK_CLASS
, 0, TELL
)) {
7300 vortex
= tamedog(vortex
, (struct obj
*) 0, FALSE
);
7301 if (vortex
) You("dominate %s!", mon_nam(vortex
));
7302 } else if ((rnd(30 - ACURR(A_CHA
))) < 4) {
7303 vortex
= tamedog(vortex
, (struct obj
*) 0, FALSE
);
7304 if (vortex
) You("dominate %s!", mon_nam(vortex
));
7305 } else if ((rnd(30 - ACURR(A_CHA
))) < 4) {
7306 vortex
= tamedog(vortex
, (struct obj
*) 0, FALSE
);
7307 if (vortex
) You("dominate %s!", mon_nam(vortex
));
7315 u
.heavyaggravation
= 0;
7316 if (DifficultyIncreased
> 0) DifficultyIncreased
--;
7317 if (HighlevelStatus
> 0) HighlevelStatus
--;
7323 case SPE_KNOW_ENCHANTMENT
:
7326 pline("You detect the enchantment status of your inventory!");
7328 register struct obj
*obj
, *obj2
;
7329 for (obj
= invent
; obj
; obj
= obj2
) {
7332 if (obj
->shirtmessage
% 4 == 0 && !obj
->known
) {
7342 case SPE_DISSOLVE_FOOD
:
7345 pline("Your food dissolves!");
7347 register struct obj
*obj
, *obj2
;
7348 for (obj
= invent
; obj
; obj
= obj2
) {
7351 if (obj
->oclass
== FOOD_CLASS
) useupall(obj
);
7359 pline("You start to disguise.");
7361 youmonst
.m_ap_type
= M_AP_OBJECT
;
7362 youmonst
.mappearance
= FunnyHallu
? ORANGE
: GOLD_PIECE
;
7367 case SPE_WHISPERS_FROM_BEYOND
:
7369 ABASE(A_INT
) -= rnd(2);
7370 if (ABASE(A_INT
) < ATTRABSMIN(A_INT
)) {
7372 Your("last thought fades away.");
7373 killer
= "brainlessness";
7374 killer_format
= KILLED_BY
;
7377 /* player still alive somehow? kill them again :P */
7379 pline("Unfortunately your brain is still gone.");
7380 killer
= "brainlessness";
7381 killer_format
= KILLED_BY
;
7385 /* if you're still alive then you're either in wizard mode, or you deserve to be able to go on playing. */
7387 ABASE(A_INT
) = ATTRABSMIN(A_INT
);
7388 You_feel("like a scarecrow.");
7390 AMAX(A_INT
) = ABASE(A_INT
);
7392 ABASE(A_WIS
) -= rnd(2);
7393 if (ABASE(A_WIS
) < ATTRABSMIN(A_WIS
)) {
7396 You("turn into an unthinkable vegetable and die.");
7397 killer
= "being turned into a vegetable";
7398 killer_format
= KILLED_BY
;
7402 /* player still alive somehow? well then, you can go on playing */
7404 ABASE(A_WIS
) = ATTRABSMIN(A_WIS
);
7406 AMAX(A_WIS
) = ABASE(A_WIS
);
7408 increasesanity(rnd(1000));
7410 /* It is not a mistake that INT loss kills you twice while WIS loss only does so once. --Amy */
7412 /* now identify the stuff because otherwise players could just hangup cheat past the bad effects... gah... */
7413 identify_pack(0, 0, 0);
7414 identify_pack(0, 0, 0);
7415 if (rn2(2)) identify_pack(0, 0, 0);
7416 if (!rn2(5)) identify_pack(0, 0, 0);
7418 if (!CannotSelectItemsInPrompts
) {
7419 otmp
= getobj(allnoncount
, "secure identify");
7422 if (yn("Really exit with no object selected?") == 'y')
7423 pline("You just wasted the opportunity to secure identify your objects.");
7424 else goto whisperchoice
;
7425 pline("A feeling of loss comes over you.");
7429 makeknown(otmp
->otyp
);
7430 if (otmp
->oartifact
) discover_artifact((int)otmp
->oartifact
);
7431 otmp
->known
= otmp
->dknown
= otmp
->bknown
= otmp
->rknown
= 1;
7432 if (otmp
->otyp
== EGG
&& otmp
->corpsenm
!= NON_PM
)
7433 learn_egg_type(otmp
->corpsenm
);
7434 prinv((char *)0, otmp
, 0L);
7441 u
.stasistime
= rnd(100);
7442 nomul(-(u
.stasistime
), "frozen in stasis", FALSE
);
7443 pline("You freeze completely.");
7447 case SPE_CRYOGENICS
:
7457 pline("The spell effect backlashes!");
7459 if (!obsidianprotection()) switch (rn2(17)) {
7463 case 3: make_confused(HConfusion
+ 12, FALSE
); /* 40% */
7467 case 6: make_confused(HConfusion
+ (2L * 12 / 3L), FALSE
); /* 30% */
7468 make_stunned(HStun
+ (12 / 3L), FALSE
);
7471 case 8: make_stunned(HStun
+ (2L * 12 / 3L), FALSE
); /* 20% */
7472 make_confused(HConfusion
+ (12 / 3L), FALSE
);
7474 case 9: make_stunned(HStun
+ 12, FALSE
); /* 10% */
7476 case 10: make_numbed(HNumbed
+ 12, FALSE
); /* 10% */
7478 case 11: make_frozen(HFrozen
+ 12, FALSE
); /* 10% */
7480 case 12: make_burned(HBurned
+ 12, FALSE
); /* 10% */
7482 case 13: make_feared(HFeared
+ 12, FALSE
); /* 10% */
7484 case 14: make_blinded(Blinded
+ 12, FALSE
); /* 10% */
7486 case 15: make_hallucinated(HHallucination
+ 12, FALSE
, 0L); /* 10% */
7488 case 16: make_dimmed(HDimmed
+ 12, FALSE
); /* 10% */
7495 register struct monst
*fleemon
;
7497 for(fleemon
= fmon
; fleemon
; fleemon
= fleemon
->nmon
) {
7498 if (DEADMONSTER(fleemon
)) continue;
7499 wakeup(fleemon
); /* monster becomes hostile */
7500 if (!resist(fleemon
, SPBOOK_CLASS
, 0, NOTELL
))
7501 monflee(fleemon
, rnd(50), FALSE
, FALSE
);
7503 You_hear("horrified screaming close by.");
7511 healamount
= (rnd(10) + 4 + (spell_damage_bonus(spellid(spell
)) * 2) + rndrnz(boosted_ulevel(1)));
7512 if (healamount
> 1) healamount
/= 2;
7513 Your("symbiote seems healthier!");
7514 u
.usymbiote
.mhp
+= healamount
;
7515 if (u
.usymbiote
.mhp
> u
.usymbiote
.mhpmax
) u
.usymbiote
.mhp
= u
.usymbiote
.mhpmax
;
7520 case SPE_PHASE_DOOR
:
7523 pline("The spell backlashes!");
7529 case SPE_TELEPORT_SELF
:
7532 pline("The spell backlashes!");
7538 case SPE_MEDIUM_HEALING
:
7540 int healamount
= d(2, 10) + 5 + (!rn2(3) ? 0 : rndrnz(boosted_ulevel(1)) );
7541 if (healamount
> 1 && !rn2(2)) healamount
/= 2;
7543 healup(healamount
, 0, FALSE
, FALSE
);
7545 You_feel("healthier!");
7548 u
.usteed
->mhp
+= rnd(12);
7549 if (u
.usteed
->mhp
> u
.usteed
->mhpmax
) u
.usteed
->mhp
= u
.usteed
->mhpmax
;
7550 pline("%s looks healthier.", Monnam(u
.usteed
));
7558 case SPE_STRONG_HEALING
:
7560 int healamount
= d(5, 10) + 10 + (rn2(3) ? 0 : rnz(boosted_ulevel(2)) );
7561 if (healamount
> 1 && !rn2(2)) healamount
/= 2;
7563 healup(healamount
, 0, FALSE
, FALSE
);
7565 You_feel("much more healthy!");
7568 u
.usteed
->mhp
+= d(5, 5);
7569 if (u
.usteed
->mhp
> u
.usteed
->mhpmax
) u
.usteed
->mhp
= u
.usteed
->mhpmax
;
7570 pline("%s looks healthier.", Monnam(u
.usteed
));
7578 case SPE_SUPER_HEALING
:
7580 int healamount
= d(13, 10) + 13 + (rn2(2) ? 0 : rnz(boosted_ulevel(4)) );
7581 if (healamount
> 1 && !rn2(2)) healamount
/= 2;
7583 healup(healamount
, 0, FALSE
, FALSE
);
7585 You_feel("healthy again!");
7588 u
.usteed
->mhp
+= d(5, 13);
7589 if (u
.usteed
->mhp
> u
.usteed
->mhpmax
) u
.usteed
->mhp
= u
.usteed
->mhpmax
;
7590 pline("%s looks healthier.", Monnam(u
.usteed
));
7598 case SPE_HEALING_RAIN
:
7601 struct monst
*hrmon
;
7603 int healamount
= d(2, 10) + 5 + (!rn2(3) ? 0 : rndrnz(boosted_ulevel(1)) );
7604 if (healamount
> 1 && !rn2(2)) healamount
/= 2;
7606 healup(healamount
, 0, FALSE
, FALSE
);
7608 You_feel("healthier!");
7611 u
.usteed
->mhp
+= rnd(12);
7612 if (u
.usteed
->mhp
> u
.usteed
->mhpmax
) u
.usteed
->mhp
= u
.usteed
->mhpmax
;
7613 pline("%s looks healthier.", Monnam(u
.usteed
));
7617 for (hrmon
= fmon
; hrmon
; hrmon
= hrmon
->nmon
) {
7618 if (DEADMONSTER(hrmon
)) continue;
7619 if (distu(hrmon
->mx
,hrmon
->my
) > 9) continue;
7620 if (!hrmon
->mtame
) continue;
7622 hrmon
->mhp
+= rnd(12);
7623 if (hrmon
->mhp
> hrmon
->mhpmax
) hrmon
->mhp
= hrmon
->mhpmax
;
7624 pline("%s looks healthier.", Monnam(hrmon
));
7632 case SPE_RELOCATION
:
7633 if (u
.uhave
.amulet
&& !u
.freeplaymode
&& u
.amuletcompletelyimbued
) {
7634 pline("The amulet prevents you from using that spell.");
7637 if (In_endgame(&u
.uz
)) {
7638 pline("That sort of magic doesn't work on the Planes.");
7648 if (u
.uenmax
< 0) u
.uenmax
= 0;
7649 if (u
.uen
> u
.uenmax
) u
.uen
= u
.uenmax
;
7651 (void) safe_teleds_normalterrain(FALSE
);
7658 u
.utraptype
= TT_INFLOOR
;
7659 pline("You are burrowed into the floor, and gain armor class.");
7663 case SPE_SWITCHEROO
:
7666 int NastinessProblemSave
= NastinessProblem
;
7668 pline("Click! The red status light goes out while the green light starts shining brightly!");
7672 NastinessProblem
= NastinessProblemSave
;
7674 pline("But then the green light goes out again and the red one lights up...");
7676 NastinessProblem
+= 10000;
7689 case SPE_GAIN_CORRUPTION
:
7691 pline("Okay, if that's really what you want... you feel corrupted.");
7692 if (FunnyHallu
) pline("At least this isn't ADOM, where having too many corruptions would instakill you!");
7694 getnastytrapintrinsic();
7698 case SPE_COMMAND_DEMON
:
7701 int soundresist
= 0;
7705 for(i
= -bd
; i
<= bd
; i
++) for(j
= -bd
; j
<= bd
; j
++) {
7706 if (!isok(u
.ux
+ i
, u
.uy
+ j
)) continue;
7707 if ((mtmp
= m_at(u
.ux
+ i
, u
.uy
+ j
)) != 0 && (is_demon(mtmp
->data
))) {
7710 switch (mtmp
->data
->msound
) {
7712 case MS_FART_NORMAL
: soundresist
= 2; break;
7713 case MS_FART_QUIET
: soundresist
= 2; break;
7714 case MS_FART_LOUD
: soundresist
= 3; break;
7715 case MS_CONVERT
: soundresist
= 3; break;
7716 case MS_STENCH
: soundresist
= 5; break;
7717 case MS_HCALIEN
: soundresist
= 10; break;
7720 if (!rn2(2) && (!soundresist
|| (!rn2(soundresist
)) ) && !resist(mtmp
, SPBOOK_CLASS
, 0, NOTELL
) && !resist(mtmp
, SPBOOK_CLASS
, 0, NOTELL
)) {
7721 (void) tamedog(mtmp
, (struct obj
*) 0, FALSE
);
7723 if (u
.uenmax
< 0) u
.uenmax
= 0;
7724 if (u
.uen
> u
.uenmax
) u
.uen
= u
.uenmax
;
7727 else if (!rn2(15) && !((rnd(30 - ACURR(A_CHA
))) < 4) && !mtmp
->mfrenzied
&& !mtmp
->mtame
) {
7728 pline("Instead of being tamed, %s enters a state of frenzy!", mon_nam(mtmp
));
7729 mtmp
->mpeaceful
= 0;
7730 mtmp
->mfrenzied
= 1;
7737 pline("The spell backfires!");
7743 case SPE_SELFDESTRUCT
:
7751 pline("%s used SELFDESTRUCT!", playeraliasname
);
7753 for(i
= -bd
; i
<= bd
; i
++) for(j
= -bd
; j
<= bd
; j
++) {
7754 if (!isok(u
.ux
+ i
, u
.uy
+ j
)) continue;
7755 if ((mtmp
= m_at(u
.ux
+ i
, u
.uy
+ j
)) != 0) {
7756 mtmp
->mhp
-= rnd(u
.uhpmax
* 5);
7757 pline("%s is hit by the explosion!", Monnam(mtmp
));
7758 if (mtmp
->mhp
<= 0) {
7759 pline("%s is killed!", Monnam(mtmp
));
7761 } else wakeup(mtmp
); /* monster becomes hostile */
7766 killer
= "selfdestructing";
7767 killer_format
= KILLED_BY
;
7770 /* No, being polymorphed does not save you. If it did, this spell would be rendered overpowered. --Amy */
7776 case SPE_FINAL_EXPLOSION
:
7783 pline("%s used EXPLOSION!", playeraliasname
);
7785 for(i
= -bd
; i
<= bd
; i
++) for(j
= -bd
; j
<= bd
; j
++) {
7786 if (!isok(u
.ux
+ i
, u
.uy
+ j
)) continue;
7787 if ((mtmp
= m_at(u
.ux
+ i
, u
.uy
+ j
)) != 0) {
7788 mtmp
->mhp
-= rnd(u
.uhpmax
* 10);
7789 pline("%s is hit by the explosion!", Monnam(mtmp
));
7790 if (mtmp
->mhp
<= 0) {
7791 pline("%s is killed!", Monnam(mtmp
));
7793 } else wakeup(mtmp
); /* monster becomes hostile */
7798 killer
= "exploding";
7799 killer_format
= KILLED_BY
;
7802 /* No, being polymorphed does not save you. If it did, this spell would be rendered overpowered. --Amy */
7808 case SPE_EARTHQUAKE
:
7809 pline_The("entire dungeon is shaking around you!");
7810 do_earthquake((GushLevel
- 1) / 3 + 1);
7812 int disableamount
= rnd(3);
7813 while (disableamount
) {
7814 deacrandomintrinsic(rnz( (monster_difficulty() * 10) + 1));
7816 if (disableamount
< 0) disableamount
= 0;
7822 case SPE_LYCANTHROPY
:
7824 if (u
.ulycn
!= NON_PM
) {
7825 pline("You are already lycanthropic!");
7834 monstZ
= rn2(NUMMONS
);
7837 } while (!(is_were(&mons
[monstZ
])) || (mons
[monstZ
].mlet
== S_HUMAN
) && attempts
< 50000);
7839 if (is_were(&mons
[monstZ
]) && !(mons
[monstZ
].mlet
== S_HUMAN
) ) {
7841 pline("You feel feverish.");
7842 u
.cnd_lycanthropecount
++;
7849 case SPE_BUC_RANDOMIZATION
:
7851 { register struct obj
*objC
;
7853 You_feel("the power of the Force against you!");
7855 You_feel("like you need some help.");
7856 if (PlayerHearsSoundEffects
) pline(issoviet
? "Vashe der'mo tol'ko chto proklinal." : "Woaaaaaa-AAAH!");
7858 for (objC
= invent
; objC
; objC
= objC
->nobj
) {
7861 /* gold isn't subject to cursing and blessing */
7862 if (objC
->oclass
== COIN_CLASS
) continue;
7864 wornmask
= (objC
->owornmask
& ~(W_BALL
|W_ART
|W_ARTI
));
7866 /* handle a couple of special cases; we don't
7867 allow auxiliary weapon slots to be used to
7868 artificially increase number of worn items */
7869 if (objC
== uswapwep
) {
7870 if (!u
.twoweap
) wornmask
= 0L;
7871 } else if (objC
== uquiver
) {
7872 if (objC
->oclass
== WEAPON_CLASS
) {
7873 /* mergeable weapon test covers ammo,
7874 missiles, spears, daggers & knives */
7875 if (!objects
[objC
->otyp
].oc_merge
)
7877 } else if (objC
->oclass
== GEM_CLASS
) {
7878 /* possibly ought to check whether
7879 alternate weapon is a sling... */
7880 if (!uslinging()) wornmask
= 0L;
7882 /* weptools don't merge and aren't
7883 reasonable quivered weapons */
7889 objC
->otyp
== LOADSTONE
||
7890 objC
->otyp
== LOADBOULDER
||
7891 objC
->otyp
== STARLIGHTSTONE
||
7892 objC
->otyp
== LUCKSTONE
||
7893 objC
->otyp
== HEALTHSTONE
||
7894 objC
->otyp
== MANASTONE
||
7895 objC
->otyp
== SLEEPSTONE
||
7896 objC
->otyp
== STONE_OF_MAGIC_RESISTANCE
||
7897 is_nastygraystone(objC
) ||
7898 is_feminismstone(objC
) ||
7899 (objC
->otyp
== LEATHER_LEASH
&& objC
->leashmon
) || (objC
->otyp
== INKA_LEASH
&& objC
->leashmon
) || (objC
->otyp
== ADAMANT_LEASH
&& objC
->leashmon
) ) && !stack_too_big(objC
) && !rn2(5) ) {
7900 blessorcurse(objC
, 2);
7911 pline("%s", fauxmessage());
7912 u
.cnd_plineamount
++;
7914 pline("%s", fauxmessage());
7915 u
.cnd_plineamount
++;
7925 if (rn2(2)) line
= getrumor(-1, buflin
, TRUE
);
7926 else line
= getrumor(0, buflin
, TRUE
);
7927 if (!*line
) line
= "Slash'EM rumors file closed for renovation.";
7933 case SPE_TRAP_DISARMING
:
7935 You_feel("out of the danger zone.");
7942 for (i
= -1; i
<= 1; i
++) for(j
= -1; j
<= 1; j
++) {
7944 if ((ttmp
= t_at(u
.ux
+ i
, u
.uy
+ j
)) != 0) {
7945 if (ttmp
->ttyp
== MAGIC_PORTAL
) continue;
7952 pline("You are hit by the magical reaction from casting this very powerful spell.");
7961 if (u
.uhpmax
< 501) {
7962 pline("You don't have enough health to control the powers of this spell!");
7965 if (Upolyd
&& u
.mhmax
< 501) {
7966 pline("You don't have enough health to control the powers of this spell!");
7969 if (u
.uenmax
< 501) {
7970 pline("You don't have enough mana to control the powers of this spell!");
7974 if (ABASE(A_STR
) < 6 || ABASE(A_DEX
) < 6 || ABASE(A_INT
) < 6 || ABASE(A_WIS
) < 6 || ABASE(A_CON
) < 6 || ABASE(A_CHA
) < 6) {
7975 pline("You don't have the stats required to power this mighty spell!");
7979 u
.uhpmax
-= rnd(500);
7980 if (u
.uhp
> u
.uhpmax
) u
.uhp
= u
.uhpmax
;
7982 u
.mhmax
-= rnd(500);
7983 if (u
.mh
> u
.mhmax
) u
.mh
= u
.mhmax
;
7985 u
.uenmax
-= rnd(500);
7986 if (u
.uen
> u
.uenmax
) u
.uen
= u
.uenmax
;
7988 ABASE(A_STR
) -= rnd(5);
7989 if (ABASE(A_STR
) < ATTRABSMIN(A_STR
)) ABASE(A_STR
) = ATTRABSMIN(A_STR
);
7990 AMAX(A_STR
) = ABASE(A_STR
);
7992 ABASE(A_DEX
) -= rnd(5);
7993 if (ABASE(A_DEX
) < ATTRABSMIN(A_DEX
)) ABASE(A_DEX
) = ATTRABSMIN(A_DEX
);
7994 AMAX(A_DEX
) = ABASE(A_DEX
);
7996 ABASE(A_INT
) -= rnd(5);
7997 if (ABASE(A_INT
) < ATTRABSMIN(A_INT
)) ABASE(A_INT
) = ATTRABSMIN(A_INT
);
7998 AMAX(A_INT
) = ABASE(A_INT
);
8000 ABASE(A_WIS
) -= rnd(5);
8001 if (ABASE(A_WIS
) < ATTRABSMIN(A_WIS
)) ABASE(A_WIS
) = ATTRABSMIN(A_WIS
);
8002 AMAX(A_WIS
) = ABASE(A_WIS
);
8004 ABASE(A_CON
) -= rnd(5);
8005 if (ABASE(A_CON
) < ATTRABSMIN(A_CON
)) ABASE(A_CON
) = ATTRABSMIN(A_CON
);
8006 AMAX(A_CON
) = ABASE(A_CON
);
8008 ABASE(A_CHA
) -= rnd(5);
8009 if (ABASE(A_CHA
) < ATTRABSMIN(A_CHA
)) ABASE(A_CHA
) = ATTRABSMIN(A_CHA
);
8010 AMAX(A_CHA
) = ABASE(A_CHA
);
8016 case SPE_ACQUIREMENT
:
8018 if (u
.uhpmax
< 101) {
8019 pline("You don't have enough health to control the powers of this spell!");
8022 if (Upolyd
&& u
.mhmax
< 101) {
8023 pline("You don't have enough health to control the powers of this spell!");
8026 if (u
.uenmax
< 101) {
8027 pline("You don't have enough mana to control the powers of this spell!");
8031 if (ABASE(A_STR
) < 4 || ABASE(A_DEX
) < 4 || ABASE(A_INT
) < 4 || ABASE(A_WIS
) < 4 || ABASE(A_CON
) < 4 || ABASE(A_CHA
) < 4) {
8032 pline("You don't have the stats required to power this mighty spell!");
8036 u
.uhpmax
-= rnd(33);
8037 if (rn2(2)) u
.uhpmax
-= rnd(33);
8038 if (!rn2(4)) u
.uhpmax
-= rnd(33);
8039 if (u
.uhp
> u
.uhpmax
) u
.uhp
= u
.uhpmax
;
8042 if (rn2(2)) u
.mhmax
-= rnd(33);
8043 if (!rn2(4)) u
.mhmax
-= rnd(33);
8044 if (u
.mh
> u
.mhmax
) u
.mh
= u
.mhmax
;
8046 u
.uenmax
-= rnd(33);
8047 if (rn2(2)) u
.uenmax
-= rnd(33);
8048 if (!rn2(4)) u
.uenmax
-= rnd(33);
8049 if (u
.uen
> u
.uenmax
) u
.uen
= u
.uenmax
;
8053 if (ABASE(A_STR
) < ATTRABSMIN(A_STR
)) ABASE(A_STR
) = ATTRABSMIN(A_STR
);
8054 AMAX(A_STR
) = ABASE(A_STR
);
8059 if (ABASE(A_DEX
) < ATTRABSMIN(A_DEX
)) ABASE(A_DEX
) = ATTRABSMIN(A_DEX
);
8060 AMAX(A_DEX
) = ABASE(A_DEX
);
8065 if (ABASE(A_INT
) < ATTRABSMIN(A_INT
)) ABASE(A_INT
) = ATTRABSMIN(A_INT
);
8066 AMAX(A_INT
) = ABASE(A_INT
);
8071 if (ABASE(A_WIS
) < ATTRABSMIN(A_WIS
)) ABASE(A_WIS
) = ATTRABSMIN(A_WIS
);
8072 AMAX(A_WIS
) = ABASE(A_WIS
);
8077 if (ABASE(A_CON
) < ATTRABSMIN(A_CON
)) ABASE(A_CON
) = ATTRABSMIN(A_CON
);
8078 AMAX(A_CON
) = ABASE(A_CON
);
8083 if (ABASE(A_CHA
) < ATTRABSMIN(A_CHA
)) ABASE(A_CHA
) = ATTRABSMIN(A_CHA
);
8084 AMAX(A_CHA
) = ABASE(A_CHA
);
8091 case SPE_MASS_HEALING
:
8093 register struct monst
*mtmp
, *mtmp2
;
8095 for (mtmp
= fmon
; mtmp
; mtmp
= mtmp2
) {
8097 if (mtmp
== &youmonst
) continue;
8098 if (DEADMONSTER(mtmp
)) continue;
8100 if (!Hallucination
&& (!mtmp
->mpeaceful
|| !rn2(2)))
8103 if (!canspotmon(mtmp
)) continue; /*you can't see it and can't sense it*/
8105 mtmp
->mhp
+= rnd(50);
8106 if (mtmp
->mhp
> mtmp
->mhpmax
) {
8107 mtmp
->mhp
= mtmp
->mhpmax
;
8109 if (mtmp
->bleedout
) {
8110 mtmp
->bleedout
-= rnd(50);
8111 if (mtmp
->bleedout
< 0) mtmp
->bleedout
= 0;
8113 pline("%s is healed.", Monnam(mtmp
));
8117 int healamount
= (d(6,8) + rndrnz(boosted_ulevel(1)) );
8118 if (healamount
> 1) healamount
/= 2;
8120 healup(healamount
,0,0,0);
8124 case SPE_TIME_SHIFT
:
8125 pline("Time goes forward...");
8132 You("call upon your chemical knowledge. Nothing happens.");
8134 case SPE_CURE_SICKNESS
:
8136 if ((Sick
|| Slimed
) && !Role_if(PM_HEALER
)) {
8139 if (u
.uen
> u
.uenmax
) u
.uen
= u
.uenmax
;
8141 You("don't have enough power for this spell.");
8146 if (Sick
) You("are no longer ill.");
8148 pline_The("slime disappears!");
8150 /* flags.botl = 1; -- healup() handles this */
8152 healup(0, 0, TRUE
, FALSE
);
8154 case SPE_CURE_HALLUCINATION
:
8155 if (HeavyHallu
) break;
8156 if (HHallucination
> (rn1(Role_if(PM_HEALER
) ? 200 : 100, 20))) {
8157 int effreduction
= rnd(HHallucination
/ 2);
8158 if (effreduction
> 0) {
8159 HHallucination
-= effreduction
;
8160 Your("hallucination counter is reduced.");
8162 if (!Role_if(PM_HEALER
) && !rn2(500)) {
8163 pline("The spell backlashes!");
8167 make_hallucinated(0L,TRUE
,0L);
8170 case SPE_CURE_CONFUSION
:
8171 if (HeavyConfusion
) break;
8172 if (HConfusion
> (rn1(Role_if(PM_HEALER
) ? 200 : 100, 20))) {
8173 int effreduction
= rnd(HConfusion
/ 2);
8174 if (effreduction
> 0) {
8175 HConfusion
-= effreduction
;
8176 Your("confusion counter is reduced.");
8178 if (!Role_if(PM_HEALER
) && !rn2(500)) {
8179 pline("The spell backlashes!");
8183 make_confused(0L,TRUE
);
8187 if (HeavyStunned
) break;
8188 if (HStun
> (rn1(Role_if(PM_HEALER
) ? 200 : 100, 20))) {
8189 int effreduction
= rnd(HStun
/ 2);
8190 if (effreduction
> 0) {
8191 HStun
-= effreduction
;
8192 Your("stun counter is reduced.");
8194 if (!Role_if(PM_HEALER
) && !rn2(500)) {
8195 pline("The spell backlashes!");
8199 make_stunned(0L,TRUE
);
8203 if (HeavyDimmed
) break;
8204 if (HDimmed
> (rn1(Role_if(PM_HEALER
) ? 200 : 100, 20))) {
8205 int effreduction
= rnd(HDimmed
/ 2);
8206 if (effreduction
> 0) {
8207 HDimmed
-= effreduction
;
8208 Your("dimness counter is reduced.");
8210 if (!Role_if(PM_HEALER
) && !rn2(500)) {
8211 pline("The spell backlashes!");
8215 make_dimmed(0L,TRUE
);
8219 if (HeavyBurned
) break;
8220 if (HBurned
> (rn1(Role_if(PM_HEALER
) ? 200 : 100, 20))) {
8221 int effreduction
= rnd(HBurned
/ 2);
8222 if (effreduction
> 0) {
8223 HBurned
-= effreduction
;
8224 Your("burn counter is reduced.");
8226 if (!Role_if(PM_HEALER
) && !rn2(500)) {
8227 pline("The spell backlashes!");
8231 make_burned(0L,TRUE
);
8234 case SPE_CURE_FREEZE
:
8235 if (HeavyFrozen
) break;
8236 if (HFrozen
> (rn1(Role_if(PM_HEALER
) ? 200 : 100, 20))) {
8237 int effreduction
= rnd(HFrozen
/ 2);
8238 if (effreduction
> 0) {
8239 HFrozen
-= effreduction
;
8240 Your("freeze counter is reduced.");
8242 if (!Role_if(PM_HEALER
) && !rn2(500)) {
8243 pline("The spell backlashes!");
8247 make_frozen(0L,TRUE
);
8250 case SPE_CURE_NUMBNESS
:
8251 if (HeavyNumbed
) break;
8252 if (HNumbed
> (rn1(Role_if(PM_HEALER
) ? 200 : 100, 20))) {
8253 int effreduction
= rnd(HNumbed
/ 2);
8254 if (effreduction
> 0) {
8255 HNumbed
-= effreduction
;
8256 Your("numbness counter is reduced.");
8258 if (!Role_if(PM_HEALER
) && !rn2(500)) {
8259 pline("The spell backlashes!");
8263 make_numbed(0L,TRUE
);
8266 case SPE_CURE_RANDOM_STATUS
:
8269 if ((Sick
|| Slimed
) && !Role_if(PM_HEALER
) && !rn2(5)) {
8272 if (u
.uen
> u
.uenmax
) u
.uen
= u
.uenmax
;
8274 You("don't have enough power for this spell.");
8279 if (Sick
) You("are no longer ill.");
8281 pline_The("slime disappears!");
8284 healup(0, 0, TRUE
, FALSE
);
8287 if (HeavyHallu
) break;
8288 if (HHallucination
> (rn1(Role_if(PM_HEALER
) ? 600 : 300, 20))) {
8289 int effreduction
= rnd(HHallucination
/ 2);
8290 if (effreduction
> 0) {
8291 HHallucination
-= effreduction
;
8292 Your("hallucination counter is reduced.");
8295 make_hallucinated(0L,TRUE
,0L);
8299 if (HeavyConfusion
) break;
8300 if (HConfusion
> (rn1(Role_if(PM_HEALER
) ? 600 : 300, 20))) {
8301 int effreduction
= rnd(HConfusion
/ 2);
8302 if (effreduction
> 0) {
8303 HConfusion
-= effreduction
;
8304 Your("confusion counter is reduced.");
8307 make_confused(0L,TRUE
);
8311 if (HeavyStunned
) break;
8312 if (HStun
> (rn1(Role_if(PM_HEALER
) ? 600 : 300, 20))) {
8313 int effreduction
= rnd(HStun
/ 2);
8314 if (effreduction
> 0) {
8315 HStun
-= effreduction
;
8316 Your("stun counter is reduced.");
8319 make_stunned(0L,TRUE
);
8323 if (HeavyBurned
) break;
8324 if (HBurned
> (rn1(Role_if(PM_HEALER
) ? 600 : 300, 20))) {
8325 int effreduction
= rnd(HBurned
/ 2);
8326 if (effreduction
> 0) {
8327 HBurned
-= effreduction
;
8328 Your("burn counter is reduced.");
8331 make_burned(0L,TRUE
);
8335 if (HeavyFrozen
) break;
8336 if (HFrozen
> (rn1(Role_if(PM_HEALER
) ? 600 : 300, 20))) {
8337 int effreduction
= rnd(HFrozen
/ 2);
8338 if (effreduction
> 0) {
8339 HFrozen
-= effreduction
;
8340 Your("freeze counter is reduced.");
8343 make_frozen(0L,TRUE
);
8347 if (HeavyNumbed
) break;
8348 if (HNumbed
> (rn1(Role_if(PM_HEALER
) ? 600 : 300, 20))) {
8349 int effreduction
= rnd(HNumbed
/ 2);
8350 if (effreduction
> 0) {
8351 HNumbed
-= effreduction
;
8352 Your("numbness counter is reduced.");
8355 make_numbed(0L,TRUE
);
8359 if (HeavyBlind
) break;
8360 if (Blinded
> (rn1(Role_if(PM_HEALER
) ? 600 : 300, 20))) {
8361 int effreduction
= rnd(Blinded
/ 2);
8362 if (effreduction
> 0) {
8363 u
.ucreamed
-= effreduction
;
8364 if ((int)(u
.ucreamed
) < 0) u
.ucreamed
= 0; /* fail safe */
8365 Blinded
-= effreduction
;
8366 Your("blindness counter is reduced.");
8369 make_blinded(0L,FALSE
);
8373 if (HeavyFeared
) break;
8374 if (HFeared
> (rn1(Role_if(PM_HEALER
) ? 600 : 300, 20))) {
8375 int effreduction
= rnd(HFeared
/ 2);
8376 if (effreduction
> 0) {
8377 HFeared
-= effreduction
;
8378 Your("fear counter is reduced.");
8381 make_feared(0L, TRUE
);
8385 if (HeavyDimmed
) break;
8386 if (HDimmed
> (rn1(Role_if(PM_HEALER
) ? 600 : 300, 20))) {
8387 int effreduction
= rnd(HDimmed
/ 2);
8388 if (effreduction
> 0) {
8389 HDimmed
-= effreduction
;
8390 Your("dimness counter is reduced.");
8393 make_dimmed(0L,TRUE
);
8399 case SPE_STINKING_CLOUD
:
8401 pline("Where do you want to center the cloud?");
8404 if (getpos(&cc
, TRUE
, "the desired position") < 0) {
8405 pline("%s", Never_mind
);
8406 if (FailureEffects
|| u
.uprops
[FAILURE_EFFECTS
].extrinsic
|| have_failurestone()) {
8407 pline("Oh wait, actually I do mind...");
8412 if (!cansee(cc
.x
, cc
.y
) || distu(cc
.x
, cc
.y
) >= 32) {
8413 You("smell rotten eggs.");
8416 (void) create_gas_cloud(cc
.x
, cc
.y
, 2, 5);
8421 You_feel("revitalized.");
8423 if ((Sick
|| Slimed
) && !Role_if(PM_HEALER
)) {
8426 if (u
.uen
> u
.uenmax
) u
.uen
= u
.uenmax
;
8428 You("don't have enough power for this spell.");
8434 fix_petrification();
8439 killer
= "dissolving completely";
8440 killer_format
= KILLED_BY
;
8445 if (u
.uhp
> u
.uhpmax
) u
.uhp
= u
.uhpmax
;
8448 if (u
.mhmax
> 1) u
.mhmax
--;
8449 if (u
.mh
> u
.mhmax
) u
.mh
= u
.mhmax
;
8452 Your("health was damaged.");
8454 u
.negativeprotection
+= rnd(3);
8455 MCReduction
+= rn1(2500, 2500);
8456 Your("body was damaged.");
8461 pline("The slime disappears.");
8465 make_sick(0L, (char *) 0, FALSE
, SICK_ALL
);
8466 make_blinded(0L,FALSE
);
8467 make_stunned(0L,TRUE
);
8468 make_confused(0L,TRUE
);
8469 (void) make_hallucinated(0L,FALSE
,0L);
8470 make_numbed(0L,TRUE
);
8471 make_feared(0L,TRUE
);
8472 make_frozen(0L,TRUE
);
8473 make_burned(0L,TRUE
);
8474 make_dimmed(0L,TRUE
);
8481 pline_The("water around you vaporizes violently!");
8483 pline_The("air around you erupts in a tower of flame!");
8486 explode(u
.ux
, u
.uy
, ZT_SPELL(ZT_FIRE
), 3 + (spell_damage_bonus(spellid(spell
)) / 2), SCROLL_CLASS
, EXPL_FIERY
);
8490 case SPE_RUSSIAN_ROULETTE
:
8496 } else if (rn2(10)) {
8497 pline("Click! You feel vitalized.");
8499 if (Upolyd
) u
.mhmax
++;
8501 u
.usymbiote
.mhpmax
++;
8502 maybe_evolve_symbiote();
8503 if (u
.usymbiote
.mhpmax
> 500) u
.usymbiote
.mhpmax
= 500;
8507 pline("BANG! You suffer from extreme blood loss!");
8509 u
.uhpmax
-= rnd(50);
8510 if (u
.uhp
> u
.uhpmax
) u
.uhp
= u
.uhpmax
;
8513 killer
= "playing russian roulette";
8514 killer_format
= KILLED_BY
;
8521 if (u
.mh
> u
.mhmax
) u
.mh
= u
.mhmax
;
8524 killer
= "playing russian roulette";
8525 killer_format
= KILLED_BY
;
8530 u
.uenmax
-= rnd(30);
8531 if (u
.uenmax
< 0) u
.uenmax
= 0;
8532 if (u
.uen
> u
.uenmax
) u
.uen
= u
.uenmax
;
8538 case SPE_ACID_INGESTION
:
8539 pline("Sulfuric acid forms in your mouth...");
8541 /* bullshit downside by Amy - we don't want petrification to be THAT trivial to cure... */
8546 killer
= "dissolving completely";
8547 killer_format
= KILLED_BY
;
8552 if (u
.uhp
> u
.uhpmax
) u
.uhp
= u
.uhpmax
;
8555 if (u
.mhmax
> 1) u
.mhmax
--;
8556 if (u
.mh
> u
.mhmax
) u
.mh
= u
.mhmax
;
8559 Your("health was damaged.");
8561 u
.negativeprotection
+= rnd(3);
8562 MCReduction
+= rn1(2500, 2500);
8563 Your("body was damaged.");
8566 if (Acid_resistance
&& (StrongAcid_resistance
|| AcidImmunity
|| rn2(10)) ) {
8567 pline("This tastes %s.", FunnyHallu
? "tangy" : "sour");
8569 pline("This burns a lot!");
8570 losehp(d(2, 8), "ingesting acid", KILLED_BY
);
8572 if (Stoned
) fix_petrification();
8576 case SPE_INDUCE_VOMITING
:
8577 pline("You put your %s into your mouth...", body_part(FINGER
));
8579 You_feel("like you're going to throw up.");
8580 make_vomiting(Vomiting
+20, TRUE
);
8581 if (Sick
&& Sick
< 100)
8582 set_itimeout(&Sick
, (Sick
* 2) + 10); /* higher chance to survive long enough --Amy */
8587 You("decide to reboot.");
8588 if (PlayerHearsSoundEffects
) pline(issoviet
? "Eto poshel na khuy vverkh. No chto zhe vy ozhidali? Igra, v kotoruyu vy mozhete legko vyigrat'? Durak!" : "DUEUEDUET!");
8589 if (!Race_if(PM_UNGENOMOLD
)) newman();
8590 else polyself(FALSE
);
8594 case SPE_FORGOTTEN_SPELL
:
8595 Your("knowledge of this spell is twisted.");
8596 pline("It invokes nightmarish images in your mind...");
8598 int duration
= rn1(25,25);
8600 if (!obsidianprotection()) switch (rn2(17)) {
8604 case 3: make_confused(HConfusion
+ duration
, FALSE
); /* 40% */
8608 case 6: make_confused(HConfusion
+ (2L * duration
/ 3L), FALSE
); /* 30% */
8609 make_stunned(HStun
+ (duration
/ 3L), FALSE
);
8612 case 8: make_stunned(HStun
+ (2L * duration
/ 3L), FALSE
); /* 20% */
8613 make_confused(HConfusion
+ (duration
/ 3L), FALSE
);
8615 case 9: make_stunned(HStun
+ duration
, FALSE
); /* 10% */
8617 case 10: make_numbed(HNumbed
+ duration
, FALSE
); /* 10% */
8619 case 11: make_frozen(HFrozen
+ duration
, FALSE
); /* 10% */
8621 case 12: make_burned(HBurned
+ duration
, FALSE
); /* 10% */
8623 case 13: make_feared(HFeared
+ duration
, FALSE
); /* 10% */
8625 case 14: make_blinded(Blinded
+ duration
, FALSE
); /* 10% */
8627 case 15: make_hallucinated(HHallucination
+ duration
, FALSE
, 0L); /* 10% */
8629 case 16: make_dimmed(HDimmed
+ duration
, FALSE
); /* 10% */
8639 pline((Role_if(PM_SAMURAI
) || Role_if(PM_NINJA
)) ? "Jikan ga teishi shimashita." : "Time has stopped.");
8640 if (rn2(3)) TimeStopped
+= (rnd(3) + 1);
8641 else TimeStopped
+= rnd(3 + spell_damage_bonus(spellid(spell
)) );
8644 if (!playerlevelportdisabled()) {
8646 pline("From your strain of casting such a powerful spell, the magical energy backlashes on you.");
8649 else pline("Hmm... that level teleport spell didn't do anything.");
8653 if (((u
.uhave
.amulet
) && !u
.freeplaymode
) || CannotTeleport
|| (u
.usteed
&& mon_has_amulet(u
.usteed
))) { pline("You shudder for a moment."); break;}
8655 if (playerlevelportdisabled()) {
8656 pline("You're unable to warp!");
8663 pline("From your strain of casting such a powerful spell, the magical energy backlashes on you.");
8668 case SPE_TRAP_CREATION
:
8670 You_feel("endangered!!");
8674 register struct trap
*ttmp
;
8675 boolean canbeinawall
= FALSE
;
8676 if (!rn2(Passes_walls
? 5 : 25)) canbeinawall
= TRUE
;
8678 for (i
= -bd
; i
<= bd
; i
++) for(j
= -bd
; j
<= bd
; j
++) {
8679 if (!isok(u
.ux
+ i
, u
.uy
+ j
)) continue;
8680 if ((levl
[u
.ux
+ i
][u
.uy
+ j
].typ
<= DBWALL
) && !canbeinawall
) continue;
8681 if (t_at(u
.ux
+ i
, u
.uy
+ j
)) continue;
8685 ttmp
= maketrap(u
.ux
+ i
, u
.uy
+ j
, rtrap
, 100, FALSE
);
8686 if (ttmp
&& !rn2(10)) ttmp
->hiddentrap
= TRUE
;
8691 makerandomtrap(FALSE
);
8692 if (!rn2(2)) makerandomtrap(FALSE
);
8693 if (!rn2(4)) makerandomtrap(FALSE
);
8694 if (!rn2(8)) makerandomtrap(FALSE
);
8695 if (!rn2(16)) makerandomtrap(FALSE
);
8696 if (!rn2(32)) makerandomtrap(FALSE
);
8697 if (!rn2(64)) makerandomtrap(FALSE
);
8698 if (!rn2(128)) makerandomtrap(FALSE
);
8699 if (!rn2(256)) makerandomtrap(FALSE
);
8702 if (!rn2(2)) makeinvisotrap();
8703 if (!rn2(4)) makeinvisotrap();
8704 if (!rn2(8)) makeinvisotrap();
8705 if (!rn2(16)) makeinvisotrap();
8706 if (!rn2(32)) makeinvisotrap();
8707 if (!rn2(64)) makeinvisotrap();
8708 if (!rn2(128)) makeinvisotrap();
8709 if (!rn2(256)) makeinvisotrap();
8717 pline("You stagger a bit...");
8718 make_stunned(HStun
+ rnd(25), FALSE
);
8720 case SPE_CONFUSE_SELF
:
8722 You_feel("somewhat dizzy.");
8723 make_confused(HConfusion
+ rnd(25), FALSE
);
8725 case SPE_BLIND_SELF
:
8726 if (!Blind
&& !u
.usleep
) pline("It suddenly gets dark.");
8727 make_blinded(Blinded
+ rnd(25), FALSE
);
8728 if (!Blind
&& !u
.usleep
) Your("%s", vision_clears
);
8731 case SPE_AIR_CURRENT
:
8733 You_hear("air current noises, and a remark by Amy about how sexy they are.");
8735 You_hear("air current noises.");
8738 if (In_sokoban(&u
.uz
) && !playercancheatinsoko()) {
8740 pline("You cheater!");
8741 if (evilfriday
) u
.ugangr
++;
8749 if (!getdir((char *)0)) {
8750 if (yn("Do you really want to input no direction?") == 'y')
8757 if (!u
.dx
&& !u
.dy
) {
8769 if (u
.uhp
> u
.uhpmax
) u
.uhp
= u
.uhpmax
;
8772 killer
= "melting down";
8773 killer_format
= KILLED_BY
;
8779 if (u
.mh
> u
.mhmax
) u
.mh
= u
.mhmax
;
8783 if (u
.uen
> u
.uenmax
) u
.uen
= u
.uenmax
;
8786 do_clear_areaX(u
.ux
, u
.uy
, 1, undo_barfloodC
, (void *)&maderoom
);
8788 You("have a sense of freedom.");
8796 do_clear_areaX(u
.ux
, u
.uy
, 5 + rnd(5), do_floodg
, (void *)&madepoolX
);
8797 if (madepoolX
) pline("Watery pits appear in the dungeon!");
8800 if (u
.uenmax
< 0) u
.uenmax
= 0;
8801 if (u
.uen
> u
.uenmax
) u
.uen
= u
.uenmax
;
8802 pline("Casting this spell is straining for your maximum mana supply.");
8811 do_clear_areaX(u
.ux
, u
.uy
, 5 + rnd(5), do_lavafloodg
, (void *)&madepool
);
8812 if (madepool
) pline("Lava pools are created!");
8815 if (u
.uenmax
< 0) u
.uenmax
= 0;
8816 if (u
.uen
> u
.uenmax
) u
.uen
= u
.uenmax
;
8817 pline("Casting this spell is straining for your maximum mana supply.");
8824 case SPE_IRON_PRISON
:
8827 do_clear_areaX(u
.ux
, u
.uy
, 5 + rnd(5), do_barfloodg
, (void *)&madepoolQ
);
8828 if (madepoolQ
) pline("Iron bars appear from thin air!");
8831 if (u
.uenmax
< 0) u
.uenmax
= 0;
8832 if (u
.uen
> u
.uenmax
) u
.uen
= u
.uenmax
;
8833 pline("Casting this spell is straining for your maximum mana supply.");
8843 do_clear_areaX(u
.ux
, u
.uy
, 5 + rnd(5), do_cloudfloodg
, (void *)&madepoolQ
);
8844 if (madepoolQ
) pline("Clouds everywhere!");
8847 if (u
.uenmax
< 0) u
.uenmax
= 0;
8848 if (u
.uen
> u
.uenmax
) u
.uen
= u
.uenmax
;
8849 pline("Casting this spell is straining for your maximum mana supply.");
8859 do_clear_areaX(u
.ux
, u
.uy
, 5 + rnd(5), do_icefloodg
, (void *)&madepoolQ
);
8860 if (madepoolQ
) pline("The landscape is winterized!");
8863 if (u
.uenmax
< 0) u
.uenmax
= 0;
8864 if (u
.uen
> u
.uenmax
) u
.uen
= u
.uenmax
;
8865 pline("Casting this spell is straining for your maximum mana supply.");
8875 do_clear_areaX(u
.ux
, u
.uy
, 5 + rnd(5), do_lockfloodg
, (void *)&madepoolQ
);
8876 if (madepoolQ
) pline("The area is walled off!");
8879 if (u
.uenmax
< 0) u
.uenmax
= 0;
8880 if (u
.uen
> u
.uenmax
) u
.uen
= u
.uenmax
;
8881 pline("Casting this spell is straining for your maximum mana supply.");
8888 case SPE_GROW_TREES
:
8891 do_clear_areaX(u
.ux
, u
.uy
, 5 + rnd(5), do_treefloodg
, (void *)&madepoolQ
);
8892 if (madepoolQ
) pline("Trees start to grow rapidly!");
8895 if (u
.uenmax
< 0) u
.uenmax
= 0;
8896 if (u
.uen
> u
.uenmax
) u
.uen
= u
.uenmax
;
8897 pline("Casting this spell is straining for your maximum mana supply.");
8907 do_clear_areaX(u
.ux
, u
.uy
, 5 + rnd(5), do_gravefloodg
, (void *)&madepoolQ
);
8908 if (madepoolQ
) pline("Hans Walt erects grave walls!");
8911 if (u
.uenmax
< 0) u
.uenmax
= 0;
8912 if (u
.uen
> u
.uenmax
) u
.uen
= u
.uenmax
;
8913 pline("Casting this spell is straining for your maximum mana supply.");
8923 do_clear_areaX(u
.ux
, u
.uy
, 5 + rnd(5), do_tunnelfloodg
, (void *)&madepoolQ
);
8924 if (madepoolQ
) pline("Lots of tunnels are built!");
8927 if (u
.uenmax
< 0) u
.uenmax
= 0;
8928 if (u
.uen
> u
.uenmax
) u
.uen
= u
.uenmax
;
8929 pline("Casting this spell is straining for your maximum mana supply.");
8939 do_clear_areaX(u
.ux
, u
.uy
, 5 + rnd(5), do_farmfloodg
, (void *)&madepoolQ
);
8940 if (madepoolQ
) pline("Farmland appears.");
8943 if (u
.uenmax
< 0) u
.uenmax
= 0;
8944 if (u
.uen
> u
.uenmax
) u
.uen
= u
.uenmax
;
8945 pline("Casting this spell is straining for your maximum mana supply.");
8955 do_clear_areaX(u
.ux
, u
.uy
, 5 + rnd(5), do_mountainfloodg
, (void *)&madepoolQ
);
8956 if (madepoolQ
) pline("An underground mountain! Wow!");
8959 if (u
.uenmax
< 0) u
.uenmax
= 0;
8960 if (u
.uen
> u
.uenmax
) u
.uen
= u
.uenmax
;
8961 pline("Casting this spell is straining for your maximum mana supply.");
8971 do_clear_areaX(u
.ux
, u
.uy
, 5 + rnd(5), do_watertunnelfloodg
, (void *)&madepoolQ
);
8972 if (madepoolQ
) pline("Flooded tunnels have been built!");
8975 if (u
.uenmax
< 0) u
.uenmax
= 0;
8976 if (u
.uen
> u
.uenmax
) u
.uen
= u
.uenmax
;
8977 pline("Casting this spell is straining for your maximum mana supply.");
8984 case SPE_CRYSTALLIZATION
:
8987 do_clear_areaX(u
.ux
, u
.uy
, 5 + rnd(5), do_crystalwaterfloodg
, (void *)&madepoolQ
);
8988 if (madepoolQ
) pline("There's water on the ceiling!");
8991 if (u
.uenmax
< 0) u
.uenmax
= 0;
8992 if (u
.uen
> u
.uenmax
) u
.uen
= u
.uenmax
;
8993 pline("Casting this spell is straining for your maximum mana supply.");
9003 do_clear_areaX(u
.ux
, u
.uy
, 5 + rnd(5), do_moorfloodg
, (void *)&madepoolQ
);
9004 if (madepoolQ
) pline("The floor becomes swampy.");
9007 if (u
.uenmax
< 0) u
.uenmax
= 0;
9008 if (u
.uen
> u
.uenmax
) u
.uen
= u
.uenmax
;
9009 pline("Casting this spell is straining for your maximum mana supply.");
9019 do_clear_areaX(u
.ux
, u
.uy
, 5 + rnd(5), do_urinefloodg
, (void *)&madepoolQ
);
9020 if (madepoolQ
) pline("Mira does her thing!");
9023 if (u
.uenmax
< 0) u
.uenmax
= 0;
9024 if (u
.uen
> u
.uenmax
) u
.uen
= u
.uenmax
;
9025 pline("Casting this spell is straining for your maximum mana supply.");
9035 do_clear_areaX(u
.ux
, u
.uy
, 5 + rnd(5), do_shiftingsandfloodg
, (void *)&madepoolQ
);
9036 if (madepoolQ
) pline("Deadly sandholes appear!");
9039 if (u
.uenmax
< 0) u
.uenmax
= 0;
9040 if (u
.uen
> u
.uenmax
) u
.uen
= u
.uenmax
;
9041 pline("Casting this spell is straining for your maximum mana supply.");
9051 do_clear_areaX(u
.ux
, u
.uy
, 5 + rnd(5), do_styxfloodg
, (void *)&madepoolQ
);
9052 if (madepoolQ
) pline("You're in the styx!");
9055 if (u
.uenmax
< 0) u
.uenmax
= 0;
9056 if (u
.uen
> u
.uenmax
) u
.uen
= u
.uenmax
;
9057 pline("Casting this spell is straining for your maximum mana supply.");
9067 do_clear_areaX(u
.ux
, u
.uy
, 5 + rnd(5), do_snowfloodg
, (void *)&madepoolQ
);
9068 if (madepoolQ
) pline("Winter is coming!");
9071 if (u
.uenmax
< 0) u
.uenmax
= 0;
9072 if (u
.uen
> u
.uenmax
) u
.uen
= u
.uenmax
;
9073 pline("Casting this spell is straining for your maximum mana supply.");
9083 do_clear_areaX(u
.ux
, u
.uy
, 5 + rnd(5), do_ashfloodg
, (void *)&madepoolQ
);
9084 if (madepoolQ
) pline("Ash terrain appears!");
9087 if (u
.uenmax
< 0) u
.uenmax
= 0;
9088 if (u
.uen
> u
.uenmax
) u
.uen
= u
.uenmax
;
9089 pline("Casting this spell is straining for your maximum mana supply.");
9099 do_clear_areaX(u
.ux
, u
.uy
, 5 + rnd(5), do_sandfloodg
, (void *)&madepoolQ
);
9100 if (madepoolQ
) pline("Sandy deserts!");
9103 if (u
.uenmax
< 0) u
.uenmax
= 0;
9104 if (u
.uen
> u
.uenmax
) u
.uen
= u
.uenmax
;
9105 pline("Casting this spell is straining for your maximum mana supply.");
9115 do_clear_areaX(u
.ux
, u
.uy
, 5 + rnd(5), do_pavementfloodg
, (void *)&madepoolQ
);
9116 if (madepoolQ
) pline("Whoa, there's a paved road!");
9119 if (u
.uenmax
< 0) u
.uenmax
= 0;
9120 if (u
.uen
> u
.uenmax
) u
.uen
= u
.uenmax
;
9121 pline("Casting this spell is straining for your maximum mana supply.");
9131 do_clear_areaX(u
.ux
, u
.uy
, 5 + rnd(5), do_highwayfloodg
, (void *)&madepoolQ
);
9132 if (madepoolQ
) pline("You build a highway to the left!");
9135 if (u
.uenmax
< 0) u
.uenmax
= 0;
9136 if (u
.uen
> u
.uenmax
) u
.uen
= u
.uenmax
;
9137 pline("Casting this spell is straining for your maximum mana supply.");
9147 do_clear_areaX(u
.ux
, u
.uy
, 5 + rnd(5), do_grassfloodg
, (void *)&madepoolQ
);
9148 if (madepoolQ
) pline("Grass is growing!");
9151 if (u
.uenmax
< 0) u
.uenmax
= 0;
9152 if (u
.uen
> u
.uenmax
) u
.uen
= u
.uenmax
;
9153 pline("Casting this spell is straining for your maximum mana supply.");
9160 case SPE_NETHER_MIST
:
9163 do_clear_areaX(u
.ux
, u
.uy
, 5 + rnd(5), do_nethermistfloodg
, (void *)&madepoolQ
);
9164 if (madepoolQ
) pline("Purple mist appears!");
9167 if (u
.uenmax
< 0) u
.uenmax
= 0;
9168 if (u
.uen
> u
.uenmax
) u
.uen
= u
.uenmax
;
9169 pline("Casting this spell is straining for your maximum mana supply.");
9176 case SPE_STALACTITE
:
9179 do_clear_areaX(u
.ux
, u
.uy
, 5 + rnd(5), do_stalactitefloodg
, (void *)&madepoolQ
);
9180 if (madepoolQ
) pline("Stalactites shoot from the ceiling!");
9183 if (u
.uenmax
< 0) u
.uenmax
= 0;
9184 if (u
.uen
> u
.uenmax
) u
.uen
= u
.uenmax
;
9185 pline("Casting this spell is straining for your maximum mana supply.");
9195 do_clear_areaX(u
.ux
, u
.uy
, 5 + rnd(5), do_cryptfloodg
, (void *)&madepoolQ
);
9196 if (madepoolQ
) pline("You entered the crypts!");
9199 if (u
.uenmax
< 0) u
.uenmax
= 0;
9200 if (u
.uen
> u
.uenmax
) u
.uen
= u
.uenmax
;
9201 pline("Casting this spell is straining for your maximum mana supply.");
9208 case SPE_BUBBLE_BOBBLE
:
9211 do_clear_areaX(u
.ux
, u
.uy
, 5 + rnd(5), do_bubblefloodg
, (void *)&madepoolQ
);
9212 if (madepoolQ
) pline("Floating bubbles!");
9215 if (u
.uenmax
< 0) u
.uenmax
= 0;
9216 if (u
.uen
> u
.uenmax
) u
.uen
= u
.uenmax
;
9217 pline("Casting this spell is straining for your maximum mana supply.");
9227 do_clear_areaX(u
.ux
, u
.uy
, 5 + rnd(5), do_raincloudfloodg
, (void *)&madepoolQ
);
9228 if (madepoolQ
) pline("There's rain clouds now!");
9231 if (u
.uenmax
< 0) u
.uenmax
= 0;
9232 if (u
.uen
> u
.uenmax
) u
.uen
= u
.uenmax
;
9233 pline("Casting this spell is straining for your maximum mana supply.");
9240 case SPE_CHAOS_TERRAIN
:
9244 do_clear_areaX(u
.ux
, u
.uy
, 5 + rnd(5), do_terrainfloodg
, (void *)&madepoolQ
);
9245 if (madepoolQ
) pline("Chaotic terrain is generated!");
9248 if (u
.uenmax
< 0) u
.uenmax
= 0;
9249 if (u
.uen
> u
.uenmax
) u
.uen
= u
.uenmax
;
9250 pline("Casting this spell is straining for your maximum mana supply.");
9261 register struct permonst
*ptrZ
;
9266 if (attempts
&& (attempts
% 10000 == 0)) u
.mondiffhack
++;
9268 } while ( (!ptrZ
|| (ptrZ
&& !(attacktype(ptrZ
, AT_EXPL
)))) && attempts
< 50000);
9270 if (ptrZ
&& attacktype(ptrZ
, AT_EXPL
)) {
9272 register struct monst
*bomber
;
9274 /* note by Amy: I can't, for the life of me, remember that converting a permonst to number is done via monsndx.
9275 * Therefore I'm leaving a note here that I can grep for the next 200 times I forget that permonst monster number
9276 * is done via monsndx! And since I STILL keep forgetting it and NOT find it, I'll leave some more breadcrumbs:
9277 * monster index to number is done via the monsndx function
9278 * monster number is done via that monsndx function */
9279 int monnumber
= monsndx(ptrZ
);
9281 bomber
= make_helper(monnumber
, u
.ux
, u
.uy
);
9284 bomber
->isspell
= bomber
->uexp
= TRUE
;
9294 case SPE_ANTI_MAGIC_SHELL
:
9295 pline("You produce an anti-magic shell.");
9296 u
.antimagicshell
+= rnd(100 + (spell_damage_bonus(spellid(spell
)) * 5) );
9297 /* can't cast it with the shell active, so no need to check for that :D --Amy */
9301 case SPE_POSSESSION
:
9303 if (CannotSelectItemsInPrompts
) break;
9304 register struct obj
*poss
;
9306 poss
= getobj((const char *)revivables
, "possess");
9308 if (yn("Really exit with no object selected?") == 'y')
9309 pline("You just wasted the opportunity to possess a corpse.");
9310 else goto possessionchoice
;
9311 pline("Your possession attempt fails.");
9314 if (poss
->otyp
!= CORPSE
) {
9315 pline("That cannot be possessed.");
9318 if (obj_resists(poss
, 0, 50)) {
9319 pline("Your attempt to possess such a powerful monster fails.");
9322 u
.wormpolymorph
= poss
->corpsenm
;
9324 u
.wormpolymorph
= rn2(NUMMONS
);
9325 pline("Your possession attempt goes out of control!");
9327 if (poss
) delobj(poss
);
9330 pline("The raw power goes out of control!");
9333 if (u
.uen
> u
.uenmax
) u
.uen
= u
.uenmax
;
9335 if (!rn2(10)) NastinessProblem
+= rnd(1000);
9344 u
.wormpolymorph
= rn2(NUMMONS
);
9345 } while(( (notake(&mons
[u
.wormpolymorph
]) && rn2(4) ) || ((mons
[u
.wormpolymorph
].mlet
== S_BAT
) && rn2(2)) || ((mons
[u
.wormpolymorph
].mlet
== S_EYE
) && rn2(2) ) || ((mons
[u
.wormpolymorph
].mmove
== 1) && rn2(4) ) || ((mons
[u
.wormpolymorph
].mmove
== 2) && rn2(3) ) || ((mons
[u
.wormpolymorph
].mmove
== 3) && rn2(2) ) || ((mons
[u
.wormpolymorph
].mmove
== 4) && !rn2(3) ) || ( (mons
[u
.wormpolymorph
].mlevel
< 10) && ((mons
[u
.wormpolymorph
].mlevel
+ 1) < rnd(u
.ulevel
)) ) || (!haseyes(&mons
[u
.wormpolymorph
]) && rn2(2) ) || ( is_nonmoving(&mons
[u
.wormpolymorph
]) && rn2(5) ) || ( is_eel(&mons
[u
.wormpolymorph
]) && rn2(5) ) || ( is_nonmoving(&mons
[u
.wormpolymorph
]) && rn2(20) ) || (is_jonadabmonster(&mons
[u
.wormpolymorph
]) && rn2(20)) || ( uncommon2(&mons
[u
.wormpolymorph
]) && !rn2(4) ) || ( uncommon3(&mons
[u
.wormpolymorph
]) && !rn2(3) ) || ( uncommon5(&mons
[u
.wormpolymorph
]) && !rn2(2) ) || ( uncommon7(&mons
[u
.wormpolymorph
]) && rn2(3) ) || ( uncommon10(&mons
[u
.wormpolymorph
]) && rn2(5) ) || ( is_eel(&mons
[u
.wormpolymorph
]) && rn2(20) ) ) );
9347 pline("You feel polyform.");
9350 pline("The magical energy goes out of control!");
9365 if (u
.mtimedone
&& !rn2(2) && Upolyd
&& mons
[u
.umonnum
].mlevel
) {
9366 u
.mtimedone
/= mons
[u
.umonnum
].mlevel
;
9367 if (u
.mtimedone
< 5) u
.mtimedone
= 5;
9372 case SPE_FIRE_GOLEM
:
9374 register struct obj
*golemfuel
;
9375 register struct monst
*firegolem
;
9377 golemfuel
= carrying(TORCH
);
9380 pline("You need a torch to create the golem from!");
9384 if (golemfuel
->lamplit
) { /* we don't want timer-related segfault panics --Amy */
9385 pline("You need a torch that isn't lit! Turn off all lit torches first!");
9390 if (golemfuel
->quan
> 1) {
9392 golemfuel
->owt
= weight(golemfuel
);
9394 else useup(golemfuel
);
9397 firegolem
= make_helper(PM_SUMMONED_FIRE_GOLEM
, u
.ux
, u
.uy
);
9398 if (!firegolem
) break;
9399 firegolem
->mtame
= 5;
9400 firegolem
->isspell
= firegolem
->uexp
= TRUE
;
9406 case SPE_TOTEM_SUMMONING
:
9408 register struct obj
*poss
;
9409 register struct monst
*posmon
;
9411 if (!Upolyd
&& u
.uhp
< 101) {
9412 pline("Totem summoning requires you to have at least 101 HP.");
9416 if (Upolyd
&& u
.mh
< 101) {
9417 pline("Totem summoning requires you to have at least 101 HP.");
9422 if (CannotSelectItemsInPrompts
) break;
9423 poss
= getobj((const char *)revivables
, "revive");
9425 if (yn("Really exit with no object selected?") == 'y')
9426 pline("You just wasted the opportunity to summon from a totem.");
9427 else goto totemsummonchoice
;
9428 pline("Your totem summoning attempt fails.");
9431 if (poss
->otyp
!= CORPSE
) {
9432 pline("That cannot be revived.");
9435 if (obj_resists(poss
, 0, 50)) {
9436 pline("Your attempt to summon such a powerful monster fails.");
9439 posmon
= revive(poss
);
9442 if (Is_blackmarket(&u
.uz
))
9446 make_happy_shk(posmon
, FALSE
);
9447 else if (!resist(posmon
, SPBOOK_CLASS
, 0, NOTELL
))
9448 (void) tamedog(posmon
, (struct obj
*) 0, FALSE
);
9449 else if (((rnd(30 - ACURR(A_CHA
))) < 4) && !resist(posmon
, SPBOOK_CLASS
, 0, NOTELL
))
9450 (void) tamedog(posmon
, (struct obj
*) 0, FALSE
);
9451 else if (((rnd(30 - ACURR(A_CHA
))) < 4) && !resist(posmon
, SPBOOK_CLASS
, 0, NOTELL
))
9452 (void) tamedog(posmon
, (struct obj
*) 0, FALSE
);
9454 if (Upolyd
) u
.mh
-= rnd(100);
9455 else u
.uhp
-= rnd(100);
9458 pline("The summoning power goes out of control!");
9460 create_critters(rnz(10), (struct permonst
*)0);
9461 u
.uenmax
-= rnd(10);
9462 if (u
.uen
> u
.uenmax
) u
.uen
= u
.uenmax
;
9471 You_feel("an anti-sexual aura.");
9473 u
.sterilized
= 10 + (spell_damage_bonus(spellid(spell
)) * 4);
9477 case SPE_DISRUPTION_SHIELD
:
9479 You("activate your mana shield.");
9481 u
.disruptionshield
= 30 + (spell_damage_bonus(spellid(spell
)) * 7);
9485 case SPE_HOLY_SHIELD
:
9487 You("activate your holy shield.");
9489 u
.holyshield
= 20 + (spell_damage_bonus(spellid(spell
)) * 3);
9495 register struct trap
*avaltrap
;
9496 avaltrap
= maketrap(u
.ux
, u
.uy
, COLLAPSE_TRAP
, 0, FALSE
);
9497 if (!avaltrap
) pline("For some reason, the avalanche does not go off!");
9499 if (avaltrap
&& avaltrap
->ttyp
== COLLAPSE_TRAP
) {
9500 dotrap(avaltrap
, 0);
9502 pline("You are severely hurt and unable to move due to being buried!");
9505 if (u
.uhp
> u
.uhpmax
) u
.uhp
= u
.uhpmax
;
9508 killer
= "an avalanche";
9509 killer_format
= KILLED_BY
;
9515 if (u
.mh
> u
.mhmax
) u
.mh
= u
.mhmax
;
9518 killer
= "an avalanche";
9519 killer_format
= KILLED_BY
;
9525 if (u
.uenmax
< 0) u
.uenmax
= 0;
9526 if (u
.uen
> u
.uenmax
) u
.uen
= u
.uenmax
;
9529 if (StrongFree_action
) {
9530 nomul(-(rnz(3)), "buried by an avalanche", TRUE
);
9531 nomovemsg
= "You finally dig yourself out of the debris.";
9532 } else if (Free_action
) {
9533 nomul(-(rnz(5)), "buried by an avalanche", TRUE
);
9534 nomovemsg
= "You finally dig yourself out of the debris.";
9536 nomul(-(rnz(10)), "buried by an avalanche", TRUE
);
9537 nomovemsg
= "You finally dig yourself out of the debris.";
9540 if (StrongFree_action
) {
9541 nomul(-(rnd(3)), "buried by an avalanche", TRUE
);
9542 nomovemsg
= "You finally dig yourself out of the debris.";
9543 } else if (Free_action
) {
9544 nomul(-(rnd(5)), "buried by an avalanche", TRUE
);
9545 nomovemsg
= "You finally dig yourself out of the debris.";
9547 nomul(-(rnd(10)), "buried by an avalanche", TRUE
);
9548 nomovemsg
= "You finally dig yourself out of the debris.";
9557 case SPE_DEMEMORIZE
:
9559 if (spellid(0) == NO_SPELL
) { /* should never happen, but I put it here just in case --Amy */
9560 You("don't know any spells, and therefore you cannot dememorize them either.");
9564 pline("Choose a spell to dememorize.");
9566 if (!dememorizespell()) {
9567 if (yn("Really exit with no spell selected?") == 'y')
9568 pline("You just wasted the opportunity to dememorize a spell.");
9569 else goto dememostart
;
9574 case SPE_INERTIA_CONTROL
:
9576 if (spellid(0) == NO_SPELL
) {
9577 You("don't know any spells, and therefore inertia control fails.");
9581 pline("Choose a spell to control.");
9583 if (!inertiacontrolspell()) {
9584 if (yn("Really exit with no spell selected?") == 'y')
9585 pline("You just wasted the opportunity to control a spell.");
9586 else goto controlagain
;
9591 case SPE_SPELLBINDER
:
9593 if (u
.spellbinder
) {
9594 pline("Spellbinder can't be used to bind itself.");
9599 register int spellbindings
= 2;
9601 if (!(PlayerCannotUseSkills
) && P_SKILL(P_OCCULT_SPELL
) >= P_SKILLED
) {
9603 switch (P_SKILL(P_OCCULT_SPELL
)) {
9604 case P_SKILLED
: spellbindings
= 3; break;
9605 case P_EXPERT
: spellbindings
= 4; break;
9606 case P_MASTER
: spellbindings
= 5; break;
9607 case P_GRAND_MASTER
: spellbindings
= 6; break;
9608 case P_SUPREME_MASTER
: spellbindings
= 7; break;
9614 u
.spellbinder
= spellbindings
;
9615 u
.spellbinder1
= -1;
9616 u
.spellbinder2
= -1;
9617 u
.spellbinder3
= -1;
9618 u
.spellbinder4
= -1;
9619 u
.spellbinder5
= -1;
9620 u
.spellbinder6
= -1;
9621 u
.spellbinder7
= -1;
9623 pline("You may cast %d more spells.", u
.spellbinder
);
9625 while (u
.spellbinder
) {
9637 register struct monst
*nexusmon
;
9638 boolean teleportdone
= FALSE
;
9640 if ((level
.flags
.noteleport
|| Race_if(PM_STABILISATOR
) || u
.antitelespelltimeout
) && !Race_if(PM_RODNEYAN
) ) {
9641 pline("A mysterious force prevents you from teleporting!");
9645 if ( ( (u
.uhave
.amulet
&& !u
.freeplaymode
&& (u
.amuletcompletelyimbued
|| !rn2(3))) || CannotTeleport
|| On_W_tower_level(&u
.uz
) || (u
.usteed
&& mon_has_amulet(u
.usteed
)) ) ) {
9646 You_feel("disoriented for a moment.");
9650 for(nexusmon
= fmon
; nexusmon
; nexusmon
= nexusmon
->nmon
) {
9651 if (nexusmon
) break;
9655 pline("No valid target for tracking. Sorry.");
9661 for(i
= -bd
; i
<= bd
; i
++) for(j
= -bd
; j
<= bd
; j
++) {
9662 if (!isok(nexusmon
->mx
+ i
, nexusmon
->my
+ j
)) continue;
9664 if (teleok(nexusmon
->mx
+ i
, nexusmon
->my
+ j
, FALSE
)) {
9665 teleportdone
= TRUE
;
9666 teleds(nexusmon
->mx
+ i
, nexusmon
->my
+ j
, FALSE
);
9668 pline("The spell backlashes!");
9674 if (!teleportdone
) pline("Tracking target is unreachable. Sorry.");
9682 pline("You sacrifice some of your %s and become able to eat through solid rock.", body_part(BLOOD
));
9684 if (u
.uhp
> u
.uhpmax
) u
.uhp
= u
.uhpmax
;
9687 killer
= "invoking geolysis with too little health";
9688 killer_format
= KILLED_BY
;
9694 if (u
.mh
> u
.mhmax
) u
.mh
= u
.mhmax
;
9697 /* re-casting it will restart the countdown rather than add to the duration --Amy */
9698 u
.geolysis
= 15 + (spell_damage_bonus(spellid(spell
)) * 5);
9702 case SPE_DRIPPING_TREAD
:
9704 pline("You sacrifice some of your %s and start dripping elements.", body_part(BLOOD
));
9706 if (u
.uhp
> u
.uhpmax
) u
.uhp
= u
.uhpmax
;
9709 killer
= "dripping the elements with too little health";
9710 killer_format
= KILLED_BY
;
9716 if (u
.mh
> u
.mhmax
) u
.mh
= u
.mhmax
;
9718 u
.drippingtreadtype
= rnd(4);
9719 /* 1 = water, 2 = lava, 3 = ice, 4 = clouds */
9721 if (!(PlayerCannotUseSkills
) && P_SKILL(P_ELEMENTAL_SPELL
) >= P_SKILLED
) {
9722 pline("Choose a terrain type to generate. You can create water, lava, ice or clouds.");
9723 if (yn("Generate water?") == 'y') {
9724 u
.drippingtreadtype
= 1;
9726 else if (yn("Generate lava?") == 'y') {
9727 u
.drippingtreadtype
= 2;
9729 else if (yn("Generate ice?") == 'y') {
9730 u
.drippingtreadtype
= 3;
9733 u
.drippingtreadtype
= 4;
9738 if (u
.drippingtreadtype
== 1) pline("Generating water.");
9739 if (u
.drippingtreadtype
== 2) pline("Generating lava.");
9740 if (u
.drippingtreadtype
== 3) pline("Generating ice.");
9741 if (u
.drippingtreadtype
== 4) pline("Generating clouds.");
9743 /* re-casting it will restart the countdown rather than add to the duration --Amy */
9744 u
.drippingtread
= 20 + (spell_damage_bonus(spellid(spell
)) * 3);
9748 case SPE_POISON_BRAND
:
9751 pline("You are not holding a weapon!");
9754 if (uwep
&& !is_poisonable(uwep
)) {
9755 pline("Your weapon cannot be poisoned!");
9759 if (!stack_too_big(uwep
)) {
9760 uwep
->opoisoned
= TRUE
;
9761 pline("Your weapon was poisoned.");
9762 } else pline("Unfortunately your wielded stack of weapons was too big, and so the poisoning failed.");
9764 pline("The poison spills over you!");
9766 if (!rn2(StrongPoison_resistance
? 10 : Poison_resistance
? 5 : 3)) {
9767 int typ
= rn2(A_MAX
);
9769 (void) adjattrib(typ
, Poison_resistance
? -1 : -rno(5), TRUE
, TRUE
);
9771 if (!Poison_resistance
) {
9772 losehp(rnd(10), "poisoning a weapon", KILLED_BY
);
9779 case SPE_STEAM_VENOM
:
9782 pline_The("water around you vaporizes violently!");
9784 pline_The("air around you explodes in a cloud of noxious gas!");
9786 explode(u
.ux
, u
.uy
, ZT_SPELL(ZT_POISON_GAS
), 24 + (spell_damage_bonus(spellid(spell
)) * 2), SCROLL_CLASS
, EXPL_NOXIOUS
);
9790 case SPE_CREATE_FAMILIAR
:
9791 u
.lamefarmer
= TRUE
;
9792 if (!rn2(5)) (void) make_familiar((struct obj
*)0, u
.ux
, u
.uy
, FALSE
, FALSE
);
9794 pline("The summoned monster does not seem to be friendly!");
9795 (void) makemon((struct permonst
*)0, u
.ux
, u
.uy
, MM_NOSPECIALS
);
9796 } else if (rn2(4)) {
9797 pline("The spell fizzled out!");
9799 pline("The spell backfired!");
9805 case SPE_CLAIRVOYANCE
:
9808 /* at present, only one thing blocks clairvoyance */
9809 else if (uarmh
&& uarmh
->otyp
== CORNUTHAUM
)
9810 You("sense a pointy hat on top of your %s.",
9813 case SPE_PROTECTION
:
9817 case SPE_FORCIBLE_MOVE
:
9820 pline("%s", nothing_happens
);
9821 if (FailureEffects
|| u
.uprops
[FAILURE_EFFECTS
].extrinsic
|| have_failurestone()) {
9822 pline("Oh wait, actually something bad happens...");
9830 if (!jump(max(role_skill
,1))) {
9831 pline("%s", nothing_happens
);
9832 if (FailureEffects
|| u
.uprops
[FAILURE_EFFECTS
].extrinsic
|| have_failurestone()) {
9833 pline("Oh wait, actually something bad happens...");
9839 case SPE_LOOT_IMPROVEMENT
:
9840 if(!(HMagicFindBonus
& INTRINSIC
)) {
9841 You_feel("able to find magical items!");
9842 incr_itimeout(&HMagicFindBonus
, HMagicFindBonus
? rnd(5) : (10 + spell_damage_bonus(spellid(spell
))) );
9844 pline("%s", nothing_happens
); /* Already have as intrinsic */
9845 if (FailureEffects
|| u
.uprops
[FAILURE_EFFECTS
].extrinsic
|| have_failurestone()) {
9846 pline("Oh wait, actually something bad happens...");
9852 case SPE_MYSTERY_PROTECTION
:
9853 if(!(HMysteryResist
& INTRINSIC
)) {
9854 You_feel("protected from mysterious magic.");
9855 incr_itimeout(&HMysteryResist
, HMysteryResist
? (rnd(3) + spell_damage_bonus(spellid(spell
))) : (rn1(33, 15) + spell_damage_bonus(spellid(spell
))*3));
9857 pline("%s", nothing_happens
); /* Already have as intrinsic */
9858 if (FailureEffects
|| u
.uprops
[FAILURE_EFFECTS
].extrinsic
|| have_failurestone()) {
9859 pline("Oh wait, actually something bad happens...");
9865 case SPE_RESIST_POISON
:
9866 if(!(HPoison_resistance
& INTRINSIC
)) {
9867 You_feel("healthy ..... for the moment at least.");
9868 incr_itimeout(&HPoison_resistance
, HPoison_resistance
? (rnd(10) + spell_damage_bonus(spellid(spell
))) : (rn1(100, 50) + spell_damage_bonus(spellid(spell
))*10));
9870 pline("%s", nothing_happens
); /* Already have as intrinsic */
9871 if (FailureEffects
|| u
.uprops
[FAILURE_EFFECTS
].extrinsic
|| have_failurestone()) {
9872 pline("Oh wait, actually something bad happens...");
9877 case SPE_ANTI_DISINTEGRATION
:
9878 if(!(HDisint_resistance
& INTRINSIC
)) {
9879 You_feel("quite firm for a while.");
9880 incr_itimeout(&HDisint_resistance
, HDisint_resistance
? (rnd(10) + spell_damage_bonus(spellid(spell
))) : (rn1(100, 50) + spell_damage_bonus(spellid(spell
))*10));
9882 pline("%s", nothing_happens
); /* Already have as intrinsic */
9883 if (FailureEffects
|| u
.uprops
[FAILURE_EFFECTS
].extrinsic
|| have_failurestone()) {
9884 pline("Oh wait, actually something bad happens...");
9889 case SPE_MAGICTORCH
:
9890 if(!(HSight_bonus
& INTRINSIC
)) {
9891 You("can see in the dark!");
9892 incr_itimeout(&HSight_bonus
, rn1(20, 10) + spell_damage_bonus(spellid(spell
))*20);
9894 pline("%s", nothing_happens
); /* Already have as intrinsic */
9895 if (FailureEffects
|| u
.uprops
[FAILURE_EFFECTS
].extrinsic
|| have_failurestone()) {
9896 pline("Oh wait, actually something bad happens...");
9901 case SPE_DISPLACEMENT
:
9902 if(!(HDisplaced
& INTRINSIC
)) {
9903 pline("Your image is displaced!");
9904 incr_itimeout(&HDisplaced
, HDisplaced
? (rnd(5) + spell_damage_bonus(spellid(spell
))) : (rn1(200, 100) + spell_damage_bonus(spellid(spell
))*20));
9906 pline("%s", nothing_happens
); /* Already have as intrinsic */
9907 if (FailureEffects
|| u
.uprops
[FAILURE_EFFECTS
].extrinsic
|| have_failurestone()) {
9908 pline("Oh wait, actually something bad happens...");
9913 case SPE_TRUE_SIGHT
:
9914 if(!(HSee_invisible
& INTRINSIC
)) {
9915 pline("You can see invisible things!");
9916 incr_itimeout(&HSee_invisible
, HSee_invisible
? (rnd(5) + spell_damage_bonus(spellid(spell
))) : (rn1(50, 25) + spell_damage_bonus(spellid(spell
))*5));
9918 pline("%s", nothing_happens
); /* Already have as intrinsic */
9919 if (FailureEffects
|| u
.uprops
[FAILURE_EFFECTS
].extrinsic
|| have_failurestone()) {
9920 pline("Oh wait, actually something bad happens...");
9926 if(!(HConflict
& INTRINSIC
)) {
9927 pline("You start generating conflict!");
9928 incr_itimeout(&HConflict
, HConflict
? (rnd(5) + spell_damage_bonus(spellid(spell
))) : (rn1(20, 10) + spell_damage_bonus(spellid(spell
))*3));
9930 pline("%s", nothing_happens
); /* Already have as intrinsic */
9931 if (FailureEffects
|| u
.uprops
[FAILURE_EFFECTS
].extrinsic
|| have_failurestone()) {
9932 pline("Oh wait, actually something bad happens...");
9938 if(!(HTelepat
& INTRINSIC
)) {
9939 You_feel("a strange mental acuity.");
9940 incr_itimeout(&HTelepat
, HTelepat
? (rnd(5) + spell_damage_bonus(spellid(spell
))) : (rn1(100, 50) + spell_damage_bonus(spellid(spell
))*10));
9942 pline("%s", nothing_happens
); /* Already have as intrinsic */
9943 if (FailureEffects
|| u
.uprops
[FAILURE_EFFECTS
].extrinsic
|| have_failurestone()) {
9944 pline("Oh wait, actually something bad happens...");
9950 if(!(HWarning
& INTRINSIC
)) {
9951 pline("You turn on your radar.");
9952 incr_itimeout(&HWarning
, HWarning
? (rnd(5) + spell_damage_bonus(spellid(spell
))) : (rn1(100, 50) + spell_damage_bonus(spellid(spell
))*10));
9954 pline("%s", nothing_happens
); /* Already have as intrinsic */
9955 if (FailureEffects
|| u
.uprops
[FAILURE_EFFECTS
].extrinsic
|| have_failurestone()) {
9956 pline("Oh wait, actually something bad happens...");
9961 case SPE_REGENERATION
:
9962 if(!(HRegeneration
& INTRINSIC
)) {
9963 pline("You direct your internal energy to closing your wounds.");
9964 incr_itimeout(&HRegeneration
, HRegeneration
? (rnd(5) + spell_damage_bonus(spellid(spell
))) : (rn1(100, 50) + spell_damage_bonus(spellid(spell
))*10));
9966 pline("%s", nothing_happens
); /* Already have as intrinsic */
9967 if (FailureEffects
|| u
.uprops
[FAILURE_EFFECTS
].extrinsic
|| have_failurestone()) {
9968 pline("Oh wait, actually something bad happens...");
9974 if(!(HSearching
& INTRINSIC
)) {
9975 pline("You start searching.");
9976 incr_itimeout(&HSearching
, HSearching
? (rnd(5) + spell_damage_bonus(spellid(spell
))) : (rn1(100, 50) + spell_damage_bonus(spellid(spell
))*10));
9978 pline("%s", nothing_happens
); /* Already have as intrinsic */
9979 if (FailureEffects
|| u
.uprops
[FAILURE_EFFECTS
].extrinsic
|| have_failurestone()) {
9980 pline("Oh wait, actually something bad happens...");
9985 case SPE_FREE_ACTION
:
9986 if(!(HFree_action
& INTRINSIC
)) {
9987 pline("You are resistant to paralysis.");
9988 incr_itimeout(&HFree_action
, HFree_action
? (rnd(5) + spell_damage_bonus(spellid(spell
))) : (rn1(100, 50) + spell_damage_bonus(spellid(spell
))*10));
9990 pline("%s", nothing_happens
); /* Already have as intrinsic */
9991 if (FailureEffects
|| u
.uprops
[FAILURE_EFFECTS
].extrinsic
|| have_failurestone()) {
9992 pline("Oh wait, actually something bad happens...");
9998 if(!(HStealth
& INTRINSIC
)) {
9999 pline("You start moving silently.");
10000 incr_itimeout(&HStealth
, HStealth
? (rnd(5) + spell_damage_bonus(spellid(spell
))) : (rn1(100, 50) + spell_damage_bonus(spellid(spell
))*10));
10002 pline("%s", nothing_happens
); /* Already have as intrinsic */
10003 if (FailureEffects
|| u
.uprops
[FAILURE_EFFECTS
].extrinsic
|| have_failurestone()) {
10004 pline("Oh wait, actually something bad happens...");
10009 case SPE_INFRAVISION
:
10010 if(!(HInfravision
& INTRINSIC
)) {
10011 pline("Your %s are suddenly very sensitive!", makeplural(body_part(EYE
)));
10012 incr_itimeout(&HInfravision
, HInfravision
? (rnd(5) + spell_damage_bonus(spellid(spell
))) : (rn1(100, 50) + spell_damage_bonus(spellid(spell
))*10));
10014 pline("%s", nothing_happens
); /* Already have as intrinsic */
10015 if (FailureEffects
|| u
.uprops
[FAILURE_EFFECTS
].extrinsic
|| have_failurestone()) {
10016 pline("Oh wait, actually something bad happens...");
10021 case SPE_COAGULATION
:
10022 if(!(HDiminishedBleeding
& INTRINSIC
)) {
10023 pline("Your %s is boiling!", body_part(BLOOD
));
10024 incr_itimeout(&HDiminishedBleeding
, HDiminishedBleeding
? (rnd(5) + spell_damage_bonus(spellid(spell
))) : (rn1(100, 50) + spell_damage_bonus(spellid(spell
))*10));
10026 pline("%s", nothing_happens
); /* Already have as intrinsic */
10027 if (FailureEffects
|| u
.uprops
[FAILURE_EFFECTS
].extrinsic
|| have_failurestone()) {
10028 pline("Oh wait, actually something bad happens...");
10033 case SPE_CURE_PARALYSIS
:
10036 TimeStopped
= 0; /* filthy exploit exploiter */
10037 You("magically regain consciousness!");
10038 } else You("weren't paralyzed to begin with, so there was nothing to cure.");
10040 case SPE_SMELL_MONSTER
:
10041 if(!(HScentView
& INTRINSIC
)) {
10042 pline("Your %s is suddenly very sensitive!", body_part(NOSE
));
10043 incr_itimeout(&HScentView
, HScentView
? (rnd(5) + spell_damage_bonus(spellid(spell
))) : (rn1(100, 50) + spell_damage_bonus(spellid(spell
))*10));
10045 pline("%s", nothing_happens
); /* Already have as intrinsic */
10046 if (FailureEffects
|| u
.uprops
[FAILURE_EFFECTS
].extrinsic
|| have_failurestone()) {
10047 pline("Oh wait, actually something bad happens...");
10052 case SPE_ECHOLOCATION
:
10053 pline("Your ears are suddenly very sensitive!");
10054 if (u
.echolocationspell
) u
.echolocationspell
+= (rnd(5) + spell_damage_bonus(spellid(spell
)));
10055 else u
.echolocationspell
+= (rn1(100, 50) + spell_damage_bonus(spellid(spell
))*10);
10057 case SPE_BOTOX_RESIST
:
10058 if(!(HSick_resistance
& INTRINSIC
)) {
10059 You_feel("resistant to sickness.");
10060 incr_itimeout(&HSick_resistance
, HSick_resistance
? (rnd(10) + spell_damage_bonus(spellid(spell
))) : (rn1(100, 50) + spell_damage_bonus(spellid(spell
))*10));
10062 pline("%s", nothing_happens
); /* Already have as intrinsic */
10063 if (FailureEffects
|| u
.uprops
[FAILURE_EFFECTS
].extrinsic
|| have_failurestone()) {
10064 pline("Oh wait, actually something bad happens...");
10069 case SPE_DRAGON_BLOOD
:
10070 if(!(HDrain_resistance
& INTRINSIC
)) {
10071 You_feel("resistant to level drainage.");
10072 incr_itimeout(&HDrain_resistance
, HDrain_resistance
? (rnd(10) + spell_damage_bonus(spellid(spell
))) : (rn1(100, 50) + spell_damage_bonus(spellid(spell
))*10));
10074 pline("%s", nothing_happens
); /* Already have as intrinsic */
10075 if (FailureEffects
|| u
.uprops
[FAILURE_EFFECTS
].extrinsic
|| have_failurestone()) {
10076 pline("Oh wait, actually something bad happens...");
10081 case SPE_ANTI_MAGIC_FIELD
:
10082 if(!(HAntimagic
& INTRINSIC
)) {
10083 You_feel("resistant to magic.");
10084 incr_itimeout(&HAntimagic
, HAntimagic
? (rnd(10) + spell_damage_bonus(spellid(spell
))) : (rn1(100, 50) + spell_damage_bonus(spellid(spell
))*10));
10086 pline("%s", nothing_happens
); /* Already have as intrinsic */
10087 if (FailureEffects
|| u
.uprops
[FAILURE_EFFECTS
].extrinsic
|| have_failurestone()) {
10088 pline("Oh wait, actually something bad happens...");
10094 case SPE_NO_EFFECT
:
10096 pline("%s", nothing_happens
);
10097 if (FailureEffects
|| u
.uprops
[FAILURE_EFFECTS
].extrinsic
|| have_failurestone()) {
10098 pline("Oh wait, actually something bad happens...");
10104 case SPE_CURE_WOUNDED_LEGS
:
10106 if (Wounded_legs
) pline("A warm glow spreads through your %s!", makeplural(body_part(LEG
)));
10108 if (HWounded_legs
> 0) {
10109 HWounded_legs
-= rn1(20, 20);
10110 if (HWounded_legs
< 0) HWounded_legs
= 0; /* fail safe */
10115 case SPE_CURE_GLIB
:
10118 pline("You clean your %s.", makeplural(body_part(HAND
)));
10119 if (Glib
> (rn1(Role_if(PM_HEALER
) ? 200 : 100, 20))) {
10120 int effreduction
= rnd(Glib
/ 2);
10121 if (effreduction
> 0) {
10122 Glib
-= effreduction
;
10123 Your("glib counter is reduced.");
10125 if (!Role_if(PM_HEALER
) && !rn2(500)) {
10126 pline("The spell backlashes!");
10140 case 1: pline("You put the knife to your lower %s and cut...", body_part(ARM
)); break;
10141 case 2: pline("You use a sharp object to cut open your belly..."); break;
10142 case 3: pline("You slide your body along a rough surface and sustain terrible skin rashes."); break;
10143 case 4: pline("You rip your butt open with a metallic edge."); break;
10144 case 5: pline("You scratch up and down your %s with a sexy leather pump until it starts bleeding.", body_part(LEG
)); break;
10145 case 6: pline("You slit your %s full length with a sharp-edged zipper.", body_part(LEG
)); break;
10146 case 7: pline("You prick yourself with a needle."); break;
10149 if (!rn2(20)) losehp(d(10,8), "cutting", KILLED_BY
);
10150 else if (!rn2(5)) losehp(d(6,8), "cutting", KILLED_BY
);
10151 else losehp(d(4,6), "cutting", KILLED_BY
);
10155 case SPE_UNLEVITATE
:
10157 if (Levitation
) pline("You try to unlevitate.");
10158 ELevitation
&= ~W_ARTI
;
10159 HLevitation
&= ~(I_SPECIAL
|TIMEOUT
);
10163 case SPE_WORLD_FALL
:
10165 You("scream \"EYGOORTS-TOGAAL, JEZEHH!\"");
10168 register struct monst
*wfm
, *wfm2
;
10170 int wflvl
= (u
.ulevel
/ 2);
10171 if (wflvl
< 1) wflvl
= 1;
10173 for (wfm
= fmon
; wfm
; wfm
= wfm2
) {
10175 if ( ((wfm
->m_lev
< wflvl
) || (!rn2(4) && wfm
->m_lev
< (2 * wflvl
))) && wfm
->mnum
!= quest_info(MS_NEMESIS
) && !(wfm
->data
->geno
& G_UNIQ
) ) {
10180 pline("Eliminated %d monster%s.", num
, plur(num
));
10183 pline("Casting such a powerful spell taxes your maximum health, and also causes massive backlash...");
10185 u
.uhpmax
-= rnd(25);
10186 if (u
.uhp
> u
.uhpmax
) u
.uhp
= u
.uhpmax
;
10189 killer
= "invoking world fall with too little health";
10190 killer_format
= KILLED_BY
;
10195 u
.mhmax
-= rnd(25);
10196 if (u
.mh
> u
.mhmax
) u
.mh
= u
.mhmax
;
10206 NastinessProblem
+= rnz(1000 * (monster_difficulty() + 1));
10212 if (role_skill
>= P_SUPREME_MASTER
) n
= 13;
10213 else if (role_skill
>= P_GRAND_MASTER
) n
= 15;
10214 else if (role_skill
>= P_MASTER
) n
= 16;
10215 else if (role_skill
>= P_EXPERT
) n
= 18;
10216 else if (role_skill
>= P_SKILLED
) n
= 20;
10217 else if (role_skill
>= P_BASIC
) n
= 22;
10218 else n
= 25; /* Unskilled or restricted */
10220 do_genocide(1); /* REALLY, see do_genocide() */
10222 Your("genocide failed!");
10225 case SPE_GAIN_LEVEL
:
10227 if (role_skill
>= P_SUPREME_MASTER
) n
= 38;
10228 else if (role_skill
>= P_GRAND_MASTER
) n
= 40;
10229 else if (role_skill
>= P_MASTER
) n
= 42;
10230 else if (role_skill
>= P_EXPERT
) n
= 44;
10231 else if (role_skill
>= P_SKILLED
) n
= 46;
10232 else if (role_skill
>= P_BASIC
) n
= 48;
10233 else n
= 50; /* Unskilled or restricted */
10236 u
.usanity
+= rnz(1000); /* doesn't give bad effects --Amy */
10239 pline("Too bad - it didn't work!");
10242 case SPE_DETECT_WATER
:
10248 case SPE_SATISFY_HUNGER
:
10250 pline("Your stomach is filled a bit.");
10261 case SPE_MAP_LEVEL
:
10263 if (level
.flags
.nommap
) {
10265 pline("Whoops, something blocks the spell's power and causes it to backfire.");
10271 if (role_skill
>= P_SUPREME_MASTER
) n
= 4;
10272 else if (role_skill
>= P_GRAND_MASTER
) n
= 5;
10273 else if (role_skill
>= P_MASTER
) n
= 7;
10274 else if (role_skill
>= P_EXPERT
) n
= 9;
10275 else if (role_skill
>= P_SKILLED
) n
= 11;
10276 else if (role_skill
>= P_BASIC
) n
= 13;
10277 else n
= 15; /* Unskilled or restricted */
10280 long save_Hconf
= HConfusion
,
10281 save_Hhallu
= HHallucination
;
10283 HConfusion
= HHallucination
= 0L;
10284 for (t
= ftrap
; t
!= 0; t
= t
->ntrap
) {
10285 if (!rn2(2)) continue;
10286 /* easier trap difficulty check compared to other detection methods because map level is powerful --Amy */
10287 if (!t
->hiddentrap
&& (t
->trapdiff
< rnd(150)) ) t
->tseen
= 1;
10291 HConfusion
= save_Hconf
;
10292 HHallucination
= save_Hhallu
;
10293 You_feel("knowledgable!");
10294 object_detect(pseudo
, 0);
10297 pline("The spell backlashes!");
10302 pline("The map refuses to reveal its secrets.");
10306 if (rn2(3)) incr_itimeout(&Invulnerable
, rnd(5) );
10307 else incr_itimeout(&Invulnerable
, rnd(5 + spell_damage_bonus(spellid(spell
)) ) );
10308 You_feel("invincible!");
10310 case SPE_ACIDSHIELD
:
10311 if(!(HAcid_resistance
& INTRINSIC
)) {
10312 You("are resistant to acid now. Your items, however, are not.");
10313 incr_itimeout(&HAcid_resistance
, HAcid_resistance
? (rnd(10) + spell_damage_bonus(spellid(spell
))) : (rn1(100, 50) + spell_damage_bonus(spellid(spell
))*10));
10315 pline("%s", nothing_happens
); /* Already have as intrinsic */
10316 if (FailureEffects
|| u
.uprops
[FAILURE_EFFECTS
].extrinsic
|| have_failurestone()) {
10317 pline("Oh wait, actually something bad happens...");
10322 case SPE_RESIST_PETRIFICATION
:
10323 if(!(HStone_resistance
& INTRINSIC
)) {
10324 You_feel("more limber. Let's eat some cockatrice meat!");
10325 incr_itimeout(&HStone_resistance
, HStone_resistance
? (rnd(5) + spell_damage_bonus(spellid(spell
))) : (rn1(40, 20) + spell_damage_bonus(spellid(spell
))*4));
10327 pline("%s", nothing_happens
); /* Already have as intrinsic */
10328 if (FailureEffects
|| u
.uprops
[FAILURE_EFFECTS
].extrinsic
|| have_failurestone()) {
10329 pline("Oh wait, actually something bad happens...");
10334 case SPE_RESIST_SLEEP
:
10335 if(!(HSleep_resistance
& INTRINSIC
)) {
10337 pline("Too much coffee!");
10339 You("no longer feel tired.");
10340 incr_itimeout(&HSleep_resistance
, HSleep_resistance
? (rnd(10) + spell_damage_bonus(spellid(spell
))) : (rn1(100, 50) + spell_damage_bonus(spellid(spell
))*10));
10342 pline("%s", nothing_happens
); /* Already have as intrinsic */
10343 if (FailureEffects
|| u
.uprops
[FAILURE_EFFECTS
].extrinsic
|| have_failurestone()) {
10344 pline("Oh wait, actually something bad happens...");
10350 if(!(HFlying
& INTRINSIC
)) {
10351 You("start flying!");
10352 incr_itimeout(&HFlying
, HFlying
? (rnd(4) + spell_damage_bonus(spellid(spell
))) : (rn1(20, 25) + spell_damage_bonus(spellid(spell
))*20));
10354 pline("%s", nothing_happens
); /* Already have as intrinsic */
10355 if (FailureEffects
|| u
.uprops
[FAILURE_EFFECTS
].extrinsic
|| have_failurestone()) {
10356 pline("Oh wait, actually something bad happens...");
10361 case SPE_ENDURE_COLD
:
10362 if(!(HCold_resistance
& INTRINSIC
)) {
10363 You_feel("warmer.");
10364 incr_itimeout(&HCold_resistance
, HCold_resistance
? (rnd(10) + spell_damage_bonus(spellid(spell
))) : (rn1(100, 50) + spell_damage_bonus(spellid(spell
))*10));
10366 pline("%s", nothing_happens
); /* Already have as intrinsic */
10367 if (FailureEffects
|| u
.uprops
[FAILURE_EFFECTS
].extrinsic
|| have_failurestone()) {
10368 pline("Oh wait, actually something bad happens...");
10373 case SPE_RESIST_STUN
:
10374 if(!(HStun_resist
& INTRINSIC
)) {
10375 You_feel("resistant to stun.");
10376 incr_itimeout(&HStun_resist
, HStun_resist
? (rnd(10) + spell_damage_bonus(spellid(spell
))) : (rn1(100, 50) + spell_damage_bonus(spellid(spell
))*10));
10378 pline("%s", nothing_happens
); /* Already have as intrinsic */
10379 if (FailureEffects
|| u
.uprops
[FAILURE_EFFECTS
].extrinsic
|| have_failurestone()) {
10380 pline("Oh wait, actually something bad happens...");
10385 case SPE_RESIST_CONFUSION
:
10386 if(!(HConf_resist
& INTRINSIC
)) {
10387 You_feel("resistant to confusion.");
10388 incr_itimeout(&HConf_resist
, HConf_resist
? (rnd(10) + spell_damage_bonus(spellid(spell
))) : (rn1(100, 50) + spell_damage_bonus(spellid(spell
))*10));
10390 pline("%s", nothing_happens
); /* Already have as intrinsic */
10391 if (FailureEffects
|| u
.uprops
[FAILURE_EFFECTS
].extrinsic
|| have_failurestone()) {
10392 pline("Oh wait, actually something bad happens...");
10397 case SPE_RESIST_CONTAMINATION
:
10398 if(!(HCont_resist
& INTRINSIC
)) {
10399 You_feel("resistant to contamination.");
10400 incr_itimeout(&HCont_resist
, HCont_resist
? (rnd(10) + spell_damage_bonus(spellid(spell
))) : (rn1(100, 50) + spell_damage_bonus(spellid(spell
))*10));
10402 pline("%s", nothing_happens
); /* Already have as intrinsic */
10403 if (FailureEffects
|| u
.uprops
[FAILURE_EFFECTS
].extrinsic
|| have_failurestone()) {
10404 pline("Oh wait, actually something bad happens...");
10409 case SPE_ENDURE_HEAT
:
10410 if(!(HFire_resistance
& INTRINSIC
)) {
10412 pline("Excellent! You feel, like, totally cool!");
10414 You_feel("colder.");
10415 incr_itimeout(&HFire_resistance
, HFire_resistance
? (rnd(10) + spell_damage_bonus(spellid(spell
))) : (rn1(100, 50) + spell_damage_bonus(spellid(spell
))*10));
10417 pline("%s", nothing_happens
); /* Already have as intrinsic */
10418 if (FailureEffects
|| u
.uprops
[FAILURE_EFFECTS
].extrinsic
|| have_failurestone()) {
10419 pline("Oh wait, actually something bad happens...");
10425 if(!(HShock_resistance
& INTRINSIC
)) {
10427 pline("Bummer! You've been grounded!");
10429 You("are not at all shocked by this feeling.");
10430 incr_itimeout(&HShock_resistance
, HShock_resistance
? (rnd(10) + spell_damage_bonus(spellid(spell
))) : (rn1(100, 50) + spell_damage_bonus(spellid(spell
))*10));
10432 pline("%s", nothing_happens
); /* Already have as intrinsic */
10433 if (FailureEffects
|| u
.uprops
[FAILURE_EFFECTS
].extrinsic
|| have_failurestone()) {
10434 pline("Oh wait, actually something bad happens...");
10441 if(!(HMagical_breathing
& INTRINSIC
)) {
10442 You("hold your breath.");
10443 incr_itimeout(&HMagical_breathing
, HMagical_breathing
? (rnd(5) + spell_damage_bonus(spellid(spell
))) : (rn1(40, 20) + spell_damage_bonus(spellid(spell
))*10));
10445 pline("%s", nothing_happens
); /* Already have as intrinsic */
10446 if (FailureEffects
|| u
.uprops
[FAILURE_EFFECTS
].extrinsic
|| have_failurestone()) {
10447 pline("Oh wait, actually something bad happens...");
10454 if(!(HSwimming
& INTRINSIC
)) {
10455 You("grow water wings.");
10456 incr_itimeout(&HSwimming
, HSwimming
? (rnd(10) + spell_damage_bonus(spellid(spell
))) : (rn1(100, 50) + spell_damage_bonus(spellid(spell
))*10));
10458 pline("%s", nothing_happens
); /* Already have as intrinsic */
10459 if (FailureEffects
|| u
.uprops
[FAILURE_EFFECTS
].extrinsic
|| have_failurestone()) {
10460 pline("Oh wait, actually something bad happens...");
10466 case SPE_RESIST_RANDOM_ELEMENT
:
10469 if(!(HShock_resistance
& INTRINSIC
)) {
10471 pline("Bummer! You've been grounded!");
10473 You("are not at all shocked by this feeling.");
10474 incr_itimeout(&HShock_resistance
, HShock_resistance
? (rnd(10) + spell_damage_bonus(spellid(spell
))) : (rn1(100, 50) + spell_damage_bonus(spellid(spell
))*10));
10476 pline("%s", nothing_happens
); /* Already have as intrinsic */
10477 if (FailureEffects
|| u
.uprops
[FAILURE_EFFECTS
].extrinsic
|| have_failurestone()) {
10478 pline("Oh wait, actually something bad happens...");
10484 if(!(HFire_resistance
& INTRINSIC
)) {
10486 pline("Excellent! You feel, like, totally cool!");
10488 You_feel("colder.");
10489 incr_itimeout(&HFire_resistance
, HFire_resistance
? (rnd(10) + spell_damage_bonus(spellid(spell
))) : (rn1(100, 50) + spell_damage_bonus(spellid(spell
))*10));
10491 pline("%s", nothing_happens
); /* Already have as intrinsic */
10492 if (FailureEffects
|| u
.uprops
[FAILURE_EFFECTS
].extrinsic
|| have_failurestone()) {
10493 pline("Oh wait, actually something bad happens...");
10499 if(!(HCold_resistance
& INTRINSIC
)) {
10500 You_feel("warmer.");
10501 incr_itimeout(&HCold_resistance
, HCold_resistance
? (rnd(10) + spell_damage_bonus(spellid(spell
))) : (rn1(100, 50) + spell_damage_bonus(spellid(spell
))*10));
10503 pline("%s", nothing_happens
); /* Already have as intrinsic */
10504 if (FailureEffects
|| u
.uprops
[FAILURE_EFFECTS
].extrinsic
|| have_failurestone()) {
10505 pline("Oh wait, actually something bad happens...");
10511 if(!(HSleep_resistance
& INTRINSIC
)) {
10513 pline("Too much coffee!");
10515 You("no longer feel tired.");
10516 incr_itimeout(&HSleep_resistance
, HSleep_resistance
? (rnd(10) + spell_damage_bonus(spellid(spell
))) : (rn1(100, 50) + spell_damage_bonus(spellid(spell
))*10));
10518 pline("%s", nothing_happens
); /* Already have as intrinsic */
10519 if (FailureEffects
|| u
.uprops
[FAILURE_EFFECTS
].extrinsic
|| have_failurestone()) {
10520 pline("Oh wait, actually something bad happens...");
10526 if(!(HStone_resistance
& INTRINSIC
)) {
10527 You_feel("more limber. Let's eat some cockatrice meat!");
10528 incr_itimeout(&HStone_resistance
, HStone_resistance
? (rnd(5) + spell_damage_bonus(spellid(spell
))) : (rn1(40, 20) + spell_damage_bonus(spellid(spell
))*4));
10530 pline("%s", nothing_happens
); /* Already have as intrinsic */
10531 if (FailureEffects
|| u
.uprops
[FAILURE_EFFECTS
].extrinsic
|| have_failurestone()) {
10532 pline("Oh wait, actually something bad happens...");
10538 if(!(HAcid_resistance
& INTRINSIC
)) {
10539 You("are resistant to acid now. Your items, however, are not.");
10540 incr_itimeout(&HAcid_resistance
, HAcid_resistance
? (rnd(10) + spell_damage_bonus(spellid(spell
))) : (rn1(100, 50) + spell_damage_bonus(spellid(spell
))*10));
10542 pline("%s", nothing_happens
); /* Already have as intrinsic */
10543 if (FailureEffects
|| u
.uprops
[FAILURE_EFFECTS
].extrinsic
|| have_failurestone()) {
10544 pline("Oh wait, actually something bad happens...");
10550 if(!(HSick_resistance
& INTRINSIC
)) {
10551 You_feel("resistant to sickness.");
10552 incr_itimeout(&HSick_resistance
, HSick_resistance
? (rnd(10) + spell_damage_bonus(spellid(spell
))) : (rn1(100, 50) + spell_damage_bonus(spellid(spell
))*10));
10554 pline("%s", nothing_happens
); /* Already have as intrinsic */
10555 if (FailureEffects
|| u
.uprops
[FAILURE_EFFECTS
].extrinsic
|| have_failurestone()) {
10556 pline("Oh wait, actually something bad happens...");
10562 if(!(HPoison_resistance
& INTRINSIC
)) {
10563 You_feel("healthy ..... for the moment at least.");
10564 incr_itimeout(&HPoison_resistance
, HPoison_resistance
? (rnd(10) + spell_damage_bonus(spellid(spell
))) : (rn1(100, 50) + spell_damage_bonus(spellid(spell
))*10));
10566 pline("%s", nothing_happens
); /* Already have as intrinsic */
10567 if (FailureEffects
|| u
.uprops
[FAILURE_EFFECTS
].extrinsic
|| have_failurestone()) {
10568 pline("Oh wait, actually something bad happens...");
10574 if(!(HDisint_resistance
& INTRINSIC
)) {
10575 You_feel("quite firm for a while.");
10576 incr_itimeout(&HDisint_resistance
, HDisint_resistance
? (rnd(10) + spell_damage_bonus(spellid(spell
))) : (rn1(100, 50) + spell_damage_bonus(spellid(spell
))*10));
10578 pline("%s", nothing_happens
); /* Already have as intrinsic */
10579 if (FailureEffects
|| u
.uprops
[FAILURE_EFFECTS
].extrinsic
|| have_failurestone()) {
10580 pline("Oh wait, actually something bad happens...");
10589 case SPE_FORBIDDEN_KNOWLEDGE
:
10590 if(!(HHalf_spell_damage
& INTRINSIC
)) {
10592 pline("Let the casting commence!");
10594 You_feel("a sense of spell knowledge.");
10595 incr_itimeout(&HHalf_spell_damage
, rn1(500, 250) + spell_damage_bonus(spellid(spell
))*50);
10597 if(!(HHalf_physical_damage
& INTRINSIC
)) {
10599 You_feel("like a tough motherfucker!");
10601 You("are resistant to normal damage.");
10602 incr_itimeout(&HHalf_physical_damage
, rn1(500, 250) + spell_damage_bonus(spellid(spell
))*50);
10608 case SPE_ALTER_REALITY
:
10614 case SPE_ENLIGHTEN
:
10615 You_feel("self-knowledgeable...");
10616 display_nhwindow(WIN_MESSAGE
, FALSE
);
10617 enlightenment(FALSE
, FALSE
);
10618 pline("The feeling subsides.");
10619 exercise(A_WIS
, TRUE
);
10622 /* WAC -- new spells */
10623 case SPE_FLAME_SPHERE
:
10624 case SPE_FREEZE_SPHERE
:
10625 { register int cnt
= 1;
10626 struct monst
*mtmp
;
10628 u
.lamefarmer
= TRUE
;
10630 if (rn2(3) && role_skill
>= P_SKILLED
) cnt
+= rnd(role_skill
- P_BASIC
);
10632 mtmp
= make_helper((pseudo
->otyp
== SPE_FLAME_SPHERE
) ?
10633 PM_SUMMONED_FLAMING_SPHERE
: PM_SUMMONED_FREEZING_SPHERE
, u
.ux
, u
.uy
);
10634 if (!mtmp
) continue;
10636 mtmp
->mhpmax
= mtmp
->mhp
= 1;
10637 mtmp
->isspell
= mtmp
->uexp
= TRUE
;
10638 } /* end while... */
10640 u
.lamefarmer
= FALSE
;
10645 case SPE_SHOCKING_SPHERE
:
10646 { register int cnt
= 1;
10647 struct monst
*mtmp
;
10649 u
.lamefarmer
= TRUE
;
10651 if (rn2(3) && role_skill
>= P_SKILLED
) cnt
+= rnd(role_skill
- P_BASIC
);
10653 mtmp
= make_helper(PM_SUMMONED_SHOCKING_SPHERE
, u
.ux
, u
.uy
);
10654 if (!mtmp
) continue;
10656 mtmp
->mhpmax
= mtmp
->mhp
= 1;
10657 mtmp
->isspell
= mtmp
->uexp
= TRUE
;
10658 } /* end while... */
10660 u
.lamefarmer
= FALSE
;
10665 case SPE_ACID_SPHERE
:
10666 { register int cnt
= 1;
10667 struct monst
*mtmp
;
10669 u
.lamefarmer
= TRUE
;
10671 if (rn2(3) && role_skill
>= P_SKILLED
) cnt
+= rnd(role_skill
- P_BASIC
);
10673 mtmp
= make_helper(PM_SUMMONED_ACID_SPHERE
, u
.ux
, u
.uy
);
10674 if (!mtmp
) continue;
10676 mtmp
->mhpmax
= mtmp
->mhp
= 1;
10677 mtmp
->isspell
= mtmp
->uexp
= TRUE
;
10678 } /* end while... */
10680 u
.lamefarmer
= FALSE
;
10686 /* KMH -- new spells */
10689 You_feel("ethereal.");
10690 incr_itimeout(&HPasses_walls
, rn1(10, 5));
10692 /* way too uber, needs nerf --Amy */
10693 if (!rn2(5)) badeffect();
10697 case SPE_DETECT_FOOT
:
10699 pline("Your nose tingles, and you smell feet!");
10700 if (nolimbs(youmonst
.data
) || slithy(youmonst
.data
)) {
10701 pline("You aren't sure where the feet might be, though.");
10703 pline("You see here a %s on the end of your %s.",body_part(FOOT
),body_part(LEG
));
10704 /* Come on sporkhack devteam, this spell could be useful. Let's see if I can make it do something. --Amy */
10705 pline("Urgh - your head spins from the vile stench!");
10706 make_confused(HConfusion
+ d(10,10), FALSE
);
10707 turn_allmonsters(); /* This even works on Demogorgon. */
10711 case SPE_REFLECTION
:
10714 case SPE_REPAIR_ARMOR
:
10715 /* removes one level of erosion (both types) for a random piece of armor */
10716 if (CannotSelectItemsInPrompts
) break;
10718 otmp
= getobj(allnoncount
, "magically enchant");
10719 /*otmp = some_armor(&youmonst);*/
10721 if (!(otmp
->owornmask
& W_ARMOR
) ) { /* bug discovered by Heliokopis - did Sporkhack never fix this? */
10723 pline("You have a feeling of loss.");
10724 } else if (greatest_erosion(otmp
) > 0) {
10726 pline("Your %s glows faintly golden for a moment.",xname(otmp
));
10728 if (otmp
->oeroded
> 0) { otmp
->oeroded
--; }
10729 if (otmp
->oeroded2
> 0) { otmp
->oeroded2
--; }
10730 if (otmp
&& objects
[(otmp
)->otyp
].oc_material
== MT_CELESTIUM
&& !stack_too_big(otmp
)) {
10731 if (!otmp
->cursed
) bless(otmp
);
10732 else uncurse(otmp
, FALSE
);
10736 pline("Your %s glows briefly, but looks as new as ever.",xname(otmp
));
10740 if (yn("Really exit with no object selected?") == 'y')
10741 pline("You just wasted the opportunity to enchant your armor.");
10742 else goto repairarmorchoice
;
10743 /* the player can probably feel this, so no need for a !Blind check :) */
10744 pline("Your embarrassing skin rash clears up slightly.");
10748 case SPE_REROLL_ARTIFACT
:
10750 if (CannotSelectItemsInPrompts
) break;
10751 pline("You may choose an artifact in your inventory to reroll. It may not be a worn one though.");
10752 rerollartifactchoice
:
10753 otmp
= getobj(allnoncount
, "reroll");
10755 if (yn("Really exit with no object selected?") == 'y')
10756 pline("You just wasted the opportunity to reroll an artifact.");
10757 else goto rerollartifactchoice
;
10758 pline("You decide not to reroll anything.");
10761 if (!otmp
->oartifact
) {
10762 pline("That is not an artifact, and can therefore not be rerolled!");
10765 if (otmp
->owornmask
) {
10766 pline("You cannot reroll an artifact that you're wearing!");
10769 if (!(otmp
->oclass
== WEAPON_CLASS
|| otmp
->oclass
== ARMOR_CLASS
|| otmp
->oclass
== RING_CLASS
|| otmp
->oclass
== AMULET_CLASS
|| otmp
->oclass
== IMPLANT_CLASS
)) {
10770 pline("You can only reroll weapons, armors, rings, implants or amulets!");
10774 switch (otmp
->oclass
) {
10779 int wpntype
; /* 1 = launcher, 2 = ammo, 3 = melee */
10780 if (is_launcher(otmp
)) wpntype
= 1;
10781 else if (is_ammo(otmp
) || is_missile(otmp
)) wpntype
= 2;
10784 otmp
->otyp
= rnd_class(ORCISH_DAGGER
,HAWAIIAN_SHIRT
-1);
10785 if (wpntype
== 1 && !is_launcher(otmp
)) goto reroll
;
10786 if (wpntype
== 2 && !is_ammo(otmp
) && !is_missile(otmp
)) goto reroll
;
10787 if (wpntype
== 3 && (is_launcher(otmp
) || is_ammo(otmp
) || is_missile(otmp
))) goto reroll
;
10796 /* 1 = shield, 2 = helmet, 3 = boots, 4 = gloves, 5 = cloak, 6 = shirt, 7 = suit */
10797 if (is_shield(otmp
)) armortype
= 1;
10798 else if (is_helmet(otmp
)) armortype
= 2;
10799 else if (is_boots(otmp
)) armortype
= 3;
10800 else if (is_gloves(otmp
)) armortype
= 4;
10801 else if (is_cloak(otmp
)) armortype
= 5;
10802 else if (is_shirt(otmp
)) armortype
= 6;
10803 else armortype
= 7;
10805 otmp
->otyp
= rnd_class(HAWAIIAN_SHIRT
,LEVITATION_BOOTS
);
10806 if (armortype
== 1 && !is_shield(otmp
)) goto rerollX
;
10807 if (armortype
== 2 && !is_helmet(otmp
)) goto rerollX
;
10808 if (armortype
== 3 && !is_boots(otmp
)) goto rerollX
;
10809 if (armortype
== 4 && !is_gloves(otmp
)) goto rerollX
;
10810 if (armortype
== 5 && !is_cloak(otmp
)) goto rerollX
;
10811 if (armortype
== 6 && !is_shirt(otmp
)) goto rerollX
;
10812 if (armortype
== 7 && !is_suit(otmp
)) goto rerollX
;
10817 otmp
->otyp
= rnd_class(RIN_ADORNMENT
,RIN_TELEPORT_CONTROL
);
10820 otmp
->otyp
= rnd_class(AMULET_OF_CHANGE
,AMULET_OF_VULNERABILITY
);
10822 case IMPLANT_CLASS
:
10823 otmp
->otyp
= rnd_class(IMPLANT_OF_ABSORPTION
,IMPLANT_OF_VIRTUE
);
10826 pline("Your artifact was rerolled to another base item!");
10828 pline("The strain of casting such a powerful spell damages your maximum health and mana.");
10830 u
.uhpmax
-= rnd(10);
10831 if (u
.uhp
> u
.uhpmax
) u
.uhp
= u
.uhpmax
;
10834 killer
= "the strain of casting reroll artifact";
10835 killer_format
= KILLED_BY
;
10840 u
.mhmax
-= rnd(10);
10841 if (u
.mh
> u
.mhmax
) u
.mh
= u
.mhmax
;
10844 u
.uenmax
-= rnd(10);
10845 if (u
.uen
> u
.uenmax
) u
.uen
= u
.uenmax
;
10849 case SPE_REPAIR_WEAPON
:
10850 /* removes one level of erosion (both types) for your wielded weapon */
10851 if (uwep
&& stack_too_big(uwep
)) {
10852 pline("The repair failed due to the stack being too big.");
10855 if(uwep
&& (uwep
->oclass
== WEAPON_CLASS
|| uwep
->oclass
== BALL_CLASS
|| uwep
->oclass
== GEM_CLASS
|| uwep
->oclass
== CHAIN_CLASS
|| uwep
->oclass
== VENOM_CLASS
|| is_weptool(uwep
))) {
10856 if (greatest_erosion(uwep
) > 0) {
10858 pline("Your %s glows faintly golden for a moment.",xname(uwep
));
10860 if (uwep
->oeroded
> 0) { uwep
->oeroded
--; }
10861 if (uwep
->oeroded2
> 0) { uwep
->oeroded2
--; }
10864 pline("Your %s glows briefly, but looks as new as ever.",xname(uwep
));
10870 pline("You don't wield a weapon!");
10875 case SPE_CHARACTER_RECURSION
:
10877 if (yn("WARNING!!! This spell will ***PERMANENTLY*** transform your character into another one, and remove ALL of your items and spells. Are you SURE you really want this?") == 'y') {
10880 register struct obj
*otmp
, *otmp2
;
10881 for (otmp
= invent
; otmp
; otmp
= otmp2
) {
10882 otmp2
= otmp
->nobj
;
10884 if (evades_destruction(otmp
) ) dropx(otmp
);
10886 delete_contents(otmp
);
10891 for (n
= 0; n
< MAXSPELL
&& spellid(n
) != NO_SPELL
; n
++) {
10892 spellid(n
) = NO_SPELL
;
10895 if (Aggravate_monster
) {
10897 reset_rndmonst(NON_PM
);
10900 (void) makemon(mkclass(S_HUMAN
,0), u
.ux
, u
.uy
, NO_MM_FLAGS
);
10901 (void) makemon(mkclass(S_HUMANOID
,0), u
.ux
, u
.uy
, NO_MM_FLAGS
);
10902 (void) makemon(mkclass(S_DEMON
,0), u
.ux
, u
.uy
, NO_MM_FLAGS
);
10903 (void) makemon(mkclass(S_GNOME
,0), u
.ux
, u
.uy
, NO_MM_FLAGS
);
10904 (void) makemon(mkclass(S_OGRE
,0), u
.ux
, u
.uy
, NO_MM_FLAGS
);
10905 (void) makemon(mkclass(S_GIANT
,0), u
.ux
, u
.uy
, NO_MM_FLAGS
);
10906 (void) makemon(mkclass(S_KOP
,0), u
.ux
, u
.uy
, NO_MM_FLAGS
);
10907 (void) makemon(mkclass(S_ORC
,0), u
.ux
, u
.uy
, NO_MM_FLAGS
);
10911 (void) safe_teleds_normalterrain(FALSE
);
10920 /*impossible("Unknown spell %d attempted.", spell);*/
10921 pline("You attempted to cast a spell %d that either doesn't exist in this game, or it has been genocided.", spell
);
10922 obfree(pseudo
, (struct obj
*)0);
10926 /* gain skill for successful cast */
10927 use_skill(skill
, spellev(spell
));
10928 if (rn2(2)) use_skill(skill
, spellev(spell
)); /* let's make gaining spellcasting skill a little bit easier --Amy */
10929 if (!rn2(50)) use_skill(skill
, (spellev(spell
) * 10) ); /* jackpot! */
10931 /* WAC successful casting increases solidity of knowledge */
10933 if (!SpellColorCyan
&& !(pseudo
&& pseudo
->otyp
== SPE_ADD_SPELL_MEMORY
) ) {
10935 int castboost
= Race_if(PM_DUNADAN
) ? DUNADAN_CAST_BOOST
: CAST_BOOST
;
10936 int baseboost
= castboost
; /* because multiplicative bonuses shouldn't exponentially increase it --Amy */
10937 boolean canboostmore
= TRUE
;
10940 switch (pseudo
->otyp
) {
10942 case SPE_ALTER_REALITY
:
10944 case SPE_CLONE_MONSTER
:
10945 case SPE_THRONE_GAMBLE
:
10946 case SPE_GAIN_LEVEL
:
10947 case SPE_ATTUNE_MAGIC
:
10948 case SPE_REROLL_ARTIFACT
:
10950 case SPE_RELOCATION
:
10951 case SPE_AULE_SMITHING
:
10952 case SPE_REPAIR_WEAPON
:
10953 case SPE_REPAIR_ARMOR
:
10955 canboostmore
= FALSE
; break;
10961 if (canboostmore
) {
10963 if (irisartiboost()) {
10965 castboost
+= (baseboost
* irisartiboost() / 100);
10969 /* if a spell is down to low memory, then casting it successfully saves it from being immediately forgotten */
10970 if (spellknow(spell
) < 5000) {
10971 if (spellknow(spell
) < 100) {
10972 castboost
+= (baseboost
* 75 / 100);
10973 } else if (spellknow(spell
) < 1000) {
10974 castboost
+= (baseboost
* 50 / 100);
10975 } else if (spellknow(spell
) < 2000) {
10976 castboost
+= (baseboost
* 40 / 100);
10977 } else if (spellknow(spell
) < 3000) {
10978 castboost
+= (baseboost
* 30 / 100);
10979 } else if (spellknow(spell
) < 4000) {
10980 castboost
+= (baseboost
* 20 / 100);
10981 } else if (spellknow(spell
) < 5000) {
10982 castboost
+= (baseboost
* 10 / 100);
10986 if (Spellboost
) castboost
+= (baseboost
* 10 / 100);
10987 if (StrongSpellboost
) castboost
+= (baseboost
* 10 / 100);
10988 if (tech_inuse(T_SPELL_SPAM
)) castboost
+= (baseboost
* 10 / 100);
10990 if (!PlayerCannotUseSkills
) {
10992 switch (P_SKILL(P_MEMORIZATION
)) {
10993 case P_BASIC
: castboost
+= (baseboost
* 5 / 100); break;
10994 case P_SKILLED
: castboost
+= (baseboost
* 10 / 100); break;
10995 case P_EXPERT
: castboost
+= (baseboost
* 15 / 100); break;
10996 case P_MASTER
: castboost
+= (baseboost
* 20 / 100); break;
10997 case P_GRAND_MASTER
: castboost
+= (baseboost
* 25 / 100); break;
10998 case P_SUPREME_MASTER
: castboost
+= (baseboost
* 30 / 100); break;
11002 if (spellev(spell
) >= 2 && !rn2(2)) {
11003 castboost
+= (baseboost
* 10 / 100);
11005 if (spellev(spell
) >= 3 && !rn2(2)) {
11006 castboost
+= (baseboost
* 9 / 100);
11008 if (spellev(spell
) >= 4 && !rn2(2)) {
11009 castboost
+= (baseboost
* 8 / 100);
11011 if (spellev(spell
) >= 5 && !rn2(2)) {
11012 castboost
+= (baseboost
* 7 / 100);
11014 if (spellev(spell
) >= 6 && !rn2(2)) {
11015 castboost
+= (baseboost
* 6 / 100);
11017 if (spellev(spell
) >= 7 && !rn2(2)) {
11018 castboost
+= (baseboost
* 5 / 100);
11020 if (spellev(spell
) >= 8 && !rn2(2)) {
11021 castboost
+= (baseboost
* 4 / 100);
11025 boostknow(spell
, castboost
);
11026 if (((rnd(spellev(spell
) + 5)) > 5) && canboostmore
) boostknow(spell
, castboost
); /* higher-level spells boost more --Amy */
11027 if (!rn2(52 - (spellev(spell
) * 2) ) && canboostmore
&& !Race_if(PM_DUNADAN
) ) { /* jackpot! */
11028 boostknow(spell
, (castboost
* 5) );
11029 boostknow(spell
, (castboost
* spellev(spell
) ) );
11032 if (Role_if(PM_MAHOU_SHOUJO
)) boostknow(spell
, castboost
);
11033 if (Role_if(PM_PSYKER
)) boostknow(spell
, castboost
);
11037 if (!(iflags
.memorizationknown
) && !(spl_book
[spell
].sp_memorize
)) {
11038 if (yn("You just cast a dememorized spell! If this means that you want to continue using that spell later, you might want to set it back to memorization mode so that its spell memory lasts longer. Press y now to set the spell back to memorization mode, or n to keep it dememorized.") == 'y') {
11039 spl_book
[spell
].sp_memorize
= TRUE
;
11040 pline("Spell memorization was activated!");
11044 if (SpellColorCyan
) {
11045 boolean cyanwillgodown
= TRUE
;
11047 /* keep this synchronized with age_spells(), please --Amy */
11049 if (Keen_memory
&& !rn2(StrongKeen_memory
? 3 : 5)) cyanwillgodown
= FALSE
;
11050 if (uarm
&& uarm
->oartifact
== ART_COPE_OF_THE_ELDRITCH_KNIGH
&& rn2(2)) cyanwillgodown
= FALSE
;
11051 if (uarmc
&& itemhasappearance(uarmc
, APP_GUILD_CLOAK
) ) cyanwillgodown
= FALSE
;
11052 if (tech_inuse(T_SPELL_SPAM
)) cyanwillgodown
= FALSE
;
11053 if (uarms
&& uarms
->oartifact
== ART_UNUSUAL_ENCH
&& !rn2(5)) cyanwillgodown
= FALSE
;
11054 if (rnd(urole
.spelrete
+ 100) > 100) cyanwillgodown
= FALSE
;
11056 if (!rn2(2) && spellmemorize(spell
)) cyanwillgodown
= FALSE
;
11058 if (spellmemorize(spell
) && ACURR(A_INT
) > 14) {
11059 int intelsave
= ACURR(A_INT
) - 14;
11060 if (intelsave
> rn2(66)) cyanwillgodown
= FALSE
;
11063 if (!PlayerCannotUseSkills
&& spellmemorize(spell
) && P_SKILL(P_MEMORIZATION
) >= P_BASIC
) {
11065 int savememochance
= 0;
11067 switch (P_SKILL(P_MEMORIZATION
)) {
11068 case P_BASIC
: savememochance
= 1; break;
11069 case P_SKILLED
: savememochance
= 2; break;
11070 case P_EXPERT
: savememochance
= 3; break;
11071 case P_MASTER
: savememochance
= 4; break;
11072 case P_GRAND_MASTER
: savememochance
= 5; break;
11073 case P_SUPREME_MASTER
: savememochance
= 6; break;
11076 if (savememochance
> rn2(10)) cyanwillgodown
= FALSE
;
11080 if (!PlayerCannotUseSkills
&& spellmemorize(spell
) && P_SKILL(spell_skilltype(spellid(spell
))) >= P_BASIC
) {
11082 int savememochance
= 0;
11084 switch (P_SKILL(spell_skilltype(spellid(spell
)))) {
11085 case P_BASIC
: savememochance
= 1; break;
11086 case P_SKILLED
: savememochance
= 2; break;
11087 case P_EXPERT
: savememochance
= 3; break;
11088 case P_MASTER
: savememochance
= 4; break;
11089 case P_GRAND_MASTER
: savememochance
= 5; break;
11090 case P_SUPREME_MASTER
: savememochance
= 6; break;
11093 if (savememochance
> rn2(20)) cyanwillgodown
= FALSE
;
11097 if (cyanwillgodown
) {
11098 drainknow(spell
, rnd(100));
11099 if (spellknow(spell
) < 0) spl_book
[spell
].sp_know
= 0;
11103 if (pseudo
&& pseudo
->otyp
== SPE_REBOOT
&& !rn2(10) ) {
11105 drainknow(spell
, (rnd(20000)));
11106 if (spellknow(spell
) < 0) spl_book
[spell
].sp_know
= 0;
11110 if (pseudo
&& ((pseudo
->otyp
== SPE_ALTER_REALITY
) || (pseudo
->otyp
== SPE_CLONE_MONSTER
) ) ) {
11112 drainknow(spell
, (rnd(20000)));
11113 if (spellknow(spell
) < 0) spl_book
[spell
].sp_know
= 0;
11117 if (pseudo
&& (pseudo
->otyp
== SPE_THRONE_GAMBLE
) && !rn2(6) ) {
11119 drainknow(spell
, (rnd(100000)));
11120 if (spellknow(spell
) < 0) spl_book
[spell
].sp_know
= 0;
11124 if (pseudo
&& (pseudo
->otyp
== SPE_GAIN_LEVEL
) && !rn2(200) ) {
11126 drainknow(spell
, (rnd(50000)));
11127 if (spellknow(spell
) < 0) spl_book
[spell
].sp_know
= 0;
11131 if (pseudo
&& (pseudo
->otyp
== SPE_ATTUNE_MAGIC
) && !rn2(6) ) {
11133 drainknow(spell
, (rnd(100000)));
11134 if (spellknow(spell
) < 0) spl_book
[spell
].sp_know
= 0;
11138 if (pseudo
&& (pseudo
->otyp
== SPE_REROLL_ARTIFACT
) && !rn2(5) ) {
11140 drainknow(spell
, (rnd(100000)));
11141 if (spellknow(spell
) < 0) spl_book
[spell
].sp_know
= 0;
11145 if (pseudo
&& (pseudo
->otyp
== SPE_CHARGING
) && !rn2(role_skill
== P_SUPREME_MASTER
? 9 : role_skill
== P_GRAND_MASTER
? 8 : role_skill
== P_MASTER
? 7 : role_skill
== P_EXPERT
? 6 : role_skill
== P_SKILLED
? 5 : 4) ) {
11147 drainknow(spell
, (rnd(100000)));
11148 if (spellknow(spell
) < 0) spl_book
[spell
].sp_know
= 0;
11152 if (pseudo
&& (pseudo
->otyp
== SPE_RELOCATION
) && !rn2(role_skill
== P_SUPREME_MASTER
? 9 : role_skill
== P_GRAND_MASTER
? 8 : role_skill
== P_MASTER
? 7 : role_skill
== P_EXPERT
? 6 : role_skill
== P_SKILLED
? 5 : 4) ) {
11154 drainknow(spell
, (rnd(10000)));
11155 if (spellknow(spell
) < 0) spl_book
[spell
].sp_know
= 0;
11159 if (pseudo
&& pseudo
->otyp
== SPE_ADD_SPELL_MEMORY
) {
11161 drainknow(spell
, 500);
11162 if (spellknow(spell
) < 0) spl_book
[spell
].sp_know
= 0;
11166 if (pseudo
&& (pseudo
->otyp
== SPE_AULE_SMITHING
) && !rn2(role_skill
== P_SUPREME_MASTER
? 9 : role_skill
== P_GRAND_MASTER
? 8 : role_skill
== P_MASTER
? 7 : role_skill
== P_EXPERT
? 6 : role_skill
== P_SKILLED
? 5 : 4) ) {
11168 drainknow(spell
, (rnd(100000)));
11169 if (spellknow(spell
) < 0) spl_book
[spell
].sp_know
= 0;
11173 if (pseudo
&& ((pseudo
->otyp
== SPE_REPAIR_WEAPON
) || (pseudo
->otyp
== SPE_REPAIR_ARMOR
)) && !rn2(role_skill
== P_SUPREME_MASTER
? 15 : role_skill
== P_GRAND_MASTER
? 14 : role_skill
== P_MASTER
? 13 : role_skill
== P_EXPERT
? 12 : role_skill
== P_SKILLED
? 11 : 10) ) {
11175 drainknow(spell
, (rnd(25000)));
11176 if (spellknow(spell
) < 0) spl_book
[spell
].sp_know
= 0;
11180 if (pseudo
&& (pseudo
->otyp
== SPE_PASSWALL
) && !rn2(role_skill
== P_SUPREME_MASTER
? 30 : role_skill
== P_GRAND_MASTER
? 25 : role_skill
== P_MASTER
? 24 : role_skill
== P_EXPERT
? 23 : role_skill
== P_SKILLED
? 22 : 20) ) {
11182 drainknow(spell
, (rnd(10000)));
11183 if (spellknow(spell
) < 0) spl_book
[spell
].sp_know
= 0;
11187 if ((spell_skilltype(spellid(spell
)) == P_OCCULT_SPELL
) && !(uarmg
&& uarmg
->oartifact
== ART_FATHIEN_ELDER_S_SECRET_POW
) ) { /* dangerous realm... */
11188 if (PlayerCannotUseSkills
) {
11189 if (!rn2(5)) badeffect();
11190 } else switch (role_skill
) {
11192 case P_ISRESTRICTED
:
11194 if (!rn2(Role_if(PM_OCCULT_MASTER
) ? 12 : 5)) {
11195 pline("You fail to control the occult powers and are hit with backlash!");
11200 if (!rn2(Role_if(PM_OCCULT_MASTER
) ? 14 : 6)) {
11201 pline("You fail to control the occult powers and are hit with backlash!");
11206 if (!rn2(Role_if(PM_OCCULT_MASTER
) ? 16 : 7)) {
11207 pline("You fail to control the occult powers and are hit with backlash!");
11212 if (!rn2(Role_if(PM_OCCULT_MASTER
) ? 20 : 8)) {
11213 pline("You fail to control the occult powers and are hit with backlash!");
11218 if (!rn2(Role_if(PM_OCCULT_MASTER
) ? 22 : 9)) {
11219 pline("You fail to control the occult powers and are hit with backlash!");
11223 case P_GRAND_MASTER
:
11224 if (!rn2(Role_if(PM_OCCULT_MASTER
) ? 25 : 10)) {
11225 pline("You fail to control the occult powers and are hit with backlash!");
11229 case P_SUPREME_MASTER
:
11230 if (!rn2(Role_if(PM_OCCULT_MASTER
) ? 30 : 11)) {
11231 pline("You fail to control the occult powers and are hit with backlash!");
11238 /* charging is way too overpowered, let's add another "bullshit downside" --Amy */
11239 if (pseudo
&& (pseudo
->otyp
== SPE_CHARGING
) && !rn2(role_skill
== P_SUPREME_MASTER
? 16 : role_skill
== P_GRAND_MASTER
? 15 : role_skill
== P_MASTER
? 13 : role_skill
== P_EXPERT
? 12 : role_skill
== P_SKILLED
? 11 : 10) ) {
11245 /* particle cannon and one point shoot need "gauge"; since this isn't Elona, we don't have an actual gauge meter,
11246 * so I decided that it just takes 50 turns to reload --Amy */
11247 if (pseudo
&& (pseudo
->otyp
== SPE_PARTICLE_CANNON
)) {
11248 pline("The particle cannon can be used again at turn %ld.", (moves
+ u
.gaugetimer
));
11250 if (pseudo
&& (pseudo
->otyp
== SPE_CONVERGE_BREATH
)) {
11251 pline("Converge Breath can be used again at turn %ld.", (moves
+ u
.gaugetimer
));
11253 if (pseudo
&& (pseudo
->otyp
== SPE_IMPACT_GUNFIRE
)) {
11254 pline("Impact Gunfire can be used again at turn %ld.", (moves
+ u
.gaugetimer
));
11256 if (pseudo
&& (pseudo
->otyp
== SPE_ONE_POINT_SHOOT
)) {
11257 pline("One Point Shoot can be used again at turn %ld.", (moves
+ u
.gaugetimer
));
11259 if (pseudo
&& (pseudo
->otyp
== SPE_BATTERING_RAM
)) {
11260 pline("Battering Ram can be used again at turn %ld.", (moves
+ u
.battertimer
));
11262 if (pseudo
&& (pseudo
->otyp
== SPE_BUBBLING_HOLE
)) {
11263 nomul(-2, "recovering from the bubbling hole", TRUE
);
11266 obfree(pseudo
, (struct obj
*)0); /* now, get rid of it */
11270 /* #spelldelete command: allows the player to erase the bottommost spell outright, but only if it's a forgotten one */
11275 for (n
= 0; n
< MAXSPELL
&& spellid(n
) != NO_SPELL
; n
++)
11279 n
--; /* fix off-by-one error */
11280 if (spellid(n
) == NO_SPELL
) {
11281 impossible("ERROR: dodeletespell() trying to erase empty spell?");
11285 if (spellknow(n
) > 0) {
11286 pline("This doesn't work as long as your bottommost spell still has memory left.");
11288 pline("Your bottommost spell is %s, which has no memory left.", spellname(n
));
11289 if (yn("Erase it from the list?") == 'y') {
11290 spellid(n
) = NO_SPELL
;
11291 /* no need to nullify spell memory because it's already zero */
11292 pline("Done! The spell has been removed from your list.");
11295 } else pline("It seems that you have no known spells in the first place.");
11297 /* shouldn't cost a turn, regardless of result */
11304 boolean confused
= (Confusion
!= 0);
11306 int thisone
, thisonetwo
, choicenumber
;
11308 if (Keen_memory
&& rn2(StrongKeen_memory
? 20 : 4)) return;
11309 if (Role_if(PM_MASTERMIND
) && mastermindsave()) return;
11311 /* have no spells? well then... magic vacuum :P --Amy */
11312 if (spellid(0) == NO_SPELL
) {
11313 make_magicvacuum((HMagicVacuum
& TIMEOUT
) + rnd(10) + rnd(monster_difficulty() * 100) );
11316 /* reduce memory of one known spell that still has memory left --Amy */
11317 for (n
= 0; n
< MAXSPELL
&& spellid(n
) != NO_SPELL
; n
++)
11322 for (n
= 0; ((n
< MAXSPELL
) && spellid(n
) != NO_SPELL
); n
++) {
11323 if ((!choicenumber
|| (!rn2(choicenumber
+ 1)) ) && (spellknow(n
) > 0)) {
11326 if (spellknow(n
) > 0) choicenumber
++;
11329 if (choicenumber
> 0 && thisone
>= 0 && (spellknow(thisone
) > 0)) {
11331 spellknow(thisone
) = rn2(spellknow(thisone
));
11333 spellknow(thisone
) = 0;
11338 /* maybe also reduce spell memory a bit more, to make the amnesia effect matter --Amy */
11339 if (!rn2(5)) spellmemoryloss(level_difficulty() + 1);
11342 for (n
= 0; n
< MAXSPELL
&& spellid(n
) != NO_SPELL
; n
++)
11345 nzap
= rn2(isfriday
? 20 : 50) ? 1 : (rnd(n
) + confused
);
11347 if (n
> urole
.spelrete
) {
11348 int retention
= urole
.spelrete
;
11349 if (retention
< 1) {
11350 impossible("player's spell retention isn't positive??");
11353 int highamount
= n
;
11354 while (highamount
> retention
) {
11356 highamount
-= rnd(retention
);
11360 if (nzap
> n
) nzap
= n
;
11361 for (i
= n
- nzap
; i
< n
; i
++) {
11362 spellid(i
) = NO_SPELL
;
11363 exercise(A_WIS
, FALSE
); /* ouch! */
11367 /* now if you have too many forgotten spells, remove them --Amy */
11369 for (n
= 0; n
< MAXSPELL
&& spellid(n
) != NO_SPELL
; n
++)
11375 for (n
= 0; ((n
< MAXSPELL
) && spellid(n
) != NO_SPELL
); n
++) {
11376 if (spellknow(n
) <= 0) {
11382 if (choicenumber
> 5 && thisone
>= 0 && spellknow(thisone
) <= 0) {
11384 spellknow(thisone
) = 0; /* make sure the spell memory is deleted! */
11385 spellid(thisone
) = NO_SPELL
;
11387 for (n
= thisone
; n
< MAXSPELL
; n
++) {
11388 if (spellid(n
) != NO_SPELL
) thisonetwo
= n
;
11390 if (thisonetwo
>= 0 && spellid(thisonetwo
) != NO_SPELL
) { /* move last known spell to the one we've erased */
11391 spellknow(thisone
) = spellknow(thisonetwo
);
11392 spellid(thisone
) = spellid(thisonetwo
);
11393 spellev(thisone
) = spellev(thisonetwo
);
11394 spellname(thisone
) = spellname(thisonetwo
);
11396 spellknow(thisonetwo
) = 0; /* make sure the spell memory is deleted! */
11397 spellid(thisonetwo
) = NO_SPELL
;
11401 if (choicenumber
> 6) goto removeagain
;
11408 /* for bad effects: spell zonking similar to the amnesia effect */
11413 int thisone
, thisonetwo
, choicenumber
;
11415 /* reduce memory of one known spell that still has memory left --Amy */
11416 for (n
= 0; n
< MAXSPELL
&& spellid(n
) != NO_SPELL
; n
++)
11421 for (n
= 0; ((n
< MAXSPELL
) && spellid(n
) != NO_SPELL
); n
++) {
11422 if ((!choicenumber
|| (!rn2(choicenumber
+ 1)) ) && (spellknow(n
) > 0)) {
11425 if (spellknow(n
) > 0) choicenumber
++;
11428 if (choicenumber
> 0 && thisone
>= 0 && (spellknow(thisone
) > 0)) {
11430 spellknow(thisone
) = rn2(spellknow(thisone
));
11431 pline("You forget a lot of %s spell knowledge!", spellname(thisone
));
11433 spellknow(thisone
) = 0;
11434 pline("You forget all usage of the %s spell!", spellname(thisone
));
11439 /* now if you have too many forgotten spells, remove them --Amy */
11441 for (n
= 0; n
< MAXSPELL
&& spellid(n
) != NO_SPELL
; n
++)
11447 for (n
= 0; ((n
< MAXSPELL
) && spellid(n
) != NO_SPELL
); n
++) {
11448 if (spellknow(n
) <= 0) {
11454 if (choicenumber
> 5 && thisone
>= 0 && spellknow(thisone
) <= 0) {
11456 spellknow(thisone
) = 0; /* make sure the spell memory is deleted! */
11457 spellid(thisone
) = NO_SPELL
;
11459 for (n
= thisone
; n
< MAXSPELL
; n
++) {
11460 if (spellid(n
) != NO_SPELL
) thisonetwo
= n
;
11462 if (thisonetwo
>= 0 && spellid(thisonetwo
) != NO_SPELL
) { /* move last known spell to the one we've erased */
11463 spellknow(thisone
) = spellknow(thisonetwo
);
11464 spellid(thisone
) = spellid(thisonetwo
);
11465 spellev(thisone
) = spellev(thisonetwo
);
11466 spellname(thisone
) = spellname(thisonetwo
);
11468 spellknow(thisonetwo
) = 0; /* make sure the spell memory is deleted! */
11469 spellid(thisonetwo
) = NO_SPELL
;
11473 if (choicenumber
> 6) goto removeagain
;
11479 /* having too many forgotten spells just clogs up the interface, so we'll occasionally remove one --Amy */
11481 removeforgottenspell()
11483 int n
, thisone
, thisonetwo
, choicenumber
;
11485 for (n
= 0; n
< MAXSPELL
&& spellid(n
) != NO_SPELL
; n
++)
11491 for (n
= 0; ((n
< MAXSPELL
) && spellid(n
) != NO_SPELL
); n
++) {
11492 if (spellknow(n
) <= 0) {
11498 if (choicenumber
> 5 && thisone
>= 0 && spellknow(thisone
) <= 0) {
11500 pline("You completely forgot the %s spell.", spellname(thisone
));
11501 if (flags
.moreforced
&& !MessagesSuppressed
) display_nhwindow(WIN_MESSAGE
, TRUE
); /* --More-- */
11502 spellknow(thisone
) = 0; /* make sure the spell memory is deleted! */
11503 spellid(thisone
) = NO_SPELL
;
11505 for (n
= thisone
; n
< MAXSPELL
; n
++) {
11506 if (spellid(n
) != NO_SPELL
) thisonetwo
= n
;
11508 if (thisonetwo
>= 0 && spellid(thisonetwo
) != NO_SPELL
) { /* move last known spell to the one we've erased */
11509 spellknow(thisone
) = spellknow(thisonetwo
);
11510 spellid(thisone
) = spellid(thisonetwo
);
11511 spellev(thisone
) = spellev(thisonetwo
);
11512 spellname(thisone
) = spellname(thisonetwo
);
11514 spellknow(thisonetwo
) = 0; /* make sure the spell memory is deleted! */
11515 spellid(thisonetwo
) = NO_SPELL
;
11525 spellmemoryloss(lossamount
)
11528 int n
, thisone
, choicenumber
, spell
, nzap
;
11530 for (n
= 0; n
< MAXSPELL
&& spellid(n
) != NO_SPELL
; n
++)
11535 for (n
= 0; n
< MAXSPELL
&& spellid(n
) != NO_SPELL
; n
++) {
11536 if ((spellknow(n
) > 0) && (!choicenumber
|| (!rn2(choicenumber
+ 1))) ) {
11539 if (spellknow(n
) > 0) choicenumber
++;
11542 /* sometimes we're mean and reduce it by more, depending on how many spells you have... --Amy */
11543 if (!rn2(3) && choicenumber
> 1) {
11544 lossamount
*= (50 + rno(choicenumber
));
11547 lossamount
*= rnd(5);
11549 if (choicenumber
> 0 && thisone
>= 0) {
11550 drainknow(thisone
, (lossamount
* 100));
11551 if (spellknow(thisone
) < 0) {
11552 spl_book
[thisone
].sp_know
= 0;
11553 pline("You lose all knowledge of the %s spell!", spellname(thisone
));
11555 else pline("Your knowledge of the %s spell is reduced!", spellname(thisone
));
11562 for (n
= 0; n
< MAXSPELL
&& spellid(n
) != NO_SPELL
; n
++)
11565 if (n
> urole
.spelrete
) {
11566 int retention
= urole
.spelrete
;
11567 if (retention
< 1) {
11568 impossible("player's spell retention isn't positive??");
11571 int highamount
= n
;
11572 while (highamount
> retention
) {
11574 highamount
-= rnd(retention
);
11578 if (n
&& nzap
> 0) pline("Some of your spells got erased!");
11582 for (n
= 0; n
< MAXSPELL
&& spellid(n
) != NO_SPELL
; n
++)
11585 if (n
>= 0 && spellid(n
) == NO_SPELL
) n
--;
11587 if (nzap
> n
) nzap
= n
;
11588 if (n
&& nzap
> 0) {
11592 if (spellknow(n
) > 0) drainknow(n
, 10000);
11593 if (spellknow(n
) < 0) spellknow(n
) = 0;
11595 if (spellknow(n
) <= 0) {
11596 spl_book
[n
].sp_know
= 0;
11597 spellid(n
) = NO_SPELL
;
11598 exercise(A_WIS
, FALSE
); /* ouch! */
11609 /* halve memory of a randomly selected spell with nonzero memory --Amy */
11613 int n
, thisone
, choicenumber
, spell
, nzap
;
11615 for (n
= 0; n
< MAXSPELL
&& spellid(n
) != NO_SPELL
; n
++)
11620 for (n
= 0; n
< MAXSPELL
&& spellid(n
) != NO_SPELL
; n
++) {
11621 if ((spellknow(n
) > 0) && (!choicenumber
|| (!rn2(choicenumber
+ 1))) ) {
11624 if (spellknow(n
) > 0) choicenumber
++;
11627 if (choicenumber
> 0 && thisone
>= 0) {
11628 spl_book
[thisone
].sp_know
/= 2;
11629 if (spellknow(thisone
) < 0) {
11630 spl_book
[thisone
].sp_know
= 0;
11631 pline("You lose all knowledge of the %s spell!", spellname(thisone
));
11633 else pline("Your knowledge of the %s spell is cut in half!", spellname(thisone
));
11640 /* the '+' command -- view known spells */
11645 int splnum
, othnum
;
11646 struct spell spl_tmp
;
11648 if (MenuIsBugged
) {
11649 pline("The spell menu command is currently unavailable!");
11650 if (flags
.moreforced
&& !MessagesSuppressed
) display_nhwindow(WIN_MESSAGE
, TRUE
); /* --More-- */
11657 char spellcolorbuf
[BUFSZ
];
11659 if (SpellColorPink
) sprintf(spellcolorbuf
, "Your spells are pink.");
11660 else if (SpellColorBrightCyan
) sprintf(spellcolorbuf
, "Your spells are bright cyan.");
11661 else if (SpellColorCyan
) sprintf(spellcolorbuf
, "Your spells are cyan.");
11662 else if (SpellColorBlack
) sprintf(spellcolorbuf
, "Your spells are black.");
11663 else if (SpellColorOrange
) sprintf(spellcolorbuf
, "Your spells are orange.");
11664 else if (SpellColorRed
) sprintf(spellcolorbuf
, "Your spells are red.");
11665 else if (SpellColorPlatinum
) sprintf(spellcolorbuf
, "Your spells are platinum.");
11666 else if (SpellColorSilver
) sprintf(spellcolorbuf
, "Your spells are silver.");
11667 else if (SpellColorMetal
) sprintf(spellcolorbuf
, "Your spells are metal.");
11668 else if (SpellColorGreen
) sprintf(spellcolorbuf
, "Your spells are green.");
11669 else if (SpellColorBlue
) sprintf(spellcolorbuf
, "Your spells are blue.");
11670 else if (SpellColorGray
) sprintf(spellcolorbuf
, "Your spells are completely gray.");
11671 else if (SpellColorBrown
) sprintf(spellcolorbuf
, "Your spells are brown.");
11672 else if (SpellColorWhite
) sprintf(spellcolorbuf
, "Your spells are white.");
11673 else if (SpellColorViolet
) sprintf(spellcolorbuf
, "Your spells are violet.");
11674 else if (SpellColorYellow
) sprintf(spellcolorbuf
, "Your spells are yellow.");
11675 else sprintf(spellcolorbuf
, "Currently known spells");
11677 if (spellid(0) == NO_SPELL
)
11678 You("don't know any spells right now.");
11680 while (dospellmenu( spellcolorbuf
, SPELLMENU_VIEW
, &splnum
, 0)) {
11681 sprintf(qbuf
, "Reordering spells; swap '%s' with",
11682 (SpellLoss
|| u
.uprops
[SPELLS_LOST
].extrinsic
|| have_spelllossstone()) ? "spell" : spellname(splnum
));
11683 if (!dospellmenu(qbuf
, splnum
, &othnum
, 0)) break;
11685 spl_tmp
= spl_book
[splnum
];
11686 spl_book
[splnum
] = spl_book
[othnum
];
11687 spl_book
[othnum
] = spl_tmp
;
11692 for (i
= 0; i
< MAXSPELL
; i
++) {
11693 if (spellid(i
) == NO_SPELL
) break;
11694 if (spellmemorize(i
)) continue;
11697 if (iflags
.memorizationknown
) dememonum
= 0;
11699 if (dememonum
>= 10) pline("You set a very large amount of spells to dememorization mode. A common misconception of players unfamiliar with the memorization system is that dememorizing some spells would magically make the memorized spells last longer. That is NOT the case. The spells are independent from each other. Every spell set to memorization mode gets a 10%% reduction in spell decay rate per memorization skill level (i.e. spell memory persists longer), so if you want to keep casting those spells, you should set them back to memorization mode. You can do that by opening the spell menu (with the + key) and pressing ? twice, which brings you to the memorization menu.");
11700 else if (dememonum
>= 5) pline("You set many spells to dememorization mode (indicated by a - next to the spell level). All those spells aren't getting the spell memory bonus from memorization skill, which is highly impractical unless you WANT to forget those spells for some bizarre reason. It's advisable to have only a single spell set to dememorization mode, i.e. the one you want to turn into a forgotten spell. You can change it in the spell menu (hit + to open it and ? twice to navigate to the memorization menu).");
11701 else if (dememonum
>= 2) pline("You set several spells to dememorization mode (indicated by a - next to the spell level), which means that those spells currently don't benefit from increased spell memory. If you want your spells to benefit from the memorization skill, you should open the spell menu (+ key by default) and navigate to the memorization menu by pressing ? twice, then setting the spells in question back to memorization mode.");
11707 dospellmenu(prompt
, splaction
, spell_no
, specialmenutype
)
11708 const char *prompt
;
11709 int splaction
; /* SPELLMENU_CAST, SPELLMENU_VIEW, or spl_book[] index */
11711 /* specialmenutype: 0 = show spells, 1 = describe spells, 2 = memorize spells */
11712 int specialmenutype
;
11717 menu_item
*selected
;
11721 tmpwin
= create_nhwindow(NHW_MENU
);
11722 start_menu(tmpwin
);
11723 any
.a_void
= 0; /* zero out all bits */
11726 * The correct spacing of the columns depends on the
11727 * following that (1) the font is monospaced and (2)
11728 * that selection letters are pre-pended to the given
11729 * string and are of the form "a - ".
11731 * To do it right would require that we implement columns
11732 * in the window-ports (say via a tab character).
11734 if (!iflags
.menu_tab_sep
)
11735 sprintf(buf
, "%-20s Level Pw %-10s Fail Memory", " Name", " Category");
11737 sprintf(buf
, "Name\tLevel\tPw\t Category\tFail");
11738 if (flags
.menu_style
== MENU_TRADITIONAL
)
11739 strcat(buf
, iflags
.menu_tab_sep
? "\tKey" : " Key");
11740 add_menu(tmpwin
, NO_GLYPH
, &any
, 0, 0, ATR_BOLD
, buf
, MENU_UNSELECTED
);
11741 if (!SpellLoss
&& !u
.uprops
[SPELLS_LOST
].extrinsic
&& !have_spelllossstone()) {for (i
= 0; i
< MAXSPELL
&& spellid(i
) != NO_SPELL
; i
++) {
11742 sprintf(buf
, iflags
.menu_tab_sep
?
11743 "%s\t%-d%s\t%s%s %d\t%-d%%" : "%-20s %2d%s%s %3d %-8s %4d%%"
11745 spellname(i
), spellev(i
),
11746 ((spellknow(i
) > 1000) || SpellColorCyan
) ? " " : (spellknow(i
) ? "!" : "*"),
11747 spellmemorize(i
) ? "+" : "-",
11748 manacost(spellid(i
)),
11749 spelltypemnemonic(spell_skilltype(spellid(i
))),
11750 SpellColorBlack
? 0 : (100 - percent_success(i
)),
11752 /* "Spell memory percentage no longer shows up in menu - Very little reason to have this considering the timeout is so long to begin with, and spellbooks are much more common." In Soviet Russia, people aren't a fan of games with good interfaces, and rather like it if there's as little information conveyed to the player as possible. The next things they'll remove are those obsolete things displayed on the bottom status line, like HP, AC and experience level; there's very little reason to display them either. Ah wait, they might just borrow the spell loss trap and display loss trap code from Slash'EM Extended and make their effect permanent - that gets rid of all the useless information displays at once, and players will be forever grateful! --Amy */
11754 SpellColorCyan
? 100 : issoviet
? 0 : (spellknow(i
) * 100 + (KEEN
-1)) / KEEN
);
11755 if (flags
.menu_style
== MENU_TRADITIONAL
)
11756 sprintf(eos(buf
), iflags
.menu_tab_sep
?
11757 "\t%c" : "%4c ", spellet(i
) ? spellet(i
) : ' ');
11759 any
.a_int
= i
+1; /* must be non-zero */
11760 add_menu(tmpwin
, NO_GLYPH
, &any
,
11761 0, 0, ATR_NONE
, buf
,
11762 (i
== splaction
) ? MENU_SELECTED
: MENU_UNSELECTED
);
11765 else {for (i
= 0; i
< MAXSPELL
&& spellid(i
) != NO_SPELL
; i
++) {
11766 sprintf(buf
, iflags
.menu_tab_sep
?
11767 "\t%c" : "%4c ", spellet(i
) ? spellet(i
) : ' ');
11768 any
.a_int
= i
+1; /* must be non-zero */
11769 add_menu(tmpwin
, NO_GLYPH
, &any
,
11770 0, 0, ATR_NONE
, buf
,
11771 (i
== splaction
) ? MENU_SELECTED
: MENU_UNSELECTED
);
11776 if (splaction
== SPELLMENU_VIEW
) {
11777 if (specialmenutype
== 0) {
11778 any
.a_int
= -1; /* must be non-zero */
11779 add_menu(tmpwin
, NO_GLYPH
, &any
,
11780 '?', 0, ATR_NONE
, "Describe a spell instead",
11783 else if (specialmenutype
== 1) {
11784 any
.a_int
= -1; /* must be non-zero */
11785 add_menu(tmpwin
, NO_GLYPH
, &any
,
11786 '?', 0, ATR_NONE
, "Memorize a spell instead",
11789 else if (specialmenutype
== 2) {
11790 any
.a_int
= -1; /* must be non-zero */
11791 add_menu(tmpwin
, NO_GLYPH
, &any
,
11792 '?', 0, ATR_NONE
, "View spells instead",
11797 end_menu(tmpwin
, prompt
);
11800 /*if (splaction == SPELLMENU_VIEW && spellid(1) == NO_SPELL)
11801 how = PICK_NONE;*/ /* only one spell => nothing to swap with */ /* Amy edit: blah, we have the ? option now */
11802 n
= select_menu(tmpwin
, how
, &selected
);
11803 destroy_nhwindow(tmpwin
);
11804 if (n
> 0 && selected
[0].item
.a_int
== -1) {
11806 char spellcolorbuf
[BUFSZ
];
11808 if (SpellColorPink
) sprintf(spellcolorbuf
, "Your spells are pink.");
11809 else if (SpellColorBrightCyan
) sprintf(spellcolorbuf
, "Your spells are bright cyan.");
11810 else if (SpellColorCyan
) sprintf(spellcolorbuf
, "Your spells are cyan.");
11811 else if (SpellColorBlack
) sprintf(spellcolorbuf
, "Your spells are black.");
11812 else if (SpellColorOrange
) sprintf(spellcolorbuf
, "Your spells are orange.");
11813 else if (SpellColorRed
) sprintf(spellcolorbuf
, "Your spells are red.");
11814 else if (SpellColorPlatinum
) sprintf(spellcolorbuf
, "Your spells are platinum.");
11815 else if (SpellColorSilver
) sprintf(spellcolorbuf
, "Your spells are silver.");
11816 else if (SpellColorMetal
) sprintf(spellcolorbuf
, "Your spells are metal.");
11817 else if (SpellColorGreen
) sprintf(spellcolorbuf
, "Your spells are green.");
11818 else if (SpellColorBlue
) sprintf(spellcolorbuf
, "Your spells are blue.");
11819 else if (SpellColorGray
) sprintf(spellcolorbuf
, "Your spells are completely gray.");
11820 else if (SpellColorBrown
) sprintf(spellcolorbuf
, "Your spells are brown.");
11821 else if (SpellColorWhite
) sprintf(spellcolorbuf
, "Your spells are white.");
11822 else if (SpellColorViolet
) sprintf(spellcolorbuf
, "Your spells are violet.");
11823 else if (SpellColorYellow
) sprintf(spellcolorbuf
, "Your spells are yellow.");
11824 else if (specialmenutype
== 0) sprintf(spellcolorbuf
, "Choose a spell to describe");
11825 else if (specialmenutype
== 1) sprintf(spellcolorbuf
, "Choose a spell to (de-)memorize");
11826 else if (specialmenutype
== 2) sprintf(spellcolorbuf
, "Currently known spells");
11827 else sprintf(spellcolorbuf
, "Bug: unknown spell menu title");
11829 return dospellmenu(spellcolorbuf
, splaction
, spell_no
, (specialmenutype
== 2) ? 0 : (specialmenutype
+ 1));
11831 if (n
> 0 && splaction
== SPELLMENU_VIEW
&& specialmenutype
== 1) { /* describe */
11833 register struct obj
*pseudo
;
11835 pseudo
= mksobj(spellid(selected
[0].item
.a_int
- 1), FALSE
, 2, FALSE
);
11837 impossible("bugged pseudo object for spell description.");
11838 return dospellmenu(prompt
, splaction
, spell_no
, specialmenutype
);
11840 if (pseudo
->otyp
== GOLD_PIECE
) pseudo
->otyp
= spellid(selected
[0].item
.a_int
- 1); /* minimalist fix */
11841 pseudo
->blessed
= pseudo
->cursed
= 0;
11842 pseudo
->quan
= 20L; /* do not let useup get it */
11844 if (SpellLoss
|| u
.uprops
[SPELLS_LOST
].extrinsic
|| have_spelllossstone()) {
11845 /* you cheater! you're not supposed to see what the spells are :P */
11846 return dospellmenu(prompt
, splaction
, spell_no
, specialmenutype
);
11849 (void) itemactions(pseudo
, TRUE
, TRUE
);
11850 obfree(pseudo
, (struct obj
*)0); /* now, get rid of it */
11851 return dospellmenu(prompt
, splaction
, spell_no
, specialmenutype
);
11853 if (n
> 0 && splaction
== SPELLMENU_VIEW
&& specialmenutype
== 2) { /* memorize */
11855 spl_book
[selected
[0].item
.a_int
- 1].sp_memorize
= !spl_book
[selected
[0].item
.a_int
- 1].sp_memorize
;
11857 char spellcolorbuf
[BUFSZ
];
11859 if (SpellLoss
|| u
.uprops
[SPELLS_LOST
].extrinsic
|| have_spelllossstone()) sprintf(spellcolorbuf
, "Memorization setting changed."); /* no, you don't get to see what it is now :P */
11860 else if (spl_book
[selected
[0].item
.a_int
- 1].sp_memorize
) sprintf(spellcolorbuf
, "Spell set to memorization mode!");
11861 else sprintf(spellcolorbuf
, "Memorization for this spell deactivated.");
11863 return dospellmenu(spellcolorbuf
, splaction
, spell_no
, specialmenutype
);
11866 *spell_no
= selected
[0].item
.a_int
- 1;
11867 /* menu selection for `PICK_ONE' does not
11868 de-select any preselected entry */
11869 if (n
> 1 && *spell_no
== splaction
)
11870 *spell_no
= selected
[1].item
.a_int
- 1;
11871 free((void *)selected
);
11872 /* default selection of preselected spell means that
11873 user chose not to swap it with anything */
11874 if (*spell_no
== splaction
) return FALSE
;
11876 } else if (splaction
>= 0) {
11877 /* explicit de-selection of preselected spell means that
11878 user is still swapping but not for the current spell */
11879 *spell_no
= splaction
;
11892 if (spellid(0) == NO_SPELL
) {
11893 dump("", "You didn't know any spells.");
11897 dump("", "Spells known in the end");
11899 sprintf(buf
, "%-20s Level Pw %-10s Fail Memory", " Name", " Category");
11901 for (i
= 0; i
< MAXSPELL
&& spellid(i
) != NO_SPELL
; i
++) {
11902 sprintf(buf
, "%c - %-19s %2d%s%s %3d %-8s %4d%% %3d%%",
11903 spellet(i
), spellname(i
), spellev(i
),
11904 ((spellknow(i
) > 1000) || SpellColorCyan
) ? " " : (spellknow(i
) ? "!" : "*"),
11905 spellmemorize(i
) ? "+" : "-",
11906 manacost(spellid(i
)),
11907 spelltypemnemonic(spell_skilltype(spellid(i
))),
11908 SpellColorBlack
? 0 : (100 - percent_success(i
)),
11909 SpellColorCyan
? 100 : issoviet
? 0 : (spellknow(i
) * 100 + (KEEN
-1)) / KEEN
);
11910 /* In Soviet Russia, people don't want to know how much spell memory they have left. --Amy */
11915 } /* dump_spells */
11918 /* Integer square root function without using floating point. */
11925 while(val
>= odd
) {
11935 percent_success(spell
)
11938 /* Intrinsic and learned ability are combined to calculate
11939 * the probability of player's success at cast a given spell.
11941 int chance
, splcaster
, special
, statused
;
11944 int armorpenalties
= 15;
11945 int shieldpenalties
= 15;
11947 if (!(PlayerCannotUseSkills
)) {
11948 switch (P_SKILL(P_BODY_ARMOR
)) {
11949 case P_BASIC
: armorpenalties
= 13; break;
11950 case P_SKILLED
: armorpenalties
= 11; break;
11951 case P_EXPERT
: armorpenalties
= 9; break;
11952 case P_MASTER
: armorpenalties
= 7; break;
11953 case P_GRAND_MASTER
: armorpenalties
= 5; break;
11954 case P_SUPREME_MASTER
: armorpenalties
= 3; break;
11959 if (!(PlayerCannotUseSkills
)) {
11960 switch (P_SKILL(P_SHIELD
)) {
11961 case P_BASIC
: shieldpenalties
= 13; break;
11962 case P_SKILLED
: shieldpenalties
= 11; break;
11963 case P_EXPERT
: shieldpenalties
= 9; break;
11964 case P_MASTER
: shieldpenalties
= 7; break;
11965 case P_GRAND_MASTER
: shieldpenalties
= 5; break;
11966 case P_SUPREME_MASTER
: shieldpenalties
= 3; break;
11971 splcaster
= urole
.spelbase
;
11972 special
= urole
.spelheal
;
11973 statused
= ACURR(urole
.spelstat
);
11975 /* Calculate armor penalties */
11976 if (uarm
&& !SpellColorMetal
&& !(uarm
->blessed
&& !issoviet
) && !(uarm
->otyp
>= ELVEN_TOGA
&& uarm
->otyp
<= ROBE_OF_WEAKNESS
) && !(uarm
->oartifact
== ART_HA_MONK
) && !(uarm
->oartifact
== ART_BOBAIS
) && !(uarm
->oartifact
== ART_AMMY_S_RETRIBUTION
) )
11977 splcaster
+= (issoviet
? 2 : 1);
11979 /* Robes are body armour in SLASH'EM */
11980 if (uarm
&& !SpellColorMetal
&& (is_metallic(uarm
) || is_filmitem(uarm
)) && !is_etheritem(uarm
) && !is_meteosteelitem(uarm
)) {
11982 /* Amy grepping target: "materialeffect" */
11983 /* baseline = 15, used by iron, alumen and sinnum */
11984 switch (objects
[(uarm
)->otyp
].oc_material
) {
11986 case MT_METAL
: armorpenalties
*= 16; armorpenalties
/= 15; break;
11987 case MT_STEEL
: armorpenalties
*= 16; armorpenalties
/= 15; break;
11988 case MT_GREEN_STEEL
: armorpenalties
*= 12; armorpenalties
/= 15; break;
11989 case MT_MERCURIAL
: armorpenalties
*= 3; armorpenalties
/= 15; break;
11990 case MT_BRONZE
: armorpenalties
*= 21; armorpenalties
/= 15; break;
11991 case MT_TITANIUM
: armorpenalties
*= 18; armorpenalties
/= 15; break;
11992 case MT_COPPER
: armorpenalties
*= 17; armorpenalties
/= 15; break;
11993 case MT_COBALT
: armorpenalties
*= 16; armorpenalties
/= 15; break;
11994 case MT_SILVER
: armorpenalties
*= 17; armorpenalties
/= 15; break;
11995 case MT_GOLD
: armorpenalties
*= 8; armorpenalties
/= 15; break;
11996 case MT_TINSEL
: armorpenalties
*= 10; armorpenalties
/= 15; break;
11997 case MT_PLATINUM
: armorpenalties
*= 18; armorpenalties
/= 15; break;
11998 case MT_FILM
: armorpenalties
*= 18; armorpenalties
/= 15; break;
11999 case MT_ALLOY
: armorpenalties
*= 18; armorpenalties
/= 15; break;
12000 case MT_MITHRIL
: armorpenalties
*= 13; armorpenalties
/= 15; break;
12001 case MT_VIVA
: armorpenalties
*= 12; armorpenalties
/= 15; break;
12002 case MT_POURPOOR
: armorpenalties
*= 20; armorpenalties
/= 15; break;
12003 case MT_LEAD
: armorpenalties
*= 25; armorpenalties
/= 15; break;
12004 case MT_CHROME
: armorpenalties
*= 11; armorpenalties
/= 15; break;
12006 if (Race_if(PM_BOVER
)) armorpenalties
*= 3;
12008 if (uwep
&& (weapon_type(uwep
) == P_QUARTERSTAFF
|| weapon_type(uwep
) == P_ORB
)) {
12009 armorpenalties
*= 4;
12010 armorpenalties
/= 5;
12013 if (uarmg
&& itemhasappearance(uarmg
, APP_VELVET_GLOVES
) ) armorpenalties
/= 2;
12014 if (uarmh
&& uarmh
->oartifact
== ART_METAL_NEGATER
) armorpenalties
/= 2;
12016 if (uarm
&& uarm
->blessed
&& !issoviet
) armorpenalties
/= 2;
12018 splcaster
+= (urole
.spelarmr
* armorpenalties
/ (issoviet
? 12 : 30));
12020 if (SpellColorMetal
&& (!uarm
|| !is_metallic(uarm
))) {
12022 if (uwep
&& (weapon_type(uwep
) == P_QUARTERSTAFF
|| weapon_type(uwep
) == P_ORB
)) {
12023 armorpenalties
*= 4;
12024 armorpenalties
/= 5;
12027 if (uarmg
&& itemhasappearance(uarmg
, APP_VELVET_GLOVES
) ) armorpenalties
/= 2;
12028 if (uarmh
&& uarmh
->oartifact
== ART_METAL_NEGATER
) armorpenalties
/= 2;
12030 if (uarm
&& uarm
->blessed
&& !issoviet
) armorpenalties
/= 2;
12032 splcaster
+= (urole
.spelarmr
* armorpenalties
/ (issoviet
? 12 : 30));
12035 if (uarmc
&& !SpellColorMetal
&& (is_metallic(uarmc
) || is_filmitem(uarmc
)) && !is_etheritem(uarmc
) && !is_meteosteelitem(uarmc
)) {
12037 switch (objects
[(uarmc
)->otyp
].oc_material
) {
12039 case MT_METAL
: armorpenalties
*= 16; armorpenalties
/= 15; break;
12040 case MT_STEEL
: armorpenalties
*= 16; armorpenalties
/= 15; break;
12041 case MT_GREEN_STEEL
: armorpenalties
*= 12; armorpenalties
/= 15; break;
12042 case MT_MERCURIAL
: armorpenalties
*= 3; armorpenalties
/= 15; break;
12043 case MT_BRONZE
: armorpenalties
*= 21; armorpenalties
/= 15; break;
12044 case MT_TITANIUM
: armorpenalties
*= 18; armorpenalties
/= 15; break;
12045 case MT_COPPER
: armorpenalties
*= 17; armorpenalties
/= 15; break;
12046 case MT_COBALT
: armorpenalties
*= 16; armorpenalties
/= 15; break;
12047 case MT_SILVER
: armorpenalties
*= 17; armorpenalties
/= 15; break;
12048 case MT_GOLD
: armorpenalties
*= 8; armorpenalties
/= 15; break;
12049 case MT_TINSEL
: armorpenalties
*= 10; armorpenalties
/= 15; break;
12050 case MT_PLATINUM
: armorpenalties
*= 18; armorpenalties
/= 15; break;
12051 case MT_FILM
: armorpenalties
*= 18; armorpenalties
/= 15; break;
12052 case MT_ALLOY
: armorpenalties
*= 18; armorpenalties
/= 15; break;
12053 case MT_MITHRIL
: armorpenalties
*= 13; armorpenalties
/= 15; break;
12054 case MT_VIVA
: armorpenalties
*= 12; armorpenalties
/= 15; break;
12055 case MT_POURPOOR
: armorpenalties
*= 20; armorpenalties
/= 15; break;
12056 case MT_LEAD
: armorpenalties
*= 25; armorpenalties
/= 15; break;
12057 case MT_CHROME
: armorpenalties
*= 11; armorpenalties
/= 15; break;
12059 if (Race_if(PM_BOVER
)) armorpenalties
*= 3;
12061 if (uwep
&& (weapon_type(uwep
) == P_QUARTERSTAFF
|| weapon_type(uwep
) == P_ORB
)) {
12062 armorpenalties
*= 4;
12063 armorpenalties
/= 5;
12066 if (uarmg
&& itemhasappearance(uarmg
, APP_VELVET_GLOVES
) ) armorpenalties
/= 2;
12067 if (uarmh
&& uarmh
->oartifact
== ART_METAL_NEGATER
) armorpenalties
/= 2;
12069 if (uarmc
&& uarmc
->blessed
&& !issoviet
) armorpenalties
/= 2;
12071 splcaster
+= (urole
.spelarmr
* armorpenalties
/ (issoviet
? 36 : 50));
12073 if (SpellColorMetal
&& (!uarmc
|| !is_metallic(uarmc
))) {
12075 if (uwep
&& (weapon_type(uwep
) == P_QUARTERSTAFF
|| weapon_type(uwep
) == P_ORB
)) {
12076 armorpenalties
*= 4;
12077 armorpenalties
/= 5;
12080 if (uarmg
&& itemhasappearance(uarmg
, APP_VELVET_GLOVES
) ) armorpenalties
/= 2;
12081 if (uarmh
&& uarmh
->oartifact
== ART_METAL_NEGATER
) armorpenalties
/= 2;
12083 if (uarmc
&& uarmc
->blessed
&& !issoviet
) armorpenalties
/= 2;
12085 splcaster
+= (urole
.spelarmr
* armorpenalties
/ (issoviet
? 36 : 50));
12089 if (uarmu
&& !SpellColorMetal
&& (is_metallic(uarmu
) || is_filmitem(uarmu
)) && !is_etheritem(uarmu
) && !is_meteosteelitem(uarmu
)) {
12091 switch (objects
[(uarmu
)->otyp
].oc_material
) {
12093 case MT_METAL
: armorpenalties
*= 16; armorpenalties
/= 15; break;
12094 case MT_STEEL
: armorpenalties
*= 16; armorpenalties
/= 15; break;
12095 case MT_GREEN_STEEL
: armorpenalties
*= 12; armorpenalties
/= 15; break;
12096 case MT_MERCURIAL
: armorpenalties
*= 3; armorpenalties
/= 15; break;
12097 case MT_BRONZE
: armorpenalties
*= 21; armorpenalties
/= 15; break;
12098 case MT_TITANIUM
: armorpenalties
*= 18; armorpenalties
/= 15; break;
12099 case MT_COPPER
: armorpenalties
*= 17; armorpenalties
/= 15; break;
12100 case MT_COBALT
: armorpenalties
*= 16; armorpenalties
/= 15; break;
12101 case MT_SILVER
: armorpenalties
*= 17; armorpenalties
/= 15; break;
12102 case MT_GOLD
: armorpenalties
*= 8; armorpenalties
/= 15; break;
12103 case MT_TINSEL
: armorpenalties
*= 10; armorpenalties
/= 15; break;
12104 case MT_PLATINUM
: armorpenalties
*= 18; armorpenalties
/= 15; break;
12105 case MT_FILM
: armorpenalties
*= 18; armorpenalties
/= 15; break;
12106 case MT_ALLOY
: armorpenalties
*= 18; armorpenalties
/= 15; break;
12107 case MT_MITHRIL
: armorpenalties
*= 13; armorpenalties
/= 15; break;
12108 case MT_VIVA
: armorpenalties
*= 12; armorpenalties
/= 15; break;
12109 case MT_POURPOOR
: armorpenalties
*= 20; armorpenalties
/= 15; break;
12110 case MT_LEAD
: armorpenalties
*= 25; armorpenalties
/= 15; break;
12111 case MT_CHROME
: armorpenalties
*= 11; armorpenalties
/= 15; break;
12113 if (Race_if(PM_BOVER
)) armorpenalties
*= 3;
12115 if (uwep
&& (weapon_type(uwep
) == P_QUARTERSTAFF
|| weapon_type(uwep
) == P_ORB
)) {
12116 armorpenalties
*= 4;
12117 armorpenalties
/= 5;
12120 if (uarmg
&& itemhasappearance(uarmg
, APP_VELVET_GLOVES
) ) armorpenalties
/= 2;
12121 if (uarmh
&& uarmh
->oartifact
== ART_METAL_NEGATER
) armorpenalties
/= 2;
12123 if (uarmu
&& uarmu
->blessed
&& !issoviet
) armorpenalties
/= 2;
12125 splcaster
+= (urole
.spelarmr
* armorpenalties
/ (issoviet
? 72 : 100));
12127 if (SpellColorMetal
&& (!uarmu
|| !is_metallic(uarmu
))) {
12129 if (uwep
&& (weapon_type(uwep
) == P_QUARTERSTAFF
|| weapon_type(uwep
) == P_ORB
)) {
12130 armorpenalties
*= 4;
12131 armorpenalties
/= 5;
12134 if (uarmg
&& itemhasappearance(uarmg
, APP_VELVET_GLOVES
) ) armorpenalties
/= 2;
12135 if (uarmh
&& uarmh
->oartifact
== ART_METAL_NEGATER
) armorpenalties
/= 2;
12137 if (uarmu
&& uarmu
->blessed
&& !issoviet
) armorpenalties
/= 2;
12139 splcaster
+= (urole
.spelarmr
* armorpenalties
/ (issoviet
? 72 : 100));
12143 if (uarms
&& !SpellColorMetal
) {
12144 if (!is_metallic(uarms
) || is_etheritem(uarms
) || is_meteosteelitem(uarms
)) shieldpenalties
/= 3;
12146 switch (objects
[(uarms
)->otyp
].oc_material
) {
12148 case MT_METAL
: shieldpenalties
*= 16; shieldpenalties
/= 15; break;
12149 case MT_STEEL
: shieldpenalties
*= 16; shieldpenalties
/= 15; break;
12150 case MT_GREEN_STEEL
: shieldpenalties
*= 12; shieldpenalties
/= 15; break;
12151 case MT_MERCURIAL
: shieldpenalties
*= 3; shieldpenalties
/= 15; break;
12152 case MT_BRONZE
: shieldpenalties
*= 21; shieldpenalties
/= 15; break;
12153 case MT_TITANIUM
: shieldpenalties
*= 18; shieldpenalties
/= 15; break;
12154 case MT_COPPER
: shieldpenalties
*= 17; shieldpenalties
/= 15; break;
12155 case MT_COBALT
: shieldpenalties
*= 16; shieldpenalties
/= 15; break;
12156 case MT_SILVER
: shieldpenalties
*= 17; shieldpenalties
/= 15; break;
12157 case MT_GOLD
: shieldpenalties
*= 8; shieldpenalties
/= 15; break;
12158 case MT_TINSEL
: shieldpenalties
*= 10; shieldpenalties
/= 15; break;
12159 case MT_PLATINUM
: shieldpenalties
*= 18; shieldpenalties
/= 15; break;
12160 case MT_FILM
: shieldpenalties
*= 18; shieldpenalties
/= 15; break;
12161 case MT_ALLOY
: shieldpenalties
*= 18; shieldpenalties
/= 15; break;
12162 case MT_MITHRIL
: shieldpenalties
*= 13; shieldpenalties
/= 15; break;
12163 case MT_VIVA
: shieldpenalties
*= 12; shieldpenalties
/= 15; break;
12164 case MT_POURPOOR
: shieldpenalties
*= 20; shieldpenalties
/= 15; break;
12165 case MT_LEAD
: shieldpenalties
*= 25; shieldpenalties
/= 15; break;
12166 case MT_CHROME
: shieldpenalties
*= 11; shieldpenalties
/= 15; break;
12168 if (Race_if(PM_BOVER
)) shieldpenalties
*= 3;
12170 if (uwep
&& (weapon_type(uwep
) == P_QUARTERSTAFF
|| weapon_type(uwep
) == P_ORB
)) {
12171 shieldpenalties
*= 4;
12172 shieldpenalties
/= 5;
12175 if (uarmg
&& itemhasappearance(uarmg
, APP_VELVET_GLOVES
) ) shieldpenalties
/= 2;
12176 if (uarmh
&& uarmh
->oartifact
== ART_METAL_NEGATER
) shieldpenalties
/= 2;
12178 if (uarms
&& uarms
->blessed
&& !issoviet
) shieldpenalties
/= 2;
12180 splcaster
+= (urole
.spelshld
* shieldpenalties
/ (issoviet
? 12 : 30));
12182 if (SpellColorMetal
&& (!uarms
|| !is_metallic(uarms
))) {
12184 if (uwep
&& (weapon_type(uwep
) == P_QUARTERSTAFF
|| weapon_type(uwep
) == P_ORB
)) {
12185 shieldpenalties
*= 4;
12186 shieldpenalties
/= 5;
12189 if (uarmg
&& itemhasappearance(uarmg
, APP_VELVET_GLOVES
) ) shieldpenalties
/= 2;
12190 if (uarmh
&& uarmh
->oartifact
== ART_METAL_NEGATER
) shieldpenalties
/= 2;
12192 if (uarms
&& uarms
->blessed
&& !issoviet
) shieldpenalties
/= 2;
12194 splcaster
+= (urole
.spelshld
* shieldpenalties
/ (issoviet
? 12 : 30));
12198 if (uarmh
&& !SpellColorMetal
&& (is_metallic(uarmh
) || is_filmitem(uarmh
)) && !is_etheritem(uarmh
) && !is_meteosteelitem(uarmh
) && uarmh
->otyp
!= HELM_OF_BRILLIANCE
) {
12200 switch (objects
[(uarmh
)->otyp
].oc_material
) {
12202 case MT_METAL
: armorpenalties
*= 16; armorpenalties
/= 15; break;
12203 case MT_STEEL
: armorpenalties
*= 16; armorpenalties
/= 15; break;
12204 case MT_GREEN_STEEL
: armorpenalties
*= 12; armorpenalties
/= 15; break;
12205 case MT_MERCURIAL
: armorpenalties
*= 3; armorpenalties
/= 15; break;
12206 case MT_BRONZE
: armorpenalties
*= 21; armorpenalties
/= 15; break;
12207 case MT_TITANIUM
: armorpenalties
*= 18; armorpenalties
/= 15; break;
12208 case MT_COPPER
: armorpenalties
*= 17; armorpenalties
/= 15; break;
12209 case MT_COBALT
: armorpenalties
*= 16; armorpenalties
/= 15; break;
12210 case MT_SILVER
: armorpenalties
*= 17; armorpenalties
/= 15; break;
12211 case MT_GOLD
: armorpenalties
*= 8; armorpenalties
/= 15; break;
12212 case MT_TINSEL
: armorpenalties
*= 10; armorpenalties
/= 15; break;
12213 case MT_PLATINUM
: armorpenalties
*= 18; armorpenalties
/= 15; break;
12214 case MT_FILM
: armorpenalties
*= 18; armorpenalties
/= 15; break;
12215 case MT_ALLOY
: armorpenalties
*= 18; armorpenalties
/= 15; break;
12216 case MT_MITHRIL
: armorpenalties
*= 13; armorpenalties
/= 15; break;
12217 case MT_VIVA
: armorpenalties
*= 12; armorpenalties
/= 15; break;
12218 case MT_POURPOOR
: armorpenalties
*= 20; armorpenalties
/= 15; break;
12219 case MT_LEAD
: armorpenalties
*= 25; armorpenalties
/= 15; break;
12220 case MT_CHROME
: armorpenalties
*= 11; armorpenalties
/= 15; break;
12222 if (Race_if(PM_BOVER
)) armorpenalties
*= 3;
12224 if (uwep
&& (weapon_type(uwep
) == P_QUARTERSTAFF
|| weapon_type(uwep
) == P_ORB
)) {
12225 armorpenalties
*= 4;
12226 armorpenalties
/= 5;
12229 if (uarmg
&& itemhasappearance(uarmg
, APP_VELVET_GLOVES
) ) armorpenalties
/= 2;
12230 if (uarmh
&& uarmh
->oartifact
== ART_METAL_NEGATER
) armorpenalties
/= 2;
12232 if (uarmh
&& uarmh
->blessed
&& !issoviet
) armorpenalties
/= 2;
12234 splcaster
+= (uarmhbon
* armorpenalties
/ (issoviet
? 10 : 20));
12236 if (SpellColorMetal
&& (!uarmh
|| !is_metallic(uarmh
))) {
12238 if (uwep
&& (weapon_type(uwep
) == P_QUARTERSTAFF
|| weapon_type(uwep
) == P_ORB
)) {
12239 armorpenalties
*= 4;
12240 armorpenalties
/= 5;
12243 if (uarmg
&& itemhasappearance(uarmg
, APP_VELVET_GLOVES
) ) armorpenalties
/= 2;
12244 if (uarmh
&& uarmh
->oartifact
== ART_METAL_NEGATER
) armorpenalties
/= 2;
12246 if (uarmh
&& uarmh
->blessed
&& !issoviet
) armorpenalties
/= 2;
12248 splcaster
+= (uarmhbon
* armorpenalties
/ (issoviet
? 10 : 20));
12252 if (uarmg
&& !SpellColorMetal
&& (is_metallic(uarmg
) || is_filmitem(uarmg
)) && !is_etheritem(uarmg
) && !is_meteosteelitem(uarmg
)) {
12254 switch (objects
[(uarmg
)->otyp
].oc_material
) {
12256 case MT_METAL
: armorpenalties
*= 16; armorpenalties
/= 15; break;
12257 case MT_STEEL
: armorpenalties
*= 16; armorpenalties
/= 15; break;
12258 case MT_GREEN_STEEL
: armorpenalties
*= 12; armorpenalties
/= 15; break;
12259 case MT_MERCURIAL
: armorpenalties
*= 3; armorpenalties
/= 15; break;
12260 case MT_BRONZE
: armorpenalties
*= 21; armorpenalties
/= 15; break;
12261 case MT_TITANIUM
: armorpenalties
*= 18; armorpenalties
/= 15; break;
12262 case MT_COPPER
: armorpenalties
*= 17; armorpenalties
/= 15; break;
12263 case MT_COBALT
: armorpenalties
*= 16; armorpenalties
/= 15; break;
12264 case MT_SILVER
: armorpenalties
*= 17; armorpenalties
/= 15; break;
12265 case MT_GOLD
: armorpenalties
*= 8; armorpenalties
/= 15; break;
12266 case MT_TINSEL
: armorpenalties
*= 10; armorpenalties
/= 15; break;
12267 case MT_PLATINUM
: armorpenalties
*= 18; armorpenalties
/= 15; break;
12268 case MT_FILM
: armorpenalties
*= 18; armorpenalties
/= 15; break;
12269 case MT_ALLOY
: armorpenalties
*= 18; armorpenalties
/= 15; break;
12270 case MT_MITHRIL
: armorpenalties
*= 13; armorpenalties
/= 15; break;
12271 case MT_VIVA
: armorpenalties
*= 12; armorpenalties
/= 15; break;
12272 case MT_POURPOOR
: armorpenalties
*= 20; armorpenalties
/= 15; break;
12273 case MT_LEAD
: armorpenalties
*= 25; armorpenalties
/= 15; break;
12274 case MT_CHROME
: armorpenalties
*= 11; armorpenalties
/= 15; break;
12276 if (Race_if(PM_BOVER
)) armorpenalties
*= 3;
12278 if (uwep
&& (weapon_type(uwep
) == P_QUARTERSTAFF
|| weapon_type(uwep
) == P_ORB
)) {
12279 armorpenalties
*= 4;
12280 armorpenalties
/= 5;
12283 if (uarmg
&& itemhasappearance(uarmg
, APP_VELVET_GLOVES
) ) armorpenalties
/= 2;
12284 if (uarmh
&& uarmh
->oartifact
== ART_METAL_NEGATER
) armorpenalties
/= 2;
12286 if (uarmg
&& uarmg
->blessed
&& !issoviet
) armorpenalties
/= 2;
12288 splcaster
+= (uarmgbon
* armorpenalties
/ (issoviet
? 10 : 20));
12290 if (SpellColorMetal
&& (!uarmg
|| !is_metallic(uarmg
))) {
12292 if (uwep
&& (weapon_type(uwep
) == P_QUARTERSTAFF
|| weapon_type(uwep
) == P_ORB
)) {
12293 armorpenalties
*= 4;
12294 armorpenalties
/= 5;
12297 if (uarmg
&& itemhasappearance(uarmg
, APP_VELVET_GLOVES
) ) armorpenalties
/= 2;
12298 if (uarmh
&& uarmh
->oartifact
== ART_METAL_NEGATER
) armorpenalties
/= 2;
12300 if (uarmg
&& uarmg
->blessed
&& !issoviet
) armorpenalties
/= 2;
12302 splcaster
+= (uarmgbon
* armorpenalties
/ (issoviet
? 10 : 20));
12306 if (uarmf
&& !SpellColorMetal
&& (is_metallic(uarmf
) || is_filmitem(uarmf
)) && !is_etheritem(uarmf
) && !is_meteosteelitem(uarmf
)) {
12308 switch (objects
[(uarmf
)->otyp
].oc_material
) {
12310 case MT_METAL
: armorpenalties
*= 16; armorpenalties
/= 15; break;
12311 case MT_STEEL
: armorpenalties
*= 16; armorpenalties
/= 15; break;
12312 case MT_GREEN_STEEL
: armorpenalties
*= 12; armorpenalties
/= 15; break;
12313 case MT_MERCURIAL
: armorpenalties
*= 3; armorpenalties
/= 15; break;
12314 case MT_BRONZE
: armorpenalties
*= 21; armorpenalties
/= 15; break;
12315 case MT_TITANIUM
: armorpenalties
*= 18; armorpenalties
/= 15; break;
12316 case MT_COPPER
: armorpenalties
*= 17; armorpenalties
/= 15; break;
12317 case MT_COBALT
: armorpenalties
*= 16; armorpenalties
/= 15; break;
12318 case MT_SILVER
: armorpenalties
*= 17; armorpenalties
/= 15; break;
12319 case MT_GOLD
: armorpenalties
*= 8; armorpenalties
/= 15; break;
12320 case MT_TINSEL
: armorpenalties
*= 10; armorpenalties
/= 15; break;
12321 case MT_PLATINUM
: armorpenalties
*= 18; armorpenalties
/= 15; break;
12322 case MT_FILM
: armorpenalties
*= 18; armorpenalties
/= 15; break;
12323 case MT_ALLOY
: armorpenalties
*= 18; armorpenalties
/= 15; break;
12324 case MT_MITHRIL
: armorpenalties
*= 13; armorpenalties
/= 15; break;
12325 case MT_VIVA
: armorpenalties
*= 12; armorpenalties
/= 15; break;
12326 case MT_POURPOOR
: armorpenalties
*= 20; armorpenalties
/= 15; break;
12327 case MT_LEAD
: armorpenalties
*= 25; armorpenalties
/= 15; break;
12328 case MT_CHROME
: armorpenalties
*= 11; armorpenalties
/= 15; break;
12330 if (Race_if(PM_BOVER
)) armorpenalties
*= 3;
12332 if (uwep
&& (weapon_type(uwep
) == P_QUARTERSTAFF
|| weapon_type(uwep
) == P_ORB
)) {
12333 armorpenalties
*= 4;
12334 armorpenalties
/= 5;
12337 if (uarmg
&& itemhasappearance(uarmg
, APP_VELVET_GLOVES
) ) armorpenalties
/= 2;
12338 if (uarmh
&& uarmh
->oartifact
== ART_METAL_NEGATER
) armorpenalties
/= 2;
12340 if (uarmf
&& uarmf
->blessed
&& !issoviet
) armorpenalties
/= 2;
12342 splcaster
+= (uarmfbon
* armorpenalties
/ (issoviet
? 10 : 20));
12345 if (SpellColorMetal
&& (!uarmf
|| !is_metallic(uarmf
))) {
12347 if (uwep
&& (weapon_type(uwep
) == P_QUARTERSTAFF
|| weapon_type(uwep
) == P_ORB
)) {
12348 armorpenalties
*= 4;
12349 armorpenalties
/= 5;
12352 if (uarmg
&& itemhasappearance(uarmg
, APP_VELVET_GLOVES
) ) armorpenalties
/= 2;
12353 if (uarmh
&& uarmh
->oartifact
== ART_METAL_NEGATER
) armorpenalties
/= 2;
12355 if (uarmf
&& uarmf
->blessed
&& !issoviet
) armorpenalties
/= 2;
12357 splcaster
+= (uarmfbon
* armorpenalties
/ (issoviet
? 10 : 20));
12361 if (spellid(spell
) == urole
.spelspec
)
12362 splcaster
+= urole
.spelsbon
;
12364 if (spellid(spell
) == u
.superspecialspell
)
12367 /* `healing spell' bonus */
12368 if (spell_skilltype(spellid(spell
)) == P_HEALING_SPELL
)
12369 splcaster
+= special
;
12371 if (uarm
&& uarm
->otyp
== ROBE_OF_POWER
) splcaster
-= 3;
12372 if (uarm
&& uarm
->otyp
== ROBE_OF_SPELL_POWER
) splcaster
-= 3;
12373 if (uarmg
&& uarmg
->oartifact
== ART_GAUNTLETS_OF_SPELL_POWER
) splcaster
-= 3;
12374 if (uarm
&& uarm
->oartifact
== ART_SPIDERSILK
) splcaster
-= 3;
12375 if (uarm
&& uarm
->oartifact
== ART_WEB_OF_LOLTH
) splcaster
-= 3;
12376 if (uarm
&& uarm
->oartifact
== ART_WEB_OF_HOHOTH
) splcaster
-= 3;
12377 if (uwep
&& uwep
->oartifact
== ART_ARYFAERN_KERYM
) splcaster
-= 3;
12379 if (Role_if(PM_PALADIN
)) splcaster
-= 3; /* it is assumed some of their power is granted by the Lord of Light himself */
12382 /* Calculate learned ability */
12384 /* Players basic likelihood of being able to cast any spell
12385 * is based of their `magic' statistic. (Int or Wis)
12387 chance
= 11 * statused
/ 2;
12390 * High level spells are harder. Easier for higher level casters.
12391 * The difficulty is based on the hero's level and their skill level
12392 * in that spell type.
12394 skill
= P_SKILL(spell_skilltype(spellid(spell
)));
12395 if (PlayerCannotUseSkills
) skill
= P_ISRESTRICTED
;
12397 /* come on, you should be able to cast better if your skill is higher! --Amy */
12398 if (!Race_if(PM_BABYLONIAN
)) {
12399 if ( skill
== P_BASIC
) splcaster
-= 3;
12400 if ( skill
== P_SKILLED
) splcaster
-= 6;
12401 if ( skill
== P_EXPERT
) splcaster
-= 9;
12402 if ( skill
== P_MASTER
) splcaster
-= 12;
12403 if ( skill
== P_GRAND_MASTER
) splcaster
-= 15;
12404 if ( skill
== P_SUPREME_MASTER
) splcaster
-= 18;
12407 /* casting it often (and thereby keeping it in memory) should also improve chances...
12408 * Amy note: 700% is the cap where it stops getting better, this is intentional */
12409 if ( spellknow(spell
) >= 20000) splcaster
-= 1;
12410 if (( spellknow(spell
) >= 23333) && (spellev(spell
) < 5) ) splcaster
-= 1;
12411 if (( spellknow(spell
) >= 26666) && (spellev(spell
) < 6) ) splcaster
-= 1;
12412 if (( spellknow(spell
) >= 30000) && (spellev(spell
) < 7) ) splcaster
-= 1;
12413 if (( spellknow(spell
) >= 33333) && (spellev(spell
) < 8) ) splcaster
-= 1;
12414 if ( spellknow(spell
) >= 36666) splcaster
-= 1;
12415 if (( spellknow(spell
) >= 40000) && (spellev(spell
) < 5) ) splcaster
-= 1;
12416 if (( spellknow(spell
) >= 43333) && (spellev(spell
) < 6) ) splcaster
-= 1;
12417 if (( spellknow(spell
) >= 46666) && (spellev(spell
) < 7) ) splcaster
-= 1;
12418 if (( spellknow(spell
) >= 50000) && (spellev(spell
) < 8) ) splcaster
-= 1;
12419 if ( spellknow(spell
) >= 53333) splcaster
-= 1;
12420 if (( spellknow(spell
) >= 56666) && (spellev(spell
) < 5) ) splcaster
-= 1;
12421 if (( spellknow(spell
) >= 60000) && (spellev(spell
) < 6) ) splcaster
-= 1;
12422 if (( spellknow(spell
) >= 63333) && (spellev(spell
) < 7) ) splcaster
-= 1;
12423 if (( spellknow(spell
) >= 66666) && (spellev(spell
) < 8) ) splcaster
-= 1;
12424 if ( spellknow(spell
) >= 69000) splcaster
-= 1;
12426 skill
= max(skill
,P_UNSKILLED
) - 1; /* unskilled => 0 */
12427 difficulty
= (spellev(spell
)-1) * 3 - ((skill
* 6) + (u
.ulevel
/3) + 1);
12431 if (splcaster
< 0) {
12433 if (splcaster
> 0) splcaster
= 0; /* fail safe */
12434 if (splcaster
< -10) splcaster
= -10; /* absolute limit */
12436 if (splcaster
> 50) splcaster
= 50;
12438 if (difficulty
> 0) {
12439 /* Player is too low level or unskilled. */
12440 chance
-= isqrt(900 * difficulty
+ 2000);
12442 /* Player is above level. Learning continues, but the
12443 * law of diminishing returns sets in quickly for
12444 * low-level spells. That is, a player quickly gains
12445 * no advantage for raising level.
12447 int learning
= 15 * -difficulty
/ spellev(spell
);
12448 chance
+= learning
> 20 ? 20 : learning
;
12451 /* Clamp the chance: >18 stat and advanced learning only help
12452 * to a limit, while chances below "hopeless" only raise the
12453 * specter of overflowing 16-bit ints (and permit wearing a
12454 * shield to raise the chances :-).
12456 if (chance
< 0) chance
= 0;
12457 if (chance
> 120) chance
= 120;
12459 /* Wearing anything but a light shield makes it very awkward
12460 * to cast a spell. The penalty is not quite so bad for the
12461 * player's class-specific spell.
12463 /* if (uarms && weight(uarms) > (int) objects[SMALL_SHIELD].oc_weight) {
12464 if (spellid(spell) == urole.spelspec) {
12471 /* Finally, chance (based on player intell/wisdom and level) is
12472 * combined with ability (based on player intrinsics and
12473 * encumbrances). No matter how intelligent/wise and advanced
12474 * a player is, intrinsics and encumbrance can prevent casting;
12475 * and no matter how able, learning is always required.
12477 chance
= chance
* (30-splcaster
) / 10;
12479 if ( (CasterProblem
|| u
.uprops
[CASTER_PROBLEM
].extrinsic
|| have_antimagicstone() || (uarm
&& uarm
->oartifact
== ART_ROBE_OF_THE_ARCHMAGI
) || (uarmc
&& uarmc
->oartifact
== ART_HERETICAL_FIGURE
) || (uarm
&& uarm
->oartifact
== ART_SHIVANHUNTER_S_UNUSED_PRIZ
) ) && chance
> 0) {
12481 chance
= (chance
* u
.uhp
/ u
.uhpmax
);
12485 switch (spellev(spell
)) {
12508 if (SpellColorBlack
) {
12510 switch (spellev(spell
)) {
12541 if (Race_if(PM_TONBERRY
)) {
12542 switch (spellev(spell
)) {
12571 if (issoviet
) chance
-= 30;
12572 if (Role_if(PM_NOOB_MODE_BARB
)) chance
-= 50;
12573 if (u
.martialstyle
== MARTIALSTYLE_MUAYTHAI
) chance
-= 20;
12575 if (Race_if(PM_PLAYER_SKELETON
)) chance
-= 50;
12577 if (spell_skilltype(spellid(spell
)) == P_CHAOS_SPELL
) { /* more difficult! */
12579 switch (spellev(spell
)) {
12583 if (!Role_if(PM_CHAOS_SORCEROR
)) chance
-= 5;
12587 if (!Role_if(PM_CHAOS_SORCEROR
)) chance
-= 10;
12591 if (!Role_if(PM_CHAOS_SORCEROR
)) chance
-= 15;
12595 if (!Role_if(PM_CHAOS_SORCEROR
)) chance
-= 25;
12599 if (!Role_if(PM_CHAOS_SORCEROR
)) chance
-= 40;
12603 if (!Role_if(PM_CHAOS_SORCEROR
)) chance
-= 60;
12607 if (!Role_if(PM_CHAOS_SORCEROR
)) chance
-= 80;
12611 if (!Role_if(PM_CHAOS_SORCEROR
)) chance
-= 100;
12618 if (uarmg
&& itemhasappearance(uarmg
, APP_UNCANNY_GLOVES
)) chance
-= 10;
12620 if (uarmh
&& uarmh
->oartifact
== ART_WAITING_FOR_MELEE
) chance
-= 15;
12621 if (uarm
&& uarm
->oartifact
== ART_DRAGON_PLATE
) chance
-= 20;
12622 if (uarmf
&& uarmf
->oartifact
== ART_THICKER_THAN_THE_HEAD
) chance
-= 20;
12623 if (uarm
&& uarm
->oartifact
== ART_MADE_OF_IRON
) chance
-= 20;
12624 if (StrongMagicVacuum
) chance
-= 50;
12626 if (Race_if(PM_PLAYER_GOLEM
)) {
12628 if (spellev(spell
) > 1) chance
-= ((spellev(spell
) - 1) * 5);
12631 if (uarm
&& uarm
->oartifact
== ART_ROFLCOPTER_WEB
) chance
+= 10;
12632 if (uarm
&& uarm
->otyp
== ROBE_OF_SPELL_POWER
) chance
+= 20;
12633 if (Role_if(PM_CELLAR_CHILD
) && uarm
&& uarm
->otyp
== MAGE_PLATE_MAIL
) chance
+= 20;
12634 if (uarmh
&& uarmh
->oartifact
== ART_ZERO_PERCENT_FAILURE
) chance
+= 10;
12635 if (uarmc
&& uarmc
->oartifact
== ART_HENRIETTA_S_HEAVY_CASTER
) chance
+= 15;
12636 if (uarmf
&& uarmf
->oartifact
== ART_SUNALI_S_SUMMONING_STORM
) chance
+= 15;
12637 if (uwep
&& uwep
->otyp
== OLDEST_STAFF
) chance
+= 10;
12638 if (uleft
&& uleft
->oartifact
== ART_HENRIETTA_S_MAGICAL_AID
) chance
+= 50;
12639 if (uright
&& uright
->oartifact
== ART_HENRIETTA_S_MAGICAL_AID
) chance
+= 50;
12640 if (uarmu
&& uarmu
->oartifact
== ART_KEITH_S_UNDEROOS
) chance
+= 50;
12641 if (Role_if(PM_ARCHEOLOGIST
) && uamul
&& uamul
->oartifact
== ART_ARCHEOLOGIST_SONG
) chance
+= 10;
12642 if (uarmh
&& itemhasappearance(uarmh
, APP_KNOWLEDGEABLE_HELMET
) ) chance
+= 10;
12643 if (uarmc
&& itemhasappearance(uarmc
, APP_SCIENCE_CLOAK
) ) chance
+= 10;
12644 if (u
.tiksrvzllatdown
) chance
+= 10;
12645 if (uarmf
&& uarmf
->oartifact
== ART_JONADAB_S_EVERYDAY_WEAR
) chance
+= 5;
12646 if (uarmf
&& uarmf
->oartifact
== ART_DON_T_FALL_INTO_THE_ABYSS
) chance
+= 10;
12647 if (uwep
&& uwep
->oartifact
== ART_BAOBHAN_MOUNTAIN
) chance
+= 10;
12648 if (uwep
&& uwep
->oartifact
== ART_ORIGIN_OF_CASTING
) chance
+= 20;
12649 if (uwep
&& uwep
->oartifact
== ART_HELIOKOPIS_S_PLAYSTYLE
) chance
+= 20;
12650 if (uarmg
&& uarmg
->oartifact
== ART_FLOEMMELFLOEMMELFLOEMMELFL
) chance
+= 5;
12651 if (uarmc
&& uarmc
->oartifact
== ART_CASTEASY
) chance
+= 5;
12652 if (uwep
&& uwep
->oartifact
== ART_INFASPEL
) chance
+= 5;
12653 if (uarmg
&& uarmg
->oartifact
== ART_HOGWILD_WIZ
) chance
+= 10;
12654 if (bmwride(ART_ZIN_BA
)) chance
+= 10;
12655 if (uarmg
&& uarmg
->oartifact
== ART_WAND_INTO_SPELL
) chance
+= 10;
12656 if (uarmc
&& uarmc
->oartifact
== ART_SHROUD
) chance
+= 10;
12657 if (have_magicrystal()) chance
+= 5;
12658 if (uarmh
&& uarmh
->oartifact
== ART_ALL_THE_BETTER_SPELLING
) chance
+= 5;
12659 if (uarm
&& uarm
->oartifact
== ART_KAMAKURA_BORI
) chance
+= 20;
12660 if (uarmh
&& uarmh
->oartifact
== ART_DREHTURN
) chance
+= 10;
12662 if (spell_skilltype(spellid(spell
)) == P_HEALING_SPELL
) {
12663 if (uwep
&& uwep
->oartifact
== ART_CELESTIAL_SCEPTRE
) chance
+= 50;
12666 /* higher spell skill should do SOMEthing --Amy */
12667 skill
= P_SKILL(spell_skilltype(spellid(spell
)));
12668 if (PlayerCannotUseSkills
) skill
= P_ISRESTRICTED
;
12670 if (!Race_if(PM_BABYLONIAN
)) {
12671 if (skill
>= P_BASIC
) chance
++;
12672 if (skill
>= P_SKILLED
) chance
++;
12673 if (skill
>= P_EXPERT
) chance
++;
12674 if (skill
>= P_MASTER
) chance
+= 5;
12675 if (skill
>= P_GRAND_MASTER
) chance
+= 5;
12676 if (skill
>= P_SUPREME_MASTER
) chance
+= 5;
12679 if (uarm
&& objects
[(uarm
)->otyp
].oc_material
== MT_CELESTIUM
) chance
+= 2;
12680 if (uarmu
&& objects
[(uarmu
)->otyp
].oc_material
== MT_CELESTIUM
) chance
+= 2;
12681 if (uarmc
&& objects
[(uarmc
)->otyp
].oc_material
== MT_CELESTIUM
) chance
+= 2;
12682 if (uarmf
&& objects
[(uarmf
)->otyp
].oc_material
== MT_CELESTIUM
) chance
+= 2;
12683 if (uarmg
&& objects
[(uarmg
)->otyp
].oc_material
== MT_CELESTIUM
) chance
+= 2;
12684 if (uarmh
&& objects
[(uarmh
)->otyp
].oc_material
== MT_CELESTIUM
) chance
+= 2;
12685 if (uarms
&& objects
[(uarms
)->otyp
].oc_material
== MT_CELESTIUM
) chance
+= 2;
12686 if (uwep
&& objects
[(uwep
)->otyp
].oc_material
== MT_CELESTIUM
) chance
+= 2;
12687 if (u
.twoweap
&& uswapwep
&& objects
[(uswapwep
)->otyp
].oc_material
== MT_CELESTIUM
) chance
+= 2;
12688 if (uamul
&& objects
[(uamul
)->otyp
].oc_material
== MT_CELESTIUM
) chance
+= 2;
12689 if (uleft
&& objects
[(uleft
)->otyp
].oc_material
== MT_CELESTIUM
) chance
+= 2;
12690 if (uright
&& objects
[(uright
)->otyp
].oc_material
== MT_CELESTIUM
) chance
+= 2;
12691 if (uimplant
&& objects
[(uimplant
)->otyp
].oc_material
== MT_CELESTIUM
) chance
+= 2;
12692 if (ublindf
&& objects
[(ublindf
)->otyp
].oc_material
== MT_CELESTIUM
) chance
+= 2;
12694 if (Race_if(PM_PLAYER_FAIRY
)) {
12697 if (uwep
&& is_metallic(uwep
) && !is_etheritem(uwep
) && !is_meteosteelitem(uwep
)) {
12699 switch (objects
[(uwep
)->otyp
].oc_material
) {
12700 default: chance
-= 20; break;
12701 case MT_METAL
: chance
-= 22; break;
12702 case MT_STEEL
: chance
-= 22; break;
12703 case MT_GREEN_STEEL
: chance
-= 16; break;
12704 case MT_MERCURIAL
: chance
-= 4; break;
12705 case MT_BRONZE
: chance
-= 28; break;
12706 case MT_TITANIUM
: chance
-= 26; break;
12707 case MT_COPPER
: chance
-= 24; break;
12708 case MT_COBALT
: chance
-= 22; break;
12709 case MT_SILVER
: chance
-= 24; break;
12710 case MT_GOLD
: chance
-= 10; break;
12711 case MT_TINSEL
: chance
-= 12; break;
12712 case MT_PLATINUM
: chance
-= 26; break;
12713 case MT_FILM
: chance
-= 26; break;
12714 case MT_ALLOY
: chance
-= 26; break;
12715 case MT_MITHRIL
: chance
-= 18; break;
12716 case MT_VIVA
: chance
-= 16; break;
12717 case MT_POURPOOR
: chance
-= 30; break;
12718 case MT_LEAD
: chance
-= 40; break;
12719 case MT_CHROME
: chance
-= 14; break;
12723 if (u
.twoweap
&& uswapwep
&& is_metallic(uswapwep
) && !is_etheritem(uswapwep
) && !is_meteosteelitem(uswapwep
)) {
12725 switch (objects
[(uswapwep
)->otyp
].oc_material
) {
12726 default: chance
-= 20; break;
12727 case MT_METAL
: chance
-= 22; break;
12728 case MT_STEEL
: chance
-= 22; break;
12729 case MT_GREEN_STEEL
: chance
-= 16; break;
12730 case MT_MERCURIAL
: chance
-= 4; break;
12731 case MT_BRONZE
: chance
-= 28; break;
12732 case MT_TITANIUM
: chance
-= 26; break;
12733 case MT_COPPER
: chance
-= 24; break;
12734 case MT_COBALT
: chance
-= 22; break;
12735 case MT_SILVER
: chance
-= 24; break;
12736 case MT_GOLD
: chance
-= 10; break;
12737 case MT_TINSEL
: chance
-= 12; break;
12738 case MT_PLATINUM
: chance
-= 26; break;
12739 case MT_FILM
: chance
-= 26; break;
12740 case MT_ALLOY
: chance
-= 26; break;
12741 case MT_MITHRIL
: chance
-= 18; break;
12742 case MT_VIVA
: chance
-= 16; break;
12743 case MT_POURPOOR
: chance
-= 30; break;
12744 case MT_LEAD
: chance
-= 40; break;
12745 case MT_CHROME
: chance
-= 14; break;
12749 if (uarm
&& is_metallic(uarm
) && !is_etheritem(uarm
) && !is_meteosteelitem(uarm
)) {
12751 switch (objects
[(uarm
)->otyp
].oc_material
) {
12752 default: chance
-= 20; break;
12753 case MT_METAL
: chance
-= 22; break;
12754 case MT_STEEL
: chance
-= 22; break;
12755 case MT_GREEN_STEEL
: chance
-= 16; break;
12756 case MT_MERCURIAL
: chance
-= 4; break;
12757 case MT_BRONZE
: chance
-= 28; break;
12758 case MT_TITANIUM
: chance
-= 26; break;
12759 case MT_COPPER
: chance
-= 24; break;
12760 case MT_COBALT
: chance
-= 22; break;
12761 case MT_SILVER
: chance
-= 24; break;
12762 case MT_GOLD
: chance
-= 10; break;
12763 case MT_TINSEL
: chance
-= 12; break;
12764 case MT_PLATINUM
: chance
-= 26; break;
12765 case MT_FILM
: chance
-= 26; break;
12766 case MT_ALLOY
: chance
-= 26; break;
12767 case MT_MITHRIL
: chance
-= 18; break;
12768 case MT_VIVA
: chance
-= 16; break;
12769 case MT_POURPOOR
: chance
-= 30; break;
12770 case MT_LEAD
: chance
-= 40; break;
12771 case MT_CHROME
: chance
-= 14; break;
12775 if (uarmc
&& is_metallic(uarmc
) && !is_etheritem(uarmc
) && !is_meteosteelitem(uarmc
)) {
12777 switch (objects
[(uarmc
)->otyp
].oc_material
) {
12778 default: chance
-= 20; break;
12779 case MT_METAL
: chance
-= 22; break;
12780 case MT_STEEL
: chance
-= 22; break;
12781 case MT_GREEN_STEEL
: chance
-= 16; break;
12782 case MT_MERCURIAL
: chance
-= 4; break;
12783 case MT_BRONZE
: chance
-= 28; break;
12784 case MT_TITANIUM
: chance
-= 26; break;
12785 case MT_COPPER
: chance
-= 24; break;
12786 case MT_COBALT
: chance
-= 22; break;
12787 case MT_SILVER
: chance
-= 24; break;
12788 case MT_GOLD
: chance
-= 10; break;
12789 case MT_TINSEL
: chance
-= 12; break;
12790 case MT_PLATINUM
: chance
-= 26; break;
12791 case MT_FILM
: chance
-= 26; break;
12792 case MT_ALLOY
: chance
-= 26; break;
12793 case MT_MITHRIL
: chance
-= 18; break;
12794 case MT_VIVA
: chance
-= 16; break;
12795 case MT_POURPOOR
: chance
-= 30; break;
12796 case MT_LEAD
: chance
-= 40; break;
12797 case MT_CHROME
: chance
-= 14; break;
12801 if (uarmh
&& is_metallic(uarmh
) && !is_etheritem(uarmh
) && !is_meteosteelitem(uarmh
)) {
12803 switch (objects
[(uarmh
)->otyp
].oc_material
) {
12804 default: chance
-= 20; break;
12805 case MT_METAL
: chance
-= 22; break;
12806 case MT_STEEL
: chance
-= 22; break;
12807 case MT_GREEN_STEEL
: chance
-= 16; break;
12808 case MT_MERCURIAL
: chance
-= 4; break;
12809 case MT_BRONZE
: chance
-= 28; break;
12810 case MT_TITANIUM
: chance
-= 26; break;
12811 case MT_COPPER
: chance
-= 24; break;
12812 case MT_COBALT
: chance
-= 22; break;
12813 case MT_SILVER
: chance
-= 24; break;
12814 case MT_GOLD
: chance
-= 10; break;
12815 case MT_TINSEL
: chance
-= 12; break;
12816 case MT_PLATINUM
: chance
-= 26; break;
12817 case MT_FILM
: chance
-= 26; break;
12818 case MT_ALLOY
: chance
-= 26; break;
12819 case MT_MITHRIL
: chance
-= 18; break;
12820 case MT_VIVA
: chance
-= 16; break;
12821 case MT_POURPOOR
: chance
-= 30; break;
12822 case MT_LEAD
: chance
-= 40; break;
12823 case MT_CHROME
: chance
-= 14; break;
12827 if (uarms
&& is_metallic(uarms
) && !is_etheritem(uarms
) && !is_meteosteelitem(uarms
)) {
12829 switch (objects
[(uarms
)->otyp
].oc_material
) {
12830 default: chance
-= 20; break;
12831 case MT_METAL
: chance
-= 22; break;
12832 case MT_STEEL
: chance
-= 22; break;
12833 case MT_GREEN_STEEL
: chance
-= 16; break;
12834 case MT_MERCURIAL
: chance
-= 4; break;
12835 case MT_BRONZE
: chance
-= 28; break;
12836 case MT_TITANIUM
: chance
-= 26; break;
12837 case MT_COPPER
: chance
-= 24; break;
12838 case MT_COBALT
: chance
-= 22; break;
12839 case MT_SILVER
: chance
-= 24; break;
12840 case MT_GOLD
: chance
-= 10; break;
12841 case MT_TINSEL
: chance
-= 12; break;
12842 case MT_PLATINUM
: chance
-= 26; break;
12843 case MT_FILM
: chance
-= 26; break;
12844 case MT_ALLOY
: chance
-= 26; break;
12845 case MT_MITHRIL
: chance
-= 18; break;
12846 case MT_VIVA
: chance
-= 16; break;
12847 case MT_POURPOOR
: chance
-= 30; break;
12848 case MT_LEAD
: chance
-= 40; break;
12849 case MT_CHROME
: chance
-= 14; break;
12853 if (uarmg
&& is_metallic(uarmg
) && !is_etheritem(uarmg
) && !is_meteosteelitem(uarmg
)) {
12855 switch (objects
[(uarmg
)->otyp
].oc_material
) {
12856 default: chance
-= 20; break;
12857 case MT_METAL
: chance
-= 22; break;
12858 case MT_STEEL
: chance
-= 22; break;
12859 case MT_GREEN_STEEL
: chance
-= 16; break;
12860 case MT_MERCURIAL
: chance
-= 4; break;
12861 case MT_BRONZE
: chance
-= 28; break;
12862 case MT_TITANIUM
: chance
-= 26; break;
12863 case MT_COPPER
: chance
-= 24; break;
12864 case MT_COBALT
: chance
-= 22; break;
12865 case MT_SILVER
: chance
-= 24; break;
12866 case MT_GOLD
: chance
-= 10; break;
12867 case MT_TINSEL
: chance
-= 12; break;
12868 case MT_PLATINUM
: chance
-= 26; break;
12869 case MT_FILM
: chance
-= 26; break;
12870 case MT_ALLOY
: chance
-= 26; break;
12871 case MT_MITHRIL
: chance
-= 18; break;
12872 case MT_VIVA
: chance
-= 16; break;
12873 case MT_POURPOOR
: chance
-= 30; break;
12874 case MT_LEAD
: chance
-= 40; break;
12875 case MT_CHROME
: chance
-= 14; break;
12879 if (uarmf
&& is_metallic(uarmf
) && !is_etheritem(uarmf
) && !is_meteosteelitem(uarmf
)) {
12881 switch (objects
[(uarmf
)->otyp
].oc_material
) {
12882 default: chance
-= 20; break;
12883 case MT_METAL
: chance
-= 22; break;
12884 case MT_STEEL
: chance
-= 22; break;
12885 case MT_GREEN_STEEL
: chance
-= 16; break;
12886 case MT_MERCURIAL
: chance
-= 4; break;
12887 case MT_BRONZE
: chance
-= 28; break;
12888 case MT_TITANIUM
: chance
-= 26; break;
12889 case MT_COPPER
: chance
-= 24; break;
12890 case MT_COBALT
: chance
-= 22; break;
12891 case MT_SILVER
: chance
-= 24; break;
12892 case MT_GOLD
: chance
-= 10; break;
12893 case MT_TINSEL
: chance
-= 12; break;
12894 case MT_PLATINUM
: chance
-= 26; break;
12895 case MT_FILM
: chance
-= 26; break;
12896 case MT_ALLOY
: chance
-= 26; break;
12897 case MT_MITHRIL
: chance
-= 18; break;
12898 case MT_VIVA
: chance
-= 16; break;
12899 case MT_POURPOOR
: chance
-= 30; break;
12900 case MT_LEAD
: chance
-= 40; break;
12901 case MT_CHROME
: chance
-= 14; break;
12905 if (uarmu
&& is_metallic(uarmu
) && !is_etheritem(uarmu
) && !is_meteosteelitem(uarmu
)) {
12907 switch (objects
[(uarmu
)->otyp
].oc_material
) {
12908 default: chance
-= 20; break;
12909 case MT_METAL
: chance
-= 22; break;
12910 case MT_STEEL
: chance
-= 22; break;
12911 case MT_GREEN_STEEL
: chance
-= 16; break;
12912 case MT_MERCURIAL
: chance
-= 4; break;
12913 case MT_BRONZE
: chance
-= 28; break;
12914 case MT_TITANIUM
: chance
-= 26; break;
12915 case MT_COPPER
: chance
-= 24; break;
12916 case MT_COBALT
: chance
-= 22; break;
12917 case MT_SILVER
: chance
-= 24; break;
12918 case MT_GOLD
: chance
-= 10; break;
12919 case MT_TINSEL
: chance
-= 12; break;
12920 case MT_PLATINUM
: chance
-= 26; break;
12921 case MT_FILM
: chance
-= 26; break;
12922 case MT_ALLOY
: chance
-= 26; break;
12923 case MT_MITHRIL
: chance
-= 18; break;
12924 case MT_VIVA
: chance
-= 16; break;
12925 case MT_POURPOOR
: chance
-= 30; break;
12926 case MT_LEAD
: chance
-= 40; break;
12927 case MT_CHROME
: chance
-= 14; break;
12931 if (uamul
&& is_metallic(uamul
) && !is_etheritem(uamul
) && !is_meteosteelitem(uamul
)) {
12933 switch (objects
[(uamul
)->otyp
].oc_material
) {
12934 default: chance
-= 20; break;
12935 case MT_METAL
: chance
-= 22; break;
12936 case MT_STEEL
: chance
-= 22; break;
12937 case MT_GREEN_STEEL
: chance
-= 16; break;
12938 case MT_MERCURIAL
: chance
-= 4; break;
12939 case MT_BRONZE
: chance
-= 28; break;
12940 case MT_TITANIUM
: chance
-= 26; break;
12941 case MT_COPPER
: chance
-= 24; break;
12942 case MT_COBALT
: chance
-= 22; break;
12943 case MT_SILVER
: chance
-= 24; break;
12944 case MT_GOLD
: chance
-= 10; break;
12945 case MT_TINSEL
: chance
-= 12; break;
12946 case MT_PLATINUM
: chance
-= 26; break;
12947 case MT_FILM
: chance
-= 26; break;
12948 case MT_ALLOY
: chance
-= 26; break;
12949 case MT_MITHRIL
: chance
-= 18; break;
12950 case MT_VIVA
: chance
-= 16; break;
12951 case MT_POURPOOR
: chance
-= 30; break;
12952 case MT_LEAD
: chance
-= 40; break;
12953 case MT_CHROME
: chance
-= 14; break;
12957 if (uimplant
&& is_metallic(uimplant
) && !is_etheritem(uimplant
) && !is_meteosteelitem(uimplant
)) {
12959 switch (objects
[(uimplant
)->otyp
].oc_material
) {
12960 default: chance
-= 20; break;
12961 case MT_METAL
: chance
-= 22; break;
12962 case MT_STEEL
: chance
-= 22; break;
12963 case MT_GREEN_STEEL
: chance
-= 16; break;
12964 case MT_MERCURIAL
: chance
-= 4; break;
12965 case MT_BRONZE
: chance
-= 28; break;
12966 case MT_TITANIUM
: chance
-= 26; break;
12967 case MT_COPPER
: chance
-= 24; break;
12968 case MT_COBALT
: chance
-= 22; break;
12969 case MT_SILVER
: chance
-= 24; break;
12970 case MT_GOLD
: chance
-= 10; break;
12971 case MT_TINSEL
: chance
-= 12; break;
12972 case MT_PLATINUM
: chance
-= 26; break;
12973 case MT_FILM
: chance
-= 26; break;
12974 case MT_ALLOY
: chance
-= 26; break;
12975 case MT_MITHRIL
: chance
-= 18; break;
12976 case MT_VIVA
: chance
-= 16; break;
12977 case MT_POURPOOR
: chance
-= 30; break;
12978 case MT_LEAD
: chance
-= 40; break;
12979 case MT_CHROME
: chance
-= 14; break;
12983 if (uleft
&& is_metallic(uleft
) && !is_etheritem(uleft
) && !is_meteosteelitem(uleft
)) {
12985 switch (objects
[(uleft
)->otyp
].oc_material
) {
12986 default: chance
-= 20; break;
12987 case MT_METAL
: chance
-= 22; break;
12988 case MT_STEEL
: chance
-= 22; break;
12989 case MT_GREEN_STEEL
: chance
-= 16; break;
12990 case MT_MERCURIAL
: chance
-= 4; break;
12991 case MT_BRONZE
: chance
-= 28; break;
12992 case MT_TITANIUM
: chance
-= 26; break;
12993 case MT_COPPER
: chance
-= 24; break;
12994 case MT_COBALT
: chance
-= 22; break;
12995 case MT_SILVER
: chance
-= 24; break;
12996 case MT_GOLD
: chance
-= 10; break;
12997 case MT_TINSEL
: chance
-= 12; break;
12998 case MT_PLATINUM
: chance
-= 26; break;
12999 case MT_FILM
: chance
-= 26; break;
13000 case MT_ALLOY
: chance
-= 26; break;
13001 case MT_MITHRIL
: chance
-= 18; break;
13002 case MT_VIVA
: chance
-= 16; break;
13003 case MT_POURPOOR
: chance
-= 30; break;
13004 case MT_LEAD
: chance
-= 40; break;
13005 case MT_CHROME
: chance
-= 14; break;
13009 if (uright
&& is_metallic(uright
) && !is_etheritem(uright
) && !is_meteosteelitem(uright
)) {
13011 switch (objects
[(uright
)->otyp
].oc_material
) {
13012 default: chance
-= 20; break;
13013 case MT_METAL
: chance
-= 22; break;
13014 case MT_STEEL
: chance
-= 22; break;
13015 case MT_GREEN_STEEL
: chance
-= 16; break;
13016 case MT_MERCURIAL
: chance
-= 4; break;
13017 case MT_BRONZE
: chance
-= 28; break;
13018 case MT_TITANIUM
: chance
-= 26; break;
13019 case MT_COPPER
: chance
-= 24; break;
13020 case MT_COBALT
: chance
-= 22; break;
13021 case MT_SILVER
: chance
-= 24; break;
13022 case MT_GOLD
: chance
-= 10; break;
13023 case MT_TINSEL
: chance
-= 12; break;
13024 case MT_PLATINUM
: chance
-= 26; break;
13025 case MT_FILM
: chance
-= 26; break;
13026 case MT_ALLOY
: chance
-= 26; break;
13027 case MT_MITHRIL
: chance
-= 18; break;
13028 case MT_VIVA
: chance
-= 16; break;
13029 case MT_POURPOOR
: chance
-= 30; break;
13030 case MT_LEAD
: chance
-= 40; break;
13031 case MT_CHROME
: chance
-= 14; break;
13035 if (ublindf
&& is_metallic(ublindf
) && !is_etheritem(ublindf
) && !is_meteosteelitem(ublindf
)) {
13037 switch (objects
[(ublindf
)->otyp
].oc_material
) {
13038 default: chance
-= 20; break;
13039 case MT_METAL
: chance
-= 22; break;
13040 case MT_STEEL
: chance
-= 22; break;
13041 case MT_GREEN_STEEL
: chance
-= 16; break;
13042 case MT_MERCURIAL
: chance
-= 4; break;
13043 case MT_BRONZE
: chance
-= 28; break;
13044 case MT_TITANIUM
: chance
-= 26; break;
13045 case MT_COPPER
: chance
-= 24; break;
13046 case MT_COBALT
: chance
-= 22; break;
13047 case MT_SILVER
: chance
-= 24; break;
13048 case MT_GOLD
: chance
-= 10; break;
13049 case MT_TINSEL
: chance
-= 12; break;
13050 case MT_PLATINUM
: chance
-= 26; break;
13051 case MT_FILM
: chance
-= 26; break;
13052 case MT_ALLOY
: chance
-= 26; break;
13053 case MT_MITHRIL
: chance
-= 18; break;
13054 case MT_VIVA
: chance
-= 16; break;
13055 case MT_POURPOOR
: chance
-= 30; break;
13056 case MT_LEAD
: chance
-= 40; break;
13057 case MT_CHROME
: chance
-= 14; break;
13063 if (Upolyd
&& dmgtype(youmonst
.data
, AD_SPEL
) ) {
13066 if (Upolyd
&& dmgtype(youmonst
.data
, AD_CLRC
) ) {
13069 if (Upolyd
&& dmgtype(youmonst
.data
, AD_CAST
) ) {
13073 if (!PlayerCannotUseSkills
&& uwep
&& is_lightsaber(uwep
) && (uwep
->lamplit
|| Role_if(PM_SHADOW_JEDI
)) ) {
13074 switch (P_SKILL(P_NIMAN
)) {
13076 case P_BASIC
: chance
+= 5; break;
13077 case P_SKILLED
: chance
+= 10; break;
13078 case P_EXPERT
: chance
+= 15; break;
13079 case P_MASTER
: chance
+= 20; break;
13080 case P_GRAND_MASTER
: chance
+= 25; break;
13081 case P_SUPREME_MASTER
: chance
+= 30; break;
13086 if (!PlayerCannotUseSkills
) {
13087 switch (P_SKILL(P_NIMAN
)) {
13089 case P_BASIC
: chance
+= 1; break;
13090 case P_SKILLED
: chance
+= 2; break;
13091 case P_EXPERT
: chance
+= 3; break;
13092 case P_MASTER
: chance
+= 4; break;
13093 case P_GRAND_MASTER
: chance
+= 5; break;
13094 case P_SUPREME_MASTER
: chance
+= 6; break;
13099 if (Race_if(PM_INKA
) && spellid(spell
) == SPE_NATURE_BEAM
)
13102 if (Race_if(PM_VIETIS
)) chance
-= 20;
13104 if (uarmc
&& itemhasappearance(uarmc
, APP_DNETHACK_CLOAK
)) chance
-= 10;
13105 if (uarms
&& uarms
->oartifact
== ART_DNETHACKC_NOONISHNESS
) chance
-= 10;
13106 if (RngeDnethack
) chance
-= 10;
13107 if (Race_if(PM_INHERITOR
)) chance
-= 10;
13108 if (RngeUnnethack
) chance
-= 33;
13109 if (ACURR(A_INT
) < 3) chance
-= 25;
13111 /* artifacts and other items that boost the chance after "hard" penalties are applied go here --Amy */
13113 if (uarmc
&& itemhasappearance(uarmc
, APP_FAILUNCAP_CLOAK
) ) chance
+= 5;
13114 if (uarmh
&& itemhasappearance(uarmh
, APP_FAILUNCAP_HELMET
) ) chance
+= 5;
13115 if (uarmg
&& itemhasappearance(uarmg
, APP_FAILUNCAP_GLOVES
) ) chance
+= 5;
13116 if (uarmf
&& itemhasappearance(uarmf
, APP_FAILUNCAP_SHOES
) ) chance
+= 5;
13117 if (uarm
&& uarm
->oartifact
== ART_ALTADOON_HERMA_MORA
) chance
+= 20;
13118 if (uarmg
&& uarmg
->oartifact
== ART_HOGWILD_WIZ
) chance
+= 5;
13119 if (uarmg
&& uarmg
->oartifact
== ART_WAND_INTO_SPELL
) chance
+= 10;
13120 if (have_magicrystal()) chance
+= 5;
13121 if (uarmh
&& uarmh
->oartifact
== ART_ALL_THE_BETTER_SPELLING
) chance
+= 5;
13123 if (uwep
&& uwep
->oartifact
== ART_RASSCHEN_TAAK
) chance
+= 5;
13125 if (Role_if(PM_OTAKU
) && uarmc
&& itemhasappearance(uarmc
, APP_FOURCHAN_CLOAK
)) chance
+= 5;
13127 /* very high INT gives a boost, even if your casting stat is WIS --Amy */
13128 if (ACURR(A_INT
) >= 16) {
13129 chance
+= (ACURR(A_INT
) - 15);
13132 if (uarm
&& uarm
->oartifact
== ART_MOTHERFUCKER_TROPHY
) {
13136 /* "bullshit change" by Amy: make it quite a bit harder to get to 0% fail, because spells are generally easier to
13137 * cast compared to vanilla which results in difficult spells being too easy for non-caster roles
13138 * THIS MUST COME AFTER ANYTHING THAT BOOSTS THE CHANCE */
13140 int chancediff
= (chance
- 50);
13142 if (chancediff
> 50) chancediff
= 50;
13143 chance
-= chancediff
;
13146 int chancediff
= (chance
- 90);
13149 if (chancediff
> 90) chancediff
= 90;
13150 chance
-= chancediff
;
13154 /* Clamp to percentile */
13155 if (chance
> 100) chance
= 100;
13157 if (RememberanceEffect
|| u
.uprops
[REMEMBERANCE_EFFECT
].extrinsic
|| have_rememberancestone()) {
13158 if (chance
> (spellknow(spell
) / 100)) chance
= (spellknow(spell
) / 100);
13161 if (uarmc
&& itemhasappearance(uarmc
, APP_SHELL_CLOAK
) ) chance
-= 20;
13163 if (is_grassland(u
.ux
, u
.uy
) && !(uarm
&& uarm
->oartifact
== ART_DORL_TSCH
) && !(uarmf
&& itemhasappearance(uarmf
, APP_GARDEN_SLIPPERS
))) chance
-= 10;
13164 if (Numbed
) chance
-= 10;
13166 if (Role_if(PM_FAILED_EXISTENCE
)) chance
/= 2; /* at least 50% fail for all spells */
13167 if (uarms
&& uarms
->otyp
== COMPLETE_BLOCKAGE_SHIELD
) chance
/= 2;
13168 if (uarmc
&& uarmc
->oartifact
== ART_ARTIFICIAL_FAKE_DIFFICULTY
) {
13172 if (ACURR(A_INT
) == 1) { /* 25% autofail if you're as stupid as possible */
13177 if (Race_if(PM_INHERITOR
)) chance
--;
13179 /* REALLY clamp chance now */
13180 if (chance
> 100) chance
= 100;
13182 if (SpellColorSilver
) {
13184 if (chance
== 50) chance
= 100;
13185 else if (chance
== 100) chance
= 10;
13186 else if (chance
> 50) chance
-= ((chance
- 50) * 2);
13187 else if (chance
> 0) chance
*= 2;
13191 if (chance
< (issoviet
? 0 : (spellev(spell
) == 8) ? 0 : (spellev(spell
) == 7) ? 1 : (spellev(spell
) == 6) ? 2 : (spellev(spell
) == 5) ? 5 : 10) ) chance
= (issoviet
? 0 : (spellev(spell
) == 8) ? 0 : (spellev(spell
) == 7) ? 1 : (spellev(spell
) == 6) ? 2 : (spellev(spell
) == 5) ? 5 : 10); /* used to be 0, but that was just stupid in my opinion --Amy */
13196 /* increase memory of a spell: now a function; inspired by Elona, the increase is now lower if your current spell memory
13197 * is already rather high. We're trying to make the decrease not be too harsh at first, but 2000% spell memory should be
13198 * extremely difficult to reach. */
13200 boostknow(spell
,boost
)
13203 int priorknow
= spl_book
[spell
].sp_know
;
13204 int boostmultiplier
= 100;
13205 if (priorknow
> 190100) boostmultiplier
= 1;
13206 else if (priorknow
> 180100) boostmultiplier
= 2;
13207 else if (priorknow
> 170100) boostmultiplier
= 3;
13208 else if (priorknow
> 160100) boostmultiplier
= 4;
13209 else if (priorknow
> 150100) boostmultiplier
= 5;
13210 else if (priorknow
> 140100) boostmultiplier
= 6;
13211 else if (priorknow
> 130100) boostmultiplier
= 7;
13212 else if (priorknow
> 120100) boostmultiplier
= 8;
13213 else if (priorknow
> 110100) boostmultiplier
= 9;
13214 else if (priorknow
> 100100) boostmultiplier
= 10;
13215 else if (priorknow
> 90100) boostmultiplier
= 15;
13216 else if (priorknow
> 80100) boostmultiplier
= 20;
13217 else if (priorknow
> 70100) boostmultiplier
= 30;
13218 else if (priorknow
> 60100) boostmultiplier
= 40;
13219 else if (priorknow
> 50100) boostmultiplier
= 50;
13220 else if (priorknow
> 40100) boostmultiplier
= 60;
13221 else if (priorknow
> 30100) boostmultiplier
= 70;
13222 else if (priorknow
> 20100) boostmultiplier
= 80;
13223 else if (priorknow
> 10100) boostmultiplier
= 90;
13225 boost
*= boostmultiplier
;
13229 boost
/= (StrongMagicVacuum
) ? 5 : 2;
13230 if (priorknow
> 9999) boost
/= 2;
13233 if (boost
< 0) boost
= 0;
13235 spl_book
[spell
].sp_know
= ((spl_book
[spell
].sp_know
+ boost
> MAX_KNOW
) ? MAX_KNOW
: (spl_book
[spell
].sp_know
+ boost
) );
13239 /* reduce memory of a spell, e.g. because you have cyan spells or cast stuff like add spell memory */
13241 drainknow(spell
, drainamount
)
13242 int spell
, drainamount
;
13244 if (spl_book
[spell
].sp_know
< drainamount
) spl_book
[spell
].sp_know
= 0;
13245 else spl_book
[spell
].sp_know
-= drainamount
;
13249 incrnknow(spell
, initial
)
13251 boolean initial
; /* FALSE if you knew the spell before, otherwise TRUE; reduction only if FALSE */
13253 int priorknow
= spl_book
[spell
].sp_know
;
13254 int knowvalue
= (Race_if(PM_DUNADAN
) ? DUNADAN_KEEN
: KEEN
);
13255 int boostmultiplier
= 100;
13256 if (priorknow
> 190100) boostmultiplier
= 1;
13257 else if (priorknow
> 180100) boostmultiplier
= 2;
13258 else if (priorknow
> 170100) boostmultiplier
= 3;
13259 else if (priorknow
> 160100) boostmultiplier
= 4;
13260 else if (priorknow
> 150100) boostmultiplier
= 5;
13261 else if (priorknow
> 140100) boostmultiplier
= 6;
13262 else if (priorknow
> 130100) boostmultiplier
= 7;
13263 else if (priorknow
> 120100) boostmultiplier
= 8;
13264 else if (priorknow
> 110100) boostmultiplier
= 9;
13265 else if (priorknow
> 100100) boostmultiplier
= 10;
13266 else if (priorknow
> 90100) boostmultiplier
= 15;
13267 else if (priorknow
> 80100) boostmultiplier
= 20;
13268 else if (priorknow
> 70100) boostmultiplier
= 30;
13269 else if (priorknow
> 60100) boostmultiplier
= 40;
13270 else if (priorknow
> 50100) boostmultiplier
= 50;
13271 else if (priorknow
> 40100) boostmultiplier
= 60;
13272 else if (priorknow
> 30100) boostmultiplier
= 70;
13273 else if (priorknow
> 20100) boostmultiplier
= 80;
13274 else if (priorknow
> 10100) boostmultiplier
= 90;
13276 if (initial
) boostmultiplier
= 100;
13278 knowvalue
*= boostmultiplier
;
13282 knowvalue
/= (StrongMagicVacuum
) ? 5 : 2;
13283 if (priorknow
> 9999) knowvalue
/= 2;
13286 if (knowvalue
< 0) knowvalue
= 0;
13288 spl_book
[spell
].sp_know
= (spl_book
[spell
].sp_know
< 1) ? knowvalue
: ((spl_book
[spell
].sp_know
+ knowvalue
) > MAX_KNOW
) ? MAX_KNOW
: (spl_book
[spell
].sp_know
+ knowvalue
);
13293 /* oh my god why oh why does that have to depend on an actual item, why can't we use the item's ID --Amy */
13298 initialwonderspell(obj
->otyp
);
13302 /* Learn a spell during creation of the initial inventory */
13304 initialwonderspell(wospelnum
)
13309 for (i
= 0; i
< MAXSPELL
; i
++) {
13310 if (spellid(i
) == wospelnum
) { /* not a bug - after all, you might e.g. play a haxor --Amy */
13311 /* pline("Error: Spell %s already known.", OBJ_NAME(objects[wospelnum])); */
13313 /* In Soviet Russia, enhancements aren't a thing. In fact, they don't even know how to spell the word 'enhancement'. Therefore, if someone goes ahead and suggests an enhancement that consists of double spellbooks giving twice the starting spellcasting memory, they say NOPE THAT IS INCOMPATIBLE WITH COMMUNISM and refuse to implement it. --Amy */
13315 incrnknow(i
, TRUE
);
13316 if (Role_if(PM_MAHOU_SHOUJO
)) incrnknow(i
, TRUE
);
13318 if (spl_book
[i
].sp_lev
== 3) incrnknow(i
, TRUE
);
13319 if (spl_book
[i
].sp_lev
== 4) { incrnknow(i
, TRUE
); incrnknow(i
, TRUE
);}
13320 if (spl_book
[i
].sp_lev
== 5) { incrnknow(i
, TRUE
); incrnknow(i
, TRUE
); incrnknow(i
, TRUE
);}
13321 if (spl_book
[i
].sp_lev
== 6) { incrnknow(i
, TRUE
); incrnknow(i
, TRUE
); incrnknow(i
, TRUE
); incrnknow(i
, TRUE
);}
13322 if (spl_book
[i
].sp_lev
== 7) { incrnknow(i
, TRUE
); incrnknow(i
, TRUE
); incrnknow(i
, TRUE
); incrnknow(i
, TRUE
); incrnknow(i
, TRUE
);}
13323 if (spl_book
[i
].sp_lev
== 8) { incrnknow(i
, TRUE
); incrnknow(i
, TRUE
); incrnknow(i
, TRUE
); incrnknow(i
, TRUE
); incrnknow(i
, TRUE
); incrnknow(i
, TRUE
);}
13328 if (spellid(i
) == NO_SPELL
) {
13329 spl_book
[i
].sp_id
= wospelnum
;
13330 spl_book
[i
].sp_lev
= objects
[wospelnum
].oc_level
;
13331 spl_book
[i
].sp_memorize
= TRUE
;
13332 incrnknow(i
, TRUE
);
13333 if (Role_if(PM_MAHOU_SHOUJO
)) incrnknow(i
, TRUE
);
13335 /* high-level starting spells will be known for a longer time
13336 * since you might not be able to cast them at all when you're just starting --Amy */
13337 if (spl_book
[i
].sp_lev
== 3) incrnknow(i
, TRUE
);
13338 if (spl_book
[i
].sp_lev
== 4) { incrnknow(i
, TRUE
); incrnknow(i
, TRUE
);}
13339 if (spl_book
[i
].sp_lev
== 5) { incrnknow(i
, TRUE
); incrnknow(i
, TRUE
); incrnknow(i
, TRUE
);}
13340 if (spl_book
[i
].sp_lev
== 6) { incrnknow(i
, TRUE
); incrnknow(i
, TRUE
); incrnknow(i
, TRUE
); incrnknow(i
, TRUE
);}
13341 if (spl_book
[i
].sp_lev
== 7) { incrnknow(i
, TRUE
); incrnknow(i
, TRUE
); incrnknow(i
, TRUE
); incrnknow(i
, TRUE
); incrnknow(i
, TRUE
);}
13342 if (spl_book
[i
].sp_lev
== 8) { incrnknow(i
, TRUE
); incrnknow(i
, TRUE
); incrnknow(i
, TRUE
); incrnknow(i
, TRUE
); incrnknow(i
, TRUE
); incrnknow(i
, TRUE
);}
13347 impossible("Too many spells memorized!");
13354 /*Vars are for studying spells 'W', 'F', 'I', 'N'*/
13357 if (getspell(&spell_no
, FALSE
)) {
13358 if (spellknow(spell_no
) <= 0) {
13359 You("are unable to focus your memory of the spell.");
13361 } else if (spellknow(spell_no
) <= 1000) {
13362 Your("focus and reinforce your memory of the spell.");
13363 incrnknow(spell_no
, FALSE
);
13364 if (Role_if(PM_MAHOU_SHOUJO
)) incrnknow(spell_no
, FALSE
);
13365 exercise(A_WIS
, TRUE
); /* extra study */
13367 } else if (spellknow(spell_no
) < 11000) {
13368 int studyvalue
= Race_if(PM_DUNADAN
) ? DUNADAN_KEEN
: KEEN
;
13369 int studydiff
= 11000 - spellknow(spell_no
); /* between 1 and 10000 */
13371 studyvalue
*= studydiff
;
13372 studyvalue
/= 10000;
13374 Your("focus and reinforce your memory of the spell.");
13375 boostknow(spell_no
, studyvalue
);
13376 if (Role_if(PM_MAHOU_SHOUJO
)) boostknow(spell_no
, studyvalue
);
13378 } else /* 11000 < spellknow(spell_no) <= whatever the maximum is */
13379 You("know that spell quite well already.");
13385 inertiacontrolspell()
13389 if (getspell(&spell_no
, FALSE
)) {
13390 if (spellid(spell_no
) == SPE_INERTIA_CONTROL
) {
13391 You("cannot control the inertia control spell.");
13393 } else if (spellid(spell_no
) != NO_SPELL
) {
13394 u
.inertiacontrolspell
= spellid(spell_no
);
13395 u
.inertiacontrolspellno
= spell_no
;
13396 u
.inertiacontrol
= 50;
13397 You("start controlling the %s spell.", spellname(spell_no
));
13400 You("decided to not control any spell after all.");
13412 if (getspell(&spell_no
, FALSE
)) {
13413 if (spellid(spell_no
) != NO_SPELL
) {
13414 spl_book
[spell_no
].sp_know
= 0;
13415 pline("Alright, the %s spell is a forgotten spell now.", spellname(spell_no
));
13418 You("decided to not dememorize any spell after all.");
13427 addsomespellmemory()
13431 if (getspell(&spell_no
, FALSE
)) {
13432 if (spellid(spell_no
) == SPE_ADD_SPELL_MEMORY
) {
13433 You("cannot add memory to that spell.");
13434 } else if (spellid(spell_no
) != NO_SPELL
) {
13435 if (rn2(10) && spellknow(spell_no
) <= 0) {
13436 pline("Your attempt to regain knowledge of that forgotten spell fails.");
13439 pline("Your knowledge of the %s spell increases.", spellname(spell_no
));
13440 boostknow(spell_no
, 500);
13443 You("decided to not add memory to any spell after all.");
13454 if (spellid(0) == NO_SPELL
) {
13455 You("don't know any spells, and therefore you cannot add spell memory to them either.");
13459 pline("Choose a spell to add spell memory.");
13461 if (!addsomespellmemoryX()) {
13462 if (yn("Really exit with no spell selected?") == 'y')
13463 pline("You just wasted the opportunity to add memory to a spell.");
13464 else goto addxtragain
;
13469 addsomespellmemoryX()
13473 if (getspell(&spell_no
, FALSE
)) {
13474 if (spellid(spell_no
) != NO_SPELL
) {
13475 if (rn2(20) && spellknow(spell_no
) <= 0) {
13476 pline("Your attempt to regain knowledge of that forgotten spell fails.");
13479 pline("Your knowledge of the %s spell increases.", spellname(spell_no
));
13480 boostknow(spell_no
, rnd(5000));
13483 You("decided to not add memory to any spell after all.");
13491 /* Assumes u.dx, u.dy already set up */
13495 register int dashrange
= 2;
13497 if (!(PlayerCannotUseSkills
) && P_SKILL(P_ELEMENTAL_SPELL
) >= P_SKILLED
) {
13498 switch (P_SKILL(P_ELEMENTAL_SPELL
)) {
13500 case P_SKILLED
: dashrange
= 3; break;
13501 case P_EXPERT
: dashrange
= 4; break;
13502 case P_MASTER
: dashrange
= 5; break;
13503 case P_GRAND_MASTER
: dashrange
= 6; break;
13504 case P_SUPREME_MASTER
: dashrange
= 7; break;
13508 while (dashrange
> 2) {
13509 pline("Current dash range: %d.", dashrange
);
13510 if (yn("Reduce the range by one?") == 'y') {
13512 } else goto dashrangefinish
;
13517 if ((!Punished
|| carried(uball
)) && !u
.utrap
)
13518 You("dash forwards!");
13519 hurtle(u
.dx
, u
.dy
, dashrange
, FALSE
);
13520 multi
= 0; /* No paralysis with dash */
13524 /* percentage chance for mastermind role to resist amnesia and spell forgetting effects --Amy */
13530 if (!Role_if(PM_MASTERMIND
)) return FALSE
; /* shouldn't happen */
13532 if (PlayerCannotUseSkills
) return FALSE
;
13534 switch (P_SKILL(P_MEMORIZATION
)) {
13535 case P_BASIC
: mmchance
= 20; break;
13536 case P_SKILLED
: mmchance
= 40; break;
13537 case P_EXPERT
: mmchance
= 60; break;
13538 case P_MASTER
: mmchance
= 80; break;
13539 case P_GRAND_MASTER
: mmchance
= 90; break;
13540 case P_SUPREME_MASTER
: mmchance
= 95; break;
13543 if (mmchance
> rn2(100)) return TRUE
;
13549 /* lose all spells unconditionally --Amy */
13551 delete_all_spells()
13555 for (n
= 0; n
< MAXSPELL
&& spellid(n
) != NO_SPELL
; n
++) {
13556 spellid(n
) = NO_SPELL
;
13561 /* calculation for mana cost, externalized --Amy */
13566 int energy
= (objects
[spellnum
].oc_level
* 5);
13567 if (energy
< 5) energy
= 5; /* fail safe */
13569 switch (spellnum
) {
13570 case SPE_FINGER_OF_DEATH
: energy
*= 3; break;
13571 case SPE_TIME
: energy
*= 4; break;
13572 case SPE_INERTIA
: energy
*= 4; break;
13573 case SPE_TIME_STOP
: energy
*= 5; break;
13574 case SPE_PARALYSIS
: energy
*= 2; break;
13575 case SPE_HELLISH_BOLT
: energy
*= 2; break;
13576 case SPE_PETRIFY
: energy
*= 4; break;
13577 case SPE_JUMPING
: energy
*= 5; break;
13578 case SPE_ARMOR_SMASH
: energy
*= 5; energy
/= 3; break;
13579 case SPE_GODMODE
: energy
*= 5; energy
/= 2; break;
13580 case SPE_DISINTEGRATION
: energy
*= 5; break;
13581 case SPE_DISINTEGRATION_BEAM
: energy
*= 5; break;
13582 case SPE_FIXING
: energy
*= 3; break;
13583 case SPE_CONVERGE_BREATH
: energy
*= 4; break;
13584 case SPE_CHROMATIC_BEAM
: energy
*= 10; energy
/= 7; break;
13585 case SPE_HEALING
: energy
*= 3; energy
/= 2; break;
13586 case SPE_WATER_FLAME
: energy
*= 3; energy
/= 2; break;
13587 case SPE_FIREBALL
: energy
*= 2; break;
13588 case SPE_SHINING_WAVE
: energy
*= 5; break;
13589 case SPE_RELOCATION
: energy
*= 5; break;
13590 case SPE_FIRE_BOLT
: energy
*= 3; energy
/= 2; break;
13591 case SPE_DEFENSIVE_FIREBALL
: energy
*= 3; energy
/= 2; break;
13592 case SPE_CONE_OF_COLD
: energy
*= 3; energy
/= 2; break;
13593 case SPE_MULTIBEAM
: energy
*= 6; energy
/= 5; break;
13594 case SPE_CALL_THE_ELEMENTS
: energy
*= 7; energy
/= 4; break;
13595 case SPE_INFERNO
: energy
*= 3; energy
/= 2; break;
13596 case SPE_ICE_BEAM
: energy
*= 3; energy
/= 2; break;
13597 case SPE_HYPER_BEAM
: energy
*= 4; energy
/= 3; break;
13598 case SPE_ELEMENTAL_BEAM
: energy
*= 6; energy
/= 5; break;
13599 case SPE_NATURE_BEAM
: energy
*= 5; energy
/= 4; break;
13600 case SPE_ULTRA_P
: energy
*= 3; energy
/= 2; break;
13607 /* learn a random spell ("whichspell" == -1) or a specific one ("whichspell" = ID of the book) --Amy */
13609 wonderspell(whichspell
)
13612 register int randomspell
= SPE_FORCE_BOLT
+ rn2((SPE_PSYBEAM
+ 1) - SPE_FORCE_BOLT
);
13614 if (whichspell
!= -1) randomspell
= whichspell
;
13616 char splname
[BUFSZ
];
13619 sprintf(splname
, "%s", OBJ_NAME(objects
[randomspell
]) );
13621 for (i
= 0; i
< MAXSPELL
; i
++) {
13622 if (spellid(i
) == randomspell
) {
13623 if (spellknow(i
) <= MAX_CAN_STUDY
) {
13624 Your("knowledge of the %s spell is keener.", splname
);
13625 incrnknow(i
, FALSE
);
13626 if (u
.emynluincomplete
) boostknow(i
, 1000);
13627 if (uarmg
&& itemhasappearance(uarmg
, APP_RUNIC_GLOVES
) && !rn2(2) ) incrnknow(i
, FALSE
);
13628 if (Role_if(PM_MAHOU_SHOUJO
)) incrnknow(i
, FALSE
);
13630 if (!PlayerCannotUseSkills
&& P_SKILL(P_MEMORIZATION
) >= P_BASIC
) {
13632 char nervbuf
[QBUFSZ
];
13633 char thisisannoying
= 0;
13635 if (!u
.youhavememorized
) {
13636 u
.youhavememorized
= TRUE
;
13637 if (!iflags
.memorizationknown
) pline("You have the memorization skill, which allows you to gain extra spell memory for newly learned spells. Whenever you learn a spell, you are asked whether you want to use the skill to boost the new spell's memory. In the case of doubt you should ALWAYS ANSWER YES. If you answer no, you just throw the bonus away. (Exception is if you want a forgotten spell, but you only ever need one of those normally.)");
13640 if (!iflags
.memorizationknown
) sprintf(nervbuf
, "Memorize this spell to add more spell memory? In the case of doubt you should always answer yes, unless you want the bonus to go to waste.");
13641 else sprintf(nervbuf
, "Memorize this spell to add more spell memory?");
13642 thisisannoying
= yn_function(nervbuf
, ynqchars
, 'y');
13643 if (thisisannoying
!= 'n') {
13646 switch (P_SKILL(P_MEMORIZATION
)) {
13647 case P_BASIC
: memoboost
= 2; break;
13648 case P_SKILLED
: memoboost
= 4; break;
13649 case P_EXPERT
: memoboost
= 6; break;
13650 case P_MASTER
: memoboost
= 8; break;
13651 case P_GRAND_MASTER
: memoboost
= 10; break;
13652 case P_SUPREME_MASTER
: memoboost
= 12; break;
13654 boostknow(i
, memoboost
* 1000);
13655 spl_book
[i
].sp_memorize
= TRUE
;
13656 pline("Spell memory increased! You gained %d%% extra spell memory.", memoboost
* 10);
13658 spl_book
[i
].sp_memorize
= FALSE
;
13659 pline("You decided to throw away the spell memory bonus. The spell was set to non-memorization mode. If you did that by mistake, you should open the spell menu and turn memorization for this spell back on so that it properly benefits from memorization skill.");
13665 You("know %s quite well already.", splname
);
13668 } else if (spellid(i
) == NO_SPELL
) {
13669 spl_book
[i
].sp_id
= randomspell
;
13670 spl_book
[i
].sp_lev
= objects
[randomspell
].oc_level
;
13671 spl_book
[i
].sp_memorize
= TRUE
;
13672 incrnknow(i
, TRUE
);
13673 if (u
.emynluincomplete
) boostknow(i
, 1000);
13674 if (uarmg
&& itemhasappearance(uarmg
, APP_RUNIC_GLOVES
) && !rn2(2) ) incrnknow(i
, TRUE
);
13675 if (Role_if(PM_MAHOU_SHOUJO
)) incrnknow(i
, TRUE
);
13676 You("gain knowledge of the %s spell.", splname
);
13677 if (randomspell
== SPE_FORBIDDEN_KNOWLEDGE
) {
13679 if (flags
.soundok
) You_hear("a thunderous growling and rumbling...");
13680 if (PlayerHearsSoundEffects
) pline(issoviet
? "Pozdravlyayu, teper' vashe bozhestvo ochen' zol. Pochemu ty ne molish'sya? Eto mozhet byt' prosto privesti svoyu zhizn' do kontsa, a zatem vy mozhete svernut' luchshe, nesovetskimi kharakter nakonets-to! SDELAY ETO SEYCHAS!" : "Grrrrrrr! Grummel! Wummmmmm!");
13683 if (randomspell
== SPE_AMNESIA
) {
13684 You_feel("dizzy!");
13685 forget(ALL_MAP
, FALSE
);
13688 if (!PlayerCannotUseSkills
&& P_SKILL(P_MEMORIZATION
) >= P_BASIC
) {
13690 char nervbuf
[QBUFSZ
];
13691 char thisisannoying
= 0;
13693 if (!u
.youhavememorized
) {
13694 u
.youhavememorized
= TRUE
;
13695 if (!iflags
.memorizationknown
) pline("You have the memorization skill, which allows you to gain extra spell memory for newly learned spells. Whenever you learn a spell, you are asked whether you want to use the skill to boost the new spell's memory. In the case of doubt you should ALWAYS ANSWER YES. If you answer no, you just throw the bonus away. (Exception is if you want a forgotten spell, but you only ever need one of those normally.)");
13698 if (!iflags
.memorizationknown
) sprintf(nervbuf
, "Memorize this spell to add more spell memory? In the case of doubt you should always answer yes, unless you want the bonus to go to waste.");
13699 else sprintf(nervbuf
, "Memorize this spell to add more spell memory?");
13700 thisisannoying
= yn_function(nervbuf
, ynqchars
, 'y');
13701 if (thisisannoying
!= 'n') {
13704 switch (P_SKILL(P_MEMORIZATION
)) {
13705 case P_BASIC
: memoboost
= 2; break;
13706 case P_SKILLED
: memoboost
= 4; break;
13707 case P_EXPERT
: memoboost
= 6; break;
13708 case P_MASTER
: memoboost
= 8; break;
13709 case P_GRAND_MASTER
: memoboost
= 10; break;
13710 case P_SUPREME_MASTER
: memoboost
= 12; break;
13712 boostknow(i
, memoboost
* 1000);
13713 spl_book
[i
].sp_memorize
= TRUE
;
13714 pline("Spell memory increased! You gained %d%% extra spell memory.", memoboost
* 10);
13716 spl_book
[i
].sp_memorize
= FALSE
;
13717 pline("You decided to throw away the spell memory bonus. The spell was set to non-memorization mode. If you did that by mistake, you should open the spell menu and turn memorization for this spell back on so that it properly benefits from memorization skill.");