MCPcopy Create free account
hub / github.com/NetHack/NetHack / magic_whistled

Function magic_whistled

src/apply.c:517–687  ·  view source on GitHub ↗

'obj' is assumed to be a magic whistle */

Source from the content-addressed store, hash-verified

515
516/* 'obj' is assumed to be a magic whistle */
517staticfn void
518magic_whistled(struct obj *obj)
519{
520 struct monst *mtmp, *nextmon;
521 char buf[BUFSZ], *mnam = 0,
522 shiftbuf[BUFSZ + sizeof "shifts location"],
523 appearbuf[BUFSZ + sizeof "appears"],
524 disappearbuf[BUFSZ + sizeof "disappears"];
525 boolean oseen, nseen,
526 already_discovered = objects[obj->otyp].oc_name_known != 0;
527 int omx, omy, shift = 0, appear = 0, disappear = 0, trapped = 0;
528
529 /* stasis prevents magic-whistling */
530 if (svl.level.flags.stasis_until >= svm.moves)
531 return;
532
533 /* need to copy (up to 3) names as they're collected rather than just
534 save pointers to them, otherwise churning through every mbuf[] might
535 clobber the ones we care about */
536 shiftbuf[0] = appearbuf[0] = disappearbuf[0] = '\0';
537
538 for (mtmp = fmon; mtmp; mtmp = nextmon) {
539 nextmon = mtmp->nmon; /* trap might kill mon */
540 if (DEADMONSTER(mtmp))
541 continue;
542 /* only tame monsters are affected;
543 steed is already at your location, so not affected;
544 this avoids trap issues if you're on a trap location */
545 if (!mtmp->mtame || mtmp == u.usteed)
546 continue;
547 if (mtmp->mtrapped) {
548 /* no longer in previous trap (affects mintrap) */
549 mtmp->mtrapped = 0;
550 fill_pit(mtmp->mx, mtmp->my);
551 }
552
553 oseen = canspotmon(mtmp); /* old 'seen' status */
554 if (oseen) /* get name in case it's one we'll remember */
555 mnam = y_monnam(mtmp); /* before mnexto(); it might disappear */
556 /* mimic must be revealed before we know whether it
557 actually moves because line-of-sight may change */
558 if (M_AP_TYPE(mtmp))
559 seemimic(mtmp);
560 omx = mtmp->mx, omy = mtmp->my;
561 mnexto(mtmp, !already_discovered ? RLOC_MSG : RLOC_NONE);
562
563 if (mtmp->mx != omx || mtmp->my != omy) {
564 if (mtmp->mundetected) { /* reveal non-mimic hider that moved */
565 mtmp->mundetected = 0;
566 newsym(mtmp->mx, mtmp->my);
567 }
568 /*
569 * FIXME:
570 * All relocated monsters should change positions essentially
571 * simultaneously but we're dealing with them sequentially.
572 * That could kill some off in the process, each time leaving
573 * their target position (which should be occupied at least
574 * momentarily) available as a potential death trap for others.

Callers 1

use_magic_whistleFunction · 0.85

Calls 11

fill_pitFunction · 0.85
y_monnamFunction · 0.85
seemimicFunction · 0.85
mnextoFunction · 0.85
newsymFunction · 0.85
mintrapFunction · 0.85
change_luckFunction · 0.85
copyncharsFunction · 0.85
upstartFunction · 0.85
eosFunction · 0.85
plineFunction · 0.70

Tested by

no test coverage detected