Blindfold removal fix
[slashemextended.git] / src / monmove.c
blob62bd71ca83e7153bedc66eeba737673bd4c83689
1 /* SCCS Id: @(#)monmove.c 3.4 2002/04/06 */
2 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
3 /* NetHack may be freely redistributed. See license for details. */
5 #include "hack.h"
6 #include "mfndpos.h"
7 #include "artifact.h"
8 #include "epri.h"
10 extern boolean notonhead;
12 #ifdef OVL0
14 STATIC_DCL int disturb(struct monst *);
15 STATIC_DCL void distfleeck(struct monst *,int *,int *,int *);
16 STATIC_DCL int m_arrival(struct monst *);
17 STATIC_DCL void watch_on_duty(struct monst *);
18 /* WAC for breath door busting */
19 static int bust_door_breath(struct monst *);
21 #endif /* OVL0 */
22 #ifdef OVLB
24 boolean /* TRUE : mtmp died */
25 mb_trapped(mtmp)
26 register struct monst *mtmp;
28 if (flags.verbose) {
29 if (cansee(mtmp->mx, mtmp->my))
30 pline("KABOOM!! You see a door explode.");
31 else if (flags.soundok)
32 You_hear("a distant explosion.");
34 wake_nearto(mtmp->mx, mtmp->my, 7*7);
35 mtmp->mstun = 1;
36 mtmp->mhp -= rnd(15);
37 if(mtmp->mhp <= 0) {
38 mondied(mtmp);
39 if (mtmp->mhp > 0) /* lifesaved */
40 return(FALSE);
41 else
42 return(TRUE);
44 return(FALSE);
47 #endif /* OVLB */
48 #ifdef OVL0
50 STATIC_OVL void
51 watch_on_duty(mtmp)
52 register struct monst *mtmp;
54 int x, y;
56 if(mtmp->mpeaceful && in_town(u.ux+u.dx, u.uy+u.dy) &&
57 mtmp->mcansee && m_canseeu(mtmp) && !rn2(3)) {
59 if((Role_if(PM_CONVICT) || Role_if(PM_MURDERER) || Race_if(PM_ALBAE) || Race_if(PM_PLAYER_DYNAMO)) && !Upolyd) {
60 verbalize("%s yells: Hey! You are the one from the wanted poster!",
61 Amonnam(mtmp));
62 (void) angry_guards(!(flags.soundok));
63 stop_occupation();
64 return;
66 if(picking_lock(&x, &y) && IS_DOOR(levl[x][y].typ) &&
67 (levl[x][y].doormask & D_LOCKED)) {
69 if(couldsee(mtmp->mx, mtmp->my)) {
71 pline("%s yells:", Amonnam(mtmp));
72 if(levl[x][y].looted & D_WARNED) {
73 verbalize("Halt, thief! You're under arrest!");
74 (void) angry_guards(!(flags.soundok));
75 } else {
76 int i;
77 verbalize("Hey, stop picking that lock!");
78 /* [ALI] Since marking a door as warned will have
79 * the side effect of trapping the door, it must be
80 * included in the doors[] array in order that trap
81 * detection will find it.
83 for(i = doorindex - 1; i >= 0; i--)
84 if (x == doors[i].x && y == doors[i].y)
85 break;
86 if (i < 0)
87 i = add_door(x, y, (struct mkroom *)0);
88 if (i >= 0)
89 levl[x][y].looted |= D_WARNED;
91 stop_occupation();
93 } else if (is_digging()) {
94 /* chewing, wand/spell of digging are checked elsewhere */
95 watch_dig(mtmp, digging.pos.x, digging.pos.y, FALSE);
100 #endif /* OVL0 */
101 #ifdef OVL1
104 dochugw(mtmp)
105 register struct monst *mtmp;
107 register int x = mtmp->mx, y = mtmp->my;
108 boolean already_saw_mon = !occupation ? 0 : canspotmon(mtmp);
109 int rd = dochug(mtmp);
111 /* Amy edit: if you have a lot of astral vision range, things farther away than BOLT_LIM should still interrupt you
112 * originally the constant interruption effect when you have astral vision was a bug, but I won't fix it :-P */
113 int interruptrange = BOLT_LIM+1;
114 if (u.xray_range > interruptrange) interruptrange = u.xray_range;
116 #if 0
117 /* part of the original warning code which was replaced in 3.3.1 */
118 register struct permonst *mdat = mtmp->data;
119 int dd;
120 if(Warning && !rd && !mtmp->mpeaceful &&
121 (dd = distu(mtmp->mx,mtmp->my)) < distu(x,y) &&
122 dd < 100 && !canseemon(mtmp)) {
123 /* Note: this assumes we only want to warn against the monster to
124 * which the weapon does extra damage, as there is no "monster
125 * which the weapon warns against" field.
127 if (spec_ability(uwep, SPFX_WARN) && spec_dbon(uwep, mtmp, 1))
128 warnlevel = 100;
129 else if ((int) (mtmp->m_lev / 6) > warnlevel)
130 warnlevel = (mtmp->m_lev / 6);
131 /* STEPHEN WHITE'S NEW CODE */
132 } else if(Undead_warning && !rd && !mtmp->mpeaceful &&
133 (dd = distu(mtmp->mx,mtmp->my)) < distu(x,y) &&
134 dd < 100 && !canseemon(mtmp) && (is_undead(mdat) || mtmp->egotype_undead) ) {
136 * The value of warnlevel coresponds to the 8
137 * cardinal directions, see mon.c.
139 if(((mtmp->mx - u.ux) < 0) && ((mtmp->my - u.uy) < 0))
140 warnlevel = 101;
141 if(((mtmp->mx - u.ux) == 0) && ((mtmp->my - u.uy) < 0))
142 warnlevel = 102;
143 if(((mtmp->mx - u.ux) > 0) && ((mtmp->my - u.uy) < 0))
144 warnlevel = 103;
145 if(((mtmp->mx - u.ux) < 0) && ((mtmp->my - u.uy) == 0))
146 warnlevel = 104;
147 if(((mtmp->mx - u.ux) > 0) && ((mtmp->my - u.uy) == 0))
148 warnlevel = 105;
149 if(((mtmp->mx - u.ux) < 0) && ((mtmp->my - u.uy) > 0))
150 warnlevel = 106;
151 if(((mtmp->mx - u.ux) == 0) && ((mtmp->my - u.uy) > 0))
152 warnlevel = 107;
153 if(((mtmp->mx - u.ux) > 0) && ((mtmp->my - u.uy) > 0))
154 warnlevel = 108;
156 #endif /* 0 */
158 /* a similar check is in monster_nearby() in hack.c */
159 /* check whether hero notices monster and stops current activity */
160 if (occupation && !rd && !Confusion &&
161 (!mtmp->mpeaceful || Hallucination) &&
162 /* it's close enough to be a threat */
163 distu(mtmp->mx,mtmp->my) <= (interruptrange * interruptrange) &&
164 /* and either couldn't see it before, or it was too far away */
165 (!already_saw_mon || !couldsee(x,y) ||
166 distu(x,y) > (interruptrange * interruptrange)) &&
167 /* can see it now, or sense it and would normally see it */
168 (canseemon(mtmp) ||
169 (sensemon(mtmp) && couldsee(mtmp->mx,mtmp->my))) &&
170 mtmp->mcanmove &&
171 !noattacks(mtmp->data) && !onscary(u.ux, u.uy, mtmp))
172 stop_occupation();
173 return(rd);
176 #endif /* OVL1 */
177 #ifdef OVL2
179 boolean
180 onscary(x, y, mtmp)
181 int x, y;
182 struct monst *mtmp;
184 int resist_percentage;
185 int scresist_percentage;
186 boolean mresists;
187 boolean scmresists;
189 /* some monsters are completely immune, certain others are highly resistant --Amy */
191 if (mtmp->isshk || mtmp->isgd || mtmp->iswiz || !mtmp->mcansee || (mtmp->data->geno & G_UNIQ) ||
192 mtmp->mpeaceful || (mtmp->data->mlet == S_HUMAN && rn2(5)) || (mtmp->data->mlet == S_DEMON && rn2(3)) ||
193 (mtmp->data->mlet == S_NEMESE && rn2(10)) || (mtmp->data->mlet == S_ARCHFIEND && rn2(25)) ||
194 mtmp->data->mlet == S_RUBMONST ||
195 is_lminion(mtmp) || (mtmp->data->mlet == S_ANGEL && rn2(20)) || (mtmp->data->mlet == S_JELLY && rn2(3)) ||
196 mtmp->data == &mons[PM_CTHULHU] || (mtmp->data->mlet == S_LIGHT && rn2(2)) ||
197 (mtmp->data->mlet == S_FUNGUS && rn2(10)) ||
198 is_rider(mtmp->data) || is_deadlysin(mtmp->data) || (is_minotaur(mtmp->data)) ||
199 (mtmp->data->msound == MS_BOSS && rn2(10) ) || (mtmp->data->msound == MS_FART_QUIET && rn2(50) ) || (mtmp->data->msound == MS_FART_NORMAL && rn2(30) ) || (mtmp->data->msound == MS_FART_LOUD && rn2(20) ) ||
200 mtmp->mnum == quest_info(MS_NEMESIS) || mtmp->mnum == PM_VLAD_THE_IMPALER || mtmp->mnum == PM_CHANOP)
201 return(FALSE);
203 if (mtmp->mhp < 2) return FALSE;
205 /* the smallest monsters always respect Elbereth;
206 * more powerful things less so */
207 /* also nerfed scare monster scrolls a bit */
209 resist_percentage = (int)(mtmp->m_lev * 3 / 2);
210 scresist_percentage = (int)(mtmp->m_lev / 2);
211 if (uwep && uwep->oartifact == ART_OMGHAXERETH) resist_percentage = (int)(mtmp->m_lev / 2);
213 mresists = rn2(100) < resist_percentage;
214 scmresists = rn2(100) < resist_percentage;
216 return (boolean)((sobj_at(SCR_SCARE_MONSTER, x, y) && !(Conflict && rn2(StrongConflict ? 5 : 2)) && !scmresists)
217 || (sengr_at("Elbereth", x, y) && !mresists && !(Conflict && rn2(StrongConflict ? 5 : 2)) && !(EngravingDoesntWork || u.uprops[ENGRAVINGBUG].extrinsic || have_engravingstone() || (uarmu && uarmu->oartifact == ART_LISE_S_UNDERWEAR) || autismweaponcheck(ART_ELBERGOFUKYOURSELF) || (uarmf && uarmf->oartifact == ART_VARIANTISH_DESIGN) ) )
218 || (is_vampire(mtmp->data) && rn2(5)
219 && IS_ALTAR(levl[x][y].typ)));
222 #endif /* OVL2 */
223 #ifdef OVL0
225 /* regenerate lost hit points */
226 void
227 mon_regen(mon, digest_meal)
228 struct monst *mon;
229 boolean digest_meal;
232 int regenrate; /* A level 30 pet large cat would otherwise regenerate waaaaaay too slowly. --Amy */
234 /* is the monster bleeding despite not being able to bleed? if so, stop its bleeding --Amy */
235 if (mon->bleedout && (!has_blood(mon->data) ) ) {
236 mon->bleedout = 0;
239 if (mon->healblock || mon->bleedout) return; /* sorry --Amy */
241 regenrate = (20 - (mon->m_lev / 3));
242 if (regenrate < 6) regenrate = 6;
243 if (ishaxor) regenrate /= 2;
245 if (mon->mhp < mon->mhpmax && !(is_golem(mon->data) && issoviet) &&
246 (!rn2(regenrate) || (FemtrapActiveGudrun && mon->female && humanoid(mon->data)) || regenerates(mon->data) || mon->egotype_regeneration )) mon->mhp++;
248 if ((mon->mhp < mon->mhpmax) && FemtrapActiveRonja && mon->female) mon->mhp++;
250 if (mon->data == &mons[PM_GROGGY_GUY]) {
251 mon->mhp += rnd(5);
252 if (mon->mhp > mon->mhpmax) mon->mhp = mon->mhpmax;
255 if (mon->data == &mons[PM_SLOWLY_GROWING_ROCK] && !rn2(500)) {
256 if (mon->mhpmax < 400) mon->mhpmax++;
259 /* super regene */
260 if (mon->data == &mons[PM_MESHERA_ALPHA_DEFORMED_ANGEL] || mon->data == &mons[PM_TESTER] || mon->data == &mons[PM_TEA_HUSSY] || mon->data == &mons[PM_OUROBOROS] || mon->data == &mons[PM_SUPER_FAST_REGENERATING_TROLL] || mon->data == &mons[PM_OLOG_THAT_COULD_HAVE_BEEN] || mon->data == &mons[PM_GENUINE_PREHISTORIC_FISH] || mon->data == &mons[PM_BILLION_YEAR_FISH] || mon->data == &mons[PM_DEEP_ROCK] || mon->data == &mons[PM_UNITDEAD_QUEEN] || mon->data == &mons[PM_UNITDEAD_KING] || mon->data == &mons[PM_REGULUS_THE_ALTERED] || mon->data == &mons[PM_SELF_HEALER] || mon->data == &mons[PM_ZANAN_ENHANCED_SOLDIER] || mon->data == &mons[PM_VANESSA_ENHANCED_SOLDIER] || mon->data == &mons[PM_BRITTA_S_SEXY_PUMP] || mon->data == &mons[PM_SUPERREGENEBOROS] || mon->data == &mons[PM_TELHUREZA_HOUSE_GUARD] || mon->data == &mons[PM_JUERE_DEMON_SOLDIER] || mon->data == &mons[PM_MAUA_YA_KIAJEMI_YA_KUELEA] || mon->data == &mons[PM_DIGGING_ON_FARMER] || mon->data == &mons[PM_JENNIFER_DEMON_SOLDIER] || mon->data == &mons[PM_ARIANE__LADY_OF_THE_ELEMENTS] || mon->data == &mons[PM_RENAI_OVER_MESHERA] || mon->data == &mons[PM_PATIENT_ZERO] || mon->data == &mons[PM_MISSU] ) {
261 mon->mhp += 20;
262 if (mon->mhp > mon->mhpmax) mon->mhp = mon->mhpmax;
265 if (mon->data == &mons[PM_CRITICALLY_INJURED_PERCENTS]) {
266 mon->mhp = mon->mhpmax;
268 if (mon->data == &mons[PM_OGRE_PERCENTS]) {
269 mon->mhp = mon->mhpmax;
272 if (FemtrapActiveGudrun && mon->female && humanoid(mon->data) ) {
273 mon->mhp += 5;
274 if (mon->mhp > mon->mhpmax) mon->mhp = mon->mhpmax;
277 if (mon->m_en < mon->m_enmax &&
278 (!rn2(regenrate) || (rn2(mon->m_lev + 5) > 15))) {
279 mon->m_en += rn1((mon->m_lev % 10 + 1),1);
280 if (mon->m_en > mon->m_enmax) mon->m_en = mon->m_enmax;
283 if (powerfulimplants() && uimplant && uimplant->oartifact == ART_READY_FOR_A_RIDE && u.usteed && (mon == u.usteed)) {
284 if (mon->mhp + 1 >= mon->mhpmax)
285 mon->mhp = mon->mhpmax;
286 else mon->mhp++;
289 if (u.usteed && mon == u.usteed) {
291 if (bmwride(ART_CURE_HASSIA_COURSE)) {
292 if (mon->mhp + 1 >= mon->mhpmax)
293 mon->mhp = mon->mhpmax;
294 else mon->mhp++;
296 if (bmwride(ART_DRESSING_EM)) {
297 if (mon->mhp + 1 >= mon->mhpmax)
298 mon->mhp = mon->mhpmax;
299 else mon->mhp++;
302 if (bmwride(ART_STEERING_WHEEL)) {
303 mon->mconf = FALSE;
308 /* good riding skill gives extra regeneration to ridden monster --Amy */
310 if (!(PlayerCannotUseSkills)) {
312 if (P_SKILL(P_RIDING) == P_BASIC && u.usteed && (mon == u.usteed) && !rn2(10) ) {
313 if (powerfulimplants() && uimplant && uimplant->oartifact == ART_READY_FOR_A_RIDE) {
314 if (mon->mhp + 1 >= mon->mhpmax)
315 mon->mhp = mon->mhpmax;
316 else mon->mhp++;
320 if (P_SKILL(P_RIDING) == P_SKILLED && u.usteed && (mon == u.usteed) && !rn2(10) ) {
321 if (mon->mhp + 1 >= mon->mhpmax)
322 mon->mhp = mon->mhpmax;
323 else mon->mhp++;
324 if (powerfulimplants() && uimplant && uimplant->oartifact == ART_READY_FOR_A_RIDE) {
325 if (mon->mhp + 2 >= mon->mhpmax)
326 mon->mhp = mon->mhpmax;
327 else mon->mhp++;
331 if (P_SKILL(P_RIDING) == P_EXPERT && u.usteed && (mon == u.usteed) && !rn2(5) ) {
332 if (mon->mhp + 1 >= mon->mhpmax)
333 mon->mhp = mon->mhpmax;
334 else mon->mhp++;
335 if (powerfulimplants() && uimplant && uimplant->oartifact == ART_READY_FOR_A_RIDE) {
336 if (mon->mhp + 3 >= mon->mhpmax)
337 mon->mhp = mon->mhpmax;
338 else mon->mhp++;
341 if (P_SKILL(P_RIDING) == P_MASTER && u.usteed && (mon == u.usteed) && !rn2(3) ) {
342 if (mon->mhp + 1 >= mon->mhpmax)
343 mon->mhp = mon->mhpmax;
344 else mon->mhp++;
345 if (powerfulimplants() && uimplant && uimplant->oartifact == ART_READY_FOR_A_RIDE) {
346 if (mon->mhp + 4 >= mon->mhpmax)
347 mon->mhp = mon->mhpmax;
348 else mon->mhp++;
351 if (P_SKILL(P_RIDING) == P_GRAND_MASTER && u.usteed && (mon == u.usteed) ) {
352 if (mon->mhp + 1 >= mon->mhpmax)
353 mon->mhp = mon->mhpmax;
354 else mon->mhp++;
355 if (powerfulimplants() && uimplant && uimplant->oartifact == ART_READY_FOR_A_RIDE) {
356 if (mon->mhp + 5 >= mon->mhpmax)
357 mon->mhp = mon->mhpmax;
358 else mon->mhp++;
361 if (P_SKILL(P_RIDING) == P_SUPREME_MASTER && u.usteed && (mon == u.usteed) ) {
362 if (mon->mhp + 1 >= mon->mhpmax)
363 mon->mhp = mon->mhpmax;
364 else mon->mhp++;
365 if (powerfulimplants() && uimplant && uimplant->oartifact == ART_READY_FOR_A_RIDE) {
366 if (mon->mhp + 6 >= mon->mhpmax)
367 mon->mhp = mon->mhpmax;
368 else mon->mhp++;
372 if (mon->mtame) {
374 if ((rnd(30 - ACURR(A_CHA))) < 4) {
375 if (mon->mhp + 1 >= mon->mhpmax)
376 mon->mhp = mon->mhpmax;
377 else mon->mhp++;
380 if (uwep && uwep->oartifact == ART_MUNZUR_S_CLUBMATE) {
381 if (mon->mhp + 1 >= mon->mhpmax)
382 mon->mhp = mon->mhpmax;
383 else mon->mhp++;
386 if (rn2(50) < boost_power_value()) {
387 if (mon->mhp + 1 >= mon->mhpmax)
388 mon->mhp = mon->mhpmax;
389 else mon->mhp++;
392 switch (P_SKILL(P_PETKEEPING)) {
393 default: break;
394 case P_BASIC:
395 if (!rn2(6)) {
396 if (mon->mhp + 1 >= mon->mhpmax)
397 mon->mhp = mon->mhpmax;
398 else mon->mhp++;
400 break;
401 case P_SKILLED:
402 if (!rn2(5)) {
403 if (mon->mhp + 1 >= mon->mhpmax)
404 mon->mhp = mon->mhpmax;
405 else mon->mhp++;
407 break;
408 case P_EXPERT:
409 if (!rn2(4)) {
410 if (mon->mhp + 1 >= mon->mhpmax)
411 mon->mhp = mon->mhpmax;
412 else mon->mhp++;
414 break;
415 case P_MASTER:
416 if (!rn2(3)) {
417 if (mon->mhp + 1 >= mon->mhpmax)
418 mon->mhp = mon->mhpmax;
419 else mon->mhp++;
421 break;
422 case P_GRAND_MASTER:
423 if (!rn2(2)) {
424 if (mon->mhp + 1 >= mon->mhpmax)
425 mon->mhp = mon->mhpmax;
426 else mon->mhp++;
428 break;
429 case P_SUPREME_MASTER:
430 if (mon->mhp + 1 >= mon->mhpmax)
431 mon->mhp = mon->mhpmax;
432 else mon->mhp++;
433 break;
440 if (mon->mspec_used) mon->mspec_used--;
441 if (digest_meal) {
442 if (mon->meating) mon->meating--;
447 * Possibly awaken the given monster. Return a 1 if the monster has been
448 * jolted awake.
450 STATIC_OVL int
451 disturb(mtmp)
452 register struct monst *mtmp;
455 * + Ettins are hard to surprise.
456 * + Nymphs, jabberwocks, and leprechauns do not easily wake up.
458 * Wake up if:
459 * in direct LOS AND
460 * within 10 squares AND
461 * not stealthy or (mon is an ettin and 9/10) AND
462 * (mon is not a nymph, jabberwock, or leprechaun) or 1/50 AND
463 * Aggravate or mon is (dog or human) or
464 * (1/7 and mon is not mimicing furniture or object)
466 if(couldsee(mtmp->mx,mtmp->my) && !(uarmc && uarmc->oartifact == ART_CLANCY_S_FURTIVENESS && rn2(3)) && !(Race_if(PM_VIETIS) && rn2(3)) && !(Race_if(PM_KUTAR) && rn2(3)) &&
467 distu(mtmp->mx,mtmp->my) <= 100 &&
468 (!Stealth || (Stealth && !StrongStealth && !rn2(5)) || (Aggravate_monster && !rn2(3) ) || (mtmp->data == &mons[PM_ETTIN] && rn2(10))) &&
469 (!(mtmp->data->mlet == S_NYMPH
470 || mtmp->data->mlet == S_JABBERWOCK
471 || mtmp->data->mlet == S_LEPRECHAUN) || !rn2(50)) &&
472 (Aggravate_monster
473 || (mtmp->data->mlet == S_DOG
474 || mtmp->data->mlet == S_HUMAN)
475 || (!rn2(7) && (mtmp->m_ap_type != M_AP_FURNITURE) && (mtmp->m_ap_type != M_AP_OBJECT)) )) {
476 mtmp->msleeping = 0;
477 return(1);
479 return(0);
482 /* monster begins fleeing for the specified time, 0 means untimed flee
483 * if first, only adds fleetime if monster isn't already fleeing
484 * if fleemsg, prints a message about new flight, otherwise, caller should */
485 void
486 monflee(mtmp, fleetime, first, fleemsg)
487 struct monst *mtmp;
488 int fleetime;
489 boolean first;
490 boolean fleemsg;
492 if (u.ustuck == mtmp) {
493 if (u.uswallow)
494 expels(mtmp, mtmp->data, TRUE);
495 else if (!sticks(youmonst.data)) {
496 unstuck(mtmp); /* monster lets go when fleeing */
497 You("get released!");
501 if (!first || !mtmp->mflee) {
502 /* don't lose untimed scare */
503 if (!fleetime)
504 mtmp->mfleetim = 0;
505 else if (!mtmp->mflee || mtmp->mfleetim) {
506 fleetime += mtmp->mfleetim;
507 /* ensure monster flees long enough to visibly stop fighting */
508 if (fleetime == 1) fleetime++;
509 mtmp->mfleetim = min(fleetime, 127);
511 if (!mtmp->mflee && fleemsg && canseemon(mtmp) && !mtmp->mfrozen) {
512 if (rn2(3)) {
513 pline("%s turns to flee!", (Monnam(mtmp)));
514 if (isok(u.ux, u.uy) && sengr_at("Elbereth", u.ux, u.uy)) u.cnd_elberethamount++;
515 mtmp->mflee = 1;
517 else {
518 pline("%s is startled for a moment.", (Monnam(mtmp)));
520 } else if (rn2(3)) mtmp->mflee = 1;
522 /* pline("%s turns to flee!", (Monnam(mtmp))); */
523 /*mtmp->mflee = 1;*/
527 STATIC_OVL void
528 distfleeck(mtmp,inrange,nearby,scared)
529 register struct monst *mtmp;
530 int *inrange, *nearby, *scared;
532 int seescaryx, seescaryy;
534 *inrange = (dist2(mtmp->mx, mtmp->my, mtmp->mux, mtmp->muy) <=
535 (BOLT_LIM * BOLT_LIM));
536 *nearby = *inrange && monnear(mtmp, mtmp->mux, mtmp->muy);
538 /* Note: if your image is displaced, the monster sees the Elbereth
539 * at your displaced position, thus never attacking your displaced
540 * position, but possibly attacking you by accident. If you are
541 * invisible, it sees the Elbereth at your real position, thus never
542 * running into you by accident but possibly attacking the spot
543 * where it guesses you are.
545 if (!mtmp->mcansee || (Invis && (StrongInvis || !rn2(3)) && !perceives(mtmp->data))) {
546 seescaryx = mtmp->mux;
547 seescaryy = mtmp->muy;
548 } else {
549 seescaryx = u.ux;
550 seescaryy = u.uy;
553 /* another nerf by Amy: if you use Elbereth, scare monster or sanctuary to make a monster turn to flee,
554 * temporarily reduce the chance that it works; this counter will add up every time it does work, making it
555 * increasingly less likely to work again. This counter should time out back to zero very slowly */
556 if (u.elberethcheese && (rnd(u.elberethcheese + 100) > 100) ) return;
558 /* "super bonus evil patch idea" by jonadab - monsters with only 1HP ignore Elbereth and similar scary stuff
559 * Amy addition: bosses are immune, you lamer, because they're supposed to be a challenge ffs! */
560 *scared =
561 /* elbereth or scare monster scroll */
562 ( (mtmp->mhp > 1) && *nearby && !(mtmp->data->geno & G_UNIQ) &&
563 (onscary(seescaryx, seescaryy, mtmp) && rn2(9)) ||
565 /* sanctuary (aka cheesy exploit for lamers) */
566 (!mtmp->mpeaceful && (rnd(5) > 2) && !(mtmp->data->geno & G_UNIQ) && in_your_sanctuary(mtmp, 0, 0)) );
568 /* note by Amy: I always felt permanent Elbereths were waaaaaaaay too strong.
569 * It's much more interesting if Elbereth has a chance to fail, too.
570 * After all, where's the challenge in burning an Elbereth, then whacking at soldier ants for two hours straight? */
572 if(*scared) {
573 u.elberethcheese++;
574 if (rn2(7))
575 monflee(mtmp, rnd(10), TRUE, TRUE);
576 else
577 monflee(mtmp, rnd(100), TRUE, TRUE);
582 /* perform a special one-time action for a monster; returns -1 if nothing
583 special happened, 0 if monster uses up its turn, 1 if monster is killed */
584 STATIC_OVL int
585 m_arrival(mon)
586 struct monst *mon;
588 mon->mstrategy &= ~STRAT_ARRIVE; /* always reset */
590 return -1;
593 static NEARDATA const char practical[] = {
594 WEAPON_CLASS, ARMOR_CLASS, GEM_CLASS, FOOD_CLASS, 0 };
595 static NEARDATA const char magical[] = {
596 AMULET_CLASS, IMPLANT_CLASS, POTION_CLASS, SCROLL_CLASS, WAND_CLASS, RING_CLASS,
597 SPBOOK_CLASS, 0 };
598 static NEARDATA const char indigestion[] = { BALL_CLASS, ROCK_CLASS, 0 };
599 static NEARDATA const char boulder_class[] = { ROCK_CLASS, 0 };
600 static NEARDATA const char gem_class[] = { GEM_CLASS, 0 };
603 /* returns 1 if monster died moving, 0 otherwise */
604 /* The whole dochugw/m_move/distfleeck/mfndpos section is serious spaghetti
605 * code. --KAA
608 dochug(mtmp)
609 register struct monst *mtmp;
611 register struct permonst *mdat, *mdat2;
612 register int tmp=0;
614 int armpro, armprolimit;
616 int inrange, nearby, scared;
617 #ifdef GOLDOBJ
618 struct obj *ygold = 0, *lepgold = 0;
619 #endif
621 /* Pre-movement adjustments */
623 boolean likegold=0, likegems=0, likeobjs=0, likemagic=0;
624 boolean uses_items=0, likerock=0;
626 mdat = mtmp->data;
628 int fartdistance = 1;
629 if (FemtrapActiveKatharina) fartdistance = (SuperFemtrapKatharina ? 15 : 12);
630 if (FemtrapActiveKatharina && mtmp->crapbonus) fartdistance = (SuperFemtrapKatharina ? 26 : 15);
632 if (TimeStopped && !immune_timestop(mtmp->data)) return 0; /* time stop completely prevents monsters from doing anything, but some are immune --Amy */
633 if (u.stasistime) return 0; /* stasis does the same --Amy */
634 if (uarmf && uarmf->oartifact == ART_ELEVECULT && !rn2(3)) return 0;
636 if (mtmp->mstrategy & STRAT_ARRIVE) {
637 int res = m_arrival(mtmp);
638 if (res >= 0) return res;
641 /* check for waitmask status change */
642 if ((mtmp->mstrategy & STRAT_WAITFORU) &&
643 (m_canseeu(mtmp) || mtmp->mhp < mtmp->mhpmax))
644 mtmp->mstrategy &= ~STRAT_WAITFORU;
646 /* update quest status flags */
647 quest_stat_check(mtmp);
649 if (!mtmp->mcanmove || (mtmp->mstrategy & STRAT_WAITMASK)) {
650 if (Hallucination) newsym(mtmp->mx,mtmp->my);
651 if (mtmp->mcanmove && (mtmp->mstrategy & STRAT_CLOSE) &&
652 !mtmp->msleeping && monnear(mtmp, u.ux, u.uy))
653 quest_talk(mtmp); /* give the leaders a chance to speak */
654 return(0); /* other frozen monsters can't do anything */
657 /* croupiers are meant to mostly stay in their casinos */
658 if ((mdat == &mons[PM_CROUPIER] || mdat == &mons[PM_MASTER_CROUPIER] || mdat == &mons[PM_EXPERIENCED_CROUPIER] || mdat == &mons[PM_EXCEPTIONAL_CROUPIER] || mdat == &mons[PM_ELITE_CROUPIER]) && mtmp->mpeaceful && !mtmp->mtame && rn2(20) && levl[mtmp->mx][mtmp->my].typ == ROOM) return 0;
660 if ((mdat == &mons[PM_BUGBEAM_CUBE] || mdat == &mons[PM_HANGFISH] || mdat == &mons[PM_JOHNNY_SINDACCO] || mdat == &mons[PM_BOXIT_CUBE] || mdat == &mons[PM_IRMGARD] || mdat == &mons[PM_WORM_THAT_WANKS] || mdat == &mons[PM_METH_HEAD] || mdat == &mons[PM_TORSTINA] || mdat == &mons[PM_MARINERV] || mdat == &mons[PM_BLINKLE_BEE] || mdat == &mons[PM_MARISTIN] || mdat == &mons[PM_HUNCHBACKED_LITTLE_MAN] || mdat == &mons[PM_MARIVERT] || mdat == &mons[PM_MARISISTER] || mdat == &mons[PM_OUTER_ONE_NO] || mdat == &mons[PM_FUNNY_ITALIAN] || mdat == &mons[PM_EAR_FIG_MACHINE] || mdat == &mons[PM_POLEPOKER] || mdat == &mons[PM_DISTURBMENT_HEAD]) && !rn2(4)) return 0; /* can sometimes not move; this is by design */
661 if ((mdat == &mons[PM_SARAH_S_AIRTIGHT_PANTS]) && rn2(5)) return 0;
663 if (uarmu && uarmu->oartifact == ART_ARTITFACT && flags.female && !rn2(5)) return 0;
665 if (uwep && uwep->oartifact == ART_STOP_THE_AIRSHIPS && is_flyer(mtmp->data) && !mtmp->mpeaceful && !mtmp->mtame && !rn2(6)) return 0;
667 if (mdat == &mons[PM_BLOTREE] && !rn2(2)) return 0;
669 /* huro troves are for the matrayser race: they're only there as a means of porting your possessions to a different
670 * dungeon level at game start; we don't want them to waste potions of invisibility or similar stuff --Amy */
671 if (mdat == &mons[PM_HURO_TROVE]) return 0;
673 /* there is a chance we will wake it */
674 if (mtmp->msleeping && !disturb(mtmp)) {
675 if (Hallucination) newsym(mtmp->mx,mtmp->my);
676 return(0);
679 if (mtmp->handytime) {
680 mtmp->handytime--;
681 if (mtmp->handytime < 0) mtmp->handytime = 0; /* fail safe */
683 if (!mtmp->handyfirst) {
684 mtmp->handyfirst = TRUE;
685 switch (rnd(16)) {
686 case 1:
687 verbalize("Hey."); break;
688 case 2:
689 verbalize("Hey, how you doing?"); break;
690 case 3:
691 verbalize("Wassup?"); break;
692 case 4:
693 verbalize("Hey dear."); break;
694 case 5:
695 verbalize("Hello there!"); break;
696 case 6:
697 verbalize("Que pasa?"); break;
698 case 7:
699 verbalize("Wei!"); break;
700 case 8:
701 verbalize("Hey mister, good that you're calling."); break;
702 case 9:
703 verbalize("Ah, hi! I was expecting your call!"); break;
704 case 10:
705 verbalize("Hi! Nice to hear from you!"); break;
706 case 11:
707 verbalize("Hi!"); break;
708 case 12:
709 verbalize("Yo wassup man?"); break;
710 case 13:
711 verbalize("Hey handsome!"); break;
712 case 14:
713 verbalize("Hey babe!"); break;
714 case 15:
715 verbalize("Hey! Did I catch you at a bad time?"); break;
716 case 16:
717 verbalize("Hi, how have you been?"); break;
721 if (mtmp->handyfirst && (mtmp->handytime > 0) && rn2(2)) switch (rnd(40)) {
722 case 1:
723 verbalize("How you doing today?"); break;
724 case 2:
725 verbalize("I've seen a mudcrab the other day."); break;
726 case 3:
727 verbalize("Nada, man."); break;
728 case 4:
729 verbalize("Lots of work today..."); break;
730 case 5:
731 verbalize("Fine, and you?"); break;
732 case 6:
733 verbalize("Whatcha doing today?"); break;
734 case 7:
735 verbalize("Wanna meet up later?"); break;
736 case 8:
737 verbalize("That's great!"); break;
738 case 9:
739 verbalize("I see."); break;
740 case 10:
741 verbalize("Cool!"); break;
742 case 11:
743 verbalize("Great news!"); break;
744 case 12:
745 verbalize("Hey, did you hear this story?"); break;
746 case 13:
747 verbalize("I gotta tell you about my relatives..."); break;
748 case 14:
749 verbalize("Nice weather today!"); break;
750 case 15:
751 verbalize("The boss is after me again."); break;
752 case 16:
753 verbalize("I got a new job!"); break;
754 case 17:
755 verbalize("Did you hear that I bought this week's winning lottery ticket?"); break;
756 case 18:
757 verbalize("Have you heard of the guy from Nantuckit?"); break;
758 case 19:
759 verbalize("I'm going to a club tonight, wanna join me?"); break;
760 case 20:
761 verbalize("Yes yes, I understand..."); break;
762 case 21:
763 verbalize("I quite agree, but not exactly, yet I'm not being indecisive."); break;
764 case 22:
765 verbalize("You're so right."); break;
766 case 23:
767 verbalize("He should be castrated."); break;
768 case 24:
769 verbalize("Hmm, what am I supposed to say about that?"); break;
770 case 25:
771 verbalize("That's terrible."); break;
772 case 26:
773 verbalize("Can I help?"); break;
774 case 27:
775 verbalize("Did you tell them?"); break;
776 case 28:
777 verbalize("You should do something about it..."); break;
778 case 29:
779 verbalize("Hey, I'd like to not talk about that on the phone, okay?"); break;
780 case 30:
781 verbalize("Really? Is it a reliable source?"); break;
782 case 31:
783 verbalize("Did you hear that story? About my neighbors?"); break;
784 case 32:
785 verbalize("You won't believe me, but my aunt called yesterday and told me about this great thing..."); break;
786 case 33:
787 verbalize("Watching any good movies on the TV tonight?"); break;
788 case 34:
789 verbalize("Hey I've been thinking, we should go out to a club!"); break;
790 case 35:
791 verbalize("I'd give a clever response to that, but my helmet is constricting my thoughts."); break;
792 case 36:
793 verbalize("Awesome, man!"); break;
794 case 37:
795 verbalize("Wow, you're really lucky!"); break;
796 case 38:
797 verbalize("That's a good thing."); break;
798 case 39:
799 verbalize("Hmm, that doesn't sound so good..."); break;
800 case 40:
801 verbalize("What? Really???"); break;
804 if (mtmp->handyfirst && (mtmp->handytime == 0) ) switch (rnd(21)) {
805 case 1:
806 verbalize("See you later!"); break;
807 case 2:
808 verbalize("Bye!"); break;
809 case 3:
810 verbalize("Later."); break;
811 case 4:
812 verbalize("Bye pal!"); break;
813 case 5:
814 verbalize("Seeya missy!"); break;
815 case 6:
816 verbalize("Call me later!"); break;
817 case 7:
818 verbalize("I am so unwilling to put down the phone! Bye!"); break;
819 case 8:
820 verbalize("Bye bitch!"); break;
821 case 9:
822 verbalize("See ya cunt!"); break;
823 case 10:
824 verbalize("Later dude!"); break;
825 case 11:
826 verbalize("Bah, I got bored of this call anyway."); break;
827 case 12:
828 verbalize("Until next time!"); break;
829 case 13:
830 verbalize("Have a nice time!"); break;
831 case 14:
832 verbalize("Godspeed!"); break;
833 case 15:
834 verbalize("Have a wonderful day!"); break;
835 case 16:
836 verbalize("I enjoyed speaking with you today! Goodbye!"); break;
837 case 17:
838 verbalize("Thanks for calling, please call back if you have any questions."); break;
839 case 18:
840 verbalize("We'll be in touch."); break;
841 case 19:
842 verbalize("Alright, I'll send you the information via e-mail shortly after this call."); break;
843 case 20:
844 verbalize("I'll call you once the update is ready. Have a nice day!"); break;
845 case 21:
846 verbalize("I hope you enjoy the rest of your day."); break;
850 return 0;
853 if(OBJ_AT(mtmp->mx, mtmp->my) && !mtmp->mpeaceful) {
855 register int pctload = (curr_mon_load(mtmp) * 100) / max_mon_load(mtmp);
857 likegold = (likes_gold(mtmp->data) && pctload < 95);
858 likegems = (likes_gems(mtmp->data) && pctload < 85);
859 uses_items = (pctload < 75);
860 likeobjs = (likes_objs(mtmp->data) && pctload < 75);
861 likemagic = (likes_magic(mtmp->data) && pctload < 85);
862 likerock = (throws_rocks(mtmp->data) && pctload < 50 && !In_sokoban(&u.uz));
864 if(g_at(mtmp->mx,mtmp->my) && likegold) mpickgold(mtmp);
866 if(!*in_rooms(mtmp->mx, mtmp->my, SHOPBASE) || !rn2(25)) {
868 if(likeobjs) mpickstuff(mtmp, practical);
869 if(likemagic) mpickstuff(mtmp, magical);
870 if(likerock) mpickstuff(mtmp, boulder_class);
871 if(likegems) mpickstuff(mtmp, gem_class);
872 if(uses_items) mpickstuff(mtmp, (char *)0);
875 if(mtmp->minvis) {
876 newsym(mtmp->mx, mtmp->my);
877 if (mtmp->wormno) see_wsegs(mtmp);
881 if (mdat == &mons[PM_LAG_MONSTER] || mdat == &mons[PM_SLITHER] || mdat == &mons[PM_LAG_DEFENSE_TOWER]) { /* laaaaaaaaaag! :D --Amy */
882 int lagamount = rno(10);
883 while (lagamount > 0) {
884 delay_output();
885 lagamount--;
888 if (mdat == &mons[PM_GAME_FREEZER] && mtmp->mhp < (mtmp->mhpmax / 3)) {
889 int lagamount = rnz(100);
890 while (lagamount > 0) {
891 delay_output();
892 lagamount--;
896 if ((mtmp->data->msound == MS_HANDY || mtmp->egotype_phonecaller) && !mtmp->handytime && !rn2(500)) {
897 mtmp->handytime = 5 + rn2(11);
898 mtmp->handyfirst = FALSE;
899 if (canseemon(mtmp)) pline("%s's phone is ringing!", Monnam(mtmp));
900 else You_hear("a phone ringing!");
903 if ((mtmp->data->msound == MS_PHOTO || mtmp->egotype_cameraclicker) && canseemon(mtmp)) {
904 int photochance = 20;
905 if (ACURR(A_CHA) > 10) photochance -= (ACURR(A_CHA) - 10);
906 if (photochance < 3) photochance = 3;
907 if (mtmp->phototaken) photochance *= 5;
909 if (!rn2(photochance)) {
910 if (rn2(5)) pline("%s announces 'Cheese!'", Monnam(mtmp));
911 else pline("%s announces 'Pin-sel-bue-schel!'", Monnam(mtmp));
912 if (flags.soundok) pline("*click*");
914 if (!resists_blnd(&youmonst)) {
915 You("are blinded by the flash!");
916 make_blinded((long)rnd(25), FALSE);
917 if (!Blind) Your("%s", vision_clears);
919 u.cnd_photo_op++;
920 mtmp->phototaken = TRUE;
924 if (mdat == &mons[PM_FUCKED_UP_RULER]) {
925 if (TimerunBug < 200) TimerunBug += 200;
928 if (FemtrapActiveKlara) {
929 struct obj *footwear = which_armor(mtmp, W_ARMF);
930 if (footwear && ishighheeled(footwear) && !rn2(50) && (distu(mtmp->mx,mtmp->my) <= BOLT_LIM*BOLT_LIM) ) {
931 You_hear(mtmp->female ? "clacking noises." : "distorted clacking noises.");
932 u.cnd_klaratrapcnt++;
936 /* jonadab loooooooves polka music <3 */
937 if ((mdat == &mons[PM_GEHENNOM_S_POLKA_MUSICIAN] && !rn2(5)) || (mdat == &mons[PM_HELLISH_POLKA_SINGER] && !rn2(3)) ) {
938 static const char *polka_msgs[] = {
939 "I brake for birds.",
940 "I rock a lot of polka dots.",
941 "To dance is human, to polka is divine.",
942 "There is never a wrong time for a polka dot.",
943 "Nuapurista kuulu se polokan tahti, jalakani pohjii kutkutti...",
944 "Salivili hipput tupput taeppyt, aeppyt tipput hilijalleen.",
945 "On kauniina muistona Karjalan maa, mutta vielaekin syoemmestae soinnahtaa, kun soittajan sormista kuulla saa, Saekkijaerven polkkaa!",
946 "On sointuna Karjalan kaunoisen: Saekkijaerven polkka!",
947 "Slim Shady won't you please stand up?",
948 "I'm Slim Shady, yes I'm the real Shady; all you other Slim Shadys are just imitating...",
949 "There's a garden, what a garden, Only happy faces bloom there, And there's never any room there, For a worry or a gloom there...",
950 "Sing a song of good cheer, 'Cause the whole gang is here, Roll it out, roll it out, Let's do the beer barrel polka!",
951 "Hoop-dee-doo, hoop-dee-doo, I hear a polka and my troubles are through",
952 "Hoop-dee-doo, hoop-dee-dee, This kind of music is like heaven to me",
953 "I am gonna get my wish, Hoop-dee-doin' it tonight",
954 "In Heaven There Is No Beer, That's why we drink it here, And when we're gone from here, All our friends will be drinking all that beer",
955 "Who laughs this way, ho ho ho? Santa laughs this way, ho ho ho! Ho ho ho, cherry nose, cap on head, suit that's red...",
956 "I come from Alabama with my Banjo on my knee, I'se gwine to Lou'siana...",
957 "De bulgine bust and de hoss ran off, I really thought I'd die; I shut my eyes to hold my bref, Susanna, dont you cry.",
958 "So they say you booked a flight and you'll be leaving. Is it business, is it pleasure, is it both.",
959 "Say hello to someone in Massachusetts, Tip your hat to every lady that you meet, Shake a hand, you'll make a friend in Massachusetts, That New England old-time custom can't be beat.",
960 "Someone stole the kishka, Someone stole the kishka, Who stole the kishka, From the butcher's shop?",
961 "Fat and round and firmly packed, It was hanging on the rack, Someone stole the kishka, When I turned my back!",
963 verbalize("%s", polka_msgs[rn2(SIZE(polka_msgs))]);
965 if (!rn2(5) && ( (distu(mtmp->mx, mtmp->my) <= 49) || !rn2(20)) ) increasesanity(rnz(20));
968 if (mdat == &mons[PM_DARKNESS_ELEMENTAL] || mdat == &mons[PM_PERMADARKNESS_ELEMENTAL]) {
969 if (isok(mtmp->mx, mtmp->my)) levl[mtmp->mx][mtmp->my].lit = FALSE;
972 if (mdat == &mons[PM_ROCK_SPAWNER] || mdat == &mons[PM_LOCKER] || mdat == &mons[PM_UTHGEN_RAPPER] || mdat == &mons[PM_WALLWORKER_ANT] || mdat == &mons[PM_SPIRIT_LOCKER] || mdat == &mons[PM_XORN_LOCKER]) {
973 if (isok(mtmp->mx, mtmp->my) && (!In_sokoban(&u.uz) || !rn2(25)) ) {
974 if (levl[mtmp->mx][mtmp->my].typ == ROOM || levl[mtmp->mx][mtmp->my].typ == CORR || (levl[mtmp->mx][mtmp->my].typ >= ICE && levl[mtmp->mx][mtmp->my].typ <= CRYPTFLOOR) || (levl[mtmp->mx][mtmp->my].typ >= AIR && levl[mtmp->mx][mtmp->my].typ <= RAINCLOUD)) {
975 levl[mtmp->mx][mtmp->my].typ = ROCKWALL;
976 blockorunblock_point(mtmp->mx,mtmp->my);
977 if(cansee(mtmp->mx,mtmp->my)) {
978 newsym(mtmp->mx,mtmp->my);
984 if (mdat == &mons[PM_WALT_IN_PERSON]) {
985 if (isok(mtmp->mx, mtmp->my)) {
986 if (levl[mtmp->mx][mtmp->my].typ == ROOM || levl[mtmp->mx][mtmp->my].typ == CORR || (levl[mtmp->mx][mtmp->my].typ >= ICE && levl[mtmp->mx][mtmp->my].typ <= CRYPTFLOOR) || (levl[mtmp->mx][mtmp->my].typ >= AIR && levl[mtmp->mx][mtmp->my].typ <= RAINCLOUD)) {
987 levl[mtmp->mx][mtmp->my].typ = GRAVEWALL;
988 blockorunblock_point(mtmp->mx,mtmp->my);
989 if(cansee(mtmp->mx,mtmp->my)) {
990 newsym(mtmp->mx,mtmp->my);
996 if (mdat == &mons[PM_CONSTRUCTION_WORKER]) {
997 if (isok(mtmp->mx, mtmp->my) && (!In_sokoban(&u.uz) || !rn2(25))) {
998 if (levl[mtmp->mx][mtmp->my].typ == ROOM || levl[mtmp->mx][mtmp->my].typ == CORR || (levl[mtmp->mx][mtmp->my].typ >= ICE && levl[mtmp->mx][mtmp->my].typ <= CRYPTFLOOR) || (levl[mtmp->mx][mtmp->my].typ >= AIR && levl[mtmp->mx][mtmp->my].typ <= RAINCLOUD)) {
999 levl[mtmp->mx][mtmp->my].typ = TUNNELWALL;
1000 blockorunblock_point(mtmp->mx,mtmp->my);
1001 if(cansee(mtmp->mx,mtmp->my)) {
1002 newsym(mtmp->mx,mtmp->my);
1008 if (mdat == &mons[PM_TERRIFYING_POISON_IVY]) {
1009 if (isok(mtmp->mx, mtmp->my) && (!In_sokoban(&u.uz) || !rn2(25))) {
1010 if (levl[mtmp->mx][mtmp->my].typ == ROOM || levl[mtmp->mx][mtmp->my].typ == CORR || (levl[mtmp->mx][mtmp->my].typ >= ICE && levl[mtmp->mx][mtmp->my].typ <= CRYPTFLOOR) || (levl[mtmp->mx][mtmp->my].typ >= AIR && levl[mtmp->mx][mtmp->my].typ <= RAINCLOUD)) {
1011 if ((levl[mtmp->mx][mtmp->my].wall_info & W_NONDIGGABLE) == 0) levl[mtmp->mx][mtmp->my].typ = TREE;
1012 blockorunblock_point(mtmp->mx,mtmp->my);
1013 if(cansee(mtmp->mx,mtmp->my)) {
1014 newsym(mtmp->mx,mtmp->my);
1020 if (mdat == &mons[PM_BJARNARHAVEN_FARMER]) {
1021 if (isok(mtmp->mx, mtmp->my) && (!In_sokoban(&u.uz) || !rn2(25))) {
1022 if (levl[mtmp->mx][mtmp->my].typ == ROOM || levl[mtmp->mx][mtmp->my].typ == CORR || (levl[mtmp->mx][mtmp->my].typ >= ICE && levl[mtmp->mx][mtmp->my].typ <= CRYPTFLOOR) || (levl[mtmp->mx][mtmp->my].typ >= AIR && levl[mtmp->mx][mtmp->my].typ <= RAINCLOUD)) {
1023 levl[mtmp->mx][mtmp->my].typ = FARMLAND;
1024 blockorunblock_point(mtmp->mx,mtmp->my);
1025 if(cansee(mtmp->mx,mtmp->my)) {
1026 newsym(mtmp->mx,mtmp->my);
1032 if (mdat == &mons[PM_MOUNTAIN_GOLEM] || mdat == &mons[PM_PHASING_MOUNTAIN_GOLEM]) {
1033 if (isok(mtmp->mx, mtmp->my) && (!In_sokoban(&u.uz) || !rn2(25))) {
1034 if (levl[mtmp->mx][mtmp->my].typ == ROOM || levl[mtmp->mx][mtmp->my].typ == CORR || (levl[mtmp->mx][mtmp->my].typ >= ICE && levl[mtmp->mx][mtmp->my].typ <= CRYPTFLOOR) || (levl[mtmp->mx][mtmp->my].typ >= AIR && levl[mtmp->mx][mtmp->my].typ <= RAINCLOUD)) {
1035 levl[mtmp->mx][mtmp->my].typ = MOUNTAIN;
1036 blockorunblock_point(mtmp->mx,mtmp->my);
1037 if(cansee(mtmp->mx,mtmp->my)) {
1038 newsym(mtmp->mx,mtmp->my);
1044 if (mdat == &mons[PM_WATERSPLASH_NYMPH]) {
1045 if (isok(mtmp->mx, mtmp->my) && (!In_sokoban(&u.uz) || !rn2(25))) {
1046 if (levl[mtmp->mx][mtmp->my].typ == ROOM || levl[mtmp->mx][mtmp->my].typ == CORR || (levl[mtmp->mx][mtmp->my].typ >= ICE && levl[mtmp->mx][mtmp->my].typ <= CRYPTFLOOR) || (levl[mtmp->mx][mtmp->my].typ >= AIR && levl[mtmp->mx][mtmp->my].typ <= RAINCLOUD)) {
1047 levl[mtmp->mx][mtmp->my].typ = POOL;
1048 blockorunblock_point(mtmp->mx,mtmp->my);
1049 if(cansee(mtmp->mx,mtmp->my)) {
1050 newsym(mtmp->mx,mtmp->my);
1056 if (mdat == &mons[PM_DELUGE_NYMPH]) {
1057 if (isok(mtmp->mx, mtmp->my) && (!In_sokoban(&u.uz) || !rn2(25))) {
1058 if (levl[mtmp->mx][mtmp->my].typ == ROOM || levl[mtmp->mx][mtmp->my].typ == CORR || (levl[mtmp->mx][mtmp->my].typ >= ICE && levl[mtmp->mx][mtmp->my].typ <= CRYPTFLOOR) || (levl[mtmp->mx][mtmp->my].typ >= AIR && levl[mtmp->mx][mtmp->my].typ <= RAINCLOUD)) {
1059 levl[mtmp->mx][mtmp->my].typ = MOAT;
1060 blockorunblock_point(mtmp->mx,mtmp->my);
1061 if(cansee(mtmp->mx,mtmp->my)) {
1062 newsym(mtmp->mx,mtmp->my);
1068 if (mdat == &mons[PM_DRIPPER_GHOST]) {
1069 if (isok(mtmp->mx, mtmp->my) && (!In_sokoban(&u.uz) || !rn2(25))) {
1070 if (levl[mtmp->mx][mtmp->my].typ == ROOM || levl[mtmp->mx][mtmp->my].typ == CORR || (levl[mtmp->mx][mtmp->my].typ <= ROCKWALL && ((levl[mtmp->mx][mtmp->my].wall_info & W_NONDIGGABLE) == 0) ) ) {
1071 levl[mtmp->mx][mtmp->my].typ = MOAT;
1072 blockorunblock_point(mtmp->mx,mtmp->my);
1073 if(cansee(mtmp->mx,mtmp->my)) {
1074 newsym(mtmp->mx,mtmp->my);
1080 if (AefdeActive && (mtmp->data->maligntyp < 0) && !rn2(25)) {
1081 if (isok(mtmp->mx, mtmp->my) && (!In_sokoban(&u.uz) || !rn2(25))) {
1082 if (levl[mtmp->mx][mtmp->my].typ == ROOM || levl[mtmp->mx][mtmp->my].typ == CORR) {
1083 int wallclass = randomwalltype();
1085 if (wallclass != TREE || (levl[mtmp->mx][mtmp->my].wall_info & W_NONDIGGABLE) == 0) levl[mtmp->mx][mtmp->my].typ = wallclass;
1086 blockorunblock_point(mtmp->mx,mtmp->my);
1087 if(cansee(mtmp->mx,mtmp->my)) {
1088 newsym(mtmp->mx,mtmp->my);
1095 if (mdat == &mons[PM_TERRAINDRIPPER]) {
1096 if (isok(mtmp->mx, mtmp->my) && (!In_sokoban(&u.uz) || !rn2(25))) {
1097 if (levl[mtmp->mx][mtmp->my].typ == ROOM || levl[mtmp->mx][mtmp->my].typ == CORR || (levl[mtmp->mx][mtmp->my].typ <= ROCKWALL && ((levl[mtmp->mx][mtmp->my].wall_info & W_NONDIGGABLE) == 0) ) ) {
1098 int wallclass = randomwalltype();
1100 if (wallclass != TREE || (levl[mtmp->mx][mtmp->my].wall_info & W_NONDIGGABLE) == 0) levl[mtmp->mx][mtmp->my].typ = wallclass;
1101 blockorunblock_point(mtmp->mx,mtmp->my);
1102 if(cansee(mtmp->mx,mtmp->my)) {
1103 newsym(mtmp->mx,mtmp->my);
1109 if (mdat == &mons[PM_VOLCANIC_NYMPH] || mdat == &mons[PM_SUPER_ANNOYING_NYMPH]) {
1110 if (isok(mtmp->mx, mtmp->my) && (!In_sokoban(&u.uz) || !rn2(25))) {
1111 if (levl[mtmp->mx][mtmp->my].typ == ROOM || levl[mtmp->mx][mtmp->my].typ == CORR || (levl[mtmp->mx][mtmp->my].typ >= ICE && levl[mtmp->mx][mtmp->my].typ <= CRYPTFLOOR) || (levl[mtmp->mx][mtmp->my].typ >= AIR && levl[mtmp->mx][mtmp->my].typ <= RAINCLOUD)) {
1112 levl[mtmp->mx][mtmp->my].typ = LAVAPOOL;
1113 blockorunblock_point(mtmp->mx,mtmp->my);
1114 if(cansee(mtmp->mx,mtmp->my)) {
1115 newsym(mtmp->mx,mtmp->my);
1121 if (mdat == &mons[PM_TERRAIN_CLEANER] || mdat == &mons[PM_TERRAIN_DIGGER]) {
1122 if (isok(mtmp->mx, mtmp->my) && (!In_sokoban(&u.uz) || !rn2(25))) {
1123 if ((levl[mtmp->mx][mtmp->my].typ >= TREE && levl[mtmp->mx][mtmp->my].typ <= MOUNTAIN) || (levl[mtmp->mx][mtmp->my].typ >= POOL && levl[mtmp->mx][mtmp->my].typ <= URINELAKE) || (levl[mtmp->mx][mtmp->my].typ >= SHIFTINGSAND && levl[mtmp->mx][mtmp->my].typ <= IRONBARS) || (levl[mtmp->mx][mtmp->my].typ >= ICE && levl[mtmp->mx][mtmp->my].typ <= CRYPTFLOOR) || (levl[mtmp->mx][mtmp->my].typ >= AIR && levl[mtmp->mx][mtmp->my].typ <= RAINCLOUD)) {
1124 levl[mtmp->mx][mtmp->my].typ = CORR;
1125 blockorunblock_point(mtmp->mx,mtmp->my);
1126 if(cansee(mtmp->mx,mtmp->my)) {
1127 newsym(mtmp->mx,mtmp->my);
1133 if (mdat == &mons[PM_MIRA_S_AGENT]) {
1134 if (isok(mtmp->mx, mtmp->my)) {
1135 if (levl[mtmp->mx][mtmp->my].typ == ROOM || levl[mtmp->mx][mtmp->my].typ == CORR || (levl[mtmp->mx][mtmp->my].typ >= ICE && levl[mtmp->mx][mtmp->my].typ <= CRYPTFLOOR) || (levl[mtmp->mx][mtmp->my].typ >= AIR && levl[mtmp->mx][mtmp->my].typ <= RAINCLOUD)) {
1136 levl[mtmp->mx][mtmp->my].typ = URINELAKE;
1137 blockorunblock_point(mtmp->mx,mtmp->my);
1138 if(cansee(mtmp->mx,mtmp->my)) {
1139 newsym(mtmp->mx,mtmp->my);
1145 if (mdat == &mons[PM_WHARF_TROLL]) {
1146 if (isok(mtmp->mx, mtmp->my) && (!In_sokoban(&u.uz) || !rn2(25))) {
1147 if (levl[mtmp->mx][mtmp->my].typ == ROOM || levl[mtmp->mx][mtmp->my].typ == CORR || (levl[mtmp->mx][mtmp->my].typ >= ICE && levl[mtmp->mx][mtmp->my].typ <= CRYPTFLOOR) || (levl[mtmp->mx][mtmp->my].typ >= AIR && levl[mtmp->mx][mtmp->my].typ <= RAINCLOUD)) {
1148 levl[mtmp->mx][mtmp->my].typ = WATERTUNNEL;
1149 blockorunblock_point(mtmp->mx,mtmp->my);
1150 if(cansee(mtmp->mx,mtmp->my)) {
1151 newsym(mtmp->mx,mtmp->my);
1157 if (mdat == &mons[PM_CAVE_MOUSER] || mdat == &mons[PM_BROODY_CAVE_MOUSER]) {
1158 if (isok(mtmp->mx, mtmp->my) && (!In_sokoban(&u.uz) || !rn2(25))) {
1159 if (levl[mtmp->mx][mtmp->my].typ == ROOM || levl[mtmp->mx][mtmp->my].typ == CORR || (levl[mtmp->mx][mtmp->my].typ >= ICE && levl[mtmp->mx][mtmp->my].typ <= CRYPTFLOOR) || (levl[mtmp->mx][mtmp->my].typ >= AIR && levl[mtmp->mx][mtmp->my].typ <= RAINCLOUD)) {
1160 levl[mtmp->mx][mtmp->my].typ = CRYSTALWATER;
1161 blockorunblock_point(mtmp->mx,mtmp->my);
1162 if(cansee(mtmp->mx,mtmp->my)) {
1163 newsym(mtmp->mx,mtmp->my);
1169 if (mdat == &mons[PM_SUMP_DRAGON]) {
1170 if (isok(mtmp->mx, mtmp->my)) {
1171 if (levl[mtmp->mx][mtmp->my].typ == ROOM || levl[mtmp->mx][mtmp->my].typ == CORR || (levl[mtmp->mx][mtmp->my].typ >= ICE && levl[mtmp->mx][mtmp->my].typ <= CRYPTFLOOR) || (levl[mtmp->mx][mtmp->my].typ >= AIR && levl[mtmp->mx][mtmp->my].typ <= RAINCLOUD)) {
1172 levl[mtmp->mx][mtmp->my].typ = MOORLAND;
1173 blockorunblock_point(mtmp->mx,mtmp->my);
1174 if(cansee(mtmp->mx,mtmp->my)) {
1175 newsym(mtmp->mx,mtmp->my);
1181 if (mdat == &mons[PM_KLEPTO]) {
1182 if (isok(mtmp->mx, mtmp->my) && (!In_sokoban(&u.uz) || !rn2(25))) {
1183 if (levl[mtmp->mx][mtmp->my].typ == ROOM || levl[mtmp->mx][mtmp->my].typ == CORR || (levl[mtmp->mx][mtmp->my].typ >= ICE && levl[mtmp->mx][mtmp->my].typ <= CRYPTFLOOR) || (levl[mtmp->mx][mtmp->my].typ >= AIR && levl[mtmp->mx][mtmp->my].typ <= RAINCLOUD)) {
1184 levl[mtmp->mx][mtmp->my].typ = SHIFTINGSAND;
1185 blockorunblock_point(mtmp->mx,mtmp->my);
1186 if(cansee(mtmp->mx,mtmp->my)) {
1187 newsym(mtmp->mx,mtmp->my);
1193 if (mdat == &mons[PM_JASON_SEEKER]) {
1194 if (isok(mtmp->mx, mtmp->my)) {
1195 if (levl[mtmp->mx][mtmp->my].typ == ROOM || levl[mtmp->mx][mtmp->my].typ == CORR || (levl[mtmp->mx][mtmp->my].typ >= ICE && levl[mtmp->mx][mtmp->my].typ <= CRYPTFLOOR) || (levl[mtmp->mx][mtmp->my].typ >= AIR && levl[mtmp->mx][mtmp->my].typ <= RAINCLOUD)) {
1196 levl[mtmp->mx][mtmp->my].typ = STYXRIVER;
1197 blockorunblock_point(mtmp->mx,mtmp->my);
1198 if(cansee(mtmp->mx,mtmp->my)) {
1199 newsym(mtmp->mx,mtmp->my);
1205 if (mdat == &mons[PM_EXTREME_IRON_BAR]) {
1206 if (isok(mtmp->mx, mtmp->my) && (!In_sokoban(&u.uz) || !rn2(25))) {
1207 if (levl[mtmp->mx][mtmp->my].typ == ROOM || levl[mtmp->mx][mtmp->my].typ == CORR || (levl[mtmp->mx][mtmp->my].typ >= ICE && levl[mtmp->mx][mtmp->my].typ <= CRYPTFLOOR) || (levl[mtmp->mx][mtmp->my].typ >= AIR && levl[mtmp->mx][mtmp->my].typ <= RAINCLOUD)) {
1208 levl[mtmp->mx][mtmp->my].typ = IRONBARS;
1209 blockorunblock_point(mtmp->mx,mtmp->my);
1210 if(cansee(mtmp->mx,mtmp->my)) {
1211 newsym(mtmp->mx,mtmp->my);
1217 if (mdat == &mons[PM_HAPPY_CLOUD]) {
1218 if (isok(mtmp->mx, mtmp->my) && (!In_sokoban(&u.uz) || !rn2(25))) {
1219 if (levl[mtmp->mx][mtmp->my].typ == ROOM || levl[mtmp->mx][mtmp->my].typ == CORR || (levl[mtmp->mx][mtmp->my].typ >= ICE && levl[mtmp->mx][mtmp->my].typ <= CRYPTFLOOR) || (levl[mtmp->mx][mtmp->my].typ >= AIR && levl[mtmp->mx][mtmp->my].typ <= RAINCLOUD)) {
1220 levl[mtmp->mx][mtmp->my].typ = CLOUD;
1221 blockorunblock_point(mtmp->mx,mtmp->my);
1222 if(cansee(mtmp->mx,mtmp->my)) {
1223 newsym(mtmp->mx,mtmp->my);
1229 if (mdat == &mons[PM_VERY_CHILLY_MAMMOTH] || mdat == &mons[PM_ICE_LICH]) {
1230 if (isok(mtmp->mx, mtmp->my)) {
1231 if (levl[mtmp->mx][mtmp->my].typ == ROOM || levl[mtmp->mx][mtmp->my].typ == CORR || (levl[mtmp->mx][mtmp->my].typ >= ICE && levl[mtmp->mx][mtmp->my].typ <= CRYPTFLOOR) || (levl[mtmp->mx][mtmp->my].typ >= AIR && levl[mtmp->mx][mtmp->my].typ <= RAINCLOUD)) {
1232 levl[mtmp->mx][mtmp->my].typ = ICE;
1233 blockorunblock_point(mtmp->mx,mtmp->my);
1234 if(cansee(mtmp->mx,mtmp->my)) {
1235 newsym(mtmp->mx,mtmp->my);
1241 if (mdat == &mons[PM_SNOW_LETTER] || mdat == &mons[PM_SNOW_FROSTER]) {
1242 if (isok(mtmp->mx, mtmp->my)) {
1243 if (levl[mtmp->mx][mtmp->my].typ == ROOM || levl[mtmp->mx][mtmp->my].typ == CORR || (levl[mtmp->mx][mtmp->my].typ >= ICE && levl[mtmp->mx][mtmp->my].typ <= CRYPTFLOOR) || (levl[mtmp->mx][mtmp->my].typ >= AIR && levl[mtmp->mx][mtmp->my].typ <= RAINCLOUD)) {
1244 levl[mtmp->mx][mtmp->my].typ = SNOW;
1245 blockorunblock_point(mtmp->mx,mtmp->my);
1246 if(cansee(mtmp->mx,mtmp->my)) {
1247 newsym(mtmp->mx,mtmp->my);
1253 if (mdat == &mons[PM_WASTE_DEADRA] || mdat == &mons[PM_ASH_GOLEM]) {
1254 if (isok(mtmp->mx, mtmp->my)) {
1255 if (levl[mtmp->mx][mtmp->my].typ == ROOM || levl[mtmp->mx][mtmp->my].typ == CORR || (levl[mtmp->mx][mtmp->my].typ >= ICE && levl[mtmp->mx][mtmp->my].typ <= CRYPTFLOOR) || (levl[mtmp->mx][mtmp->my].typ >= AIR && levl[mtmp->mx][mtmp->my].typ <= RAINCLOUD)) {
1256 levl[mtmp->mx][mtmp->my].typ = ASH;
1257 blockorunblock_point(mtmp->mx,mtmp->my);
1258 if(cansee(mtmp->mx,mtmp->my)) {
1259 newsym(mtmp->mx,mtmp->my);
1265 if (mdat == &mons[PM_SAND_DROPPER] || mdat == &mons[PM_SAND_DRAGON]) {
1266 if (isok(mtmp->mx, mtmp->my)) {
1267 if (levl[mtmp->mx][mtmp->my].typ == ROOM || levl[mtmp->mx][mtmp->my].typ == CORR || (levl[mtmp->mx][mtmp->my].typ >= ICE && levl[mtmp->mx][mtmp->my].typ <= CRYPTFLOOR) || (levl[mtmp->mx][mtmp->my].typ >= AIR && levl[mtmp->mx][mtmp->my].typ <= RAINCLOUD)) {
1268 levl[mtmp->mx][mtmp->my].typ = SAND;
1269 blockorunblock_point(mtmp->mx,mtmp->my);
1270 if(cansee(mtmp->mx,mtmp->my)) {
1271 newsym(mtmp->mx,mtmp->my);
1277 if (mdat == &mons[PM_ANIMATED_PAVEMENT_HEEL] || mdat == &mons[PM_SHADE_OF_THE_KING]) {
1278 if (isok(mtmp->mx, mtmp->my)) {
1279 if (levl[mtmp->mx][mtmp->my].typ == ROOM || levl[mtmp->mx][mtmp->my].typ == CORR || (levl[mtmp->mx][mtmp->my].typ >= ICE && levl[mtmp->mx][mtmp->my].typ <= CRYPTFLOOR) || (levl[mtmp->mx][mtmp->my].typ >= AIR && levl[mtmp->mx][mtmp->my].typ <= RAINCLOUD)) {
1280 levl[mtmp->mx][mtmp->my].typ = PAVEDFLOOR;
1281 blockorunblock_point(mtmp->mx,mtmp->my);
1282 if(cansee(mtmp->mx,mtmp->my)) {
1283 newsym(mtmp->mx,mtmp->my);
1289 if (mdat == &mons[PM_HIGHWAY_RACER] || mdat == &mons[PM_SPEEDOKRAKEN]) {
1290 if (isok(mtmp->mx, mtmp->my)) {
1291 if (levl[mtmp->mx][mtmp->my].typ == ROOM || levl[mtmp->mx][mtmp->my].typ == CORR || (levl[mtmp->mx][mtmp->my].typ >= ICE && levl[mtmp->mx][mtmp->my].typ <= CRYPTFLOOR) || (levl[mtmp->mx][mtmp->my].typ >= AIR && levl[mtmp->mx][mtmp->my].typ <= RAINCLOUD)) {
1292 levl[mtmp->mx][mtmp->my].typ = HIGHWAY;
1293 blockorunblock_point(mtmp->mx,mtmp->my);
1294 if(cansee(mtmp->mx,mtmp->my)) {
1295 newsym(mtmp->mx,mtmp->my);
1301 if (mdat == &mons[PM_GRASS_SPY] || mdat == &mons[PM_WAR_CRIMER]) {
1302 if (isok(mtmp->mx, mtmp->my)) {
1303 if (levl[mtmp->mx][mtmp->my].typ == ROOM || levl[mtmp->mx][mtmp->my].typ == CORR || (levl[mtmp->mx][mtmp->my].typ >= ICE && levl[mtmp->mx][mtmp->my].typ <= CRYPTFLOOR) || (levl[mtmp->mx][mtmp->my].typ >= AIR && levl[mtmp->mx][mtmp->my].typ <= RAINCLOUD)) {
1304 levl[mtmp->mx][mtmp->my].typ = GRASSLAND;
1305 blockorunblock_point(mtmp->mx,mtmp->my);
1306 if(cansee(mtmp->mx,mtmp->my)) {
1307 newsym(mtmp->mx,mtmp->my);
1313 if (mdat == &mons[PM_NETHERREALM_GHOST] || mdat == &mons[PM_ABSOLUTE_NETHER_DRAGON]) {
1314 if (isok(mtmp->mx, mtmp->my)) {
1315 if (levl[mtmp->mx][mtmp->my].typ == ROOM || levl[mtmp->mx][mtmp->my].typ == CORR || (levl[mtmp->mx][mtmp->my].typ >= ICE && levl[mtmp->mx][mtmp->my].typ <= CRYPTFLOOR) || (levl[mtmp->mx][mtmp->my].typ >= AIR && levl[mtmp->mx][mtmp->my].typ <= RAINCLOUD)) {
1316 levl[mtmp->mx][mtmp->my].typ = NETHERMIST;
1317 blockorunblock_point(mtmp->mx,mtmp->my);
1318 if(cansee(mtmp->mx,mtmp->my)) {
1319 newsym(mtmp->mx,mtmp->my);
1325 if (mdat == &mons[PM_STALACTITE_CRUNCHER] || mdat == &mons[PM_STALACTUNNITE]) {
1326 if (isok(mtmp->mx, mtmp->my)) {
1327 if (levl[mtmp->mx][mtmp->my].typ == ROOM || levl[mtmp->mx][mtmp->my].typ == CORR || (levl[mtmp->mx][mtmp->my].typ >= ICE && levl[mtmp->mx][mtmp->my].typ <= CRYPTFLOOR) || (levl[mtmp->mx][mtmp->my].typ >= AIR && levl[mtmp->mx][mtmp->my].typ <= RAINCLOUD)) {
1328 levl[mtmp->mx][mtmp->my].typ = STALACTITE;
1329 blockorunblock_point(mtmp->mx,mtmp->my);
1330 if(cansee(mtmp->mx,mtmp->my)) {
1331 newsym(mtmp->mx,mtmp->my);
1337 if (mdat == &mons[PM_FLEECY_BUBBLE] || mdat == &mons[PM_BALLBATH_WOMAN]) {
1338 if (isok(mtmp->mx, mtmp->my)) {
1339 if (levl[mtmp->mx][mtmp->my].typ == ROOM || levl[mtmp->mx][mtmp->my].typ == CORR || (levl[mtmp->mx][mtmp->my].typ >= ICE && levl[mtmp->mx][mtmp->my].typ <= CRYPTFLOOR) || (levl[mtmp->mx][mtmp->my].typ >= AIR && levl[mtmp->mx][mtmp->my].typ <= RAINCLOUD)) {
1340 levl[mtmp->mx][mtmp->my].typ = BUBBLES;
1341 blockorunblock_point(mtmp->mx,mtmp->my);
1342 if(cansee(mtmp->mx,mtmp->my)) {
1343 newsym(mtmp->mx,mtmp->my);
1349 if (mdat == &mons[PM_STORMY_WEATHER] || mdat == &mons[PM_GUY_THAT_LOOKS_LIKE_A_RAINER]) {
1350 if (isok(mtmp->mx, mtmp->my)) {
1351 if (levl[mtmp->mx][mtmp->my].typ == ROOM || levl[mtmp->mx][mtmp->my].typ == CORR || (levl[mtmp->mx][mtmp->my].typ >= ICE && levl[mtmp->mx][mtmp->my].typ <= CRYPTFLOOR) || (levl[mtmp->mx][mtmp->my].typ >= AIR && levl[mtmp->mx][mtmp->my].typ <= RAINCLOUD)) {
1352 levl[mtmp->mx][mtmp->my].typ = RAINCLOUD;
1353 blockorunblock_point(mtmp->mx,mtmp->my);
1354 if(cansee(mtmp->mx,mtmp->my)) {
1355 newsym(mtmp->mx,mtmp->my);
1361 if (mdat == &mons[PM_CHAOS_TILER] || mdat == &mons[PM_CHAOTIC_FILLER]) {
1362 if (isok(mtmp->mx, mtmp->my)) {
1363 if (levl[mtmp->mx][mtmp->my].typ == ROOM || levl[mtmp->mx][mtmp->my].typ == CORR) {
1365 int wallclass = randomwalltype();
1367 if (wallclass != TREE || (levl[mtmp->mx][mtmp->my].wall_info & W_NONDIGGABLE) == 0) levl[mtmp->mx][mtmp->my].typ = wallclass;
1368 blockorunblock_point(mtmp->mx,mtmp->my);
1369 if(cansee(mtmp->mx,mtmp->my)) {
1370 newsym(mtmp->mx,mtmp->my);
1376 if (mdat == &mons[PM_DIMM_COIN]) {
1377 if (isok(mtmp->mx, mtmp->my)) {
1378 if (levl[mtmp->mx][mtmp->my].typ == ROOM || levl[mtmp->mx][mtmp->my].typ == CORR) {
1380 int wallclass = GRASSLAND;
1381 switch (mtmp->terraintrans) {
1382 case 1:
1383 wallclass = TREE; break;
1384 case 2:
1385 wallclass = MOAT; break;
1386 case 3:
1387 wallclass = LAVAPOOL; break;
1388 case 4:
1389 wallclass = IRONBARS; break;
1390 case 5:
1391 wallclass = CORR; break;
1392 case 6:
1393 wallclass = ICE; break;
1394 case 7:
1395 wallclass = CLOUD; break;
1396 case 8:
1397 wallclass = ROCKWALL; break;
1398 case 9:
1399 wallclass = GRAVEWALL; break;
1400 case 10:
1401 wallclass = TUNNELWALL; break;
1402 case 11:
1403 wallclass = FARMLAND; break;
1404 case 12:
1405 wallclass = MOUNTAIN; break;
1406 case 13:
1407 wallclass = WATERTUNNEL; break;
1408 case 14:
1409 wallclass = CRYSTALWATER; break;
1410 case 15:
1411 wallclass = MOORLAND; break;
1412 case 16:
1413 wallclass = URINELAKE; break;
1414 case 17:
1415 wallclass = SHIFTINGSAND; break;
1416 case 18:
1417 wallclass = STYXRIVER; break;
1418 case 19:
1419 wallclass = SNOW; break;
1420 case 20:
1421 wallclass = ASH; break;
1422 case 21:
1423 wallclass = SAND; break;
1424 case 22:
1425 wallclass = PAVEDFLOOR; break;
1426 case 23:
1427 wallclass = HIGHWAY; break;
1428 case 24:
1429 wallclass = GRASSLAND; break;
1430 case 25:
1431 wallclass = NETHERMIST; break;
1432 case 26:
1433 wallclass = STALACTITE; break;
1434 case 27:
1435 wallclass = CRYPTFLOOR; break;
1436 case 28:
1437 wallclass = BUBBLES; break;
1438 case 29:
1439 wallclass = RAINCLOUD; break;
1442 if (wallclass != TREE || (levl[mtmp->mx][mtmp->my].wall_info & W_NONDIGGABLE) == 0) levl[mtmp->mx][mtmp->my].typ = wallclass;
1443 blockorunblock_point(mtmp->mx,mtmp->my);
1444 if(cansee(mtmp->mx,mtmp->my)) {
1445 newsym(mtmp->mx,mtmp->my);
1451 if (mdat == &mons[PM_DEVIOUS_TRAP_INSTALLER] && !rn2(5)) {
1452 if (isok(mtmp->mx, mtmp->my) && (!In_sokoban(&u.uz) || !rn2(25))) {
1453 if (!(t_at(mtmp->mx, mtmp->my))) {
1454 (void) maketrap(mtmp->mx, mtmp->my, rndtrap(), 100, FALSE);
1459 if (mdat == &mons[PM_LITTLE_HIDDEN_BOX]) {
1460 if (isok(mtmp->mx, mtmp->my) && (!In_sokoban(&u.uz) || !rn2(25))) {
1461 if (!(t_at(mtmp->mx, mtmp->my))) {
1462 (void) maketrap(mtmp->mx, mtmp->my, rndtrap(), 100, FALSE);
1467 if (mdat == &mons[PM_XTRA_WEBBER] && !rn2(3)) {
1468 if (isok(mtmp->mx, mtmp->my) && (!In_sokoban(&u.uz) || !rn2(25))) {
1469 if (!(t_at(mtmp->mx, mtmp->my))) {
1470 (void) maketrap(mtmp->mx, mtmp->my, rndtrap(), 100, FALSE);
1475 if (mdat == &mons[PM_SUPERREGENEBOROS]) {
1476 if (isok(mtmp->mx, mtmp->my) && (!In_sokoban(&u.uz) || !rn2(25))) {
1477 if (!(t_at(mtmp->mx, mtmp->my))) {
1478 (void) maketrap(mtmp->mx, mtmp->my, rndtrap(), 100, FALSE);
1483 if ((mtmp->data->geno & G_UNIQ) && !rn2(20) && (RangCallEffect || (uarmc && uarmc->oartifact == ART_CLOAK_OF_THE_UNHELD_ONE) || (uarmc && uarmc->oartifact == ART_CLOAK_OF_THE_UNHELD_POTATO) || u.uprops[RANG_CALL_EFFECT].extrinsic || have_rangcallstone())) {
1484 pline("A horrible call rang in your head...");
1485 if (RangCallXtra) increasesanity(5);
1486 else increasesanity(1);
1489 if ((mdat == &mons[PM_KRINSCH_SAEIER] || mdat == &mons[PM_KRINSCHESTES_TSCHEILD]) && !rn2(10) && (distu(mtmp->mx,mtmp->my) <= BOLT_LIM*BOLT_LIM) ) {
1490 verbalize(rn2(2) ? "krinsch" : "is ja krinsch");
1492 if (mdat == &mons[PM_LOSTESTER_TEENAGER] && !rn2(10) && (distu(mtmp->mx,mtmp->my) <= BOLT_LIM*BOLT_LIM) ) {
1493 verbalize(rn2(2) ? "lost" : "is ja lost");
1495 if (mdat == &mons[PM_BUNDLE_MONSTER] && !rn2(10) && (distu(mtmp->mx,mtmp->my) <= BOLT_LIM*BOLT_LIM) ) {
1496 You_hear("'bundlebundlebundle!!'");
1498 if (mdat == &mons[PM_CUDDLE_MONSTER] && !rn2(10) && (distu(mtmp->mx,mtmp->my) <= BOLT_LIM*BOLT_LIM) ) {
1499 You_hear("'cuddlecuddlecuddle!!'");
1501 if (mdat == &mons[PM_FLEECE_MONSTER] && !rn2(10) && (distu(mtmp->mx,mtmp->my) <= BOLT_LIM*BOLT_LIM) ) {
1502 You_hear("'fleecelfleecelfleecel!!'");
1504 if (mdat == &mons[PM_FELEECHY] && !rn2(10) && (distu(mtmp->mx,mtmp->my) <= BOLT_LIM*BOLT_LIM) ) {
1505 You_hear("'feleechfeleechfeleech!!'");
1508 if (mdat == &mons[PM_UBERNAZGUL] && rn2(2)) { /* sporkhack nazgul --Amy */
1509 if (canseemon(mtmp)) {
1510 pline("%s screams!",Monnam(mtmp));
1511 } else {
1512 You_hear("a horrific scream!");
1514 if (u.usleep) { unmul("You are shocked awake!"); }
1515 Your("mind reels from the noise!");
1516 make_stunned(HStun + rnd(20),FALSE);
1520 if ((WakeupCallBug || (uarm && uarm->oartifact == ART_THERE_GOES_SHE_TO) || u.uprops[WAKEUP_CALL_BUG].extrinsic || have_wakeupcallstone() || autismweaponcheck(ART_POST_OFFICE_COURSE) || (uarm && uarm->oartifact == ART_ALTADOON_HERMA_MORA) || (uarmf && uarmf->oartifact == ART_CAMELIC_SCENT) || (uarmf && uarmf->oartifact == ART_LISSIE_S_SHEAGENTUR) || (uarmf && uarmf->oartifact == ART_MAY_BRITT_S_ADULTHOOD) || autismweaponcheck(ART_DRAMA_STAFF) || autismweaponcheck(ART_MASSIVE_BUT_LOVELY) || Race_if(PM_SERB)) && mtmp->mpeaceful && !mtmp->mtame && !rn2(WakeupCallXtra ? 1000 : 10000)) {
1521 wakeup(mtmp);
1524 if (uwep && uwep->otyp == CIRCULAR_SAW && mtmp->mpeaceful && !mtmp->mtame) wakeup(mtmp);
1525 if (u.twoweap && uswapwep && uswapwep->otyp == CIRCULAR_SAW && mtmp->mpeaceful && !mtmp->mtame) wakeup(mtmp);
1527 if (mdat == &mons[PM_NINJA_SALESMAN] && mtmp->mpeaceful && !mtmp->mtame && !rn2(500)) {
1528 wakeup(mtmp);
1531 if (mdat == &mons[PM_MILU]) {
1532 mtmp->mconf = FALSE;
1533 mtmp->mstun = FALSE;
1536 /* not frozen or sleeping: wipe out texts written in the dust */
1537 wipe_engr_at(mtmp->mx, mtmp->my, 1);
1539 /* bleeding monsters will take damage and may die from blood loss --Amy */
1540 if (mtmp->bleedout) {
1542 int bleedingdamage = rnd(1 + (mtmp->bleedout / 10));
1543 if (bleedingdamage > mtmp->bleedout) bleedingdamage = mtmp->bleedout;
1544 int bleedingtimeout = bleedingdamage;
1545 if (!mtmp->mtame && (mtmp->data->geno & G_UNIQ)) {
1546 bleedingdamage /= 5;
1547 if (bleedingdamage < 1) bleedingdamage = 1;
1548 bleedingtimeout *= 2;
1551 mtmp->mhp -= bleedingdamage;
1552 mtmp->bleedout -= bleedingtimeout;
1553 if (cansee(mtmp->mx,mtmp->my) && !rn2(10)) pline("%s bleeds.", Monnam(mtmp));
1554 if (mtmp->bleedout < 0) mtmp->bleedout = 0; /* fail safe */
1556 if (mtmp->mhp <= 0) {
1557 if (cansee(mtmp->mx,mtmp->my)) pline("%s dies from loss of blood", Monnam(mtmp));
1558 /* the lack of a period is intentional because the message is the same in Elona :P --Amy */
1559 mondied(mtmp);
1560 return(1);
1564 /* heal block will time out --Amy */
1565 if (mtmp->healblock) {
1566 mtmp->healblock--;
1568 if (!PlayerCannotUseSkills && mtmp->mtame) {
1570 switch (P_SKILL(P_PETKEEPING)) {
1571 default: break;
1572 case P_BASIC: if (!rn2(10)) mtmp->healblock--; break;
1573 case P_SKILLED: if (!rn2(5)) mtmp->healblock--; break;
1574 case P_EXPERT: if (rnd(10) > 7) mtmp->healblock--; break;
1575 case P_MASTER: if (rnd(10) > 6) mtmp->healblock--; break;
1576 case P_GRAND_MASTER: if (!rn2(2)) mtmp->healblock--; break;
1577 case P_SUPREME_MASTER: if (rnd(10) > 4) mtmp->healblock--; break;
1582 if (mtmp->healblock < 0) mtmp->healblock = 0; /* fail safe */
1585 /* inertia will also time out, and slows down the monster --Amy */
1586 if (mtmp->inertia) {
1587 mtmp->inertia--;
1589 if (!PlayerCannotUseSkills && mtmp->mtame) {
1591 switch (P_SKILL(P_PETKEEPING)) {
1592 default: break;
1593 case P_BASIC: if (!rn2(5)) mtmp->inertia--; break;
1594 case P_SKILLED: if (rnd(5) > 3) mtmp->inertia--; break;
1595 case P_EXPERT: if (rnd(5) > 2) mtmp->inertia--; break;
1596 case P_MASTER: if (rn2(5)) mtmp->inertia--; break;
1597 case P_GRAND_MASTER: mtmp->inertia--; break;
1598 case P_SUPREME_MASTER: if (!rn2(5)) mtmp->inertia--; mtmp->inertia--; break;
1603 if (mtmp->inertia < 0) mtmp->inertia = 0; /* fail safe */
1604 if (!rn2(2)) return 0; /* because I'm lazy :P monster loses a turn with 50% chance, instead of every other turn */
1607 /* confused monsters get unconfused with small probability */
1608 if (mtmp->mconf) {
1609 int unconfusechance = 50;
1611 if (!mtmp->mtame && (mtmp->data->geno & G_UNIQ)) unconfusechance = 10;
1613 if (!PlayerCannotUseSkills && mtmp->mtame) {
1615 switch (P_SKILL(P_PETKEEPING)) {
1616 default: break;
1617 case P_BASIC: unconfusechance = 45; break;
1618 case P_SKILLED: unconfusechance = 40; break;
1619 case P_EXPERT: unconfusechance = 35; break;
1620 case P_MASTER: unconfusechance = 30; break;
1621 case P_GRAND_MASTER: unconfusechance = 25; break;
1622 case P_SUPREME_MASTER: unconfusechance = 20; break;
1627 if (!rn2(unconfusechance)) mtmp->mconf = 0;
1630 /* stunned monsters get un-stunned with larger probability */
1631 if (mtmp->mstun) {
1632 int unstunchance = 10;
1634 if (!mtmp->mtame && (mtmp->data->geno & G_UNIQ)) unstunchance = 2;
1636 if (!PlayerCannotUseSkills && mtmp->mtame) {
1638 switch (P_SKILL(P_PETKEEPING)) {
1639 default: break;
1640 case P_BASIC: unstunchance = 9; break;
1641 case P_SKILLED: unstunchance = 8; break;
1642 case P_EXPERT: unstunchance = 7; break;
1643 case P_MASTER: unstunchance = 6; break;
1644 case P_GRAND_MASTER: unstunchance = 5; break;
1645 case P_SUPREME_MASTER: unstunchance = 4; break;
1650 if (!rn2(unstunchance)) mtmp->mstun = 0;
1654 /* cancelled monsters get un-cancelled with a VERY low probability --Amy */
1655 if (mtmp->mcan) {
1656 int uncancelchance = 10000;
1657 if (!mtmp->mtame && (mtmp->data->geno & G_UNIQ)) uncancelchance = 1000;
1659 if (!rn2(uncancelchance)) {
1660 mtmp->mcan = 0;
1661 mtmp->canceltimeout = 0;
1664 /* and much more often if you used the spell */
1665 if (mtmp->mcan && mtmp->canceltimeout) {
1667 int uncancelchance = 500;
1668 if (!mtmp->mtame && (mtmp->data->geno & G_UNIQ)) uncancelchance = 50;
1670 if (!rn2(uncancelchance)) {
1671 mtmp->mcan = 0;
1672 mtmp->canceltimeout = 0;
1676 /* slowed monsters get un-slowed with a low probability --Amy */
1677 if (mtmp->mspeed == MSLOW && mtmp->permspeed == MSLOW && !mtmp->inertia) {
1679 int unslowchance = 2000;
1680 if (!mtmp->mtame && (mtmp->data->geno & G_UNIQ)) unslowchance = 200;
1682 if (!rn2(unslowchance)) {
1683 mon_adjust_speed(mtmp, 1, (struct obj *)0);
1684 mtmp->slowtimeout = 0;
1687 /* and much more often if you used the spell */
1688 if (mtmp->mspeed == MSLOW && mtmp->permspeed == MSLOW && mtmp->slowtimeout && !mtmp->inertia) {
1690 int unslowchance = 100;
1691 if (!mtmp->mtame && (mtmp->data->geno & G_UNIQ)) unslowchance = 10;
1693 if (!rn2(unslowchance)) {
1694 mon_adjust_speed(mtmp, 1, (struct obj *)0);
1695 mtmp->slowtimeout = 0;
1699 /* is the monster charging a special laser cannon? */
1700 if (mtmp->hominglazer) {
1701 mtmp->hominglazer++;
1702 /* it can only be charged for so long, and then the monster needs to charge it again */
1703 if (mtmp->hominglazer > 200) {
1704 mtmp->hominglazer = 0;
1705 You_hear("a sparking sound.");
1709 /* monsters whose butts were bashed by you will slowly recover --Amy */
1710 if (mtmp->butthurt && !rn2(mdat->msound == MS_FART_QUIET ? 5 : mdat->msound == MS_FART_NORMAL ? 20 : 50) ) mtmp->butthurt -= 1;
1712 /* some monsters teleport */
1713 if (mtmp->mflee && !rn2(40) && can_teleport(mdat) && !mtmp->iswiz &&
1714 !level.flags.noteleport && !Race_if(PM_STABILISATOR) && !u.antitelespelltimeout) {
1715 (void) rloc(mtmp, FALSE);
1716 return(0);
1718 if (mdat->msound == MS_SHRIEK && !(bmwride(ART_SHUT_UP_YOU_FUCK) && u.usteed && (mtmp == u.usteed) ) && !um_dist(mtmp->mx, mtmp->my, 1))
1719 m_respond(mtmp);
1721 if (mtmp->fartbonus > 9) mtmp->fartbonus = 9; /* fail save, gaaaaaah */
1723 if (FemtrapActiveMeltem && !(bmwride(ART_SHUT_UP_YOU_FUCK) && u.usteed && (mtmp == u.usteed) ) && mtmp->female && humanoid(mdat) && !rn2(10 + mtmp->butthurt - mtmp->fartbonus) && (distu(mtmp->mx, mtmp->my) <= fartdistance) && !mtmp->mpeaceful) {
1724 pline("%s produces %s farting noises with %s %s butt.", Monnam(mtmp), rn2(2) ? "beautiful" : "squeaky", mhis(mtmp), mtmp->female ? "sexy" : "ugly" );
1725 u.cnd_fartingcount++;
1726 if (Role_if(PM_CLIMACTERIAL)) climtrainsqueaking(1);
1727 if (Role_if(PM_BUTT_LOVER) && !rn2(20)) buttlovertrigger();
1728 if (Role_if(PM_SOCIAL_JUSTICE_WARRIOR)) sjwtrigger();
1729 if (uarmf && uarmf->oartifact == ART_ELIANE_S_SHIN_SMASH) {
1730 pline("The farting gas destroys your footwear instantly.");
1731 useup(uarmf);
1733 if (mtmp->butthurt) mtmp->butthurt--;
1734 if (mtmp->butthurt) mtmp->butthurt--;
1735 if (uarmf && uarmf->oartifact == ART_ELIANE_S_COMBAT_SNEAKERS) {
1736 pline("Eek! You can't stand farting gas!");
1737 badeffect();
1738 badeffect();
1739 badeffect();
1740 badeffect();
1742 if (!extralongsqueak()) badeffect();
1744 if (uarmh && itemhasappearance(uarmh, APP_BREATH_CONTROL_HELMET) ) {
1745 pline("Your breath control helmet keeps pumping the farting gas into your %s...", body_part(NOSE));
1746 badeffect();
1747 badeffect();
1750 if (uarmh && uarmh->oartifact == ART_VACUUM_CLEANER_DEATH) {
1751 pline("The farting gas almost asphyxiates you!");
1752 badeffect();
1753 badeffect();
1754 badeffect();
1755 badeffect();
1756 badeffect();
1757 losehp(rnd(u.ulevel * 3), "suffocating on farting gas", KILLED_BY);
1760 if (!rn2(20)) increasesanity(1);
1762 while (FemtrapActiveElena && !rn2(3)) {
1763 pline("You long for more!");
1764 pline("%s produces %s farting noises with %s %s butt.", Monnam(mtmp), rn2(2) ? "beautiful" : "squeaky", mhis(mtmp), mtmp->female ? "sexy" : "ugly" );
1765 u.cnd_fartingcount++;
1766 if (Role_if(PM_CLIMACTERIAL)) climtrainsqueaking(1);
1767 if (Role_if(PM_BUTT_LOVER) && !rn2(20)) buttlovertrigger();
1768 if (Role_if(PM_SOCIAL_JUSTICE_WARRIOR)) sjwtrigger();
1769 if (uarmf && uarmf->oartifact == ART_ELIANE_S_SHIN_SMASH) {
1770 pline("The farting gas destroys your footwear instantly.");
1771 useup(uarmf);
1773 if (mtmp->butthurt) mtmp->butthurt--;
1774 if (mtmp->butthurt) mtmp->butthurt--;
1775 if (uarmf && uarmf->oartifact == ART_ELIANE_S_COMBAT_SNEAKERS) {
1776 pline("Eek! You can't stand farting gas!");
1777 badeffect();
1778 badeffect();
1779 badeffect();
1780 badeffect();
1782 if (!extralongsqueak()) badeffect();
1784 if (uarmh && itemhasappearance(uarmh, APP_BREATH_CONTROL_HELMET) ) {
1785 pline("Your breath control helmet keeps pumping the farting gas into your %s...", body_part(NOSE));
1786 badeffect();
1787 badeffect();
1790 if (uarmh && uarmh->oartifact == ART_VACUUM_CLEANER_DEATH) {
1791 pline("The farting gas almost asphyxiates you!");
1792 badeffect();
1793 badeffect();
1794 badeffect();
1795 badeffect();
1796 badeffect();
1797 losehp(rnd(u.ulevel * 3), "suffocating on farting gas", KILLED_BY);
1800 if (!rn2(20)) increasesanity(1);
1806 if (mdat->msound == MS_FART_QUIET && !(bmwride(ART_SHUT_UP_YOU_FUCK) && u.usteed && (mtmp == u.usteed) ) && !rn2(10 + mtmp->butthurt - mtmp->fartbonus) && (distu(mtmp->mx, mtmp->my) <= fartdistance) && (!mtmp->mpeaceful || FemtrapActiveJennifer)) {
1807 m_respond(mtmp);
1808 while (FemtrapActiveElena && !rn2(3)) {
1809 pline("You long for more!");
1810 m_respond(mtmp);
1813 if (mdat->msound == MS_FART_NORMAL && !(bmwride(ART_SHUT_UP_YOU_FUCK) && u.usteed && (mtmp == u.usteed) ) && !rn2(10 + mtmp->butthurt - mtmp->fartbonus) && (distu(mtmp->mx, mtmp->my) <= fartdistance) && (!mtmp->mpeaceful || (FemtrapActiveSueLyn && mtmp->female && !mtmp->mtame) ) ) {
1814 m_respond(mtmp);
1815 while (FemtrapActiveElena && !rn2(3)) {
1816 pline("You long for more!");
1817 m_respond(mtmp);
1820 if (mdat->msound == MS_FART_LOUD && !(bmwride(ART_SHUT_UP_YOU_FUCK) && u.usteed && (mtmp == u.usteed) ) && !rn2(10 + mtmp->butthurt - mtmp->fartbonus) && (distu(mtmp->mx, mtmp->my) <= fartdistance) && !mtmp->mpeaceful) {
1821 m_respond(mtmp);
1822 while (FemtrapActiveElena && !rn2(3)) {
1823 pline("You long for more!");
1824 m_respond(mtmp);
1828 if (mdat->msound == MS_PANTS && !(bmwride(ART_SHUT_UP_YOU_FUCK) && u.usteed && (mtmp == u.usteed) ) && !rn2(10) && !um_dist(mtmp->mx, mtmp->my, 1) && !mtmp->mpeaceful) {
1829 m_respond(mtmp);
1831 if (mdat->msound == MS_SOCKS && !(bmwride(ART_SHUT_UP_YOU_FUCK) && u.usteed && (mtmp == u.usteed) ) && !rn2(10) && !um_dist(mtmp->mx, mtmp->my, 1) && !mtmp->mpeaceful) {
1832 m_respond(mtmp);
1834 if ((mdat->msound == MS_ALLA || mtmp->egotype_alladrainer) && !(bmwride(ART_SHUT_UP_YOU_FUCK) && u.usteed && (mtmp == u.usteed) ) && !um_dist(mtmp->mx, mtmp->my, 1) && !mtmp->mpeaceful) {
1835 pline("alla");
1836 drain_alla(1);
1839 if (mtmp->singannoyance && !u.singtrapocc && !u.katitrapocc && !um_dist(mtmp->mx, mtmp->my, 1) && !mtmp->mpeaceful) {
1840 singclean(mtmp);
1843 if (FemtrapActiveKati && !u.singtrapocc && !u.katitrapocc && !um_dist(mtmp->mx, mtmp->my, 1) && !rn2(20) && !mtmp->mpeaceful && humanoid(mtmp->data) && is_female(mtmp->data) && attacktype(mtmp->data, AT_KICK) && !mtmp->mfrenzied) {
1844 katiclean(mtmp);
1847 if ((mdat->msound == MS_SING || mtmp->egotype_singagent) && !(uwep && uwep->oartifact == ART_KATI_GAVE_YOU_THE_ENGLISH_) && !u.singtrapocc && !u.katitrapocc && !um_dist(mtmp->mx, mtmp->my, 1) && !mtmp->singability) {
1849 int attempts = 0;
1850 struct permonst *pm = 0;
1852 if (Aggravate_monster) {
1853 u.aggravation = 1;
1854 reset_rndmonst(NON_PM);
1857 newbossSING:
1858 do {
1859 pm = rndmonst();
1860 attempts++;
1861 if (attempts && (attempts % 10000 == 0)) u.mondiffhack++;
1862 if (!rn2(2000)) reset_rndmonst(NON_PM);
1864 } while ( (!pm || (pm && !(pm->msound == MS_SHOE )) || (pm && !(type_is_pname(pm))) ) && attempts < 50000);
1866 if (!pm && rn2(50) ) {
1867 attempts = 0;
1868 goto newbossSING;
1870 if (pm && !(pm->msound == MS_SHOE) && rn2(50) ) {
1871 attempts = 0;
1872 goto newbossSING;
1874 if (pm && !(type_is_pname(pm)) && rn2(50) ) {
1875 attempts = 0;
1876 goto newbossSING;
1879 if (pm) {
1880 struct monst *singbitch;
1881 singbitch = makemon(pm, u.ux, u.uy, MM_ANGRY|MM_ADJACENTOK); /* not frenzied --Amy */
1882 if (singbitch) singbitch->singannoyance = TRUE; /* in case you're preoccupied... --Amy */
1883 if (singbitch && !u.singtrapocc && !u.katitrapocc) {
1884 if (!singclean(singbitch)) {
1885 mtmp->mpeaceful = TRUE;
1886 mtmp->mfrenzied = FALSE;
1891 u.aggravation = 0;
1892 u.mondiffhack = 0;
1894 mtmp->singability = TRUE;
1897 if (mdat->msound == MS_FART_QUIET && !(bmwride(ART_SHUT_UP_YOU_FUCK) && u.usteed && (mtmp == u.usteed) ) && mtmp->crapbonus && (rn2(2000) < mtmp->crapbonus) && !um_dist(mtmp->mx, mtmp->my, 1) && (!mtmp->mpeaceful || FemtrapActiveJennifer))
1899 pline("Using %s %s butt, %s produces tender noises and craps right in your %s.", mhis(mtmp), mtmp->female ? "sexy" : "ugly", mon_nam(mtmp), body_part(FACE) );
1901 int blindinc = rnd(20);
1902 u.ucreamed += blindinc;
1903 make_blinded(Blinded + (long)blindinc, FALSE);
1904 if (!rn2(5)) increasesanity(rnd(10));
1905 u.cnd_crappingcount++;
1906 if (Role_if(PM_SOCIAL_JUSTICE_WARRIOR)) sjwtrigger();
1909 if (mdat->msound == MS_FART_NORMAL && !(bmwride(ART_SHUT_UP_YOU_FUCK) && u.usteed && (mtmp == u.usteed) ) && mtmp->crapbonus && (rn2(1000) < mtmp->crapbonus) && !um_dist(mtmp->mx, mtmp->my, 1) && !mtmp->mpeaceful)
1911 pline("Using %s %s butt, %s produces beautiful noises and craps right in your %s.", mhis(mtmp), mtmp->female ? "sexy" : "ugly", mon_nam(mtmp), body_part(FACE) );
1913 int blindinc = rnd(50);
1914 u.ucreamed += blindinc;
1915 make_blinded(Blinded + (long)blindinc, FALSE);
1916 if (!rn2(5)) increasesanity(rnd(10));
1917 u.cnd_crappingcount++;
1918 if (Role_if(PM_SOCIAL_JUSTICE_WARRIOR)) sjwtrigger();
1921 if (mdat->msound == MS_FART_LOUD && !(bmwride(ART_SHUT_UP_YOU_FUCK) && u.usteed && (mtmp == u.usteed) ) && mtmp->crapbonus && (rn2(400) < mtmp->crapbonus) && !um_dist(mtmp->mx, mtmp->my, 1) && !mtmp->mpeaceful)
1923 pline("Using %s %s butt, %s produces disgusting noises and craps right in your %s.", mhis(mtmp), mtmp->female ? "sexy" : "ugly", mon_nam(mtmp), body_part(FACE) );
1925 int blindinc = rnd(100);
1926 u.ucreamed += blindinc;
1927 make_blinded(Blinded + (long)blindinc, FALSE);
1928 if (!rn2(5)) increasesanity(rnd(10));
1929 u.cnd_crappingcount++;
1930 if (Role_if(PM_SOCIAL_JUSTICE_WARRIOR)) sjwtrigger();
1934 if (!(mdat->msound == MS_FART_LOUD || mdat->msound == MS_FART_NORMAL || mdat->msound == MS_FART_QUIET) && mtmp->egotype_farter && !(bmwride(ART_SHUT_UP_YOU_FUCK) && u.usteed && (mtmp == u.usteed) ) && !rn2(10 + mtmp->butthurt) && (distu(mtmp->mx, mtmp->my) <= fartdistance) && !mtmp->mpeaceful) {
1935 m_respond(mtmp);
1936 while (FemtrapActiveElena && !rn2(3)) {
1937 pline("You long for more!");
1938 m_respond(mtmp);
1942 if ( (mdat->msound == MS_SOUND || mtmp->egotype_sounder) && !rn2(20) && !um_dist(mtmp->mx, mtmp->my, 1) && !mtmp->mpeaceful)
1943 m_respond(mtmp);
1944 if (mdat == &mons[PM_MEDUSA] && !(bmwride(ART_SHUT_UP_YOU_FUCK) && u.usteed && (mtmp == u.usteed) ) && couldsee(mtmp->mx, mtmp->my))
1945 m_respond(mtmp);
1946 if (mtmp->mhp <= 0) return(1); /* m_respond gaze can kill medusa */
1948 /* fleeing monsters might regain courage */
1949 if (mtmp->mflee && !mtmp->mfleetim && mtmp->mhp == mtmp->mhpmax) {
1950 int unfleechance = 25;
1951 if (!mtmp->mtame && (mtmp->data->geno & G_UNIQ)) unfleechance = 5;
1953 if (!rn2(unfleechance)) {
1954 mtmp->mflee = 0;
1959 if (mtmp->mflee && (mtmp->mfleetim > 0) && !mtmp->mtame && (mtmp->data->geno & G_UNIQ)) {
1960 mtmp->mfleetim /= 2;
1961 if (mtmp->mfleetim < 0) mtmp->mfleetim = 0;
1962 if (mtmp->mfleetim == 0) mtmp->mflee = 0;
1965 if (FemtrapActiveElla && mtmp->female && humanoid(mtmp->data) && (mtmp->mhp < (mtmp->mhpmax * 9 / 10) )) {
1966 mtmp->mflee = 0;
1967 mtmp->mfleetim = 0;
1970 if (mdat == &mons[PM_SERPENT_S_CHOSEN]) {
1971 mtmp->mflee = 0;
1972 mtmp->mfleetim = 0;
1975 set_apparxy(mtmp);
1976 /* Must be done after you move and before the monster does. The
1977 * set_apparxy() call in m_move() doesn't suffice since the variables
1978 * inrange, etc. all depend on stuff set by set_apparxy().
1981 if (!mtmp->mtame && !mtmp->mpeaceful) monsteremptycontainers(mtmp);
1983 /* Monsters that want to acquire things */
1984 /* may teleport, so do it before inrange is set */
1985 if( (is_covetous(mdat) || mtmp->egotype_covetous || (FemtrapActiveLuisa && mtmp->female && mtmp->data->msound == MS_SHOE && type_is_pname(mtmp->data) ) || (Role_if(PM_SINGSLAVE) && mtmp->singannoyance) ) && (!rn2(10) || (mdat == &mons[PM_AT_RAINKID] && !rn2(3)) || (mdat == &mons[PM_TEA_HUSSY] && !rn2(3)) || (CovetousnessBug || u.uprops[COVETOUSNESS_BUG].extrinsic || have_covetousstone() ) ) ) (void) tactics(mtmp);
1987 /* check distance and scariness of attacks */
1988 distfleeck(mtmp,&inrange,&nearby,&scared);
1990 if(find_defensive(mtmp)) {
1991 if (use_defensive(mtmp) != 0)
1992 return 1;
1993 } else if(find_misc(mtmp)) {
1994 if (use_misc(mtmp) != 0)
1995 return 1;
1998 /* Demonic Blackmail! */
1999 if(nearby && mdat->msound == MS_BRIBE &&
2000 (monsndx(mdat) != PM_PRISON_GUARD) &&
2001 mtmp->mpeaceful && !mtmp->mtame && !u.uswallow) {
2002 if (mtmp->mux != u.ux || mtmp->muy != u.uy) {
2003 pline("%s whispers at thin air.",
2004 cansee(mtmp->mux, mtmp->muy) ? Monnam(mtmp) : "It");
2006 if (is_demon(youmonst.data)) {
2007 /* "Good hunting, brother" */
2008 if (!tele_restrict(mtmp)) (void) rloc(mtmp, FALSE);
2009 } else {
2010 mtmp->minvis = mtmp->perminvis = 0;
2011 /* Why? For the same reason in real demon talk */
2012 pline("%s gets angry!", Amonnam(mtmp));
2013 mtmp->mpeaceful = 0;
2014 /* since no way is an image going to pay it off */
2016 } else if(demon_talk(mtmp)) return(1); /* you paid it off */
2019 /* Prison guard extortion */
2020 if(nearby && (monsndx(mdat) == PM_PRISON_GUARD) && !mtmp->mpeaceful
2021 && !mtmp->mtame && !u.uswallow && (!mtmp->mspec_used)) {
2022 long gdemand = 500 * u.ulevel;
2023 long goffer = 0;
2025 pline("%s demands %ld %s to avoid re-arrest.", Amonnam(mtmp),
2026 gdemand, currency(gdemand));
2027 if ((goffer = bribe(mtmp)) >= gdemand) {
2028 verbalize("Good. Now beat it, scum!");
2029 if (!mtmp->mfrenzied) mtmp->mpeaceful = 1;
2030 set_malign(mtmp);
2031 } else {
2032 pline("I said %ld!", gdemand);
2033 mtmp->mspec_used = 1000;
2037 if (monsndx(mdat) == PM_SINGPIR && !rn2(20)) {
2038 if (!(t_at(mtmp->mx, mtmp->my))) {
2039 maketrap(mtmp->mx, mtmp->my, SHIT_TRAP, 0, FALSE);
2043 if (FemtrapActiveLarissa && !rn2(200) && mtmp->data->mlet == S_DOG) {
2044 if (!(t_at(mtmp->mx, mtmp->my))) {
2045 maketrap(mtmp->mx, mtmp->my, SHIT_TRAP, 0, FALSE);
2049 if (uarmf && itemhasappearance(uarmf, APP_TREADED_HEELS) && !rn2(250) && mtmp->data->mlet == S_DOG) {
2050 if (!(t_at(mtmp->mx, mtmp->my))) {
2051 maketrap(mtmp->mx, mtmp->my, SHIT_TRAP, 0, FALSE);
2055 if (FemtrapActiveAnna && !rn2(1000) && humanoid(mtmp->data) && is_female(mtmp->data) && (mdat->msound == MS_STENCH)) {
2056 if (!(t_at(mtmp->mx, mtmp->my))) {
2057 maketrap(mtmp->mx, mtmp->my, SHIT_TRAP, 0, FALSE);
2061 if (FemtrapActiveKatrin && !rn2(1000) && humanoid(mtmp->data) && is_female(mtmp->data) ) {
2062 if (!(t_at(mtmp->mx, mtmp->my))) {
2063 maketrap(mtmp->mx, mtmp->my, PARALYSIS_TRAP, 0, FALSE);
2067 /* monster noise trap: some of these noises have effects, might add others in future --Amy */
2068 if ((MonnoiseEffect || (uarmf && uarmf->oartifact == ART_IS_THERE_A_SOUND_) || (uarm && uarm->oartifact == ART_ZURA_S_DRESSCODE) || u.uprops[MONNOISE_EFFECT].extrinsic || have_monnoisestone()) && !(bmwride(ART_SHUT_UP_YOU_FUCK) && u.usteed && (mtmp == u.usteed) ) && !rn2(MonNoiseXtra ? 50 : 250) && !mtmp->mpeaceful && (distu(mtmp->mx, mtmp->my) <= BOLT_LIM * BOLT_LIM) ) {
2069 switch (mdat->msound) {
2071 case MS_PRIEST:
2072 verbalize(rn2(2) ? "Hoyo hoyo!" : "Wololo");
2073 adjalign(-(mtmp->m_lev + 1));
2074 You_feel("less faithful!");
2075 break;
2076 case MS_VAMPIRE:
2077 verbalize("I vill suck you dry!");
2078 if (!rn2(3)) {
2079 You("are too scared to move.");
2080 nomul(-5, "scared by a vampire", TRUE);
2081 nomovemsg = 0;
2083 break;
2084 case MS_WERE:
2085 if (canseemon(mtmp))
2086 pline("%s throws back %s head and lets out a blood curdling %s!", Monnam(mtmp), mhis(mtmp), mtmp->data == &mons[PM_HUMAN_WERERAT] ? "shriek" : "howl");
2087 else You_hear("a blood curdling sound!");
2088 make_numbed(HNumbed + rnz((2 * level_difficulty()) + 1), FALSE);
2089 break;
2090 case MS_BARK:
2091 if (canseemon(mtmp)) pline("%s %s!", Monnam(mtmp), rn2(2) ? "growls" : "barks");
2092 else You_hear("a barking sound!");
2093 break;
2094 case MS_MEW:
2095 if (canseemon(mtmp)) pline("%s %s!", Monnam(mtmp), rn2(2) ? "growls" : "hisses");
2096 else You_hear("a growling sound!");
2097 break;
2098 case MS_ROAR:
2099 if (canseemon(mtmp)) pline("%s roars!", Monnam(mtmp));
2100 else You_hear("a loud roar nearby!");
2101 if (!rn2(3)) make_feared(HFeared + rnz((2 * level_difficulty()) + 1), TRUE);
2102 break;
2103 case MS_SQEEK:
2104 if (canseemon(mtmp)) pline("%s squeaks!", Monnam(mtmp));
2105 else You_hear("a squeak nearby!");
2106 break;
2107 case MS_SQAWK:
2108 if (canseemon(mtmp)) pline("%s squawks!", Monnam(mtmp));
2109 else You_hear("a squawk nearby!");
2110 break;
2111 case MS_HISS:
2112 if (canseemon(mtmp)) pline("%s hisses!", Monnam(mtmp));
2113 else You_hear("a hiss nearby!");
2114 break;
2115 case MS_BUZZ:
2116 if (canseemon(mtmp)) pline("%s buzzes!", Monnam(mtmp));
2117 else You_hear("a buzzing nearby!");
2118 break;
2119 case MS_GRUNT:
2120 if (canseemon(mtmp)) pline("%s grunts!", Monnam(mtmp));
2121 else You_hear("a grunting nearby!");
2122 break;
2123 case MS_NEIGH:
2124 if (canseemon(mtmp)) pline("%s neighs!", Monnam(mtmp));
2125 else You_hear("a neighing nearby!");
2126 break;
2127 case MS_WAIL:
2128 if (canseemon(mtmp)) pline("%s wails frighteningly.", Monnam(mtmp));
2129 else You_hear("a nearby wail.");
2130 break;
2131 case MS_GURGLE:
2132 if (canseemon(mtmp)) pline("%s gurgles.", Monnam(mtmp));
2133 else You_hear("a nearby gurgle.");
2134 break;
2135 case MS_BURBLE:
2136 if (canseemon(mtmp)) pline("%s burbles.", Monnam(mtmp));
2137 else You_hear("a nearby burble.");
2138 break;
2139 case MS_FART_QUIET:
2140 case MS_FART_NORMAL:
2141 case MS_FART_LOUD:
2142 if (canseemon(mtmp)) pline("%s makes woman noises.", Monnam(mtmp));
2143 else You_hear("nearby woman noises.");
2144 break;
2145 case MS_IMITATE:
2146 if (canseemon(mtmp)) {
2147 pline("%s seems to imitate you.", Monnam(mtmp));
2148 make_confused(HConfusion + rnz((2 * level_difficulty()) + 1), FALSE);
2150 break;
2151 case MS_SHEEP:
2152 if (canseemon(mtmp)) pline("%s baaaas!", Monnam(mtmp));
2153 else You_hear("a nearby 'baaaa!'");
2154 break;
2155 case MS_CHICKEN:
2156 if (canseemon(mtmp)) pline("%s clucks!", Monnam(mtmp));
2157 else You_hear("a clucking sound!");
2158 break;
2159 case MS_COW:
2160 if (canseemon(mtmp)) pline("%s bellows!", Monnam(mtmp));
2161 else You_hear("a bellowing sound!");
2162 break;
2163 case MS_LAUGH:
2164 if (canseemon(mtmp)) pline("%s laughs at you!", Monnam(mtmp));
2165 else You_hear("someone laughing at you!");
2166 if (!rn2(10)) {
2167 pline("You are trembling!");
2168 u.tremblingamount++;
2170 break;
2171 case MS_MUMBLE:
2172 if (canseemon(mtmp)) pline("%s mumbles incomprehensibly.", Monnam(mtmp));
2173 else You_hear("an incomprehensible mumbling.");
2174 break;
2175 case MS_SHOE:
2176 verbalize("We absolutely want to kick you. Hopefully you enjoy pain!");
2177 break;
2178 case MS_CASINO:
2179 verbalize("Place your bets here! Only 2000 zorkmids per casino chip!");
2180 break;
2181 case MS_SOCKS:
2182 if (canseemon(mtmp)) pline("%s is emanating a sweaty stench.", Monnam(mtmp));
2183 else You("sense a sweaty stench emanating from something close by.");
2184 break;
2185 case MS_PANTS:
2186 if (canseemon(mtmp)) pline("Eww, %s stinks like shit!", mon_nam(mtmp));
2187 else You("sense something stinky close by.");
2188 break;
2189 case MS_CAR:
2190 verbalize("Vrrrrrrrr! Here I come!");
2191 break;
2192 case MS_JAPANESE:
2193 verbalize("Yameru! Nigemichi wa arimasen!");
2194 break;
2195 case MS_SOVIET:
2196 verbalize("Vasha igra dolzhna byt' izmenena, chtoby garantirovat', chto vy ne vyigrayete.");
2197 break;
2198 case MS_SNORE:
2199 if (canseemon(mtmp)) pline("%s yawns loudly.", Monnam(mtmp));
2200 else You_hear("a yawning sound nearby.");
2201 break;
2202 case MS_PHOTO:
2203 verbalize("Don't move, I want to take a photo of you!");
2204 break;
2205 case MS_REPAIR:
2206 verbalize("Repair your equipment here!");
2207 break;
2208 case MS_BARBER:
2209 verbalize("Come here, I'm gonna give you a new haircut!");
2210 break;
2211 case MS_DRUGS:
2212 verbalize("Hey %s! Hit me if you want the good stuff!", flags.female ? "gal" : "dude");
2213 break;
2214 case MS_COMBAT:
2215 verbalize("I own this dungeon. Fight me.");
2216 break;
2217 case MS_DEAD:
2218 verbalize("Man I don't want to fight you. Can't you just go away and leave me alone?");
2219 break;
2220 case MS_FEARHARE:
2221 verbalize("Oh no! The player character is coming to get me! I should probably flee!");
2222 break;
2223 case MS_DEEPSTATE:
2224 verbalize("You are going down.");
2225 break;
2226 case MS_MUTE:
2227 if (canseemon(mtmp)) pline("%s grumbles and grunts loudly.", Monnam(mtmp));
2228 else You_hear("loud grumbling and grunting.");
2229 break;
2230 case MS_CORONA:
2231 verbalize("Wear your fucking mask goddammit!");
2232 break;
2233 case MS_PAIN:
2234 verbalize("I may be in pain, but soon the same will apply to you!");
2235 break;
2236 case MS_OHGOD:
2237 verbalize("Oh god the %s!", playeraliasname);
2238 break;
2239 case MS_PRINCESSLEIA:
2240 verbalize("Please, don't hurt me, I'm the princess!");
2241 break;
2242 case MS_LIEDER:
2243 verbalize("Hey, you! Why aren't you busy doing your quest?");
2244 break;
2245 case MS_WOLLOH:
2246 verbalize("Wolloh age, I'ma beat you up wolloh!");
2247 break;
2248 case MS_TALONCOMPANY:
2249 verbalize("Talon Company!");
2250 break;
2251 case MS_REGULATOR:
2252 verbalize("I want that head on a fucking plate!");
2253 break;
2254 case MS_RAIDER:
2255 verbalize("You n'wah!");
2256 break;
2257 case MS_ENCLAVE:
2258 verbalize("For President Eden!");
2259 break;
2260 case MS_MUTANT:
2261 verbalize("I will soon have you killed, little human!");
2262 break;
2263 case MS_MYTHICALDAWN:
2264 verbalize("Be glad that you won't live to see Lord Dagon's arrival.");
2265 break;
2266 case MS_BOS:
2267 if (canseemon(mtmp)) pline("%s chants a prayer!", Monnam(mtmp));
2268 else You_hear("someone praying!");
2269 break;
2270 case MS_OUTCAST:
2271 verbalize("Attack! Attack!");
2272 break;
2273 case MS_DREMORA:
2274 verbalize("You shouldn't even be here, mortal. Your blood will be spilled, and your flesh is mine!");
2275 break;
2276 case MS_SHIVERINGESLES:
2277 verbalize("Rani Ruh! Rani Ruh!");
2278 break;
2279 case MS_ANOREXIA:
2280 verbalize("You! Please! Tell me I look skinny!");
2281 break;
2282 case MS_BULIMIA:
2283 verbalize("You didn't see my teeth. Understood? Woe to you if you tell anyone...");
2284 break;
2285 case MS_TEMPER:
2286 verbalize("RAAAAARGH! I'm gonna crush ya!");
2287 break;
2288 case MS_CONDESCEND:
2289 verbalize("Heh, a tin can like you is no match for me anyway...");
2290 break;
2291 case MS_MOLEST:
2292 verbalize(flags.female ? "You're fair game to me, woman!" : "Have you seen any sexy women lately?");
2293 break;
2294 case MS_SHOCKTROOPER:
2295 verbalize("pur thirv pur kss kss");
2296 break;
2297 case MS_PIRATE:
2298 verbalize("Arrrr gon' rape ye!");
2299 break;
2300 case MS_ARMORER:
2301 verbalize("I'll smash you!");
2302 break;
2303 case MS_GAGA:
2304 verbalize("Woe to you if you don't address me as a %s!", mongenderidentity(mtmp) );
2305 break;
2306 case MS_BEG:
2307 verbalize("Give me some money please!");
2308 break;
2309 case MS_MIDI:
2310 pline("klick klack - klick klack");
2311 break;
2312 case MS_SILLY:
2313 verbalize("Bundle in the face hang!");
2314 break;
2315 case MS_HERCULES:
2316 verbalize("You're no match for me.");
2317 break;
2318 case MS_CRYTHROAT:
2319 verbalize("NOOOOO I DO NOT WANT");
2320 break;
2321 case MS_HOOT:
2322 if (canseemon(mtmp)) pline("%s hoots!", Monnam(mtmp));
2323 else You_hear("a hooting sound!");
2324 break;
2325 case MS_RUSTLE:
2326 if (canseemon(mtmp)) pline("%s rustles!", Monnam(mtmp));
2327 else You_hear("a rustling sound!");
2328 break;
2329 case MS_SEMEN:
2330 verbalize(flags.female ? "I'll ejaculate my semen into your vagina." : "Damn, why can't you be female, you asshole?");
2331 break;
2332 case MS_SCIENTIST:
2333 verbalize("I'll plug my quantum harmonizer into your photon resonance chamber!");
2334 break;
2335 case MS_GAARDIEN:
2336 verbalize("Why is that weirdo over there not doing %s job?", flags.female ? "her" : "his");
2337 break;
2338 case MS_SISSY:
2339 verbalize("help i am afraid!");
2340 break;
2341 case MS_SING:
2342 verbalize("Come here, I have this sexy pair of female shoes that you're allowed to clean.");
2343 break;
2344 case MS_POMPEJI:
2345 verbalize("Pompe-e-ji! Pompe-e-ji!");
2346 break;
2347 case MS_FLUIDATOR:
2348 verbalize("Now Mach I you fully all!");
2349 break;
2350 case MS_BULLETATOR:
2351 verbalize("Death to all who use automatic guns!");
2352 break;
2353 case MS_ALLA:
2354 verbalize("I will leave a permanent scar on your body.");
2355 break;
2356 case MS_BOT:
2357 switch (rnd(5)) {
2358 case 1:
2359 verbalize("Target lock mode activated. Enemy target will be attacked.");
2360 break;
2361 case 2:
2362 verbalize("Aim... Fire.");
2363 break;
2364 case 3:
2365 verbalize("Please don't act surprised if you get killed once I found you.");
2366 break;
2367 case 4:
2368 verbalize("With the blue beans we come!");
2369 break;
2370 case 5:
2371 verbalize("Oh, that's nice, I found you.");
2372 break;
2374 break;
2375 case MS_APOC:
2376 verbalize("The world may be headed for destruction, but you shall be destroyed first!");
2377 break;
2378 case MS_GIBBERISH:
2379 pline("%s", generate_garbage_string());
2380 break;
2381 case MS_GLYPHS:
2382 verbalize("Hmm, the green glyph is good, but I also have the red one... too bad I have no idea where the blue glyph ended up!");
2383 break;
2384 case MS_STENCH:
2385 if (canseemon(mtmp)) pline("%s sprays %sself with perfume.", Monnam(mtmp), mhim(mtmp));
2386 else You_hear("the sound of a spray box.");
2387 break;
2388 case MS_BOAST:
2389 if (canseemon(mtmp)) pline("%s boasts!", Monnam(mtmp));
2390 else You_hear("someone boasting!");
2391 break;
2392 case MS_SEDUCE:
2393 if (canseemon(mtmp)) pline("%s looks at you seductively!", Monnam(mtmp));
2394 else You_hear("a seductive voice!");
2396 if (!rn2(100)) {
2397 char bufof[BUFSZ];
2398 bufof[0] = '\0';
2399 steal(mtmp, bufof, FALSE, FALSE);
2402 break;
2403 case MS_ARREST:
2404 verbalize("I will hold you, you for asshole!");
2405 break;
2406 case MS_SPELL:
2407 if (canseemon(mtmp)) pline("%s casts furiously!", Monnam(mtmp));
2408 else You_hear("a furious chant!");
2409 break;
2410 case MS_NURSE:
2411 verbalize("Hold still and let me JAM this needle into you.");
2412 increasesanity(1);
2413 break;
2414 case MS_SOLDIER:
2415 verbalize("My commander will be very pleased if I kill you!");
2416 break;
2417 case MS_RIDER:
2418 verbalize("You're going down, War.");
2419 break;
2420 case MS_VICE:
2421 verbalize("I shall taint your soul before I send you to Hell.");
2422 break;
2423 case MS_DOUGLAS_ADAMS:
2425 static const char *da_msgs[] = {
2426 "42",
2427 "It's a nice day today!",
2428 "Have a Pan Galactic Gargle Blaster?",
2429 "Time is relative. Lunchtime doubly so.",
2430 "This is some strange usage of the word 'safe' that I wasn't aware of.",
2432 if (mtmp->data == &mons[PM_MARVIN]) {
2433 verbalize("Life, loathe it or ignore it, you cannot like it.");
2434 } else if (mtmp->data == &mons[PM_DEEP_THOUGHT]) {
2435 verbalize("6*9 = 42");
2436 } else if (mtmp->data == &mons[PM_EDDIE]) {
2437 verbalize("I'm feeling just great, guys!");
2438 } else {
2439 verbalize("%s", da_msgs[rn2(SIZE(da_msgs))]);
2442 break;
2443 case MS_PUPIL:
2444 verbalize("No, I do not have the homework today and you are a shitty teacher anyway.");
2445 break;
2446 case MS_TEACHER:
2447 verbalize("You get 10 hours of detention for your misbehavior!");
2448 break;
2449 case MS_PRINCIPAL:
2450 verbalize("Now come here, little rascal! We're gonna have a SERIOUS talk about the things you did!");
2451 break;
2453 default: /* nothing happens */
2454 break;
2459 if ((mdat->msound == MS_CONVERT || mtmp->egotype_converter) && !(bmwride(ART_SHUT_UP_YOU_FUCK) && u.usteed && (mtmp == u.usteed) ) && !Race_if(PM_TURMENE) && !Race_if(PM_HC_ALIEN) && !Race_if(PM_SLYER_ALIEN) && !mtmp->mpeaceful && (distu(mtmp->mx, mtmp->my) <= BOLT_LIM * BOLT_LIM) && !(have_hardcoreaddiction() && rn2(10)) && !(uarmh && uarmh->oartifact == ART_JAMILA_S_BELIEF) && !rn2(10)) {
2461 conversionsermon();
2463 u.cnd_conversioncount++;
2464 if (Role_if(PM_SOCIAL_JUSTICE_WARRIOR)) sjwtrigger();
2466 armpro = magic_negation(&youmonst);
2467 armprolimit = 75;
2468 if (!(PlayerCannotUseSkills)) {
2470 switch (P_SKILL(P_SPIRITUALITY)) {
2471 default: armprolimit = 75; break;
2472 case P_BASIC: armprolimit = 78; break;
2473 case P_SKILLED: armprolimit = 81; break;
2474 case P_EXPERT: armprolimit = 84; break;
2475 case P_MASTER: armprolimit = 87; break;
2476 case P_GRAND_MASTER: armprolimit = 90; break;
2477 case P_SUPREME_MASTER: armprolimit = 93; break;
2481 if ((rn2(3) >= armpro) || ((rnd(100) > armprolimit) && ((armpro < 4) || (rnd(armpro) < 4) ) ) ) {
2483 if (uarmf && uarmf->oartifact == ART_RUEA_S_FAILED_CONVERSION && rn2(20)) goto convertdone;
2484 if (uwep && uwep->oartifact == ART_CRONVERT && rn2(10)) goto convertdone;
2485 if (uarmf && uarmf->oartifact == ART_EXHAUST_DAMAGE) goto convertdone;
2486 if (uamul && uamul->otyp == AMULET_OF_SPECIAL_SHIELDING && rn2(3)) goto convertdone;
2488 You_feel("less faithful!");
2490 if (u.ualign.record < -20 && !rn2(Race_if(PM_KORONST) ? 10 : 100) && (sgn(mtmp->data->maligntyp) != u.ualign.type) ) { /* You have been converted! */
2492 if(u.ualignbase[A_CURRENT] == u.ualignbase[A_ORIGINAL] && mtmp->data->maligntyp != A_NONE) {
2493 You("have a strong feeling that %s is angry...", u_gname());
2494 pline("%s accepts your allegiance.", align_gname(sgn(mtmp->data->maligntyp)));
2496 /* The player wears a helm of opposite alignment? */
2497 if (uarmh && uarmh->otyp == HELM_OF_OPPOSITE_ALIGNMENT)
2498 u.ualignbase[A_CURRENT] = sgn(mtmp->data->maligntyp);
2499 else
2500 u.ualign.type = u.ualignbase[A_CURRENT] = sgn(mtmp->data->maligntyp);
2501 u.ublessed = 0;
2502 flags.botl = 1;
2504 You("have a sudden sense of a new direction.");
2505 /* Beware, Conversion is costly */
2506 change_luck(-3);
2507 u.ublesscnt += (ishaxor ? 150 : 300);
2508 adjalign((int)(u.ualignbase[A_ORIGINAL] * (u.alignlim / 2)));
2510 } else {
2511 u.ugangr += 3;
2512 adjalign(-25);
2513 godvoice(sgn(mtmp->data->maligntyp), "Suffer, infidel!");
2514 change_luck(-5);
2515 (void) adjattrib(A_WIS, -2, TRUE, TRUE);
2516 angrygods(sgn(mtmp->data->maligntyp));
2520 adjalign(-(mtmp->m_lev + 1));
2522 if (!rn2(10)) badeffect();
2528 convertdone:
2530 if ((mdat->msound == MS_HCALIEN || mtmp->egotype_wouwouer) && !(bmwride(ART_SHUT_UP_YOU_FUCK) && u.usteed && (mtmp == u.usteed) ) && !Race_if(PM_TURMENE) && !Race_if(PM_HC_ALIEN) && !Race_if(PM_SLYER_ALIEN) && !mtmp->mpeaceful && (distu(mtmp->mx, mtmp->my) <= BOLT_LIM * BOLT_LIM) && !(have_hardcoreaddiction() && rn2(4)) && !(uarmh && uarmh->oartifact == ART_JAMILA_S_BELIEF) && !rn2(15)) {
2532 wouwoutaunt();
2533 u.cnd_wouwoucount++;
2534 if (Role_if(PM_SOCIAL_JUSTICE_WARRIOR)) sjwtrigger();
2536 armpro = magic_negation(&youmonst);
2537 armprolimit = 75;
2538 if (!(PlayerCannotUseSkills)) {
2540 switch (P_SKILL(P_SPIRITUALITY)) {
2541 default: armprolimit = 75; break;
2542 case P_BASIC: armprolimit = 78; break;
2543 case P_SKILLED: armprolimit = 81; break;
2544 case P_EXPERT: armprolimit = 84; break;
2545 case P_MASTER: armprolimit = 87; break;
2546 case P_GRAND_MASTER: armprolimit = 90; break;
2547 case P_SUPREME_MASTER: armprolimit = 93; break;
2551 if ((rn2(3) >= armpro) || ((rnd(100) > armprolimit) && ((armpro < 4) || (rnd(armpro) < 4) ) ) ) {
2553 boolean wouwouresisted = FALSE;
2555 if (MysteryResist && !rn2(StrongMysteryResist ? 3 : 5)) wouwouresisted = TRUE;
2556 if (chitinprotection() && !rn2(5)) wouwouresisted = TRUE;
2557 if (uamul && uamul->otyp == AMULET_OF_SPECIAL_SHIELDING && rn2(3)) wouwouresisted = TRUE;
2559 if (!wouwouresisted) {
2561 badeffect();
2562 stop_occupation();
2563 if (!obsidianprotection()) switch (rn2(17)) {
2564 case 0:
2565 case 1:
2566 case 2:
2567 case 3: make_confused(HConfusion + rnd(100 + (mtmp->m_lev * 5) ), FALSE); /* 40% */
2568 break;
2569 case 4:
2570 case 5:
2571 case 6: make_confused(HConfusion + (2L * rnd(100 + (mtmp->m_lev * 5) ) / 3L), FALSE); /* 30% */
2572 make_stunned(HStun + (rnd(100 + (mtmp->m_lev * 5) ) / 3L), FALSE);
2573 break;
2574 case 7:
2575 case 8: make_stunned(HStun + (2L * rnd(100 + (mtmp->m_lev * 5) ) / 3L), FALSE); /* 20% */
2576 make_confused(HConfusion + (rnd(100 + (mtmp->m_lev * 5) ) / 3L), FALSE);
2577 break;
2578 case 9: make_stunned(HStun + rnd(100 + (mtmp->m_lev * 5) ), FALSE); /* 10% */
2579 break;
2580 case 10: make_numbed(HNumbed + rnd(100 + (mtmp->m_lev * 5) ), FALSE); /* 10% */
2581 break;
2582 case 11: make_frozen(HFrozen + rnd(100 + (mtmp->m_lev * 5) ), FALSE); /* 10% */
2583 break;
2584 case 12: make_burned(HBurned + rnd(100 + (mtmp->m_lev * 5) ), FALSE); /* 10% */
2585 break;
2586 case 13: make_feared(HFeared + rnd(100 + (mtmp->m_lev * 5) ), FALSE); /* 10% */
2587 break;
2588 case 14: make_blinded(Blinded + rnd(100 + (mtmp->m_lev * 5) ), FALSE); /* 10% */
2589 break;
2590 case 15: make_hallucinated(HHallucination + rnd(100 + (mtmp->m_lev * 5) ), FALSE, 0L); /* 10% */
2591 break;
2592 case 16: make_dimmed(HDimmed + rnd(100 + (mtmp->m_lev * 5) ), FALSE); /* 10% */
2593 break;
2595 if (!rn2(20)) increasesanity(rnd(10 + (mtmp->m_lev * 2) ));
2601 if (mdat->msound == MS_SHOE && !mtmp->mpeaceful && evilfriday && !(bmwride(ART_SHUT_UP_YOU_FUCK) && u.usteed && (mtmp == u.usteed) ) && !rn2(50) && (distu(mtmp->mx, mtmp->my) <= 12)) {
2602 int paralysistime = mtmp->m_lev / 4;
2603 if (!isstunfish && (paralysistime > 1)) paralysistime = rnd(paralysistime);
2604 if (paralysistime > 5) {
2605 while (rn2(5) && (paralysistime > 5)) {
2606 paralysistime--;
2610 pline("%s uses %s sweaty inlay, causing you to become unconscious from the stench!", Monnam(mtmp), mhis(mtmp));
2611 if (isstunfish) nomul(-(rnz(5) + paralysistime), "smelling sweaty inlays", TRUE);
2612 else nomul(-(rnd(5) + paralysistime), "smelling sweaty inlays", TRUE);
2615 if (spawnswithsneakers(mtmp->data) && !mtmp->mpeaceful && FemtrapActiveKerstin && !(bmwride(ART_SHUT_UP_YOU_FUCK) && u.usteed && (mtmp == u.usteed) ) && !rn2(50) && (distu(mtmp->mx, mtmp->my) <= 12)) {
2616 int paralysistime = mtmp->m_lev / 4;
2617 if (paralysistime > 1) paralysistime = rnd(paralysistime);
2618 if (paralysistime > 5) {
2619 while (rn2(5) && (paralysistime > 5)) {
2620 paralysistime--;
2624 pline("%s uses %s sweaty inlay, causing you to become unconscious from the stench!", Monnam(mtmp), mhis(mtmp));
2625 if (isstunfish) nomul(-(rnz(5) + paralysistime), "smelling sweaty inlays", TRUE);
2626 else nomul(-(rnd(5) + paralysistime), "smelling sweaty inlays", TRUE);
2629 if (mdat == &mons[PM_STINKING_HEAP_OF_SHIT] && multi >= 0 && !(bmwride(ART_SHUT_UP_YOU_FUCK) && u.usteed && (mtmp == u.usteed) ) && (distu(mtmp->mx, mtmp->my) <= BOLT_LIM * BOLT_LIM) && !rn2(10)) {
2630 pline("Urrrrrgh, there seems to be a stinking heap of shit nearby! You pass out from the vile stench.");
2631 if (isstunfish) nomul(-(rnz(5)), "unconscious from smelling shit", TRUE);
2632 else nomul(-(rnd(5)), "unconscious from smelling shit", TRUE);
2634 if (mdat == &mons[PM_HEAP_OF_SHIT] && multi >= 0 && !(bmwride(ART_SHUT_UP_YOU_FUCK) && u.usteed && (mtmp == u.usteed) ) && (distu(mtmp->mx, mtmp->my) <= BOLT_LIM * BOLT_LIM) && !rn2(10)) {
2635 pline("Urrrrrgh, there seems to be a stinking heap of shit nearby! You pass out from the vile stench.");
2636 if (isstunfish) nomul(-(rnz(5)), "unconscious from smelling shit", TRUE);
2637 else nomul(-(rnd(5)), "unconscious from smelling shit", TRUE);
2639 if (mdat == &mons[PM_STINK_HOMER] && multi >= 0 && !(bmwride(ART_SHUT_UP_YOU_FUCK) && u.usteed && (mtmp == u.usteed) ) && (distu(mtmp->mx, mtmp->my) <= BOLT_LIM * BOLT_LIM) && !rn2(10)) {
2640 pline("Urrrrrgh, some really stinky person seems to be nearby! You pass out from the vile stench.");
2641 if (isstunfish) nomul(-(rnz(5)), "unconscious from the stink homer's stench", TRUE);
2642 else nomul(-(rnd(5)), "unconscious from the stink homer's stench", TRUE);
2644 if (mdat == &mons[PM_HUEPPOGREIFSCH] && multi >= 0 && !(bmwride(ART_SHUT_UP_YOU_FUCK) && u.usteed && (mtmp == u.usteed) ) && (distu(mtmp->mx, mtmp->my) <= BOLT_LIM * BOLT_LIM) && !rn2(10)) {
2645 pline("Oh, damn hueppogreifsch...");
2646 if (isstunfish) nomul(-(rnz(5)), "unconscious from the hueppogreifsch", TRUE);
2647 else nomul(-(rnd(5)), "unconscious from the hueppogreifsch", TRUE);
2649 if (mdat == &mons[PM_WOK] && !(bmwride(ART_SHUT_UP_YOU_FUCK) && u.usteed && (mtmp == u.usteed) ) && (distu(mtmp->mx, mtmp->my) <= BOLT_LIM * BOLT_LIM) && !rn2(10)) {
2650 verbalize("I am the WOK!");
2653 if ((mdat == &mons[PM_NOISY_ANNOYANCE] || mdat == &mons[PM_DEMAGOGUE] || mdat == &mons[PM_UNDEAD_DEMAGOGUE]) && !(bmwride(ART_SHUT_UP_YOU_FUCK) && u.usteed && (mtmp == u.usteed) ) && (distu(mtmp->mx, mtmp->my) <= BOLT_LIM * BOLT_LIM) && !rn2(20)) {
2654 demagogueparole();
2655 aggravate();
2657 if (mdat == &mons[PM_GHOST_PORKER] && !(bmwride(ART_SHUT_UP_YOU_FUCK) && u.usteed && (mtmp == u.usteed) ) && (distu(mtmp->mx, mtmp->my) <= BOLT_LIM * BOLT_LIM) && !rn2(20)) {
2658 verbalize("DENERF! DENERF! DENERF!");
2660 if (mdat == &mons[PM_MIKRAANESIS] && !(bmwride(ART_SHUT_UP_YOU_FUCK) && u.usteed && (mtmp == u.usteed) ) && (distu(mtmp->mx, mtmp->my) <= BOLT_LIM * BOLT_LIM) && !rn2(20)) {
2661 pline("*tschoeck tschoeck* Mikraanesis stopped time.");
2662 if (isstunfish) nomul(-(rnz(10)), "Mikraanesis had stopped time", FALSE);
2663 else nomul(-(rnd(10)), "Mikraanesis had stopped time", FALSE);
2666 if (FemtrapActiveSueLyn && u.ualign.record < 0 && mtmp->female && mtmp->data->msound == MS_FART_NORMAL) {
2667 if (mtmp->mtame) mtmp->mtame = FALSE;
2668 if (mtmp->mpeaceful) mtmp->mpeaceful = FALSE;
2669 mtmp->mfrenzied = TRUE;
2672 if (mdat->msound == MS_TREESQUAD && u.treesquadwantedlevel) {
2673 if (mtmp->mtame) mtmp->mtame = FALSE;
2674 if (mtmp->mpeaceful) mtmp->mpeaceful = FALSE;
2677 if (mdat->msound == MS_AREOLA && (distu(mtmp->mx, mtmp->my) <= BOLT_LIM * BOLT_LIM) && m_canseeu(mtmp) ) {
2678 int areolachance = 500;
2679 int playerareola = u.areoladiameter;
2680 if (playerareola >= 10 && playerareola <= 30) {
2681 while (playerareola > 20) {
2682 areolachance -= 40;
2683 playerareola--;
2685 while (playerareola < 20) {
2686 areolachance += 50;
2687 playerareola++;
2690 else switch (u.areoladiameter) {
2691 default: areolachance = 500; break;
2692 case 1: areolachance = 1000000; break;
2693 case 2: areolachance = 25000; break;
2694 case 3: areolachance = 10000; break;
2695 case 4: areolachance = 5000; break;
2696 case 5: areolachance = 4000; break;
2697 case 6: areolachance = 3000; break;
2698 case 7: areolachance = 2000; break;
2699 case 8: areolachance = 1500; break;
2700 case 9: areolachance = 1200; break;
2701 case 31: areolachance = 90; break;
2702 case 32: areolachance = 80; break;
2703 case 33: areolachance = 70; break;
2704 case 34: areolachance = 60; break;
2705 case 35: areolachance = 50; break;
2706 case 36: areolachance = 40; break;
2707 case 37: areolachance = 30; break;
2708 case 38: areolachance = 20; break;
2709 case 39: areolachance = 10; break;
2710 case 40: areolachance = 5; break;
2713 if (!rn2(areolachance)) {
2715 if ((flags.female && mtmp->female) || (!flags.female && !mtmp->female)) {
2716 if (mtmp->mtame) {
2717 mtmp->mtame = FALSE;
2718 pline("%s doesn't seem to want you anymore!", Monnam(mtmp));
2719 } else if (mtmp->mpeaceful) {
2720 mtmp->mpeaceful = FALSE;
2721 pline("%s is getting all envious about you, and decides to attack!", Monnam(mtmp));
2723 } else {
2724 if (!mtmp->mfrenzied) {
2725 if (!mtmp->mpeaceful) {
2726 mtmp->mpeaceful = TRUE;
2727 pline("%s seems to like you, and decides to stop attacking!", Monnam(mtmp));
2728 } else if (!mtmp->mtame) {
2729 pline("%s is crazy about you, and wants to join your team!", Monnam(mtmp));
2730 mtmp = tamedog(mtmp, (struct obj *) 0, TRUE);
2731 if (!mtmp) return 1; /* shouldn't happen, but who knows... */
2740 if ( ((mdat->msound == MS_STABILIZE) || (mtmp->egotype_stabilizer)) && !u.antitelespelltimeout && !rn2(100) && (distu(mtmp->mx, mtmp->my) <= BOLT_LIM * BOLT_LIM) ) {
2741 u.antitelespelltimeout = rnz(20);
2742 pline("%s stabilizes the space around.", Monnam(mtmp)); /* message is sic from Elona */
2745 if ( ((mdat->msound == MS_ESCAPE) || (mtmp->egotype_escaper)) && (mtmp->mhp < (mtmp->mhpmax / 4)) ) {
2746 pline("%s vanishs.", Monnam(mtmp)); /* message is sic from Elona */
2747 mongone(mtmp);
2748 return 1;
2751 if ( ((mdat->msound == MS_SELFHARM) || (mtmp->egotype_selfharmer)) && !rn2(50)) {
2753 if (canseemon(mtmp)) {
2754 switch (rnd(7)) {
2756 case 1: pline("%s puts the knife to %s lower %s and cuts...", Monnam(mtmp), mhis(mtmp), mbodypart(mtmp, ARM)); break;
2757 case 2: pline("%s uses a sharp object to cut open %s belly...", Monnam(mtmp), mhis(mtmp)); break;
2758 case 3: pline("%s slides %s body along a rough surface and sustains terrible skin rashes.", Monnam(mtmp), mhis(mtmp)); break;
2759 case 4: pline("%s rips %s butt open with a metallic edge.", Monnam(mtmp), mhis(mtmp)); break;
2760 case 5: pline("%s scratches up and down %s %s with a sexy leather pump until it starts bleeding.", Monnam(mtmp), mhis(mtmp), mbodypart(mtmp, LEG)); break;
2761 case 6: pline("%s slits %s %s full length with a sharp-edged zipper.", Monnam(mtmp), mhis(mtmp), mbodypart(mtmp, LEG)); break;
2762 case 7: pline("%s pricks %srself with a needle.", Monnam(mtmp), mhim(mtmp)); break;
2764 increasesanity(rnz(25 + mtmp->m_lev));
2766 mtmp->bleedout += rnz(12);
2770 if (mdat->msound == MS_POKEDEX && (distu(mtmp->mx, mtmp->my) <= BOLT_LIM * BOLT_LIM) && !rn2(100)) {
2771 int pokedexmon = rn2(NUMMONS);
2773 somepokedex(pokedexmon);
2776 if (mdat->msound == MS_BRAG && !mtmp->mpeaceful && (distu(mtmp->mx, mtmp->my) <= BOLT_LIM * BOLT_LIM) && !rn2(20)) {
2777 switch (rnd(11)) {
2778 case 1:
2779 pline("%s brags 'No one can take off my remaining %d HP!'", Monnam(mtmp), mtmp->mhp);
2780 break;
2781 case 2:
2782 pline("%s brags 'My health status is very good, I've got %d HP!'", Monnam(mtmp), mtmp->mhp);
2783 break;
2784 case 3:
2785 pline("%s brags 'I'm very powerful with my %d HP!'", Monnam(mtmp), mtmp->mhp);
2786 break;
2787 case 4:
2788 pline("%s brags 'Man, I'm really the sturdiest being in this dungeon, I've got %d HP! Fear me!'", Monnam(mtmp), mtmp->mhp);
2789 break;
2790 case 5:
2791 pline("%s brags 'Ha! I've got %d HP remaining!'", Monnam(mtmp), mtmp->mhp);
2792 break;
2793 case 6:
2794 pline("%s brags 'Yo, my maximum HP is a whopping %d!'", Monnam(mtmp), mtmp->mhpmax);
2795 break;
2796 case 7:
2797 pline("%s brags 'Hey, my level is %d! I bet yours is lower!'", Monnam(mtmp), mtmp->m_lev);
2798 break;
2799 case 8:
2800 pline("%s brags 'Fear my movement rate of %d!'", Monnam(mtmp), mtmp->movement);
2801 break;
2802 case 9:
2803 pline("%s brags 'I hold the high ground at coordinates %d,%d!'", Monnam(mtmp), mtmp->mx, mtmp->my);
2804 break;
2805 case 10:
2806 pline("%s brags 'Still got %d mana left!'", Monnam(mtmp), mtmp->m_en);
2807 break;
2808 case 11:
2809 pline("%s brags 'You certainly can't beat my max mana of %d...'", Monnam(mtmp), mtmp->m_enmax);
2810 break;
2814 if ((mdat->msound == MS_STENCH || mtmp->egotype_perfumespreader) && !(uarmf && uarmf->oartifact == ART_BARBED_HOOK_ZIPPER && !mtmp->mfrenzied) && !Role_if(PM_HUSSY) && !(youmonst.data->msound == MS_STENCH) && !(bmwride(ART_SHUT_UP_YOU_FUCK) && u.usteed && (mtmp == u.usteed) ) && !mtmp->mpeaceful && (distu(mtmp->mx, mtmp->my) <= BOLT_LIM * BOLT_LIM) && !rn2((mdat == &mons[PM_NICE_AUNTIE_HILDA]) ? 5 : (mdat == &mons[PM_AUNT_ANITA]) ? 5 : 20)) {
2816 boolean wouwouresisted = FALSE;
2818 if (MysteryResist && !rn2(StrongMysteryResist ? 3 : 5)) wouwouresisted = TRUE;
2819 if (chitinprotection() && !rn2(5)) wouwouresisted = TRUE;
2820 if (uamul && uamul->otyp == AMULET_OF_SPECIAL_SHIELDING && rn2(3)) wouwouresisted = TRUE;
2822 if (!wouwouresisted) {
2824 switch (rnd(10)) {
2826 case 1:
2827 pline("Urgh! You inhale the vile stench that emanates from %s!", mon_nam(mtmp));
2828 break;
2829 case 2:
2830 if (mtmp->female) pline("%s's perfume is beguiling, and you have trouble concentrating!", Monnam(mtmp));
2831 else pline("Ugh, %s's body lotion smells utterly repulsive. You can hardly concentrate on what you're doing.", mon_nam(mtmp));
2832 break;
2833 case 3:
2834 if (mtmp->female) pline("You deeply inhale %s's feminine scent.", mon_nam(mtmp));
2835 else pline("%s's gritty aftershave makes you dizzy.", Monnam(mtmp));
2836 break;
2837 case 4:
2838 if (mtmp->female) pline("%s's odor cloud made of concentrated perfume infiltrates your %s!", Monnam(mtmp), body_part(NOSE));
2839 else pline("Bleh, your %s just can't handle the stench that %s's aftershave is spreading.", body_part(NOSE), mon_nam(mtmp));
2840 break;
2841 case 5:
2842 pline("Your %s are having trouble dealing with the asphyxiating stench that comes from %s!", makeplural(body_part(LUNG)), mon_nam(mtmp));
2843 break;
2844 case 6:
2845 if (mtmp->female) pline("%s attacks you with a fragrance cloud!", Monnam(mtmp));
2846 else pline("%s attacks you with a stinking cloud!", Monnam(mtmp));
2847 break;
2848 case 7:
2849 if (mtmp->female) pline("%s is close enough that you can smell %s perfume... but it's way too concentrated, and inhaling the aroma makes you dizzy!", Monnam(mtmp), mhis(mtmp));
2850 else pline("The unbearable odor of %s's body lotion wafts through the dungeon, and having to smell such a stink makes you want to vomit.", mon_nam(mtmp));
2851 break;
2852 case 8:
2853 if (mtmp->female) pline("The lovely scent of femininity floods your nostrils... until you realize that it's getting ever stronger, and you are having trouble when breathing!");
2854 else pline("Some bitter male smell is hanging in the air... and it's getting stronger! You can hardly breathe!");
2855 break;
2856 case 9:
2857 if (mtmp->female) pline("%s's perfume is so scentful that %s reminds you of what your aunt smells like when she comes for a visit on Christmas! Ugh!", Monnam(mtmp), mhe(mtmp));
2858 else pline("Even your most odoriferous relative doesn't smell as bad as %s! Ugh!", mon_nam(mtmp));
2859 break;
2860 case 10:
2861 pline("%s's odor reminds you of an oriental brothel! What an intrusive perfume is %s using, anyway?", Monnam(mtmp), mhe(mtmp));
2862 break;
2864 u.cnd_perfumecount++;
2865 if (Role_if(PM_SOCIAL_JUSTICE_WARRIOR)) sjwtrigger();
2867 if (rn2(10) && uarmh && itemhasappearance(uarmh, APP_GAS_MASK) ) {
2868 pline("But the gas mask protects you from the effects.");
2869 } else if (rn2(5) && uarmf && uarmf->oartifact == ART_CLAUDIA_S_SELF_WILL) {
2870 pline("But you actually enjoy the lovely scent.");
2871 } else if (rn2(20) && uwep && uwep->oartifact == ART_HIGH_ORIENTAL_PRAISE) {
2872 pline("But you actually enjoy the lovely scent.");
2873 } else if (rn2(10) && uarmf && uarmf->oartifact == ART_KATHARINA_S_SIGH) {
2874 pline("But you actually enjoy the lovely scent.");
2875 } else {
2877 badeffect();
2878 if (rn2(2) || Role_if(PM_EMERA)) increasesanity(rnz(20 + mtmp->m_lev));
2879 stop_occupation();
2881 } /* mystery res check */
2884 /* Monsters with MS_BONES can rattle. If this causes you to snap out of a longer paralysis, more power to you :D */
2885 if (mdat->msound == MS_BONES && !(bmwride(ART_SHUT_UP_YOU_FUCK) && u.usteed && (mtmp == u.usteed) ) && !mtmp->mpeaceful && (distu(mtmp->mx, mtmp->my) <= BOLT_LIM * BOLT_LIM) && !rn2(100)) {
2886 pline(FunnyHallu ? "%s plays the xylophone!" : "%s rattles noisily!", Monnam(mtmp));
2888 armpro = magic_negation(&youmonst);
2889 armprolimit = 75;
2890 if (!(PlayerCannotUseSkills)) {
2892 switch (P_SKILL(P_SPIRITUALITY)) {
2893 default: armprolimit = 75; break;
2894 case P_BASIC: armprolimit = 78; break;
2895 case P_SKILLED: armprolimit = 81; break;
2896 case P_EXPERT: armprolimit = 84; break;
2897 case P_MASTER: armprolimit = 87; break;
2898 case P_GRAND_MASTER: armprolimit = 90; break;
2899 case P_SUPREME_MASTER: armprolimit = 93; break;
2903 if ((rn2(3) >= armpro) || ((rnd(100) > armprolimit) && ((armpro < 4) || (rnd(armpro) < 4) ) ) ) {
2904 You("freeze for a moment.");
2905 nomul(-2, "scared by rattling", TRUE);
2906 nomovemsg = 0;
2910 if (FemtrapActiveLisa && mtmp->female && humanoid(mtmp->data) && !mtmp->lisaseen && canseemon(mtmp)) {
2912 pline("%s comes into view. She is wearing %s.", Monnam(mtmp), pantsdescription(mtmp));
2914 mtmp->lisaseen = TRUE;
2918 /* the watch will look around and see if you are up to no good :-) */
2919 if (mdat == &mons[PM_WATCHMAN] || mdat == &mons[PM_WATCH_CAPTAIN] || mdat == &mons[PM_WATCH_LEADER] || mdat == &mons[PM_WATCH_LIEUTENANT])
2920 watch_on_duty(mtmp);
2922 /* [DS] Cthulhu also uses psychic blasts */
2923 else if ((is_mind_flayer(mdat) || mdat == &mons[PM_CTHULHU] || mdat == &mons[PM_FLYING_ASSHOLE] )
2924 && !rn2( (uarmh && itemhasappearance(uarmh, APP_NARROW_HELMET) ) ? 4 : 20)) {
2925 struct monst *m2, *nmon = (struct monst *)0;
2927 if (canseemon(mtmp))
2928 pline("%s concentrates.", Monnam(mtmp));
2929 if (distu(mtmp->mx, mtmp->my) > BOLT_LIM * BOLT_LIM) {
2930 You(FunnyHallu ? "sense a fantastic wave of psychic energy." : "sense a faint wave of psychic energy.");
2931 if (!mtmp->mpeaceful && !(uarmh && uarmh->oartifact == ART_NOTKNOW_EY) && !rn2(5)) maybehackimplant();
2932 goto toofar;
2934 pline("A wave of psychic energy pours over you!");
2935 if ( (mtmp->mpeaceful || (Psi_resist && rn2(StrongPsi_resist ? 100 : 20) ) ) &&
2936 (!Conflict || resist(mtmp, RING_CLASS, 0, 0))) {
2937 pline("It feels quite soothing.");
2938 } else if ((uarmh && uarmh->oartifact == ART_NOTKNOW_EY) || (uarmh && itemhasappearance(uarmh, APP_TT_HELMET)) || (uarmh && uarmh->oartifact == ART_PROTECTOR_NO____)) {
2939 pline("But it doesn't affect you.");
2940 } else {
2941 if (!mtmp->mpeaceful) maybehackimplant();
2942 register boolean m_sen = sensemon(mtmp);
2944 if (m_sen || (Blind_telepat && rn2(2)) || !rn2(10)) {
2945 int dmg;
2946 pline("It locks on to your %s!",
2947 m_sen ? "telepathy" :
2948 Blind_telepat ? "latent telepathy" : "mind");
2949 dmg = (mdat == &mons[PM_CTHULHU])?
2950 rn1(10, 10) :
2951 rn1(4, 4);
2952 if (Half_spell_damage && rn2(2) ) dmg = (dmg+1) / 2;
2953 if (StrongHalf_spell_damage && rn2(2) ) dmg = (dmg+1) / 2;
2954 if (!rn2(100)) { /* evil patch idea by jonadab: 1% chance of causing amnesia */
2955 forget(1 + rn2(5), FALSE);
2957 /* evil patch idea by Amy: chance of causing other adverse effects, like ToME eldritch horror */
2958 if (!rn2(100)) {
2959 losexp("eldritch life force drain", FALSE, TRUE);
2961 if (!rn2(100)) {
2962 make_stunned(HStun + rnd(10) + rnd(monster_difficulty() + 1), TRUE);
2963 make_confused(HConfusion + rnd(10) + rnd(monster_difficulty() + 1), TRUE);
2964 pline("You're confused!");
2966 if (!rn2(100)) {
2967 adjattrib(A_INT, -1, 1, TRUE);
2968 adjattrib(A_WIS, -1, 1, TRUE);
2970 if (!rn2(100)) {
2971 (void) make_hallucinated(HHallucination + rnd(10) + rnd(monster_difficulty() + 1), TRUE, 0L);
2972 if (!Free_action || !rn2(StrongFree_action ? 100 : 20)) {
2973 pline("You are frozen in place!");
2974 if (isstunfish) nomul(-rnz(5), "frozen by an eldritch blast", TRUE);
2975 else nomul(-rnd(5), "frozen by an eldritch blast", TRUE);
2976 if (PlayerHearsSoundEffects) pline(issoviet ? "Teper' vy ne mozhete dvigat'sya. Nadeyus', chto-to ubivayet vas, prezhde chem vash paralich zakonchitsya." : "Klltsch-tsch-tsch-tsch-tsch!");
2977 nomovemsg = You_can_move_again;
2978 exercise(A_DEX, FALSE);
2982 if (!rn2(100)) {
2983 pline("You let out a bloodcurdling scream!");
2984 wake_nearby();
2986 if (!rn2(100)) {
2987 make_feared(HFeared + rnd(10) + rnd(monster_difficulty() + 1), TRUE);
2989 if (!rn2(100)) {
2990 badeffect();
2992 if (!rn2(100)) {
2993 badeffect();
2995 if (!rn2(100)) {
2996 badeffect();
2998 losehp(dmg, "psychic blast", KILLED_BY_AN);
2999 if (!rn2(25)) increasesanity(rnz(5));
3000 make_magicvacuum((HMagicVacuum & TIMEOUT) + rnd((mtmp->m_lev * 10) + 1) );
3002 stop_occupation();
3005 for(m2=fmon; m2; m2 = nmon) {
3006 nmon = m2->nmon;
3007 if (DEADMONSTER(m2)) continue;
3008 if (m2->mpeaceful == mtmp->mpeaceful) continue;
3009 if (mindless(m2->data) || m2->egotype_undead) continue;
3011 /* WTF! why would that have infinite range --Amy */
3012 if (dist2(mtmp->mx, mtmp->my, m2->mx, m2->my) > (BOLT_LIM * BOLT_LIM)) continue;
3014 if (m2 == mtmp) continue;
3015 if ((telepathic(m2->data) &&
3016 (rn2(2) || m2->mblinded)) || !rn2(10)) {
3017 if (cansee(m2->mx, m2->my))
3018 pline("It locks on to %s.", mon_nam(m2));
3019 m2->mhp -= (mtmp->mpeaceful ? rnd(2) : rnd(15));
3020 if (m2->mhp <= 0)
3021 if (mtmp->uexp)
3022 mon_xkilled(m2, "", AD_DRIN);
3023 else
3024 monkilled(m2, "", AD_DRIN);
3025 else
3026 m2->msleeping = 0;
3031 /* occasionally hint at the presence of psychic beings, if you are telepathic --Amy */
3032 if (dmgtype(mdat, AD_SPC2) && !rn2((uarmh && itemhasappearance(uarmh, APP_NARROW_HELMET) ) ? 40 : 200) && Blind_telepat) {
3033 You(FunnyHallu ? "sense a fantastic psionic wave." : "sense a faint psionic wave.");
3036 toofar:
3038 /* try to attack the player's pets at range, if possible (from dnethack) */
3039 if (!DEADMONSTER(mtmp) && !mtmp->mpeaceful && !mtmp->mtame) {
3040 register struct monst *mtmp2 = mfind_target(mtmp, FALSE);
3041 if (mtmp2 && (mtmp2 != &youmonst) && (mtmp2 != mtmp)) {
3043 int res;
3044 res = mattackm(mtmp, mtmp2);
3045 if (res & MM_AGR_DIED) return 1; /* Oops. */
3046 /* now the pet should be able to fight back if it's still alive */
3047 if (rn2(4) && !(res & MM_AGR_DIED) && !(res & MM_DEF_DIED) && ((res & MM_HIT) || !rn2(5)) ) {
3048 res = mattackm(mtmp2, mtmp);
3049 if (res & MM_DEF_DIED) return 1; /* Oops. */
3054 /* If monster is nearby you, and has to wield a weapon, do so. This
3055 * costs the monster a move, of course.
3057 if((!mtmp->mpeaceful || Conflict) && inrange &&
3058 dist2(mtmp->mx, mtmp->my, mtmp->mux, mtmp->muy) <= 8
3059 && attacktype(mdat, AT_WEAP)) {
3060 struct obj *mw_tmp;
3062 /* The scared check is necessary. Otherwise a monster that is
3063 * one square near the player but fleeing into a wall would keep
3064 * switching between pick-axe and weapon. If monster is stuck
3065 * in a trap, prefer ranged weapon (wielding is done in thrwmu).
3066 * This may cost the monster an attack, but keeps the monster
3067 * from switching back and forth if carrying both.
3069 mw_tmp = MON_WEP(mtmp);
3070 if (!(scared && mw_tmp && is_pick(mw_tmp)) &&
3071 mtmp->weapon_check == NEED_WEAPON &&
3072 !(mtmp->mtrapped && !nearby && select_rwep(mtmp, FALSE))) {
3073 mtmp->weapon_check = NEED_HTH_WEAPON;
3074 if (mon_wield_item(mtmp) != 0) return(0);
3078 /* Now the actual movement phase */
3080 #ifndef GOLDOBJ
3081 if(!nearby || (monsterflees(mtmp->data) && !rn2(3)) || (mtmp->mnum == PM_YOU_SEE_) || (mtmp->mnum == PM_BROKEN_UMBRELLA && !rn2(3)) || (mtmp->data->msound == MS_METALMAFIA && !rn2(3)) || (u.singtrapocc && rn2(5)) || (u.katitrapocc && rn2(5)) || (uarmc && uarmc->oartifact == ART_AT_ARMS_LENGTH) || mtmp->mflee || scared ||
3082 mtmp->mconf || mtmp->mstun || (mtmp->minvis && !rn2(3)) ||
3083 (mdat->mlet == S_LEPRECHAUN && !u.ugold && (mtmp->mgold || rn2(2))) ||
3085 #else
3086 if (mdat->mlet == S_LEPRECHAUN) {
3087 ygold = findgold(invent);
3088 lepgold = findgold(mtmp->minvent);
3091 if(!nearby || (monsterflees(mtmp->data) && !rn2(3)) || (mtmp->mnum == PM_YOU_SEE_) || (mtmp->mnum == PM_BROKEN_UMBRELLA && !rn2(3)) || (mtmp->data->msound == MS_METALMAFIA && !rn2(3)) || (u.singtrapocc && rn2(5)) || (u.katitrapocc && rn2(5)) || (uarmc && uarmc->oartifact == ART_AT_ARMS_LENGTH) || mtmp->mflee || scared ||
3092 mtmp->mconf || mtmp->mstun || (mtmp->minvis && !rn2(3)) ||
3093 (mdat->mlet == S_LEPRECHAUN && !ygold && (lepgold || rn2(2))) ||
3094 #endif
3095 (is_wanderer(mdat) && !rn2(4)) || (Race_if(PM_SWIKNI) && mtmp->isshk == 0 && mtmp->ispriest == 0 && mtmp->isgd == 0 && (!resist(mtmp, RING_CLASS, 0, 0) )) || (Conflict && mtmp->mcansee && haseyes(mtmp->data) && (!resist(mtmp, RING_CLASS, 0, 0) || (StrongConflict && !resist(mtmp, RING_CLASS, 0, 0)) ) && !mtmp->iswiz
3096 && !Is_blackmarket(&u.uz)
3097 ) ||
3098 (!mtmp->mcansee && !rn2(iswarper ? 2 : 8)) || mtmp->mpeaceful) {
3099 /* Possibly cast an undirected spell if not attacking you */
3100 /* note that most of the time castmu() will pick a directed
3101 spell and do nothing, so the monster moves normally */
3102 /* arbitrary distance restriction to keep monster far away
3103 from you from having cast dozens of sticks-to-snakes
3104 or similar spells by the time you reach it */
3105 if (dist2(mtmp->mx, mtmp->my, u.ux, u.uy) <= 49 && (!mtmp->mspec_used || (mtmp->data == &mons[PM_MAND_PENDING__MAGIC_SPELL___])) && (!rn2(iswarper ? 2 : 4) || (mtmp->data == &mons[PM_MAND_PENDING__MAGIC_SPELL___])) ) {
3106 struct attack *a;
3108 for (a = &mdat->mattk[0]; a < &mdat->mattk[NATTK]; a++) {
3109 if (a->aatyp == AT_MAGC && (a->adtyp == AD_SPEL || a->adtyp == AD_CLRC || a->adtyp == AD_CAST)) {
3111 if (castmu(mtmp, a, FALSE, FALSE)) {
3112 tmp = 3;
3113 break;
3117 if (mtmp->egotype_arcane) {
3118 mdat2 = &mons[PM_CAST_DUMMY];
3119 a = &mdat2->mattk[0];
3120 if (castmu(mtmp, a, FALSE, FALSE)) {
3121 tmp = 3;
3124 if (mtmp->egotype_clerical) {
3125 mdat2 = &mons[PM_CAST_DUMMY];
3126 a = &mdat2->mattk[1];
3127 if (castmu(mtmp, a, FALSE, FALSE)) {
3128 tmp = 3;
3131 if (mtmp->egotype_mastercaster) {
3132 mdat2 = &mons[PM_CAST_DUMMY];
3133 a = &mdat2->mattk[2];
3134 if (castmu(mtmp, a, FALSE, FALSE)) {
3135 tmp = 3;
3140 tmp = m_move(mtmp, 0);
3141 distfleeck(mtmp,&inrange,&nearby,&scared); /* recalc */
3143 switch (tmp) {
3144 case 0: /* no movement, but it can still attack you */
3145 case 3: /* absolutely no movement */
3146 /* for pets, case 0 and 3 are equivalent */
3147 /* vault guard might have vanished */
3148 if (mtmp->isgd && (mtmp->mhp < 1 ||
3149 (mtmp->mx == 0 && mtmp->my == 0)))
3150 return 1; /* behave as if it died */
3151 /* During hallucination, monster appearance should
3152 * still change - even if it doesn't move.
3154 if(Hallucination) newsym(mtmp->mx,mtmp->my);
3155 break;
3156 case 1: /* monster moved */
3157 /* Maybe it stepped on a trap and fell asleep... */
3158 if (mtmp->msleeping || !mtmp->mcanmove) return(0);
3159 if(!nearby &&
3160 (!issoviet || ranged_attk(mdat) || mtmp->egotype_weaponizer || mtmp->egotype_arcane || mtmp->egotype_clerical || mtmp->egotype_mastercaster || mtmp->egotype_hugger || (evilfriday && mtmp->data->mlet == S_GIANT) || (uarmf && itemhasappearance(uarmf, APP_CHRISTMAS_CHILD_MODE_BOOTS) && dmgtype(mtmp->data, AD_NIVE)) || mtmp->egotype_abomination || mtmp->egotype_weeper || mtmp->egotype_breather || mtmp->egotype_radiator || (FemtrapActiveNelly && humanoid(mtmp->data) && is_female(mtmp->data)) || (FemtrapActiveConny && thick_skinned(mtmp->data) && is_female(mtmp->data)) || mtmp->egotype_reactor || find_offensive(mtmp)))
3161 break;
3162 else if(u.uswallow && mtmp == u.ustuck) {
3163 /* a monster that's digesting you can move at the
3164 * same time -dlc
3166 return(mattacku(mtmp));
3167 } else
3168 return(0);
3169 /*NOTREACHED*/
3170 break;
3171 case 2: /* monster died */
3172 return(1);
3176 /* Now, attack the player if possible - one attack set per monst */
3178 if (!mtmp->mpeaceful || (mtmp->mnum == PM_FRENZY_KANGAROO) || (Race_if(PM_SWIKNI) && mtmp->isshk == 0 && mtmp->ispriest == 0 && mtmp->isgd == 0 && (!resist(mtmp, RING_CLASS, 0, 0) ) ) || ((Conflict && !resist(mtmp, RING_CLASS, 0, 0)) || (StrongConflict && !resist(mtmp, RING_CLASS, 0, 0)) && !Is_blackmarket(&u.uz)) ) {
3180 /* FIQ found out that self-genocide while polymorphed can make monsters stop attacking entirely. Fixed. */
3182 if(/*inrange && */ /* !noattacks(mdat) && */ (Upolyd || u.uhp > 0) && !scared && tmp != 3)
3183 /* noattacks check removed, since now there's things like egotype shriekers... --Amy */
3184 if(mattacku(mtmp)) return(1); /* monster died (e.g. exploded) */
3186 if(mtmp->wormno) wormhitu(mtmp);
3188 /* special speeches for quest monsters */
3189 if (!mtmp->msleeping && mtmp->mcanmove && nearby)
3190 quest_talk(mtmp);
3191 /* extra emotional attack for vile monsters */
3192 /* Come on, monsters can still cuss at you if you can't see them. Seriously, what the heck. --Amy */
3194 if(inrange && dmgtype(mtmp->data, AD_FAKE) && !mtmp->mpeaceful && !rn2(20))
3196 pline("%s", fauxmessage());
3197 u.cnd_plineamount++;
3198 if (!rn2(3)) {
3199 pline("%s", fauxmessage());
3200 u.cnd_plineamount++;
3204 if(inrange && mtmp->egotype_faker && !mtmp->mpeaceful && !rn2(20))
3206 pline("%s", fauxmessage());
3207 u.cnd_plineamount++;
3208 if (!rn2(3)) {
3209 pline("%s", fauxmessage());
3210 u.cnd_plineamount++;
3214 if (mdat == &mons[PM_BIRD_MACHINE] && !rn2(5)) {
3215 if (canseemon(mtmp)) pline("%s squawks!", Monnam(mtmp));
3216 else You_hear("a squawk nearby!");
3219 if (inrange && (mdat == &mons[PM_HARDFOUGHT_ANTI_AMY_SQUAD]) && !mtmp->mpeaceful && !rn2(5) && !u.antiamysquad ) {
3220 u.antiamysquad = TRUE;
3221 /* this monster cannot actually be reasoned with; the messages are just fluff */
3223 if (!strncmpi(plname, "Amy", 4) || !strncmpi(plalias, "Amy", 4) || !strncmpi(plname, "Bluescreen", 11) || !strncmpi(plalias, "Bluescreen", 11)) {
3224 You("hear an angry voice shouting:");
3225 verbalize("AMY ALERT! Oh my god SHE'S HERE! Quick, it's time to beat up that heretical witch and punish her for the crime of putting all those offensive things into her game!");
3226 } else {
3227 You("hear an angry voice speaking to you:");
3228 verbalize("Hey! We're looking for Amy, we're gonna beat her up. Do you know where she is?");
3230 winid tmpwin;
3231 anything any;
3232 menu_item *selected;
3233 int n;
3235 any.a_void = 0; /* zero out all bits */
3236 tmpwin = create_nhwindow(NHW_MENU);
3237 start_menu(tmpwin);
3238 any.a_int = 1;
3239 add_menu(tmpwin, NO_GLYPH, &any , 'a', 0, ATR_NONE, "Actually, I am Amy.", MENU_UNSELECTED);
3240 any.a_int = 2;
3241 add_menu(tmpwin, NO_GLYPH, &any , 'b', 0, ATR_NONE, "Uhh, I think she's three levels down from here.", MENU_UNSELECTED);
3242 any.a_int = 3;
3243 add_menu(tmpwin, NO_GLYPH, &any , 'c', 0, ATR_NONE, "I have no idea.", MENU_UNSELECTED);
3244 any.a_int = 4;
3245 add_menu(tmpwin, NO_GLYPH, &any , 'd', 0, ATR_NONE, "Why are you looking for her?", MENU_UNSELECTED);
3247 end_menu(tmpwin, "Your answer:");
3248 n = select_menu(tmpwin, PICK_ONE, &selected);
3249 destroy_nhwindow(tmpwin);
3251 if (n > 0) {
3252 switch (selected[0].item.a_int) {
3253 case 1:
3254 verbalize("WHAT? Guys we got her, OVER HERE! Now we'll punish that demon for all the grubby shit in her NetHack variant! She's gonna get one hell of a beating!");
3255 break;
3256 case 2:
3257 verbalize("What? We don't believe you. In fact, we're fairly certain you're protecting her. That won't be tolerated and we'll have to remove you now.");
3258 break;
3259 case 3:
3260 verbalize("Another useless fool... wait, didn't the boss tell us to leave no witnesses? Oh well, we're gonna remove that idiot real quick and then continue searching for that pesky Amy demon!");
3261 break;
3262 case 4:
3263 verbalize("Ain't that obvious? She's responsible for creating a game that has all kinds of seriously offensive stuff in it! And you know what, judging by the stupidity of your question, I have the suspicion that you're either her in disguise or one of her agents, so I'll just beat you up now, punk!");
3264 break;
3266 } else verbalize("What, you think you can pretend you haven't heard me? Oh well, I'm just gonna beat you up too. And then we're really gonna find Amy and show her what we think of her sorry excuse for a 'video game'!");
3272 if ((mdat == &mons[PM_HARDFOUGHT_SLEXTINCTIONIST]) && !mtmp->mpeaceful && !rn2(5) ) {
3274 if (inrange) {
3275 static const char *slextinctclose_msgs[] = {
3276 "rm -rf slex",
3277 "SLEX is dead.",
3278 "I completely wiped your game from the server, including your savegame files.",
3279 "Your game was deleted, reason is that I'm a prude who can't handle the mention of sexual acts in video games.",
3280 "I've managed to extinct the entire game, didn't even have to kill all the monsters (many of which are offensive) 120 times.",
3281 "I'm the slextinctionist because I managed to remove SLEX permanently! Praise me!",
3282 "I acted very quickly when I got wind of the icky stuff you put into your game. Who cares that your shit managed to fly under my radar for years? At least it's gone now!",
3283 "I already deleted your game, now I shall delete you as well.",
3284 "Your game was removed permanently and no matter what you do, it won't come back.",
3285 "Why are you still here? There's nothing left for you, and I already told you that I removed your game permanently.",
3287 verbalize("%s", slextinctclose_msgs[rn2(SIZE(slextinctclose_msgs))]);
3289 } else {
3290 static const char *slextinctfar_msgs[] = {
3291 "I've always wanted to get rid of SLEX, now I finally found an excuse for doing so.",
3292 "Amy is insane if she thinks her 'my way or the highway' method is gonna fly here.",
3293 "guess I'll have to screen all variants on my server for offensive content from now on...",
3294 "People are gonna celebrate me as their lord and savior for making sure no grubby variants are available on my server.",
3295 "Everyone will agree that I'm very good at taking care of the server. Now that SLEX is gone, we've stopped merely surviving, from now on we shall THRIVE!",
3296 "Gotta delete all trace of SLEX.",
3297 "Backups? Bah! I don't keep backups of pornographic games! Everything must go!",
3298 "If anyone misses their savegames, they're out of luck. Why would I care about them?",
3299 "No one should trust that Amy bitch, she dared to put that stuff into her game and thought it would be tolerated.",
3300 "Amy can hang around in her little hell-hole all she wants, but if she comes here and tries to stir up some shit, I'll definitely take action.",
3302 verbalize("%s", slextinctfar_msgs[rn2(SIZE(slextinctfar_msgs))]);
3308 if (inrange && (mdat == &mons[PM_NETHACKWIKI_DICTATOR]) && !mtmp->mpeaceful && !rn2(5) ) {
3309 static const char *nhdictator_msgs[] = {
3310 "ban amy",
3311 "ban amy forever",
3312 "amy begone",
3313 "amy go away",
3314 "amy has no rights",
3315 "amy is not welcome",
3316 "slex is not welcome",
3317 "gotta protect my faithful slex-hating sheep",
3318 "woe to anyone who criticizes the anti-slex workers",
3319 "if amy misbehaves i will take appropriate action",
3321 verbalize("%s", nhdictator_msgs[rn2(SIZE(nhdictator_msgs))]);
3325 if (inrange && (mdat == &mons[PM_TRANS_INCLUSIONARY_RADICAL_MISOGYNIST]) && !rn2(10) ) {
3326 verbalize("trans women are also women and therefore belong in the kitchen"); /* literal quote by kerio */
3329 if (inrange && (mdat == &mons[PM_NETHACKWIKI_ANTI_SLEX_WORKER] || mdat == &mons[PM_NETHACKWIKI_ANTI_SLEX_WORKER__] || mdat == &mons[PM_NETHACKWIKI_ANTI_SLEX_WORKER_WITH_POWER]) && !mtmp->mpeaceful && !rn2(5) ) {
3330 static const char *nhworker_msgs[] = {
3331 "that page had slex info in it... emphasis on had! hahahahaha!",
3332 "hey i fixed ten pages that had slex info today!",
3333 "get the champagne, i deleted the main slex page from the wiki!",
3334 "long live the vendetta! long live the anti-slex workers!",
3335 "amy has no right to be present on the wiki!",
3336 "slex is just bad and no one should bother with it!",
3337 "man i wish we could just rm -rf all slex info from the wiki in one fell swoop",
3338 "i used to be a slex player but then i decided to be a total wendehals just to fuck amy over muahahahaha",
3339 "we have to protect people from having to see any slex-specific info!",
3340 "everything about slex is bad and offensive and therefore we have to purge everything!!!",
3341 "in my safe space, everything that i find offensive is banned and people who even mention the existence of slex are hit by the hammer of thor!",
3342 "the wiki is only the beginning, one day we will remove slex and amy from all other places where theyre present on the web!",
3343 "the day will come when slex finally stops existing for good, and then we can all happily bore our asses off with nethack variants that are no fun to play, because at least they dont have offensive content!",
3344 "i think we should support that guys slex-clean variant which removes all of amys garbage! let that variant displace the original slex off the internet forever!!!",
3346 verbalize("%s", nhworker_msgs[rn2(SIZE(nhworker_msgs))]);
3350 if ((mdat == &mons[PM_ENEMY_FROM_LEVEL___]) && !mtmp->mpeaceful && !rn2(5) ) {
3351 static const char *levelfiftyfive_msgs[] = {
3352 "THIS IS YOUR END",
3353 "DEATH TO THE ADVENTURER",
3354 "YOU ARE ALREADY DEAD",
3355 "YOU WILL DIE NOW",
3356 "I WILL KILL YOU",
3357 "YOU HAVE NO CHANCE",
3358 "FLEE MY WRATH",
3359 "RUN FOR YOUR LIFE",
3360 "YOU WILL DISAPPEAR ONE WAY OR ANOTHER",
3361 "YOUR DAYS ARE NUMBERED",
3362 "YOUR GOOSE HAS BEEN COOKED",
3363 "YOUR GAME ENDS HERE",
3364 "GAME OVER FOR YOU",
3365 "BETTER HOPE I DONT CATCH YOU",
3366 "YOU CANT HIDE FROM ME",
3367 "I WILL FIND AND INSTAKILL YOU",
3368 "YOURE NO MATCH FOR ME",
3369 "CURIOSITY KILLED THE CAT",
3370 "I AM THE LAST THING YOULL SEE",
3371 "MY NAME WILL GRACE YOUR TOMBSTONE",
3373 verbalize("%s", levelfiftyfive_msgs[rn2(SIZE(levelfiftyfive_msgs))]);
3377 if (inrange && (mdat == &mons[PM_HARDFOUGHT_SLEXTERMINATOR]) && !mtmp->mpeaceful && !rn2(5) ) {
3378 static const char *slexterminator_msgs[] = {
3379 "kill",
3380 "terminate",
3381 "exterminate",
3382 "destroy",
3383 "delete",
3384 "vaporize",
3385 "slex must die",
3386 "annihilate",
3387 "crush",
3388 "devastate",
3389 "demolish",
3390 "wreck",
3391 "squash her hopes",
3392 "destruct",
3393 "lay waste",
3394 "undo her work",
3395 "raze everything",
3396 "nuke her",
3397 "death to amy",
3398 "disintegrate",
3399 "erase her",
3400 "rub her out",
3401 "remove all trace of slex",
3403 verbalize("%s", slexterminator_msgs[rn2(SIZE(slexterminator_msgs))]);
3407 if (inrange && (mdat == &mons[PM_HARDFOUGHT_VENDETTA_LEADER]) && !mtmp->mpeaceful && !rn2(5) ) {
3408 static const char *vendettaleader_msgs[] = {
3409 "everyone agrees that slex has to be purged",
3410 "everyone who doesnt agree with me is put on the enemies list",
3411 "why would we want anyone to stumble upon slex on the web, that has to be prevented",
3412 "amy had her chance but didnt use it",
3413 "it was amy who burned all bridges and stopped any contact with the rest of the community",
3414 "amy can do whatever she wants but we know that were on the winners faction and she will lose",
3415 "amy has no chance",
3416 "if amy had wised up and fixed her game, wed have tolerated its continued existence",
3417 "amy was obligated to remove all the bad stuff from her game, but she didnt and therefore she is public enemy number one now",
3418 "slex does not exist, we shall remove all trace of it from the web forever",
3419 "we need to put filtering software into place so that re-posting of the bad slex content isnt possible",
3420 "we fixed pinobot, we eradicated slex from junethack and now well purge the wiki of that evil abomination!",
3421 "censorship is just the best thing ever!!!!!!!111einself i decided that slex is not allowed to exist and i organized a huge mob with torches and pitchforks who will all help me to rub that evil amy witchs creation off the face of this earth!",
3423 verbalize("%s", vendettaleader_msgs[rn2(SIZE(vendettaleader_msgs))]);
3427 if (inrange && (mdat == &mons[PM_JUNETHACK_PUPPET]) && !mtmp->mpeaceful && !rn2(5) ) {
3428 static const char *jupuppet_msgs[] = {
3429 "i had no other choice",
3430 "i was forced to take off the variants",
3431 "yes *slex had to be removed",
3432 "slex is no longer in junethack",
3433 "the admin threatened me to do bad things if i dont remove your game",
3434 "the trophies are well designed",
3435 "start scumming is allowed",
3436 "the only thing thats forbidden is hacking into the server",
3437 "if the game isnt on a server it cannot be in the tournament",
3438 "dnhslex is offensive because nowadays shoes are considered offensive",
3439 "i do everything that the big server admin says",
3440 "amy why the hell are you mad at me",
3441 "amy i want to think about you sitting naked in front of your pc",
3442 "why does nethack have the tendency to attract dysfunctional people and programmers",
3444 verbalize("%s", jupuppet_msgs[rn2(SIZE(jupuppet_msgs))]);
3448 if (inrange && (mdat == &mons[PM_HARDFOUGHT_DICTATOR]) && !mtmp->mpeaceful && !rn2(5) ) {
3449 static const char *hdictator_msgs[] = {
3450 "slex is offensive",
3451 "slex had to be removed",
3452 "dnhslex is also offensive",
3453 "every variant designed by amy contains offensive shit",
3454 "nethack fourk is very well designed",
3455 "fourkmids are the best system eva",
3456 "man im so proud to run evilhack",
3457 "sporkhack is great and has no bugs at all",
3458 "grunthack is too easy",
3459 "fiqhack has very smooth gameplay",
3460 "dnethack is easy to understand for newbies",
3461 "unnethack is the best variant",
3462 "slashem is well balanced",
3463 "slashthem is just the best thing since sliced bread",
3464 "i was skeptical about gnollhack but now im convinced that its great",
3465 "splicehack just fucking rocks",
3466 "splicehack-r is even better than the original",
3467 "even notdnethack is good enough to be hosted on my server",
3468 "nethack4 is better than most variants",
3469 "dynahack doesnt ever crash",
3470 "nethack 3.7 is the true vanilla",
3471 "nethack 3.4.3 suxxorz",
3472 "tnnt has soooooo many great additions",
3473 "but anyway amy sucks and so does her game",
3474 "amy includes the r-word in her game and that cannot be tolerated",
3475 "and the worst offender has to be the kurwa role in slex that shit is just incredibly gross",
3476 "why would i care that the kurwa has been there for years before i decided to no longer tolerate it",
3477 "why would i care that amy lost progressed savegames to the wipe",
3478 "amy can whine as much as she wants i no longer consider her a being with basic human rights",
3479 "and amy should just delete her repo as well as her account and never come back",
3481 verbalize("%s", hdictator_msgs[rn2(SIZE(hdictator_msgs))]);
3485 if (inrange && (mdat == &mons[PM_HARDFOUGHT_FELLOW_RUNNER]) && !mtmp->mpeaceful && !rn2(5) ) {
3486 static const char *fellowrunner_msgs[] = {
3487 "i dont play slex anyway",
3488 "always felt slex was too over the top",
3489 "ah that variant was unbalanced anyway",
3490 "i dont miss slex",
3491 "why would i care about that irrelevant variant",
3492 "slex is silly",
3493 "yeah amy was a weirdo",
3494 "didnt like that alienating feature in slex",
3495 "my favorite variant is terrahack anyway",
3496 "maybe amy should make a variant that is actually good",
3497 "she could have listened before it was too late",
3498 "ah its her own fault if you ask me",
3499 "its good that this irritating person is gone now",
3500 "she always felt out of place as if she didnt really belong here",
3501 "pornography in games isnt tolerated and thats how it ought to be",
3503 verbalize("%s", fellowrunner_msgs[rn2(SIZE(fellowrunner_msgs))]);
3507 if (inrange && (mdat == &mons[PM_HARDFOUGHT_EXILE_KEEPER]) && !mtmp->mpeaceful && !rn2(5) ) {
3508 static const char *exilekeeper_msgs[] = {
3509 "This area is off-limits to people like you who aren't members of the hdf community.",
3510 "You were elevated to full pariah status!",
3511 "Yes, we exiled you from our community, but we'll tell everyone that you exiled yourself so people will blame you, not us. Muahahahaha.",
3512 "You got the order to stay away from our house! Disappear now, or we'll make you!",
3513 "You there! You have no business in this area!",
3514 "Hey! You were exiled from this community because of things you put into your NetHack variant! What are you doing here?",
3515 "We deleted your game from the server, along with your savegame files, the reason for that was something really petty that no normal human would have considered a ban reason but we did it anyway because we don't like you.",
3516 "What is that pariah doing in here?",
3517 "Hmm. The boss said that the pariah probably wouldn't be coming back, guess he was wrong... oh well, time for us to finish the job and send that foolish intruder away permanently.",
3518 "You got lucky that it was us who found you, because we're just gonna ban you. Be glad you didn't run into the mob with the torches and pitchforks instead, because they want your blood.",
3519 "We're sorry, but you're no longer wanted around these parts. So we have to ask you to kindly leave now.",
3521 verbalize("%s", exilekeeper_msgs[rn2(SIZE(exilekeeper_msgs))]);
3525 if (inrange && (mdat == &mons[PM_EVERCOMPLAINING_UBERSJW]) && !mtmp->mpeaceful && !rn2(5) ) {
3526 static const char *ubersjw_msgs[] = {
3527 "omg that monster has 'girl' in its name that is soooooo offensive",
3528 "oh my god amy keeps doubling down on the offensiveness",
3529 "slex is sexist",
3530 "the stupid obsession with body functions is retarded",
3531 "holy shit the transvestite role breaks new ground in offensiveness",
3532 "the game is full of transmisogyny",
3533 "discrimination everywhere! dont play slex!",
3534 "this garbage makes me feel uncomfortable",
3535 "amy uses the evil r-word in her game",
3536 "those new playable roles are childish and stupid",
3537 "why all the farting, that doesnt belong in the game",
3538 "omg this game is like fatal the roguelike",
3539 "we should put slex on the index",
3540 "why am i a monster in slex, that is so unfair",
3541 "the insults in the random scroll labels need to go",
3542 "eimi wa bakadesu", /* "Amy is stupid" translated to japanese */
3543 "using 'gay' as an insult is way below the belt",
3544 "the creator keeps digging a deeper hole for herself by calling people 'retards'",
3546 verbalize("%s", ubersjw_msgs[rn2(SIZE(ubersjw_msgs))]);
3550 if(inrange && mtmp->data->msound == MS_BOSS && !mtmp->mpeaceful && !rn2(10))
3551 pline("%s %s", Monnam(mtmp), bosstaunt());
3553 if(inrange && (mtmp->data->msound == MS_STENCH || mtmp->data->msound == MS_WHORE || mtmp->data->msound == MS_SUPERMAN || mtmp->data->msound == MS_HCALIEN || mtmp->data->msound == MS_CONVERT || mtmp->data->msound == MS_FART_QUIET || mtmp->data->msound == MS_FART_NORMAL || mtmp->data->msound == MS_FART_LOUD) && (mtmp->data->geno & G_UNIQ) && !mtmp->mpeaceful && !rn2(10))
3554 pline("%s %s", Monnam(mtmp), bosstaunt());
3556 if(inrange && mtmp->data->msound == MS_GIBBERISH && !mtmp->mpeaceful && !rn2(5)) {
3557 pline("%s", generate_garbage_string());
3560 if (inrange && (uarmf && uarmf->oartifact == ART_THICK_PLATFORM_CRAZE) && !mtmp->mpeaceful && mtmp->female && humanoid(mtmp->data) && !rn2(25)) {
3561 static const char *platform_msgs[] = {
3562 "hahaha",
3563 "what a fag",
3564 "lol those shoes",
3565 "is he kidding us",
3566 "is that a tranny?",
3567 "for real?",
3568 "he must be gay",
3569 "did he escape from the asylum?",
3571 static const char *platform_msgs2[] = {
3572 "lol that girl with those lame-ass shoes",
3573 "those are sooooo out of vogue",
3574 "who the hell wears platform shoes???",
3575 "is she compensating for something?",
3576 "what a stupid girl",
3577 "haha is the cunt crying now?",
3578 "she looks fat in those shoes",
3579 "platform shoes were in use 50 years ago, is she some old granny?",
3581 if (flags.female) verbalize("%s", platform_msgs2[rn2(SIZE(platform_msgs2))]);
3582 else verbalize("%s", platform_msgs[rn2(SIZE(platform_msgs))]);
3584 make_dimmed(HDimmed + rnd(10) + rnd(monster_difficulty() + 1), TRUE);
3585 if (Role_if(PM_CELLAR_CHILD)) losehp(monster_difficulty(),"monsters making fun of the shoes",KILLED_BY);
3588 if (inrange && uarmu && uarmu->oartifact == ART_PLEINLY && !mtmp->mpeaceful && humanoid(mtmp->data) && !rn2(100)) {
3589 static const char *pleinlymsgs[] = {
3590 "lol what a stupid shirt",
3591 "are you kidding with that lame-ass outfit?",
3592 "who would wear that???",
3593 "did you really waste all your money on such a silly shirt?",
3594 "why don't you wear some proper clothes instead",
3597 verbalize("%s", pleinlymsgs[rn2(SIZE(pleinlymsgs))]);
3599 make_dimmed(HDimmed + rnd(10) + rnd(monster_difficulty() + 1), TRUE);
3603 if (inrange && PlayerInColumnarHeels && !FemtrapActiveNaomi && !mtmp->mpeaceful && (P_MAX_SKILL(P_HIGH_HEELS) == P_ISRESTRICTED) && humanoid(mtmp->data) && !rn2(50) && flags.female && mtmp->female) {
3604 verbalize("haha look at that bitch with those silly heels");
3605 if (!rn2(3)) verbalize("she can't even walk in them, lol");
3606 adjattrib(A_CHA, -1, FALSE, TRUE);
3609 if (inrange && PlayerInColumnarHeels && !FemtrapActiveNaomi && !mtmp->mpeaceful && (P_MAX_SKILL(P_HIGH_HEELS) == P_ISRESTRICTED) && humanoid(mtmp->data) && !rn2(100) && !flags.female && !mtmp->female) {
3610 verbalize("lol look at that fag over there in those ridiculous heels");
3611 if (!rn2(5)) verbalize("if he could at least walk in them, but nope...");
3612 adjattrib(A_CHA, -1, FALSE, TRUE);
3615 if(inrange && mtmp->data->msound == MS_CUSS && !mtmp->mpeaceful && !rn2(5))
3616 cuss(mtmp);
3618 if(inrange && mtmp->data->msound == MS_PUPIL && !mtmp->mpeaceful && !rn2(5)) {
3619 pupiltaunt();
3622 if(inrange && mtmp->data->msound == MS_WHORE && !mtmp->mpeaceful && !rn2(5))
3626 prostitutetaunt();
3627 armpro = magic_negation(&youmonst);
3628 armprolimit = 75;
3629 if (!(PlayerCannotUseSkills)) {
3631 switch (P_SKILL(P_SPIRITUALITY)) {
3632 default: armprolimit = 75; break;
3633 case P_BASIC: armprolimit = 78; break;
3634 case P_SKILLED: armprolimit = 81; break;
3635 case P_EXPERT: armprolimit = 84; break;
3636 case P_MASTER: armprolimit = 87; break;
3637 case P_GRAND_MASTER: armprolimit = 90; break;
3638 case P_SUPREME_MASTER: armprolimit = 93; break;
3642 if ((rn2(3) >= armpro) || ((rnd(100) > armprolimit) && ((armpro < 4) || (rnd(armpro) < 4) ) ) ) {
3643 make_dimmed(HDimmed + rnd(10) + rnd(monster_difficulty() + 1), TRUE);
3646 if (uarmf && uarmf->oartifact == ART_AERES_RUNNING_SHOES) {
3647 make_feared(HFeared + rnz(1000),FALSE);
3648 set_itimeout(&HeavyFeared, HFeared);
3649 pline("Oh no, the mean prostitute wants to kick you! Help!");
3654 if(inrange && mtmp->data->msound == MS_SUPERMAN && !mtmp->mpeaceful && !rn2(mtmp->mnum == PM_BARTOLI_RETARD ? 25 : 5))
3657 supermantaunt();
3658 badeffect();
3659 increasesanity(rnz(50 + (mtmp->m_lev * 5) ));
3660 u.cnd_supermancount++;
3661 stop_occupation();
3664 if(inrange && mtmp->data->msound == MS_PRINCIPAL && !mtmp->mpeaceful && !rn2(5)) {
3666 principaltaunt();
3670 if(inrange && mtmp->data->msound == MS_TEACHER && !mtmp->mpeaceful && !rn2(5)) {
3672 teachertaunt();
3675 return(tmp == 2);
3678 boolean
3679 itsstuck(mtmp)
3680 register struct monst *mtmp;
3682 if (sticks(youmonst.data) && mtmp==u.ustuck && !u.uswallow) {
3683 pline("%s cannot escape from you!", Monnam(mtmp));
3684 return(TRUE);
3686 return(FALSE);
3689 /* Return values:
3690 * 0: did not move, but can still attack and do other stuff.
3691 * 1: moved, possibly can attack.
3692 * 2: monster died.
3693 * 3: did not move, and can't do anything else either.
3696 m_move(mtmp, after)
3697 register struct monst *mtmp;
3698 register int after;
3700 register int appr;
3701 xchar gx,gy,nix,niy,chcnt;
3702 int chi; /* could be schar except for stupid Sun-2 compiler */
3703 boolean likegold=0, likegems=0, likeobjs=0, likemagic=0, conceals=0;
3704 boolean likerock=0, can_tunnel=0;
3705 boolean can_open=0, can_unlock=0, doorbuster=0;
3706 boolean uses_items=0, setlikes=0;
3707 boolean avoid=FALSE;
3708 boolean astralspecial = FALSE;
3709 struct permonst *ptr;
3710 struct monst *mtoo;
3711 schar mmoved = 0; /* not strictly nec.: chi >= 0 will do */
3712 long info[9];
3713 long flag;
3714 int omx = mtmp->mx, omy = mtmp->my;
3715 struct obj *mw_tmp;
3717 /* if a frenzied monster somehow becomes peaceful or tame, it immediately becomes hostile again (failsafe) --Amy */
3718 if (mtmp->mfrenzied && mtmp->mpeaceful) mtmp->mpeaceful = 0;
3719 if (mtmp->mfrenzied && mtmp->mtame) mtmp->mtame = 0;
3721 /* but if a hostile one is tame, it becomes peaceful (somehow this happens occasionally, not sure why) --Amy */
3722 if (mtmp->mtame && !mtmp->mpeaceful && !mtmp->mfrenzied) mtmp->mpeaceful = TRUE; /* and also remains tame */
3724 if (mtmp->data->mlet == S_TURRET || (mtmp->data == &mons[PM_SECRETIVE_INFORMANT] && !mtmp->codeguessed) || stationary(mtmp->data) || ((is_hider(mtmp->data) || mtmp->egotype_hide || mtmp->egotype_mimic) && (mtmp->mundetected || mtmp->m_ap_type == M_AP_FURNITURE || mtmp->m_ap_type == M_AP_OBJECT) ) ) {
3726 if (mtmp->meating) { /* special case here by Amy, otherwise they'd never finish eating! */
3727 mtmp->meating--;
3728 return 3; /* still eating */
3731 if(mtmp->mtame) {
3732 mmoved = dog_move(mtmp, after);
3733 goto postmov;
3736 return(0); /* stationary turrets --Amy */
3739 if (uwep && uwep->oartifact == ART_FLOWERBANE && !rn2(2) && mtmp->data->mlet == S_BAD_FOOD) return 0;
3741 /* mcalcmove() in mon.c allows sessile monsters to get turns. We still don't want them to move around though. --Amy */
3742 if (!mtmp->data->mmove && (!mtmp->egotype_speedster) && (!mtmp->egotype_racer) ) {
3744 if (mtmp->meating) { /* special case here by Amy, otherwise they'd never finish eating! */
3745 mtmp->meating--;
3746 return 3; /* still eating */
3749 return(0);
3752 if(mtmp->mtrapped) {
3753 int i = mintrap(mtmp);
3754 if(i >= 2) { newsym(mtmp->mx,mtmp->my); return(2); }/* it died */
3755 if(i == 1) return(0); /* still in trap, so didn't move */
3758 ptr = mtmp->data; /* mintrap() can change mtmp->data -dlc */
3760 if (mtmp->meating) {
3761 mtmp->meating--;
3762 return 3; /* still eating */
3765 if (hides_under(ptr) && mtmp->mundetected && OBJ_AT(mtmp->mx, mtmp->my) && rn2(10))
3766 return 0; /* do not leave hiding place - Amy edit: but don't keep camping if the player found you!! */
3768 set_apparxy(mtmp);
3769 /* where does mtmp think you are? */
3770 /* Not necessary if m_move called from this file, but necessary in
3771 * other calls of m_move (ex. leprechauns dodging)
3773 #ifdef REINCARNATION
3774 if (!Is_rogue_level(&u.uz))
3775 #endif
3776 can_tunnel = tunnels(ptr);
3777 can_open = !(nohands(ptr) || verysmall(ptr));
3778 can_unlock = ((can_open && m_carrying(mtmp, SKELETON_KEY)) || (can_open && m_carrying(mtmp, SECRET_KEY)) || (can_open && m_carrying(mtmp, CONTROVERSY_CODE)) ||
3779 mtmp->iswiz || is_rider(ptr) || is_deadlysin(ptr));
3780 /* doorbuster = is_giant(ptr);*/
3782 /* WAC add dragon breath */
3783 doorbuster = is_giant(ptr) || (bust_door_breath(mtmp) != -1);
3785 if(mtmp->wormno) goto not_special;
3786 /* my dog gets special treatment */
3787 if(mtmp->mtame) {
3788 mmoved = dog_move(mtmp, after);
3789 goto postmov;
3792 /* likewise for shopkeeper */
3793 if(mtmp->isshk) {
3794 mmoved = shk_move(mtmp);
3795 if(mmoved == -2) return(2);
3796 if(mmoved >= 0) goto postmov;
3797 mmoved = 0; /* follow player outside shop */
3800 /* and for the guard */
3801 if(mtmp->isgd) {
3802 mmoved = gd_move(mtmp);
3803 if(mmoved == -2) return(2);
3804 if(mmoved >= 0) goto postmov;
3805 mmoved = 0;
3808 /* and the acquisitive monsters get special treatment */
3809 if( (is_covetous(ptr) || mtmp->egotype_covetous) && !rn2(10)) {
3810 xchar tx = STRAT_GOALX(mtmp->mstrategy),
3811 ty = STRAT_GOALY(mtmp->mstrategy);
3812 struct monst *intruder = m_at(tx, ty);
3814 * if there's a monster on the object or in possesion of it,
3815 * attack it.
3817 if((dist2(mtmp->mx, mtmp->my, tx, ty) < 2) &&
3818 intruder && (intruder != mtmp)) {
3820 notonhead = (intruder->mx != tx || intruder->my != ty);
3821 if(mattackm(mtmp, intruder) == 2) return(2);
3822 mmoved = 1;
3823 } else mmoved = 0;
3824 goto postmov;
3827 /* and for the priest */
3828 if(mtmp->ispriest) {
3830 /* if the elder priest is hurt below 75%, regardless of HOW, he becomes covetous --Amy */
3831 if (mtmp->data == &mons[PM_DNETHACK_ELDER_PRIEST_TM_] && (mtmp->mhp <= (mtmp->mhpmax * 3 / 4)) ) {
3832 mtmp->isegotype = 1;
3833 mtmp->egotype_covetous = 1;
3835 mmoved = pri_move(mtmp);
3836 if(mmoved == -2) return(2);
3837 if(mmoved >= 0) goto postmov;
3838 mmoved = 0;
3841 #ifdef MAIL
3842 if(ptr == &mons[PM_MAIL_DAEMON]) {
3843 if(flags.soundok && canseemon(mtmp))
3844 verbalize("I'm late!");
3845 mongone(mtmp);
3846 return(2);
3848 #endif
3850 /* teleport if that lies in our nature */
3851 if( (ptr == &mons[PM_TENGU] || ptr == &mons[PM_CORONA_TASK_FORCE] || ptr == &mons[PM_PURPLE_BOUNCING_GIRL] || ptr == &mons[PM_CORONA_LICHEN] || ptr == &mons[PM_STALKING_CORONA_LICHEN] || ptr == &mons[PM_CORONA_SPORE_LICHEN] || ptr == &mons[PM_CORONA_COLONY_LICHEN] || ptr == &mons[PM_SUDDEN_TENGU] || ptr == &mons[PM_FAKE_NEWS_TENGU] || ptr == &mons[PM_LASTING_TENGU] || ptr == &mons[PM_TELEPORTER] || ptr == &mons[PM_BULLETATOR_I] || ptr == &mons[PM_DISCONNECT_DEVIL] || ptr == &mons[PM_COUNTRY_SHARK] || ptr == &mons[PM_POLITICAL_TENGU] || ptr == &mons[PM_EASTERN_TENGU] || ptr == &mons[PM_PHASING_TENGU] || ptr == &mons[PM_FROZEN_JUMP] || ptr == &mons[PM_CHEERFUL_LEPRECHAUN] || ptr == &mons[PM_BLINK] || ptr == &mons[PM_TELE_VIRUS] || ptr == &mons[PM_VORPAL_BUNNY] || ptr == &mons[PM_KING_OF_PORN] || ptr == &mons[PM_SHRIEKSHRIEKSHRIEKER] || ptr == &mons[PM_TAXI] || ptr == &mons[PM_TAXI_XPRESS] || ptr == &mons[PM_JIL_S_SCENTFUL_SOCKS] || ptr == &mons[PM_ZOMBIE_STUNTMAN] || ptr == &mons[PM_OF_FLOW] || ptr == &mons[PM_PEARDUCK] || ptr == &mons[PM_UAE] || ptr == &mons[PM_CHEATY_SILVER_COIN] || ptr == &mons[PM_SPACEWARP_JELLY] || ptr == &mons[PM_ALSAPIA_MURDERER_MASK] || ptr == &mons[PM_NIGHTMARE_SHEEP] || ptr == &mons[PM_HELL_SHEEP] || ptr == &mons[PM_LOVECRAFT_SHEEP] || ptr == &mons[PM_INDIVIDUAL_WILL_O_THE_WISP] || ptr == &mons[PM_TELEHOBBIT] || ptr == &mons[PM_SPOOPY_GHOST] || ptr == &mons[PM_ANNOYING_SLEX_GHOST] || ptr == &mons[PM_SPRING_WOLF] || ptr == &mons[PM_DIMENSIONAL_SHAMBLER] || ptr == &mons[PM_MAGNET_ELEMENTAL] || ptr == &mons[PM_PHASE_KNIGHT] || ptr == &mons[PM_TELEPORTING_DEMON] || ptr == &mons[PM_BEAMING_UFO_PART] || ptr == &mons[PM_BEAMER] || mtmp->egotype_teleportself) && !rn2(25) && !mtmp->mcan &&
3852 !tele_restrict(mtmp)) {
3853 if(mtmp->mhp < 7 || (ptr == &mons[PM_SPOOPY_GHOST]) || mtmp->mpeaceful || rn2(2))
3854 (void) rloc(mtmp, FALSE);
3855 else
3856 mnexto(mtmp);
3857 mmoved = 1;
3858 goto postmov;
3861 if (AefdeActive && (mtmp->data->maligntyp < 0) && !rn2(100) && !tele_restrict(mtmp)) {
3862 (void) rloc(mtmp, FALSE);
3863 mmoved = 1;
3864 goto postmov;
3867 if ((ptr == &mons[PM_ASIMA] || ptr == &mons[PM_UTHGEN_RAPPER] || ptr == &mons[PM_YOUR_MAP_SHOWS_] || ptr == &mons[PM_FLEETFOOT] || ptr == &mons[PM_BEARER_OF_BAD_NEWS]) && !rn2(25) && !mtmp->mcan &&
3868 !tele_restrict(mtmp) ) {
3869 (void) rloc(mtmp, FALSE);
3870 mmoved = 1;
3871 goto postmov;
3874 if (ptr == &mons[PM_MECHTNED] && distu(mtmp->mx, mtmp->my) < 4 && !tele_restrict(mtmp) ) {
3875 /* name means "doesn't want to (fight you)", so he teleports away from you */
3876 (void) rloc(mtmp, FALSE);
3877 mmoved = 1;
3878 goto postmov;
3881 if (mtmp->egotype_blinker && !mtmp->mcan && !rn2(5) ) {
3882 (void) rloc(mtmp, FALSE);
3883 mmoved = 1;
3884 goto postmov;
3887 if (ptr == &mons[PM_ROW_PERCENTD_COL_PERCENTD] && rn2(3)) {
3888 (void) rloc(mtmp, FALSE);
3889 mmoved = 1;
3890 goto postmov;
3893 if (ptr == &mons[PM_CHEATY_SILVER_COIN] && rn2(3)) {
3894 (void) rloc(mtmp, FALSE);
3895 mmoved = 1;
3896 goto postmov;
3899 not_special:
3900 if(u.uswallow && !mtmp->mflee && u.ustuck != mtmp) return(1);
3901 omx = mtmp->mx;
3902 omy = mtmp->my;
3903 gx = mtmp->mux;
3904 gy = mtmp->muy;
3906 if (FemtrapActiveKlara && spawnswithsandals(mtmp->data) && mtmp->mhp >= mtmp->mhpmax) {
3907 int toiletamount = 0;
3908 int altarx = 0, altary = 0;
3909 while (altarx++ < COLNO) {
3910 altary = 0;
3911 while (altary++ < ROWNO) {
3913 if (isok(altarx, altary) && (IS_TOILET(levl[altarx][altary].typ))) {
3914 toiletamount++;
3915 if (((mtmp->terraintrans) % toiletamount) == 0) {
3916 gx = altarx;
3917 gy = altary;
3926 if (isevilvariant && mon_has_amulet(mtmp) && !u.freeplaymode && Is_astralevel(&u.uz) ) {
3928 int altarx = 0, altary = 0;
3929 while (altarx++ < COLNO) {
3930 altary = 0;
3931 while (altary++ < ROWNO) {
3932 if (isok(altarx, altary) && (IS_ALTAR(levl[altarx][altary].typ))) {
3934 aligntyp astalign;
3936 astalign = levl[altarx][altary].altarmask & AM_MASK;
3937 if (astalign == AM_LAWFUL) astalign = 1;
3938 else if (astalign == AM_NEUTRAL) astalign = 0;
3939 else if (astalign == AM_CHAOTIC) astalign = -1;
3941 if (astalign == sgn(mtmp->data->maligntyp)) {
3943 gx = altarx;
3944 gy = altary;
3945 astralspecial = TRUE;
3947 if (mtmp->mx == altarx && mtmp->my == altary) { /* game over */
3948 u.youaredead = 1;
3949 u.youarereallydead = 1;
3950 pline("Oh no! Someone else managed to offer the Amulet of Yendor and obtained immortality. You have failed your mission and the game ends here.");
3951 killer_format = NO_KILLER_PREFIX;
3952 killer = "allowed someone else to offer the Amulet of Yendor to the gods";
3953 done(DIED);
3954 done(DIED);
3955 done(QUIT); /* sorry but your game *really* ends here --Amy */
3959 goto altarfound;
3967 altarfound:
3969 appr = mtmp->mflee ? -1 : 1;
3971 if (monsndx(ptr) == PM_DEMON_SPOTTER && !mtmp->cham && !rn2(23) && !mtmp->mpeaceful && !mtmp->mtame) {
3972 msummon(mtmp, FALSE);
3973 pline("%s opens a gate!",Monnam(mtmp) );
3974 if (PlayerHearsSoundEffects) pline(issoviet ? "Sovetskaya nadeyetsya, chto demony zapolnyayut ves' uroven' i ubit' vas." : "Pitschaeff!");
3977 if (monsndx(ptr) == PM_FUNK_CAR && distu(mtmp->mx,mtmp->my) < 65 && !mtmp->cham && !rn2(184) && !mtmp->mpeaceful && !mtmp->mtame) {
3978 msummon(mtmp, FALSE);
3979 pline("%s opens a gate!",Monnam(mtmp) );
3980 if (PlayerHearsSoundEffects) pline(issoviet ? "Sovetskaya nadeyetsya, chto demony zapolnyayut ves' uroven' i ubit' vas." : "Pitschaeff!");
3984 if (mtmp->data->msound == MS_SNORE && !rn2(500)) mtmp->msleeping = 1;
3985 if (mtmp->data->msound == MS_SNORE && (mtmp->msleeping || mtmp->masleep) && !rn2(5)) {
3986 wake_nearto(mtmp->mx, mtmp->my, 25);
3987 if (canseemon(mtmp)) pline("%s snores loudly!", Monnam(mtmp));
3988 else You_hear("loud snoring!");
3990 if (mtmp->data->msound == MS_TRUMPET && !rn2(200)) {
3991 wake_nearto(mtmp->mx, mtmp->my, rn1(50, 50));
3992 if (canseemon(mtmp)) pline("%s trumpets loudly!", Monnam(mtmp));
3993 else You_hear("a trumpet sound!");
3996 if (mtmp->singability && !rn2(10000)) mtmp->singability = FALSE;
3998 if (monsndx(ptr) == PM_SLEEPING_GIANT && !rn2(10)) mtmp->msleeping = 1;
3999 if (monsndx(ptr) == PM_MUEJDE && !rn2(10)) mtmp->msleeping = 1;
4000 if (monsndx(ptr) == PM_SLEEP_BUNDLE_TIREDEL && !rn2(10)) mtmp->msleeping = 1;
4001 if (monsndx(ptr) == PM_APATHETIC_ASSHOLE && !rn2(10)) mtmp->msleeping = 1;
4002 if (monsndx(ptr) == PM_SARSLEEPER && !rn2(10)) mtmp->msleeping = 1;
4003 if (monsndx(ptr) == PM_SLEEPY_GIRL && !rn2(10)) mtmp->msleeping = 1;
4004 if (monsndx(ptr) == PM_SLEEPY_WOMAN && !rn2(10)) mtmp->msleeping = 1;
4005 if (monsndx(ptr) == PM_SLEEPY_LADY && !rn2(10)) mtmp->msleeping = 1;
4006 if (monsndx(ptr) == PM_SLEEPING_ASIAN_GIRL && !rn2(10)) mtmp->msleeping = 1;
4007 if (monsndx(ptr) == PM_DIDDLY_DINGUS_DUDE && !rn2(20)) mtmp->msleeping = 1;
4008 if (monsndx(ptr) == PM_HUMDIGGLE_DISINTEGRATOR && !rn2(20)) mtmp->msleeping = 1;
4009 if (monsndx(ptr) == PM_NOTHING_CHECKER_WHO_IS_CONFUSED) mtmp->mconf = 1;
4010 if (monsndx(ptr) == PM_WATER_MATERIAL_BLONDE) mtmp->mconf = 1;
4011 if (monsndx(ptr) == PM_DAFT_SHEEP) mtmp->mconf = 1;
4012 if (monsndx(ptr) == PM_METH_HEAD) mtmp->mconf = 1;
4013 if (monsndx(ptr) == PM_CONTRULLA) mtmp->mconf = 1;
4014 if (monsndx(ptr) == PM_GAGAGAGOGL) mtmp->mconf = 1;
4015 if (monsndx(ptr) == PM_IRMGARD) mtmp->mconf = 1;
4016 if (monsndx(ptr) == PM_DRUG_ADDICTED_BANG_PIN) mtmp->mconf = 1;
4017 if (monsndx(ptr) == PM_HIGH_PROSTITUTE_OF_MOLOCH) mtmp->mconf = 1;
4018 if (monsndx(ptr) == PM_LIQUOR_CORPSE) mtmp->mconf = 1;
4019 if (monsndx(ptr) == PM_SWIMMING_TRUNKS) mtmp->mconf = 1;
4020 if (monsndx(ptr) == PM_IRITAL) mtmp->mconf = 1;
4021 if (monsndx(ptr) == PM_FULL_WEAKMATE_O) mtmp->mconf = 1;
4022 if (monsndx(ptr) == PM_DEBILITATED_DANNY) mtmp->mconf = 1;
4023 if (monsndx(ptr) == PM_DIM_GIRL) mtmp->mconf = 1;
4024 if (monsndx(ptr) == PM_GRAWLIX) mtmp->mconf = 1;
4025 if (monsndx(ptr) == PM_BLONDE_FEMMY) mtmp->mconf = 1;
4026 if (monsndx(ptr) == PM_LASSY_GIRL) mtmp->mconf = 1;
4027 if (monsndx(ptr) == PM_LOST_ITALIAN_PLUMBER) mtmp->mconf = 1;
4028 if (monsndx(ptr) == PM_BEER_BELLY) mtmp->mconf = 1;
4029 if (monsndx(ptr) == PM_SLOOB) mtmp->mconf = 1;
4030 if (monsndx(ptr) == PM_CRAMP_CART_TO_THE_WALL_DRIVER) mtmp->mconf = 1;
4031 if (monsndx(ptr) == PM_SOBER_THE_DRUNK) mtmp->mconf = 1;
4032 if (monsndx(ptr) == PM_LOONIE_BOSS) mtmp->mconf = 1;
4033 if (monsndx(ptr) == PM_BARTOLI_RETARD) mtmp->mconf = 1;
4034 if (monsndx(ptr) == PM_ERR_BOSS) mtmp->mconf = 1;
4035 if (monsndx(ptr) == PM_ERR) mtmp->mconf = 1;
4036 if (monsndx(ptr) == PM_TRANS_BIRTH) mtmp->mconf = 1;
4037 if (monsndx(ptr) == PM_CONFUSTICA_EQUA_STABILIA) mtmp->mconf = 1;
4038 if (monsndx(ptr) == PM_STUPIDITY_AUTIST) mtmp->mconf = 1;
4039 if (monsndx(ptr) == PM_SEIZURE_FOOBACUS) mtmp->mconf = 1;
4040 if (monsndx(ptr) == PM_HIGHEST_PRIESTEST) mtmp->mconf = 1;
4041 if (monsndx(ptr) == PM_HAMMER_DRIVE) mtmp->mconf = 1;
4042 if (monsndx(ptr) == PM_PANCAKE_SPIRIT) mtmp->mconf = 1;
4043 if (monsndx(ptr) == PM_WESTERHARE) mtmp->mflee = 1;
4044 if (monsndx(ptr) == PM_DIDDLY_DINGUS_DUDE && !rn2(10)) mtmp->mconf = 1;
4045 if (monsndx(ptr) == PM_PARROT_RIDING_A_GIANT_PENIS && !rn2(10)) mtmp->mconf = 1;
4046 if (mtmp->mconf || (uarmh && !rn2(10) && itemhasappearance(uarmh, APP_INKCOAT_HELMET) ) || (uarmh && uarmh->oartifact == ART_RADAR_NOT_WORKING) || (u.uswallow && mtmp == u.ustuck))
4047 appr = 0;
4048 else {
4049 #ifdef GOLDOBJ
4050 struct obj *lepgold, *ygold;
4051 #endif
4052 boolean should_see = (couldsee(omx, omy) &&
4053 (levl[gx][gy].lit ||
4054 !levl[omx][omy].lit) &&
4055 (dist2(omx, omy, gx, gy) <= (level.flags.shortsighted ? 36 : (ublindf && ublindf->oartifact == ART_IT_BE_NITE) ? 36 : 100) ));
4057 if (astralspecial) should_see = TRUE;
4059 if (!mtmp->mcansee ||
4060 /* monsters no longer automatically know where you are. That was just incredibly annoying. --Amy */
4061 ( (!Aggravate_monster || !rn2(5)) && !should_see && distu(mtmp->mx,mtmp->my) > 10 && ((Stealth && (StrongStealth || !rn2(3))) ? (can_track(ptr) ? !rn2(4) : rn2(2) ) : (can_track(ptr) ? !rn2(10) : !rn2(4) ) ) ) ||
4062 ( (!Aggravate_monster || !rn2(20)) && is_wanderer(mtmp->data) ? ((Stealth && (StrongStealth || !rn2(3))) ? !rn2(3) : !rn2(5) ) : ((Stealth && (StrongStealth || !rn2(3))) ? !rn2(5) : !rn2(25) ) ) ||
4063 (should_see && Invis && (StrongInvis || !rn2(3)) && haseyes(ptr) &&
4064 ( (!perceives(ptr) || (uarm && uarm->oartifact == ART_YOU_CANNOT_SEE_ME) ) && rn2(3)) ) ||
4065 (youmonst.m_ap_type == M_AP_OBJECT && youmonst.mappearance == STRANGE_OBJECT) || u.uundetected ||
4066 (youmonst.m_ap_type == M_AP_OBJECT && youmonst.mappearance == GOLD_PIECE && !likes_gold(ptr)) ||
4067 (mtmp->mpeaceful && !mtmp->isshk) || /* allow shks to follow */
4068 ((monsndx(ptr) == PM_STALKER || is_bat(ptr) ||
4069 ptr->mlet == S_LIGHT) && !rn2(3)))
4070 appr = 0;
4072 /* monsters that are very far away shouldn't know where you are --Amy
4073 * but if they're injured, they should (most of the time it's because you tried to kill them) */
4075 if (mtmp->mhp >= mtmp->mhpmax) {
4077 int nositerange = 900, siterange = 2500;
4078 if (Aggravate_monster) {
4079 nositerange *= 3;
4080 siterange *= 3;
4082 if (StrongAggravate_monster) {
4083 nositerange *= 3;
4084 siterange *= 3;
4086 if (Stealth) {
4087 nositerange /= 2;
4088 siterange /= 2;
4090 if (StrongStealth) {
4091 nositerange /= 2;
4092 siterange /= 2;
4095 if (clear_path(u.ux, u.uy, mtmp->mx, mtmp->my) && (distu(mtmp->mx,mtmp->my) > siterange)) appr = 0;
4096 if (!clear_path(u.ux, u.uy, mtmp->mx, mtmp->my) && (distu(mtmp->mx,mtmp->my) > nositerange)) appr = 0;
4100 /* if(monsndx(ptr) == PM_LEPRECHAUN && (appr == 1) &&
4101 #ifndef GOLDOBJ
4102 (mtmp->mgold > u.ugold))
4103 #else
4104 ( (lepgold = findgold(mtmp->minvent)) &&
4105 (lepgold->quan > ((ygold = findgold(invent)) ? ygold->quan : 0L)) ))
4106 #endif
4107 appr = -1;*/ /* commented out - they should still be attacking you --Amy */
4109 if (!should_see && can_track(ptr)) {
4110 register coord *cp;
4112 cp = gettrack(omx,omy);
4113 if (cp && !astralspecial) {
4114 gx = cp->x;
4115 gy = cp->y;
4120 if (appr == 1 && !rn2(5) && (uarm && itemhasappearance(uarm, APP_CAMO_ROBE)) ) appr = 0;
4122 if (appr == 1 && uarmf && uarmf->oartifact == ART_SMELL_LIKE_DOG_SHIT && !rn2(10)) appr = 0;
4124 if (appr == 1 && uarmf && uarmf->oartifact == ART_DARK_BALL_OF_LIGHT) appr = 0;
4126 if (appr == 1 && !rn2(5) && (uarmc && itemhasappearance(uarmc, APP_PINK_CLOAK) )) appr = 0;
4128 if (appr == 1 && uarmf && uarmf->oartifact == ART_LAUGH_WHEN_YOU_FALL && (multi < 0) && rn2(10)) appr = 0;
4130 if (monsterrandomwalk(ptr)) appr = 0;
4131 if (monsterflees(ptr)) appr = -1;
4133 if (uarmh && uarmh->oartifact == ART_VERSCENT_ && mtmp->data->msound == MS_STENCH) appr = -1;
4134 if (uarmh && uarmh->oartifact == ART_VERSCENT_ && mtmp->egotype_perfumespreader) appr = -1;
4136 if (appr == 1 && mtmp->data->msound == MS_METALMAFIA && distu(mtmp->mx,mtmp->my) <= 3*3 ) appr = 0;
4138 if (appr == 1 && u.usteed && uarm && uarm->oartifact == ART_FAER_ME && distu(mtmp->mx,mtmp->my) < 3*3 && (mtmp->m_lev < (GushLevel / 2) ) ) appr = 0;
4140 if (ptr == &mons[PM_DECISION_WEAKSKI]) appr = (!rn2(3) ? -1 : rn2(2) ? 0 : 1);
4141 if (ptr == &mons[PM_STOIAKMIDM]) appr = (!rn2(3) ? -1 : rn2(2) ? 0 : 1);
4142 if (ptr == &mons[PM_SPACKMATICIAN]) appr = (!rn2(3) ? -1 : rn2(2) ? 0 : 1);
4143 if (ptr == &mons[PM_HEADER_RA____AUTO]) appr = (!rn2(3) ? -1 : rn2(2) ? 0 : 1);
4144 if (ptr == &mons[PM_IRMGARD]) appr = (!rn2(3) ? -1 : rn2(2) ? 0 : 1);
4146 if (ptr == &mons[PM_WILD_ELEPHANT] && (mtmp->mhp >= mtmp->mhpmax)) appr = 0;
4147 if (ptr == &mons[PM_NORMAL_BOAR] && (mtmp->mhp >= mtmp->mhpmax)) appr = 0;
4148 if (ptr == &mons[PM_JAVELINA] && (mtmp->mhp >= mtmp->mhpmax)) appr = 0;
4149 if (ptr == &mons[PM_JAVELIN_A] && (mtmp->mhp >= mtmp->mhpmax)) appr = 0;
4151 if (u.katitrapocc && !mtmp->mpeaceful) appr = -1; /* they're supposed to let you perform your occupation in peace */
4152 if (u.singtrapocc && !mtmp->mpeaceful) appr = -1;
4154 if ((!mtmp->mpeaceful || !rn2(10))
4155 #ifdef REINCARNATION
4156 && (!Is_rogue_level(&u.uz))
4157 #endif
4159 boolean in_line = lined_up(mtmp) &&
4160 (distmin(mtmp->mx, mtmp->my, mtmp->mux, mtmp->muy) <=
4161 ( (throws_rocks(youmonst.data) || (uarmg && uarmg->oartifact == ART_MOUNTAIN_FISTS)) ? 20 : ACURRSTR/2+1)
4164 if (appr != 1 || !in_line) {
4165 /* Monsters in combat won't pick stuff up, avoiding the
4166 * situation where you toss arrows at it and it has nothing
4167 * better to do than pick the arrows up.
4169 register int pctload = (curr_mon_load(mtmp) * 100) /
4170 max_mon_load(mtmp);
4172 /* look for gold or jewels nearby */
4173 likegold = (likes_gold(ptr) && pctload < 95);
4174 likegems = (likes_gems(ptr) && pctload < 85);
4175 uses_items = (/*!mindless(ptr) && !is_animal(ptr)
4176 && */pctload < 75); /* I just decided that "mindless" isn't the same as "stupid". --Amy */
4177 likeobjs = (likes_objs(ptr) && pctload < 75);
4178 likemagic = (likes_magic(ptr) && pctload < 85);
4179 likerock = (throws_rocks(ptr) && pctload < 50 && !In_sokoban(&u.uz));
4180 conceals = hides_under(ptr);
4181 setlikes = TRUE;
4185 #define SQSRCHRADIUS 5
4187 { register int minr = SQSRCHRADIUS; /* not too far away */
4188 register struct obj *otmp;
4189 register int xx, yy;
4190 int oomx, oomy, lmx, lmy;
4192 /* cut down the search radius if it thinks character is closer. */
4193 if(distmin(mtmp->mux, mtmp->muy, omx, omy) < SQSRCHRADIUS &&
4194 !mtmp->mpeaceful) minr--;
4195 /* guards shouldn't get too distracted */
4196 if(!mtmp->mpeaceful && is_mercenary(ptr)) minr = 1;
4198 if((likegold || likegems || likeobjs || likemagic || likerock || conceals)
4199 && (!*in_rooms(omx, omy, SHOPBASE) || (!rn2(25) && !mtmp->isshk))) {
4200 look_for_obj:
4201 oomx = min(COLNO-1, omx+minr);
4202 oomy = min(ROWNO-1, omy+minr);
4203 lmx = max(1, omx-minr);
4204 lmy = max(0, omy-minr);
4205 for(otmp = fobj; otmp; otmp = otmp->nobj) {
4206 /* monsters may pick rocks up, but won't go out of their way
4207 to grab them; this might hamper sling wielders, but it cuts
4208 down on move overhead by filtering out most common item */
4209 if (otmp->otyp == ROCK) continue;
4210 xx = otmp->ox;
4211 yy = otmp->oy;
4212 /* Nymphs take everything. Most other creatures should not
4213 * pick up corpses except as a special case like in
4214 * searches_for_item(). We need to do this check in
4215 * mpickstuff() as well.
4217 if(xx >= lmx && xx <= oomx && yy >= lmy && yy <= oomy) {
4218 /* don't get stuck circling around an object that's underneath
4219 an immobile or hidden monster; paralysis victims excluded */
4220 if ((mtoo = m_at(xx,yy)) != 0 &&
4221 (mtoo->msleeping || mtoo->mundetected ||
4222 (mtoo->mappearance && !mtoo->iswiz) ||
4223 !mtoo->data->mmove)) continue;
4225 if(((likegold && otmp->oclass == COIN_CLASS) ||
4226 (likeobjs && index(practical, otmp->oclass) &&
4227 (otmp->otyp != CORPSE || ((ptr->mlet == S_NYMPH || ptr == &mons[PM_GOLDEN_KNIGHT] || ptr == &mons[PM_GOLDEN_HOLY_KNIGHT] || ptr == &mons[PM_URCAGUARY])
4228 && !is_rider(&mons[otmp->corpsenm]) && !is_deadlysin(&mons[otmp->corpsenm]) ))) ||
4229 (likemagic && index(magical, otmp->oclass)) ||
4230 (uses_items && searches_for_item(mtmp, otmp)) ||
4231 (likerock && otmp->otyp == BOULDER) ||
4232 (likegems && otmp->oclass == GEM_CLASS &&
4233 objects[otmp->otyp].oc_material != MT_MINERAL) ||
4234 (conceals && !cansee(otmp->ox,otmp->oy)) ||
4235 (ptr == &mons[PM_GELATINOUS_CUBE] &&
4236 !index(indigestion, otmp->oclass) &&
4237 !(otmp->otyp == CORPSE &&
4238 touch_petrifies(&mons[otmp->corpsenm])))
4239 ) && touch_artifact(otmp,mtmp)) {
4240 if(can_carry(mtmp,otmp) &&
4241 otmp->otyp != STATUE &&
4242 otmp->otyp != CHARGER &&
4243 otmp->otyp != SYMBIOTE &&
4244 otmp->otyp != SWITCHER &&
4245 otmp->otyp != BITCHER &&
4246 otmp->otyp != POTATO_BAG &&
4247 otmp->otyp != UGH_MEMORY_TO_CREATE_INVENTORY &&
4248 (throws_rocks(ptr) ||
4249 !sobj_at(BOULDER,xx,yy)) &&
4250 (!is_unicorn(ptr) ||
4251 objects[otmp->otyp].oc_material == MT_GEMSTONE) &&
4252 /* Don't get stuck circling an Elbereth */
4253 !(onscary(xx, yy, mtmp))) {
4254 minr = distmin(omx,omy,xx,yy);
4255 oomx = min(COLNO-1, omx+minr);
4256 oomy = min(ROWNO-1, omy+minr);
4257 lmx = max(1, omx-minr);
4258 lmy = max(0, omy-minr);
4259 if (!astralspecial) {
4260 gx = otmp->ox;
4261 gy = otmp->oy;
4263 /*if (gx == omx && gy == omy) {
4264 mmoved = 3; actually unnecessary
4265 goto postmov;
4271 } else if(likegold) {
4272 /* don't try to pick up anything else, but use the same loop */
4273 uses_items = 0;
4274 likegems = likeobjs = likemagic = likerock = conceals = 0;
4275 goto look_for_obj;
4278 if(minr < SQSRCHRADIUS && appr == -1) {
4279 if(!astralspecial && (distmin(omx,omy,mtmp->mux,mtmp->muy) <= 3)) {
4280 gx = mtmp->mux;
4281 gy = mtmp->muy;
4282 } else
4283 appr = 1;
4287 if (astralspecial) appr = 1;
4289 /* don't tunnel if hostile and close enough to prefer a weapon */
4290 if (can_tunnel && needspick(ptr) &&
4291 ((!mtmp->mpeaceful || Conflict) &&
4292 dist2(mtmp->mx, mtmp->my, mtmp->mux, mtmp->muy) <= 8))
4293 can_tunnel = FALSE;
4295 nix = omx;
4296 niy = omy;
4297 flag = 0L;
4298 if (mtmp->mpeaceful && (!Conflict || (resist(mtmp, RING_CLASS, 0, 0) && (!StrongConflict || resist(mtmp, RING_CLASS, 0, 0)) ) ))
4299 flag |= (ALLOW_SANCT | ALLOW_SSM);
4300 else {
4301 flag |= ALLOW_U;
4303 if (is_minion(ptr) || is_rider(ptr) || is_deadlysin(ptr)) flag |= ALLOW_SANCT;
4304 /* unicorn may not be able to avoid hero on a noteleport level */
4305 if (is_unicorn(ptr) && !level.flags.noteleport && !Race_if(PM_STABILISATOR) && !u.antitelespelltimeout) flag |= NOTONL;
4306 if (passes_walls(ptr) || (mtmp->egotype_wallwalk) ) flag |= (ALLOW_WALL | ALLOW_ROCK);
4307 if (passes_bars(ptr) && !In_sokoban(&u.uz)) flag |= ALLOW_BARS;
4308 if (can_tunnel) flag |= ALLOW_DIG;
4309 if (is_human(ptr) || is_minotaur(ptr) || ptr == &mons[PM_CHANOP]) flag |= ALLOW_SSM;
4310 if ( (is_undead(ptr) || mtmp->egotype_undead) && ptr->mlet != S_GHOST) flag |= NOGARLIC;
4311 if (throws_rocks(ptr) || passes_walls(ptr) || (mtmp->egotype_wallwalk) || amorphous(ptr) || is_whirly(ptr) || ptr->mlet == S_NEMESE || ptr->mlet == S_ARCHFIEND || ptr->msound == MS_NEMESIS || ptr->geno & G_UNIQ ||
4312 verysmall(ptr) || slithy(ptr) || ptr == &mons[PM_BLACK_MARKETEER]) flag |= ALLOW_ROCK;
4313 /* Boulder forts will be a lot less effective at holding dangerous monsters at bay. --Amy */
4314 if (can_open) flag |= OPENDOOR;
4315 if (can_unlock) flag |= UNLOCKDOOR;
4316 if (doorbuster) flag |= BUSTDOOR;
4318 register int i, j, nx, ny, nearer;
4319 int jcnt, cnt;
4320 int ndist, nidist;
4321 register coord *mtrk;
4322 coord poss[9];
4324 cnt = mfndpos(mtmp, poss, info, flag);
4325 chcnt = 0;
4326 jcnt = min(MTSZ, cnt-1);
4327 chi = -1;
4328 nidist = dist2(nix,niy,gx,gy);
4329 /* allow monsters be shortsighted on some levels for balance */
4330 if(!mtmp->mpeaceful && (level.flags.shortsighted || (ublindf && ublindf->oartifact == ART_IT_BE_NITE) || (uarmf && uarmf->oartifact == ART_UPWARD_HEELS) || (uarm && uarm->oartifact == ART_THEY_WON_T_SEE_ME___ && !rn2(4)) || (uarm && uarm->oartifact == ART_DARK_L) || (rn2(10) && RngeLightAbsorption) || (rn2(10) && uarmc && itemhasappearance(uarmc, APP_ABSORBING_CLOAK) ) ) &&
4331 nidist > (couldsee(nix,niy) ? 144 : 36) && appr == 1) appr = 0;
4332 /* special coding for "homing" giant wasps from the hunger games --Amy */
4333 if ((ptr == &mons[PM_TRACKER_JACKER] || ptr == &mons[PM_FIGHTING_ENTITY] || ptr == &mons[PM_PERSON_WHO_IS_REALLY_AFTER_YOU__NO__YOU_RE_NOT_PARANOID_] || autismweaponcheck(ART_EMERALD_SWORD) || ptr == &mons[PM_TRACKBAG] || ptr == &mons[PM_BLACK_SUN_BASS] || ptr == &mons[PM_LINDEN_BASS] || (FemtrapActiveElla && mtmp->female && humanoid(mtmp->data) && (mtmp->mhp < (mtmp->mhpmax * 9 / 10) )) || ptr == &mons[PM_ASSHOLE_WHO_CANNOT_ENJOY_ANYTHING__NOT_EVEN_A_PAIR_OF_CUDDLE_HEELS] || ptr == &mons[PM_KILLER_GIANT_RAT] || ptr == &mons[PM_POLICE_DOG] || ptr == &mons[PM_MANBOO] || ptr == &mons[PM_SOLARFISH] || ptr == &mons[PM_POLICE_HUSKY] || ptr == &mons[PM_BIG_POLICE_DOG] || ptr == &mons[PM_CURSED____LEFTHANDED_FARTING_ELEPHANT] || ptr == &mons[PM_VERONA_MARBLE] || ptr == &mons[PM_CHASE_BIRD] || ptr == &mons[PM_JAYCEE] || ptr == &mons[PM_OOGABOOGAGOBILITGOOK_SEEKER_AREHETYPE_FUCKING_RETARD_ASS_SHIT_FLINGING_MONKEY_MONSTER] || ptr == &mons[PM_FULL_REFUGE] || ptr == &mons[PM_DRIVE_TRAIN] || ptr == &mons[PM_XTREME_TRACKER] || ptr == &mons[PM_REFUGE_UHLERT] || ptr == &mons[PM_THE_ULTIMATE_REFUGE]) && !mtmp->mpeaceful) appr = 1;
4335 if (uarmh && itemhasappearance(uarmh, APP_BUG_TRACKING_HELMET) && !rn2(3) ) appr = 1;
4337 if (FemtrapActiveJane && mtmp->female && !mtmp->mpeaceful && !mtmp->mtame) {
4338 if (mtmp->data->msize <= MZ_SMALL && !rn2(4)) appr = 1;
4339 if (mtmp->data->msize <= MZ_TINY && rn2(4)) appr = 1;
4342 if (uarmf && itemhasappearance(uarmf, APP_RAINBOW_BOOTS) && !rn2(3) ) appr = 1;
4344 if (uarmf && uarmf->oartifact == ART_HENRIETTA_S_DOGSHIT_BOOTS) appr = 1;
4346 if (uarmf && uarmf->oartifact == ART_DARK_BALL_OF_LIGHT) appr = 0;
4348 if (uarmh && uarmh->oartifact == ART_RADAR_NOT_WORKING) appr = 0;
4350 if (uarmf && uarmf->oartifact == ART_ENDARKEN_EVERYTHING && appr == 1 && !mtmp->mtame && !mtmp->mpeaceful && !rn2(3)) appr = 0;
4352 if (uarmf && uarmf->oartifact == ART_MARIYA_S_SEXYCHARM && (humanoid(mtmp->data) || is_animal(mtmp->data)) && !rn2(2)) {
4353 if (!resist(mtmp, ARMOR_CLASS, 0, 0)) {
4354 appr = -1;
4358 if (uarm && uarm->oartifact == ART_AND_HOW_SHE_IS_CURSED) {
4359 if (appr == 1 && !rn2(5)) appr = 0;
4360 if (!rn2(20)) appr = -1;
4363 if (is_unicorn(ptr) && (level.flags.noteleport || Race_if(PM_STABILISATOR) || u.antitelespelltimeout)) {
4364 /* on noteleport levels, perhaps we cannot avoid hero */
4365 for(i = 0; i < cnt; i++)
4366 if(!(info[i] & NOTONL)) avoid=TRUE;
4368 if (avoid_player(ptr) || mtmp->egotype_avoider ) avoid=TRUE; /* making this into a monster flag --Amy */
4370 if (astralspecial) appr = 1;
4372 for(i=0; i < cnt; i++) {
4373 if (avoid && (info[i] & NOTONL)) continue;
4374 nx = poss[i].x;
4375 ny = poss[i].y;
4377 if (FeelerGauges || u.uprops[FEELER_GAUGES].extrinsic || have_feelergaugesstone() || autismringcheck(ART_BILL_S_CHIP) || (uarm && uarm->oartifact == ART_THEY_SOMEHOW_HAVE_A_RADAR) || autismweaponcheck(ART_BAT_FROM_BALTIMORE) ) appr = 1;
4378 if (Race_if(PM_BULDOZGAR) && !mtmp->mpeaceful && !mtmp->mtame) appr = 1;
4380 if (appr != 0) {
4381 mtrk = &mtmp->mtrack[0];
4382 for(j=0; j < jcnt; mtrk++, j++)
4383 if(nx == mtrk->x && ny == mtrk->y)
4384 if(rn2(4*(cnt-j)))
4385 goto nxti;
4388 nearer = ((ndist = dist2(nx,ny,gx,gy)) < nidist);
4390 if((appr == 1 && nearer) || (appr == -1 && !nearer) ||
4391 (!appr && !rn2(++chcnt)) || !mmoved) {
4392 nix = nx;
4393 niy = ny;
4394 nidist = ndist;
4395 chi = i;
4396 mmoved = 1;
4398 nxti: ;
4402 if(mmoved) {
4403 register int j;
4405 if (mmoved==1 && (u.ux != nix || u.uy != niy) && itsstuck(mtmp))
4406 return(3);
4408 if (((IS_ROCK(levl[nix][niy].typ) && !(IS_FARMLAND(levl[nix][niy].typ) || IS_MOUNTAIN(levl[nix][niy].typ) || IS_GRAVEWALL(levl[nix][niy].typ)) && may_dig(nix,niy)) ||
4409 closed_door(nix, niy)) &&
4410 mmoved==1 && can_tunnel && needspick(ptr)) {
4411 if (closed_door(nix, niy)) {
4412 if (!(mw_tmp = MON_WEP(mtmp)) ||
4413 (mw_tmp && (!is_pick(mw_tmp) || !is_axe(mw_tmp))) )
4414 mtmp->weapon_check = NEED_PICK_OR_AXE;
4415 } else if (IS_TREE(levl[nix][niy].typ)) {
4416 if (!(mw_tmp = MON_WEP(mtmp)) || (mw_tmp && !is_axe(mw_tmp)) )
4417 mtmp->weapon_check = NEED_AXE;
4418 } else if (!(mw_tmp = MON_WEP(mtmp)) || (mw_tmp && !is_pick(mw_tmp)) ) {
4419 mtmp->weapon_check = NEED_PICK_AXE;
4421 if (mtmp->weapon_check >= NEED_PICK_AXE && mon_wield_item(mtmp))
4422 return(3);
4424 /* If ALLOW_U is set, either it's trying to attack you, or it
4425 * thinks it is. In either case, attack this spot in preference to
4426 * all others.
4428 /* Actually, this whole section of code doesn't work as you'd expect.
4429 * Most attacks are handled in dochug(). It calls distfleeck(), which
4430 * among other things sets nearby if the monster is near you--and if
4431 * nearby is set, we never call m_move unless it is a special case
4432 * (confused, stun, etc.) The effect is that this ALLOW_U (and
4433 * mfndpos) has no effect for normal attacks, though it lets a confused
4434 * monster attack you by accident.
4436 if(info[chi] & ALLOW_U) {
4437 nix = mtmp->mux;
4438 niy = mtmp->muy;
4440 if (nix == u.ux && niy == u.uy) {
4441 mtmp->mux = u.ux;
4442 mtmp->muy = u.uy;
4443 return(0);
4445 /* The monster may attack another based on 1 of 2 conditions:
4446 * 1 - It may be confused.
4447 * 2 - It may mistake the monster for your (displaced) image.
4448 * Pets get taken care of above and shouldn't reach this code.
4449 * Conflict gets handled even farther away (movemon()).
4451 if((info[chi] & ALLOW_M) ||
4452 (nix == mtmp->mux && niy == mtmp->muy)) {
4453 struct monst *mtmp2;
4454 int mstatus;
4455 mtmp2 = m_at(nix,niy);
4457 notonhead = mtmp2 && (nix != mtmp2->mx || niy != mtmp2->my);
4458 /* note: mstatus returns 0 if mtmp2 is nonexistent */
4459 mstatus = mattackm(mtmp, mtmp2);
4461 if (mstatus & MM_AGR_DIED) /* aggressor died */
4462 return 2;
4464 if ( ((mstatus & MM_HIT) || (mtmp2 && mtmp2->mtame && mtmp && !mtmp->mtame && !rn2(4))) && !(mstatus & MM_DEF_DIED) &&
4465 ((rn2(4) && mtmp2 && mtmp2->movement >= NORMAL_SPEED) || (mtmp2 && mtmp2->mtame && mtmp && !mtmp->mtame)) ) {
4466 mtmp2->movement -= NORMAL_SPEED;
4467 if (mtmp2->movement < 0) mtmp2->movement = 0; /* fail safe */
4468 notonhead = 0;
4469 mstatus = mattackm(mtmp2, mtmp); /* return attack */
4470 if (mstatus & MM_DEF_DIED)
4471 return 2;
4473 return 3;
4476 if (!m_in_out_region(mtmp,nix,niy))
4477 return 3;
4478 remove_monster(omx, omy);
4479 place_monster(mtmp, nix, niy);
4481 for(j = MTSZ-1; j > 0; j--)
4482 mtmp->mtrack[j] = mtmp->mtrack[j-1];
4483 mtmp->mtrack[0].x = omx;
4484 mtmp->mtrack[0].y = omy;
4485 /* Place a segment at the old position. */
4486 if (mtmp->wormno) worm_move(mtmp);
4487 } else {
4488 if(is_unicorn(ptr) && ptr != &mons[PM_YOUNG_UNICORN] && rn2(2) && !tele_restrict(mtmp)) {
4489 (void) rloc(mtmp, FALSE);
4490 return(1);
4492 if(mtmp->wormno) worm_nomove(mtmp);
4494 postmov:
4495 if(mmoved == 1 || mmoved == 3) {
4496 boolean canseeit = cansee(mtmp->mx, mtmp->my);
4498 if(mmoved == 1) {
4499 newsym(omx,omy); /* update the old position */
4500 if (mintrap(mtmp) >= 2) {
4501 if(mtmp->mx) newsym(mtmp->mx,mtmp->my);
4502 return(2); /* it died */
4504 ptr = mtmp->data;
4506 /* open a door, or crash through it, if you can */
4507 if(IS_DOOR(levl[mtmp->mx][mtmp->my].typ)
4508 && !passes_walls(ptr) && (!mtmp->egotype_wallwalk) /* doesn't need to open doors */
4509 && !can_tunnel /* taken care of below */
4511 struct rm *here = &levl[mtmp->mx][mtmp->my];
4512 boolean btrapped = (here->doormask & D_TRAPPED);
4514 if(here->doormask & (D_LOCKED|D_CLOSED) && (amorphous(ptr) ) ) {
4515 if (flags.verbose && canseemon(mtmp))
4516 pline("%s %s under the door.", Monnam(mtmp),
4517 (ptr == &mons[PM_FOG_CLOUD] ||
4518 ptr == &mons[PM_YELLOW_LIGHT])
4519 ? "flows" : "oozes");
4520 } else if(here->doormask & D_LOCKED && can_unlock) {
4521 if(btrapped) {
4522 here->doormask = D_NODOOR;
4523 newsym(mtmp->mx, mtmp->my);
4524 unblock_point(mtmp->mx,mtmp->my); /* vision */
4525 if(mb_trapped(mtmp)) return(2);
4526 } else {
4527 if (flags.verbose) {
4528 if (canseeit) {
4529 You("see a door unlock and open.");
4530 if (PlayerHearsSoundEffects) pline(issoviet ? "Kto-to klyuch k pobede pervogo igroka. Bud'te ochen' boyatsya." : "Kloeck-wong!");
4532 else if (flags.soundok)
4533 You_hear("a door unlock and open.");
4535 here->doormask = D_ISOPEN;
4536 /* newsym(mtmp->mx, mtmp->my); */
4537 unblock_point(mtmp->mx,mtmp->my); /* vision */
4539 } else if (here->doormask == D_CLOSED && (can_open ) ) {
4540 if(btrapped) {
4541 here->doormask = D_NODOOR;
4542 newsym(mtmp->mx, mtmp->my);
4543 unblock_point(mtmp->mx,mtmp->my); /* vision */
4544 if(mb_trapped(mtmp)) return(2);
4545 } else {
4546 if (flags.verbose) {
4547 if (canseeit) {
4548 You("see a door open.");
4549 if (PlayerHearsSoundEffects) pline(issoviet ? "Mirskiye veshchi, kak dveri ne mozhet derzhat' vas v bezopasnosti, nub!" : "Wong!");
4551 else if (flags.soundok)
4552 You_hear("a door open.");
4554 here->doormask = D_ISOPEN;
4555 /* newsym(mtmp->mx, mtmp->my); */ /* done below */
4556 unblock_point(mtmp->mx,mtmp->my); /* vision */
4558 } else if (here->doormask & (D_LOCKED|D_CLOSED)) {
4559 /* mfndpos guarantees this must be a doorbuster */
4560 /* WAC do dragons and breathers */
4561 if (bust_door_breath(mtmp) != -1) {
4562 (void) breamspot(mtmp,
4563 &ptr->mattk[bust_door_breath(mtmp)],
4564 (nix-omx), (niy-omy));
4565 } else
4566 if(btrapped) {
4567 here->doormask = D_NODOOR;
4568 newsym(mtmp->mx, mtmp->my);
4569 unblock_point(mtmp->mx,mtmp->my); /* vision */
4570 if(mb_trapped(mtmp)) return(2);
4571 } else {
4572 if (flags.verbose) {
4573 if (canseeit) {
4574 You("see a door crash open.");
4575 if (PlayerHearsSoundEffects) pline(issoviet ? "Tam net bar'yera mezhdu vami i burlyashchey ordy monstrov. Vse oni budut obdavat' vas, kak bibleyskiy potop!" : "Wongwongwongwongwongwongwongbooooooooooooooom!");
4577 else if (flags.soundok)
4578 You_hear("a door crash open.");
4580 if (here->doormask & D_LOCKED && !rn2(2))
4581 here->doormask = D_NODOOR;
4582 else here->doormask = D_BROKEN;
4583 /* newsym(mtmp->mx, mtmp->my); */ /* done below */
4584 unblock_point(mtmp->mx,mtmp->my); /* vision */
4586 /* if it's a shop door, schedule repair */
4587 if (*in_rooms(mtmp->mx, mtmp->my, SHOPBASE))
4588 add_damage(mtmp->mx, mtmp->my, 0L);
4590 } else if (levl[mtmp->mx][mtmp->my].typ == IRONBARS) {
4591 if (flags.verbose && canseemon(mtmp))
4592 Norep("%s %s %s the iron bars.", Monnam(mtmp),
4593 /* pluralization fakes verb conjugation */
4594 makeplural(locomotion(ptr, "pass")),
4595 passes_walls(ptr) ? "through" : "between");
4598 /* possibly dig */
4599 if (can_tunnel && mdig_tunnel(mtmp))
4600 return(2); /* mon died (position already updated) */
4602 /* set also in domove(), hack.c */
4603 if (u.uswallow && mtmp == u.ustuck &&
4604 (mtmp->mx != omx || mtmp->my != omy)) {
4605 /* If the monster moved, then update */
4606 u.ux0 = u.ux;
4607 u.uy0 = u.uy;
4608 u.ux = mtmp->mx;
4609 u.uy = mtmp->my;
4610 swallowed(0);
4611 } else
4612 newsym(mtmp->mx,mtmp->my);
4614 if(OBJ_AT(mtmp->mx, mtmp->my) && mtmp->mcanmove) {
4615 /* recompute the likes tests, in case we polymorphed
4616 * or if the "likegold" case got taken above */
4617 if (setlikes) {
4618 register int pctload = (curr_mon_load(mtmp) * 100) /
4619 max_mon_load(mtmp);
4621 /* look for gold or jewels nearby */
4622 likegold = (likes_gold(ptr) && pctload < 95);
4623 likegems = (likes_gems(ptr) && pctload < 85);
4624 uses_items = (/*!mindless(ptr) && !is_animal(ptr)
4625 && */pctload < 75);
4626 likeobjs = (likes_objs(ptr) && pctload < 75);
4627 likemagic = (likes_magic(ptr) && pctload < 85);
4628 likerock = (throws_rocks(ptr) && pctload < 50 &&
4629 !In_sokoban(&u.uz));
4630 conceals = hides_under(ptr);
4633 if ((EaterBugEffect || u.uprops[EATER_BUG].extrinsic || have_eaterstone() || ptr == &mons[PM_RAW_MATERIAL_COLLECTING_TANK] || ptr == &mons[PM_BURNEL_WHIRL] || ptr == &mons[PM_ITEM_VANISHER_CUBE] || ptr == &mons[PM_FLUIDATOR_NOB] || mtmp->egotype_allivore)) {
4634 if (meatanything(mtmp) == 2) return 2; /* it died */
4637 /* Maybe a rock mole just ate some metal object */
4638 if (metallivorous(ptr) || mtmp->egotype_metallivore) {
4639 if (meatmetal(mtmp) == 2) return 2; /* it died */
4642 /* or a lithic object */
4643 if (lithivorous(ptr) || mtmp->egotype_lithivore) {
4644 if (meatlithic(mtmp) == 2) return 2; /* it died */
4647 if(g_at(mtmp->mx,mtmp->my) && likegold) mpickgold(mtmp);
4649 /* Maybe a cube ate just about anything */
4650 /* KMH -- Taz likes organics, too! */
4651 if (organivorous(ptr) || mtmp->egotype_organivore) {
4652 if (meatobj(mtmp) == 2) return 2; /* it died */
4654 if (saprovorous(ptr) || ptr == &mons[PM_CORPULENT_DOG] || ptr == &mons[PM_SPIT_DEMON] || ptr == &mons[PM_THESTRAL] || ptr == &mons[PM_THICK_POTATO] || ptr == &mons[PM_BLACK_MUZZLE] || ptr == &mons[PM_CORPSE_SPITTER] || ptr == &mons[PM_MUZZLE_FIEND] || ptr == &mons[PM_MAW_FIEND] || ptr == &mons[PM_ROCKET_MUZZLE]) meatcorpse(mtmp);
4656 if(!*in_rooms(mtmp->mx, mtmp->my, SHOPBASE) || !rn2(25)) {
4657 boolean picked = FALSE;
4659 if(likeobjs) picked |= mpickstuff(mtmp, practical);
4660 if(likemagic) picked |= mpickstuff(mtmp, magical);
4661 if(likerock) picked |= mpickstuff(mtmp, boulder_class);
4662 if(likegems) picked |= mpickstuff(mtmp, gem_class);
4663 if(uses_items) picked |= mpickstuff(mtmp, (char *)0);
4664 /*if(picked) mmoved = 3;*/
4667 if(mtmp->minvis) {
4668 newsym(mtmp->mx, mtmp->my);
4669 if (mtmp->wormno) see_wsegs(mtmp);
4673 if(hides_under(ptr) || (ptr->mlet == S_EEL && !(uarmc && uarmc->oartifact == ART_SATAN_S_SUGGESTION) && !(ptr == &mons[PM_DEFORMED_FISH]) ) ) {
4674 /* Always set--or reset--mundetected if it's already hidden
4675 (just in case the object it was hiding under went away);
4676 usually set mundetected unless monster can't move. */
4677 if (mtmp->mundetected ||
4678 (mtmp->mcanmove && !mtmp->msleeping && rn2(5)))
4679 mtmp->mundetected = (ptr->mlet != S_EEL) ?
4680 OBJ_AT(mtmp->mx, mtmp->my) :
4681 ((is_waterypool(mtmp->mx, mtmp->my) || is_watertunnel(mtmp->mx, mtmp->my) || is_shiftingsand(mtmp->mx, mtmp->my)) && !Is_waterlevel(&u.uz));
4682 newsym(mtmp->mx, mtmp->my);
4684 if (ptr == &mons[PM_LAVA_SPIDER] && is_lava(mtmp->mx, mtmp->my)) {
4685 mtmp->mundetected = 1;
4686 newsym(mtmp->mx, mtmp->my);
4688 if (mtmp->isshk) {
4689 after_shk_move(mtmp);
4692 return(mmoved);
4695 #endif /* OVL0 */
4696 #ifdef OVL2
4698 boolean
4699 closed_door(x, y)
4700 register int x, y;
4702 return((boolean)(IS_DOOR(levl[x][y].typ) &&
4703 (levl[x][y].doormask & (D_LOCKED | D_CLOSED))));
4706 boolean
4707 accessible(x, y)
4708 register int x, y;
4710 return((boolean)(ACCESSIBLE(levl[x][y].typ) && !closed_door(x, y)));
4713 #endif /* OVL2 */
4714 #ifdef OVL0
4716 /* decide where the monster thinks you are standing */
4717 void
4718 set_apparxy(mtmp)
4719 register struct monst *mtmp;
4721 boolean notseen, gotu;
4722 register int disp, mx = mtmp->mux, my = mtmp->muy;
4723 #ifdef GOLDOBJ
4724 long umoney = money_cnt(invent);
4725 #endif
4728 * do cheapest and/or most likely tests first
4731 /* pet knows your smell; grabber still has hold of you */
4732 if (mtmp->mtame || mtmp == u.ustuck) goto found_you;
4734 /* monsters which know where you are don't suddenly forget,
4735 if you haven't moved away */
4736 if (mx == u.ux && my == u.uy) goto found_you;
4738 notseen = (!mtmp->mcansee || (Invis && (StrongInvis || !rn2(3)) && haseyes(mtmp->data) && (!perceives(mtmp->data) || (uarm && uarm->oartifact == ART_YOU_CANNOT_SEE_ME) ) ));
4739 /* add cases as required. eg. Displacement ... */
4740 if (notseen || Underwater) {
4741 /* Xorns can smell valuable metal like gold, treat as seen */
4742 if ((mtmp->data == &mons[PM_XORN]) &&
4743 #ifndef GOLDOBJ
4744 u.ugold
4745 #else
4746 umoney
4747 #endif
4748 && !Underwater)
4749 disp = 0;
4750 else
4751 disp = 1;
4752 } else if (Displaced && (StrongDisplaced || !rn2(3)) && !(dmgtype(mtmp->data, AD_DISP) ) && !(dmgtype(mtmp->data, AD_MAGM) ) && !(dmgtype(mtmp->data, AD_MCRE) ) && mtmp->data != &mons[PM_BABY_GRAY_DRAGON] && mtmp->data != &mons[PM_YOUNG_GRAY_DRAGON] && mtmp->data != &mons[PM_YOUNG_ADULT_GRAY_DRAGON] &&
4753 !(dmgtype(mtmp->data, AD_RBRE)) && !(dmgtype(mtmp->data, AD_RNG)) ) {
4754 disp = couldsee(mx, my) ? 2 : 1;
4755 } else disp = 0;
4756 if (!disp) goto found_you;
4758 /* without something like the following, invis. and displ.
4759 are too powerful */
4760 gotu = notseen ? rn2(3) : StrongDisplaced ? rn2(2) : Displaced ? rn2(2) : FALSE;
4762 #if 0 /* this never worked as intended & isn't needed anyway */
4763 /* If invis but not displaced, staying around gets you 'discovered' */
4764 gotu |= (!Displaced && u.dx == 0 && u.dy == 0);
4765 #endif
4767 if (!gotu) {
4768 register int try_cnt = 0;
4769 do {
4770 if (++try_cnt > 200) goto found_you; /* punt */
4771 mx = u.ux - disp + rn2(2*disp+1);
4772 my = u.uy - disp + rn2(2*disp+1);
4773 } while (!isok(mx,my)
4774 || (disp != 2 && mx == mtmp->mx && my == mtmp->my)
4775 || ((mx != u.ux || my != u.uy) &&
4776 !passes_walls(mtmp->data) && (!mtmp->egotype_wallwalk) &&
4777 (!ACCESSIBLE(levl[mx][my].typ) ||
4778 (closed_door(mx, my) && !can_ooze(mtmp))))
4779 || !couldsee(mx, my));
4780 } else {
4781 found_you:
4782 mx = u.ux;
4783 my = u.uy;
4786 mtmp->mux = mx;
4787 mtmp->muy = my;
4790 boolean
4791 can_ooze(mtmp)
4792 struct monst *mtmp;
4794 struct obj *chain, *obj;
4796 if (!amorphous(mtmp->data)) return FALSE;
4798 /* If you carry really little stuff, you should be able to ooze even if the items are bulky. --Amy */
4800 if (mtmp == &youmonst && ((inv_weight() + weight_cap()) < 100) ) return TRUE;
4802 if (mtmp == &youmonst && ((inv_weight() + weight_cap()) < (weight_cap() / 10) ) ) return TRUE;
4805 if (mtmp == &youmonst) {
4806 #ifndef GOLDOBJ
4807 if (u.ugold > 100L) return FALSE;
4808 #endif
4809 chain = invent;
4810 } else {
4811 #ifndef GOLDOBJ
4812 if (mtmp->mgold > 100L) return FALSE;
4813 #endif
4814 chain = mtmp->minvent;
4816 for (obj = chain; obj; obj = obj->nobj) {
4817 int typ = obj->otyp;
4819 #ifdef GOLDOBJ
4820 if (typ == COIN_CLASS && obj->quan > 100L) return FALSE;
4821 #endif
4822 if (obj->oclass != GEM_CLASS &&
4823 !(typ >= ARROW && typ <= DARK_BATARANG) &&
4824 !(typ >= DAGGER && typ <= CRYSKNIFE) &&
4825 typ != SLING &&
4826 !is_cloak(obj) && typ != FEDORA &&
4827 !is_gloves(obj) && typ != LEATHER_JACKET &&
4828 typ != CREDIT_CARD && typ != DATA_CHIP && !is_shirt(obj) &&
4829 !(typ == CORPSE && verysmall(&mons[obj->corpsenm])) &&
4830 typ != FORTUNE_COOKIE && typ != CANDY_BAR &&
4831 typ != PANCAKE && typ != LEMBAS_WAFER &&
4832 typ != LUMP_OF_ROYAL_JELLY &&
4833 obj->oclass != AMULET_CLASS &&
4834 obj->oclass != IMPLANT_CLASS &&
4835 obj->oclass != RING_CLASS &&
4836 obj->oclass != VENOM_CLASS &&
4837 typ != SACK && typ != BAG_OF_HOLDING &&
4838 typ != BAG_OF_TRICKS && !Is_candle(obj) &&
4839 typ != OILSKIN_SACK && typ != TITAN_SACK && typ != LEATHER_LEASH &&
4840 typ != INKA_LEASH && typ != ADAMANT_LEASH &&
4841 typ != STETHOSCOPE && typ != BLINDFOLD && typ != EYECLOSER && typ != DRAGON_EYEPATCH && typ != TOWEL &&
4842 typ != TIN_WHISTLE && typ != GRASS_WHISTLE && typ != MAGIC_WHISTLE &&
4843 typ != MAGIC_MARKER && typ != TIN_OPENER && typ != BUDO_NO_SASU && typ != JEONTU_GEOM &&
4844 typ != SKELETON_KEY && typ != SECRET_KEY && typ != LOCK_PICK && typ != HAIRCLIP
4845 ) return FALSE;
4846 if (Is_container(obj) && obj->cobj) return FALSE;
4849 return TRUE;
4852 static int
4853 bust_door_breath(mtmp)
4854 register struct monst *mtmp;
4856 struct permonst *ptr = mtmp->data;
4857 int i;
4860 if (mtmp->mcan || mtmp->mspec_used) return (-1); /* Cancelled/used up */
4862 for(i = 0; i < NATTK; i++)
4863 if ((ptr->mattk[i].aatyp == AT_BREA) &&
4864 (ptr->mattk[i].adtyp == AD_ACID ||
4865 ptr->mattk[i].adtyp == AD_MAGM ||
4866 ptr->mattk[i].adtyp == AD_DISN ||
4867 ptr->mattk[i].adtyp == AD_ELEC ||
4868 ptr->mattk[i].adtyp == AD_FIRE ||
4869 ptr->mattk[i].adtyp == AD_COLD)) return(i);
4871 return(-1);
4875 #endif /* OVL0 */
4877 /*monmove.c*/