Source:NetHack 3.6.1/src/music.c

From NetHackWiki
(Redirected from Source:Ref/awaken soldiers)
Jump to: navigation, search

Below is the full text to music.c from the source code of NetHack 3.6.1. To link to a particular line, write [[Source:NetHack 3.6.1/src/music.c#line123]], for example.

Top of file

  1.  /* NetHack 3.6	music.c	$NHDT-Date: 1517877381 2018/02/06 00:36:21 $  $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.47 $ */
  2.  /*      Copyright (c) 1989 by Jean-Christophe Collet */
  3.  /* NetHack may be freely redistributed.  See license for details. */

The NetHack General Public License applies to screenshots, source code and other content from NetHack.

This content was modified from the original NetHack source code distribution (by splitting up NetHack content between wiki pages, and possibly further editing). See the page history for a list of who changed it, and on what dates.

  1.  
  2.  /*
  3.   * This file contains the different functions designed to manipulate the
  4.   * musical instruments and their various effects.
  5.   *
  6.   * The list of instruments / effects is :
  7.   *
  8.   * (wooden) flute       may calm snakes if player has enough dexterity
  9.   * magic flute          may put monsters to sleep:  area of effect depends
  10.   *                      on player level.
  11.   * (tooled) horn        Will awaken monsters:  area of effect depends on
  12.   *                      player level.  May also scare monsters.
  13.   * fire horn            Acts like a wand of fire.
  14.   * frost horn           Acts like a wand of cold.
  15.   * bugle                Will awaken soldiers (if any):  area of effect depends
  16.   *                      on player level.
  17.   * (wooden) harp        May calm nymph if player has enough dexterity.
  18.   * magic harp           Charm monsters:  area of effect depends on player
  19.   *                      level.
  20.   * (leather) drum       Will awaken monsters like the horn.
  21.   * drum of earthquake   Will initiate an earthquake whose intensity depends
  22.   *                      on player level.  That is, it creates random pits
  23.   *                      called here chasms.
  24.   */
  25.  
  26.  #include "hack.h"
  27.  
  28.  STATIC_DCL void FDECL(awaken_monsters, (int));
  29.  STATIC_DCL void FDECL(put_monsters_to_sleep, (int));
  30.  STATIC_DCL void FDECL(charm_snakes, (int));
  31.  STATIC_DCL void FDECL(calm_nymphs, (int));
  32.  STATIC_DCL void FDECL(charm_monsters, (int));
  33.  STATIC_DCL void FDECL(do_earthquake, (int));
  34.  STATIC_DCL int FDECL(do_improvisation, (struct obj *));
  35.  
  36.  #ifdef UNIX386MUSIC
  37.  STATIC_DCL int NDECL(atconsole);
  38.  STATIC_DCL void FDECL(speaker, (struct obj *, char *));
  39.  #endif
  40.  #ifdef VPIX_MUSIC
  41.  extern int sco_flag_console; /* will need changing if not _M_UNIX */
  42.  STATIC_DCL void NDECL(playinit);
  43.  STATIC_DCL void FDECL(playstring, (char *, size_t));
  44.  STATIC_DCL void FDECL(speaker, (struct obj *, char *));
  45.  #endif
  46.  #ifdef PCMUSIC
  47.  void FDECL(pc_speaker, (struct obj *, char *));
  48.  #endif
  49.  #ifdef AMIGA
  50.  void FDECL(amii_speaker, (struct obj *, char *, int));
  51.  #endif
  52.  

awaken_monsters

  1.  /*
  2.   * Wake every monster in range...
  3.   */
  4.  
  5.  STATIC_OVL void
  6.  awaken_monsters(distance)
  7.  int distance;
  8.  {
  9.      register struct monst *mtmp;
  10.      register int distm;
  11.  
  12.      for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
  13.          if (DEADMONSTER(mtmp))
  14.              continue;
  15.          if ((distm = distu(mtmp->mx, mtmp->my)) < distance) {
  16.              mtmp->msleeping = 0;
  17.              mtmp->mcanmove = 1;
  18.              mtmp->mfrozen = 0;
  19.              /* may scare some monsters -- waiting monsters excluded */
  20.              if (!unique_corpstat(mtmp->data)
  21.                  && (mtmp->mstrategy & STRAT_WAITMASK) != 0)
  22.                  mtmp->mstrategy &= ~STRAT_WAITMASK;
  23.              else if (distm < distance / 3
  24.                       && !resist(mtmp, TOOL_CLASS, 0, NOTELL)
  25.                       /* some monsters are immune */
  26.                       && onscary(0, 0, mtmp))
  27.                  monflee(mtmp, 0, FALSE, TRUE);
  28.          }
  29.      }
  30.  }
  31.  

put_monsters_to_sleep

  1.  /*
  2.   * Make monsters fall asleep.  Note that they may resist the spell.
  3.   */
  4.  
  5.  STATIC_OVL void
  6.  put_monsters_to_sleep(distance)
  7.  int distance;
  8.  {
  9.      register struct monst *mtmp;
  10.  
  11.      for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
  12.          if (DEADMONSTER(mtmp))
  13.              continue;
  14.          if (distu(mtmp->mx, mtmp->my) < distance
  15.              && sleep_monst(mtmp, d(10, 10), TOOL_CLASS)) {
  16.              mtmp->msleeping = 1; /* 10d10 turns + wake_nearby to rouse */
  17.              slept_monst(mtmp);
  18.          }
  19.      }
  20.  }
  21.  

charm_snakes

  1.  /*
  2.   * Charm snakes in range.  Note that the snakes are NOT tamed.
  3.   */
  4.  
  5.  STATIC_OVL void
  6.  charm_snakes(distance)
  7.  int distance;
  8.  {
  9.      register struct monst *mtmp;
  10.      int could_see_mon, was_peaceful;
  11.  
  12.      for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
  13.          if (DEADMONSTER(mtmp))
  14.              continue;
  15.          if (mtmp->data->mlet == S_SNAKE && mtmp->mcanmove
  16.              && distu(mtmp->mx, mtmp->my) < distance) {
  17.              was_peaceful = mtmp->mpeaceful;
  18.              mtmp->mpeaceful = 1;
  19.              mtmp->mavenge = 0;
  20.              mtmp->mstrategy &= ~STRAT_WAITMASK;
  21.              could_see_mon = canseemon(mtmp);
  22.              mtmp->mundetected = 0;
  23.              newsym(mtmp->mx, mtmp->my);
  24.              if (canseemon(mtmp)) {
  25.                  if (!could_see_mon)
  26.                      You("notice %s, swaying with the music.", a_monnam(mtmp));
  27.                  else
  28.                      pline("%s freezes, then sways with the music%s.",
  29.                            Monnam(mtmp),
  30.                            was_peaceful ? "" : ", and now seems quieter");
  31.              }
  32.          }
  33.      }
  34.  }
  35.  

calm_nymphs

  1.  /*
  2.   * Calm nymphs in range.
  3.   */
  4.  
  5.  STATIC_OVL void
  6.  calm_nymphs(distance)
  7.  int distance;
  8.  {
  9.      register struct monst *mtmp;
  10.  
  11.      for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
  12.          if (DEADMONSTER(mtmp))
  13.              continue;
  14.          if (mtmp->data->mlet == S_NYMPH && mtmp->mcanmove
  15.              && distu(mtmp->mx, mtmp->my) < distance) {
  16.              mtmp->msleeping = 0;
  17.              mtmp->mpeaceful = 1;
  18.              mtmp->mavenge = 0;
  19.              mtmp->mstrategy &= ~STRAT_WAITMASK;
  20.              if (canseemon(mtmp))
  21.                  pline(
  22.                      "%s listens cheerfully to the music, then seems quieter.",
  23.                        Monnam(mtmp));
  24.          }
  25.      }
  26.  }
  27.  

awaken_soldiers

  1.  /* Awake soldiers anywhere the level (and any nearby monster). */
  2.  void
  3.  awaken_soldiers(bugler)
  4.  struct monst *bugler; /* monster that played instrument */
  5.  {
  6.      register struct monst *mtmp;
  7.      int distance, distm;
  8.  
  9.      /* distance of affected non-soldier monsters to bugler */
  10.      distance = ((bugler == &youmonst) ? u.ulevel : bugler->data->mlevel) * 30;
  11.  
  12.      for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
  13.          if (DEADMONSTER(mtmp))
  14.              continue;
  15.          if (is_mercenary(mtmp->data) && mtmp->data != &mons[PM_GUARD]) {
  16.              mtmp->mpeaceful = mtmp->msleeping = mtmp->mfrozen = 0;
  17.              mtmp->mcanmove = 1;
  18.              mtmp->mstrategy &= ~STRAT_WAITMASK;
  19.              if (canseemon(mtmp))
  20.                  pline("%s is now ready for battle!", Monnam(mtmp));
  21.              else
  22.                  Norep("You hear the rattle of battle gear being readied.");
  23.          } else if ((distm = ((bugler == &youmonst)
  24.                                   ? distu(mtmp->mx, mtmp->my)
  25.                                   : dist2(bugler->mx, bugler->my, mtmp->mx,
  26.                                           mtmp->my))) < distance) {
  27.              mtmp->msleeping = 0;
  28.              mtmp->mcanmove = 1;
  29.              mtmp->mfrozen = 0;
  30.              /* may scare some monsters -- waiting monsters excluded */
  31.              if (!unique_corpstat(mtmp->data)
  32.                  && (mtmp->mstrategy & STRAT_WAITMASK) != 0)
  33.                  mtmp->mstrategy &= ~STRAT_WAITMASK;
  34.              else if (distm < distance / 3
  35.                       && !resist(mtmp, TOOL_CLASS, 0, NOTELL))
  36.                  monflee(mtmp, 0, FALSE, TRUE);
  37.          }
  38.      }
  39.  }
  40.  

charm_monsters

  1.  /* Charm monsters in range.  Note that they may resist the spell.
  2.   * If swallowed, range is reduced to 0.
  3.   */
  4.  STATIC_OVL void
  5.  charm_monsters(distance)
  6.  int distance;
  7.  {
  8.      struct monst *mtmp, *mtmp2;
  9.  
  10.      if (u.uswallow) {
  11.          if (!resist(u.ustuck, TOOL_CLASS, 0, NOTELL))
  12.              (void) tamedog(u.ustuck, (struct obj *) 0);
  13.      } else {
  14.          for (mtmp = fmon; mtmp; mtmp = mtmp2) {
  15.              mtmp2 = mtmp->nmon;
  16.              if (DEADMONSTER(mtmp))
  17.                  continue;
  18.  
  19.              if (distu(mtmp->mx, mtmp->my) <= distance) {
  20.                  if (!resist(mtmp, TOOL_CLASS, 0, NOTELL))
  21.                      (void) tamedog(mtmp, (struct obj *) 0);
  22.              }
  23.          }
  24.      }
  25.  }
  26.  

do_earthquake

  1.  /* Generate earthquake :-) of desired force.
  2.   * That is:  create random chasms (pits).
  3.   */
  4.  STATIC_OVL void
  5.  do_earthquake(force)
  6.  int force;
  7.  {
  8.      register int x, y;
  9.      struct monst *mtmp;
  10.      struct obj *otmp;
  11.      struct trap *chasm, *trap_at_u = t_at(u.ux, u.uy);
  12.      int start_x, start_y, end_x, end_y;
  13.      schar filltype;
  14.      unsigned tu_pit = 0;
  15.  
  16.      if (trap_at_u)
  17.          tu_pit = (trap_at_u->ttyp == PIT || trap_at_u->ttyp == SPIKED_PIT);
  18.      start_x = u.ux - (force * 2);
  19.      start_y = u.uy - (force * 2);
  20.      end_x = u.ux + (force * 2);
  21.      end_y = u.uy + (force * 2);
  22.      if (start_x < 1)
  23.          start_x = 1;
  24.      if (start_y < 1)
  25.          start_y = 1;
  26.      if (end_x >= COLNO)
  27.          end_x = COLNO - 1;
  28.      if (end_y >= ROWNO)
  29.          end_y = ROWNO - 1;
  30.      for (x = start_x; x <= end_x; x++)
  31.          for (y = start_y; y <= end_y; y++) {
  32.              if ((mtmp = m_at(x, y)) != 0) {
  33.                  wakeup(mtmp, TRUE); /* peaceful monster will become hostile */
  34.                  if (mtmp->mundetected && is_hider(mtmp->data)) {
  35.                      mtmp->mundetected = 0;
  36.                      if (cansee(x, y))
  37.                          pline("%s is shaken loose from the ceiling!",
  38.                                Amonnam(mtmp));
  39.                      else
  40.                          You_hear("a thumping sound.");
  41.                      if (x == u.ux && y == u.uy)
  42.                          You("easily dodge the falling %s.", mon_nam(mtmp));
  43.                      newsym(x, y);
  44.                  }
  45.              }
  46.              if (!rn2(14 - force))
  47.                  switch (levl[x][y].typ) {
  48.                  case FOUNTAIN: /* Make the fountain disappear */
  49.                      if (cansee(x, y))
  50.                          pline_The("fountain falls into a chasm.");
  51.                      goto do_pit;
  52.                  case SINK:
  53.                      if (cansee(x, y))
  54.                          pline_The("kitchen sink falls into a chasm.");
  55.                      goto do_pit;
  56.                  case ALTAR:
  57.                      if (Is_astralevel(&u.uz) || Is_sanctum(&u.uz))
  58.                          break;
  59.  
  60.                      if (cansee(x, y))
  61.                          pline_The("altar falls into a chasm.");
  62.                      goto do_pit;
  63.                  case GRAVE:
  64.                      if (cansee(x, y))
  65.                          pline_The("headstone topples into a chasm.");
  66.                      goto do_pit;
  67.                  case THRONE:
  68.                      if (cansee(x, y))
  69.                          pline_The("throne falls into a chasm.");
  70.                      /*FALLTHRU*/
  71.                  case ROOM:
  72.                  case CORR: /* Try to make a pit */
  73.                  do_pit:
  74.                      chasm = maketrap(x, y, PIT);
  75.                      if (!chasm)
  76.                          break; /* no pit if portal at that location */
  77.                      chasm->tseen = 1;
  78.  
  79.                      levl[x][y].doormask = 0;
  80.                      /*
  81.                       * Let liquid flow into the newly created chasm.
  82.                       * Adjust corresponding code in apply.c for
  83.                       * exploding wand of digging if you alter this sequence.
  84.                       */
  85.                      filltype = fillholetyp(x, y, FALSE);
  86.                      if (filltype != ROOM) {
  87.                          levl[x][y].typ = filltype;
  88.                          liquid_flow(x, y, filltype, chasm, (char *) 0);
  89.                      }
  90.  
  91.                      mtmp = m_at(x, y);
  92.  
  93.                      if ((otmp = sobj_at(BOULDER, x, y)) != 0) {
  94.                          if (cansee(x, y))
  95.                              pline("KADOOM! The boulder falls into a chasm%s!",
  96.                                    ((x == u.ux) && (y == u.uy)) ? " below you"
  97.                                                                 : "");
  98.                          if (mtmp)
  99.                              mtmp->mtrapped = 0;
  100.                          obj_extract_self(otmp);
  101.                          (void) flooreffects(otmp, x, y, "");
  102.                          break;
  103.                      }
  104.  
  105.                      /* We have to check whether monsters or player
  106.                         falls in a chasm... */
  107.                      if (mtmp) {
  108.                          if (!is_flyer(mtmp->data)
  109.                              && !is_clinger(mtmp->data)) {
  110.                              boolean m_already_trapped = mtmp->mtrapped;
  111.                              mtmp->mtrapped = 1;
  112.                              if (!m_already_trapped) { /* suppress messages */
  113.                                  if (cansee(x, y))
  114.                                      pline("%s falls into a chasm!",
  115.                                            Monnam(mtmp));
  116.                                  else if (humanoid(mtmp->data))
  117.                                      You_hear("a scream!");
  118.                              }
  119.                              /* Falling is okay for falling down
  120.                                  within a pit from jostling too */
  121.                              mselftouch(mtmp, "Falling, ", TRUE);
  122.                              if (mtmp->mhp > 0) {
  123.                                  mtmp->mhp -= rnd(m_already_trapped ? 4 : 6);
  124.                                  if (mtmp->mhp <= 0) {
  125.                                      if (!cansee(x, y)) {
  126.                                          pline("It is destroyed!");
  127.                                      } else {
  128.                                          You("destroy %s!",
  129.                                              mtmp->mtame
  130.                                                ? x_monnam(mtmp, ARTICLE_THE,
  131.                                                           "poor",
  132.                                                           has_mname(mtmp)
  133.                                                             ? SUPPRESS_SADDLE
  134.                                                             : 0,
  135.                                                           FALSE)
  136.                                                : mon_nam(mtmp));
  137.                                      }
  138.                                      xkilled(mtmp, XKILL_NOMSG);
  139.                                  }
  140.                              }
  141.                          }
  142.                      } else if (x == u.ux && y == u.uy) {
  143.                          if (Levitation || Flying
  144.                              || is_clinger(youmonst.data)) {
  145.                              if (!tu_pit) { /* no pit here previously */
  146.                                  pline("A chasm opens up under you!");
  147.                                  You("don't fall in!");
  148.                              }
  149.                          } else if (!tu_pit || !u.utrap
  150.                                     || (u.utrap && u.utraptype != TT_PIT)) {
  151.                              /* no pit here previously, or you were
  152.                                 not in it even it there was */
  153.                              You("fall into a chasm!");
  154.                              u.utrap = rn1(6, 2);
  155.                              u.utraptype = TT_PIT;
  156.                              losehp(Maybe_Half_Phys(rnd(6)),
  157.                                     "fell into a chasm", NO_KILLER_PREFIX);
  158.                              selftouch("Falling, you");
  159.                          } else if (u.utrap && u.utraptype == TT_PIT) {
  160.                              boolean keepfooting =
  161.                                  ((Fumbling && !rn2(5))
  162.                                   || (!rnl(Role_if(PM_ARCHEOLOGIST) ? 3 : 9))
  163.                                   || ((ACURR(A_DEX) > 7) && rn2(5)));
  164.                              You("are jostled around violently!");
  165.                              u.utrap = rn1(6, 2);
  166.                              u.utraptype = TT_PIT; /* superfluous */
  167.                              losehp(Maybe_Half_Phys(rnd(keepfooting ? 2 : 4)),
  168.                                     "hurt in a chasm", NO_KILLER_PREFIX);
  169.                              if (keepfooting)
  170.                                  exercise(A_DEX, TRUE);
  171.                              else
  172.                                  selftouch(
  173.                                      (Upolyd && (slithy(youmonst.data)
  174.                                                  || nolimbs(youmonst.data)))
  175.                                          ? "Shaken, you"
  176.                                          : "Falling down, you");
  177.                          }
  178.                      } else
  179.                          newsym(x, y);
  180.                      break;
  181.                  case DOOR: /* Make the door collapse */
  182.                      if (levl[x][y].doormask == D_NODOOR)
  183.                          goto do_pit;
  184.                      if (cansee(x, y))
  185.                          pline_The("door collapses.");
  186.                      if (*in_rooms(x, y, SHOPBASE))
  187.                          add_damage(x, y, 0L);
  188.                      levl[x][y].doormask = D_NODOOR;
  189.                      unblock_point(x, y);
  190.                      newsym(x, y);
  191.                      break;
  192.                  }
  193.          }
  194.  }
  195.  

generic_lvl_desc

  1.  const char *
  2.  generic_lvl_desc()
  3.  {
  4.      if (Is_astralevel(&u.uz))
  5.          return "astral plane";
  6.      else if (In_endgame(&u.uz))
  7.          return "plane";
  8.      else if (Is_sanctum(&u.uz))
  9.          return "sanctum";
  10.      else if (In_sokoban(&u.uz))
  11.          return "puzzle";
  12.      else if (In_V_tower(&u.uz))
  13.          return "tower";
  14.      else
  15.          return "dungeon";
  16.  }
  17.  

do_improvisation

  1.  /*
  2.   * The player is trying to extract something from his/her instrument.
  3.   */
  4.  STATIC_OVL int
  5.  do_improvisation(instr)
  6.  struct obj *instr;
  7.  {
  8.      int damage, mode, do_spec = !(Stunned || Confusion);
  9.      struct obj itmp;
  10.  
  11.      itmp = *instr;
  12.      itmp.oextra = (struct oextra *) 0; /* ok on this copy as instr maintains
  13.                                            the ptr to free at some point if
  14.                                            there is one */
  15.  
  16.      /* if won't yield special effect, make sound of mundane counterpart */
  17.      if (!do_spec || instr->spe <= 0)
  18.          while (objects[itmp.otyp].oc_magic)
  19.              itmp.otyp -= 1;
  20.  #ifdef MAC
  21.      mac_speaker(&itmp, "C");
  22.  #endif
  23.  #ifdef AMIGA
  24.      amii_speaker(&itmp, "Cw", AMII_OKAY_VOLUME);
  25.  #endif
  26.  #ifdef VPIX_MUSIC
  27.      if (sco_flag_console)
  28.          speaker(&itmp, "C");
  29.  #endif
  30.  #ifdef PCMUSIC
  31.      pc_speaker(&itmp, "C");
  32.  #endif
  33.  
  34.  #define PLAY_NORMAL   0x00
  35.  #define PLAY_STUNNED  0x01
  36.  #define PLAY_CONFUSED 0x02
  37.  #define PLAY_HALLU    0x04
  38.      mode = PLAY_NORMAL;
  39.      if (Stunned)
  40.          mode |= PLAY_STUNNED;
  41.      if (Confusion)
  42.          mode |= PLAY_CONFUSED;
  43.      if (Hallucination)
  44.          mode |= PLAY_HALLU;
  45.  
  46.      switch (mode) {
  47.      case PLAY_NORMAL:
  48.          You("start playing %s.", yname(instr));
  49.          break;
  50.      case PLAY_STUNNED:
  51.          You("produce an obnoxious droning sound.");
  52.          break;
  53.      case PLAY_CONFUSED:
  54.          You("produce a raucous noise.");
  55.          break;
  56.      case PLAY_HALLU:
  57.          You("produce a kaleidoscopic display of floating butterfiles.");
  58.          break;
  59.      /* TODO? give some or all of these combinations their own feedback;
  60.         hallucination ones should reference senses other than hearing... */
  61.      case PLAY_STUNNED | PLAY_CONFUSED:
  62.      case PLAY_STUNNED | PLAY_HALLU:
  63.      case PLAY_CONFUSED | PLAY_HALLU:
  64.      case PLAY_STUNNED | PLAY_CONFUSED | PLAY_HALLU:
  65.      default:
  66.          pline("What you produce is quite far from music...");
  67.          break;
  68.      }
  69.  #undef PLAY_NORMAL
  70.  #undef PLAY_STUNNED
  71.  #undef PLAY_CONFUSED
  72.  #undef PLAY_HALLU
  73.  
  74.      switch (itmp.otyp) { /* note: itmp.otyp might differ from instr->otyp */
  75.      case MAGIC_FLUTE: /* Make monster fall asleep */
  76.          consume_obj_charge(instr, TRUE);
  77.  
  78.          You("produce %s music.", Hallucination ? "piped" : "soft");
  79.          put_monsters_to_sleep(u.ulevel * 5);
  80.          exercise(A_DEX, TRUE);
  81.          break;
  82.      case WOODEN_FLUTE: /* May charm snakes */
  83.          do_spec &= (rn2(ACURR(A_DEX)) + u.ulevel > 25);
  84.          pline("%s.", Tobjnam(instr, do_spec ? "trill" : "toot"));
  85.          if (do_spec)
  86.              charm_snakes(u.ulevel * 3);
  87.          exercise(A_DEX, TRUE);
  88.          break;
  89.      case FIRE_HORN:  /* Idem wand of fire */
  90.      case FROST_HORN: /* Idem wand of cold */
  91.          consume_obj_charge(instr, TRUE);
  92.  
  93.          if (!getdir((char *) 0)) {
  94.              pline("%s.", Tobjnam(instr, "vibrate"));
  95.              break;
  96.          } else if (!u.dx && !u.dy && !u.dz) {
  97.              if ((damage = zapyourself(instr, TRUE)) != 0) {
  98.                  char buf[BUFSZ];
  99.  
  100.                  Sprintf(buf, "using a magical horn on %sself", uhim());
  101.                  losehp(damage, buf, KILLED_BY); /* fire or frost damage */
  102.              }
  103.          } else {
  104.              buzz((instr->otyp == FROST_HORN) ? AD_COLD - 1 : AD_FIRE - 1,
  105.                   rn1(6, 6), u.ux, u.uy, u.dx, u.dy);
  106.          }
  107.          makeknown(instr->otyp);
  108.          break;
  109.      case TOOLED_HORN: /* Awaken or scare monsters */
  110.          You("produce a frightful, grave sound.");
  111.          awaken_monsters(u.ulevel * 30);
  112.          exercise(A_WIS, FALSE);
  113.          break;
  114.      case BUGLE: /* Awaken & attract soldiers */
  115.          You("extract a loud noise from %s.", yname(instr));
  116.          awaken_soldiers(&youmonst);
  117.          exercise(A_WIS, FALSE);
  118.          break;
  119.      case MAGIC_HARP: /* Charm monsters */
  120.          consume_obj_charge(instr, TRUE);
  121.  
  122.          pline("%s very attractive music.", Tobjnam(instr, "produce"));
  123.          charm_monsters((u.ulevel - 1) / 3 + 1);
  124.          exercise(A_DEX, TRUE);
  125.          break;
  126.      case WOODEN_HARP: /* May calm Nymph */
  127.          do_spec &= (rn2(ACURR(A_DEX)) + u.ulevel > 25);
  128.          pline("%s %s.", Yname2(instr),
  129.                do_spec ? "produces a lilting melody" : "twangs");
  130.          if (do_spec)
  131.              calm_nymphs(u.ulevel * 3);
  132.          exercise(A_DEX, TRUE);
  133.          break;
  134.      case DRUM_OF_EARTHQUAKE: /* create several pits */
  135.          consume_obj_charge(instr, TRUE);
  136.  
  137.          You("produce a heavy, thunderous rolling!");
  138.          pline_The("entire %s is shaking around you!", generic_lvl_desc());
  139.          do_earthquake((u.ulevel - 1) / 3 + 1);
  140.          /* shake up monsters in a much larger radius... */
  141.          awaken_monsters(ROWNO * COLNO);
  142.          makeknown(DRUM_OF_EARTHQUAKE);
  143.          break;
  144.      case LEATHER_DRUM: /* Awaken monsters */
  145.          You("beat a deafening row!");
  146.          awaken_monsters(u.ulevel * 40);
  147.          incr_itimeout(&HDeaf, rn1(20, 30));
  148.          exercise(A_WIS, FALSE);
  149.          context.botl = TRUE;
  150.          break;
  151.      default:
  152.          impossible("What a weird instrument (%d)!", instr->otyp);
  153.          return 0;
  154.      }
  155.      return 2; /* That takes time */
  156.  }
  157.  

do_play_instrument

  1.  /*
  2.   * So you want music...
  3.   */
  4.  int
  5.  do_play_instrument(instr)
  6.  struct obj *instr;
  7.  {
  8.      char buf[BUFSZ] = DUMMY, c = 'y';
  9.      char *s;
  10.      int x, y;
  11.      boolean ok;
  12.  
  13.      if (Underwater) {
  14.          You_cant("play music underwater!");
  15.          return 0;
  16.      } else if ((instr->otyp == WOODEN_FLUTE || instr->otyp == MAGIC_FLUTE
  17.                  || instr->otyp == TOOLED_HORN || instr->otyp == FROST_HORN
  18.                  || instr->otyp == FIRE_HORN || instr->otyp == BUGLE)
  19.                 && !can_blow(&youmonst)) {
  20.          You("are incapable of playing %s.", the(distant_name(instr, xname)));
  21.          return 0;
  22.      }
  23.      if (instr->otyp != LEATHER_DRUM && instr->otyp != DRUM_OF_EARTHQUAKE
  24.          && !(Stunned || Confusion || Hallucination)) {
  25.          c = ynq("Improvise?");
  26.          if (c == 'q')
  27.              goto nevermind;
  28.      }
  29.  
  30.      if (c == 'n') {
  31.          if (u.uevent.uheard_tune == 2)
  32.              c = ynq("Play the passtune?");
  33.          if (c == 'q') {
  34.              goto nevermind;
  35.          } else if (c == 'y') {
  36.              Strcpy(buf, tune);
  37.          } else {
  38.              getlin("What tune are you playing? [5 notes, A-G]", buf);
  39.              (void) mungspaces(buf);
  40.              if (*buf == '\033')
  41.                  goto nevermind;
  42.  
  43.              /* convert to uppercase and change any "H" to the expected "B" */
  44.              for (s = buf; *s; s++) {
  45.  #ifndef AMIGA
  46.                  *s = highc(*s);
  47.  #else
  48.                  /* The AMIGA supports two octaves of notes */
  49.                  if (*s == 'h')
  50.                      *s = 'b';
  51.  #endif
  52.                  if (*s == 'H')
  53.                      *s = 'B';
  54.              }
  55.          }
  56.          You("extract a strange sound from %s!", the(xname(instr)));
  57.  #ifdef UNIX386MUSIC
  58.          /* if user is at the console, play through the console speaker */
  59.          if (atconsole())
  60.              speaker(instr, buf);
  61.  #endif
  62.  #ifdef VPIX_MUSIC
  63.          if (sco_flag_console)
  64.              speaker(instr, buf);
  65.  #endif
  66.  #ifdef MAC
  67.          mac_speaker(instr, buf);
  68.  #endif
  69.  #ifdef PCMUSIC
  70.          pc_speaker(instr, buf);
  71.  #endif
  72.  #ifdef AMIGA
  73.          {
  74.              char nbuf[20];
  75.              int i;
  76.  
  77.              for (i = 0; buf[i] && i < 5; ++i) {
  78.                  nbuf[i * 2] = buf[i];
  79.                  nbuf[(i * 2) + 1] = 'h';
  80.              }
  81.              nbuf[i * 2] = 0;
  82.              amii_speaker(instr, nbuf, AMII_OKAY_VOLUME);
  83.          }
  84.  #endif
  85.          /* Check if there was the Stronghold drawbridge near
  86.           * and if the tune conforms to what we're waiting for.
  87.           */
  88.          if (Is_stronghold(&u.uz)) {
  89.              exercise(A_WIS, TRUE); /* just for trying */
  90.              if (!strcmp(buf, tune)) {
  91.                  /* Search for the drawbridge */
  92.                  for (y = u.uy - 1; y <= u.uy + 1; y++)
  93.                      for (x = u.ux - 1; x <= u.ux + 1; x++)
  94.                          if (isok(x, y))
  95.                              if (find_drawbridge(&x, &y)) {
  96.                                  u.uevent.uheard_tune =
  97.                                      2; /* tune now fully known */
  98.                                  if (levl[x][y].typ == DRAWBRIDGE_DOWN)
  99.                                      close_drawbridge(x, y);
  100.                                  else
  101.                                      open_drawbridge(x, y);
  102.                                  return 1;
  103.                              }
  104.              } else if (!Deaf) {
  105.                  if (u.uevent.uheard_tune < 1)
  106.                      u.uevent.uheard_tune = 1;
  107.                  /* Okay, it wasn't the right tune, but perhaps
  108.                   * we can give the player some hints like in the
  109.                   * Mastermind game */
  110.                  ok = FALSE;
  111.                  for (y = u.uy - 1; y <= u.uy + 1 && !ok; y++)
  112.                      for (x = u.ux - 1; x <= u.ux + 1 && !ok; x++)
  113.                          if (isok(x, y))
  114.                              if (IS_DRAWBRIDGE(levl[x][y].typ)
  115.                                  || is_drawbridge_wall(x, y) >= 0)
  116.                                  ok = TRUE;
  117.                  if (ok) { /* There is a drawbridge near */
  118.                      int tumblers, gears;
  119.                      boolean matched[5];
  120.  
  121.                      tumblers = gears = 0;
  122.                      for (x = 0; x < 5; x++)
  123.                          matched[x] = FALSE;
  124.  
  125.                      for (x = 0; x < (int) strlen(buf); x++)
  126.                          if (x < 5) {
  127.                              if (buf[x] == tune[x]) {
  128.                                  gears++;
  129.                                  matched[x] = TRUE;
  130.                              } else
  131.                                  for (y = 0; y < 5; y++)
  132.                                      if (!matched[y] && buf[x] == tune[y]
  133.                                          && buf[y] != tune[y]) {
  134.                                          tumblers++;
  135.                                          matched[y] = TRUE;
  136.                                          break;
  137.                                      }
  138.                          }
  139.                      if (tumblers)
  140.                          if (gears)
  141.                              You_hear("%d tumbler%s click and %d gear%s turn.",
  142.                                       tumblers, plur(tumblers), gears,
  143.                                       plur(gears));
  144.                          else
  145.                              You_hear("%d tumbler%s click.", tumblers,
  146.                                       plur(tumblers));
  147.                      else if (gears) {
  148.                          You_hear("%d gear%s turn.", gears, plur(gears));
  149.                          /* could only get `gears == 5' by playing five
  150.                             correct notes followed by excess; otherwise,
  151.                             tune would have matched above */
  152.                          if (gears == 5)
  153.                              u.uevent.uheard_tune = 2;
  154.                      }
  155.                  }
  156.              }
  157.          }
  158.          return 1;
  159.      } else
  160.          return do_improvisation(instr);
  161.  
  162.  nevermind:
  163.      pline1(Never_mind);
  164.      return 0;
  165.  }
  166.  
  167.  #ifdef UNIX386MUSIC

atconsole

  1.  /*
  2.   * Play audible music on the machine's speaker if appropriate.
  3.   */
  4.  
  5.  STATIC_OVL int
  6.  atconsole()
  7.  {
  8.      /*
  9.       * Kluge alert: This code assumes that your [34]86 has no X terminals
  10.       * attached and that the console tty type is AT386 (this is always true
  11.       * under AT&T UNIX for these boxen). The theory here is that your remote
  12.       * ttys will have terminal type `ansi' or something else other than
  13.       * `AT386' or `xterm'. We'd like to do better than this, but testing
  14.       * to see if we're running on the console physical terminal is quite
  15.       * difficult given the presence of virtual consoles and other modern
  16.       * UNIX impedimenta...
  17.       */
  18.      char *termtype = nh_getenv("TERM");
  19.  
  20.      return (!strcmp(termtype, "AT386") || !strcmp(termtype, "xterm"));
  21.  }
  22.  

speaker

  1.  STATIC_OVL void
  2.  speaker(instr, buf)
  3.  struct obj *instr;
  4.  char *buf;
  5.  {
  6.      /*
  7.       * For this to work, you need to have installed the PD speaker-control
  8.       * driver for PC-compatible UNIX boxes that I (esr@snark.thyrsus.com)
  9.       * posted to comp.sources.unix in Feb 1990.  A copy should be included
  10.       * with your nethack distribution.
  11.       */
  12.      int fd;
  13.  
  14.      if ((fd = open("/dev/speaker", 1)) != -1) {
  15.          /* send a prefix to modify instrumental `timbre' */
  16.          switch (instr->otyp) {
  17.          case WOODEN_FLUTE:
  18.          case MAGIC_FLUTE:
  19.              (void) write(fd, ">ol", 1); /* up one octave & lock */
  20.              break;
  21.          case TOOLED_HORN:
  22.          case FROST_HORN:
  23.          case FIRE_HORN:
  24.              (void) write(fd, "<<ol", 2); /* drop two octaves & lock */
  25.              break;
  26.          case BUGLE:
  27.              (void) write(fd, "ol", 2); /* octave lock */
  28.              break;
  29.          case WOODEN_HARP:
  30.          case MAGIC_HARP:
  31.              (void) write(fd, "l8mlol", 4); /* fast, legato, octave lock */
  32.              break;
  33.          }
  34.          (void) write(fd, buf, strlen(buf));
  35.          (void) nhclose(fd);
  36.      }
  37.  }
  38.  #endif /* UNIX386MUSIC */
  39.  
  40.  #ifdef VPIX_MUSIC
  41.  
  42.  #if 0
  43.  #include <sys/types.h>
  44.  #include <sys/console.h>
  45.  #include <sys/vtkd.h>
  46.  #else
  47.  #define KIOC ('K' << 8)
  48.  #define KDMKTONE (KIOC | 8)
  49.  #endif
  50.  
  51.  #define noDEBUG
  52.  

tone

  1.  /* emit tone of frequency hz for given number of ticks */
  2.  STATIC_OVL void
  3.  tone(hz, ticks)
  4.  unsigned int hz, ticks;
  5.  {
  6.      ioctl(0, KDMKTONE, hz | ((ticks * 10) << 16));
  7.  #ifdef DEBUG
  8.      printf("TONE: %6d %6d\n", hz, ticks * 10);
  9.  #endif
  10.      nap(ticks * 10);
  11.  }
  12.  

rest

  1.  /* rest for given number of ticks */
  2.  STATIC_OVL void
  3.  rest(ticks)
  4.  int ticks;
  5.  {
  6.      nap(ticks * 10);
  7.  #ifdef DEBUG
  8.      printf("REST:        %6d\n", ticks * 10);
  9.  #endif
  10.  }
  11.  
  12.  #include "interp.c" /* from snd86unx.shr */
  13.  

speaker

  1.  STATIC_OVL void
  2.  speaker(instr, buf)
  3.  struct obj *instr;
  4.  char *buf;
  5.  {
  6.      /* emit a prefix to modify instrumental `timbre' */
  7.      playinit();
  8.      switch (instr->otyp) {
  9.      case WOODEN_FLUTE:
  10.      case MAGIC_FLUTE:
  11.          playstring(">ol", 1); /* up one octave & lock */
  12.          break;
  13.      case TOOLED_HORN:
  14.      case FROST_HORN:
  15.      case FIRE_HORN:
  16.          playstring("<<ol", 2); /* drop two octaves & lock */
  17.          break;
  18.      case BUGLE:
  19.          playstring("ol", 2); /* octave lock */
  20.          break;
  21.      case WOODEN_HARP:
  22.      case MAGIC_HARP:
  23.          playstring("l8mlol", 4); /* fast, legato, octave lock */
  24.          break;
  25.      }
  26.      playstring(buf, strlen(buf));
  27.  }
  28.  
  29.  #ifdef VPIX_DEBUG
  30.  main(argc, argv)
  31.  int argc;
  32.  char *argv[];
  33.  {
  34.      if (argc == 2) {
  35.          playinit();
  36.          playstring(argv[1], strlen(argv[1]));
  37.      }
  38.  }
  39.  #endif
  40.  #endif /* VPIX_MUSIC */
  41.  
  42.  /*music.c*/