1 /* SCCS Id: @(#)hack.c 3.4 2003/04/30 */
2 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
3 /* NetHack may be freely redistributed. See license for details. */
8 STATIC_DCL
int moverock(void);
9 STATIC_DCL
int still_chewing(XCHAR_P
,XCHAR_P
);
10 STATIC_DCL
void dosinkfall(void);
11 STATIC_DCL boolean
findtravelpath(BOOLEAN_P
);
12 STATIC_DCL boolean
monstinroom(struct permonst
*,int);
13 STATIC_DCL boolean
anymonstinroom(int);
15 STATIC_DCL
void move_update(BOOLEAN_P
);
16 STATIC_PTR
void set_litX(int,int,void *);
18 static boolean door_opened
; /* set to true if door was opened during test_move */
21 #define IS_SHOP(x) (rooms[x].rtype >= SHOPBASE)
27 rndmappos(x
,y
) /* guaranteed to return a valid coord */
31 if (*x
>= COLNO
) *x
= COLNO
;
32 else if (*x
== -1) *x
= rn2(COLNO
-1)+1;
33 else if (*x
< 1) *x
= 1;
35 if (*y
>= ROWNO
) *y
= ROWNO
;
36 else if (*y
== -1) *y
= rn2(ROWNO
);
37 else if (*y
< 0) *y
= 0;
40 #define HERB_GROWTH_LIMIT 3 /* to limit excessive farming */
42 static const struct herb_info
{
46 { SPRIG_OF_WOLFSBANE
, FALSE
},
47 { CLOVE_OF_GARLIC
, FALSE
},
53 count_herbs_at(x
,y
, watery
)
58 register long count
= 0;
61 for (dd
= 0; dd
< SIZE(herb_info
); dd
++) {
62 if (watery
== herb_info
[dd
].in_water
) {
63 register struct obj
*otmp
= sobj_at(herb_info
[dd
].herb
, x
,y
);
72 /* returns TRUE if a herb can grow at (x,y) */
74 herb_can_grow_at(x
,y
, watery
)
78 register struct rm
*lev
= &levl
[x
][y
];
79 if (inside_shop(x
,y
)) return FALSE
;
81 return (IS_POOL(lev
->typ
) &&
82 ((count_herbs_at(x
,y
, watery
)) < HERB_GROWTH_LIMIT
));
83 return (lev
->lit
&& (lev
->typ
== ROOM
|| lev
->typ
== CORR
||
85 ((lev
->doormask
== D_NODOOR
) ||
86 (lev
->doormask
== D_ISOPEN
) ||
87 (lev
->doormask
== D_BROKEN
)))) &&
88 (count_herbs_at(x
,y
, watery
) < HERB_GROWTH_LIMIT
));
91 /* grow herbs in water. return true if did something. */
93 grow_water_herbs(herb
, x
,y
)
100 otmp
= sobj_at(herb
, x
, y
);
101 if (otmp
&& herb_can_grow_at(x
,y
, TRUE
)) {
103 otmp
->owt
= weight(otmp
);
105 /* There's no need to start growing these on the neighboring
106 * mapgrids, as they move around (see water_current())
112 /* grow herb on ground at (x,y), or maybe spread out.
113 return true if did something. */
115 grow_herbs(herb
, x
,y
, showmsg
, update
)
118 boolean showmsg
, update
;
125 otmp
= sobj_at(herb
, x
, y
);
126 if (otmp
&& herb_can_grow_at(x
,y
, FALSE
)) {
127 if (otmp
->quan
<= rn2(HERB_GROWTH_LIMIT
)) {
129 otmp
->owt
= weight(otmp
);
132 int dd
, dofs
= rn2(8);
133 /* check surroundings, maybe grow there? */
134 for (dd
= 0; dd
< 8; dd
++) {
137 dtoxy(&pos
, (dd
+dofs
) % 8);
140 if (isok(pos
.x
,pos
.y
) && herb_can_grow_at(pos
.x
,pos
.y
, FALSE
)) {
141 lev
= &levl
[pos
.x
][pos
.y
];
142 otmp
= sobj_at(herb
, pos
.x
, pos
.y
);
144 if (otmp
->quan
<= rn2(HERB_GROWTH_LIMIT
)) {
146 otmp
->owt
= weight(otmp
);
150 otmp
= mksobj(herb
, TRUE
, FALSE
, FALSE
);
153 otmp
->owt
= weight(otmp
);
154 place_object(otmp
, pos
.x
, pos
.y
);
155 if (update
) newsym(pos
.x
,pos
.y
);
156 if (cansee(pos
.x
,pos
.y
)) {
157 if (showmsg
&& flags
.verbose
) {
159 if (herb
== CLOVE_OF_GARLIC
)
160 what
= "some garlic";
162 what
= an(xname(otmp
));
163 Norep("Suddenly you notice %s growing on the %s.",
164 what
, surface(pos
.x
,pos
.y
));
177 /* moves topmost object in water at (x,y) to dir.
178 return true if did something. */
180 water_current(x
,y
,dir
,waterforce
, showmsg
, update
)
183 unsigned waterforce
; /* strength of the water current */
184 boolean showmsg
, update
;
193 if (isok(pos
.x
,pos
.y
) && IS_POOL(levl
[x
][y
].typ
) &&
194 IS_POOL(levl
[pos
.x
][pos
.y
].typ
)) {
195 otmp
= level
.objects
[x
][y
];
196 if (otmp
&& otmp
->where
== OBJ_FLOOR
) {
198 otmp
= splitobj(otmp
, otmp
->quan
- 1);
199 if (otmp
->owt
<= waterforce
) {
200 if (showmsg
&& Underwater
&&
201 (cansee(pos
.x
,pos
.y
) || cansee(x
,y
))) {
202 Norep("%s floats%s in%s the murky water.",
204 (cansee(x
,y
) && cansee(pos
.x
,pos
.y
)) ? "" :
205 (cansee(x
,y
) ? " away from you" : " towards you"),
206 flags
.verbose
? " the currents of" : "");
208 obj_extract_self(otmp
);
209 place_object(otmp
, pos
.x
,pos
.y
);
216 } else /* the object didn't move, put it back */
223 /* a tree at (x,y) spontaneously drops a ripe fruit */
225 drop_ripe_treefruit(x
,y
,showmsg
, update
)
227 boolean showmsg
, update
;
229 register struct rm
*lev
;
233 if (IS_TREE(lev
->typ
) && !(lev
->looted
& TREE_LOOTED
) && may_dig(x
,y
)) {
235 int dir
, dofs
= rn2(8);
237 /* Amy edit: this shouldn't be a 100% chance, after all kicking isn't either */
239 levl
[x
][y
].looted
|= TREE_LOOTED
;
243 for (dir
= 0; dir
< 8; dir
++) {
244 dtoxy(&pos
, (dir
+ dofs
) % 8);
247 if (!isok(pos
.x
, pos
.y
)) return FALSE
;
248 lev
= &levl
[pos
.x
][pos
.y
];
249 if (SPACE_POS(lev
->typ
) || IS_POOL(lev
->typ
)) {
251 otmp
= rnd_treefruit_at(pos
.x
,pos
.y
);
254 otmp
->owt
= weight(otmp
);
255 obj_extract_self(otmp
);
257 if ((cansee(pos
.x
,pos
.y
) || cansee(x
,y
))) {
258 Norep("%s falls from %s%s.",
259 cansee(pos
.x
,pos
.y
) ? An(xname(otmp
)) : Something
,
260 cansee(x
,y
) ? "the tree" : "somewhere",
261 (cansee(x
,y
) && IS_POOL(lev
->typ
)) ?
262 " into the water" : "");
263 } else if (distu(pos
.x
,pos
.y
) < 9 &&
264 otmp
->otyp
!= EUCALYPTUS_LEAF
) {
265 /* a leaf is too light to cause any sound */
267 (IS_POOL(lev
->typ
) || IS_FOUNTAIN(lev
->typ
)) ?
268 "plop" : "splut"); /* rainforesty sounds */
271 place_object(otmp
, pos
.x
,pos
.y
);
273 if (rn2(6)) levl
[x
][y
].looted
|= TREE_LOOTED
;
274 if (update
) newsym(pos
.x
,pos
.y
);
283 /* Tree at (x,y) seeds. returns TRUE if a new tree was created.
284 * Creates a kind of forest, with (hopefully) most places available.
294 if (IS_TREE(levl
[x
][y
].typ
) && may_dig(x
,y
)) {
300 dtoxy(&pos2
, (dir
+rn2(2)) % 8);
304 if (!isok(pos
.x
,pos
.y
)) return FALSE
;
305 lev
= &levl
[pos
.x
][pos
.y
];
306 if (lev
->lit
&& !cansee(pos
.x
,pos
.y
) && !inside_shop(pos
.x
,pos
.y
) &&
307 (lev
->typ
== ROOM
|| lev
->typ
== CORR
) &&
308 !(u
.ux
== pos
.x
&& u
.uy
== pos
.y
) && !m_at(pos
.x
,pos
.y
) &&
309 !t_at(pos
.x
,pos
.y
) && !OBJ_AT(pos
.x
,pos
.y
)) {
312 for (dx
= pos
.x
-1; dx
<= pos
.x
+1; dx
++) {
313 for (dy
= pos
.y
-1; dy
<= pos
.y
+1; dy
++) {
315 (isok(dx
,dy
) && !SPACE_POS(levl
[dx
][dy
].typ
)))
321 lev
->looted
&= ~TREE_LOOTED
;
322 block_point(pos
.x
,pos
.y
);
331 dgn_growths(showmsg
, update
, treesnstuff
)
332 boolean showmsg
; /* show messages */
333 boolean update
; /* do newsym() */
336 int herbnum
= rn2(SIZE(herb_info
));
337 int randomx
, randomy
;
338 int i
, j
, count
, randchance
=0;
339 boolean secretcorr
= TRUE
;
340 /*register struct monst *mtmp;*/
342 /* note by Amy: disabled herb growth and water currents. GDB says that the dreaded savegame error is happening
343 * in this function, and since Paliculo had the savegame error happen in SLASH'EM 0.08, chances are it's something
344 * that was introduced pre-SLEX. That said, the newsym() function was erroring too, and since the dgn_growths
345 * function is being called during saving for every single level that exists, I wouldn't be at all surprised if
346 * that's somehow related. At the very least I'm taking out the minliquid() call below, and that means we don't need
347 * the mtmp anymore either. If it's still somehow crashing then we'll need to look into the GDB output which will
348 * hopefully tell us where exactly in newsym() it's choking...
349 * another note: on levels that the character isn't currently on, only regrow walls, don't drop fruit */
351 /* update: *sigh* apparently the newsym() is really the culprit and I could just have used the update variable! */
353 if (!rn2(100)) (void) seed_tree(-1,-1);
354 /*if (herb_info[herbnum].in_water)
355 (void) grow_water_herbs(herb_info[herbnum].herb, -1,-1);
357 (void) grow_herbs(herb_info[herbnum].herb, -1,-1, showmsg, update);*/
359 if (treesnstuff
&& !rn2(isfriday
? 100 : 30)) (void) drop_ripe_treefruit(-1,-1, showmsg
, update
);
361 /*(void) water_current(-1,-1, rn2(8), Is_waterlevel(&u.uz) ? 200 : 25, showmsg, update);*/
365 /* evil patch idea by Amy: occasionally, corridors and room squares will "grow" back into solid rock or walls.
366 * Depending on the # of surrounding squares that are blocked, give a higher or lower chance to place a new wall.
367 * If 6 out of 8 surrounding squares are blocked it most probably means that it's a corridor, which would
368 * completely block progress if it were made into a wall, and since players don't always have a pick-axe, let that
369 * only happen rarely. On the other hand, if all 8 surrounding squares are blocked, there probably isn't much
370 * harm done in closing it.
371 * Why am I such a filthy bitch who even thinks up such bullshit?
372 * Relax! There's a simple reason - after a while, umber hulks and similar monsters might dig out entire levels,
373 * and in vanilla there's absolutely no way to restore them to their previous condition. Not so here,
374 * where the dungeon will gradually "repair" itself, so to speak. Scrolls of lockout can further that repair.*/
375 if (!rn2(iswarper
? 5 : 10) ) {
376 randomx
= rn1(COLNO
-3,2);
377 randomy
= rn2(ROWNO
);
379 if ((!rn2(3) || (!In_sokoban(&u
.uz
)) ) && 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
) ) ) {
381 for (i
= -1; i
<=1; i
++) for(j
= -1; j
<=1; j
++) {
382 if (!i
&& !j
) continue;
383 if (!isok(randomx
+i
, randomy
+j
) || IS_WATERTUNNEL(levl
[randomx
+i
][randomy
+j
].typ
) || IS_STWALL(levl
[randomx
+i
][randomy
+j
].typ
) )
389 randchance
= (levl
[randomx
][randomy
].wall_info
& W_EASYGROWTH
) ? 1 : 10;
392 randchance
= (levl
[randomx
][randomy
].wall_info
& W_EASYGROWTH
) ? 1 : 20;
395 randchance
= (levl
[randomx
][randomy
].wall_info
& W_EASYGROWTH
) ? 10 : 10000;
398 randchance
= (levl
[randomx
][randomy
].wall_info
& W_EASYGROWTH
) ? 5 : 2000;
401 randchance
= (levl
[randomx
][randomy
].wall_info
& W_EASYGROWTH
) ? 2 : 500;
404 randchance
= (levl
[randomx
][randomy
].wall_info
& W_EASYGROWTH
) ? 2 : 100;
407 randchance
= (levl
[randomx
][randomy
].wall_info
& W_EASYGROWTH
) ? 1 : 30;
410 randchance
= (levl
[randomx
][randomy
].wall_info
& W_EASYGROWTH
) ? 1 : 20;
413 default: /* e.g. if it's 9 */
414 randchance
= (levl
[randomx
][randomy
].wall_info
& W_EASYGROWTH
) ? 1 : 10;
418 /*pline("coord %d,%d, count %d, chance %d",randomx, randomy, count, randchance);*/
420 /* In Soviet Russia, digging out an entire level should be permanent, like Moscow's Scorched Earth strategy
421 * in World War II. You should have no way of restoring any area to its previous condition, no matter what.
422 * And of course there are no pick-axes either, or any other methods of removing newly created walls. --Amy */
424 if (issoviet
) randchance
*= 100;
426 if (!rn2(randchance
) && (!In_sokoban(&u
.uz
) || !sobj_at(BOULDER
, randomx
, randomy
) ) ) {
429 /* Sigh again. I had already given up (see below), and now of course this line was also causing
430 * the savegame error again. One day I will fucking eradicate newsym() entirely. BULLSHIT! */
432 doorlockX(randomx
, randomy
, update
); /* let's hope this "update" will FINALLY fix things ARGH */
433 if (!(levl
[randomx
][randomy
].wall_info
& W_EASYGROWTH
)) levl
[randomx
][randomy
].wall_info
|= W_HARDGROWTH
;
435 else if ((levl
[randomx
][randomy
].wall_info
& W_NONDIGGABLE
) == 0) {
436 if (levl
[randomx
][randomy
].typ
!= DOOR
) {
437 if (secretcorr
&& !rn2(10)) levl
[randomx
][randomy
].typ
= SCORR
;
438 else levl
[randomx
][randomy
].typ
= ROCKWALL
;
441 if (secretcorr
&& !rn2(10)) levl
[randomx
][randomy
].typ
= SDOOR
;
442 else levl
[randomx
][randomy
].typ
= CROSSWALL
;
444 if (!(levl
[randomx
][randomy
].wall_info
& W_EASYGROWTH
)) levl
[randomx
][randomy
].wall_info
|= W_HARDGROWTH
;
445 blockorunblock_point(randomx
,randomy
);
446 del_engr_at(randomx
, randomy
);
448 /*if ((mtmp = m_at(randomx, randomy)) != 0) {
449 (void) minliquid(mtmp);
451 if (update
) newsym(randomx
,randomy
);
452 /* this line, without the update variable check, is probably the monument of stupidity that caused savegame errors */
462 /* yet another update by Amy: I give up. No fucking idea why the line below is causing the savegame error,
463 * but it is. Apparently, calling this function during saving fucks up the "uwep" or "uswapwep" structures,
464 * even though the safety checks should make sure that it works right. Oh well, have to make the function get called
465 * only during regular play then, even though that is really stupid. */
469 if ((u
.uprops
[WALL_TRAP_EFFECT
].extrinsic
|| WallTrapping
|| have_wallstone() || (uarmh
&& uarmh
->oartifact
== ART_JABONE_S_COLOR_CHANGE
) || (uarmg
&& uarmg
->oartifact
== ART_STOUT_IMMURRING
) || (uarmc
&& uarmc
->oartifact
== ART_MOST_CHARISMATIC_PRESIDENT
) || (uimplant
&& uimplant
->oartifact
== ART_THEY_RE_REALLY_AFTER_ME
) || autismweaponcheck(ART_CUDGEL_OF_CUTHBERT
) || autismweaponcheck(ART_ONE_THROUGH_FOUR_SCEPTER
) ) && rn2(WallRegrowXtra
? 500 : 100)) {
478 /* catch up with growths when returning to a previously visited level */
480 catchup_dgn_growths(mvs
)
483 if (mvs
< 0) mvs
= 0;
484 else if (mvs
> LARGEST_INT
) mvs
= LARGEST_INT
;
486 dgn_growths(FALSE
, FALSE
, FALSE
);
488 #endif /* DUNGEON_GROWTH */
491 revive_nasty(x
, y
, msg
)
495 register struct obj
*otmp
, *otmp2
;
498 boolean revived
= FALSE
;
500 for(otmp
= level
.objects
[x
][y
]; otmp
; otmp
= otmp2
) {
501 otmp2
= otmp
->nexthere
;
502 if (otmp
->otyp
== CORPSE
&&
503 (is_rider(&mons
[otmp
->corpsenm
]) || is_deadlysin(&mons
[otmp
->corpsenm
]) ||
504 otmp
->corpsenm
== PM_WIZARD_OF_YENDOR
)) {
505 /* move any living monster already at that location */
506 if((mtmp
= m_at(x
,y
)) && enexto(&cc
, x
, y
, mtmp
->data
))
507 rloc_to(mtmp
, cc
.x
, cc
.y
);
508 if(msg
) Norep("%s", msg
);
509 revived
= revive_corpse(otmp
, FALSE
);
513 /* this location might not be safe, if not, move revived monster */
516 if (mtmp
&& !goodpos(x
, y
, mtmp
, 0) &&
517 enexto(&cc
, x
, y
, mtmp
->data
)) {
518 rloc_to(mtmp
, cc
.x
, cc
.y
);
520 /* else impossible? */
529 register xchar rx
, ry
, sx
, sy
;
530 register struct obj
*otmp
;
531 register struct trap
*ttmp
;
532 register struct monst
*mtmp
;
534 sx
= u
.ux
+ u
.dx
, sy
= u
.uy
+ u
.dy
; /* boulder starting position */
535 while ((otmp
= sobj_at(BOULDER
, sx
, sy
)) != 0) {
536 /* make sure that this boulder is visible as the top object */
537 if (otmp
!= level
.objects
[sx
][sy
]) movobj(otmp
, sx
, sy
);
539 rx
= u
.ux
+ 2 * u
.dx
; /* boulder destination position */
540 ry
= u
.uy
+ 2 * u
.dy
;
542 /* if you combine levitator and sokosolver the game shouldn't be unwinnable --Amy */
543 if ((Levitation
|| Is_airlevel(&u
.uz
)) && !Race_if(PM_LEVITATOR
) ) {
544 if (Blind
) feel_location(sx
,sy
);
545 You("don't have enough leverage to push %s.", the(xname(otmp
)));
546 /* Give them a chance to climb over it? */
549 if (verysmall(youmonst
.data
) && !Race_if(PM_TRANSFORMER
) && !u
.usteed
) {
550 if (Blind
) feel_location(sx
,sy
);
551 pline("You're too small to push that %s.", xname(otmp
));
554 if (isok(rx
,ry
) && !IS_ROCK(levl
[rx
][ry
].typ
) &&
555 levl
[rx
][ry
].typ
!= IRONBARS
&&
556 (!IS_DOOR(levl
[rx
][ry
].typ
) || !(u
.dx
&& u
.dy
) || (
558 !Is_rogue_level(&u
.uz
) &&
560 (levl
[rx
][ry
].doormask
& ~D_BROKEN
) == D_NODOOR
)) &&
561 !sobj_at(BOULDER
, rx
, ry
)) {
565 /* KMH -- Sokoban doesn't let you push boulders diagonally */
566 if (In_sokoban(&u
.uz
) && u
.dx
&& u
.dy
) {
567 if (Blind
) feel_location(sx
,sy
);
568 pline("%s won't roll diagonally on this %s.",
569 The(xname(otmp
)), surface(sx
, sy
));
573 if (revive_nasty(rx
, ry
, "You sense movement on the other side.")) {
574 pline("The boulder vanishes!");
575 delobj(otmp
); /* prevent easy Death farming --Amy */
579 if (mtmp
&& !noncorporeal(mtmp
->data
) &&
581 !(ttmp
&& ((ttmp
->ttyp
== PIT
) || (ttmp
->ttyp
== SHIT_PIT
) || (ttmp
->ttyp
== MANA_PIT
)
582 || (ttmp
->ttyp
== ANOXIC_PIT
) || (ttmp
->ttyp
== HYPOXIC_PIT
) || (ttmp
->ttyp
== ACID_PIT
) || (ttmp
->ttyp
== SPIKED_PIT
) || (ttmp
->ttyp
== GIANT_CHASM
))))) {
584 if (Blind
) feel_location(sx
,sy
);
585 if (canspotmon(mtmp
)) {
586 boolean by_name
= (mtmp
->data
->geno
& G_UNIQ
||
587 mtmp
->isshk
|| mtmp
->mnamelth
);
588 if (by_name
&& !Hallucination
)
589 pline("%s is on the other side.", Monnam(mtmp
));
591 pline("There's %s on the other side.", a_monnam(mtmp
));
593 You_hear("a monster behind %s.", the(xname(otmp
)));
594 if (!(mtmp
->data
->msound
== MS_DEEPSTATE
) && !(mtmp
->egotype_deepstatemember
)) map_invisible(rx
, ry
);
597 pline("Perhaps that's why %s cannot move it.", u
.usteed
? y_monnam(u
.usteed
) : "you");
605 obj_extract_self(otmp
);
606 place_object(otmp
, rx
, ry
);
607 unblock_point(sx
, sy
);
609 pline("KAABLAMM!!! %s %s land mine.",
610 Tobjnam(otmp
, "trigger"),
611 ttmp
->madeby_u
? "your" : "a");
612 blow_up_landmine(ttmp
);
613 /* if the boulder remains, it should fill the pit */
614 fill_pit(u
.ux
, u
.uy
);
615 if (cansee(rx
,ry
)) newsym(rx
,ry
);
627 obj_extract_self(otmp
);
628 /* vision kludge to get messages right;
629 the pit will temporarily be seen even
630 if this is one among multiple boulders */
631 if (!Blind
) viz_array
[ry
][rx
] |= IN_SIGHT
;
632 if (!flooreffects(otmp
, rx
, ry
, "fall")) {
633 place_object(otmp
, rx
, ry
);
635 if (mtmp
&& !Blind
) newsym(rx
, ry
);
642 pline("Kerplunk! You no longer feel %s.",
645 pline("%s%s and %s a %s in the %s!",
647 (ttmp
->ttyp
== TRAPDOOR
) ? "trigger" : "fall"),
648 (ttmp
->ttyp
== TRAPDOOR
) ? nul
: " into",
649 otense(otmp
, "plug"),
650 (ttmp
->ttyp
== TRAPDOOR
) ? "trap door" : "hole",
652 if (PlayerHearsSoundEffects
) pline(issoviet
? "Takim obrazom, vy deystvitel'no dumayete, chto vy dostatochno umny, chtoby reshit' golovolomku bloka. Ya ser'yezno somnevayus' v etom." : "Tchueb!");
656 if (cansee(rx
,ry
)) newsym(rx
,ry
);
663 pline("%s pushes %s and suddenly it disappears!",
664 upstart(y_monnam(u
.usteed
)), the(xname(otmp
)));
666 You("push %s and suddenly it disappears!",
668 if (ttmp
->ttyp
== TELEP_TRAP
)
670 else if (ttmp
->ttyp
== BEAMER_TRAP
)
673 int newlev
= random_teleport_level();
676 if (newlev
== depth(&u
.uz
) || In_endgame(&u
.uz
))
678 obj_extract_self(otmp
);
679 add_to_migration(otmp
);
680 get_level(&dest
, newlev
);
681 otmp
->ox
= dest
.dnum
;
682 otmp
->oy
= dest
.dlevel
;
683 otmp
->owornmask
= (long)MIGR_RANDOM
;
688 if (closed_door(rx
, ry
))
690 if (boulder_hits_pool(otmp
, rx
, ry
, TRUE
))
693 * Re-link at top of fobj chain so that pile order is preserved
694 * when level is restored.
698 place_object(otmp
, otmp
->ox
, otmp
->oy
);
702 #ifdef LINT /* static long lastmovetime; */
706 /* note: reset to zero after save/restore cycle */
707 static NEARDATA
long lastmovetime
;
710 if (moves
> lastmovetime
+2 || moves
< lastmovetime
)
711 pline("With %s effort you move %s.",
712 (throws_rocks(youmonst
.data
) || (uarmg
&& uarmg
->oartifact
== ART_MOUNTAIN_FISTS
)) ? "little" : "great",
714 if (!rn2(50) || (otmp
->oartifact
== ART_COOL_DUMBBELL
) ) exercise(A_STR
, TRUE
);
716 pline("%s moves %s.",
717 upstart(y_monnam(u
.usteed
)), the(xname(otmp
)));
718 lastmovetime
= moves
;
720 if (otmp
&& otmp
->oartifact
== ART_ENTRAP_THE_UNWARY
&& !rn2(100)) {
721 if (t_at(u
.ux
, u
.uy
) == 0) (void) maketrap(u
.ux
, u
.uy
, rndtrap(), 0, FALSE
);
724 if (otmp
&& otmp
->oartifact
== ART_SIGNAL_TONE
) {
728 if (otmp
&& otmp
->oartifact
== ART_WENDYHOLE
) {
729 pline("Wendy produces %s farting noises with her sexy butt.", !rn2(3) ? "loud" : !rn2(2) ? "disgusting" : "erogenous");
730 u
.cnd_fartingcount
++;
731 if (Role_if(PM_CLIMACTERIAL
)) climtrainsqueaking(1);
732 if (Role_if(PM_BUTT_LOVER
) && !rn2(20)) buttlovertrigger();
733 if (Role_if(PM_SOCIAL_JUSTICE_WARRIOR
)) sjwtrigger();
734 if (!extralongsqueak()) badeffect();
738 /* Move the boulder *after* the message. */
739 if (memory_is_invisible(rx
, ry
))
740 unmap_object(rx
, ry
);
741 movobj(otmp
, rx
, ry
); /* does newsym(rx,ry) */
743 feel_location(rx
,ry
);
744 feel_location(sx
,sy
);
751 pline("%s tries to move %s, but cannot.",
752 upstart(y_monnam(u
.usteed
)), the(xname(otmp
)));
754 You("try to move %s, but in vain.", the(xname(otmp
)));
755 if (Blind
) feel_location(sx
,sy
);
757 if (throws_rocks(youmonst
.data
) || (uarmg
&& uarmg
->oartifact
== ART_MOUNTAIN_FISTS
) ) {
758 if (u
.usteed
&& !(uwep
&& uwep
->oartifact
== ART_SORTIE_A_GAUCHE
) && !(powerfulimplants() && uimplant
&& uimplant
->oartifact
== ART_READY_FOR_A_RIDE
) && !FemtrapActiveKerstin
&& !(bmwride(ART_DEEPER_LAID_BMW
)) && (PlayerCannotUseSkills
|| P_SKILL(P_RIDING
) < P_BASIC
) ) {
759 You("aren't skilled enough to %s %s from %s.",
760 (flags
.pickup
&& !In_sokoban(&u
.uz
))
761 ? "pick up" : "push aside",
762 the(xname(otmp
)), y_monnam(u
.usteed
));
765 pline("However, you can easily %s.",
766 (flags
.pickup
&& !In_sokoban(&u
.uz
))
767 ? "pick it up" : "push it aside");
768 if (yn("Do it?") != 'y')
771 if (In_sokoban(&u
.uz
) && !playercancheatinsoko()) {
773 pline("You cheater!");
774 if (evilfriday
) u
.ugangr
++;
782 if (!u
.usteed
&& (((!invent
|| inv_weight() <= -1500) &&
783 (!u
.dx
|| !u
.dy
|| (IS_ROCK(levl
[u
.ux
][sy
].typ
)
784 && IS_ROCK(levl
[sx
][u
.uy
].typ
))))
785 || verysmall(youmonst
.data
))) {
787 if (yn("However, you can squeeze yourself into a small opening. Do it?") != 'y')
790 if (In_sokoban(&u
.uz
) && !playercancheatinsoko()) {
792 pline("You cheater!");
793 if (evilfriday
) u
.ugangr
++;
809 * Chew on a wall, door, or boulder. Returns TRUE if still eating, FALSE
816 struct rm
*lev
= &levl
[x
][y
];
817 struct obj
*boulder
= sobj_at(BOULDER
,x
,y
);
818 const char *digtxt
= (char *)0, *dmgtxt
= (char *)0;
820 if (digging
.down
) /* not continuing previous dig (w/ pick-axe) */
821 (void) memset((void *)&digging
, 0, sizeof digging
);
823 if (!boulder
&& IS_ROCK(lev
->typ
) && !may_dig(x
,y
)) {
824 You("hurt your teeth on the %s.",
825 IS_TREE(lev
->typ
) ? "tree" : "hard stone");
828 } else if (digging
.pos
.x
!= x
|| digging
.pos
.y
!= y
||
829 !on_level(&digging
.level
, &u
.uz
)) {
830 digging
.down
= FALSE
;
832 digging
.warned
= FALSE
;
835 assign_level(&digging
.level
, &u
.uz
);
836 /* solid rock takes more work & time to dig through */
838 (IS_ROCK(lev
->typ
) && !IS_TREE(lev
->typ
) ? 30 : 60) + increase_damage_bonus_value();
839 You("start chewing %s %s.",
840 (boulder
|| IS_TREE(lev
->typ
)) ? "on a" : "a hole in the",
841 boulder
? "boulder" :
842 IS_TREE(lev
->typ
) ? "tree" : IS_WATERTUNNEL(lev
->typ
) ? "rock above the water" : IS_ROCK(lev
->typ
) ? "rock" : "door");
843 watch_dig((struct monst
*)0, x
, y
, FALSE
);
845 } else if ((digging
.effort
+= (30 + increase_damage_bonus_value())) <= 100) {
847 You("%s chewing on the %s.",
848 digging
.chew
? "continue" : "begin",
849 boulder
? "boulder" :
850 IS_TREE(lev
->typ
) ? "tree" :
851 IS_ROCK(lev
->typ
) ? "rock" : "door");
853 watch_dig((struct monst
*)0, x
, y
, FALSE
);
857 /* Okay, you've chewed through something */
859 if (FemtrapActiveNora
) {
864 u
.uhunger
+= rnd(20);
867 delobj(boulder
); /* boulder goes bye-bye */
868 You("eat the boulder."); /* yum */
871 * The location could still block because of
872 * 1. More than one boulder
873 * 2. Boulder stuck in a wall/stone/door.
875 * [perhaps use does_block() below (from vision.c)]
877 if (IS_ROCK(lev
->typ
) || closed_door(x
,y
) || sobj_at(BOULDER
,x
,y
)) {
878 block_point(x
,y
); /* delobj will unblock the point */
879 /* reset dig state */
880 (void) memset((void *)&digging
, 0, sizeof digging
);
884 } else if (IS_WATERTUNNEL(lev
->typ
)) {
885 digtxt
= "chew away the rock above the water.";
887 } else if (IS_WALL(lev
->typ
)) {
888 if (*in_rooms(x
, y
, SHOPBASE
)) {
889 add_damage(x
, y
, 10L * ACURRSTR
);
892 digtxt
= "chew a hole in the wall.";
893 if (level
.flags
.is_maze_lev
) {
895 if (u
.geolysis
&& !rn2(4)) {
896 lev
->typ
= !rn2(3) ? WATER
: !rn2(2) ? ICE
: CLOUD
;
898 } else if (level
.flags
.is_cavernous_lev
&& !in_town(x
, y
)) {
900 if (u
.geolysis
&& !rn2(4)) {
901 lev
->typ
= !rn2(3) ? WATER
: !rn2(2) ? ICE
: CLOUD
;
905 lev
->doormask
= D_NODOOR
;
907 } else if (IS_TREE(lev
->typ
)) {
908 digtxt
= "chew through the tree.";
910 } else if (lev
->typ
== SDOOR
) {
911 if (lev
->doormask
& D_TRAPPED
) {
912 lev
->doormask
= D_NODOOR
;
913 b_trapped("secret door", 0);
915 digtxt
= "chew through the secret door.";
916 lev
->doormask
= D_BROKEN
;
920 } else if (IS_DOOR(lev
->typ
)) {
921 if (*in_rooms(x
, y
, SHOPBASE
)) {
922 add_damage(x
, y
, 400L);
925 if (lev
->doormask
& D_TRAPPED
) {
926 lev
->doormask
= D_NODOOR
;
927 b_trapped("door", 0);
929 digtxt
= "chew through the door.";
930 lev
->doormask
= D_BROKEN
;
933 } else { /* STONE or SCORR */
934 digtxt
= "chew a passage through the rock.";
936 if (u
.geolysis
&& !rn2(4)) {
937 lev
->typ
= !rn2(3) ? WATER
: !rn2(2) ? ICE
: CLOUD
;
941 unblock_point(x
, y
); /* vision */
942 if (!(levl
[x
][y
].wall_info
& W_HARDGROWTH
)) levl
[x
][y
].wall_info
|= W_EASYGROWTH
;
944 if (digtxt
) You("%s", digtxt
); /* after newsym */
945 if (dmgtxt
) pay_for_damage(dmgtxt
, FALSE
);
946 (void) memset((void *)&digging
, 0, sizeof digging
);
955 register struct obj
*obj
;
956 register xchar ox
, oy
;
958 /* optimize by leaving on the fobj chain? */
960 newsym(obj
->ox
, obj
->oy
);
961 place_object(obj
, ox
, oy
);
965 static NEARDATA
const char fell_on_sink
[] = "fell onto a sink";
970 register struct obj
*obj
;
972 if (is_floater(youmonst
.data
) || (HLevitation
& FROMOUTSIDE
)) {
973 You("wobble unsteadily for a moment.");
975 long save_ELev
= ELevitation
, save_HLev
= HLevitation
;
977 /* fake removal of levitation in advance so that final
978 disclosure will be right in case this turns out to
979 be fatal; fortunately the fact that rings and boots
980 are really still worn has no effect on bones data */
981 ELevitation
= HLevitation
= 0L;
982 You("crash to the floor!");
983 losehp(rn1(8, 25 - (int)ACURR(A_CON
)),
984 fell_on_sink
, NO_KILLER_PREFIX
);
985 exercise(A_DEX
, FALSE
);
986 selftouch("Falling, you");
987 for (obj
= level
.objects
[u
.ux
][u
.uy
]; obj
; obj
= obj
->nexthere
)
988 if (obj
->oclass
== WEAPON_CLASS
|| is_weptool(obj
)) {
989 You("fell on %s.", doname(obj
));
990 losehp(rnd(3), fell_on_sink
, NO_KILLER_PREFIX
);
991 exercise(A_CON
, FALSE
);
993 ELevitation
= save_ELev
;
994 HLevitation
= save_HLev
;
997 ELevitation
&= ~W_ARTI
;
998 HLevitation
&= ~(I_SPECIAL
|TIMEOUT
);
1000 if(uleft
&& uleft
->otyp
== RIN_LEVITATION
) {
1005 if(uright
&& uright
->otyp
== RIN_LEVITATION
) {
1010 if(uarmf
&& uarmf
->otyp
== LEVITATION_BOOTS
) {
1021 /* intended to be called only on ROCKs */
1023 return (boolean
)(!(IS_STWALL(levl
[x
][y
].typ
) && !(IS_DIGGABLEWALL(levl
[x
][y
].typ
)) &&
1024 (levl
[x
][y
].wall_info
& W_NONDIGGABLE
)) && !(IS_FARMLAND(levl
[x
][y
].typ
)) && !(IS_GRAVEWALL(levl
[x
][y
].typ
)) && !(IS_MOUNTAIN(levl
[x
][y
].typ
)) );
1031 return (boolean
)(!(IS_STWALL(levl
[x
][y
].typ
) && !(IS_DIGGABLEWALL(levl
[x
][y
].typ
)) &&
1032 (levl
[x
][y
].wall_info
& W_NONPASSWALL
)));
1038 /* [ALI] Changed to take monst * as argument to support passwall property */
1044 struct permonst
*mdat
= mon
->data
;
1045 boolean passwall
= mon
== &youmonst
? Passes_walls
: ( passes_walls(mdat
) || (mon
->egotype_wallwalk
) );
1046 return((boolean
) ((In_sokoban(&u
.uz
) && sobj_at(BOULDER
,x
,y
)) ||
1047 (IS_ROCKWFL(levl
[x
][y
].typ
)
1048 && (!tunnels(mdat
) || needspick(mdat
) || !may_dig(x
,y
))
1049 && !(passwall
&& may_passwall(x
,y
)))));
1053 invocation_pos(x
, y
)
1056 return((boolean
)(Invocation_lev(&u
.uz
) && x
== inv_pos
.x
&& y
== inv_pos
.y
));
1061 /* For my clever ending messages... */
1062 int Instant_Death
= 0;
1063 int Quick_Death
= 0;
1064 int Nibble_Death
= 0;
1066 int second_last_hit
= 0;
1067 int third_last_hit
= 0;
1069 /* For those tough guys who get carried away... */
1072 /* return TRUE if (dx,dy) is an OK place to move
1073 * mode is one of DO_MOVE, TEST_MOVE or TEST_TRAV
1076 test_move(ux
, uy
, dx
, dy
, mode
)
1082 register struct rm
*tmpr
= &levl
[x
][y
];
1083 register struct rm
*ust
;
1084 boolean opentry
= 0;
1087 * Check for physical obstacles. First, the place we are going.
1089 if (IS_ROCK(tmpr
->typ
) || tmpr
->typ
== IRONBARS
|| (SpellColorPlatinum
&& (glyph_to_cmap(glyph_at(x
,y
)) == S_bars
) ) || tmpr
->typ
== WOODENTABLE
|| tmpr
->typ
== WATERTUNNEL
) {
1090 if (Blind
&& mode
== DO_MOVE
) feel_location(x
,y
);
1091 if (tmpr
->typ
== IRONBARS
|| (SpellColorPlatinum
&& (glyph_to_cmap(glyph_at(x
,y
)) == S_bars
) ) ) {
1092 if (!(Passes_walls
|| passes_bars(youmonst
.data
) || (powerfulimplants() && uimplant
&& uimplant
&& uimplant
->oartifact
== ART_SIGNIFICANT_RNG_JITTER
) )) {
1093 if (mode
== DO_MOVE
) {
1094 if (WallsAreHyperBlue
) {
1095 You("crash into a set of iron bars! Ouch!");
1097 losehp(rnd(10), "walking into iron bars", KILLED_BY
);
1098 if (!rn2(Role_if(PM_COURIER
) ? 1000 : uarmh
? 50 : 10)) {
1100 adjattrib(rn2(2) ? A_INT
: A_WIS
, -rno(3), FALSE
, TRUE
);
1101 if (!rn2(50)) adjattrib(rn2(2) ? A_INT
: A_WIS
, -rno(2), FALSE
, TRUE
);
1104 forget(1 + rn2(5), FALSE
);
1108 } else pline("There is a set of iron bars in the way!");
1112 else if (In_sokoban(&u
.uz
)) {
1113 if (mode
== DO_MOVE
)
1114 pline_The("Sokoban bars resist your ability.");
1117 } else if (Passes_walls
&& may_passwall(x
,y
)) {
1119 } else if (Race_if(PM_HUMANOID_DRYAD
) && tmpr
->typ
== TREE
) {
1120 ; /* dryad can walk thru trees --Amy */
1121 } else if (uarmg
&& uarmg
->oartifact
== ART_GREEN_THUMB
&& tmpr
->typ
== TREE
) {
1123 } else if (uarmf
&& uarmf
->oartifact
== ART_EVERYTHING_IS_GREEN
&& tmpr
->typ
== TREE
) {
1124 ; /* special effect of that artifact --Amy */
1125 } else if (uarmf
&& uarmf
->oartifact
== ART_SAFARI_ROCKZ
&& tmpr
->typ
== TREE
) {
1126 ; /* special effect of that artifact --Amy */
1127 } else if (uwep
&& uwep
->oartifact
== ART_GIFT_TO_NATURE
&& tmpr
->typ
== TREE
) {
1128 ; /* special effect of that artifact --Amy */
1130 } else if (tmpr
->typ
== WOODENTABLE
) {
1132 if ( (near_capacity() > UNENCUMBERED
) && !Passes_walls
) {
1133 if (mode
!= DO_MOVE
) return FALSE
;
1134 if (mode
== DO_MOVE
) {
1135 pline("Climbing the table does not work while you're burdened.");
1140 } else if (tmpr
->typ
== MOUNTAIN
) {
1141 if (mode
!= DO_MOVE
) return FALSE
;
1142 if (mode
== DO_MOVE
&& !(uwep
&& uwep
->oartifact
== ART_UNDERIRDIC_
) && !(uwep
&& uwep
->oartifact
== ART_NOW_GO_AND_CLIMB
) && !Passes_walls
&& !(powerfulimplants() && uimplant
&& uimplant
&& uimplant
->oartifact
== ART_SIGNIFICANT_RNG_JITTER
)) {
1143 int climbingchance
= 100;
1144 if (uamul
&& uamul
->otyp
== AMULET_OF_CLIMBING
) climbingchance
= ((levl
[u
.ux
][u
.uy
].typ
== MOUNTAIN
) ? 3 : 10);
1145 if (ublindf
&& ublindf
->otyp
== CLIMBING_SET
) climbingchance
= ((levl
[u
.ux
][u
.uy
].typ
== MOUNTAIN
) ? 3 : 10);
1146 if (uwep
&& uwep
->oartifact
== ART_KEY_OF_EREBOR
) climbingchance
= ((levl
[u
.ux
][u
.uy
].typ
== MOUNTAIN
) ? 3 : 10);
1147 if (uarm
&& uarm
->oartifact
== ART_GO_TO_THE_HIGH_RANGE
) climbingchance
= ((levl
[u
.ux
][u
.uy
].typ
== MOUNTAIN
) ? 3 : 10);
1148 if (uwep
&& uwep
->otyp
== CLIMBING_STICK
) climbingchance
= ((levl
[u
.ux
][u
.uy
].typ
== MOUNTAIN
) ? 3 : 10);
1149 if (uarmf
&& itemhasappearance(uarmf
, APP_CLIMBING_BOOTS
)) climbingchance
= ((levl
[u
.ux
][u
.uy
].typ
== MOUNTAIN
) ? 3 : 10);
1151 if (!(u
.usteed
) && rn2(climbingchance
)) {
1152 TimerunBug
+= 1; /* ugly hack --Amy */
1153 Norep("You try to scale the mountain. This may take many attempts to succeed.");
1154 /* Note that it is not a bug that you cannot easily walk over the next mountain tile
1155 * even if you're already on one, since they're considered to have different heights :D --Amy
1156 * however, with climbing gear it will indeed help */
1161 You("successfully climb the mountain.");
1162 if (flags
.moreforced
&& !MessagesSuppressed
) display_nhwindow(WIN_MESSAGE
, TRUE
); /* --More-- */
1166 } else if (tmpr
->typ
== FARMLAND
) {
1167 if (mode
!= DO_MOVE
&& !Levitation
&& !Flying
&& !(uarmf
&& uarmf
->oartifact
== ART_PURPLE_JUNGLE
) && !(uarmf
&& uarmf
->oartifact
== ART_UTE_S_GREENCHANGE
) && !(ublindf
&& ublindf
->oartifact
== ART_FREEBOUND
) && !(uarm
&& uarm
->oartifact
== ART_TILLING_FIELDS
) && !(uwep
&& uwep
->oartifact
== ART_GARY_S_RIVALRY
) && !(uwep
&& uwep
->oartifact
== ART_REAL_WALKING
) && !(u
.usteed
&& u
.usteed
->data
->mlet
== S_QUADRUPED
) && !(Upolyd
&& youmonst
.data
->mlet
== S_QUADRUPED
)) return FALSE
;
1169 if (mode
== DO_MOVE
&& !Levitation
&& !Flying
&& !(uarmf
&& uarmf
->oartifact
== ART_PURPLE_JUNGLE
) && !(uarmf
&& uarmf
->oartifact
== ART_UTE_S_GREENCHANGE
) && !(ublindf
&& ublindf
->oartifact
== ART_FREEBOUND
) && !(uarm
&& uarm
->oartifact
== ART_TILLING_FIELDS
) && !(uwep
&& uwep
->oartifact
== ART_UNDERIRDIC_
) && !(uwep
&& uwep
->oartifact
== ART_GARY_S_RIVALRY
) && !(uwep
&& uwep
->oartifact
== ART_REAL_WALKING
) && !(u
.usteed
&& u
.usteed
->data
->mlet
== S_QUADRUPED
) && !(Upolyd
&& youmonst
.data
->mlet
== S_QUADRUPED
) && !(powerfulimplants() && uimplant
&& uimplant
&& uimplant
->oartifact
== ART_SIGNIFICANT_RNG_JITTER
) ) {
1171 if (WallsAreHyperBlue
) {
1172 You("crash into a farmland! Ouch!");
1174 losehp(rnd(10), "walking into a farmland", KILLED_BY
);
1175 if (!rn2(Role_if(PM_COURIER
) ? 1000 : uarmh
? 50 : 10)) {
1177 adjattrib(rn2(2) ? A_INT
: A_WIS
, -rno(3), FALSE
, TRUE
);
1178 if (!rn2(50)) adjattrib(rn2(2) ? A_INT
: A_WIS
, -rno(2), FALSE
, TRUE
);
1181 forget(1 + rn2(5), FALSE
);
1185 You("cannot cross the farmland!");
1186 if (FunnyHallu
) pline("Nature preservation and all that.");
1187 /* Even passwall does not help here, this is intentional. --Amy */
1193 } else if (tmpr
->typ
== TUNNELWALL
) {
1194 if (mode
!= DO_MOVE
&& !Passes_walls
&& (Flying
|| Levitation
)) return FALSE
;
1195 if (mode
== DO_MOVE
&& !Passes_walls
&& (Flying
|| Levitation
)) {
1197 if (WallsAreHyperBlue
) {
1198 You("crash into a tunnel! Ouch!");
1200 losehp(rnd(10), "walking into a tunnel", KILLED_BY
);
1201 if (!rn2(Role_if(PM_COURIER
) ? 1000 : uarmh
? 50 : 10)) {
1203 adjattrib(rn2(2) ? A_INT
: A_WIS
, -rno(3), FALSE
, TRUE
);
1204 if (!rn2(50)) adjattrib(rn2(2) ? A_INT
: A_WIS
, -rno(2), FALSE
, TRUE
);
1207 forget(1 + rn2(5), FALSE
);
1211 if (Levitation
) pline("While levitating, you cannot enter the tunnel.");
1212 else pline("While flying, you cannot enter the tunnel.");
1219 } else if (tmpr
->typ
== GRAVEWALL
) {
1220 /* Once again, passwall intentionally does not help --Amy */
1222 if (u
.walscholarpass
) goto walscholardone
; /* can pass through */
1224 if (mode
!= DO_MOVE
) return FALSE
;
1226 if (Role_if(PM_WALSCHOLAR
) && (yn("You can move into the grave wall, which will require you to use some nutrition.") == 'y') ) { /* so that you don't get suck having to trash your alignment --Amy */
1228 goto walscholardone
;
1231 if (Role_if(PM_WALSCHOLAR
) && (yn("Do you really want to dig into the grave wall? Doing so would be sinful for a Walscholar.") != 'y') ) return FALSE
;
1233 if (rn2(5) && !(uwep
&& uwep
->oartifact
== ART_CERULEAN_SMASH
) ) {
1234 Norep("You dig into the grave wall.");
1235 TimerunBug
+= 1; /* ugly hack --Amy */
1238 You("dig out the grave wall.");
1239 if (flags
.moreforced
&& !MessagesSuppressed
) display_nhwindow(WIN_MESSAGE
, TRUE
); /* --More-- */
1240 u
.cnd_gravewallamount
++;
1242 if (Role_if(PM_WALSCHOLAR
)) {
1243 You_feel("like a miserably hussy.");
1244 if (FunnyHallu
) pline("Maybe you should buy a bottle of drum stint reluctance perfume.");
1245 increasesincounter(1);
1251 blockorunblock_point(ux
+dx
,uy
+dy
);
1252 newsym(ux
+dx
,uy
+dy
);
1253 if (FemtrapActiveJana
&& !rn2(2)) {
1255 pline("There was a woman hidden underneath the wall!");
1256 (void) makemon(specialtensmon(111), ux
+dx
, uy
+dy
, MM_ANGRY
|MM_ADJACENTOK
|MM_FRENZIED
);
1259 if (isstunfish
) nomul(-(rnz(30)), "paralyzed by Jana's cursed called", FALSE
);
1260 else nomul(-(rn1(15, 15)), "paralyzed by Jana's cursed called", FALSE
);
1261 pline("Jana is laughing at you because there was a cursed called hidden underneath the wall.");
1263 } else if (!rn2(20) && isok(ux
+dx
, uy
+dy
)) {
1264 maketrap(ux
+dx
, uy
+dy
, rndtrap(), 100, TRUE
);
1265 } else if (!rn2(20) && isok(ux
+dx
, uy
+dy
)) {
1266 pline("There was a monster hidden underneath the wall!");
1267 makemon((struct permonst
*)0, ux
+dx
, uy
+dy
, MM_ADJACENTOK
);
1271 if (Role_if(PM_HUSSY
)) {
1272 You("feel like a proper hussy.");
1275 pline("There was some gold hidden in the grave wall!");
1278 if (!rn2(1000) && isok(ux
+dx
, uy
+dy
)) {
1279 (void) mksobj_at(DIAMOND
, ux
+dx
, uy
+dy
, TRUE
, TRUE
, FALSE
);
1280 pline("Wow, this was one of the special grave walls where Hans Walt had hidden a diamond!");
1284 if (!Role_if(PM_WALSCHOLAR
)) {
1285 more_experienced(Role_if(PM_HUSSY
) ? 50 : 5, 0);
1294 } else if (tmpr
->typ
== WATERTUNNEL
) {
1295 if (mode
!= DO_MOVE
) return FALSE
;
1297 if ( ( ( (tunnels(youmonst
.data
) && !needspick(youmonst
.data
)) || (uarmf
&& uarmf
->oartifact
== ART_STONEWALL_CHECKERBOARD_DIS
) || (Race_if(PM_SCURRIER
) && !Upolyd
) || u
.geolysis
) ) && flags
.eatingwalls
&& (Flying
|| Levitation
) ) {
1298 /* can eat the stupid things */
1299 if (mode
== DO_MOVE
&& still_chewing(x
,y
)) return FALSE
;
1302 /* if you just ate it, you shouldn't crash into a no-longer-existing rock part above the tunnel */
1303 if (mode
== DO_MOVE
&& !Passes_walls
&& (Flying
|| Levitation
|| Wwalking
) && (levl
[x
][y
].typ
== WATERTUNNEL
) ) {
1305 if (WallsAreHyperBlue
) {
1306 You("crash into a water tunnel! Ouch!");
1308 losehp(rnd(10), "walking into a water tunnel", KILLED_BY
);
1309 if (!rn2(Role_if(PM_COURIER
) ? 1000 : uarmh
? 50 : 10)) {
1311 adjattrib(rn2(2) ? A_INT
: A_WIS
, -rno(3), FALSE
, TRUE
);
1312 if (!rn2(50)) adjattrib(rn2(2) ? A_INT
: A_WIS
, -rno(2), FALSE
, TRUE
);
1315 forget(1 + rn2(5), FALSE
);
1319 if (Levitation
) pline("While levitating, you cannot enter the water tunnel.");
1320 else if (Flying
) pline("While flying, you cannot enter the water tunnel.");
1321 else if (Wwalking
) You("don't seem to fit into the water tunnel.");
1322 else pline("Something prevents you from entering the water tunnel.");
1329 } else if ( ( ( (tunnels(youmonst
.data
) && !needspick(youmonst
.data
)) || (uarmf
&& uarmf
->oartifact
== ART_STONEWALL_CHECKERBOARD_DIS
) || (Race_if(PM_SCURRIER
) && !Upolyd
) || u
.geolysis
) ) && flags
.eatingwalls
) {
1331 if (mode
== DO_MOVE
&& still_chewing(x
,y
)) return FALSE
;
1333 /* autodig: note by Amy, this needs to interact with all nasty traps that would fire when you apply something.
1334 * For simplicity of coding, I decided to make autodig do nothing if you have such a trap active :P */
1335 } else if (flags
.autodig
&& !(u
.powerfailure
|| (uarmf
&& uarmf
->oartifact
== ART_BRITTA_S_MURDER_STORY
) || CurseAsYouUse
|| InterruptEffect
|| u
.uprops
[INTERRUPT_EFFECT
].extrinsic
|| have_interruptionstone() || (isselfhybrid
&& (moves
% 3 == 0 && moves
% 11 != 0) ) ) && !(WallsAreHyperBlue
) && !flags
.run
&& !flags
.nopick
&&
1336 uwep
&& is_pick(uwep
)) {
1337 /* MRKR: Automatic digging when wielding the appropriate tool */
1338 if (mode
== DO_MOVE
) {
1339 if (!touch_artifact(uwep
, &youmonst
)) return FALSE
;
1340 (void) use_pick_axe2(uwep
);
1344 if (mode
== DO_MOVE
) {
1345 if (Is_stronghold(&u
.uz
) && is_db_wall(x
,y
))
1346 pline_The("drawbridge is up!");
1347 if (Passes_walls
&& !may_passwall(x
,y
) && In_sokoban(&u
.uz
))
1348 pline_The("Sokoban walls resist your ability.");
1350 if (!(Is_stronghold(&u
.uz
) && is_db_wall(x
,y
)) && !(Passes_walls
&& !may_passwall(x
,y
) && In_sokoban(&u
.uz
))) {
1351 if (tmpr
->typ
== TREE
&& mode
== DO_MOVE
) {
1353 if (WallsAreHyperBlue
) {
1354 You("crash into a tree! Ouch!");
1356 losehp(rnd(10), "walking into a tree", KILLED_BY
);
1357 if (!rn2(Role_if(PM_COURIER
) ? 1000 : uarmh
? 50 : 10)) {
1359 adjattrib(rn2(2) ? A_INT
: A_WIS
, -rno(3), FALSE
, TRUE
);
1360 if (!rn2(50)) adjattrib(rn2(2) ? A_INT
: A_WIS
, -rno(2), FALSE
, TRUE
);
1363 forget(1 + rn2(5), FALSE
);
1366 } else pline("There is a tree in the way!");
1368 } else if (mode
== DO_MOVE
) {
1370 if (WallsAreNoFun
) {
1371 nofunwalltrigger(x
, y
);
1372 TimerunBug
+= 1; /* ugly hack --Amy */
1375 if (WallsAreHyperBlue
) {
1376 You("crash into a wall! Ouch!");
1378 losehp(rnd(10), "walking into a wall", KILLED_BY
);
1379 if (!rn2(Role_if(PM_COURIER
) ? 1000 : uarmh
? 50 : 10)) {
1381 adjattrib(rn2(2) ? A_INT
: A_WIS
, -rno(3), FALSE
, TRUE
);
1382 if (!rn2(50)) adjattrib(rn2(2) ? A_INT
: A_WIS
, -rno(2), FALSE
, TRUE
);
1385 forget(1 + rn2(5), FALSE
);
1388 } else pline("There is a wall in the way!");
1394 } else if (IS_DOOR(tmpr
->typ
)) {
1395 if (closed_door(x
,y
)) {
1397 if (Blind
&& mode
== DO_MOVE
) feel_location(x
,y
);
1398 /* ALI - artifact doors */
1399 if (artifact_door(x
, y
)) {
1400 if (mode
== DO_MOVE
) {
1401 if (amorphous(youmonst
.data
))
1402 You("try to ooze under the door, but the gap is too small.");
1403 else if ((tunnels(youmonst
.data
) && !needspick(youmonst
.data
)) || (uarmf
&& uarmf
->oartifact
== ART_STONEWALL_CHECKERBOARD_DIS
) || (Race_if(PM_SCURRIER
) && !Upolyd
))
1404 You("hurt your teeth on the re-enforced door.");
1405 else if (x
== u
.ux
|| y
== u
.uy
) {
1406 if (Blind
|| Stunned
|| Numbed
|| ACURR(A_DEX
) < 10 || Fumbling
) { pline("Ouch! You bump into a heavy door.");
1407 exercise(A_DEX
, FALSE
);
1408 } else pline("That door is closed.");
1415 else if (can_ooze(&youmonst
) || (uwep
&& uwep
->oartifact
== ART_DOORS_ARE_NO_OBSTACLES
)) {
1416 if (mode
== DO_MOVE
) You("ooze under the door.");
1417 } else if (((tunnels(youmonst
.data
) && !needspick(youmonst
.data
)) || (uarmf
&& uarmf
->oartifact
== ART_STONEWALL_CHECKERBOARD_DIS
) || (Race_if(PM_SCURRIER
) && !Upolyd
)) && flags
.eatingdoors
) {
1419 if (mode
== DO_MOVE
&& still_chewing(x
,y
)) return FALSE
;
1421 if (mode
== DO_MOVE
) {
1422 if (amorphous(youmonst
.data
))
1423 You("try to ooze under the door, but can't squeeze your possessions through.");
1424 else if (iflags
.autoopen
&& !Confusion
&& !Stunned
&& !Fumbling
&& levl
[ux
][uy
].seenv
&& !(RightMouseButtonDoesNotGo
|| u
.totter
|| (uarms
&& uarms
->oartifact
== ART_DOLORES__VIRGINITY
) || (uarms
&& uarms
->oartifact
== ART_BLUE_SHIRT_OF_DEATH
) || u
.uprops
[TOTTER_EFFECT
].extrinsic
|| TotterTrapEffect
|| have_directionswapstone() || autismweaponcheck(ART_HOW_IS_THE_CAR_ROWED
) || (uimplant
&& uimplant
->oartifact
== ART_CORTEX_COPROCESSOR
) || ClockwiseSpinBug
|| u
.uprops
[CLOCKWISE_SPIN_BUG
].extrinsic
|| have_clockwisestone() || CounterclockwiseSpin
|| u
.uprops
[COUNTERCLOCKWISE_SPIN_BUG
].extrinsic
|| have_counterclockwisestone() || InterfaceScrewed
|| u
.uprops
[INTERFACE_SCREW
].extrinsic
|| have_interfacescrewstone() || QuasarVision
|| u
.uprops
[QUASAR_BUG
].extrinsic
|| have_quasarstone() || GrayoutBug
|| u
.uprops
[GRAYOUT_BUG
].extrinsic
|| have_grayoutstone() || (uarmc
&& uarmc
->oartifact
== ART_DOEDOEDOEDOEDOEDOEDOE_TEST
) || autismweaponcheck(ART_PWNHAMMER
) || GrayCenterBug
|| u
.uprops
[GRAY_CENTER_BUG
].extrinsic
|| have_graycenterstone() || Quaversal
|| u
.uprops
[QUAVERSAL
].extrinsic
|| have_quaversalstone() || (uimplant
&& uimplant
->oartifact
== ART_ND_D___N_NDMNN_ND___NDMN_N
) || autismweaponcheck(ART_OMGHAXERETH
) || (SpellColorSilver
&& !u
.seesilverspell
) || CheckerboardBug
|| u
.uprops
[CHECKERBOARD_BUG
].extrinsic
|| have_checkerboardstone() || autismweaponcheck(ART_SAY__CHESS_
) || WallsAreHyperBlue
) ) {
1425 door_opened
= flags
.move
= doopen_indir(x
, y
);
1428 else if (x
== ux
|| y
== uy
) {
1430 if (WallsAreHyperBlue
) {
1431 You("crash into a door! Ouch!");
1433 losehp(rnd(10), "walking into a door", KILLED_BY
);
1434 if (!rn2(Role_if(PM_COURIER
) ? 1000 : uarmh
? 50 : 10)) {
1436 adjattrib(rn2(2) ? A_INT
: A_WIS
, -rno(3), FALSE
, TRUE
);
1437 if (!rn2(50)) adjattrib(rn2(2) ? A_INT
: A_WIS
, -rno(2), FALSE
, TRUE
);
1440 forget(1 + rn2(5), FALSE
);
1444 /* It is not a mistake that the next message will still be displayed,
1445 * since it contains the check for dexterity abuse and hyperbluewalls should not disable that :D --Amy */
1447 if (Blind
|| Stunned
|| Numbed
|| ACURR(A_DEX
) < 10 || Fumbling
) {
1449 You_cant("lead %s through that closed door.",
1450 y_monnam(u
.usteed
));
1453 pline("Ouch! You bump into a door.");
1454 exercise(A_DEX
, FALSE
);
1456 } else pline("That door is closed.");
1460 } else if (mode
== TEST_TRAV
) goto testdiag
;
1461 if (mode
== DO_MOVE
) {
1463 if (WallsAreHyperBlue
) {
1464 You("crash into a door! Ouch!");
1466 losehp(rnd(10), "walking into a door", KILLED_BY
);
1467 if (!rn2(Role_if(PM_COURIER
) ? 1000 : uarmh
? 50 : 10)) {
1469 adjattrib(rn2(2) ? A_INT
: A_WIS
, -rno(3), FALSE
, TRUE
);
1470 if (!rn2(50)) adjattrib(rn2(2) ? A_INT
: A_WIS
, -rno(2), FALSE
, TRUE
);
1473 forget(1 + rn2(5), FALSE
);
1478 /* only print "there is a door in the way" if autoopen didn't try to open it --Amy */
1480 else if (dx
&& dy
&& !opentry
&& !Passes_walls
&& ((tmpr
->doormask
& ~D_BROKEN
)
1481 #ifdef REINCARNATION
1482 || Is_rogue_level(&u
.uz
)
1484 || block_door(x
,y
))) {
1486 pline("There is a door in the way!");
1494 if ((dx
&& dy
&& !Passes_walls
1495 && ((tmpr
->doormask
& ~D_BROKEN
)
1496 #ifdef REINCARNATION
1497 || Is_rogue_level(&u
.uz
)
1499 || block_door(x
,y
))) && !can_ooze(&youmonst
) && !(uwep
&& uwep
->oartifact
== ART_DOORS_ARE_NO_OBSTACLES
)) {
1500 /* Diagonal moves into a door are not allowed. */
1501 if (Blind
&& mode
== DO_MOVE
)
1503 if (mode
== DO_MOVE
) pline("You cannot diagonally move through a door!");
1509 && bad_rock(&youmonst
,ux
,y
) && bad_rock(&youmonst
,x
,uy
)) {
1510 /* Move at a diagonal. */
1511 if (In_sokoban(&u
.uz
)) {
1512 if (mode
== DO_MOVE
)
1513 You("cannot pass that way.");
1516 if ( (bigmonst(youmonst
.data
) && !Race_if(PM_TRANSFORMER
) ) || FemtrapActivePatricia
|| (!Upolyd
&& Race_if(PM_HUMANOID_CENTAUR
) ) || (!Upolyd
&& Race_if(PM_URGOTH
) ) || (!Upolyd
&& Race_if(PM_ETHEREALOID
) ) || (!Upolyd
&& Race_if(PM_INCORPOREALOID
) ) || (!Upolyd
&& Race_if(PM_PLAYER_CERBERUS
) ) || (!Upolyd
&& Race_if(PM_CHIROPTERAN
) ) || (!Upolyd
&& Race_if(PM_THUNDERLORD
) ) || (uarmf
&& uarmf
->oartifact
== ART_ANTJE_S_POWERSTRIDE
) || (uarms
&& uarms
->oartifact
== ART_FETTIS_SLOT
) || (!Upolyd
&& Race_if(PM_PLAYER_JABBERWOCK
) ) ) {
1517 if (mode
== DO_MOVE
)
1518 Your("body is too large to fit through.");
1521 if (invent
&& ((inv_weight() + weight_cap()) > max_carr_cap() )) {
1522 if (mode
== DO_MOVE
)
1524 You("are carrying too much to get through.");
1528 /* Pick travel path that does not require crossing a trap.
1529 * Avoid water and lava using the usual running rules.
1530 * (but not u.ux/u.uy because findtravelpath walks toward u.ux/u.uy) */
1531 if (flags
.run
== 8 && mode
!= DO_MOVE
&& (x
!= u
.ux
|| y
!= u
.uy
)) {
1532 struct trap
* t
= t_at(x
, y
);
1534 if ((t
&& t
->tseen
) ||
1535 (!Levitation
&& !Flying
&&
1536 !is_clinger(youmonst
.data
) &&
1537 (is_waterypool(x
, y
) || is_watertunnel(x
,y
) || is_moorland(x
,y
) || is_styxriver(x
,y
) || is_shiftingsand(x
,y
) || is_urinelake(x
,y
) || is_lava(x
, y
)) && levl
[x
][y
].seenv
))
1541 ust
= &levl
[ux
][uy
];
1543 /* Now see if other things block our way . . */
1544 if (dx
&& dy
&& !Passes_walls
&& !can_ooze(&youmonst
) && !(uwep
&& uwep
->oartifact
== ART_DOORS_ARE_NO_OBSTACLES
)
1545 && (IS_DOOR(ust
->typ
) && ((ust
->doormask
& ~D_BROKEN
)
1546 #ifdef REINCARNATION
1547 || Is_rogue_level(&u
.uz
)
1549 || block_entry(x
, y
))
1551 /* Can't move at a diagonal out of a doorway with door. */
1552 if (mode
== DO_MOVE
) pline("You cannot diagonally move out of a door!");
1556 if (sobj_at(BOULDER
,x
,y
) && (In_sokoban(&u
.uz
) || !Passes_walls
)) {
1557 if (!(Blind
|| Hallucination
) && (flags
.run
>= 1) && mode
!= TEST_TRAV
)
1559 if (mode
== DO_MOVE
) {
1560 /* tunneling monsters will chew before pushing */
1561 if ( (( (tunnels(youmonst
.data
) && !needspick(youmonst
.data
)) || (uarmf
&& uarmf
->oartifact
== ART_STONEWALL_CHECKERBOARD_DIS
) || (Race_if(PM_SCURRIER
) && !Upolyd
) || u
.geolysis
) &&
1562 !In_sokoban(&u
.uz
)) && flags
.eatingboulders
) {
1563 if (still_chewing(x
,y
)) return FALSE
;
1565 if (moverock() < 0) return FALSE
;
1566 } else if (mode
== TEST_TRAV
) {
1569 /* don't pick two boulders in a row, unless there's a way thru */
1570 if (sobj_at(BOULDER
,ux
,uy
) && !In_sokoban(&u
.uz
)) {
1571 if (!Passes_walls
&&
1572 !(tunnels(youmonst
.data
) && !needspick(youmonst
.data
)) &&
1573 !(Race_if(PM_SCURRIER
) && !Upolyd
) &&
1574 !(uarmf
&& uarmf
->oartifact
== ART_STONEWALL_CHECKERBOARD_DIS
) &&
1575 !carrying(PICK_AXE
) && !carrying(CONGLOMERATE_PICK
) && !carrying(UNWIELDY_PICK
) && !carrying(CONUNDRUM_PICK
) && !carrying(SHOVEL
) && !carrying(MYSTERY_PICK
) &&
1576 !carrying(BRONZE_PICK
) && !carrying(NANO_PICK
) && !carrying(BRICK_PICK
) && !carrying(MYSTERIOUS_PICK
) && !carrying(DWARVISH_MATTOCK
) &&
1577 !((obj
= carrying(WAN_DIGGING
)) &&
1578 !objects
[obj
->otyp
].oc_name_known
))
1582 /* assume you'll be able to push it when you get there... */
1585 /* OK, it is a legal place to move. */
1590 * Find a path from the destination (u.tx,u.ty) back to (u.ux,u.uy).
1591 * A shortest path is returned. If guess is TRUE, consider various
1592 * inaccessible locations as valid intermediate path points.
1593 * Returns TRUE if a path was found.
1596 findtravelpath(guess
)
1599 /* if travel to adjacent, reachable location, use normal movement rules */
1600 if (!guess
&& iflags
.travel1
&& distmin(u
.ux
, u
.uy
, u
.tx
, u
.ty
) == 1 && !(u
.ux
!= u
.tx
&& u
.uy
!= u
.ty
&& (BishopGridbug
|| u
.uprops
[BISHOP_GRIDBUG
].extrinsic
|| have_bishopstone() || (uarmg
&& uarmg
->oartifact
== ART_LINE_CAN_PLAY_BY_YOURSELF
) || autismweaponcheck(ART_KILLER_PIANO
) || isgridbug(youmonst
.data
) || (Race_if(PM_WEAPON_BUG
) && !Upolyd
)) ) ) {
1602 if (test_move(u
.ux
, u
.uy
, u
.tx
-u
.ux
, u
.ty
-u
.uy
, TEST_MOVE
)) {
1606 iflags
.travelcc
.x
= iflags
.travelcc
.y
= -1;
1611 if (u
.tx
!= u
.ux
|| u
.ty
!= u
.uy
) {
1612 xchar travel
[COLNO
][ROWNO
];
1613 xchar travelstepx
[2][COLNO
*ROWNO
];
1614 xchar travelstepy
[2][COLNO
*ROWNO
];
1615 xchar tx
, ty
, ux
, uy
;
1616 int n
= 1; /* max offset in travelsteps */
1617 int set
= 0; /* two sets current and previous */
1618 int radius
= 1; /* search radius */
1621 /* If guessing, first find an "obvious" goal location. The obvious
1622 * goal is the position the player knows of, or might figure out
1623 * (couldsee) that is closest to the target on a straight path.
1626 tx
= u
.ux
; ty
= u
.uy
; ux
= u
.tx
; uy
= u
.ty
;
1628 tx
= u
.tx
; ty
= u
.ty
; ux
= u
.ux
; uy
= u
.uy
;
1632 (void) memset((void *)travel
, 0, sizeof(travel
));
1633 travelstepx
[0][0] = tx
;
1634 travelstepy
[0][0] = ty
;
1639 for (i
= 0; i
< n
; i
++) {
1641 int x
= travelstepx
[set
][i
];
1642 int y
= travelstepy
[set
][i
];
1643 static int ordered
[] = { 0, 2, 4, 6, 1, 3, 5, 7 };
1644 /* no diagonal movement for grid bugs */
1645 int dirmax
= (BishopGridbug
|| u
.uprops
[BISHOP_GRIDBUG
].extrinsic
|| have_bishopstone() || (uarmg
&& uarmg
->oartifact
== ART_LINE_CAN_PLAY_BY_YOURSELF
) || autismweaponcheck(ART_KILLER_PIANO
) || isgridbug(youmonst
.data
) || (Race_if(PM_WEAPON_BUG
) && !Upolyd
))? 4 : 8;
1647 for (dir
= 0; dir
< dirmax
; ++dir
) {
1648 int nx
= x
+xdir
[ordered
[dir
]];
1649 int ny
= y
+ydir
[ordered
[dir
]];
1651 if (!isok(nx
, ny
)) continue;
1652 if ((!Passes_walls
&& !can_ooze(&youmonst
) && !(uwep
&& uwep
->oartifact
== ART_DOORS_ARE_NO_OBSTACLES
) &&
1653 closed_door(x
, y
)) || sobj_at(BOULDER
, x
, y
)) {
1654 /* closed doors and boulders usually
1655 * cause a delay, so prefer another path */
1656 if (travel
[x
][y
] > radius
-3) {
1657 travelstepx
[1-set
][nn
] = x
;
1658 travelstepy
[1-set
][nn
] = y
;
1659 /* don't change travel matrix! */
1664 if (test_move(x
, y
, nx
-x
, ny
-y
, TEST_TRAV
) &&
1665 (levl
[nx
][ny
].seenv
|| (!Blind
&& couldsee(nx
, ny
)))) {
1666 if (nx
== ux
&& ny
== uy
) {
1670 if (x
== u
.tx
&& y
== u
.ty
) {
1672 /* reset run so domove run checks work */
1674 iflags
.travelcc
.x
= iflags
.travelcc
.y
= -1;
1678 } else if (!travel
[nx
][ny
]) {
1679 travelstepx
[1-set
][nn
] = nx
;
1680 travelstepy
[1-set
][nn
] = ny
;
1681 travel
[nx
][ny
] = radius
;
1693 /* if guessing, find best location in travel matrix and go there */
1695 int px
= tx
, py
= ty
; /* pick location */
1696 int dist
, nxtdist
, d2
, nd2
;
1698 dist
= distmin(ux
, uy
, tx
, ty
);
1699 d2
= dist2(ux
, uy
, tx
, ty
);
1700 for (tx
= 1; tx
< COLNO
; ++tx
)
1701 for (ty
= 0; ty
< ROWNO
; ++ty
)
1702 if (travel
[tx
][ty
]) {
1703 nxtdist
= distmin(ux
, uy
, tx
, ty
);
1704 if (nxtdist
== dist
&& couldsee(tx
, ty
)) {
1705 nd2
= dist2(ux
, uy
, tx
, ty
);
1707 /* prefer non-zigzag path */
1711 } else if (nxtdist
< dist
&& couldsee(tx
, ty
)) {
1714 d2
= dist2(ux
, uy
, tx
, ty
);
1718 if (px
== u
.ux
&& py
== u
.uy
) {
1719 /* no guesses, just go in the general direction */
1720 u
.dx
= sgn(u
.tx
- u
.ux
);
1721 u
.dy
= sgn(u
.ty
- u
.uy
);
1722 if (test_move(u
.ux
, u
.uy
, u
.dx
, u
.dy
, TEST_MOVE
))
1746 ask_about_trap(int x
, int y
)
1749 struct trap
*traphere
= t_at(x
, y
);
1751 if (ParanoiaBugEffect
|| u
.uprops
[PARANOIA_BUG
].extrinsic
|| have_paranoiastone()) return FALSE
;
1753 if (KnowledgeBug
|| u
.uprops
[KNOWLEDGE_BUG
].extrinsic
|| have_trapknowledgestone()) return FALSE
;
1755 /* hallu means you cannot tell traps apart, and we used to make it so that you never get any confirmation;
1756 * it's much more fair if you always get one though --Amy
1757 * what we definitely cannot do is make it give the confirmation depending on what trap it is, because that would
1758 * be leaking info */
1759 if (Hallucination
&& (traphere
&& traphere
->tseen
) && !(Confusion
&& !Conf_resist
) && !(Stunned
&& !Stun_resist
&& !(uarmf
&& itemhasappearance(uarmf
, APP_FLUFFY_SANDALS
)) )) return TRUE
;
1761 if (/* is_pool(x, y) || is_lava(x, y) || */ (traphere
&& traphere
->tseen
) && !(Confusion
&& !Conf_resist
) && !(Stunned
&& !Stun_resist
&& !(uarmf
&& itemhasappearance(uarmf
, APP_FLUFFY_SANDALS
)) ) && !Hallucination
) {
1763 /* who the heck included this? Maybe the player doesn't really want to use the portal at all! --Amy */
1764 /*if (traphere->ttyp == MAGIC_PORTAL) {
1768 if (SpellColorBrown
&& traphere
->ttyp
== SHIT_TRAP
) return FALSE
;
1770 if (traphere
->ttyp
== S_PRESSING_TRAP
) {
1773 if (traphere
->ttyp
== WRONG_STAIRS
) {
1777 if (Role_if(PM_TOPMODEL
) && Is_qlocate(&u
.uz
)) /* traps on this level do wind damage */
1779 if (Role_if(PM_FAILED_EXISTENCE
) && Is_qlocate(&u
.uz
))
1782 if (Levitation
|| Flying
) {
1783 if (!In_sokoban(&u
.uz
) && traphere
->ttyp
== PIT
) {
1786 if (!In_sokoban(&u
.uz
) && traphere
->ttyp
== SPIKED_PIT
) {
1789 if (!In_sokoban(&u
.uz
) && traphere
->ttyp
== GIANT_CHASM
) {
1792 if (!In_sokoban(&u
.uz
) && traphere
->ttyp
== SHIT_PIT
) {
1795 if (!In_sokoban(&u
.uz
) && traphere
->ttyp
== MANA_PIT
) {
1798 if (!In_sokoban(&u
.uz
) && traphere
->ttyp
== ANOXIC_PIT
) {
1801 if (!In_sokoban(&u
.uz
) && traphere
->ttyp
== HYPOXIC_PIT
) {
1804 if (!In_sokoban(&u
.uz
) && traphere
->ttyp
== ACID_PIT
) {
1807 if (!In_sokoban(&u
.uz
) && traphere
->ttyp
== HOLE
) {
1810 if (!In_sokoban(&u
.uz
) && traphere
->ttyp
== SHAFT_TRAP
) {
1813 if (!In_sokoban(&u
.uz
) && traphere
->ttyp
== TRAPDOOR
) {
1816 if (traphere
->ttyp
== BEAR_TRAP
) {
1819 if (traphere
->ttyp
== ACID_POOL
) {
1822 if (traphere
->ttyp
== WATER_POOL
) {
1825 if (traphere
->ttyp
== SQKY_BOARD
) {
1828 /* used to ask for shit trap but that one has so many ways to trigger anyway... --Amy */
1836 ask_about_water(int x
, int y
)
1838 if (ParanoiaBugEffect
|| u
.uprops
[PARANOIA_BUG
].extrinsic
|| have_paranoiastone()) return FALSE
;
1840 if (is_pool(u
.ux
, u
.uy
)) return FALSE
;
1841 if (is_watertunnel(u
.ux
, u
.uy
)) return FALSE
;
1843 if (is_pool(x
, y
) && !Levitation
&& !Flying
&& !(Confusion
&& !Conf_resist
) && !(Stunned
&& !Stun_resist
&& !(uarmf
&& itemhasappearance(uarmf
, APP_FLUFFY_SANDALS
)) ) && levl
[x
][y
].seenv
) return TRUE
;
1845 if (is_pool(x
, y
) && !(Confusion
&& !Conf_resist
) && !(Stunned
&& !Stun_resist
&& !(uarmf
&& itemhasappearance(uarmf
, APP_FLUFFY_SANDALS
)) ) && levl
[x
][y
].seenv
&& Role_if(PM_TOPMODEL
) && Is_qlocate(&u
.uz
) ) return TRUE
;
1846 if (is_pool(x
, y
) && !(Confusion
&& !Conf_resist
) && !(Stunned
&& !Stun_resist
&& !(uarmf
&& itemhasappearance(uarmf
, APP_FLUFFY_SANDALS
)) ) && levl
[x
][y
].seenv
&& Role_if(PM_FAILED_EXISTENCE
) && Is_qlocate(&u
.uz
) ) return TRUE
;
1852 ask_about_lava(int x
, int y
)
1854 if (ParanoiaBugEffect
|| u
.uprops
[PARANOIA_BUG
].extrinsic
|| have_paranoiastone()) return FALSE
;
1856 if (is_lava(u
.ux
, u
.uy
)) return FALSE
;
1858 if (is_lava(x
, y
) && !Levitation
&& !Flying
&& !(Confusion
&& !Conf_resist
) && !(Stunned
&& !Stun_resist
&& !(uarmf
&& itemhasappearance(uarmf
, APP_FLUFFY_SANDALS
)) ) && levl
[x
][y
].seenv
) return TRUE
;
1863 ask_about_watertunnel(int x
, int y
)
1865 if (ParanoiaBugEffect
|| u
.uprops
[PARANOIA_BUG
].extrinsic
|| have_paranoiastone()) return FALSE
;
1867 if (is_watertunnel(u
.ux
, u
.uy
)) return FALSE
;
1868 if (is_pool(u
.ux
, u
.uy
)) return FALSE
;
1870 if (is_watertunnel(x
, y
) && !Levitation
&& !Flying
&& !(Confusion
&& !Conf_resist
) && !(Stunned
&& !Stun_resist
&& !(uarmf
&& itemhasappearance(uarmf
, APP_FLUFFY_SANDALS
)) ) && levl
[x
][y
].seenv
) return TRUE
;
1875 ask_about_crystalwater(int x
, int y
)
1877 if (ParanoiaBugEffect
|| u
.uprops
[PARANOIA_BUG
].extrinsic
|| have_paranoiastone()) return FALSE
;
1879 if (is_crystalwater(u
.ux
, u
.uy
)) return FALSE
;
1881 if (is_crystalwater(x
, y
) && (Levitation
|| Flying
) && !(Confusion
&& !Conf_resist
) && !(Stunned
&& !Stun_resist
&& !(uarmf
&& itemhasappearance(uarmf
, APP_FLUFFY_SANDALS
)) ) && levl
[x
][y
].seenv
) return TRUE
;
1886 ask_about_moorland(int x
, int y
)
1888 if (ParanoiaBugEffect
|| u
.uprops
[PARANOIA_BUG
].extrinsic
|| have_paranoiastone()) return FALSE
;
1890 if (is_moorland(u
.ux
, u
.uy
)) return FALSE
;
1892 if (is_moorland(x
, y
) && !Levitation
&& !Flying
&& !(Confusion
&& !Conf_resist
) && !(Stunned
&& !Stun_resist
&& !(uarmf
&& itemhasappearance(uarmf
, APP_FLUFFY_SANDALS
)) ) && levl
[x
][y
].seenv
) return TRUE
;
1897 ask_about_urinelake(int x
, int y
)
1899 if (ParanoiaBugEffect
|| u
.uprops
[PARANOIA_BUG
].extrinsic
|| have_paranoiastone()) return FALSE
;
1901 if (is_urinelake(u
.ux
, u
.uy
)) return FALSE
;
1903 if (is_urinelake(x
, y
) && !Levitation
&& !Flying
&& !(Confusion
&& !Conf_resist
) && !(Stunned
&& !Stun_resist
&& !(uarmf
&& itemhasappearance(uarmf
, APP_FLUFFY_SANDALS
)) ) && levl
[x
][y
].seenv
) return TRUE
;
1908 ask_about_shiftingsand(int x
, int y
)
1910 if (ParanoiaBugEffect
|| u
.uprops
[PARANOIA_BUG
].extrinsic
|| have_paranoiastone()) return FALSE
;
1912 if (is_shiftingsand(u
.ux
, u
.uy
)) return FALSE
;
1914 if (is_shiftingsand(x
, y
) && !Levitation
&& !Flying
&& !(Confusion
&& !Conf_resist
) && !(Stunned
&& !Stun_resist
&& !(uarmf
&& itemhasappearance(uarmf
, APP_FLUFFY_SANDALS
)) ) && levl
[x
][y
].seenv
) return TRUE
;
1919 ask_about_styxriver(int x
, int y
)
1921 if (ParanoiaBugEffect
|| u
.uprops
[PARANOIA_BUG
].extrinsic
|| have_paranoiastone()) return FALSE
;
1923 if (is_styxriver(u
.ux
, u
.uy
)) return FALSE
;
1925 if (is_styxriver(x
, y
) && !(Confusion
&& !Conf_resist
) && !(Stunned
&& !Stun_resist
&& !(uarmf
&& itemhasappearance(uarmf
, APP_FLUFFY_SANDALS
)) ) && levl
[x
][y
].seenv
) return TRUE
;
1930 ask_about_burningwagon(int x
, int y
)
1932 if (ParanoiaBugEffect
|| u
.uprops
[PARANOIA_BUG
].extrinsic
|| have_paranoiastone()) return FALSE
;
1934 if (is_burningwagon(u
.ux
, u
.uy
)) return FALSE
;
1936 if (is_burningwagon(x
, y
) && !(Confusion
&& !Conf_resist
) && !(Stunned
&& !Stun_resist
&& !(uarmf
&& itemhasappearance(uarmf
, APP_FLUFFY_SANDALS
)) ) && levl
[x
][y
].seenv
) return TRUE
;
1941 ask_about_nethermist(int x
, int y
)
1943 if (ParanoiaBugEffect
|| u
.uprops
[PARANOIA_BUG
].extrinsic
|| have_paranoiastone()) return FALSE
;
1945 if (is_nethermist(u
.ux
, u
.uy
)) return FALSE
;
1947 if (is_nethermist(x
, y
) && !(Confusion
&& !Conf_resist
) && !(Stunned
&& !Stun_resist
&& !(uarmf
&& itemhasappearance(uarmf
, APP_FLUFFY_SANDALS
)) ) && levl
[x
][y
].seenv
) return TRUE
;
1952 ask_about_stalactite(int x
, int y
)
1954 if (ParanoiaBugEffect
|| u
.uprops
[PARANOIA_BUG
].extrinsic
|| have_paranoiastone()) return FALSE
;
1956 if (is_stalactite(u
.ux
, u
.uy
)) return FALSE
;
1958 if (is_stalactite(x
, y
) && (Flying
|| Levitation
) && !(Confusion
&& !Conf_resist
) && !(Stunned
&& !Stun_resist
&& !(uarmf
&& itemhasappearance(uarmf
, APP_FLUFFY_SANDALS
)) ) && levl
[x
][y
].seenv
) return TRUE
;
1963 ask_about_raincloud(int x
, int y
)
1965 if (ParanoiaBugEffect
|| u
.uprops
[PARANOIA_BUG
].extrinsic
|| have_paranoiastone()) return FALSE
;
1967 if (is_raincloud(u
.ux
, u
.uy
)) return FALSE
;
1969 if (is_raincloud(x
, y
) && !(Confusion
&& !Conf_resist
) && !(Stunned
&& !Stun_resist
&& !(uarmf
&& itemhasappearance(uarmf
, APP_FLUFFY_SANDALS
)) ) && levl
[x
][y
].seenv
) return TRUE
;
1974 ask_about_bubble(int x
, int y
)
1976 if (ParanoiaBugEffect
|| u
.uprops
[PARANOIA_BUG
].extrinsic
|| have_paranoiastone()) return FALSE
;
1978 if (is_bubble(u
.ux
, u
.uy
)) return FALSE
;
1980 if (is_bubble(x
, y
) && !(Confusion
&& !Conf_resist
) && !(Stunned
&& !Stun_resist
&& !(uarmf
&& itemhasappearance(uarmf
, APP_FLUFFY_SANDALS
)) ) && levl
[x
][y
].seenv
) return TRUE
;
1987 register struct monst
*mtmp
;
1988 register struct rm
*tmpr
;
1991 struct trap
*traphere
= t_at(x
, y
);
1994 xchar chainx
, chainy
, ballx
, bally
; /* ball&chain new positions */
1995 int bc_control
; /* control for ball&chain */
1996 boolean cause_delay
= FALSE
; /* dragging ball will skip a move */
1997 const char *predicament
;
1998 boolean displacer
= FALSE
; /* defender attempts to displace you */
1999 boolean peacedisplacer
= FALSE
;
2000 boolean canexistonsquare
= TRUE
;
2002 u_wipe_engr(rnd(5));
2005 if (!findtravelpath(FALSE
))
2006 (void) findtravelpath(TRUE
);
2010 if(((wtcap
= near_capacity()) >= OVERLOADED
2011 || (wtcap
> SLT_ENCUMBER
&&
2012 (Upolyd
? (u
.mh
< 5 && u
.mh
!= u
.mhmax
)
2013 : (u
.uhp
< 10 && u
.uhp
!= u
.uhpmax
))))
2014 && !Is_airlevel(&u
.uz
)) {
2015 if(wtcap
< OVERLOADED
) {
2016 You("don't have enough stamina to move.");
2017 exercise(A_CON
, FALSE
);
2019 You("collapse under your load.");
2023 if (Race_if(PM_ELONA_SNAIL
) && !flags
.forcefight
&& uarmf
&& !PlayerInHighHeels
) {
2024 pline("In order to move, snails need to be bare-footed or wearing high heels!");
2031 u
.ux
= x
= u
.ustuck
->mx
;
2032 u
.uy
= y
= u
.ustuck
->my
;
2035 if (Is_airlevel(&u
.uz
) && !flags
.forcefight
&& rn2(2) && /* was rn2(4) - let's make it a bit easier --Amy */
2036 !Levitation
&& !Flying
) {
2039 You("tumble in place.");
2040 exercise(A_DEX
, FALSE
);
2043 You_cant("control your movements very well."); break;
2045 pline("It's hard to walk in thin air.");
2046 exercise(A_DEX
, TRUE
);
2052 /* check slippery ice */
2053 on_ice
= !Levitation
&& is_ice(u
.ux
, u
.uy
);
2056 if (uarmf
&& uarmf
->oartifact
== ART_MERLOT_FUTURE
&& !(HFast
)) {
2057 incr_itimeout(&HFast
, rnd(500));
2058 pline("Vrooooom, your ski heels speed up thanks to walking on snow!");
2061 static int skates
= 0;
2062 if (!skates
) skates
= find_skates();
2063 static int skates2
= 0;
2064 if (!skates2
) skates2
= find_skates2();
2065 static int skates3
= 0;
2066 if (!skates3
) skates3
= find_skates3();
2067 static int skates4
= 0;
2068 if (!skates4
) skates4
= find_skates4();
2069 static int skates5
= 0;
2070 if (!skates5
) skates5
= find_cyan_sneakers();
2071 if ((uarmf
&& uarmf
->otyp
== skates
)
2072 || (powerfulimplants() && uimplant
&& uimplant
->oartifact
== ART_WHITE_WHALE_HATH_COME
)
2073 || (uarmf
&& uarmf
->otyp
== skates2
)
2074 || (uarmf
&& uarmf
->otyp
== skates3
)
2075 || (uarmf
&& uarmf
->otyp
== skates4
)
2076 || (uarmf
&& uarmf
->otyp
== skates5
)
2077 || (uwep
&& uwep
->oartifact
== ART_GLACIERDALE
)
2078 || (uarmf
&& uarmf
->oartifact
== ART_BRIDGE_SHITTE
)
2079 || (uarmf
&& uarmf
->oartifact
== ART_THICKER_THAN_THE_HEAD
)
2080 || (uarmf
&& uarmf
->oartifact
== ART_LITTLE_ICE_BLOCK_WITH_THE_
)
2081 || (uarmf
&& uarmf
->oartifact
== ART_ONSET_OF_WINTER
)
2082 || (uarmf
&& uarmf
->oartifact
== ART_MERLOT_FUTURE
)
2083 || (uarmf
&& uarmf
->oartifact
== ART_IMPOSSIBLE_CATWALK
)
2084 || (uarmf
&& uarmf
->oartifact
== ART_ANTI_SLIDE
)
2085 || (uwep
&& uwep
->oartifact
== ART_DAMN_SKI_WEDGE
&& uarmf
)
2086 || resists_cold(&youmonst
) || Flying
2087 || is_floater(youmonst
.data
) || is_clinger(youmonst
.data
)
2088 || is_whirly(youmonst
.data
))
2090 else if (!rn2(ColdImmunity
? 20 : Cold_resistance
? 3 : 2)) {
2091 HFumbling
|= FROMOUTSIDE
;
2092 HFumbling
&= ~TIMEOUT
;
2093 HFumbling
+= 1; /* slip on next move */
2096 if (!on_ice
&& !u
.fumbleduration
&& (HFumbling
& FROMOUTSIDE
))
2097 HFumbling
&= ~FROMOUTSIDE
;
2101 /* Check if your steed can move */
2102 if (u
.usteed
&& !flags
.forcefight
&& (!u
.usteed
->mcanmove
|| u
.usteed
->msleeping
)) {
2103 Your("steed doesn't respond!");
2108 /* In Soviet Russia, stunning is a crippling status effect that will fuck you up. You're not supposed to stand
2109 * any chance while stunned, because seriously, players having a chance? That's a no-go! --Amy */
2111 if ((Stunned
&& !rn2(issoviet
? 1 : StrongStun_resist
? 20 : Stun_resist
? 8 : 2)) || (Confusion
&& !rn2(issoviet
? 2 : StrongConf_resist
? 200 : Conf_resist
? 40 : 8) || (autismweaponcheck(ART_MISGUIDED_MISSILE
) && !rn2(20)) || ((uarmh
&& itemhasappearance(uarmh
, APP_THINKING_HELMET
)) && !rn2(8) ) || (uimplant
&& uimplant
->oartifact
== ART_IRON_OF_INNERMOST_JOY
&& ((moves
% 13) < 10) ) )
2112 /* toned down so it's less crippling --Amy
2113 * nerf for extremely fast steeds: they cause you to sometimes walk randomly */
2114 || (u
.usteed
&& ((u
.usteed
->mconf
&& confsteeddir()) || (u
.usteed
->data
->mmove
> 36 && rnd(u
.usteed
->data
->mmove
) > 36) ) )
2116 register int tries
= 0;
2126 } while(!isok(x
, y
) || bad_rock(&youmonst
, x
, y
));
2128 /* turbulence might alter your actual destination */
2131 if (!u
.dx
&& !u
.dy
) {
2142 if (((trap
= t_at(x
, y
)) && trap
->tseen
) ||
2143 (Blind
&& !Levitation
&& !Flying
&&
2144 !is_clinger(youmonst
.data
) &&
2145 (is_waterypool(x
, y
) || is_watertunnel(x
,y
) || is_shiftingsand(x
,y
) || is_moorland(x
,y
) || is_urinelake(x
,y
) || is_lava(x
, y
)) && levl
[x
][y
].seenv
)) {
2146 if(flags
.run
>= 2) {
2154 if (u
.ustuck
&& (x
!= u
.ustuck
->mx
|| y
!= u
.ustuck
->my
)) {
2155 if (distu(u
.ustuck
->mx
, u
.ustuck
->my
) > 2) {
2156 /* perhaps it fled (or was teleported or ... ) */
2158 } else if (sticks(youmonst
.data
)) {
2159 /* When polymorphed into a sticking monster,
2160 * u.ustuck means it's stuck to you, not you to it.
2162 You("release %s.", mon_nam(u
.ustuck
));
2165 /* If holder is asleep or paralyzed:
2166 * 37.5% chance of getting away,
2167 * 12.5% chance of waking/releasing it;
2169 * 7.5% chance of getting away.
2170 * [strength ought to be a factor]
2171 * If holder is tame and there is no conflict,
2172 * guaranteed escape.
2174 switch (rn2(!u
.ustuck
->mcanmove
? 8 : 40)) {
2175 case 0: case 1: case 2:
2177 You("pull free from %s.", mon_nam(u
.ustuck
));
2181 if (!u
.ustuck
->mcanmove
) {
2182 /* it's free to move on next turn */
2183 u
.ustuck
->mfrozen
= 1;
2184 u
.ustuck
->msleeping
= 0;
2188 if (u
.ustuck
->mtame
&&
2189 !Conflict
&& !u
.ustuck
->mconf
)
2191 You("cannot escape from %s!", mon_nam(u
.ustuck
));
2200 /* Don't attack if you're running, and can see it */
2201 /* We should never get here if forcefight */
2203 ((!Blind
&& mon_visible(mtmp
) &&
2204 ((mtmp
->m_ap_type
!= M_AP_FURNITURE
&&
2205 mtmp
->m_ap_type
!= M_AP_OBJECT
) ||
2206 Protection_from_shape_changers
)) ||
2219 /* attack monster */
2224 /* only attack if we know it's there */
2225 /* or if we used the 'F' command to fight blindly */
2226 /* or if it hides_under, in which case we call attack() to print
2227 * the Wait! message.
2228 * This is different from ceiling hiders, who aren't handled in
2232 /* If they used a 'm' command, trying to move onto a monster
2233 * prints the below message and wastes a turn. The exception is
2234 * if the monster is unseen and the player doesn't remember an
2235 * invisible monster--then, we fall through to attack() and
2236 * attack_check(), which still wastes a turn, but prints a
2237 * different message and makes the player remember the monster. */
2239 (canspotmon(mtmp
) || memory_is_invisible(x
, y
))){
2240 if(mtmp
->m_ap_type
&& !Protection_from_shape_changers
2242 stumble_onto_mimic(mtmp
);
2243 else if (mtmp
->mpeaceful
&& !Hallucination
) {
2244 pline("Pardon me, %s.", m_monnam(mtmp
));
2246 /* Amy edit: it makes no fucking sense that Stormbringer doesn't auto-attack in this situation!
2247 * You fucking bumped into a fucking peaceful monster with a fucking Stormbringer for fuck's sake!
2248 * Since it's too annoying to program it so that it does, I'm just making the monster hostile for now */
2249 if (BloodthirstyAttacking
|| (uwep
&& weapon_is_bloodthirsty(uwep
)) || (u
.twoweap
&& uswapwep
&& weapon_is_bloodthirsty(uswapwep
)) ) {
2253 You("move right into %s.", mon_nam(mtmp
));
2254 if (BloodthirstyAttacking
|| (uwep
&& weapon_is_bloodthirsty(uwep
)) || (u
.twoweap
&& uswapwep
&& weapon_is_bloodthirsty(uswapwep
)) ) {
2261 /* If there is ANYthing that might be a remembered monster,
2262 * the player should goddamn ATTACK IT and NOT waste a turn. GRRRR. --Amy */
2263 if(flags
.forcefight
|| memory_is_invisible(x
, y
) || mon_warning(mtmp
) || !mtmp
->mundetected
|| sensemon(mtmp
) ||
2264 ((hides_under(mtmp
->data
) || mtmp
->data
->mlet
== S_EEL
) &&
2265 !is_safepet(mtmp
))){
2267 if(wtcap
>= HVY_ENCUMBER
&& moves
%3) {
2268 if (Upolyd
&& u
.mh
> 1) {
2270 } else if (!Upolyd
&& u
.uhp
> 1) {
2273 You("pass out from exertion!");
2274 exercise(A_CON
, FALSE
);
2275 fall_asleep(-10, FALSE
);
2278 if(multi
< 0) return; /* we just fainted */
2279 /* new displacer beast thingie -- by [Tom] */
2280 /* sometimes, instead of attacking, you displace it. */
2281 /* Good joke, huh? */
2282 if ( (mtmp
->data
== &mons
[PM_DISPLACER_BEAST
] || mtmp
->data
== &mons
[PM_HYPER_CAVE_BEAR
] || mtmp
->data
== &mons
[PM_KURIKKUSHITEKUDASAI__ANATA_NO_OKANE_WANAKU_NATTE_IMASU
] || mtmp
->data
== &mons
[PM_REPLACER_BEAST
] || mtmp
->data
== &mons
[PM_MISPLACER_BEAST
] || mtmp
->data
== &mons
[PM_ELOCATOR
] || mtmp
->data
== &mons
[PM_ANCIENT_OF_THE_BURNING_WASTES
] || mtmp
->data
== &mons
[PM_SARTAN_TANNIN
] || mtmp
->data
== &mons
[PM_POLYMORPH_CODE
] || mtmp
->data
== &mons
[PM_SECRET_POLYMORPH_CODE
] || mtmp
->data
== &mons
[PM_FIRST_WRAITHWORM
] || mtmp
->data
== &mons
[PM_WRAITHWORM
] || mtmp
->data
== &mons
[PM_LILAC_FEMMY
] || mtmp
->data
== &mons
[PM_SHARAB_KAMEREL
] || mtmp
->data
== &mons
[PM_WUXTINA
] || mtmp
->data
== &mons
[PM_IVEL_WUXTINA
] || mtmp
->data
== &mons
[PM_FLUTTERBUG
] || mtmp
->data
== &mons
[PM_LIPSTICK_HC_GIRL
] || mtmp
->data
== &mons
[PM_CREEPY_EVIL_GHOST
] || mtmp
->data
== &mons
[PM_ORTHOS
] || mtmp
->data
== &mons
[PM_SHIMMERING_DRACONIAN
] || mtmp
->data
== &mons
[PM_JUMPING_CHAMPION
] || mtmp
->data
->mlet
== S_GRUE
|| mtmp
->data
== &mons
[PM_QUANTUM_MOLD
] || mtmp
->data
== &mons
[PM_QUANTUM_GROWTH
] || mtmp
->data
== &mons
[PM_QUANTUM_FUNGUS
] || mtmp
->data
== &mons
[PM_QUANTUM_PATCH
] || mtmp
->data
== &mons
[PM_QUANTUM_STALK
] || mtmp
->data
== &mons
[PM_QUANTUM_MUSHROOM
] || mtmp
->data
== &mons
[PM_QUANTUM_SPORE
] || mtmp
->data
== &mons
[PM_QUANTUM_COLONY
] || mtmp
->data
== &mons
[PM_QUANTUM_FORCE_FUNGUS
] || mtmp
->data
== &mons
[PM_QUANTUM_WORT
] || mtmp
->data
== &mons
[PM_QUANTUM_FORCE_PATCH
] || mtmp
->data
== &mons
[PM_QUANTUM_WARP_FUNGUS
] || mtmp
->data
== &mons
[PM_QUANTUM_WARP_PATCH
] || mtmp
->egotype_displacer
) && !rn2(2))
2283 displacer
= TRUE
; /* grues can also displace the player to make them more annoying --Amy */
2284 else if (mtmp
->data
== &mons
[PM_XXXXXXXXXXXXXXXXXXXX
]) displacer
= TRUE
;
2285 else if (tech_inuse(T_EDDY_WIND
)) peacedisplacer
= TRUE
;
2286 else if (u
.swappositioncount
) peacedisplacer
= TRUE
;
2287 else if (uwep
&& uwep
->oartifact
== ART_DIZZY_METAL_STORM
) peacedisplacer
= TRUE
;
2288 /* Displacement allows the player to displace peaceful things --Amy */
2289 else if (Displaced
&& !mtmp
->isshk
&& !mtmp
->ispriest
&& mtmp
->mpeaceful
) peacedisplacer
= TRUE
;
2290 else if (Race_if(PM_BABYLONIAN
) && mtmp
->mpeaceful
&& mtmp
->data
->mlet
== S_TURRET
) peacedisplacer
= TRUE
;
2292 /* try to attack; note that it might evade */
2293 /* also, we don't attack tame when _safepet_ */
2295 if(attack(mtmp
)) return;
2297 if (tech_inuse(T_EDDY_WIND
) && flags
.forcefight
) {
2298 if(attack(mtmp
)) return;
2300 if (u
.swappositioncount
&& flags
.forcefight
) {
2301 if(attack(mtmp
)) return;
2303 if (uwep
&& uwep
->oartifact
== ART_DIZZY_METAL_STORM
&& flags
.forcefight
) {
2304 if(attack(mtmp
)) return;
2309 /* fucked up bug where we can reach here even when engulfed and waste a turn... --Amy
2310 * This could crash the game if the player is punished, which we'll prevent by just aborting the player's move */
2312 pline("Caution: You seem to have encountered the bug where moving into an engulfer wastes a turn. In order to attack the monster, prefix your movement with F (shift-f), please. Sorry for the inconvenience. --Amy");
2316 /* Amy feature: safety question when displacing pets into liquids, impossible to do it to non-pets (too cheesy) */
2317 if (mtmp
&& (displacer
|| peacedisplacer
|| mtmp
->mtame
)) {
2318 boolean inpool
, inlava
;
2320 inpool
= (is_waterypool(u
.ux
, u
.uy
) || is_watertunnel(u
.ux
, u
.uy
)) && !is_flyer(mtmp
->data
) && !(is_urinelake(u
.ux
, u
.uy
)) && !(is_moorland(u
.ux
, u
.uy
)) && !(is_crystalwater(u
.ux
, u
.uy
)) && (!mtmp
->egotype_flying
) && !is_floater(mtmp
->data
);
2321 inlava
= is_lava(u
.ux
, u
.uy
) && !is_flyer(mtmp
->data
) && (!mtmp
->egotype_flying
) && !is_floater(mtmp
->data
);
2323 if (inpool
|| inlava
) canexistonsquare
= FALSE
;
2326 if (!canexistonsquare
) {
2327 if (mtmp
&& !mtmp
->mtame
) {
2328 You("cannot displace that monster into a harmful liquid!");
2330 } else if (mtmp
&& mtmp
->mtame
) {
2331 if (!(ParanoiaBugEffect
|| u
.uprops
[PARANOIA_BUG
].extrinsic
|| have_paranoiastone())) {
2332 if (yn("Really displace the pet into a harmful liquid?") != 'y') {
2339 /* specifying 'F' with no monster wastes a turn */
2340 if (flags
.forcefight
||
2341 /* remembered an 'I' && didn't use a move command */
2342 (memory_is_invisible(x
, y
) && !flags
.nopick
)) {
2343 boolean expl
= (Upolyd
&& attacktype(youmonst
.data
, AT_EXPL
));
2345 sprintf(buf
,"a vacant spot on the %s", surface(x
,y
));
2347 expl
? "explode at" : "attack",
2348 !Underwater
? "thin air" :
2349 is_waterypool(x
,y
) ? "empty water" : buf
);
2350 unmap_object(x
, y
); /* known empty -- remove 'I' if present */
2354 if (!Race_if(PM_UNGENOMOLD
)) {
2355 u
.mh
= -1; /* dead in the current form */
2357 } else polyself(FALSE
);
2361 if (memory_is_invisible(x
, y
)) {
2365 /* not attacking an animal, so we try to move */
2368 if (peacedisplacer
) goto peacedisplace
;
2370 if (u
.usteed
&& !u
.usteed
->mcanmove
&& (u
.dx
|| u
.dy
)) {
2371 pline("%s won't move!", upstart(y_monnam(u
.usteed
)));
2375 if( is_nonmoving(youmonst
.data
) && !Race_if(PM_MISSINGNO
) && !(uactivesymbiosis
&& Upolyd
&& (u
.umonnum
== u
.usymbiote
.mnum
)) ) {
2376 /* This catches the moveamt code in hack.c, preventing you from moving as a red mold
2377 * even if you do get some movement points. It's mainly meant to prevent you from being unable to do anything
2378 * until you get knocked out of red mold form, so you can at least sit around and maybe throw some daggers. --Amy */
2379 You("are rooted %s.",
2380 Levitation
|| Is_airlevel(&u
.uz
) || Is_waterlevel(&u
.uz
) ?
2381 "in place" : "to the ground");
2386 if (trap
= t_at(u
.ux
, u
.uy
)) {
2387 if (trap
->ttyp
== VIVISECTION_TRAP
) {
2389 You("fail to escape the vivisection trap.");
2395 if (StrongInvertedState
&& rn2(2)) {
2396 You("fail to move in your inverted state!");
2401 if(u
.utraptype
== TT_PIT
) {
2402 if (!rn2(2) && sobj_at(BOULDER
, u
.ux
, u
.uy
)) {
2403 Your("%s gets stuck in a crevice.", body_part(LEG
));
2404 display_nhwindow(WIN_MESSAGE
, FALSE
);
2405 clear_nhwindow(WIN_MESSAGE
);
2406 You("free your %s.", body_part(LEG
));
2407 } else if (Flying
&& !In_sokoban(&u
.uz
)) {
2408 /* eg fell in pit, poly'd to a flying monster */
2409 You("fly from the pit.");
2411 fill_pit(u
.ux
, u
.uy
);
2412 vision_full_recalc
= 1; /* vision limits change */
2413 } else if (!(--u
.utrap
)) {
2414 You("%s to the edge of the pit.",
2415 (In_sokoban(&u
.uz
) && Levitation
) ?
2416 "struggle against the air currents and float" :
2417 u
.usteed
? "ride" : "crawl");
2418 fill_pit(u
.ux
, u
.uy
);
2419 vision_full_recalc
= 1; /* vision limits change */
2420 } else if (flags
.verbose
) {
2422 Norep("%s is still in a pit.",
2423 upstart(y_monnam(u
.usteed
)));
2425 Norep( (FunnyHallu
&& !rn2(5)) ?
2426 "You've fallen, and you can't get up." :
2427 "You are still in a pit." );
2430 if (FemtrapActiveNatalje
) {
2431 u
.nataljetrapturns
= moves
;
2432 u
.nataljetrapx
= u
.ux
;
2433 u
.nataljetrapy
= u
.uy
;
2436 traphere
= t_at(u
.ux
,u
.uy
);
2437 if (u
.utrap
&& traphere
&& traphere
->ttyp
== SHIT_PIT
) {
2438 pline("You splotch into a heap of dog shit!");
2440 num
= d(2, 2) + rnd((monster_difficulty() / 3) + 1);
2441 if (Acid_resistance
) { /* let's just assume the stuff is acidic or corrosive --Amy */
2442 shieldeff(u
.ux
, u
.uy
);
2443 num
= d(1, 2) + rnd((monster_difficulty() / 7) + 1);
2445 if (Stoned
) fix_petrification();
2447 if (!rn2(10) || !(uarmf
&& itemhasappearance(uarmf
, APP_PROFILED_BOOTS
) ) ) {
2449 if (uarmf
&& !rn2(5)) (void)rust_dmg(uarmf
, xname(uarmf
), 0, TRUE
, &youmonst
);
2450 if (uarmf
&& !rn2(5)) (void)rust_dmg(uarmf
, xname(uarmf
), 1, TRUE
, &youmonst
);
2451 if (uarmf
&& !rn2(5)) (void)rust_dmg(uarmf
, xname(uarmf
), 2, TRUE
, &youmonst
);
2452 if (uarmf
&& !rn2(5)) (void)rust_dmg(uarmf
, xname(uarmf
), 3, TRUE
, &youmonst
);
2453 /* Dog shit is extremely aggressive to footwear. Let's give it a chance to do withering damage. --Amy */
2454 if (uarmf
&& !rn2(25)) (void)wither_dmg(uarmf
, xname(uarmf
), 0, TRUE
, &youmonst
);
2455 if (uarmf
&& !rn2(25)) (void)wither_dmg(uarmf
, xname(uarmf
), 1, TRUE
, &youmonst
);
2456 if (uarmf
&& !rn2(25)) (void)wither_dmg(uarmf
, xname(uarmf
), 2, TRUE
, &youmonst
);
2457 if (uarmf
&& !rn2(25)) (void)wither_dmg(uarmf
, xname(uarmf
), 3, TRUE
, &youmonst
);
2462 pline("You slip on the shit with your bare %s.", makeplural(body_part(FOOT
)));
2466 if (uarmf
? !rn2(20) : !rn2(15)) {
2467 HFumbling
= FROMOUTSIDE
| rnd(5);
2468 incr_itimeout(&HFumbling
, rnd(2));
2469 u
.fumbleduration
+= rnz(uarmf
? 30 : 20);
2473 if (uarmf
&& itemhasappearance(uarmf
, APP_PROFILED_BOOTS
) ) {
2474 if (!(HFast
& INTRINSIC
)) {
2478 Your("quickness feels more natural.");
2479 exercise(A_DEX
, TRUE
);
2481 HFast
|= FROMOUTSIDE
;
2483 } else if (!rn2(20)) u_slow_down();
2485 if ( !rn2(StrongFree_action
? 1000 : 100) || (!Free_action
&& !rn2(10))) {
2486 You("inhale the intense smell of shit! The world spins and goes dark.");
2487 nomovemsg
= "You are conscious again."; /* default: "you can move again" */
2488 if (isstunfish
) nomul(-rnz(10), "unconscious from smelling dog shit", TRUE
);
2489 else nomul(-rnd(10), "unconscious from smelling dog shit", TRUE
);
2490 exercise(A_DEX
, FALSE
);
2493 if (uarmf
&& itemhasappearance(uarmf
, APP_PROFILED_BOOTS
) ) num
/= 4;
2494 if (num
) losehp(num
, "heap of shit", KILLED_BY_AN
);
2498 if (u
.utrap
&& traphere
&& traphere
->ttyp
== MANA_PIT
) {
2499 drain_en(rnz(monster_difficulty() + 1));
2502 } else if (u
.utraptype
== TT_LAVA
) { /* WHO THE HELL MADE THIS INTO A NOREP GAAAAAAH --Amy */
2504 if (FemtrapActiveNatalje
) {
2505 u
.nataljetrapturns
= moves
;
2506 u
.nataljetrapx
= u
.ux
;
2507 u
.nataljetrapy
= u
.uy
;
2511 predicament
= "stuck in the lava";
2513 pline("%s is %s.", upstart(y_monnam(u
.usteed
)),
2516 pline("You are %s.", predicament
);
2520 if((u
.utrap
& 0xff) == 0) {
2522 You("lead %s to the edge of the lava.",
2523 y_monnam(u
.usteed
));
2525 You("pull yourself to the edge of the lava.");
2530 } else if (u
.utraptype
== TT_WEB
) {
2531 if(uwep
&& uwep
->oartifact
== ART_STING
) {
2533 pline("Sting cuts through the web!");
2537 if (FemtrapActiveNatalje
) {
2538 u
.nataljetrapturns
= moves
;
2539 u
.nataljetrapx
= u
.ux
;
2540 u
.nataljetrapy
= u
.uy
;
2545 predicament
= "stuck to the web";
2547 Norep("%s is %s.", upstart(y_monnam(u
.usteed
)),
2550 Norep("You are %s.", predicament
);
2554 pline("%s breaks out of the web.",
2555 upstart(y_monnam(u
.usteed
)));
2557 You("disentangle yourself.");
2559 } else if (u
.utraptype
== TT_GLUE
) {
2561 if (FemtrapActiveNatalje
) {
2562 u
.nataljetrapturns
= moves
;
2563 u
.nataljetrapx
= u
.ux
;
2564 u
.nataljetrapy
= u
.uy
;
2569 predicament
= "held in place by the glue";
2571 Norep("%s is %s.", upstart(y_monnam(u
.usteed
)),
2574 Norep("You are %s.", predicament
);
2578 pline("%s breaks out of the glue.",
2579 upstart(y_monnam(u
.usteed
)));
2581 You("finally get the sticky glue off.");
2583 } else if (u
.utraptype
== TT_INFLOOR
) {
2585 if (FemtrapActiveNatalje
) {
2586 u
.nataljetrapturns
= moves
;
2587 u
.nataljetrapx
= u
.ux
;
2588 u
.nataljetrapy
= u
.uy
;
2593 predicament
= "stuck in the";
2595 Norep("%s is %s %s.",
2596 upstart(y_monnam(u
.usteed
)),
2597 predicament
, surface(u
.ux
, u
.uy
));
2599 Norep("You are %s %s.", predicament
,
2600 surface(u
.ux
, u
.uy
));
2604 pline("%s finally wiggles free.",
2605 upstart(y_monnam(u
.usteed
)));
2607 You("finally wiggle free.");
2611 if (FemtrapActiveNatalje
) {
2612 u
.nataljetrapturns
= moves
;
2613 u
.nataljetrapx
= u
.ux
;
2614 u
.nataljetrapy
= u
.uy
;
2618 predicament
= "caught in a bear trap";
2620 Norep("%s is %s.", upstart(y_monnam(u
.usteed
)),
2623 Norep("You are %s.", predicament
);
2625 if((u
.dx
&& u
.dy
) || !rn2(5)) {
2627 if (u
.utrap
== 0) pline("You pull free from the trap.");
2628 else pline("You try to get out of the trap.");}
2633 if (!test_move(u
.ux
, u
.uy
, x
-u
.ux
, y
-u
.uy
, DO_MOVE
)) {
2645 traphere
= t_at(x
,y
);
2646 if (traphere
&& traphere
->ttyp
== NUPESELL_TRAP
) {
2656 /* warn player before walking into known traps */
2657 if (ask_about_trap(x
, y
)) {
2660 sprintf(qbuf
,"Do you really want to %s into that %s?",
2661 locomotion(youmonst
.data
, "step"),
2662 Hallucination
? "trap" : defsyms
[trap_to_defsym(trap
->ttyp
)].explanation
);
2663 if (yn(qbuf
) != 'y') {
2670 if (ask_about_water(x
, y
)) {
2672 if (Role_if(PM_TOPMODEL
) && Is_qlocate(&u
.uz
) ) {
2673 if (yn("There is a strong wind above the water. It seems dangerous. Really step there?") != 'y') {
2679 if (Role_if(PM_FAILED_EXISTENCE
) && Is_qlocate(&u
.uz
) ) {
2680 if (yn("There is a strong wind above the water. It seems dangerous. Really step there?") != 'y') {
2688 if (yn("This is a water tile that can cause you to drown. Really step on it?") != 'y') {
2697 if (ask_about_lava(x
, y
)) {
2699 if (yn("This is a lava tile that can burn you to a crisp. Really step on it?") != 'y') {
2705 getlin ("Are you really sure [yes/no]?",bufX
);
2706 if (strcmp (bufX
, "yes")) {
2713 if (ask_about_watertunnel(x
, y
)) {
2715 if (yn("This is a water tunnel that can cause you to drown. Really dive into it?") != 'y') {
2722 if (ask_about_crystalwater(x
, y
)) {
2724 if (yn("This is a crystal water tile that can cause you to drown. Really fly into it?") != 'y') {
2731 if (ask_about_moorland(x
, y
)) {
2733 if (yn("This is moorland; swimming in it will continuously hurt you. Really do it?") != 'y') {
2740 if (ask_about_urinelake(x
, y
)) {
2742 if (yn("This is a urine lake, which can be detrimental to swim in. Really do it?") != 'y') {
2749 if (ask_about_shiftingsand(x
, y
)) {
2751 if (yn("This is a shifting sand tile, which will quickly kill you by suffocation. Really step on it?") != 'y') {
2757 getlin ("Are you really sure [yes/no]?",bufX
);
2758 if (strcmp (bufX
, "yes")) {
2765 if (ask_about_styxriver(x
, y
)) {
2767 if (yn("This is a styx river, which will continuously contaminate you. Really step on it?") != 'y') {
2774 if (ask_about_burningwagon(x
, y
)) {
2776 if (yn("This is a burning wagon, which will burn you. Really step on it?") != 'y') {
2783 if (ask_about_nethermist(x
, y
)) {
2785 if (yn("This is a nether mist tile, which can drain your experience. Really step on it?") != 'y') {
2792 if (ask_about_stalactite(x
, y
)) {
2794 if (yn("This is a stalactite, which will hurt you if you fly into it. Really do it?") != 'y') {
2801 if (ask_about_raincloud(x
, y
)) {
2803 if (yn("This is a rain cloud, which will make you and your entire inventory wet. Really step into it?") != 'y') {
2810 if (ask_about_bubble(x
, y
)) {
2812 if (yn("This is a bubble, which causes stunning. Really step into it?") != 'y') {
2819 } else if (!test_move(u
.ux
, u
.uy
, x
-u
.ux
, y
-u
.uy
, TEST_MOVE
)) {
2821 * If a monster attempted to displace us but failed
2822 * then we are entitled to our normal attack.
2824 if (!attack(mtmp
)) {
2831 /* Move ball and chain. */
2833 if (!drag_ball(x
,y
, &bc_control
, &ballx
, &bally
, &chainx
, &chainy
,
2834 &cause_delay
, TRUE
))
2837 /* Check regions entering/leaving */
2838 if (!in_out_region(x
,y
)) {
2840 /* [ALI] This can't happen at present, but if it did we would
2841 * also need to worry about the call to drag_ball above.
2843 if (displacer
) (void)attack(mtmp
);
2848 /* now move the hero */
2854 if (TronEffect
|| u
.uprops
[TRON_EFFECT
].extrinsic
|| have_tronstone() || (uarmh
&& itemhasappearance(uarmh
, APP_HARDCORE_CLOTH
)) || Race_if(PM_SLYER_ALIEN
) ) {
2855 if (u
.dx
== 1 && !u
.dy
) u
.trontrapdirection
= 1; /* east */
2856 else if (u
.dx
== 1 && u
.dy
== 1) u
.trontrapdirection
= 2; /* southeast */
2857 else if (!u
.dx
&& u
.dy
== -1) u
.trontrapdirection
= 3; /* north */
2858 else if (u
.dx
== -1 && u
.dy
== -1) u
.trontrapdirection
= 4; /* northwest */
2859 else if (u
.dx
== -1 && !u
.dy
) u
.trontrapdirection
= 5; /* west */
2860 else if (u
.dx
== -1 && u
.dy
== 1) u
.trontrapdirection
= 6; /* southwest */
2861 else if (!u
.dx
&& u
.dy
== 1) u
.trontrapdirection
= 7; /* south */
2862 else if (u
.dx
== 1 && u
.dy
== -1) u
.trontrapdirection
= 8; /* northeast */
2863 else u
.trontrapdirection
= -1;
2865 u
.trontrapturn
= moves
;
2869 /* Move your steed, too */
2871 u
.usteed
->mx
= u
.ux
;
2872 u
.usteed
->my
= u
.uy
;
2876 /* exercising high heel skill takes a while... */
2877 if (PlayerInHighHeels
&& (u
.uhighheelturns
++ >= 50)) {
2878 u
.uhighheelturns
= 0;
2879 use_skill(P_HIGH_HEELS
, 1);
2882 if (PlayerInColumnarHeels
) {
2884 /* an odd one: male characters can train it faster, lacking the high heels skill makes it slower, and if
2885 * you're female without the high heels skill you cannot train it at all --Amy */
2887 int columnarneeded
= 150;
2888 boolean cancolumnar
= TRUE
;
2889 if (flags
.female
) columnarneeded
= 500;
2891 if (P_MAX_SKILL(P_HIGH_HEELS
) == P_ISRESTRICTED
) {
2892 if (flags
.female
) cancolumnar
= FALSE
;
2893 else columnarneeded
= 500;
2897 if (cancolumnar
&& (u
.columnarturns
>= columnarneeded
)) {
2898 u
.columnarturns
= 0;
2900 if (u
.columnarskill
== 20) You("are now more skilled in type 5: columnar heels.");
2901 if (u
.columnarskill
== 160) You("are now more skilled in type 5: columnar heels.");
2902 if (u
.columnarskill
== 540) You("are now more skilled in type 5: columnar heels.");
2903 if (u
.columnarskill
== 1280) You("are now more skilled in type 5: columnar heels.");
2904 if (u
.columnarskill
== 2500) You("are now more skilled in type 5: columnar heels.");
2905 if (u
.columnarskill
== 4320) You("are now most skilled in type 5: columnar heels.");
2909 if (PlayerInStilettoHeels
) {
2910 u
.ustilettoheelturns
++;
2911 if (u
.ustilettoheelturns
>= ((flags
.female
|| Role_if(PM_TRANSVESTITE
) || Role_if(PM_TRANSSYLVANIAN
)) ? 350 : 2500) ) {
2912 u
.ustilettoheelturns
= 0;
2913 use_skill(P_STILETTO_HEELS
, 1);
2917 if (PlayerInConeHeels
) {
2919 if (u
.uconeheelturns
>= ((flags
.female
|| Role_if(PM_TRANSVESTITE
) || Role_if(PM_TRANSSYLVANIAN
)) ? 200 : 500) ) {
2920 u
.uconeheelturns
= 0;
2921 use_skill(P_CONE_HEELS
, 1);
2925 if (PlayerInBlockHeels
) {
2926 u
.ublockheelturns
++;
2927 if (u
.ublockheelturns
>= 250) {
2928 u
.ublockheelturns
= 0;
2929 use_skill(P_BLOCK_HEELS
, 1);
2933 if (PlayerInWedgeHeels
) {
2934 u
.uwedgeheelturns
++;
2935 if (u
.uwedgeheelturns
>= 200) {
2936 u
.uwedgeheelturns
= 0;
2937 use_skill(P_WEDGE_HEELS
, 1);
2941 /* exercising sexy flats does too, especially if you're male */
2942 if (PlayerInSexyFlats
&& (flags
.female
|| !rn2(5)) && (u
.usexyflatturns
++ >= 50)) {
2943 u
.usexyflatturns
= 0;
2944 use_skill(P_SEXY_FLATS
, 1);
2947 if (displacer
|| peacedisplacer
) {
2948 char pnambuf
[BUFSZ
];
2950 u
.utrap
= 0; /* A lucky escape */
2951 /* save its current description in case of polymorph */
2952 strcpy(pnambuf
, mon_nam(mtmp
));
2954 if (mtmp
->data
== &mons
[PM_KURIKKUSHITEKUDASAI__ANATA_NO_OKANE_WANAKU_NATTE_IMASU
]) {
2958 pline("Ops, sorry."); /* sic from Elona */
2962 remove_monster(x
, y
);
2963 place_monster(mtmp
, u
.ux0
, u
.uy0
);
2965 if (u
.swappositioncount
) u
.swappositioncount
= 0;
2967 /* check for displacing it into pools and traps */
2968 switch (minliquid(mtmp
) ? 2 : mintrap(mtmp
)) {
2970 if (tech_inuse(T_EDDY_WIND
)) You("whirl past %s.", pnambuf
);
2971 else You("displaced %s.", pnambuf
);
2977 u
.uconduct
.killer
++;
2983 * if safepet at destination then move the pet to the hero's
2984 * previous location using the same conditions as in attack().
2985 * there are special extenuating circumstances:
2986 * (1) if the pet dies then your god angers,
2987 * (2) if the pet gets trapped then your god may disapprove,
2988 * (3) if the pet was already trapped and you attempt to free it
2989 * not only do you encounter the trap but you may frighten your
2990 * pet causing it to go wild! moral: don't abuse this privilege.
2992 * Ceiling-hiding pets are skipped by this section of code, to
2993 * be caught by the normal falling-monster code.
2994 * Amy addition: displacement already allows you to displace monsters; don't call the displacing code twice
2996 if (is_safepet(mtmp
) && !Displaced
&& !( (is_hider(mtmp
->data
) || mtmp
->egotype_hide
|| mtmp
->egotype_mimic
) && mtmp
->mundetected
)) {
2997 /* if trapped, there's a chance the pet goes wild */
2998 if (mtmp
->mtrapped
) {
2999 if (!rn2(mtmp
->mtame
) && !((rnd(30 - ACURR(A_CHA
))) < 4) ) {
3000 mtmp
->mtame
= mtmp
->mpeaceful
= mtmp
->msleeping
= 0;
3001 if (mtmp
->mleashed
) m_unleash(mtmp
, TRUE
);
3007 mtmp
->mundetected
= 0;
3008 if (mtmp
->m_ap_type
) seemimic(mtmp
);
3009 else if (!mtmp
->mtame
) newsym(mtmp
->mx
, mtmp
->my
);
3011 if (mtmp
->mtrapped
&&
3012 (trap
= t_at(mtmp
->mx
, mtmp
->my
)) != 0 &&
3013 (trap
->ttyp
== PIT
|| trap
->ttyp
== SPIKED_PIT
|| trap
->ttyp
== GIANT_CHASM
|| trap
->ttyp
== SHIT_PIT
|| trap
->ttyp
== MANA_PIT
|| trap
->ttyp
== ANOXIC_PIT
|| trap
->ttyp
== HYPOXIC_PIT
|| trap
->ttyp
== ACID_PIT
) &&
3014 sobj_at(BOULDER
, trap
->tx
, trap
->ty
)) {
3015 /* can't swap places with pet pinned in a pit by a boulder */
3016 u
.ux
= u
.ux0
, u
.uy
= u
.uy0
; /* didn't move after all */
3017 } else if (u
.ux0
!= x
&& u
.uy0
!= y
&&
3018 bad_rock(mtmp
, x
, u
.uy0
) &&
3019 bad_rock(mtmp
, u
.ux0
, y
) &&
3020 (bigmonst(mtmp
->data
) || (curr_mon_load(mtmp
) > 5000))) {
3021 /* can't swap places when pet won't fit thru the opening */
3022 u
.ux
= u
.ux0
, u
.uy
= u
.uy0
; /* didn't move after all */
3023 You("stop. %s won't fit through.", upstart(y_monnam(mtmp
)));
3025 char pnambuf
[BUFSZ
];
3027 /* save its current description in case of polymorph */
3028 strcpy(pnambuf
, y_monnam(mtmp
));
3030 remove_monster(x
, y
);
3031 place_monster(mtmp
, u
.ux0
, u
.uy0
);
3033 /* check for displacing it into pools and traps */
3034 switch (minliquid(mtmp
) ? 2 : mintrap(mtmp
)) {
3036 You("%s %s.", mtmp
->mtame
? "displaced" : "frightened",
3039 case 1: /* trapped */
3040 case 3: /* changed levels */
3041 /* there's already been a trap message, reinforce it */
3046 /* it may have drowned or died. that's no way to
3047 * treat a pet! your god gets angry.
3050 You_feel("guilty about losing your pet like this.");
3055 /* you killed your pet by direct action.
3056 * minliquid and mintrap don't know to do this
3058 u
.uconduct
.killer
++;
3061 pline("that's strange, unknown mintrap result!");
3067 reset_occupations();
3069 if ( flags
.run
< 8 )
3070 if (IS_DOOR(tmpr
->typ
) || IS_ROCK(tmpr
->typ
) ||
3071 IS_FURNITURE(tmpr
->typ
))
3075 if (hides_under(youmonst
.data
) || (uarmh
&& itemhasappearance(uarmh
, APP_SECRET_HELMET
) ) || (!night() && uarmg
&& uarmg
->oartifact
== ART_NIGHTLY_HIGHWAY
) || (uarmc
&& uarmc
->oartifact
== ART_JANA_S_EXTREME_HIDE_AND_SE
) )
3076 u
.uundetected
= OBJ_AT(u
.ux
, u
.uy
);
3077 else if (youmonst
.data
->mlet
== S_EEL
)
3078 u
.uundetected
= is_waterypool(u
.ux
, u
.uy
) && !Is_waterlevel(&u
.uz
);
3079 else if (is_wagon(u
.ux
, u
.uy
))
3080 u
.uundetected
= TRUE
;
3081 else if (u
.dx
|| u
.dy
)
3085 * Mimics (or whatever) become noticeable if they move and are
3086 * imitating something that doesn't move. We could extend this
3087 * to non-moving monsters...
3089 if ((u
.dx
|| u
.dy
) && (youmonst
.m_ap_type
== M_AP_OBJECT
3090 || youmonst
.m_ap_type
== M_AP_FURNITURE
))
3091 youmonst
.m_ap_type
= M_AP_NOTHING
;
3093 check_leash(u
.ux0
,u
.uy0
);
3095 if(u
.ux0
!= u
.ux
|| u
.uy0
!= u
.uy
) {
3098 /* Clean old position -- vision_recalc() will print our new one. */
3099 newsym(u
.ux0
,u
.uy0
);
3100 /* Since the hero has moved, adjust what can be seen/unseen. */
3101 vision_recalc(1); /* Do the work now in the recover time. */
3102 invocation_message();
3105 if (Punished
) /* put back ball and chain */
3106 move_bc(0,bc_control
,ballx
,bally
,chainx
,chainy
);
3110 /* delay next move because of ball dragging */
3111 /* must come after we finished picking up, in spoteffects() */
3113 nomul(-2, "dragging an iron ball", TRUE
);
3117 if (flags
.run
&& iflags
.runmode
!= RUN_TPORT
) {
3118 /* display every step or every 7th step depending upon mode */
3119 if (iflags
.runmode
!= RUN_LEAP
|| !(moves
% 7L)) {
3120 if (flags
.time
) flags
.botl
= 1;
3123 if (iflags
.runmode
== RUN_CRAWL
) {
3134 invocation_message()
3136 /* a special clue-msg when on the Invocation position */
3137 if(invocation_pos(u
.ux
, u
.uy
) && !On_stairs(u
.ux
, u
.uy
)) {
3139 struct obj
*otmp
= carrying(CANDELABRUM_OF_INVOCATION
);
3141 nomul(0, 0, FALSE
); /* stop running or travelling */
3143 pline("You're picking up good vibrations!");
3144 if (flags
.moreforced
&& !MessagesSuppressed
) display_nhwindow(WIN_MESSAGE
, TRUE
); /* --More-- */
3146 if (u
.usteed
) sprintf(buf
, "beneath %s", y_monnam(u
.usteed
));
3148 if (Levitation
|| Flying
) strcpy(buf
, "beneath you");
3149 else sprintf(buf
, "under your %s", makeplural(body_part(FOOT
)));
3151 You_feel("a strange vibration %s.", buf
);
3152 if (flags
.moreforced
&& !MessagesSuppressed
) display_nhwindow(WIN_MESSAGE
, TRUE
); /* --More-- */
3154 if (otmp
&& otmp
->spe
== 7 && otmp
->lamplit
)
3155 pline("%s %s!", The(xname(otmp
)),
3156 Blind
? "throbs palpably" : "glows with a strange light");
3160 if (!u
.vibratingsquarefind
) {
3161 u
.vibratingsquarefind
= 1;
3162 qt_pager(QT_VIBRATINGSQUARE
);
3168 /* Wounds patch gotten from 5lo's SLEX mod --Amy */
3170 static const char * const hallu_adverb
[] = { /* 5lo: Wounds patch by L */
3171 "mildly", "mostly", "somewhat", "slightly", "probably", "massively", "extremely",
3172 "flagrantly", "flamboyantly", "supremely", "excessively", "truly", "terribly",
3173 "not at all", "barely", "heavily", "critically", "normally", "nonchalantly", "strangely",
3174 "fleecily", "painfully", "hurtingly", "almost", "nearly", "now", "no longer",
3175 "apparently", "frighteningly", "totally", "awfully", "with difficulty", "secretly",
3176 "immediately", "fatally", "magically", "dreadfully", "superficially", "openly",
3177 "sharply", "in some way", "maybe", "seemingly", "really", "not really", "unremarkably",
3178 "happily", "randomly", "stupidly", "intelligently", "strongly", "weakly", "wisely",
3179 "always", "never", "more", "less", "certainly", "irredeemably", "questionably",
3180 "perhaps", "confused and", "stunned and", "dead or", "hallucinating but not", "more or less",
3181 "incredibly", "unbelievably", "obscenely", "insanely", "amazingly", "absolutely"
3188 if (mon_wounds(mon
))
3189 pline("%s is %s.", Monnam(mon
), mon_wounds(mon
));
3196 static char buf
[BUFSZ
];
3197 boolean wounded
= ((!nonliving(mon
->data
) ||
3198 /* Zombies and mummies (but not skeletons) have flesh */
3199 ((mon
->data
->mlet
== S_ZOMBIE
&& mon
->data
!= &mons
[PM_SKELETON
])
3200 || mon
->data
->mlet
== S_MUMMY
|| mon
->data
->mlet
== S_VAMPIRE
3201 || mon
->data
== &mons
[PM_FLESH_GOLEM
]))
3202 && !vegetarian(mon
->data
)); /* :TODO?: Check and see if some Extended monsters fit the above */
3204 /* Able to detect wounds? */
3205 if (!(canseemon(mon
) || (u
.ustuck
== mon
&& u
.uswallow
&& !Blind
))
3206 || (!Race_if(PM_HERBALIST
) && !Role_if(PM_HEALER
) && !Role_if(PM_SCIENTIST
) && !Role_if(PM_EMPATH
) && !Race_if(PM_ALCHEMIST
) && !Role_if(PM_NECROMANCER
) && !Role_if(PM_UNDERTAKER
) && (mon
->data
->msound
!= MS_PAIN
) ) )
3207 /* 5lo: Expanded for more roles */
3209 if (mon
->mhp
== mon
->mhpmax
|| mon
->mhp
< 1)
3211 if (!Hallucination
&& mon
->mhp
<= mon
->mhpmax
/ 6) {
3212 sprintf(buf
,"almost ");
3213 strcat(buf
, nonliving(mon
->data
) ? "destroyed" : "dead");
3215 if (Hallucination
) {
3216 sprintf(buf
, "%s", hallu_adverb
[rn2(SIZE(hallu_adverb
))]);
3219 else if (mon
->mhp
<= mon
->mhpmax
/ 4)
3220 sprintf(buf
,"horribly ");
3221 else if (mon
->mhp
<= mon
->mhpmax
/ 3)
3222 sprintf(buf
,"heavily ");
3223 else if (mon
->mhp
<= 3 * mon
->mhpmax
/ 4)
3224 sprintf(buf
,"moderately ");
3226 sprintf(buf
,"lightly ");
3227 strcat(buf
, wounded
|| (Hallucination
&& rn2(2)) ? "wounded" : "damaged");
3240 register struct monst
*mtmp
;
3242 if (is_pool(u
.ux
, u
.uy
) && (Role_if(PM_TOPMODEL
) || Role_if(PM_FAILED_EXISTENCE
)) && Is_qlocate(&u
.uz
) ) {
3244 /* strong winds over the Grand Canyon. Please don't ask me how they can continue working underwater. :-) --Amy */
3246 pline(FunnyHallu
? "This whirl is like the eye of a hurricane, but it tickles!" : "There are scathing winds here! Your skin is scraped off!");
3247 losehp(rnz(u
.legscratching
), "scathing winds", KILLED_BY
);
3250 make_stunned(HStun
+ rnz(u
.legscratching
), FALSE
);
3255 if (t_at(u
.ux
, u
.uy
) && (Role_if(PM_TOPMODEL
) || Role_if(PM_FAILED_EXISTENCE
)) && Is_qlocate(&u
.uz
) ) {
3257 /* every trap on the Grand Canyon level also has a lesser wind effect. --Amy */
3259 pline(FunnyHallu
? "A twister... or is that a tornado?" : "You are enclosed in a whirlwind!");
3260 losehp(rnd(u
.legscratching
+ 2), "whirlwinds", KILLED_BY
);
3264 if (is_crystalwater(u
.ux
,u
.uy
) && (Flying
|| Levitation
)) {
3271 if (!is_drowningpool(u
.ux
,u
.uy
)) {
3272 if (Is_waterlevel(&u
.uz
))
3273 You("pop into an air bubble.");
3274 else if (is_lava(u
.ux
, u
.uy
))
3275 You("leave the water..."); /* oops! */
3277 You("are on solid %s again.",
3278 is_ice(u
.ux
, u
.uy
) ? "ice" : "land");
3280 else if (Is_waterlevel(&u
.uz
))
3282 else if (Levitation
&& !is_crystalwater(u
.ux
,u
.uy
))
3283 You("pop out of the water like a cork!");
3284 /* KMH, balance patch -- new intrinsic */
3285 else if (Flying
&& !is_crystalwater(u
.ux
,u
.uy
))
3286 You("fly out of the water.");
3287 else if (uarmc
&& itemhasappearance(uarmc
, APP_FLIER_CLOAK
) && !is_crystalwater(u
.ux
,u
.uy
))
3288 You("fly out of the water.");
3289 else if (uarmf
&& uarmf
->oartifact
== ART_RUBBER_LOVE
&& !is_crystalwater(u
.ux
,u
.uy
))
3290 You("float on top of the water.");
3291 else if ((Wwalking
|| Race_if(PM_KORONST
)) && !is_crystalwater(u
.ux
,u
.uy
))
3292 You("slowly rise above the surface.");
3293 /* else if (Swimming)
3294 You("paddle up to the surface.");*/
3297 was_underwater
= Underwater
&& !Is_waterlevel(&u
.uz
);
3298 u
.uinwater
= 0; /* leave the water */
3299 if (was_underwater
) { /* restore vision */
3301 vision_full_recalc
= 1;
3305 if (!Levitation
&& !u
.ustuck
&& !Flying
&& !(uarmf
&& uarmf
->oartifact
== ART_RUBBER_LOVE
) && !(uarmc
&& itemhasappearance(uarmc
, APP_FLIER_CLOAK
)) ) {
3306 /* limit recursive calls through teleds() */
3307 if ((is_drowningpool(u
.ux
, u
.uy
) && !(is_crystalwater(u
.ux
,u
.uy
))) || is_lava(u
.ux
, u
.uy
)) {
3308 if (u
.usteed
&& !is_flyer(u
.usteed
->data
) && (!u
.usteed
->egotype_flying
) &&
3309 !is_swimmer(u
.usteed
->data
) &&
3310 !is_floater(u
.usteed
->data
) &&
3311 !is_clinger(u
.usteed
->data
)) {
3312 dismount_steed(Underwater
?
3313 DISMOUNT_FELL
: DISMOUNT_GENERIC
);
3314 /* dismount_steed() -> float_down() -> pickup() */
3315 if (!Is_airlevel(&u
.uz
) && !Is_waterlevel(&u
.uz
))
3318 if (is_lava(u
.ux
, u
.uy
)) {
3319 if (lava_effects()) return;
3320 } else if (!Wwalking
&& !Race_if(PM_KORONST
) && drown())
3324 check_special_room(FALSE
);
3325 if(IS_SINK(levl
[u
.ux
][u
.uy
].typ
) && Levitation
)
3327 if (!in_steed_dismounting
) { /* if dismounting, we'll check again later */
3328 struct trap
*trap
= t_at(u
.ux
, u
.uy
);
3330 pit
= (trap
&& (trap
->ttyp
== PIT
|| trap
->ttyp
== SPIKED_PIT
|| trap
->ttyp
== GIANT_CHASM
|| trap
->ttyp
== SHIT_PIT
|| trap
->ttyp
== MANA_PIT
|| trap
->ttyp
== ANOXIC_PIT
|| trap
->ttyp
== HYPOXIC_PIT
|| trap
->ttyp
== ACID_PIT
));
3332 dotrap(trap
, 0); /* fall into pit */
3333 /* somehow, being engulfed can sometimes result in "you can't take out blablabla" messages when you very
3334 * obviously just wanted to attack the engulfer, but I can't seem to be able to reproduce it... yet it's
3335 * incredibly annoying whenever it happens; I hope this is the correct line of code to change --Amy */
3336 if (pick
&& !u
.uswallow
) (void) pickup(1);
3338 dotrap(trap
, 0); /* fall into arrow trap, etc. */
3340 if((mtmp
= m_at(u
.ux
, u
.uy
)) && !u
.uswallow
) {
3341 mtmp
->mundetected
= mtmp
->msleeping
= 0;
3342 switch(mtmp
->data
->mlet
) {
3344 pline("%s suddenly drops from the %s!",
3345 Amonnam(mtmp
), ceiling(u
.ux
,u
.uy
));
3346 if(mtmp
->mtame
) /* jumps to greet you, not attack */
3348 else if(uarmh
&& is_hardmaterial(uarmh
))
3349 pline("Its blow glances off your helmet.");
3350 else if (u
.uac
+ 3 <= rnd(20) && rn2(3) ) /* ac no longer gives complete protection --Amy */
3351 You("are almost hit by %s!",
3352 x_monnam(mtmp
, ARTICLE_A
, "falling", 0, TRUE
));
3356 You("are hit by %s!",
3357 x_monnam(mtmp
, ARTICLE_A
, "falling", 0, TRUE
));
3358 /* Amy edit: make it depend on the monster's level */
3359 molev
= mtmp
->data
->mlevel
;
3360 if (molev
> 5) molev
-= ((molev
- 4) * 2 / 3);
3361 if (molev
< 1) molev
= 1;
3363 if(Half_physical_damage
&& (rn2(2) || (uwep
&& uwep
->oartifact
== ART_SOOTHE_
)) ) dmg
= (dmg
+1) / 2;
3364 if(StrongHalf_physical_damage
&& (rn2(2) || (uwep
&& uwep
->oartifact
== ART_SOOTHE_
)) ) dmg
= (dmg
+1) / 2;
3365 mdamageu(mtmp
, dmg
);
3368 default: /* monster surprises you. */
3370 pline("%s jumps near you from the %s.",
3371 Amonnam(mtmp
), ceiling(u
.ux
,u
.uy
));
3372 else if(mtmp
->mpeaceful
) {
3374 Blind
&& !sensemon(mtmp
) ?
3375 something
: a_monnam(mtmp
));
3376 mtmp
->mpeaceful
= 0;
3377 } else if (mtmp
->data
== &mons
[PM_DROPCLONK_BEAR
] || mtmp
->data
== &mons
[PM_DROPTREE_BEAR
] || mtmp
->data
== &mons
[PM_BONKERS_BEAR
]) {
3379 You("are hit by %s!",
3380 x_monnam(mtmp
, ARTICLE_A
, "falling", 0, TRUE
));
3382 if(Half_physical_damage
&& (rn2(2) || (uwep
&& uwep
->oartifact
== ART_SOOTHE_
)) ) dmg
= (dmg
+1) / 2;
3383 if(StrongHalf_physical_damage
&& (rn2(2) || (uwep
&& uwep
->oartifact
== ART_SOOTHE_
)) ) dmg
= (dmg
+1) / 2;
3384 if (uarmh
) dmg
= (dmg
+1) / 2;
3385 mdamageu(mtmp
, dmg
);
3388 pline("%s attacks you by surprise!", Amonnam(mtmp
));
3392 mnexto(mtmp
); /* have to move the monster */
3397 monstinroom(mdat
,roomno
)
3398 struct permonst
*mdat
;
3401 register struct monst
*mtmp
;
3403 for(mtmp
= fmon
; mtmp
; mtmp
= mtmp
->nmon
)
3404 if(!DEADMONSTER(mtmp
) && mtmp
->data
== mdat
&&
3405 index(in_rooms(mtmp
->mx
, mtmp
->my
, 0), roomno
+ ROOMOFFSET
))
3411 anymonstinroom(roomno
)
3414 register struct monst
*mtmp
;
3416 for(mtmp
= fmon
; mtmp
; mtmp
= mtmp
->nmon
)
3417 if(!DEADMONSTER(mtmp
) && index(in_rooms(mtmp
->mx
, mtmp
->my
, 0), roomno
+ ROOMOFFSET
))
3423 in_rooms(x
, y
, typewanted
)
3424 register xchar x
, y
;
3425 register int typewanted
;
3428 char rno
, *ptr
= &buf
[4];
3429 int typefound
, min_x
, min_y
, max_x
, max_y_offset
, step
;
3430 register struct rm
*lev
;
3432 #define goodtype(rno) (!typewanted || \
3433 ((typefound = rooms[rno - ROOMOFFSET].rtype) == typewanted) || \
3434 ((typewanted == SHOPBASE) && (typefound > SHOPBASE))) \
3436 switch (rno = levl[x][y].roomno) {
3445 default: /* i.e. a regular room # */
3463 max_y_offset
-= step
;
3465 if ((min_y
+ max_y_offset
) >= ROWNO
)
3466 max_y_offset
-= step
;
3468 for (x
= min_x
; x
<= max_x
; x
+= step
) {
3469 lev
= &levl
[x
][min_y
];
3471 if (((rno
= lev
[y
].roomno
) >= ROOMOFFSET
) &&
3472 !index(ptr
, rno
) && goodtype(rno
))
3475 if (y
> max_y_offset
)
3477 if (((rno
= lev
[y
].roomno
) >= ROOMOFFSET
) &&
3478 !index(ptr
, rno
) && goodtype(rno
))
3481 if (y
> max_y_offset
)
3483 if (((rno
= lev
[y
].roomno
) >= ROOMOFFSET
) &&
3484 !index(ptr
, rno
) && goodtype(rno
))
3491 in_roomscolouur(x
, y
, typewanted
)
3492 register xchar x
, y
;
3493 register int typewanted
;
3496 char rno
, *ptr
= &buf
[4];
3497 int typefound
, min_x
, min_y
, max_x
, max_y_offset
, step
;
3498 register struct rm
*lev
;
3500 #define goodtypeX(rno) (!typewanted || \
3501 ((typefound = rooms[rno - ROOMOFFSET].colouur) == typewanted)) \
3503 switch (rno = levl[x][y].roomno) {
3512 default: /* i.e. a regular room # */
3530 max_y_offset
-= step
;
3532 if ((min_y
+ max_y_offset
) >= ROWNO
)
3533 max_y_offset
-= step
;
3535 for (x
= min_x
; x
<= max_x
; x
+= step
) {
3536 lev
= &levl
[x
][min_y
];
3538 if (((rno
= lev
[y
].roomno
) >= ROOMOFFSET
) &&
3539 !index(ptr
, rno
) && goodtypeX(rno
))
3542 if (y
> max_y_offset
)
3544 if (((rno
= lev
[y
].roomno
) >= ROOMOFFSET
) &&
3545 !index(ptr
, rno
) && goodtypeX(rno
))
3548 if (y
> max_y_offset
)
3550 if (((rno
= lev
[y
].roomno
) >= ROOMOFFSET
) &&
3551 !index(ptr
, rno
) && goodtypeX(rno
))
3558 /* is (x,y) in a town? */
3563 s_level
*slev
= Is_special(&u
.uz
);
3564 register struct mkroom
*sroom
;
3565 boolean has_subrooms
= FALSE
;
3567 if (!slev
|| !slev
->flags
.town
) return FALSE
;
3570 * See if (x,y) is in a room with subrooms, if so, assume it's the
3571 * town. If there are no subrooms, the whole level is in town.
3573 for (sroom
= &rooms
[0]; sroom
->hx
> 0; sroom
++) {
3574 if (sroom
->nsubrooms
> 0) {
3575 has_subrooms
= TRUE
;
3576 if (inside_room(sroom
, x
, y
)) return TRUE
;
3580 return !has_subrooms
;
3585 register boolean newlev
;
3587 char *ptr1
, *ptr2
, *ptr3
, *ptr4
;
3589 strcpy(u
.urooms0
, u
.urooms
);
3590 strcpy(u
.ushops0
, u
.ushops
);
3593 u
.uentered
[0] = '\0';
3595 u
.ushops_entered
[0] = '\0';
3596 strcpy(u
.ushops_left
, u
.ushops0
);
3599 strcpy(u
.urooms
, in_rooms(u
.ux
, u
.uy
, 0));
3601 for (ptr1
= &u
.urooms
[0],
3602 ptr2
= &u
.uentered
[0],
3603 ptr3
= &u
.ushops
[0],
3604 ptr4
= &u
.ushops_entered
[0];
3606 if (!index(u
.urooms0
, *ptr1
))
3608 if (IS_SHOP(*ptr1
- ROOMOFFSET
)) {
3610 if (!index(u
.ushops0
, *ptr1
))
3618 /* filter u.ushops0 -> u.ushops_left */
3619 for (ptr1
= &u
.ushops0
[0], ptr2
= &u
.ushops_left
[0]; *ptr1
; ptr1
++)
3620 if (!index(u
.ushops
, *ptr1
))
3626 check_special_room(newlev
)
3627 register boolean newlev
;
3629 register struct monst
*mtmp
;
3632 move_update(newlev
);
3635 u_left_shop(u
.ushops_left
, newlev
);
3637 if (!*u
.uentered
&& !*u
.ushops_entered
) /* implied by newlev */
3638 return; /* no entrance messages necessary */
3640 /* Did we just enter a shop? */
3641 if (*u
.ushops_entered
)
3642 u_entered_shop(u
.ushops_entered
);
3644 for (ptr
= &u
.uentered
[0]; *ptr
; ptr
++) {
3645 register int roomno
= *ptr
- ROOMOFFSET
, rt
= rooms
[roomno
].rtype
;
3647 /* Did we just enter some other special room? */
3648 /* vault.c insists that a vault remain a VAULT,
3649 * and temples should remain TEMPLEs,
3650 * but everything else gives a message only the first time */
3651 /* edit by Amy - removed that stupidity. Why the heck would a swamp turn into an ordinary room???
3652 * Besides, I _like_ ambient level messages! They can be anything from soothing to terrifying!
3653 * There's no reason to get rid of them if you enter a room, and it's OK to get a message every time, too. */
3656 /* "Special Room monster change. Entering a special room will no longer awaken all monsters inside of the room, making the behavior the same as Vanilla Nethack and Slash'EM. Removed wake_nearby, gets really annoying" In Soviet Russia, players want to be able to mindlessly slaughter all the denizens of special rooms, because they're somehow unable to handle a game posing an actual challenge. They don't view it as too easy if they can hack up one monster after the other without the remaining ones even reacting or doing anything. But of course we all know that this is not the way it's supposed to be, so for all the other races the monsters will wake up. --Amy
3657 * edit: do the wake_nearby only if there are monsters in the room, because they're the reason why we're
3658 * doing it at all: to make sure that you can't simply kill the sleeping monsters. If there's no monsters
3659 * in the room anyway, we have no need to wake up monsters somewhere else on the level! */
3662 pline(FunnyHallu
? "Welcome to our Theme Park!" : "Welcome to David's treasure zoo!");
3663 if (!issoviet
&& anymonstinroom(roomno
)) wake_nearby();
3666 pline("It %s rather %s down here.",
3667 Blind
? "feels" : "looks",
3668 Blind
? "humid" : "muddy");
3669 if (!issoviet
&& anymonstinroom(roomno
)) wake_nearby();
3672 You(FunnyHallu
? "enter the Queen's chambers!" : "enter an opulent throne room!");
3673 if (!issoviet
&& anymonstinroom(roomno
)) wake_nearby();
3676 You(FunnyHallu
? "feel that some extinct species might still live here!" : "enter a smelly zoo!");
3677 if (!issoviet
&& anymonstinroom(roomno
)) wake_nearby();
3680 You(FunnyHallu
? "enter a real huge hall!" : "enter a giant throne room!");
3681 if (!issoviet
&& anymonstinroom(roomno
)) wake_nearby();
3684 You(FunnyHallu
? "enter a fairy lair!" : "enter a dragon lair...");
3685 if (!issoviet
&& anymonstinroom(roomno
)) wake_nearby();
3688 You(FunnyHallu
? "enter some sort of market! Perhaps you can buy some weed here?" : "enter an abandoned store...");
3689 if (!issoviet
&& anymonstinroom(roomno
)) wake_nearby();
3692 You(FunnyHallu
? "encounter a Stonehenge replica!" : "enter a leprechaun hall!");
3693 if (!issoviet
&& anymonstinroom(roomno
)) wake_nearby();
3697 const char *run
= locomotion(youmonst
.data
, "Run");
3698 pline("%s away! %s away!", run
, run
);
3700 { You("have an uncanny feeling..."); }
3701 if (!issoviet
&& anymonstinroom(roomno
)) wake_nearby();
3704 You(FunnyHallu
? "enter a tracker jacker nest! RUN AWAY!!!" : "enter a giant beehive!");
3705 if (!issoviet
&& anymonstinroom(roomno
)) wake_nearby();
3708 You(FunnyHallu
? "enter the Devil's Lair!" : "enter a pit of screaming lemures!");
3709 if (!issoviet
&& anymonstinroom(roomno
)) wake_nearby();
3712 You(FunnyHallu
? "enter some futuristic alien structure!" : "enter a strange hive!");
3713 if (!issoviet
&& anymonstinroom(roomno
)) wake_nearby();
3716 You(FunnyHallu
? "enter a sticky, slimy room..." : "enter a room full of fungi!");
3717 if (!issoviet
&& anymonstinroom(roomno
)) wake_nearby();
3720 You(FunnyHallu
? "sense the well-known smell of weed as you enter this room!" : "enter a disgusting nest!");
3721 if (!issoviet
&& anymonstinroom(roomno
)) wake_nearby();
3724 You(FunnyHallu
? "enter a room filled with bugs!" : "enter an anthole!");
3725 if (!issoviet
&& anymonstinroom(roomno
)) wake_nearby();
3728 You(FunnyHallu
? "feel reminded of 'Emergency Room' as you enter this area!" : "enter a modern hospital.");
3729 if (!issoviet
&& anymonstinroom(roomno
)) wake_nearby();
3732 You(FunnyHallu
? "see the gods as you enter! WOW! So that's what they look like..." : "enter a radiating hall of Angels!");
3733 if (!issoviet
&& anymonstinroom(roomno
)) wake_nearby();
3736 You(FunnyHallu
? "feel like you just got detected by a tripwire!" : "enter a terrifying hall.");
3737 if (!issoviet
&& anymonstinroom(roomno
)) wake_nearby();
3740 You(FunnyHallu
? "have died. Do you want your possessions identified? [ynq] (n) _" : "enter a killer room! This is actually an ADOM tension room.");
3741 if (!issoviet
&& anymonstinroom(roomno
)) wake_nearby();
3744 You(FunnyHallu
? "get a vision of Mother Nature as you enter!" : "enter a room full of elementals!");
3745 if (!issoviet
&& anymonstinroom(roomno
)) wake_nearby();
3748 You(FunnyHallu
? "see a picture on the wall of this room. It shows the most beautiful woman you ever saw..." : "enter a beautiful garden!");
3749 if (!issoviet
&& anymonstinroom(roomno
)) wake_nearby();
3752 You(FunnyHallu
? "enter some old weapon storage chamber! Let's see what weapons are left!" : "enter a dilapidated armory.");
3753 if (!issoviet
&& anymonstinroom(roomno
)) wake_nearby();
3756 You(FunnyHallu
? "enter a room full of treasure, and it's all going to be yours! YEAH!" : "enter a room filled with money!");
3757 if (!issoviet
&& anymonstinroom(roomno
)) wake_nearby();
3760 You(FunnyHallu
? "feel that this room smells like a public toilet!" : "enter a room full of stinking trolls...");
3761 if (!issoviet
&& anymonstinroom(roomno
)) wake_nearby();
3764 You(FunnyHallu
? "encounter a party room! Let's invite some hot girls!" : "encounter a living room!");
3765 if (!issoviet
&& anymonstinroom(roomno
)) wake_nearby();
3768 You(FunnyHallu
? "notice spiders of all forms and sizes in this room sitting everywhere!" : "stumble into a nest of spiders...");
3769 if (!issoviet
&& anymonstinroom(roomno
)) wake_nearby();
3772 You(FunnyHallu
? "encounter some warmeches!" : "enter a room full of golems!");
3773 if (!issoviet
&& anymonstinroom(roomno
)) wake_nearby();
3776 if (wizard
) You("enter a trapped room!");
3779 if (wizard
) You("enter an empty nest!");
3782 if (wizard
) You("enter a pool room!");
3785 if (wizard
) You("enter a statue room!");
3788 if (wizard
) You("enter a nasty central!");
3791 You(FunnyHallu
? "enter a normal-looking room." : "enter a weird-looking room...");
3792 if (!issoviet
&& anymonstinroom(roomno
)) wake_nearby();
3795 You(FunnyHallu
? "encounter an underground mountain! Wait, what? This makes no sense!" : "encounter an underground river!");
3796 if (!issoviet
&& anymonstinroom(roomno
)) wake_nearby();
3799 pline(FunnyHallu
? "It is radiant bright. You are likely to be eaten by the sun." : "It is pitch black. You are likely to be eaten by a grue.");
3800 do_clear_areaX(u
.ux
,u
.uy
, /* extra darkness --Amy */
3801 15, set_litX
, (void *)((char *)0));
3802 /* IMHO grue rooms may remove light every time you enter them. --Amy */
3803 if (!issoviet
&& anymonstinroom(roomno
)) wake_nearby();
3806 You(FunnyHallu
? "forgot to bring your light source and can't see anything in this room." : "enter the dark crypts!");
3807 if (!issoviet
&& anymonstinroom(roomno
)) wake_nearby();
3810 You(FunnyHallu
? "got tons of trouble, baby!" : "enter the trouble zone!");
3811 if (!issoviet
&& anymonstinroom(roomno
)) wake_nearby();
3814 You(FunnyHallu
? "see people with long pointy sticks who want to impale you!" : "enter a weapons chamber!");
3815 if (!issoviet
&& anymonstinroom(roomno
)) wake_nearby();
3818 pline(FunnyHallu
? "Gee, this looks exactly like the realms of Oblivion!" : "You enter the fiery pits of Hell!");
3819 if (!issoviet
&& anymonstinroom(roomno
)) wake_nearby();
3822 You(FunnyHallu
? "enter a room full of girls in sexy bikinis and high-heeled leather boots! WOW!" : "enter a feminist meeting room!");
3823 if (!issoviet
&& anymonstinroom(roomno
)) wake_nearby();
3826 You(FunnyHallu
? "stumble into a ranch! Where's the cowboys and horses?" : "encounter a cattle meadow!");
3827 if (!issoviet
&& anymonstinroom(roomno
)) wake_nearby();
3829 case COOLINGCHAMBER
:
3830 You(FunnyHallu
? "entered the radiator area!" : "freeze as you enter the cooling chamber.");
3831 if (!issoviet
&& anymonstinroom(roomno
)) wake_nearby();
3834 pline(FunnyHallu
? "Your body warps strangely and you cease to exist... Do you want your possessions identified? [ynq] (n) _" : "You entered the Void!");
3835 if (!issoviet
&& anymonstinroom(roomno
)) wake_nearby();
3838 pline(FunnyHallu
? "This room looks not dangerous at all." : "You've stumbled over a tiny hamlet!");
3839 if (Role_if(PM_SPACEWARS_FIGHTER
) || Role_if(PM_CAMPERSTRIKER
)) {
3840 pline(FunnyHallu
? "You feel that you've seen this before... it reminds you of the Woodstock Festival!" : "It looks familiar... didn't your adventures usually start in a similar place?");
3843 if (!issoviet
&& anymonstinroom(roomno
)) wake_nearby();
3846 pline(FunnyHallu
? "As you enter the heavily guarded army base, bullets start flying in your direction! TAKE COVER!" : "You've entered the local police station!");
3847 if (!issoviet
&& anymonstinroom(roomno
)) wake_nearby();
3850 You(FunnyHallu
? "were fated to die here. DIE!" : "feel that you will meet your fate here.");
3851 if (!issoviet
&& anymonstinroom(roomno
)) wake_nearby();
3854 You(FunnyHallu
? "enter a room that looks like it was designed by God Himself!" : "enter the Random Number Generator central!");
3855 if (!issoviet
&& anymonstinroom(roomno
)) wake_nearby();
3858 You(FunnyHallu
? "disturbed some old wizened fool that lives here, and now you have to kill that stupid git!" : "entered a wizard's dormitory!");
3859 if (!issoviet
&& anymonstinroom(roomno
)) wake_nearby();
3861 case DOOMEDBARRACKS
:
3862 You(FunnyHallu
? "realize that the game has turned into DoomRL! Quick, ready your kalashnikov and BFG!" : "enter an alien barracks!");
3863 if (!issoviet
&& anymonstinroom(roomno
)) wake_nearby();
3866 pline(FunnyHallu
? "I heard you were sleeping there." : "You stumble into a sleeping room!");
3867 if (!issoviet
&& anymonstinroom(roomno
)) wake_nearby();
3870 You(FunnyHallu
? "enter a huge swimming pool, and the entrance is free! YEAH! Now you can splash around in the water and have many hours of pure FUN!" : "encounter the diver's paradise!");
3871 if (!issoviet
&& anymonstinroom(roomno
)) wake_nearby();
3874 You(FunnyHallu
? "enter a zoo filled with prehistoric animals! Err... I really hope they're peaceful!" : "enter a menagerie!");
3875 if (!issoviet
&& anymonstinroom(roomno
)) wake_nearby();
3878 pline(FunnyHallu
? "This looks like the Shifting Sand Land from Super Mario 64!" : "The air in this room is hot and arid.");
3881 pline(FunnyHallu
? "It's the dungeon master's rarity collection! Quick, steal it before he turns up!" : "You enter a room filled with rare creatures!");
3882 if (!issoviet
&& anymonstinroom(roomno
)) wake_nearby();
3885 pline(FunnyHallu
? "Oh, look at all the zoo exhibits! Can I feed them? Can I pet them? Mind if I incinerate them?" : "You encounter an exhibit of strange creatures!");
3886 if (!issoviet
&& anymonstinroom(roomno
)) wake_nearby();
3889 pline(FunnyHallu
? "Go directly to jail. Do not pass go. Do not collect 200 zorkmids." : "You enter a prison!");
3890 if (FunnyHallu
) pline("Do you want your possessions identified? [ynq] (n) _");
3891 if (!issoviet
&& anymonstinroom(roomno
)) wake_nearby();
3893 case NUCLEARCHAMBER
:
3894 pline(FunnyHallu
? "It's where the government is researching weaponized uranium! If you can steal their technology, you can nuke the entire dungeon and ascend prematurely!" : "You encounter a nuclear power plant!");
3895 if (!issoviet
&& anymonstinroom(roomno
)) wake_nearby();
3898 pline(FunnyHallu
? "Are the people in here celebrating a corona party? Call the police! They're spreading the virus!" : "Apparently a rival gang of adventurers has set up camp here!");
3899 if (!issoviet
&& anymonstinroom(roomno
)) wake_nearby();
3901 case LEVELSEVENTYROOM
: /* no message but still wake_nearby --Amy */
3902 if (wizard
) You("enter a level 70 room!");
3903 if (!issoviet
&& anymonstinroom(roomno
)) wake_nearby();
3906 pline(FunnyHallu
? "The game suddenly turned into dnethack. The elder priest tentacles to tentacle you! Your cloak of magic resistance disintegrates!" : "You encounter a room from another variant!");
3907 if (!issoviet
&& anymonstinroom(roomno
)) wake_nearby();
3910 pline(FunnyHallu
? "Oh my god, Amy's fanfics have come true!" : "You enter the robbers' hideout!");
3911 if (!issoviet
&& anymonstinroom(roomno
)) wake_nearby();
3914 pline(FunnyHallu
? "As you enter the room, your head starts to ring like a slot machine!" : "You enter a casino!");
3916 case SANITATIONCENTRAL
:
3917 pline(FunnyHallu
? "Muahahahahaha, you feel like focusing your gaze on a great race of yith because who needs sanity anyway?" : "Something seems to focus on your mind as you enter this room.");
3918 if (!issoviet
&& anymonstinroom(roomno
)) wake_nearby();
3922 if(anymonstinroom(roomno
)) {
3923 You("enter a military barracks!");
3925 You("enter an abandoned barracks.");
3927 if (!issoviet
&& anymonstinroom(roomno
)) wake_nearby();
3930 if(monstinroom(&mons
[PM_ORACLE
], roomno
))
3931 verbalize("%s, %s, welcome to Delphi!", Hello((struct monst
*) 0), playeraliasname
);
3932 if (!issoviet
&& anymonstinroom(roomno
)) wake_nearby();
3936 if (!issoviet
&& anymonstinroom(roomno
)) wake_nearby();
3939 pline(FunnyHallu
? "Eek, you've stumbled into a SJW meeting!" : "The feel of this room is giving you the creeps.");
3940 if (!issoviet
&& anymonstinroom(roomno
)) wake_nearby();
3942 case RELIGIONCENTER
:
3943 pline(FunnyHallu
? "Ugh, an overwhelming cancerous stench floods your nostrils as you enter this room!" : "This room smells like rotten holy water.");
3944 if (!issoviet
&& anymonstinroom(roomno
)) wake_nearby();
3946 case CURSEDMUMMYROOM
:
3947 pline(FunnyHallu
? "You entered the Pharao's chambers!" : "Things that should be dead are walking this room.");
3948 if (!issoviet
&& anymonstinroom(roomno
)) wake_nearby();
3950 case ARDUOUSMOUNTAIN
:
3951 pline(FunnyHallu
? "You encounter an underground mountain. Wait, why the hell is there a mountain in the dungeon???" : "You encounter an underground mountain.");
3952 if (!issoviet
&& anymonstinroom(roomno
)) wake_nearby();
3955 pline(FunnyHallu
? "Boah, it's THE area! And there's a pentagram in the center!" : "This room reminds you of your heritage.");
3956 if (!issoviet
&& anymonstinroom(roomno
)) wake_nearby();
3959 pline(FunnyHallu
? "It's the womens locker room! Quick, quaff a potion of make invisible!" : "Seems like you entered a changing room.");
3960 if (!issoviet
&& anymonstinroom(roomno
)) wake_nearby();
3963 pline(FunnyHallu
? "You entered your insufferable boss's office! Make sure that he doesn't see the knife you're holding in one hand behind your back." : "Uh-oh, your superiors are waiting for you in this room, and they don't seem to be pleased with your work.");
3964 if (!issoviet
&& anymonstinroom(roomno
)) wake_nearby();
3967 pline(FunnyHallu
? "Hey, this room looks just like your own living room!" : "This room looks familiar, but somehow different too.");
3968 if (!issoviet
&& anymonstinroom(roomno
)) wake_nearby();
3971 pline(FunnyHallu
? "Oh great, you entered a room full of shit." : "The air in this room is rank with mildew.");
3972 if (!issoviet
&& anymonstinroom(roomno
)) wake_nearby();
3975 if (wizard
) pline("You enter a chaos room!");
3977 case LETTERSALADROOM
:
3978 if (!issoviet
&& anymonstinroom(roomno
)) wake_nearby();
3979 if (wizard
) pline("You enter a letter salad room!");
3982 if (wizard
) pline("You enter a full room!");
3985 if (wizard
) pline("You enter a rampage room!");
3988 if (wizard
) pline("You enter a mixed pool!");
3991 pline(FunnyHallu
? "Whoa, this room totally smells of ammonia!" : "As you enter the room, you can hear Mira inviting you for a swim.");
3992 if (!issoviet
&& anymonstinroom(roomno
)) wake_nearby();
3995 pline(FunnyHallu
? "It's the inside of the Space Shuttle!" : "You enter a machinery room.");
3996 if (uarmf
&& itemhasappearance(uarmf
, APP_MACHINERY_BOOTS
) && !u
.uspellprot
) {
3999 if (!u
.usptime
) u
.usptime
= u
.uspmtime
;
4002 You_feel("at home here, thanks to your machinery boots!");
4004 if (uarmf
&& uarmf
->oartifact
== ART_PERMINANT_INCREASE
&& u
.ublessed
< 4) {
4005 if (!(HProtection
& INTRINSIC
)) HProtection
|= FROMOUTSIDE
;
4009 pline("A holy aura of protection surrounds you!");
4011 if (!issoviet
&& anymonstinroom(roomno
)) wake_nearby();
4014 pline(FunnyHallu
? "Wow! You seem to have found the Niagara Falls!" : "You enter the shower.");
4016 case GREENCROSSROOM
:
4017 pline(FunnyHallu
? "Entering this room feels like being put in headlock by your wonderful fleecy roommate!" : "This room has a very peaceful atmosphere.");
4020 pline(FunnyHallu
? "You enter Satan's chamber! Quick, ask him what is inferior to SLEX!" : "You enter a desecrated church.");
4021 if (!issoviet
&& anymonstinroom(roomno
)) wake_nearby();
4024 pline(FunnyHallu
? "You've entered the local Game Stop store! The storeclerk says: 'Hello sir or miss, what can I do for you? I have GTA 5, the newest Call of Duty and of course also the latest Pokemon generation games available!'" : "You encounter a game corner!");
4025 if (!issoviet
&& anymonstinroom(roomno
)) wake_nearby();
4028 pline(FunnyHallu
? "This room is an illusion and a trap devisut by Satan. Go ahead dauntlessly! Make rapid progres!" : "Somehow, this room doesn't seem to be what it looks like.");
4029 if (!issoviet
&& anymonstinroom(roomno
)) wake_nearby();
4032 pline(FunnyHallu
? "It's the Straight Road! In order to get through this room, you need to stay on the road at all times and be fast or the Straight Road will weaken and ultimately be destroyed!" : "You encounter a highway to the left.");
4035 intemple(roomno
+ ROOMOFFSET
);
4042 /*rooms[roomno].rtype = OROOM;*/
4043 /*if (!search_special(rt)) {*/
4044 /* No more room of that type */
4048 level.flags.has_court = 0;
4051 level.flags.has_swamp = 0;
4054 level.flags.has_morgue = 0;
4058 level.flags.has_zoo = 0;
4061 level.flags.has_barracks = 0;
4064 level.flags.has_clinic = 0;
4067 level.flags.has_mimichall = 0;
4070 level.flags.has_angelhall = 0;
4073 level.flags.has_terrorhall = 0;
4076 level.flags.has_tenshall = 0;
4079 level.flags.has_elemhall = 0;
4082 level.flags.has_nymphhall = 0;
4085 level.flags.has_golemhall = 0;
4088 level.flags.has_traproom = 0;
4091 level.flags.has_grueroom = 0;
4094 level.flags.has_cryptroom = 0;
4097 level.flags.has_troublezone = 0;
4100 level.flags.has_weaponchamber = 0;
4103 level.flags.has_hellpit = 0;
4106 level.flags.has_robbercave = 0;
4109 level.flags.has_casinoroom = 0;
4111 case SANITATIONCENTRAL:
4112 level.flags.has_sanitationcentral = 0;
4115 level.flags.has_feminismroom = 0;
4118 level.flags.has_meadowroom = 0;
4120 case COOLINGCHAMBER:
4121 level.flags.has_coolingchamber = 0;
4124 level.flags.has_voidroom = 0;
4127 level.flags.has_armory = 0;
4130 level.flags.has_hamletroom = 0;
4133 level.flags.has_kopstation = 0;
4136 level.flags.has_bossroom = 0;
4139 level.flags.has_rngcenter = 0;
4142 level.flags.has_wizardsdorm = 0;
4144 case DOOMEDBARRACKS:
4145 level.flags.has_doomedbarracks = 0;
4148 level.flags.has_sleepingroom = 0;
4151 level.flags.has_diverparadise = 0;
4154 level.flags.has_menagerie = 0;
4157 level.flags.has_nastycentral = 0;
4160 level.flags.has_emptydesert = 0;
4163 level.flags.has_rarityroom = 0;
4166 level.flags.has_exhibitroom = 0;
4169 level.flags.has_prisonchamber = 0;
4171 case NUCLEARCHAMBER:
4172 level.flags.has_nuclearchamber = 0;
4174 case LEVELSEVENTYROOM:
4175 level.flags.has_levelseventyroom = 0;
4178 level.flags.has_playercentral = 0;
4181 level.flags.has_variantroom = 0;
4184 level.flags.has_poolroom = 0;
4187 level.flags.has_statueroom = 0;
4190 level.flags.has_insideroom = 0;
4193 level.flags.has_riverroom = 0;
4196 level.flags.has_humanhall = 0;
4199 level.flags.has_coinhall = 0;
4202 level.flags.has_trollhall = 0;
4205 level.flags.has_spiderhall = 0;
4208 level.flags.has_temple = 0;
4211 level.flags.has_beehive = 0;
4214 level.flags.has_lemurepit = 0;
4217 level.flags.has_migohive = 0;
4220 level.flags.has_fungusfarm = 0;
4223 level.flags.has_evilroom = 0;
4225 case RELIGIONCENTER:
4226 level.flags.has_religioncenter = 0;
4228 case CURSEDMUMMYROOM:
4229 level.flags.has_cursedmummyroom = 0;
4231 case ARDUOUSMOUNTAIN:
4232 level.flags.has_arduousmountain = 0;
4235 level.flags.has_levelffroom = 0;
4238 level.flags.has_verminroom = 0;
4241 level.flags.has_miraspa = 0;
4244 level.flags.has_machineroom = 0;
4247 level.flags.has_showerroom = 0;
4249 case GREENCROSSROOM:
4250 level.flags.has_greencrossroom = 0;
4253 level.flags.has_ruinedchurch = 0;
4256 level.flags.has_gamecorner = 0;
4259 level.flags.has_illusionroom = 0;
4263 if(rt
==COURT
|| rt
==SWAMP
|| rt
==MORGUE
|| rt
==ZOO
|| (rt
&& !rn2(10)) )
4264 for(mtmp
= fmon
; mtmp
; mtmp
= mtmp
->nmon
)
4265 if (!DEADMONSTER(mtmp
) && (!Stealth
|| Aggravate_monster
) && !rn2(3)) mtmp
->msleeping
= 0;
4279 struct trap
*traphere
= t_at(u
.ux
, u
.uy
);
4280 /* awful kludge to work around parse()'s pre-decrement */
4281 count
= (multi
|| (save_cm
&& *save_cm
== ',')) ? multi
+ 1 : 0;
4282 multi
= 0; /* always reset */
4283 /* uswallow case added by GAN 01/29/87 */
4285 if (!u
.ustuck
->minvent
) {
4286 if (is_animal(u
.ustuck
->data
)) {
4287 You("pick up %s tongue.",
4288 s_suffix(mon_nam(u
.ustuck
)));
4289 pline("But it's kind of slimy, so you drop it.");
4291 You("don't %s anything in here to pick up.",
4292 Blind
? "feel" : "see");
4295 int tmpcount
= -count
;
4296 return loot_mon(u
.ustuck
, &tmpcount
, (boolean
*)0);
4299 if((is_waterypool(u
.ux
, u
.uy
) || is_watertunnel(u
.ux
, u
.uy
) || is_moorland(u
.ux
, u
.uy
) || is_urinelake(u
.ux
, u
.uy
)) && !(is_crystalwater(u
.ux
, u
.uy
)) ) {
4300 if (Wwalking
|| Race_if(PM_KORONST
) || is_floater(youmonst
.data
) || is_clinger(youmonst
.data
)
4301 || (Flying
&& !(uarmf
&& uarmf
->oartifact
== ART_DIP_DIVE
) && !StrongFlying
&& !Breathless
&& !Swimming
)) {
4302 You("cannot dive into the water to pick things up.");
4304 } else if (!Underwater
&& !(uarmf
&& uarmf
->oartifact
== ART_DIP_DIVE
) && !Swimming
&& !StrongFlying
) {
4305 You_cant("even see the bottom, let alone pick up %s.",
4310 if (is_lava(u
.ux
, u
.uy
)) {
4311 if (Wwalking
|| Race_if(PM_KORONST
) || is_floater(youmonst
.data
) || is_clinger(youmonst
.data
)
4312 || (Flying
&& !(uarmf
&& uarmf
->oartifact
== ART_DIP_DIVE
) && !StrongFlying
&& !Breathless
)) {
4313 You_cant("reach the bottom to pick things up.");
4315 } else if (!likes_lava(youmonst
.data
) && !FireImmunity
&& !(uarmf
&& itemhasappearance(uarmf
, APP_HOT_BOOTS
) ) && !(uwep
&& uwep
->oartifact
== ART_EVERYTHING_MUST_BURN
) && !(uamul
&& uamul
->otyp
== AMULET_OF_D_TYPE_EQUIPMENT
) && !(uarmf
&& uarmf
->oartifact
== ART_DIP_DIVE
) && !Race_if(PM_PLAYER_SALAMANDER
) && !(uwep
&& uwep
->oartifact
== ART_MANUELA_S_PRACTICANT_TERRO
) && !(powerfulimplants() && uimplant
&& uimplant
->oartifact
== ART_RUBBER_SHOALS
) && !(uarm
&& uarm
->oartifact
== ART_LAURA_CROFT_S_BATTLEWEAR
) && !(uarmc
&& uarmc
->oartifact
== ART_SCOOBA_COOBA
) && !(uarm
&& uarm
->oartifact
== ART_D_TYPE_EQUIPMENT
) && !(uarmf
&& uarmf
->oartifact
== ART_JOHANNA_S_RED_CHARM
) ) {
4316 You("would burn to a crisp trying to pick things up.");
4320 if(!OBJ_AT(u
.ux
, u
.uy
)) {
4321 There("is nothing here to pick up.");
4324 if (!can_reach_floor()) {
4325 if (u
.usteed
&& !(uwep
&& uwep
->oartifact
== ART_SORTIE_A_GAUCHE
) && !(powerfulimplants() && uimplant
&& uimplant
->oartifact
== ART_READY_FOR_A_RIDE
) && !FemtrapActiveKerstin
&& !(bmwride(ART_DEEPER_LAID_BMW
)) && (PlayerCannotUseSkills
|| P_SKILL(P_RIDING
) < P_BASIC
) )
4326 You("aren't skilled enough to reach from %s.",
4327 y_monnam(u
.usteed
));
4329 You("cannot reach the %s.", surface(u
.ux
,u
.uy
));
4333 if (traphere
&& traphere
->tseen
) {
4334 /* Allow pickup from holes and trap doors that you escaped from
4335 * because that stuff is teetering on the edge just like you, but
4336 * not pits, because there is an elevation discrepancy with stuff
4339 /* [BarclayII] phasing or flying players can phase/fly into the pit */
4340 if ((traphere
->ttyp
== PIT
|| traphere
->ttyp
== SPIKED_PIT
|| traphere
->ttyp
== GIANT_CHASM
|| traphere
->ttyp
== SHIT_PIT
|| traphere
->ttyp
== MANA_PIT
|| traphere
->ttyp
== ANOXIC_PIT
|| traphere
->ttyp
== HYPOXIC_PIT
|| traphere
->ttyp
== ACID_PIT
) &&
4341 (!u
.utrap
|| (u
.utrap
&& u
.utraptype
!= TT_PIT
)) && !Passes_walls
&& !Flying
) {
4342 You("cannot reach the bottom of the pit.");
4347 return (pickup(-count
));
4353 /* stop running if we see something interesting */
4354 /* turn around a corner if that is the only way we can proceed */
4355 /* do not turn left or right twice */
4359 register int x
, y
, i
, x0
= 0, y0
= 0, m0
= 1, i0
= 9;
4360 register int corrct
= 0, noturn
= 0;
4361 register struct monst
*mtmp
;
4362 register struct trap
*trap
;
4364 /* Grid bugs stop if trying to move diagonal, even if blind. Maybe */
4365 /* they polymorphed while in the middle of a long move. */
4366 if ((BishopGridbug
|| u
.uprops
[BISHOP_GRIDBUG
].extrinsic
|| have_bishopstone() || (uarmg
&& uarmg
->oartifact
== ART_LINE_CAN_PLAY_BY_YOURSELF
) || autismweaponcheck(ART_KILLER_PIANO
) || isgridbug(youmonst
.data
) || (Race_if(PM_WEAPON_BUG
) && !Upolyd
))&& u
.dx
&& u
.dy
) {
4371 if(Blind
|| flags
.run
== 0) return;
4372 for(x
= u
.ux
-1; x
<= u
.ux
+1; x
++) for(y
= u
.uy
-1; y
<= u
.uy
+1; y
++) {
4373 if(!isok(x
,y
)) continue;
4375 if((BishopGridbug
|| u
.uprops
[BISHOP_GRIDBUG
].extrinsic
|| have_bishopstone() || (uarmg
&& uarmg
->oartifact
== ART_LINE_CAN_PLAY_BY_YOURSELF
) || autismweaponcheck(ART_KILLER_PIANO
) || isgridbug(youmonst
.data
) || (Race_if(PM_WEAPON_BUG
) && !Upolyd
)) && x
!= u
.ux
&& y
!= u
.uy
) continue;
4377 if(x
== u
.ux
&& y
== u
.uy
) continue;
4379 if((mtmp
= m_at(x
,y
)) &&
4380 mtmp
->m_ap_type
!= M_AP_FURNITURE
&&
4381 mtmp
->m_ap_type
!= M_AP_OBJECT
&&
4382 (!mtmp
->minvis
|| (See_invisible
&& (StrongSee_invisible
|| mtmp
->seeinvisble
) ) ) && !mtmp
->minvisreal
&& !mtmp
->mundetected
) {
4383 if((flags
.run
!= 1 && !mtmp
->mtame
)
4384 || (x
== u
.ux
+u
.dx
&& y
== u
.uy
+u
.dy
))
4388 if (levl
[x
][y
].typ
== STONE
) continue;
4389 if (x
== u
.ux
-u
.dx
&& y
== u
.uy
-u
.dy
) continue;
4391 if (IS_ROCK(levl
[x
][y
].typ
) || (levl
[x
][y
].typ
== ROOM
) ||
4392 IS_AIR(levl
[x
][y
].typ
))
4394 else if (closed_door(x
,y
) ||
4395 (mtmp
&& mtmp
->m_ap_type
== M_AP_FURNITURE
&&
4396 (mtmp
->mappearance
== S_hcdoor
||
4397 mtmp
->mappearance
== S_vcdoor
))) {
4398 if(x
!= u
.ux
&& y
!= u
.uy
) continue;
4399 if(flags
.run
!= 1) goto stop
;
4401 } else if (levl
[x
][y
].typ
== CORR
) {
4403 if(levl
[u
.ux
][u
.uy
].typ
!= ROOM
) {
4404 if(flags
.run
== 1 || flags
.run
== 3 || flags
.run
== 8) {
4405 i
= dist2(x
,y
,u
.ux
+u
.dx
,u
.uy
+u
.dy
);
4407 if(corrct
== 1 && dist2(x
,y
,x0
,y0
) != 1)
4419 } else if ((trap
= t_at(x
,y
)) && trap
->tseen
) {
4420 if(flags
.run
== 1) goto bcorr
; /* if you must */
4421 if(x
== u
.ux
+u
.dx
&& y
== u
.uy
+u
.dy
) goto stop
;
4423 } else if (is_waterypool(x
,y
) || is_watertunnel(x
,y
) || is_urinelake(x
,y
) || is_shiftingsand(x
,y
) || is_moorland(x
,y
) || is_lava(x
,y
)) {
4424 /* water and lava only stop you if directly in front, and stop
4425 * you even if you are running
4427 /* KMH, balance patch -- new intrinsic */
4428 if(!Levitation
&& !Flying
&& !is_clinger(youmonst
.data
) &&
4429 x
== u
.ux
+u
.dx
&& y
== u
.uy
+u
.dy
)
4430 /* No Wwalking check; otherwise they'd be able
4431 * to test boots by trying to SHIFT-direction
4432 * into a pool and seeing if the game allowed it
4436 } else { /* e.g. objects or trap or stairs */
4437 if(flags
.run
== 1) goto bcorr
;
4438 if(flags
.run
== 8) continue;
4439 if(mtmp
) continue; /* d */
4440 if(((x
== u
.ux
- u
.dx
) && (y
!= u
.uy
+ u
.dy
)) ||
4441 ((y
== u
.uy
- u
.dy
) && (x
!= u
.ux
+ u
.dx
)))
4447 } /* end for loops */
4449 if(corrct
> 1 && flags
.run
== 2) goto stop
;
4450 if((flags
.run
== 1 || flags
.run
== 3 || flags
.run
== 8) &&
4451 !noturn
&& !m0
&& i0
&& (corrct
== 1 || (corrct
== 2 && i0
== 1)))
4453 /* make sure that we do not turn too far */
4455 if(u
.dx
== y0
-u
.uy
&& u
.dy
== u
.ux
-x0
)
4456 i
= 2; /* straight turn right */
4458 i
= -2; /* straight turn left */
4459 } else if(u
.dx
&& u
.dy
) {
4460 if((u
.dx
== u
.dy
&& y0
== u
.uy
) || (u
.dx
!= u
.dy
&& y0
!= u
.uy
))
4461 i
= -1; /* half turn left */
4463 i
= 1; /* half turn right */
4465 if((x0
-u
.ux
== y0
-u
.uy
&& !u
.dy
) || (x0
-u
.ux
!= y0
-u
.uy
&& u
.dy
))
4466 i
= 1; /* half turn right */
4468 i
= -1; /* half turn left */
4471 i
+= u
.last_str_turn
;
4472 if(i
<= 2 && i
>= -2) {
4473 u
.last_str_turn
= i
;
4480 /* something like lookaround, but we are not running */
4481 /* react only to monsters that might hit us */
4486 register struct monst
*mtmp
;
4488 /* Also see the similar check in dochugw() in monmove.c */
4489 for(x
= u
.ux
-1; x
<= u
.ux
+1; x
++)
4490 for(y
= u
.uy
-1; y
<= u
.uy
+1; y
++) {
4491 if(!isok(x
,y
)) continue;
4492 if(x
== u
.ux
&& y
== u
.uy
) continue;
4493 if((mtmp
= m_at(x
,y
)) &&
4494 mtmp
->m_ap_type
!= M_AP_FURNITURE
&&
4495 mtmp
->m_ap_type
!= M_AP_OBJECT
&&
4496 (!mtmp
->mpeaceful
|| Hallucination
) &&
4497 ( (!is_hider(mtmp
->data
) && (!mtmp
->egotype_hide
) && (!mtmp
->egotype_mimic
) ) || !mtmp
->mundetected
) &&
4498 !noattacks(mtmp
->data
) &&
4499 mtmp
->mcanmove
&& !mtmp
->msleeping
&& /* aplvax!jcn */
4500 !onscary(u
.ux
, u
.uy
, mtmp
) &&
4510 /* from Elona: maybe emit a sound when you're hurt; this is especially useful if you have display loss --Amy
4511 * known issue: you might be in a form that cannot "scream", I decided that I don't care and you scream anyway :P */
4512 int painchance
= 10;
4513 int distresslevel
= 0;
4516 if (u
.mh
< (u
.mhmax
/ 4)) distresslevel
= 3;
4517 else if (u
.mh
< (u
.mhmax
/ 2)) distresslevel
= 2;
4518 else if (u
.mh
< (u
.mhmax
* 3 / 4)) distresslevel
= 1;
4521 if (u
.uhp
< (u
.uhpmax
/ 4)) distresslevel
= 3;
4522 else if (u
.uhp
< (u
.uhpmax
/ 2)) distresslevel
= 2;
4523 else if (u
.uhp
< (u
.uhpmax
* 3 / 4)) distresslevel
= 1;
4526 if ( (PainSense
&& !rn2(10)) || (StrongPainSense
&& !rn2(5)) || (painchance
< rnd(11)) ) {
4527 if (distresslevel
== 3) You("are severely hurt!");
4528 else if (distresslevel
== 2) You("writhe in pain.");
4529 else if (distresslevel
== 1) You("scream.");
4530 /* otherwise you haven't lost enough health yet */
4538 static short powers
[] = { TELEPORT
, SEE_INVIS
, POISON_RES
, COLD_RES
,
4539 SHOCK_RES
, FIRE_RES
, SLEEP_RES
, DISINT_RES
,
4540 TELEPORT_CONTROL
, STEALTH
, FAST
, INVIS
};
4542 if (moves
<= wailmsg
+ 50) return;
4545 if (Role_if(PM_WIZARD
) || Role_if(PM_CONVICT
) || Role_if(PM_COURIER
) || Role_if(PM_CAMPERSTRIKER
) || Role_if(PM_SPACEWARS_FIGHTER
) || Role_if(PM_WARRIOR
) || Role_if(PM_ELPH
) || Role_if(PM_TWELPH
) || Race_if(PM_ELF
) || Race_if(PM_ASGARDIAN
) || Race_if(PM_RODNEYAN
) || ishaxor
|| isheretic
|| Race_if(PM_ALBAE
) || Role_if(PM_VALKYRIE
) || Role_if(PM_VANILLA_VALK
)) {
4549 who
= (!rn2(10)) ? urace
.noun
:(Role_if(PM_WIZARD
) || Role_if(PM_CONVICT
) || Role_if(PM_COURIER
) || Role_if(PM_CAMPERSTRIKER
) || Role_if(PM_SPACEWARS_FIGHTER
) || Role_if(PM_WARRIOR
) || Role_if(PM_ELPH
) || Role_if(PM_TWELPH
) || Race_if(PM_ASGARDIAN
) || ishaxor
|| isheretic
|| Race_if(PM_ALBAE
) || Role_if(PM_VALKYRIE
) || Role_if(PM_VANILLA_VALK
)) ?
4550 urole
.name
.m
: Race_if(PM_RODNEYAN
) ? "Wizard of Yendor" : "Elf";
4552 pline("%s is about to die.", who
);
4554 for (i
= 0, powercnt
= 0; i
< SIZE(powers
); ++i
)
4555 if (u
.uprops
[powers
[i
]].intrinsic
& INTRINSIC
) ++powercnt
;
4557 pline(powercnt
>= 4 ? "%s, all your powers will be lost..."
4558 : "%s, your life force is running out.", who
);
4561 You_hear(u
.uhp
== 1 ? "the wailing of the Banshee..."
4562 : "the howling of the CwnAnnwn...");
4563 if (u
.uhp
== 1 && (PlayerHearsSoundEffects
)) pline(issoviet
? "Da! Umri, pozhaluysta! Ya nenavizhu tebya! Nadeyus', vy nastol'ko glupy, chtoby pozvolit' vse, chto chudovishche privelo vas k blizkoy smerti, chtoby snova udarit' tebya, a potom eto igra zakonchena GA GA GA!" : "SKRIIIIE-IIIIE-IIIIE-IIIIE-IIIIE!");
4564 else if (PlayerHearsSoundEffects
) pline(issoviet
? "Nadeyus', vy prodolzhat' deystvovat' tak glupo, potomu chto togda vy budete umirat' i pridetsya svernut' novyy kharakter. Eto budet sluzhit' vam pravil'no, vy plokhoy igrok!" : "Wueueueue-oooooooh!");
4568 u
.cnd_bansheecount
++;
4569 if (autismweaponcheck(ART_P_WING
)) {
4570 if (uwep
&& uwep
->spe
> -10) {
4572 pline("Powerup lost.");
4574 if (u
.twoweap
&& uswapwep
&& uswapwep
->oartifact
== ART_P_WING
&& uswapwep
->spe
> -10) uswapwep
->spe
= -10;
4577 u
.cnd_cwnannwncount
++;
4578 if (autismweaponcheck(ART_P_WING
)) {
4581 pline("Powerup degraded.");
4583 if (u
.twoweap
&& uswapwep
&& uswapwep
->oartifact
== ART_P_WING
) curse(uswapwep
);
4587 if (practicantterror
&& ((u
.cnd_bansheecount
+ u
.cnd_cwnannwncount
) >= 5)) {
4588 if (!u
.pract_cwnannwn
) {
4589 u
.pract_cwnannwn
= TRUE
;
4590 pline("%s rings out: 'It seems that you have a habit of getting into trouble. This is not how things run in this lab, maggot. Stop it or there'll be sanctions.'", noroelaname());
4592 int cwnannwnfine
= (u
.cnd_bansheecount
+ u
.cnd_cwnannwncount
) * 100;
4593 pline("%s thunders: 'I told you to stay away from trouble! That costs %d zorkmids.'", noroelaname(), cwnannwnfine
);
4594 fineforpracticant(cwnannwnfine
, 0, 0);
4602 nomul(nval
, txt
, discountpossible
)
4605 boolean discountpossible
;
4607 if (uarmc
&& uarmc
->oartifact
== ART_LIGHTSPEED_TRAVEL
&& nval
== 0) return;
4609 if (uarmf
&& nval
== 0 && itemhasappearance(uarmf
, APP_TURBO_BOOTS
) ) return;
4611 if (u
.katitrapocc
&& nval
== 0) {
4612 pline("Something tries to interrupt your attempt to clean the Kati shoes! If you stop now, the sexy girl will hate you!");
4613 if (yn("Really stop cleaning them?") == 'y') {
4614 register struct monst
*mtmp2
;
4616 for (mtmp2
= fmon
; mtmp2
; mtmp2
= mtmp2
->nmon
) {
4618 if (!mtmp2
->mtame
&& !is_infrastructure_monster(mtmp2
) ) {
4619 mtmp2
->mpeaceful
= 0;
4620 mtmp2
->mfrenzied
= 1;
4621 mtmp2
->mhp
= mtmp2
->mhpmax
;
4624 u
.katitrapocc
= FALSE
;
4625 pline("The beautiful girl in the sexy Kati shoes is very sad that you didn't finish cleaning her lovely boots, and urges everyone in her vicinity to bludgeon you.");
4630 if (u
.singtrapocc
&& nval
== 0) {
4631 pline("Something tries to interrupt your attempt to clean the female shoes! If you stop now, the sexy girl will hate you!");
4632 if (yn("Really stop cleaning them?") == 'y') {
4633 register struct monst
*mtmp2
;
4635 for (mtmp2
= fmon
; mtmp2
; mtmp2
= mtmp2
->nmon
) {
4637 if (!mtmp2
->mtame
&& !is_infrastructure_monster(mtmp2
) ) {
4638 mtmp2
->mpeaceful
= 0;
4639 mtmp2
->mfrenzied
= 1;
4640 mtmp2
->mhp
= mtmp2
->mhpmax
;
4643 u
.cnd_singrefused
++;
4644 u
.singtrapocc
= FALSE
;
4645 u
.singtraptreaded
= FALSE
;
4646 u
.singtraphighheel
= FALSE
;
4647 u
.singtrapcowdung
= FALSE
;
4648 pline("The beautiful girl in the sexy female shoes is very sad that you didn't finish cleaning her lovely footwear, and urges everyone in her vicinity to bludgeon you.");
4654 if(multi
< nval
) return; /* This is a bug fix by ab@unido */
4655 u
.uinvulnerable
= FALSE
; /* Kludge to avoid ctrl-C bug -dlc */
4658 if (PlayerInWedgeHeels
&& discountpossible
&& (nval
< -1)) {
4659 register int dmgreductor
= 90;
4660 if (!(PlayerCannotUseSkills
)) switch (P_SKILL(P_HIGH_HEELS
)) {
4661 case P_BASIC
: dmgreductor
= 88; break;
4662 case P_SKILLED
: dmgreductor
= 86; break;
4663 case P_EXPERT
: dmgreductor
= 84; break;
4664 case P_MASTER
: dmgreductor
= 82; break;
4665 case P_GRAND_MASTER
: dmgreductor
= 80; break;
4666 case P_SUPREME_MASTER
: dmgreductor
= 78; break;
4668 nval
*= dmgreductor
;
4671 if (nval
> -2) nval
= -2;
4674 if (PlayerInColumnarHeels
&& discountpossible
&& (nval
< -1)) {
4675 register int dmgreductor
= 100;
4676 if (u
.columnarskill
>= 20) dmgreductor
-= 10;
4677 if (u
.columnarskill
>= 160) dmgreductor
-= 10;
4678 if (u
.columnarskill
>= 540) dmgreductor
-= 10;
4679 if (u
.columnarskill
>= 1280) dmgreductor
-= 10;
4680 if (u
.columnarskill
>= 2500) dmgreductor
-= 10;
4681 if (u
.columnarskill
>= 4320) dmgreductor
-= 10;
4683 nval
*= dmgreductor
;
4686 if (nval
> -2) nval
= -2;
4690 if (irisartiboost() && discountpossible
&& (nval
< -1)) {
4691 register int dmgreductor
= 10;
4692 dmgreductor
-= irisartiboost();
4694 nval
*= dmgreductor
;
4697 if (nval
> -2) nval
= -2;
4700 if (discountpossible
&& (nval
< -2) && !rn2(10) && uarmf
&& itemhasappearance(uarmf
, APP_PLOF_HEELS
) ) {
4702 if (nval
> -2) nval
= -2;
4705 if (nval
< 0 && FemtrapActiveLara
&& !u
.laratraptimer
) {
4707 struct permonst
*pm
= 0;
4709 register struct monst
*laramon
;
4711 if (Aggravate_monster
) {
4713 reset_rndmonst(NON_PM
);
4720 if (attempts
&& (attempts
% 10000 == 0)) u
.mondiffhack
++;
4721 if (!rn2(2000)) reset_rndmonst(NON_PM
);
4723 } while ( (!pm
|| (pm
&& !(treadedshoemonster(pm
) && highheeledshoemonster(pm
)) )) && attempts
< 50000);
4725 if (!pm
&& rn2(50) ) {
4729 if (pm
&& !(treadedshoemonster(pm
) && highheeledshoemonster(pm
)) && rn2(50) ) {
4734 if (pm
) (laramon
= makemon(pm
, u
.ux
, u
.uy
, MM_ANGRY
|MM_ADJACENTOK
));
4737 laramon
->laramonst
= TRUE
;
4738 u
.laratraptimer
= (SuperFemtrapLara
? 200 : 1000);
4746 /* Discount action will halve paralysis duration, but some paralysis sources ignore it --Amy */
4747 if (Discount_action
&& discountpossible
&& (nval
< -1)) nval
/= 2;
4748 if (StrongDiscount_action
&& discountpossible
&& (nval
< -1)) nval
/= 2;
4750 /* at most 2 turns with sexy stand tech, as long as it's a resistable kind of paralysis --Amy */
4751 if (tech_inuse(T_SEXY_STAND
) && PlayerInBlockHeels
&& discountpossible
&& (nval
< -2)) nval
= -2;
4753 if (uarmg
&& uarmg
->otyp
== GAUNTLETS_OF_PARALYSIS_ANNOUNC
&& nval
< 0) {
4754 pline("You've been paralyzed for %d turns.", abs(nval
));
4757 if (uarmg
&& uarmg
->oartifact
== ART_NOPE_OUT_OF_PARA
&& nval
< 0 && discountpossible
&& (uarmg
->invoketimer
<= monstermoves
) ) {
4758 if (yn("Nope out of the paralysis?") == 'y') {
4760 int artitimeout
= rnz(2000);
4761 if (!rn2(5)) artitimeout
= rnz(20000); /* squeaking does not help here, as it's not an actual invoke --Amy */
4762 uarmg
->invoketimer
= (monstermoves
+ artitimeout
);
4768 if (multi
< 0) flags
.botl
= 1;
4770 (void) strncpy(multi_txt
, txt
, BUFSZ
);
4772 (void) memset(multi_txt
, 0, BUFSZ
);
4773 flags
.travel
= iflags
.travel1
= flags
.mv
= flags
.run
= 0;
4777 forcenomul(nval
, txt
)
4781 if(multi
< nval
) return; /* This is a bug fix by ab@unido */
4782 u
.uinvulnerable
= FALSE
; /* Kludge to avoid ctrl-C bug -dlc */
4785 if (multi
< 0) flags
.botl
= 1;
4787 (void) strncpy(multi_txt
, txt
, BUFSZ
);
4789 (void) memset(multi_txt
, 0, BUFSZ
);
4790 flags
.travel
= iflags
.travel1
= flags
.mv
= flags
.run
= 0;
4793 /* called when a non-movement, multi-turn action has completed */
4796 const char *msg_override
;
4800 multi
= 0; /* caller will usually have done this already */
4801 (void) memset(multi_txt
, 0, BUFSZ
);
4802 if (msg_override
) nomovemsg
= msg_override
;
4803 else if (!nomovemsg
) nomovemsg
= You_can_move_again
;
4804 if (*nomovemsg
) pline("%s", nomovemsg
);
4807 if (afternmv
) (*afternmv
)();
4811 /* lara trap effect: specially spawned monsters should banish themselves when you're unparalyzed --Amy */
4812 for (mtmp
= fmon
; mtmp
; mtmp
= mtmp
->nmon
) {
4813 if (mtmp
->laramonst
) {
4814 mtmp
->laramonst
= 0;
4818 if (mon_has_amulet(mtmp
) || In_endgame(&u
.uz
)) {
4821 flev
= random_banishment_level();
4822 migrate_to_level(mtmp
, ledger_no(&flev
), MIGR_RANDOM
, (coord
*)0);
4835 /* Print the amount of damage inflicted */
4836 /* KMH -- Centralized to one function */
4843 if (DamageMeterBug
|| u
.uprops
[DAMAGE_METER_BUG
].extrinsic
|| have_damagemeterstone()) return;
4844 if (Role_if(PM_NOOB_MODE_BARB
)) return; /* sorry --Amy */
4846 if (flags
.showdmg
&& n
> 1) {
4847 switch (Role_switch
) {
4848 case PM_BARBARIAN
: case PM_MONK
: lev
= 10; break;
4849 case PM_CAVEMAN
: case PM_VALKYRIE
: lev
= 12; break;
4850 /* vanilla valk doesn't get this because showdmg isn't even a thing in vanilla --Amy */
4851 case PM_SAMURAI
: case PM_KNIGHT
: case PM_CHEVALIER
: case PM_GOLDMINER
: lev
= 14; break;
4852 default: lev
= 17; break;
4854 switch (Race_switch
) {
4855 case PM_GNOME
: if (lev
> 14) lev
= 14; break;
4856 case PM_VEELA
: if (lev
> 1) lev
= 1; break;
4859 if (wizard
) lev
= 1;
4861 if(GushLevel
>= lev
)
4862 pline("(%d pts.)", n
);
4868 /* dnethack weeping angel contamination. Unlike dnethack, we have many sources of contamination, which is why I
4869 * don't call it "weeping angel" contamination; it's more like nuclear radiation or something. There will be certain
4870 * weeping angel types that use it as an attack, but the effect is just a generic "contamination". --Amy */
4872 contaminate(amount
, tellplayer
)
4873 register int amount
;
4879 while (!rn2(5)) amount
*= 2;
4881 /* Yes I totally know this will call the SJWs and they will whine and bitch like mad, but there is an actual reason
4882 * for this: female characters are much more resistant to most item-stealers (since almost all nymphs are female),
4883 * and mhitu.c also specifically makes females more resistant to certain shoes when they are used by monsters.
4884 * Some players have even asserted that there is basically no advantage to playing a male character, and so I
4885 * decided to make females a little bit more susceptible to contamination.
4886 * THIS DOES NOT MEAN I HATE WOMEN, SO YOU SJWS CAN JUST BUGGER OFF KTHX --Amy */
4888 if (Race_if(PM_HUMANOID_ANGEL
)) amount
*= 2;
4889 /* It is also widely known that the angel race is teh uber pwnz0r and has almost no downsides, so I added one here */
4891 if (FalloutEffectXtra
) amount
*= 2;
4893 /* Contamination resistance divides incoming contamination by 5, but not below 1 */
4894 if (Cont_resist
&& amount
> 1) {
4896 if (amount
< 1) amount
= 1;
4898 if (StrongCont_resist
) {
4900 if (amount
< 1 && rn2(2)) amount
= 1;
4902 if (tellplayer
) pline("Somehow, the contamination doesn't affect you.");
4907 if (isfriday
&& !rn2(5)) amount
*= 2;
4909 if (u
.extracontres
&& !rn2(5)) {
4910 if (tellplayer
) pline("The contamination doesn't seem to affect you.");
4914 if (uarmc
&& itemhasappearance(uarmc
, APP_VINDALE_CLOAK
) && rn2(2)) {
4915 if (tellplayer
) pline("The contamination is absorbed by the cloak!");
4919 /* Mercury amulets in particular offer a bit of protection, but not other mercury equipment --Amy */
4920 if (uamul
&& objects
[uamul
->otyp
].oc_material
== MT_MERCURIAL
&& !rn2(10)) {
4921 if (tellplayer
) pline("Your mercury amulet prevents you from being contaminated!");
4925 /* Platinum is supposed to be a material that shields you against contamination --Amy */
4926 if (uwep
&& objects
[uwep
->otyp
].oc_material
== MT_PLATINUM
&& !rn2(10)) {
4927 if (tellplayer
) pline("Your platinum weapon prevents you from being contaminated!");
4930 if (u
.twoweap
&& uswapwep
&& objects
[uswapwep
->otyp
].oc_material
== MT_PLATINUM
&& !rn2(10)) {
4931 if (tellplayer
) pline("Your platinum off-hand weapon prevents you from being contaminated!");
4934 if (uarm
&& objects
[uarm
->otyp
].oc_material
== MT_PLATINUM
&& !rn2(10)) {
4935 if (tellplayer
) pline("Your platinum armor prevents you from being contaminated!");
4938 if (uarmc
&& objects
[uarmc
->otyp
].oc_material
== MT_PLATINUM
&& !rn2(10)) {
4939 if (tellplayer
) pline("Your platinum cloak prevents you from being contaminated!");
4942 if (uarmh
&& objects
[uarmh
->otyp
].oc_material
== MT_PLATINUM
&& !rn2(10)) {
4943 if (tellplayer
) pline("Your platinum helmet prevents you from being contaminated!");
4946 if (uarms
&& objects
[uarms
->otyp
].oc_material
== MT_PLATINUM
&& !rn2(10)) {
4947 if (tellplayer
) pline("Your platinum shield prevents you from being contaminated!");
4950 if (uarmg
&& objects
[uarmg
->otyp
].oc_material
== MT_PLATINUM
&& !rn2(10)) {
4951 if (tellplayer
) pline("Your platinum pair of gauntlets prevents you from being contaminated!");
4954 if (uarmf
&& objects
[uarmf
->otyp
].oc_material
== MT_PLATINUM
&& !rn2(10)) {
4955 if (tellplayer
) pline("Your platinum pair of boots prevents you from being contaminated!");
4958 if (uarmu
&& objects
[uarmu
->otyp
].oc_material
== MT_PLATINUM
&& !rn2(10)) {
4959 if (tellplayer
) pline("Your platinum shirt prevents you from being contaminated!");
4962 if (uamul
&& objects
[uamul
->otyp
].oc_material
== MT_PLATINUM
&& !rn2(10)) {
4963 if (tellplayer
) pline("Your platinum amulet prevents you from being contaminated!");
4966 if (uimplant
&& objects
[uimplant
->otyp
].oc_material
== MT_PLATINUM
&& !rn2(10)) {
4967 if (tellplayer
) pline("Your platinum implant prevents you from being contaminated!");
4970 if (uleft
&& objects
[uleft
->otyp
].oc_material
== MT_PLATINUM
&& !rn2(10)) {
4971 if (tellplayer
) pline("Your platinum left ring prevents you from being contaminated!");
4974 if (uright
&& objects
[uright
->otyp
].oc_material
== MT_PLATINUM
&& !rn2(10)) {
4975 if (tellplayer
) pline("Your platinum right ring prevents you from being contaminated!");
4978 if (ublindf
&& objects
[ublindf
->otyp
].oc_material
== MT_PLATINUM
&& !rn2(10)) {
4979 if (tellplayer
) pline("Your platinum blindfold prevents you from being contaminated!");
4983 /* lead shields against contamination even more --Amy */
4984 if (uwep
&& objects
[uwep
->otyp
].oc_material
== MT_LEAD
&& !rn2(5)) {
4985 if (tellplayer
) pline("Your lead weapon prevents you from being contaminated!");
4988 if (u
.twoweap
&& uswapwep
&& objects
[uswapwep
->otyp
].oc_material
== MT_LEAD
&& !rn2(5)) {
4989 if (tellplayer
) pline("Your lead off-hand weapon prevents you from being contaminated!");
4992 if (uarm
&& objects
[uarm
->otyp
].oc_material
== MT_LEAD
&& !rn2(5)) {
4993 if (tellplayer
) pline("Your lead armor prevents you from being contaminated!");
4996 if (uarmc
&& objects
[uarmc
->otyp
].oc_material
== MT_LEAD
&& !rn2(5)) {
4997 if (tellplayer
) pline("Your lead cloak prevents you from being contaminated!");
5000 if (uarmh
&& objects
[uarmh
->otyp
].oc_material
== MT_LEAD
&& !rn2(5)) {
5001 if (tellplayer
) pline("Your lead helmet prevents you from being contaminated!");
5004 if (uarms
&& objects
[uarms
->otyp
].oc_material
== MT_LEAD
&& !rn2(5)) {
5005 if (tellplayer
) pline("Your lead shield prevents you from being contaminated!");
5008 if (uarmg
&& objects
[uarmg
->otyp
].oc_material
== MT_LEAD
&& !rn2(5)) {
5009 if (tellplayer
) pline("Your lead pair of gauntlets prevents you from being contaminated!");
5012 if (uarmf
&& objects
[uarmf
->otyp
].oc_material
== MT_LEAD
&& !rn2(5)) {
5013 if (tellplayer
) pline("Your lead pair of boots prevents you from being contaminated!");
5016 if (uarmu
&& objects
[uarmu
->otyp
].oc_material
== MT_LEAD
&& !rn2(5)) {
5017 if (tellplayer
) pline("Your lead shirt prevents you from being contaminated!");
5020 if (uamul
&& objects
[uamul
->otyp
].oc_material
== MT_LEAD
&& !rn2(5)) {
5021 if (tellplayer
) pline("Your lead amulet prevents you from being contaminated!");
5024 if (uimplant
&& objects
[uimplant
->otyp
].oc_material
== MT_LEAD
&& !rn2(5)) {
5025 if (tellplayer
) pline("Your lead implant prevents you from being contaminated!");
5028 if (uleft
&& objects
[uleft
->otyp
].oc_material
== MT_LEAD
&& !rn2(5)) {
5029 if (tellplayer
) pline("Your lead left ring prevents you from being contaminated!");
5032 if (uright
&& objects
[uright
->otyp
].oc_material
== MT_LEAD
&& !rn2(5)) {
5033 if (tellplayer
) pline("Your lead right ring prevents you from being contaminated!");
5036 if (ublindf
&& objects
[ublindf
->otyp
].oc_material
== MT_LEAD
&& !rn2(5)) {
5037 if (tellplayer
) pline("Your lead blindfold prevents you from being contaminated!");
5041 precheckamount
= u
.contamination
;
5043 u
.contamination
+= amount
;
5045 if (u
.contamination
>= 100 && u
.contamination
< 200 && precheckamount
< 100) pline(FunnyHallu
? "Your body itches comfortably." : "You are now afflicted with minor contamination.");
5046 if (u
.contamination
>= 200 && u
.contamination
< 400 && precheckamount
< 200) pline(FunnyHallu
? "The itching on your body increases." : "You are now afflicted with light contamination.");
5047 if (u
.contamination
>= 400 && u
.contamination
< 600 && precheckamount
< 400) pline(FunnyHallu
? "You seem to be developing ulcers." : "You are now afflicted with contamination.");
5048 if (u
.contamination
>= 600 && u
.contamination
< 800 && precheckamount
< 600) pline(FunnyHallu
? "You feel like your digestive tract started to digest itself." : "You are now afflicted with severe contamination.");
5049 if (u
.contamination
>= 800 && u
.contamination
< 1000 && precheckamount
< 800) pline(FunnyHallu
? "You feel that your body is consuming itself from within." : "You are now afflicted with lethal contamination.");
5050 if (u
.contamination
>= 1000 && precheckamount
< 1000) pline(FunnyHallu
? "You feel terminally ill. Something tells you that you only have three days to live." : "You are now afflicted with fatal contamination. Seek medical attention immediately.");
5052 /* if you got told that you were contaminated, and wisdom is low, give a warning --Amy */
5054 if (ABASE(A_WIS
) < 2) {
5055 pline("DANGER!!! Your wisdom is critically low and you're very likely to die from the contamination! You can cure it by using a scroll or wand of remove curse, or by successfully praying on a coaligned altar. Amnesia may also help in a pinch, or you may buy a decontamination service from a nurse.");
5056 } else if (ABASE(A_WIS
) < 4) {
5057 pline("Watch out!! Your wisdom is very low, the contamination may well reduce it below 1 and then you die! You can cure it by using a scroll or wand of remove curse, or by successfully praying on a coaligned altar. Amnesia may also help in a pinch, or you may buy a decontamination service from a nurse.");
5058 } else if (ABASE(A_WIS
) < 6) {
5059 pline("Warning! Your wisdom is low and if the contamination causes it to fall below 1, you die! You can cure it by using a scroll or wand of remove curse, or by successfully praying on a coaligned altar. Amnesia may also help in a pinch, or you may buy a decontamination service from a nurse.");
5063 /* Actual contamination effects are handled in attrib.c */
5067 decontaminate(amount
)
5068 register int amount
;
5072 precheckamount
= u
.contamination
;
5074 u
.contamination
-= amount
;
5075 if (u
.contamination
< 0) u
.contamination
= 0;
5077 if (u
.contamination
== 0 && precheckamount
>= 1) pline(FunnyHallu
? "Your body feels completely normal again." : "Your contamination has faded away completely.");
5078 if (u
.contamination
< 100 && u
.contamination
>= 1 && precheckamount
>= 100) pline(FunnyHallu
? "Your body no longer itches." : "You are only very slightly contaminated now.");
5079 if (u
.contamination
< 200 && u
.contamination
>= 100 && precheckamount
>= 200) pline(FunnyHallu
? "The itching on your body decreases." : "Your contamination decreased to a low level.");
5080 if (u
.contamination
< 400 && u
.contamination
>= 200 && precheckamount
>= 400) pline(FunnyHallu
? "Your ulcers disappear." : "You are only lightly contaminated now.");
5081 if (u
.contamination
< 600 && u
.contamination
>= 400 && precheckamount
>= 600) pline(FunnyHallu
? "Your digestive tract seems okay now." : "Your contamination is no longer severe.");
5082 if (u
.contamination
< 800 && u
.contamination
>= 600 && precheckamount
>= 800) pline(FunnyHallu
? "Your body no longer tries to consume itself." : "You are only severely contaminated now.");
5083 if (u
.contamination
< 1000 && u
.contamination
>= 800 && precheckamount
>= 1000) pline(FunnyHallu
? "Your terminal illness has passed and you may actually survive." : "You are only lethally contaminated now.");
5088 reducesanity(amount
)
5089 register int amount
;
5091 if (!(u
.usanity
)) return;
5093 u
.usanity
-= amount
;
5094 if (u
.usanity
< 0) u
.usanity
= 0;
5095 if (u
.usanity
== 0) pline("Your sanity was cured completely.");
5096 else if (amount
< 10) pline("Your sanity was reduced.");
5097 else if (amount
< 100) pline("Your sanity was reduced greatly.");
5098 else if (amount
< 1000) pline("Your sanity was reduced enormously.");
5099 else pline("Your sanity was reduced by a really huge amount but is still not cured.");
5103 losehp(n
, knam
, k_format
)
5105 register const char *knam
;
5106 int k_format
; /* WAC k_format is an int */
5110 killer_format
= k_format
;
5111 killer
= knam
; /* the thing that killed you */
5112 You("explode in a fountain of red pixels!");
5113 pline("GAME OVER - press R to try again");
5119 if (youmonst
.m_ap_type
== M_AP_OBJECT
&& (multi
< 0)) { /* bullshit! you should stop mimicking in that case! --Amy */
5120 You("took damage, and therefore stopped mimicking an object!");
5121 unmul((char *)0); /* immediately stop mimicking */
5122 youmonst
.m_ap_type
= M_AP_NOTHING
;
5123 youmonst
.mappearance
= 0;
5124 /* after all, you just took damage, so no sense in continuing to pretend that you're a stupid orange */
5127 if (uarms
&& uarms
->oartifact
== ART_OF_VOIDING
&& n
> 0) {
5131 if (uarms
&& uarms
->oartifact
== ART_OF_NULLING
&& n
> 0) {
5136 /* let's allow the player to deflect some damage if he's lucky (higher chance with good constitution). --Amy */
5137 if (rn2(ABASE(A_CON
))) {
5138 if (!rn2(3) && n
>= 1) {n
++; n
= n
/ 2; if (n
< 1) n
= 1;}
5139 if (!rn2(10) && rn2(ABASE(A_CON
)) && n
>= 1 && GushLevel
>= 10) {n
++; n
= n
/ 3; if (n
< 1) n
= 1;}
5140 if (!rn2(15) && rn2(ABASE(A_CON
)) && rn2(ABASE(A_CON
)) && n
>= 1 && GushLevel
>= 14) {n
++; n
= n
/ 4; if (n
< 1) n
= 1;}
5141 if (!rn2(20) && rn2(ABASE(A_CON
)) && rn2(ABASE(A_CON
)) && rn2(ABASE(A_CON
)) && n
>= 1 && GushLevel
>= 20) {n
++; n
= n
/ 5; if (n
< 1) n
= 1;}
5142 if (!rn2(50) && rn2(ABASE(A_CON
)) && rn2(ABASE(A_CON
)) && rn2(ABASE(A_CON
)) && rn2(ABASE(A_CON
)) && n
>= 1 && GushLevel
>= 30) {n
++; n
= n
/ 10; if (n
< 1) n
= 1;}
5145 if (PlayerInConeHeels
&& n
> 0) {
5146 register int dmgreductor
= 95;
5147 if (!(PlayerCannotUseSkills
)) switch (P_SKILL(P_HIGH_HEELS
)) {
5148 case P_BASIC
: dmgreductor
= 92; break;
5149 case P_SKILLED
: dmgreductor
= 89; break;
5150 case P_EXPERT
: dmgreductor
= 86; break;
5151 case P_MASTER
: dmgreductor
= 83; break;
5152 case P_GRAND_MASTER
: dmgreductor
= 80; break;
5153 case P_SUPREME_MASTER
: dmgreductor
= 77; break;
5161 if (n
> 0 && StrongDetect_monsters
) {
5168 if (Race_if(PM_ITAQUE
) && n
> 0) {
5170 n
*= (100 - u
.ulevel
);
5175 if (Race_if(PM_CARTHAGE
) && u
.usteed
&& (mcalcmove(u
.usteed
) < 12) && n
> 0) {
5182 if (is_sand(u
.ux
,u
.uy
) && n
> 0) {
5189 if (Race_if(PM_VIKING
) && n
> 0) {
5194 if (Race_if(PM_SPARD
) && n
> 0) {
5199 if (Race_if(PM_MAYMES
) && uwep
&& weapon_type(uwep
) == P_FIREARM
&& n
> 0) {
5206 if (n
> 0 && uarmf
&& itemhasappearance(uarmf
, APP_MARJI_SHOES
) ) {
5213 if (n
> 0 && uarm
&& uarm
->oartifact
== ART_KRAH_HOOOOO
) {
5220 if (n
> 0 && uarms
&& uarms
->oartifact
== ART_AL_UD
) {
5227 /* very early on, low-level characters should be more survivable
5228 * this can certainly be exploited in some way; if players start exploiting it I'll have to fix it
5229 * but it should fix the annoying problem where you often instadie to a trap while your max HP are bad --Amy */
5230 if (depth(&u
.uz
) == 1 && u
.ulevel
== 1 && moves
< 1000 && In_dod(&u
.uz
) && n
> 1) { n
/= 2; }
5231 if (depth(&u
.uz
) == 1 && u
.ulevel
== 2 && moves
< 1000 && In_dod(&u
.uz
) && n
> 1) { n
*= 2; n
/= 3; }
5233 if (n
&& Race_if(PM_YUKI_PLAYA
)) n
+= rnd(5);
5234 if (Role_if(PM_BLEEDER
)) n
= n
* 2; /* bleeders are harder than hard mode */
5235 if (!rn2(10) && (uarmf
&& uarmf
->oartifact
== ART_XTRA_CUTENESS
)) n
= n
* 2;
5236 if (have_cursedmagicresstone()) n
= n
* 2;
5241 if (StrongWinceState
) {
5245 if (n
<= damutemp
) n
++;
5247 if (ACURR(A_CON
) == 2) {
5251 if (ACURR(A_CON
) == 1) {
5255 if (uarmh
&& uarmh
->oartifact
== ART_HEAD_W
) {
5259 if (Role_if(PM_DANCER
) && !rn2(3)) n
= n
* 2;
5260 if (Race_if(PM_METAL
)) n
*= rnd(10);
5261 if (HardModeEffect
|| u
.uprops
[HARD_MODE_EFFECT
].extrinsic
|| have_hardmodestone() || autismringcheck(ART_RING_OF_FAST_LIVING
) || autismweaponcheck(ART_PAINBOWSWANDIR
) || autismweaponcheck(ART_RAISING_HEART
) || (uimplant
&& uimplant
->oartifact
== ART_IME_SPEW
) || (uarm
&& uarm
->oartifact
== ART_CHEST_TANK
)) n
= n
* 2;
5262 if (uamul
&& uamul
->otyp
== AMULET_OF_VULNERABILITY
) n
*= rnd(4);
5263 if (RngeFrailness
) n
= n
* 2;
5265 if (Race_if(PM_SHELL
) && !Upolyd
&& n
> 1) n
/= 2;
5267 if (u
.martialstyle
== MARTIALSTYLE_SILAT
&& !rn2(5) && !uwep
&& (!u
.twoweap
|| !uswapwep
) && n
> 1) n
/= 2;
5269 if (isfriday
&& !rn2(50)) n
+= rnd(n
);
5271 /* [max] Invulnerable no dmg */
5272 if (Invulnerable
|| (uarmf
&& uarmf
->oartifact
== ART_GODLY_POSTMAN
&& !rn2(10)) || ((PlayerInBlockHeels
|| PlayerInWedgeHeels
) && tech_inuse(T_EXTREME_STURDINESS
) && !rn2(2) ) || (Stoned_chiller
&& Stoned
&& !(u
.stonedchilltimer
) && !rn2(3)) ) {
5274 pline("You are unharmed!");
5275 /* NOTE: DO NOT RETURN - losehp is also called to check for death
5278 } else if (StrongWonderlegs
&& !rn2(10) && Wounded_legs
) {
5280 pline("You are unharmed!");
5281 } else if (uarms
&& uarms
->otyp
== NULLIFICATION_SHIELD
&& !rn2(20) ) {
5283 Your("shield nullifies the damage!");
5284 } else if (uimplant
&& uimplant
->oartifact
== ART_GLEN_HOSPITAL
&& !rn2(10)) {
5286 Your("implant nullifies the damage!");
5287 } else if (PlayerInConeHeels
&& !PlayerCannotUseSkills
&& P_SKILL(P_CONE_HEELS
) >= P_BASIC
&& (rnd(100) < P_SKILL(P_CONE_HEELS
)) ) {
5289 Your("cone heels nullify the damage!");
5290 } else if (u
.twoweap
&& uswapwep
&& uswapwep
->oartifact
== ART_SHIELD_TONFA
&& !rn2(10)) {
5292 Your("tonfa nullifies the damage!");
5293 } else if (uarm
&& uarm
->oartifact
== ART_SUSA_MAIL
&& !rn2(10)) {
5295 Your("armor nullifies the damage!");
5296 } else if (uarmf
&& uarmf
->oartifact
== ART_ELENA_S_EPITOME
&& !rn2(10)) {
5298 Your("pair of heels nullifies the damage!");
5299 } else if (uarmf
&& uarmf
->oartifact
== ART_IRMA_S_CHOICE
&& !rn2(10)) {
5301 Your("pair of heels nullifies the damage!");
5302 } else if (uarms
&& uarms
->oartifact
== ART_PLANK_OF_CARNEADES
&& !rn2(10)) {
5304 Your("shield nullifies the damage!");
5305 } else if (uarms
&& uarms
->oartifact
== ART_AL_UD
&& !rn2(10)) {
5307 Your("shield nullifies the damage!");
5308 } else if (uarms
&& uarms
->oartifact
== ART_DOUBLEBLANK
&& !rn2(10)) {
5310 Your("shield nullifies the damage!");
5311 } else if (uwep
&& uwep
->oartifact
== ART_ETERNAL_LONGING
&& !rn2(10)) {
5313 Your("soft lady shoe nullifies the damage!");
5314 } else if (u
.metalguard
) {
5317 Your("metal guard prevents the damage!");
5320 if (uactivesymbiosis
&& !u
.symbiotedmghack
&& (rn2(100) < u
.symbioteaggressivity
) && !(u
.usymbiote
.mhpmax
>= 5 && u
.usymbiote
.mhp
<= (u
.usymbiote
.mhpmax
/ 5) && rn2(5))) {
5321 if (tech_inuse(T_POWERBIOSIS
) && n
> 1) n
/= 2;
5322 if (tech_inuse(T_IMPLANTED_SYMBIOSIS
) && uimplant
&& objects
[uimplant
->otyp
].oc_charged
&& uimplant
->spe
> 0) {
5323 int imbiophases
= uimplant
->spe
;
5324 while ((imbiophases
> 0) && n
> 1) {
5330 u
.usymbiote
.mhp
-= n
;
5331 Your("%s symbiote takes the damage for you.", mons
[u
.usymbiote
.mnum
].mname
);
5332 if (u
.usymbiote
.mhp
<= 0) {
5334 if (uarmf
&& itemhasappearance(uarmf
, APP_REMORA_HEELS
) && u
.usymbiote
.mnum
== PM_REMORA
) {
5335 if (uarmf
->spe
> -1) uarmf
->spe
= -1;
5338 if (uamul
&& uamul
->otyp
== AMULET_OF_SYMBIOTE_SAVING
) {
5339 makeknown(AMULET_OF_SYMBIOTE_SAVING
);
5341 u
.usymbiote
.mhp
= u
.usymbiote
.mhpmax
;
5342 Your("symbiote glows, and your amulet crumbles to dust!");
5344 u
.usymbiote
.active
= 0;
5345 u
.usymbiote
.mnum
= PM_PLAYERMON
;
5346 u
.usymbiote
.mhp
= 0;
5347 u
.usymbiote
.mhpmax
= 0;
5348 u
.usymbiote
.cursed
= u
.usymbiote
.hvycurse
= u
.usymbiote
.prmcurse
= u
.usymbiote
.bbcurse
= u
.usymbiote
.morgcurse
= u
.usymbiote
.evilcurse
= u
.usymbiote
.stckcurse
= 0;
5349 u
.cnd_symbiotesdied
++;
5350 if (FunnyHallu
) pline("Ack! You feel like you quaffed aqua pura by mistake, and feel like something inside you has been flushed away!");
5351 else Your("symbiote dies from protecting you, and you feel very sad...");
5354 if (flags
.showsymbiotehp
) flags
.botl
= TRUE
;
5355 } else if (u
.disruptionshield
&& u
.uen
>= n
) {
5357 pline("Your mana shield takes the damage for you!");
5360 } else if (Upolyd
) {
5362 if (u
.mhmax
< u
.mh
) u
.mhmax
= u
.mh
;
5364 if (u
.mh
> 0) maybe_scream();
5370 } else if (n
> 0 && u
.mh
*10 < u
.mhmax
&& Unchanging
)
5374 if (flags
.showdmg
&& !(DamageMeterBug
|| u
.uprops
[DAMAGE_METER_BUG
].extrinsic
|| have_damagemeterstone()) && !DisplayDoesNotGoAtAll
&& n
> 0) {
5375 pline("[-%d -> %d]", n
, (Upolyd
? (u
.mh
) : (u
.uhp
) ) ); /* WAC see damage */
5382 if(u
.uhp
> u
.uhpmax
)
5383 u
.uhpmax
= u
.uhp
; /* perhaps n was negative */
5386 flags
.botl
= 1; /* Update status bar */
5388 if (u
.uhp
> 0) maybe_scream();
5392 killer_format
= k_format
;
5393 killer
= knam
; /* the thing that killed you */
5394 You(isangbander
? "have died." : "die...");
5397 } else if (n
> 0 && u
.uhp
*10 < u
.uhpmax
) {
5402 if (flags
.showdmg
&& !(DamageMeterBug
|| u
.uprops
[DAMAGE_METER_BUG
].extrinsic
|| have_damagemeterstone()) && !DisplayDoesNotGoAtAll
&& n
> 0) {
5404 pline("[-%d -> %d]", n
, (Upolyd
? (u
.mh
) : (u
.uhp
) ) ); /* WAC see damage */
5405 if (!Upolyd
&& (( (u
.uhp
) * 5) < u
.uhpmax
)) pline(isangbander
? "***LOW HITPOINT WARNING***" : "Warning: HP low!");
5406 if (isangbander
&& (!Upolyd
&& (( (u
.uhp
) * 5) < u
.uhpmax
)) && (PlayerHearsSoundEffects
)) pline(issoviet
? "Umeret' glupyy igrok ublyudka!" : "TSCHINGTSCHINGTSCHINGTSCHING!");
5411 if (u
.uprops
[TURNLIMITATION
].extrinsic
|| (uarmh
&& uarmh
->oartifact
== ART_TEJUS__VACANCY
) || (uarmf
&& uarmf
->oartifact
== ART_OUT_OF_TIME
) || (uarmu
&& uarmu
->oartifact
== ART_THERMAL_BATH
) || TurnLimitation
|| have_limitationstone() || (uarm
&& uarm
->oartifact
== ART_AMMY_S_EASYMODE
) ) {
5413 if (LimitationXtra
&& (n
> 0)) u
.ascensiontimelimit
-= (n
* 10);
5414 else if (n
> 0) u
.ascensiontimelimit
-= n
;
5415 if (u
.ascensiontimelimit
< 1) u
.ascensiontimelimit
= 1;
5418 if (Race_if(PM_CELTIC
) && !rn2(100)) {
5419 if (u
.berserktime
) {
5420 if (!obsidianprotection()) switch (rn2(11)) {
5422 make_sick(Sick
? Sick
/2L + 1L : (long)rn1(ACURR(A_CON
),20), "celtic sickness", TRUE
, SICK_NONVOMITABLE
);
5424 case 1: make_blinded(Blinded
+ 25, TRUE
);
5426 case 2: if (!Confusion
)
5427 You("suddenly feel %s.", FunnyHallu
? "trippy" : "confused");
5428 make_confused(HConfusion
+ 25, TRUE
);
5430 case 3: make_stunned(HStun
+ 25, TRUE
);
5432 case 4: make_numbed(HNumbed
+ 25, TRUE
);
5434 case 5: make_frozen(HFrozen
+ 25, TRUE
);
5436 case 6: make_burned(HBurned
+ 25, TRUE
);
5438 case 7: (void) adjattrib(rn2(A_MAX
), -1, FALSE
, TRUE
);
5440 case 8: (void) make_hallucinated(HHallucination
+ 25, TRUE
, 0L);
5442 case 9: make_feared(HFeared
+ 25, TRUE
);
5444 case 10: make_dimmed(HDimmed
+ 25, TRUE
);
5448 } else u
.berserktime
= 25;
5456 int maxcarrcap
= 5000;
5458 if (tech_inuse(T_LIGHTER_BALLS
)) {
5459 if (uwep
&& uwep
->oclass
== BALL_CLASS
) maxcarrcap
+= (uwep
->owt
/ 2);
5460 if (u
.twoweap
&& uswapwep
&& uswapwep
->oclass
== BALL_CLASS
) maxcarrcap
+= (uswapwep
->owt
/ 2);
5462 if (have_daisybag()) maxcarrcap
+= 500;
5463 if (uarm
&& uarm
->oartifact
== ART_COLLECTING_EXPANSION
) maxcarrcap
+= 5000;
5464 if (uwep
&& uwep
->oartifact
== ART_FIRST_CARRYING_BOX
) maxcarrcap
+= 1000;
5465 if (uarm
&& uarm
->oartifact
== ART_SCHOOL_SATCHEL
) maxcarrcap
+= 2000;
5466 if (uarmc
&& uarmc
->oartifact
== ART_STRIPED_SHIRT_OF_THE_MURDE
) maxcarrcap
+= 1000;
5467 if (uarm
&& uarm
->oartifact
== ART_STACHEL_SATCHEL
) maxcarrcap
+= 500;
5468 if (uarm
&& uarm
->oartifact
== ART_COMPLETELY_LIGHT
) maxcarrcap
+= 500;
5469 if (uarm
&& uarm
->oartifact
== ART_AND_LONGITUDE
) maxcarrcap
+= 1000;
5470 if (uarm
&& uarm
->oartifact
== ART_NATAS_IS_BACK
) maxcarrcap
+= 2000;
5471 if (uarmc
&& uarmc
->otyp
== TORNISTER_CLOAK
) maxcarrcap
+= 500;
5472 if (uamul
&& uamul
->oartifact
== ART_ATLAS_WEIGHT_CRUNCH
) maxcarrcap
+= 2000;
5473 if (uarm
&& uarm
->oartifact
== ART_TRIANGLE_GIRL
) {
5475 if (flags
.female
&& u
.ulevel
< 10) maxcarrcap
+= 4000;
5477 if (uwep
&& uwep
->otyp
== BAGGY_SLING
) maxcarrcap
+= 100;
5478 if (uwep
&& uwep
->oartifact
== ART_USEFUL_BINDLE
) maxcarrcap
+= 1000;
5479 if (uarmc
&& uarmc
->oartifact
== ART_NEUTRINO
) maxcarrcap
+= 1000;
5480 if (RngeCarryingBoost
) maxcarrcap
+= 1000;
5481 if (u
.xtralevelmult
> 1) maxcarrcap
+= ((u
.xtralevelmult
- 1) * 10);
5483 if (uarmh
&& uarmh
->oartifact
== ART_LIVIN__IT_UP
) maxcarrcap
*= 2;
5491 register long carrcap
;
5493 carrcap
= 50*(ACURRSTR
+ ACURR(A_CON
)) + 50 + 50*(u
.ulevel
);
5495 /* consistent with can_carry() in mon.c */
5496 if (youmonst
.data
->mlet
== S_NYMPH
|| youmonst
.data
== &mons
[PM_GOLDEN_KNIGHT
] || youmonst
.data
== &mons
[PM_GOLDEN_HOLY_KNIGHT
] || youmonst
.data
== &mons
[PM_URCAGUARY
])
5497 carrcap
= max_carr_cap();
5498 else if (!youmonst
.data
->cwt
)
5499 carrcap
= ((carrcap
* (long)youmonst
.data
->msize
) / MZ_HUMAN
) + 50*(u
.ulevel
);
5500 else if (!strongmonst(youmonst
.data
)
5501 || (strongmonst(youmonst
.data
) && (youmonst
.data
->cwt
> WT_HUMAN
)))
5502 carrcap
= ((carrcap
* (long)youmonst
.data
->cwt
/ WT_HUMAN
)) + 50*(u
.ulevel
);
5503 if (carrcap
< 500) carrcap
= 500;
5506 /* Intelligence increases carrying capacity, because a smarter character is able to organize and balance their pack
5507 * more evenly. (I don't remember who had this idea, maybe aosdict? --Amy) */
5508 carrcap
+= 10*(ACURR(A_INT
));
5510 if (u
.menoraget
) carrcap
+= 200;
5511 if (u
.bookofthedeadget
) carrcap
+= 250;
5512 if (u
.silverbellget
) carrcap
+= 150;
5513 if (u
.chaoskeyget
) carrcap
+= 50;
5514 if (u
.neutralkeyget
) carrcap
+= 50;
5515 if (u
.lawfulkeyget
) carrcap
+= 50;
5516 if (u
.medusaremoved
) carrcap
+= 150;
5517 if (u
.luckstoneget
) carrcap
+= 50;
5518 if (u
.sokobanfinished
) carrcap
+= 50;
5519 if (u
.deepminefinished
) carrcap
+= 50;
5520 if (uarm
&& uarm
->oartifact
== ART_DRAGON_PLATE
) carrcap
-= 250;
5521 if (ACURR(A_STR
) == 1) carrcap
-= 200;
5522 if (ACURR(A_STR
) == 2) carrcap
-= 100;
5523 if (uarmg
&& uarmg
->oartifact
== ART_HANDBOXED
) carrcap
+= 1000;
5524 if (uwep
&& uwep
->oartifact
== ART_GIRLFUL_BONKING
) carrcap
-= 500;
5525 if (u
.twoweap
&& uswapwep
&& uswapwep
->oartifact
== ART_GIRLFUL_BONKING
) carrcap
-= 500;
5526 if (uleft
&& uleft
->oartifact
== ART_CORGON_S_RING
) carrcap
+= 100;
5527 if (uright
&& uright
->oartifact
== ART_CORGON_S_RING
) carrcap
+= 100;
5528 if (have_daisybag()) carrcap
+= 1000;
5529 if (uarm
&& uarm
->oartifact
== ART_COLLECTING_EXPANSION
) carrcap
+= 2000;
5530 if (uarm
&& uarm
->oartifact
== ART_SCHOOL_SATCHEL
) carrcap
+= 2000;
5531 if (uarm
&& uarm
->oartifact
== ART_NATAS_IS_BACK
) carrcap
+= 2000;
5532 if (uamul
&& uamul
->oartifact
== ART_ATLAS_WEIGHT_CRUNCH
) carrcap
+= 1000;
5533 if (uarm
&& uarm
->oartifact
== ART_TRIANGLE_GIRL
) {
5535 if (flags
.female
&& u
.ulevel
< 10) carrcap
+= 4000;
5537 if (uleft
&& uleft
->oartifact
== ART_RING_OF_STEEL_DRAGON
) carrcap
+= 100;
5538 if (uright
&& uright
->oartifact
== ART_RING_OF_STEEL_DRAGON
) carrcap
+= 100;
5539 if (uarmc
&& uarmc
->oartifact
== ART_STRIPED_SHIRT_OF_THE_MURDE
) carrcap
+= 1000;
5540 if (uarm
&& uarm
->oartifact
== ART_COMPLETELY_LIGHT
) carrcap
+= 500;
5541 if (uarm
&& uarm
->oartifact
== ART_STACHEL_SATCHEL
) carrcap
+= 2000;
5542 if (uarmc
&& uarmc
->otyp
== TORNISTER_CLOAK
) carrcap
+= 500;
5543 if (uwep
&& uwep
->oartifact
== ART_FIRST_CARRYING_BOX
) carrcap
+= 1000;
5544 if (uarm
&& uarm
->oartifact
== ART_AND_LONGITUDE
) carrcap
+= 500;
5545 if (uarmc
&& uarmc
->oartifact
== ART_NEUTRINO
) carrcap
+= 1000;
5546 if (RngeCarryingBoost
) carrcap
+= 1000;
5547 if (u
.cnd_trophiesobtained
) carrcap
+= (u
.cnd_trophiesobtained
* 50);
5548 if (u
.xtralevelmult
> 1) carrcap
+= ((u
.xtralevelmult
- 1) * 50);
5549 if (uarmc
&& uarmc
->oartifact
== ART_OH_MY_GOD_SPANDEX
) carrcap
+= 200;
5550 if (uwep
&& uwep
->otyp
== BAGGY_SLING
) carrcap
+= 250;
5551 if (uwep
&& uwep
->oartifact
== ART_USEFUL_BINDLE
) carrcap
+= 1000;
5553 if (!PlayerCannotUseSkills
&& uarm
&& (uarm
->otyp
>= ROBE
&& uarm
->otyp
<= ROBE_OF_WEAKNESS
)) {
5555 switch (P_SKILL(P_SORESU
)) {
5556 case P_BASIC
: carrcap
+= 200; break;
5557 case P_SKILLED
: carrcap
+= 400; break;
5558 case P_EXPERT
: carrcap
+= 600; break;
5559 case P_MASTER
: carrcap
+= 800; break;
5560 case P_GRAND_MASTER
: carrcap
+= 1000; break;
5561 case P_SUPREME_MASTER
: carrcap
+= 1200; break;
5567 if (Race_if(PM_CHIROPTERAN
)) carrcap
+= 2000;
5568 if (Race_if(PM_PLAYER_SHEEP
) && u
.ulevel
>= 20) carrcap
+= 2000;
5570 if (tech_inuse(T_LIGHTER_BALLS
)) {
5571 if (uwep
&& uwep
->oclass
== BALL_CLASS
) carrcap
+= (uwep
->owt
/ 2);
5572 if (u
.twoweap
&& uswapwep
&& uswapwep
->oclass
== BALL_CLASS
) carrcap
+= (uswapwep
->owt
/ 2);
5575 if (Levitation
|| Is_airlevel(&u
.uz
) /* pugh@cornell */
5576 || (u
.usteed
&& strongmonst(u
.usteed
->data
)) ) {
5578 } else if (!Flying
) {
5579 if (HWounded_legs
) carrcap
-= 250;
5580 if (EWounded_legs
) carrcap
-= 250;
5583 /* multipliers go here */
5585 if (Race_if(PM_HAXOR
)) carrcap
*= 2;
5586 if (Race_if(PM_HUMANOID_CENTAUR
)) carrcap
/= 2;
5588 if (Upolyd
&& !PlayerCannotUseSkills
) {
5589 switch (P_SKILL(P_POLYMORPHING
)) {
5590 case P_BASIC
: carrcap
*= 6; carrcap
/= 5; break;
5591 case P_SKILLED
: carrcap
*= 7; carrcap
/= 5; break;
5592 case P_EXPERT
: carrcap
*= 8; carrcap
/= 5; break;
5593 case P_MASTER
: carrcap
*= 9; carrcap
/= 5; break;
5594 case P_GRAND_MASTER
: carrcap
*= 10; carrcap
/= 5; break;
5595 case P_SUPREME_MASTER
: carrcap
*= 11; carrcap
/= 5; break;
5599 if (uarmf
&& uarmf
->oartifact
== ART_A_SPOONFUL_OF_FO_U_RK
) {
5600 carrcap
= max_carr_cap();
5603 /* absolute minimum and maximum values --Amy */
5604 if (carrcap
< 500) carrcap
= 500;
5605 if(carrcap
> (max_carr_cap())) carrcap
= max_carr_cap();
5607 /* the "fuck you Amy, your weight limits are as shitty as vanilla nethack's" effect :-P */
5608 if (CarrcapEffect
|| u
.uprops
[CARRCAP_EFFECT
].extrinsic
|| have_carrcapstone() || (uamul
&& uamul
->oartifact
== ART_ARVIAT_S_LOAD
) || have_minimejewel() ) {
5609 if (carrcap
> 500) carrcap
= 500;
5612 return((int) carrcap
);
5615 static int wc
; /* current weight_cap(); valid after call to inv_weight() */
5617 /* returns how far beyond the normal capacity the player is currently. */
5618 /* inv_weight() is negative if the player is below normal capacity. */
5622 register struct obj
*otmp
= invent
;
5623 register int wt
= 0;
5626 /* when putting stuff into containers, gold is inserted at the head
5627 of invent for easier manipulation by askchain & co, but it's also
5628 retained in u.ugold in order to keep the status line accurate; we
5629 mustn't add its weight in twice under that circumstance */
5630 /* tried to make gold lighter --Amy */
5631 wt
= (otmp
&& otmp
->oclass
== COIN_CLASS
) ? 0 :
5632 (int)((u
.ugold
+ 50L) / /*100L*/1000000L);
5636 if ( (otmp
->otyp
!= BOULDER
&& otmp
->otyp
!= LOADBOULDER
) || (!throws_rocks(youmonst
.data
) && !(uarmg
&& uarmg
->oartifact
== ART_MOUNTAIN_FISTS
)) )
5638 if (otmp
->oclass
== COIN_CLASS
)
5639 wt
+= (int)(((long)otmp
->quan
+ 50L) / /*100L*/10000L);
5640 else if ( (otmp
->otyp
!= BOULDER
&& otmp
->otyp
!= LOADBOULDER
) || !throws_rocks(youmonst
.data
))
5644 /* boulders shouldn't be completely weightless as a giant! --Amy */
5645 if ( (throws_rocks(youmonst
.data
) || (uarmg
&& uarmg
->oartifact
== ART_MOUNTAIN_FISTS
)) && (otmp
->otyp
== BOULDER
)) {
5648 if ( (throws_rocks(youmonst
.data
) || (uarmg
&& uarmg
->oartifact
== ART_MOUNTAIN_FISTS
)) && (otmp
->otyp
== LOADBOULDER
)) {
5654 if (IncreasedGravity
) wt
+= IncreasedGravity
;
5655 if (u
.graundweight
) wt
+= u
.graundweight
;
5656 if (uarmh
&& itemhasappearance(uarmh
, APP_LEAD_HELMET
)) wt
+= 50;
5657 if (uarmf
&& itemhasappearance(uarmf
, APP_LEAD_BOOTS
)) wt
+= 100;
5658 if (uarm
&& uarm
->oartifact
== ART_SUPERHEAVY_GARBO
) wt
+= 250;
5659 if (uarmf
&& itemhasappearance(uarmf
, APP_WEIGHT_ATTACHMENT_BOOTS
)) wt
+= 500;
5660 if (have_stashitcontainer()) wt
+= 1000;
5661 if (uwep
&& uwep
->oartifact
== ART_MJOLLNIR
) wt
+= 500;
5662 if (u
.twoweap
&& uswapwep
&& uswapwep
->oartifact
== ART_MJOLLNIR
) wt
+= 500;
5663 if (uwep
&& uwep
->oartifact
== ART_FRISIA_S_TAIL
) wt
+= 500;
5664 if (u
.twoweap
&& uswapwep
&& uswapwep
->oartifact
== ART_FRISIA_S_TAIL
) wt
+= 500;
5665 if (uwep
&& uwep
->oartifact
== ART_CAT_S_TAIL
) wt
+= 500;
5666 if (u
.twoweap
&& uswapwep
&& uswapwep
->oartifact
== ART_CAT_S_TAIL
) wt
+= 500;
5667 if (uwep
&& uwep
->oartifact
== ART_OTHER_MJOLLNIR
) wt
+= 500;
5668 if (u
.twoweap
&& uswapwep
&& uswapwep
->oartifact
== ART_OTHER_MJOLLNIR
) wt
+= 500;
5669 if (uwep
&& uwep
->oartifact
== ART_UNWIELDYTINE
) wt
+= 200;
5670 if (u
.twoweap
&& uswapwep
&& uswapwep
->oartifact
== ART_UNWIELDYTINE
) wt
+= 200;
5672 /* Symbiotes can have a weight. If you're a symbiant, the weight is considerably lower; everyone else will get
5673 * a skill-dependant amount of weight added. At master and above, the weight no longer gets a multiplier --Amy
5674 * climacterial role has zero symbiote weight starting at XL5 */
5676 if (uinsymbiosis
) wt
+= symbioteweight(u
.usymbiote
.mnum
);
5678 if (u
.martialstyle
== MARTIALSTYLE_SILAT
) {
5683 if (BurdenedState
) wt
*= 2;
5684 if (StrongBurdenedState
) {
5685 /* add 2000 more, unless you have a low cap because being insta-overloaded with no way to fix it ain't fun --Amy */
5686 if (weight_cap() < 1000) wt
+= (weight_cap() * 2);
5692 if ( (MeanBurdenEffect
|| u
.uprops
[MEAN_BURDEN_EFFECT
].extrinsic
|| have_meanburdenstone() || autismringcheck(ART_KRATSCHEM_HARD
) ) && (wt
<= wc
)) wt
= (wc
+ 1);
5698 symbioteweight(symbiotetype
)
5703 if (uinsymbiosis
&& !(Role_if(PM_CLIMACTERIAL
) && u
.ulevel
>= 5)) {
5705 if (Role_if(PM_SYMBIANT
)) {
5709 if (mons
[symbiotetype
].msize
>= MZ_GIGANTIC
) symweight
+= 100;
5710 else if (mons
[symbiotetype
].msize
>= MZ_HUGE
) symweight
+= 30;
5711 else if (mons
[symbiotetype
].msize
>= MZ_LARGE
) symweight
+= 10;
5712 if ((int) mons
[symbiotetype
].cwt
> 99) symweight
+= ((int) mons
[symbiotetype
].cwt
/ 100);
5714 if (Race_if(PM_BABYLONIAN
) && mons
[symbiotetype
].mlet
== S_TURRET
) symweight
= 0;
5715 if (uarmf
&& itemhasappearance(uarmf
, APP_REMORA_HEELS
) && symbiotetype
== PM_REMORA
) symweight
= 0;
5717 if (symweight
< 0) symweight
= 0; /* fail safe */
5718 xtraweight
+= symweight
;
5722 int symweight
= 50; /* base weight even for weightless one */
5724 if (mons
[symbiotetype
].msize
>= MZ_GIGANTIC
) symweight
+= 1000;
5725 else if (mons
[symbiotetype
].msize
>= MZ_HUGE
) symweight
+= 300;
5726 else if (mons
[symbiotetype
].msize
>= MZ_LARGE
) symweight
+= 100;
5727 if ((int) mons
[symbiotetype
].cwt
> 9) symweight
+= ((int) mons
[symbiotetype
].cwt
/ 10);
5729 /* goauld is special: they don't get a multiplier */
5730 if (Race_if(PM_GOAULD
)) ;
5731 else if (!(PlayerCannotUseSkills
)) {
5732 switch (P_SKILL(P_SYMBIOSIS
)) {
5733 default: symweight
*= 5; break;
5734 case P_BASIC
: symweight
*= 4; break;
5735 case P_SKILLED
: symweight
*= 3; break;
5736 case P_EXPERT
: symweight
*= 2; break;
5737 case P_MASTER
: break;
5738 case P_GRAND_MASTER
: break;
5739 case P_SUPREME_MASTER
: break;
5741 } else symweight
*= 5;
5743 if (Race_if(PM_BABYLONIAN
) && mons
[symbiotetype
].mlet
== S_TURRET
) symweight
= 0;
5744 if (uarmf
&& itemhasappearance(uarmf
, APP_REMORA_HEELS
) && symbiotetype
== PM_REMORA
) symweight
= 0;
5746 if (symweight
< 0) symweight
= 0; /* fail safe */
5747 xtraweight
+= symweight
;
5756 * Returns 0 if below normal capacity, or the number of "capacity units"
5757 * over the normal capacity the player is loaded. Max is 5.
5760 calc_capacity(xtra_wt
)
5763 int cap
, wt
= inv_weight() + xtra_wt
;
5765 if (wt
<= 0) return UNENCUMBERED
;
5766 if (wc
<= 1) return OVERLOADED
;
5767 /* cap = (wt*2 / wc) + 1;*/
5768 cap
= (wt
/ wc
) + 1;
5769 return min(cap
, OVERLOADED
);
5775 return calc_capacity(0);
5781 int wt
= inv_weight();
5783 /* return (wt - (2 * wc)); */
5784 return (wt
- (4 * wc
));
5791 if(near_capacity() >= EXT_ENCUMBER
) {
5795 You_cant("do that while carrying so much stuff.");
5797 if (flags
.moreforced
&& !MessagesSuppressed
) display_nhwindow(WIN_MESSAGE
, TRUE
); /* --More-- */
5810 register struct obj
*otmp
= invent
;
5811 register int ct
= 0;
5821 /* Counts the money in an object chain. */
5822 /* Intended use is for your or some monsters inventory, */
5823 /* now that u.gold/m.gold is gone.*/
5824 /* Counting money in a container might be possible too. */
5830 /* Must change when silver & copper is implemented: */
5831 if (otmp
->oclass
== COIN_CLASS
) return otmp
->quan
;
5850 snuff_light_source(x
, y
);
5854 /* will zorkmids be renamed to buckazoids? */
5858 if (In_ZAPM(&u
.uz
) || Role_if(PM_SOFTWARE_ENGINEER
) || Role_if(PM_CRACKER
) || Role_if(PM_JANITOR
) || Role_if(PM_SPACE_MARINE
) || Role_if(PM_STORMBOY
) || Role_if(PM_YAUTJA
) || Role_if(PM_QUARTERBACK
) || Role_if(PM_PSYKER
) || Role_if(PM_EMPATH
) || Role_if(PM_MASTERMIND
) || Role_if(PM_WEIRDBOY
) || Role_if(PM_ASTRONAUT
) || Role_if(PM_CYBERNINJA
) || Role_if(PM_DISSIDENT
) || Race_if(PM_RETICULAN
) || Race_if(PM_OUTSIDER
) || Role_if(PM_XELNAGA
)) return TRUE
;