Source:NetHack 3.6.0/src/music.c

From NetHackWiki
(Redirected from Music.c)
Jump to: navigation, search

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

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.

Top of file

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

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.                  monflee(mtmp, 0, FALSE, TRUE);
  26.          }
  27.      }
  28.  }
  29.  

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); /* 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.                  /* Falls into next case */
  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.                                  if ((mtmp->mhp -=
  124.                                       rnd(m_already_trapped ? 4 : 6)) <= 0) {
  125.                                      if (!cansee(x, y))
  126.                                          pline("It is destroyed!");
  127.                                      else {
  128.                                          You("destroy %s!",
  129.                                              mtmp->mtame
  130.                                                  ? x_monnam(
  131.                                                        mtmp, ARTICLE_THE,
  132.                                                        "poor",
  133.                                                        (has_mname(mtmp))
  134.                                                            ? SUPPRESS_SADDLE
  135.                                                            : 0,
  136.                                                        FALSE)
  137.                                                  : mon_nam(mtmp));
  138.                                      }
  139.                                      xkilled(mtmp, 0);
  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.  

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

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

atconsole

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

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.  
  53.  /* emit tone of frequency hz for given number of ticks */
  54.  STATIC_OVL void
  55.  tone(hz, ticks)
  56.  unsigned int hz, ticks;
  57.  {
  58.      ioctl(0, KDMKTONE, hz | ((ticks * 10) << 16));
  59.  #ifdef DEBUG
  60.      printf("TONE: %6d %6d\n", hz, ticks * 10);
  61.  #endif
  62.      nap(ticks * 10);
  63.  }
  64.  
  65.  /* rest for given number of ticks */
  66.  STATIC_OVL void
  67.  rest(ticks)
  68.  int ticks;
  69.  {
  70.      nap(ticks * 10);
  71.  #ifdef DEBUG
  72.      printf("REST:        %6d\n", ticks * 10);
  73.  #endif
  74.  }
  75.  
  76.  #include "interp.c" /* from snd86unx.shr */
  77.  
  78.  STATIC_OVL void
  79.  speaker(instr, buf)
  80.  struct obj *instr;
  81.  char *buf;
  82.  {
  83.      /* emit a prefix to modify instrumental `timbre' */
  84.      playinit();
  85.      switch (instr->otyp) {
  86.      case WOODEN_FLUTE:
  87.      case MAGIC_FLUTE:
  88.          playstring(">ol", 1); /* up one octave & lock */
  89.          break;
  90.      case TOOLED_HORN:
  91.      case FROST_HORN:
  92.      case FIRE_HORN:
  93.          playstring("<<ol", 2); /* drop two octaves & lock */
  94.          break;
  95.      case BUGLE:
  96.          playstring("ol", 2); /* octave lock */
  97.          break;
  98.      case WOODEN_HARP:
  99.      case MAGIC_HARP:
  100.          playstring("l8mlol", 4); /* fast, legato, octave lock */
  101.          break;
  102.      }
  103.      playstring(buf, strlen(buf));
  104.  }
  105.  
  106.  #ifdef VPIX_DEBUG
  107.  main(argc, argv)
  108.  int argc;
  109.  char *argv[];
  110.  {
  111.      if (argc == 2) {
  112.          playinit();
  113.          playstring(argv[1], strlen(argv[1]));
  114.      }
  115.  }
  116.  #endif
  117.  #endif /* VPIX_MUSIC */
  118.  
  119.  /*music.c*/