Source:NetHack 3.6.0/src/cmd.c

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

Below is the full text to cmd.c from the source code of NetHack 3.6.0. To link to a particular line, write [[Source:NetHack 3.6.0/src/cmd.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	cmd.c	$NHDT-Date: 1446975462 2015/11/08 09:37:42 $  $NHDT-Branch: master $:$NHDT-Revision: 1.206 $ */
  2.  /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
  3.  /* NetHack may be freely redistributed.  See license for details. */
  4.  
  5.  #include "hack.h"
  6.  #include "func_tab.h"
  7.  
  8.  #ifdef ALTMETA
  9.  STATIC_VAR boolean alt_esc = FALSE;
  10.  #endif
  11.  
  12.  struct cmd Cmd = { 0 }; /* flag.h */
  13.  
  14.  extern const char *hu_stat[];  /* hunger status from eat.c */
  15.  extern const char *enc_stat[]; /* encumbrance status from botl.c */
  16.  
  17.  #ifdef UNIX
  18.  /*
  19.   * Some systems may have getchar() return EOF for various reasons, and
  20.   * we should not quit before seeing at least NR_OF_EOFS consecutive EOFs.
  21.   */
  22.  #if defined(SYSV) || defined(DGUX) || defined(HPUX)
  23.  #define NR_OF_EOFS 20
  24.  #endif
  25.  #endif
  26.  
  27.  #define CMD_TRAVEL (char) 0x90
  28.  #define CMD_CLICKLOOK (char) 0x8F
  29.  
  30.  #ifdef DEBUG
  31.  extern int NDECL(wiz_debug_cmd_bury);
  32.  extern int NDECL(wiz_debug_cmd_traveldisplay);
  33.  #endif
  34.  
  35.  #ifdef DUMB /* stuff commented out in extern.h, but needed here */
  36.  extern int NDECL(doapply);            /**/
  37.  extern int NDECL(dorub);              /**/
  38.  extern int NDECL(dojump);             /**/
  39.  extern int NDECL(doextlist);          /**/
  40.  extern int NDECL(enter_explore_mode); /**/
  41.  extern int NDECL(dodrop);             /**/
  42.  extern int NDECL(doddrop);            /**/
  43.  extern int NDECL(dodown);             /**/
  44.  extern int NDECL(doup);               /**/
  45.  extern int NDECL(donull);             /**/
  46.  extern int NDECL(dowipe);             /**/
  47.  extern int NDECL(docallcnd);          /**/
  48.  extern int NDECL(dotakeoff);          /**/
  49.  extern int NDECL(doremring);          /**/
  50.  extern int NDECL(dowear);             /**/
  51.  extern int NDECL(doputon);            /**/
  52.  extern int NDECL(doddoremarm);        /**/
  53.  extern int NDECL(dokick);             /**/
  54.  extern int NDECL(dofire);             /**/
  55.  extern int NDECL(dothrow);            /**/
  56.  extern int NDECL(doeat);              /**/
  57.  extern int NDECL(done2);              /**/
  58.  extern int NDECL(vanquished);         /**/
  59.  extern int NDECL(doengrave);          /**/
  60.  extern int NDECL(dopickup);           /**/
  61.  extern int NDECL(ddoinv);             /**/
  62.  extern int NDECL(dotypeinv);          /**/
  63.  extern int NDECL(dolook);             /**/
  64.  extern int NDECL(doprgold);           /**/
  65.  extern int NDECL(doprwep);            /**/
  66.  extern int NDECL(doprarm);            /**/
  67.  extern int NDECL(doprring);           /**/
  68.  extern int NDECL(dopramulet);         /**/
  69.  extern int NDECL(doprtool);           /**/
  70.  extern int NDECL(dosuspend);          /**/
  71.  extern int NDECL(doforce);            /**/
  72.  extern int NDECL(doopen);             /**/
  73.  extern int NDECL(doclose);            /**/
  74.  extern int NDECL(dosh);               /**/
  75.  extern int NDECL(dodiscovered);       /**/
  76.  extern int NDECL(doclassdisco);       /**/
  77.  extern int NDECL(doset);              /**/
  78.  extern int NDECL(dotogglepickup);     /**/
  79.  extern int NDECL(dowhatis);           /**/
  80.  extern int NDECL(doquickwhatis);      /**/
  81.  extern int NDECL(dowhatdoes);         /**/
  82.  extern int NDECL(dohelp);             /**/
  83.  extern int NDECL(dohistory);          /**/
  84.  extern int NDECL(doloot);             /**/
  85.  extern int NDECL(dodrink);            /**/
  86.  extern int NDECL(dodip);              /**/
  87.  extern int NDECL(dosacrifice);        /**/
  88.  extern int NDECL(dopray);             /**/
  89.  extern int NDECL(dotip);              /**/
  90.  extern int NDECL(doturn);             /**/
  91.  extern int NDECL(doredraw);           /**/
  92.  extern int NDECL(doread);             /**/
  93.  extern int NDECL(dosave);             /**/
  94.  extern int NDECL(dosearch);           /**/
  95.  extern int NDECL(doidtrap);           /**/
  96.  extern int NDECL(dopay);              /**/
  97.  extern int NDECL(dosit);              /**/
  98.  extern int NDECL(dotalk);             /**/
  99.  extern int NDECL(docast);             /**/
  100.  extern int NDECL(dovspell);           /**/
  101.  extern int NDECL(dotele);             /**/
  102.  extern int NDECL(dountrap);           /**/
  103.  extern int NDECL(doversion);          /**/
  104.  extern int NDECL(doextversion);       /**/
  105.  extern int NDECL(doswapweapon);       /**/
  106.  extern int NDECL(dowield);            /**/
  107.  extern int NDECL(dowieldquiver);      /**/
  108.  extern int NDECL(dozap);              /**/
  109.  extern int NDECL(doorganize);         /**/
  110.  #endif                                /* DUMB */
  111.  
  112.  static int NDECL(dosuspend_core); /**/
  113.  
  114.  static int NDECL((*timed_occ_fn));
  115.  
  116.  STATIC_PTR int NDECL(doprev_message);
  117.  STATIC_PTR int NDECL(timed_occupation);
  118.  STATIC_PTR int NDECL(doextcmd);
  119.  STATIC_PTR int NDECL(domonability);
  120.  STATIC_PTR int NDECL(dooverview_or_wiz_where);
  121.  STATIC_PTR int NDECL(dotravel);
  122.  STATIC_PTR int NDECL(doterrain);
  123.  STATIC_PTR int NDECL(wiz_wish);
  124.  STATIC_PTR int NDECL(wiz_identify);
  125.  STATIC_PTR int NDECL(wiz_map);
  126.  STATIC_PTR int NDECL(wiz_genesis);
  127.  STATIC_PTR int NDECL(wiz_where);
  128.  STATIC_PTR int NDECL(wiz_detect);
  129.  STATIC_PTR int NDECL(wiz_panic);
  130.  STATIC_PTR int NDECL(wiz_polyself);
  131.  STATIC_PTR int NDECL(wiz_level_tele);
  132.  STATIC_PTR int NDECL(wiz_level_change);
  133.  STATIC_PTR int NDECL(wiz_show_seenv);
  134.  STATIC_PTR int NDECL(wiz_show_vision);
  135.  STATIC_PTR int NDECL(wiz_smell);
  136.  STATIC_PTR int NDECL(wiz_mon_polycontrol);
  137.  STATIC_PTR int NDECL(wiz_show_wmodes);
  138.  STATIC_DCL void NDECL(wiz_map_levltyp);
  139.  STATIC_DCL void NDECL(wiz_levltyp_legend);
  140.  #if defined(__BORLANDC__) && !defined(_WIN32)
  141.  extern void FDECL(show_borlandc_stats, (winid));
  142.  #endif
  143.  #ifdef DEBUG_MIGRATING_MONS
  144.  STATIC_PTR int NDECL(wiz_migrate_mons);
  145.  #endif
  146.  STATIC_DCL int FDECL(size_monst, (struct monst *));
  147.  STATIC_DCL int FDECL(size_obj, (struct obj *));
  148.  STATIC_DCL void FDECL(count_obj, (struct obj *, long *, long *,
  149.                                    BOOLEAN_P, BOOLEAN_P));
  150.  STATIC_DCL void FDECL(obj_chain, (winid, const char *, struct obj *,
  151.                                    long *, long *));
  152.  STATIC_DCL void FDECL(mon_invent_chain, (winid, const char *, struct monst *,
  153.                                           long *, long *));
  154.  STATIC_DCL void FDECL(mon_chain, (winid, const char *, struct monst *,
  155.                                    long *, long *));
  156.  STATIC_DCL void FDECL(contained, (winid, const char *, long *, long *));
  157.  STATIC_PTR int NDECL(wiz_show_stats);
  158.  STATIC_DCL boolean FDECL(accept_menu_prefix, (int NDECL((*))));
  159.  #ifdef PORT_DEBUG
  160.  STATIC_DCL int NDECL(wiz_port_debug);
  161.  #endif
  162.  STATIC_PTR int NDECL(wiz_rumor_check);
  163.  STATIC_DCL char FDECL(cmd_from_func, (int NDECL((*))));
  164.  STATIC_PTR int NDECL(doattributes);
  165.  STATIC_PTR int NDECL(doconduct); /**/
  166.  
  167.  STATIC_DCL void FDECL(enlght_line, (const char *, const char *, const char *,
  168.                                      const char *));
  169.  STATIC_DCL char *FDECL(enlght_combatinc, (const char *, int, int, char *));
  170.  STATIC_DCL void FDECL(enlght_halfdmg, (int, int));
  171.  STATIC_DCL boolean NDECL(walking_on_water);
  172.  STATIC_DCL boolean FDECL(cause_known, (int));
  173.  STATIC_DCL char *FDECL(attrval, (int, int, char *));
  174.  STATIC_DCL void FDECL(background_enlightenment, (int, int));
  175.  STATIC_DCL void FDECL(characteristics_enlightenment, (int, int));
  176.  STATIC_DCL void FDECL(one_characteristic, (int, int, int));
  177.  STATIC_DCL void FDECL(status_enlightenment, (int, int));
  178.  STATIC_DCL void FDECL(attributes_enlightenment, (int, int));
  179.  
  180.  static const char *readchar_queue = "";
  181.  static coord clicklook_cc;
  182.  
  183.  STATIC_DCL char *NDECL(parse);
  184.  STATIC_DCL boolean FDECL(help_dir, (CHAR_P, const char *));
  185.  

doprev_message

  1.  STATIC_PTR int
  2.  doprev_message(VOID_ARGS)
  3.  {
  4.      return nh_doprev_message();
  5.  }
  6.  

timed_occupation

  1.  /* Count down by decrementing multi */
  2.  STATIC_PTR int
  3.  timed_occupation(VOID_ARGS)
  4.  {
  5.      (*timed_occ_fn)();
  6.      if (multi > 0)
  7.          multi--;
  8.      return multi > 0;
  9.  }
  10.  

reset_occuptations

  1.  /* If you have moved since initially setting some occupations, they
  2.   * now shouldn't be able to restart.
  3.   *
  4.   * The basic rule is that if you are carrying it, you can continue
  5.   * since it is with you.  If you are acting on something at a distance,
  6.   * your orientation to it must have changed when you moved.
  7.   *
  8.   * The exception to this is taking off items, since they can be taken
  9.   * off in a number of ways in the intervening time, screwing up ordering.
  10.   *
  11.   *      Currently:      Take off all armor.
  12.   *                      Picking Locks / Forcing Chests.
  13.   *                      Setting traps.
  14.   */
  15.  void
  16.  reset_occupations()
  17.  {
  18.      reset_remarm();
  19.      reset_pick();
  20.      reset_trapset();
  21.  }
  22.  

set_occupation

  1.  /* If a time is given, use it to timeout this function, otherwise the
  2.   * function times out by its own means.
  3.   */
  4.  void
  5.  set_occupation(fn, txt, xtime)
  6.  int NDECL((*fn));
  7.  const char *txt;
  8.  int xtime;
  9.  {
  10.      if (xtime) {
  11.          occupation = timed_occupation;
  12.          timed_occ_fn = fn;
  13.      } else
  14.          occupation = fn;
  15.      occtxt = txt;
  16.      occtime = 0;
  17.      return;
  18.  }
  19.  

popch

  1.  STATIC_DCL char NDECL(popch);
  2.  
  3.  /* Provide a means to redo the last command.  The flag `in_doagain' is set
  4.   * to true while redoing the command.  This flag is tested in commands that
  5.   * require additional input (like `throw' which requires a thing and a
  6.   * direction), and the input prompt is not shown.  Also, while in_doagain is
  7.   * TRUE, no keystrokes can be saved into the saveq.
  8.   */
  9.  #define BSIZE 20
  10.  static char pushq[BSIZE], saveq[BSIZE];
  11.  static NEARDATA int phead, ptail, shead, stail;
  12.  
  13.  STATIC_OVL char
  14.  popch()
  15.  {
  16.      /* If occupied, return '\0', letting tgetch know a character should
  17.       * be read from the keyboard.  If the character read is not the
  18.       * ABORT character (as checked in pcmain.c), that character will be
  19.       * pushed back on the pushq.
  20.       */
  21.      if (occupation)
  22.          return '\0';
  23.      if (in_doagain)
  24.          return (char) ((shead != stail) ? saveq[stail++] : '\0');
  25.      else
  26.          return (char) ((phead != ptail) ? pushq[ptail++] : '\0');
  27.  }
  28.  

pgetchar

  1.  char
  2.  pgetchar() /* courtesy of aeb@cwi.nl */
  3.  {
  4.      register int ch;
  5.  
  6.      if (!(ch = popch()))
  7.          ch = nhgetch();
  8.      return (char) ch;
  9.  }
  10.  

pushch

  1.  /* A ch == 0 resets the pushq */
  2.  void
  3.  pushch(ch)
  4.  char ch;
  5.  {
  6.      if (!ch)
  7.          phead = ptail = 0;
  8.      if (phead < BSIZE)
  9.          pushq[phead++] = ch;
  10.      return;
  11.  }
  12.  

savech

  1.  /* A ch == 0 resets the saveq.  Only save keystrokes when not
  2.   * replaying a previous command.
  3.   */
  4.  void
  5.  savech(ch)
  6.  char ch;
  7.  {
  8.      if (!in_doagain) {
  9.          if (!ch)
  10.              phead = ptail = shead = stail = 0;
  11.          else if (shead < BSIZE)
  12.              saveq[shead++] = ch;
  13.      }
  14.      return;
  15.  }
  16.  

doextcmd

  1.  /* here after # - now read a full-word command */
  2.  STATIC_PTR int
  3.  doextcmd(VOID_ARGS)
  4.  {
  5.      int idx, retval;
  6.      int NDECL((*func));
  7.  
  8.      /* keep repeating until we don't run help or quit */
  9.      do {
  10.          idx = get_ext_cmd();
  11.          if (idx < 0)
  12.              return 0; /* quit */
  13.  
  14.          func = extcmdlist[idx].ef_funct;
  15.          if (iflags.menu_requested && !accept_menu_prefix(func)) {
  16.              pline("'m' prefix has no effect for this command.");
  17.              iflags.menu_requested = FALSE;
  18.          }
  19.          retval = (*func)();
  20.      } while (func == doextlist);
  21.  
  22.      return retval;
  23.  }
  24.  

doextlist

  1.  /* here after #? - now list all full-word commands */
  2.  int
  3.  doextlist(VOID_ARGS)
  4.  {
  5.      register const struct ext_func_tab *efp;
  6.      char buf[BUFSZ];
  7.      winid datawin;
  8.  
  9.      datawin = create_nhwindow(NHW_TEXT);
  10.      putstr(datawin, 0, "");
  11.      putstr(datawin, 0, "            Extended Commands List");
  12.      putstr(datawin, 0, "");
  13.      putstr(datawin, 0, "    Press '#', then type:");
  14.      putstr(datawin, 0, "");
  15.  
  16.      for (efp = extcmdlist; efp->ef_txt; efp++) {
  17.          Sprintf(buf, "    %-15s - %s.", efp->ef_txt, efp->ef_desc);
  18.          putstr(datawin, 0, buf);
  19.      }
  20.      display_nhwindow(datawin, FALSE);
  21.      destroy_nhwindow(datawin);
  22.      return 0;
  23.  }
  24.  

extcmd_via_menu

  1.  #ifdef TTY_GRAPHICS
  2.  #define MAX_EXT_CMD 50 /* Change if we ever have > 50 ext cmds */
  3.  
  4.  /*
  5.   * This is currently used only by the tty port and is
  6.   * controlled via runtime option 'extmenu'.
  7.   * ``# ?'' is counted towards the limit of the number of commands,
  8.   * so we actually support MAX_EXT_CMD-1 "real" extended commands.
  9.   *
  10.   * Here after # - now show pick-list of possible commands.
  11.   */
  12.  int
  13.  extcmd_via_menu()
  14.  {
  15.      const struct ext_func_tab *efp;
  16.      menu_item *pick_list = (menu_item *) 0;
  17.      winid win;
  18.      anything any;
  19.      const struct ext_func_tab *choices[MAX_EXT_CMD + 1];
  20.      char buf[BUFSZ];
  21.      char cbuf[QBUFSZ], prompt[QBUFSZ], fmtstr[20];
  22.      int i, n, nchoices, acount;
  23.      int ret, biggest;
  24.      int accelerator, prevaccelerator;
  25.      int matchlevel = 0;
  26.  
  27.      ret = 0;
  28.      cbuf[0] = '\0';
  29.      biggest = 0;
  30.      while (!ret) {
  31.          i = n = 0;
  32.          any = zeroany;
  33.          /* populate choices */
  34.          for (efp = extcmdlist; efp->ef_txt; efp++) {
  35.              if (!matchlevel || !strncmp(efp->ef_txt, cbuf, matchlevel)) {
  36.                  choices[i] = efp;
  37.                  if ((int) strlen(efp->ef_desc) > biggest) {
  38.                      biggest = strlen(efp->ef_desc);
  39.                      Sprintf(fmtstr, "%%-%ds", biggest + 15);
  40.                  }
  41.                  if (++i > MAX_EXT_CMD) {
  42.  #if defined(BETA)
  43.                      impossible(
  44.        "Exceeded %d extended commands in doextcmd() menu; 'extmenu' disabled.",
  45.                                 MAX_EXT_CMD);
  46.  #endif /* BETA */
  47.                      iflags.extmenu = 0;
  48.                      return -1;
  49.                  }
  50.              }
  51.          }
  52.          choices[i] = (struct ext_func_tab *) 0;
  53.          nchoices = i;
  54.          /* if we're down to one, we have our selection so get out of here */
  55.          if (nchoices == 1) {
  56.              for (i = 0; extcmdlist[i].ef_txt != (char *) 0; i++)
  57.                  if (!strncmpi(extcmdlist[i].ef_txt, cbuf, matchlevel)) {
  58.                      ret = i;
  59.                      break;
  60.                  }
  61.              break;
  62.          }
  63.  
  64.          /* otherwise... */
  65.          win = create_nhwindow(NHW_MENU);
  66.          start_menu(win);
  67.          accelerator = prevaccelerator = 0;
  68.          acount = 0;
  69.          for (i = 0; choices[i]; ++i) {
  70.              accelerator = choices[i]->ef_txt[matchlevel];
  71.              if (accelerator != prevaccelerator || nchoices < (ROWNO - 3)) {
  72.                  if (acount) {
  73.                      /* flush extended cmds for that letter already in buf */
  74.                      Sprintf(buf, fmtstr, prompt);
  75.                      any.a_char = prevaccelerator;
  76.                      add_menu(win, NO_GLYPH, &any, any.a_char, 0, ATR_NONE,
  77.                               buf, FALSE);
  78.                      acount = 0;
  79.                  }
  80.              }
  81.              prevaccelerator = accelerator;
  82.              if (!acount || nchoices < (ROWNO - 3)) {
  83.                  Sprintf(prompt, "%s [%s]", choices[i]->ef_txt,
  84.                          choices[i]->ef_desc);
  85.              } else if (acount == 1) {
  86.                  Sprintf(prompt, "%s or %s", choices[i - 1]->ef_txt,
  87.                          choices[i]->ef_txt);
  88.              } else {
  89.                  Strcat(prompt, " or ");
  90.                  Strcat(prompt, choices[i]->ef_txt);
  91.              }
  92.              ++acount;
  93.          }
  94.          if (acount) {
  95.              /* flush buf */
  96.              Sprintf(buf, fmtstr, prompt);
  97.              any.a_char = prevaccelerator;
  98.              add_menu(win, NO_GLYPH, &any, any.a_char, 0, ATR_NONE, buf,
  99.                       FALSE);
  100.          }
  101.          Sprintf(prompt, "Extended Command: %s", cbuf);
  102.          end_menu(win, prompt);
  103.          n = select_menu(win, PICK_ONE, &pick_list);
  104.          destroy_nhwindow(win);
  105.          if (n == 1) {
  106.              if (matchlevel > (QBUFSZ - 2)) {
  107.                  free((genericptr_t) pick_list);
  108.  #if defined(BETA)
  109.                  impossible("Too many chars (%d) entered in extcmd_via_menu()",
  110.                             matchlevel);
  111.  #endif
  112.                  ret = -1;
  113.              } else {
  114.                  cbuf[matchlevel++] = pick_list[0].item.a_char;
  115.                  cbuf[matchlevel] = '\0';
  116.                  free((genericptr_t) pick_list);
  117.              }
  118.          } else {
  119.              if (matchlevel) {
  120.                  ret = 0;
  121.                  matchlevel = 0;
  122.              } else
  123.                  ret = -1;
  124.          }
  125.      }
  126.      return ret;
  127.  }
  128.  #endif /* TTY_GRAPHICS */
  129.  

domonability

  1.  /* #monster command - use special monster ability while polymorphed */
  2.  STATIC_PTR int
  3.  domonability(VOID_ARGS)
  4.  {
  5.      if (can_breathe(youmonst.data))
  6.          return dobreathe();
  7.      else if (attacktype(youmonst.data, AT_SPIT))
  8.          return dospit();
  9.      else if (youmonst.data->mlet == S_NYMPH)
  10.          return doremove();
  11.      else if (attacktype(youmonst.data, AT_GAZE))
  12.          return dogaze();
  13.      else if (is_were(youmonst.data))
  14.          return dosummon();
  15.      else if (webmaker(youmonst.data))
  16.          return dospinweb();
  17.      else if (is_hider(youmonst.data))
  18.          return dohide();
  19.      else if (is_mind_flayer(youmonst.data))
  20.          return domindblast();
  21.      else if (u.umonnum == PM_GREMLIN) {
  22.          if (IS_FOUNTAIN(levl[u.ux][u.uy].typ)) {
  23.              if (split_mon(&youmonst, (struct monst *) 0))
  24.                  dryup(u.ux, u.uy, TRUE);
  25.          } else
  26.              There("is no fountain here.");
  27.      } else if (is_unicorn(youmonst.data)) {
  28.          use_unicorn_horn((struct obj *) 0);
  29.          return 1;
  30.      } else if (youmonst.data->msound == MS_SHRIEK) {
  31.          You("shriek.");
  32.          if (u.uburied)
  33.              pline("Unfortunately sound does not carry well through rock.");
  34.          else
  35.              aggravate();
  36.      } else if (youmonst.data->mlet == S_VAMPIRE)
  37.          return dopoly();
  38.      else if (Upolyd)
  39.          pline("Any special ability you may have is purely reflexive.");
  40.      else
  41.          You("don't have a special ability in your normal form!");
  42.      return 0;
  43.  }
  44.  

enter_explore_mode

  1.  int
  2.  enter_explore_mode(VOID_ARGS)
  3.  {
  4.      if (wizard) {
  5.          You("are in debug mode.");
  6.      } else if (discover) {
  7.          You("are already in explore mode.");
  8.      } else {
  9.  #ifdef SYSCF
  10.  #if defined(UNIX)
  11.          if (!sysopt.explorers || !sysopt.explorers[0]
  12.              || !check_user_string(sysopt.explorers)) {
  13.              You("cannot access explore mode.");
  14.              return 0;
  15.          }
  16.  #endif
  17.  #endif
  18.          pline(
  19.          "Beware!  From explore mode there will be no return to normal game.");
  20.          if (paranoid_query(ParanoidQuit,
  21.                             "Do you want to enter explore mode?")) {
  22.              clear_nhwindow(WIN_MESSAGE);
  23.              You("are now in non-scoring explore mode.");
  24.              discover = TRUE;
  25.          } else {
  26.              clear_nhwindow(WIN_MESSAGE);
  27.              pline("Resuming normal game.");
  28.          }
  29.      }
  30.      return 0;
  31.  }
  32.  

dooverview_or_wiz_where

  1.  STATIC_PTR int
  2.  dooverview_or_wiz_where(VOID_ARGS)
  3.  {
  4.      if (wizard)
  5.          return wiz_where();
  6.      else
  7.          dooverview();
  8.      return 0;
  9.  }
  10.  

wiz_wish

  1.  /* ^W command - wish for something */
  2.  STATIC_PTR int
  3.  wiz_wish(VOID_ARGS) /* Unlimited wishes for debug mode by Paul Polderman */
  4.  {
  5.      if (wizard) {
  6.          boolean save_verbose = flags.verbose;
  7.  
  8.          flags.verbose = FALSE;
  9.          makewish();
  10.          flags.verbose = save_verbose;
  11.          (void) encumber_msg();
  12.      } else
  13.          pline("Unavailable command '%s'.",
  14.                visctrl((int) cmd_from_func(wiz_wish)));
  15.      return 0;
  16.  }
  17.  

wiz_identify

  1.  /* ^I command - reveal and optionally identify hero's inventory */
  2.  STATIC_PTR int
  3.  wiz_identify(VOID_ARGS)
  4.  {
  5.      if (wizard) {
  6.          iflags.override_ID = (int) cmd_from_func(wiz_identify);
  7.          if (display_inventory((char *) 0, TRUE) == -1)
  8.              identify_pack(0, FALSE);
  9.          iflags.override_ID = 0;
  10.      } else
  11.          pline("Unavailable command '%s'.",
  12.                visctrl((int) cmd_from_func(wiz_identify)));
  13.      return 0;
  14.  }
  15.  

wiz_map

  1.  /* ^F command - reveal the level map and any traps on it */
  2.  STATIC_PTR int
  3.  wiz_map(VOID_ARGS)
  4.  {
  5.      if (wizard) {
  6.          struct trap *t;
  7.          long save_Hconf = HConfusion, save_Hhallu = HHallucination;
  8.  
  9.          HConfusion = HHallucination = 0L;
  10.          for (t = ftrap; t != 0; t = t->ntrap) {
  11.              t->tseen = 1;
  12.              map_trap(t, TRUE);
  13.          }
  14.          do_mapping();
  15.          HConfusion = save_Hconf;
  16.          HHallucination = save_Hhallu;
  17.      } else
  18.          pline("Unavailable command '%s'.",
  19.                visctrl((int) cmd_from_func(wiz_map)));
  20.      return 0;
  21.  }
  22.  

wiz_genesis

  1.  /* ^G command - generate monster(s); a count prefix will be honored */
  2.  STATIC_PTR int
  3.  wiz_genesis(VOID_ARGS)
  4.  {
  5.      if (wizard)
  6.          (void) create_particular();
  7.      else
  8.          pline("Unavailable command '%s'.",
  9.                visctrl((int) cmd_from_func(wiz_genesis)));
  10.      return 0;
  11.  }
  12.  

wiz_where

  1.  /* ^O command - display dungeon layout */
  2.  STATIC_PTR int
  3.  wiz_where(VOID_ARGS)
  4.  {
  5.      if (wizard)
  6.          (void) print_dungeon(FALSE, (schar *) 0, (xchar *) 0);
  7.      else
  8.          pline("Unavailable command '%s'.",
  9.                visctrl((int) cmd_from_func(wiz_where)));
  10.      return 0;
  11.  }
  12.  

wiz_detect

  1.  /* ^E command - detect unseen (secret doors, traps, hidden monsters) */
  2.  STATIC_PTR int
  3.  wiz_detect(VOID_ARGS)
  4.  {
  5.      if (wizard)
  6.          (void) findit();
  7.      else
  8.          pline("Unavailable command '%s'.",
  9.                visctrl((int) cmd_from_func(wiz_detect)));
  10.      return 0;
  11.  }
  12.  

wiz_level_tele

  1.  /* ^V command - level teleport */
  2.  STATIC_PTR int
  3.  wiz_level_tele(VOID_ARGS)
  4.  {
  5.      if (wizard)
  6.          level_tele();
  7.      else
  8.          pline("Unavailable command '%s'.",
  9.                visctrl((int) cmd_from_func(wiz_level_tele)));
  10.      return 0;
  11.  }
  12.  

wiz_mon_polycontrol

  1.  /* #monpolycontrol command - choose new form for shapechangers, polymorphees */
  2.  STATIC_PTR int
  3.  wiz_mon_polycontrol(VOID_ARGS)
  4.  {
  5.      iflags.mon_polycontrol = !iflags.mon_polycontrol;
  6.      pline("Monster polymorph control is %s.",
  7.            iflags.mon_polycontrol ? "on" : "off");
  8.      return 0;
  9.  }
  10.  

wiz_level_change

  1.  /* #levelchange command - adjust hero's experience level */
  2.  STATIC_PTR int
  3.  wiz_level_change(VOID_ARGS)
  4.  {
  5.      char buf[BUFSZ];
  6.      int newlevel;
  7.      int ret;
  8.  
  9.      getlin("To what experience level do you want to be set?", buf);
  10.      (void) mungspaces(buf);
  11.      if (buf[0] == '\033' || buf[0] == '\0')
  12.          ret = 0;
  13.      else
  14.          ret = sscanf(buf, "%d", &newlevel);
  15.  
  16.      if (ret != 1) {
  17.          pline1(Never_mind);
  18.          return 0;
  19.      }
  20.      if (newlevel == u.ulevel) {
  21.          You("are already that experienced.");
  22.      } else if (newlevel < u.ulevel) {
  23.          if (u.ulevel == 1) {
  24.              You("are already as inexperienced as you can get.");
  25.              return 0;
  26.          }
  27.          if (newlevel < 1)
  28.              newlevel = 1;
  29.          while (u.ulevel > newlevel)
  30.              losexp("#levelchange");
  31.      } else {
  32.          if (u.ulevel >= MAXULEV) {
  33.              You("are already as experienced as you can get.");
  34.              return 0;
  35.          }
  36.          if (newlevel > MAXULEV)
  37.              newlevel = MAXULEV;
  38.          while (u.ulevel < newlevel)
  39.              pluslvl(FALSE);
  40.      }
  41.      u.ulevelmax = u.ulevel;
  42.      return 0;
  43.  }
  44.  

wiz_panic

  1.  /* #panic command - test program's panic handling */
  2.  STATIC_PTR int
  3.  wiz_panic(VOID_ARGS)
  4.  {
  5.      if (yn("Do you want to call panic() and end your game?") == 'y')
  6.          panic("Crash test.");
  7.      return 0;
  8.  }
  9.  

wiz_polyself

  1.  /* #polyself command - change hero's form */
  2.  STATIC_PTR int
  3.  wiz_polyself(VOID_ARGS)
  4.  {
  5.      polyself(1);
  6.      return 0;
  7.  }
  8.  

wiz_show_seenv

  1.  /* #seenv command */
  2.  STATIC_PTR int
  3.  wiz_show_seenv(VOID_ARGS)
  4.  {
  5.      winid win;
  6.      int x, y, v, startx, stopx, curx;
  7.      char row[COLNO + 1];
  8.  
  9.      win = create_nhwindow(NHW_TEXT);
  10.      /*
  11.       * Each seenv description takes up 2 characters, so center
  12.       * the seenv display around the hero.
  13.       */
  14.      startx = max(1, u.ux - (COLNO / 4));
  15.      stopx = min(startx + (COLNO / 2), COLNO);
  16.      /* can't have a line exactly 80 chars long */
  17.      if (stopx - startx == COLNO / 2)
  18.          startx++;
  19.  
  20.      for (y = 0; y < ROWNO; y++) {
  21.          for (x = startx, curx = 0; x < stopx; x++, curx += 2) {
  22.              if (x == u.ux && y == u.uy) {
  23.                  row[curx] = row[curx + 1] = '@';
  24.              } else {
  25.                  v = levl[x][y].seenv & 0xff;
  26.                  if (v == 0)
  27.                      row[curx] = row[curx + 1] = ' ';
  28.                  else
  29.                      Sprintf(&row[curx], "%02x", v);
  30.              }
  31.          }
  32.          /* remove trailing spaces */
  33.          for (x = curx - 1; x >= 0; x--)
  34.              if (row[x] != ' ')
  35.                  break;
  36.          row[x + 1] = '\0';
  37.  
  38.          putstr(win, 0, row);
  39.      }
  40.      display_nhwindow(win, TRUE);
  41.      destroy_nhwindow(win);
  42.      return 0;
  43.  }
  44.  

wiz_show_vision

  1.  /* #vision command */
  2.  STATIC_PTR int
  3.  wiz_show_vision(VOID_ARGS)
  4.  {
  5.      winid win;
  6.      int x, y, v;
  7.      char row[COLNO + 1];
  8.  
  9.      win = create_nhwindow(NHW_TEXT);
  10.      Sprintf(row, "Flags: 0x%x could see, 0x%x in sight, 0x%x temp lit",
  11.              COULD_SEE, IN_SIGHT, TEMP_LIT);
  12.      putstr(win, 0, row);
  13.      putstr(win, 0, "");
  14.      for (y = 0; y < ROWNO; y++) {
  15.          for (x = 1; x < COLNO; x++) {
  16.              if (x == u.ux && y == u.uy)
  17.                  row[x] = '@';
  18.              else {
  19.                  v = viz_array[y][x]; /* data access should be hidden */
  20.                  if (v == 0)
  21.                      row[x] = ' ';
  22.                  else
  23.                      row[x] = '0' + viz_array[y][x];
  24.              }
  25.          }
  26.          /* remove trailing spaces */
  27.          for (x = COLNO - 1; x >= 1; x--)
  28.              if (row[x] != ' ')
  29.                  break;
  30.          row[x + 1] = '\0';
  31.  
  32.          putstr(win, 0, &row[1]);
  33.      }
  34.      display_nhwindow(win, TRUE);
  35.      destroy_nhwindow(win);
  36.      return 0;
  37.  }
  38.  

wiz_show_wmodes

  1.  /* #wmode command */
  2.  STATIC_PTR int
  3.  wiz_show_wmodes(VOID_ARGS)
  4.  {
  5.      winid win;
  6.      int x, y;
  7.      char row[COLNO + 1];
  8.      struct rm *lev;
  9.      boolean istty = !strcmp(windowprocs.name, "tty");
  10.  
  11.      win = create_nhwindow(NHW_TEXT);
  12.      if (istty)
  13.          putstr(win, 0, ""); /* tty only: blank top line */
  14.      for (y = 0; y < ROWNO; y++) {
  15.          for (x = 0; x < COLNO; x++) {
  16.              lev = &levl[x][y];
  17.              if (x == u.ux && y == u.uy)
  18.                  row[x] = '@';
  19.              else if (IS_WALL(lev->typ) || lev->typ == SDOOR)
  20.                  row[x] = '0' + (lev->wall_info & WM_MASK);
  21.              else if (lev->typ == CORR)
  22.                  row[x] = '#';
  23.              else if (IS_ROOM(lev->typ) || IS_DOOR(lev->typ))
  24.                  row[x] = '.';
  25.              else
  26.                  row[x] = 'x';
  27.          }
  28.          row[COLNO] = '\0';
  29.          /* map column 0, levl[0][], is off the left edge of the screen */
  30.          putstr(win, 0, &row[1]);
  31.      }
  32.      display_nhwindow(win, TRUE);
  33.      destroy_nhwindow(win);
  34.      return 0;
  35.  }
  36.  

wiz_map_levltyp

  1.  /* wizard mode variant of #terrain; internal levl[][].typ values in base-36 */
  2.  STATIC_OVL void
  3.  wiz_map_levltyp(VOID_ARGS)
  4.  {
  5.      winid win;
  6.      int x, y, terrain;
  7.      char row[COLNO + 1];
  8.      boolean istty = !strcmp(windowprocs.name, "tty");
  9.  
  10.      win = create_nhwindow(NHW_TEXT);
  11.      /* map row 0, levl[][0], is drawn on the second line of tty screen */
  12.      if (istty)
  13.          putstr(win, 0, ""); /* tty only: blank top line */
  14.      for (y = 0; y < ROWNO; y++) {
  15.          /* map column 0, levl[0][], is off the left edge of the screen;
  16.             it should always have terrain type "undiggable stone" */
  17.          for (x = 1; x < COLNO; x++) {
  18.              terrain = levl[x][y].typ;
  19.              /* assumes there aren't more than 10+26+26 terrain types */
  20.              row[x - 1] = (char) ((terrain == 0 && !may_dig(x, y))
  21.                                      ? '*'
  22.                                      : (terrain < 10)
  23.                                         ? '0' + terrain
  24.                                         : (terrain < 36)
  25.                                            ? 'a' + terrain - 10
  26.                                            : 'A' + terrain - 36);
  27.          }
  28.          if (levl[0][y].typ != 0 || may_dig(0, y))
  29.              row[x++] = '!';
  30.          row[x] = '\0';
  31.          putstr(win, 0, row);
  32.      }
  33.  
  34.      {
  35.          char dsc[BUFSZ];
  36.          s_level *slev = Is_special(&u.uz);
  37.  
  38.          Sprintf(dsc, "D:%d,L:%d", u.uz.dnum, u.uz.dlevel);
  39.          /* [dungeon branch features currently omitted] */
  40.          /* special level features */
  41.          if (slev) {
  42.              Sprintf(eos(dsc), " \"%s\"", slev->proto);
  43.              /* special level flags (note: dungeon.def doesn't set `maze'
  44.                 or `hell' for any specific levels so those never show up) */
  45.              if (slev->flags.maze_like)
  46.                  Strcat(dsc, " mazelike");
  47.              if (slev->flags.hellish)
  48.                  Strcat(dsc, " hellish");
  49.              if (slev->flags.town)
  50.                  Strcat(dsc, " town");
  51.              if (slev->flags.rogue_like)
  52.                  Strcat(dsc, " roguelike");
  53.              /* alignment currently omitted to save space */
  54.          }
  55.          /* level features */
  56.          if (level.flags.nfountains)
  57.              Sprintf(eos(dsc), " %c:%d", defsyms[S_fountain].sym,
  58.                      (int) level.flags.nfountains);
  59.          if (level.flags.nsinks)
  60.              Sprintf(eos(dsc), " %c:%d", defsyms[S_sink].sym,
  61.                      (int) level.flags.nsinks);
  62.          if (level.flags.has_vault)
  63.              Strcat(dsc, " vault");
  64.          if (level.flags.has_shop)
  65.              Strcat(dsc, " shop");
  66.          if (level.flags.has_temple)
  67.              Strcat(dsc, " temple");
  68.          if (level.flags.has_court)
  69.              Strcat(dsc, " throne");
  70.          if (level.flags.has_zoo)
  71.              Strcat(dsc, " zoo");
  72.          if (level.flags.has_morgue)
  73.              Strcat(dsc, " morgue");
  74.          if (level.flags.has_barracks)
  75.              Strcat(dsc, " barracks");
  76.          if (level.flags.has_beehive)
  77.              Strcat(dsc, " hive");
  78.          if (level.flags.has_swamp)
  79.              Strcat(dsc, " swamp");
  80.          /* level flags */
  81.          if (level.flags.noteleport)
  82.              Strcat(dsc, " noTport");
  83.          if (level.flags.hardfloor)
  84.              Strcat(dsc, " noDig");
  85.          if (level.flags.nommap)
  86.              Strcat(dsc, " noMMap");
  87.          if (!level.flags.hero_memory)
  88.              Strcat(dsc, " noMem");
  89.          if (level.flags.shortsighted)
  90.              Strcat(dsc, " shortsight");
  91.          if (level.flags.graveyard)
  92.              Strcat(dsc, " graveyard");
  93.          if (level.flags.is_maze_lev)
  94.              Strcat(dsc, " maze");
  95.          if (level.flags.is_cavernous_lev)
  96.              Strcat(dsc, " cave");
  97.          if (level.flags.arboreal)
  98.              Strcat(dsc, " tree");
  99.          if (Sokoban)
  100.              Strcat(dsc, " sokoban-rules");
  101.          /* non-flag info; probably should include dungeon branching
  102.             checks (extra stairs and magic portals) here */
  103.          if (Invocation_lev(&u.uz))
  104.              Strcat(dsc, " invoke");
  105.          if (On_W_tower_level(&u.uz))
  106.              Strcat(dsc, " tower");
  107.          /* append a branch identifier for completeness' sake */
  108.          if (u.uz.dnum == 0)
  109.              Strcat(dsc, " dungeon");
  110.          else if (u.uz.dnum == mines_dnum)
  111.              Strcat(dsc, " mines");
  112.          else if (In_sokoban(&u.uz))
  113.              Strcat(dsc, " sokoban");
  114.          else if (u.uz.dnum == quest_dnum)
  115.              Strcat(dsc, " quest");
  116.          else if (Is_knox(&u.uz))
  117.              Strcat(dsc, " ludios");
  118.          else if (u.uz.dnum == 1)
  119.              Strcat(dsc, " gehennom");
  120.          else if (u.uz.dnum == tower_dnum)
  121.              Strcat(dsc, " vlad");
  122.          else if (In_endgame(&u.uz))
  123.              Strcat(dsc, " endgame");
  124.          else {
  125.              /* somebody's added a dungeon branch we're not expecting */
  126.              const char *brname = dungeons[u.uz.dnum].dname;
  127.  
  128.              if (!brname || !*brname)
  129.                  brname = "unknown";
  130.              if (!strncmpi(brname, "the ", 4))
  131.                  brname += 4;
  132.              Sprintf(eos(dsc), " %s", brname);
  133.          }
  134.          /* limit the line length to map width */
  135.          if (strlen(dsc) >= COLNO)
  136.              dsc[COLNO - 1] = '\0'; /* truncate */
  137.          putstr(win, 0, dsc);
  138.      }
  139.  
  140.      display_nhwindow(win, TRUE);
  141.      destroy_nhwindow(win);
  142.      return;
  143.  }
  144.  

wiz_lvltyp_legend

  1.  /* temporary? hack, since level type codes aren't the same as screen
  2.     symbols and only the latter have easily accessible descriptions */
  3.  static const char *levltyp[] = {
  4.      "stone", "vertical wall", "horizontal wall", "top-left corner wall",
  5.      "top-right corner wall", "bottom-left corner wall",
  6.      "bottom-right corner wall", "cross wall", "tee-up wall", "tee-down wall",
  7.      "tee-left wall", "tee-right wall", "drawbridge wall", "tree",
  8.      "secret door", "secret corridor", "pool", "moat", "water",
  9.      "drawbridge up", "lava pool", "iron bars", "door", "corridor", "room",
  10.      "stairs", "ladder", "fountain", "throne", "sink", "grave", "altar", "ice",
  11.      "drawbridge down", "air", "cloud",
  12.      /* not a real terrain type, but used for undiggable stone
  13.         by wiz_map_levltyp() */
  14.      "unreachable/undiggable",
  15.      /* padding in case the number of entries above is odd */
  16.      ""
  17.  };
  18.  
  19.  /* explanation of base-36 output from wiz_map_levltyp() */
  20.  STATIC_OVL void
  21.  wiz_levltyp_legend(VOID_ARGS)
  22.  {
  23.      winid win;
  24.      int i, j, last, c;
  25.      const char *dsc, *fmt;
  26.      char buf[BUFSZ];
  27.  
  28.      win = create_nhwindow(NHW_TEXT);
  29.      putstr(win, 0, "#terrain encodings:");
  30.      putstr(win, 0, "");
  31.      fmt = " %c - %-28s"; /* TODO: include tab-separated variant for win32 */
  32.      *buf = '\0';
  33.      /* output in pairs, left hand column holds [0],[1],...,[N/2-1]
  34.         and right hand column holds [N/2],[N/2+1],...,[N-1];
  35.         N ('last') will always be even, and may or may not include
  36.         the empty string entry to pad out the final pair, depending
  37.         upon how many other entries are present in levltyp[] */
  38.      last = SIZE(levltyp) & ~1;
  39.      for (i = 0; i < last / 2; ++i)
  40.          for (j = i; j < last; j += last / 2) {
  41.              dsc = levltyp[j];
  42.              c = !*dsc ? ' '
  43.                     : !strncmp(dsc, "unreachable", 11) ? '*'
  44.                        /* same int-to-char conversion as wiz_map_levltyp() */
  45.                        : (j < 10) ? '0' + j
  46.                           : (j < 36) ? 'a' + j - 10
  47.                              : 'A' + j - 36;
  48.              Sprintf(eos(buf), fmt, c, dsc);
  49.              if (j > i) {
  50.                  putstr(win, 0, buf);
  51.                  *buf = '\0';
  52.              }
  53.          }
  54.      display_nhwindow(win, TRUE);
  55.      destroy_nhwindow(win);
  56.      return;
  57.  }
  58.  

wiz_smell

  1.  /* #wizsmell command - test usmellmon(). */
  2.  STATIC_PTR int
  3.  wiz_smell(VOID_ARGS)
  4.  {
  5.      int ans = 0;
  6.      int mndx;  /* monster index */
  7.      coord cc;  /* screen pos of unknown glyph */
  8.      int glyph; /* glyph at selected position */
  9.  
  10.      cc.x = u.ux;
  11.      cc.y = u.uy;
  12.      mndx = 0; /* gcc -Wall lint */
  13.      if (!olfaction(youmonst.data)) {
  14.          You("are incapable of detecting odors in your present form.");
  15.          return 0;
  16.      }
  17.  
  18.      pline("You can move the cursor to a monster that you want to smell.");
  19.      do {
  20.          pline("Pick a monster to smell.");
  21.          ans = getpos(&cc, TRUE, "a monster");
  22.          if (ans < 0 || cc.x < 0) {
  23.              return 0; /* done */
  24.          }
  25.          /* Convert the glyph at the selected position to a mndxbol. */
  26.          glyph = glyph_at(cc.x, cc.y);
  27.          if (glyph_is_monster(glyph))
  28.              mndx = glyph_to_mon(glyph);
  29.          else
  30.              mndx = 0;
  31.          /* Is it a monster? */
  32.          if (mndx) {
  33.              if (!usmellmon(&mons[mndx]))
  34.                  pline("That monster seems to give off no smell.");
  35.          } else
  36.              pline("That is not a monster.");
  37.      } while (TRUE);
  38.      return 0;
  39.  }
  40.  

wiz_rumor_check

  1.  /* #wizrumorcheck command - verify each rumor access */
  2.  STATIC_PTR int
  3.  wiz_rumor_check(VOID_ARGS)
  4.  {
  5.      rumor_check();
  6.      return 0;
  7.  }
  8.  

doterrain

  1.  /* #terrain command -- show known map, inspired by crawl's '|' command */
  2.  STATIC_PTR int
  3.  doterrain(VOID_ARGS)
  4.  {
  5.      winid men;
  6.      menu_item *sel;
  7.      anything any;
  8.      int n;
  9.      int which;
  10.  
  11.      /*
  12.       * normal play: choose between known map without mons, obj, and traps
  13.       *  (to see underlying terrain only), or
  14.       *  known map without mons and objs (to see traps under mons and objs), or
  15.       *  known map without mons (to see objects under monsters);
  16.       * explore mode: normal choices plus full map (w/o mons, objs, traps);
  17.       * wizard mode: normal and explore choices plus
  18.       *  a dump of the internal levl[][].typ codes w/ level flags, or
  19.       *  a legend for the levl[][].typ codes dump
  20.       */
  21.      men = create_nhwindow(NHW_MENU);
  22.      any = zeroany;
  23.      any.a_int = 1;
  24.      add_menu(men, NO_GLYPH, &any, 0, 0, ATR_NONE,
  25.               "known map without monsters, objects, and traps",
  26.               MENU_SELECTED);
  27.      any.a_int = 2;
  28.      add_menu(men, NO_GLYPH, &any, 0, 0, ATR_NONE,
  29.               "known map without monsters and objects",
  30.               MENU_UNSELECTED);
  31.      any.a_int = 3;
  32.      add_menu(men, NO_GLYPH, &any, 0, 0, ATR_NONE,
  33.               "known map without monsters",
  34.               MENU_UNSELECTED);
  35.      if (discover || wizard) {
  36.          any.a_int = 4;
  37.          add_menu(men, NO_GLYPH, &any, 0, 0, ATR_NONE,
  38.                   "full map without monsters, objects, and traps",
  39.                   MENU_UNSELECTED);
  40.          if (wizard) {
  41.              any.a_int = 5;
  42.              add_menu(men, NO_GLYPH, &any, 0, 0, ATR_NONE,
  43.                       "internal levl[][].typ codes in base-36",
  44.                       MENU_UNSELECTED);
  45.              any.a_int = 6;
  46.              add_menu(men, NO_GLYPH, &any, 0, 0, ATR_NONE,
  47.                       "legend of base-36 levl[][].typ codes",
  48.                       MENU_UNSELECTED);
  49.          }
  50.      }
  51.      end_menu(men, "View which?");
  52.  
  53.      n = select_menu(men, PICK_ONE, &sel);
  54.      destroy_nhwindow(men);
  55.      /*
  56.       * n <  0: player used ESC to cancel;
  57.       * n == 0: preselected entry was explicitly chosen and got toggled off;
  58.       * n == 1: preselected entry was implicitly chosen via <space>|<enter>;
  59.       * n == 2: another entry was explicitly chosen, so skip preselected one.
  60.       */
  61.      which = (n < 0) ? -1 : (n == 0) ? 1 : sel[0].item.a_int;
  62.      if (n > 1 && which == 1)
  63.          which = sel[1].item.a_int;
  64.      if (n > 0)
  65.          free((genericptr_t) sel);
  66.  
  67.      switch (which) {
  68.      case 1: reveal_terrain(0, 0);   break; /* known map */
  69.      case 2: reveal_terrain(0, 1);   break; /* known map with traps */
  70.      case 3: reveal_terrain(0, 1|2); break; /* known map w/ traps & objs */
  71.      case 4: reveal_terrain(1, 0);   break; /* full map */
  72.      case 5: wiz_map_levltyp();      break; /* map internals */
  73.      case 6: wiz_levltyp_legend();   break; /* internal details */
  74.      default: break;
  75.      }
  76.      return 0; /* no time elapses */
  77.  }
  78.  

enlght_line

  1.  /* -enlightenment and conduct- */
  2.  static winid en_win = WIN_ERR;
  3.  static const char You_[] = "You ", are[] = "are ", were[] = "were ",
  4.                    have[] = "have ", had[] = "had ", can[] = "can ",
  5.                    could[] = "could ";
  6.  static const char have_been[] = "have been ", have_never[] = "have never ",
  7.                    never[] = "never ";
  8.  
  9.  #define enl_msg(prefix, present, past, suffix, ps) \
  10.      enlght_line(prefix, final ? past : present, suffix, ps)
  11.  #define you_are(attr, ps) enl_msg(You_, are, were, attr, ps)
  12.  #define you_have(attr, ps) enl_msg(You_, have, had, attr, ps)
  13.  #define you_can(attr, ps) enl_msg(You_, can, could, attr, ps)
  14.  #define you_have_been(goodthing) enl_msg(You_, have_been, were, goodthing, "")
  15.  #define you_have_never(badthing) \
  16.      enl_msg(You_, have_never, never, badthing, "")
  17.  #define you_have_X(something) \
  18.      enl_msg(You_, have, (const char *) "", something, "")
  19.  
  20.  static void
  21.  enlght_line(start, middle, end, ps)
  22.  const char *start, *middle, *end, *ps;
  23.  {
  24.      char buf[BUFSZ];
  25.  
  26.      Sprintf(buf, " %s%s%s%s.", start, middle, end, ps);
  27.      putstr(en_win, 0, buf);
  28.  }
  29.  

enlght_combatinc

  1.  /* format increased chance to hit or damage or defense (Protection) */
  2.  static char *
  3.  enlght_combatinc(inctyp, incamt, final, outbuf)
  4.  const char *inctyp;
  5.  int incamt, final;
  6.  char *outbuf;
  7.  {
  8.      const char *modif, *bonus;
  9.      boolean invrt;
  10.      int absamt;
  11.  
  12.      absamt = abs(incamt);
  13.      /* Protection amount is typically larger than damage or to-hit;
  14.         reduce magnitude by a third in order to stretch modifier ranges
  15.         (small:1..5, moderate:6..10, large:11..19, huge:20+) */
  16.      if (!strcmp(inctyp, "defense"))
  17.          absamt = (absamt * 2) / 3;
  18.  
  19.      if (absamt <= 3)
  20.          modif = "small";
  21.      else if (absamt <= 6)
  22.          modif = "moderate";
  23.      else if (absamt <= 12)
  24.          modif = "large";
  25.      else
  26.          modif = "huge";
  27.  
  28.      modif = !incamt ? "no" : an(modif); /* ("no" case shouldn't happen) */
  29.      bonus = (incamt >= 0) ? "bonus" : "penalty";
  30.      /* "bonus <foo>" (to hit) vs "<bar> bonus" (damage, defense) */
  31.      invrt = strcmp(inctyp, "to hit") ? TRUE : FALSE;
  32.  
  33.      Sprintf(outbuf, "%s %s %s", modif, invrt ? inctyp : bonus,
  34.              invrt ? bonus : inctyp);
  35.      if (final || wizard)
  36.          Sprintf(eos(outbuf), " (%s%d)", (incamt > 0) ? "+" : "", incamt);
  37.  
  38.      return outbuf;
  39.  }
  40.  

enlght_halfdmg

  1.  /* report half physical or half spell damage */
  2.  STATIC_OVL void
  3.  enlght_halfdmg(category, final)
  4.  int category;
  5.  int final;
  6.  {
  7.      const char *category_name;
  8.      char buf[BUFSZ];
  9.  
  10.      switch (category) {
  11.      case HALF_PHDAM:
  12.          category_name = "physical";
  13.          break;
  14.      case HALF_SPDAM:
  15.          category_name = "spell";
  16.          break;
  17.      default:
  18.          category_name = "unknown";
  19.          break;
  20.      }
  21.      Sprintf(buf, " %s %s damage", (final || wizard) ? "half" : "reduced",
  22.              category_name);
  23.      enl_msg(You_, "take", "took", buf, from_what(category));
  24.  }
  25.  

walking_on_water

  1.  /* is hero actively using water walking capability on water (or lava)? */
  2.  STATIC_OVL boolean
  3.  walking_on_water()
  4.  {
  5.      if (u.uinwater || Levitation || Flying)
  6.          return FALSE;
  7.      return (boolean) (Wwalking
  8.                        && (is_pool(u.ux, u.uy) || is_lava(u.ux, u.uy)));
  9.  }
  10.  

cause_known

  1.  /* check whether hero is wearing something that player definitely knows
  2.     confers the target property; item must have been seen and its type
  3.     discovered but it doesn't necessarily have to be fully identified */
  4.  STATIC_OVL boolean
  5.  cause_known(propindx)
  6.  int propindx; /* index of a property which can be conveyed by worn item */
  7.  {
  8.      register struct obj *o;
  9.      long mask = W_ARMOR | W_AMUL | W_RING | W_TOOL;
  10.  
  11.      /* simpler than from_what()/what_gives(); we don't attempt to
  12.         handle artifacts and we deliberately ignore wielded items */
  13.      for (o = invent; o; o = o->nobj) {
  14.          if (!(o->owornmask & mask))
  15.              continue;
  16.          if ((int) objects[o->otyp].oc_oprop == propindx
  17.              && objects[o->otyp].oc_name_known && o->dknown)
  18.              return TRUE;
  19.      }
  20.      return FALSE;
  21.  }
  22.  

attrval

  1.  /* format a characteristic value, accommodating Strength's strangeness */
  2.  STATIC_OVL char *
  3.  attrval(attrindx, attrvalue, resultbuf)
  4.  int attrindx, attrvalue;
  5.  char resultbuf[]; /* should be at least [7] to hold "18/100\0" */
  6.  {
  7.      if (attrindx != A_STR || attrvalue <= 18)
  8.          Sprintf(resultbuf, "%d", attrvalue);
  9.      else if (attrvalue > STR18(100)) /* 19 to 25 */
  10.          Sprintf(resultbuf, "%d", attrvalue - 100);
  11.      else /* simplify "18/ **" to be "18/100" */
  12.          Sprintf(resultbuf, "18/%02d", attrvalue - 18);
  13.      return resultbuf;
  14.  }
  15.  

enlightenment

  1.  void
  2.  enlightenment(mode, final)
  3.  int mode;  /* BASICENLIGHTENMENT | MAGICENLIGHTENMENT (| both) */
  4.  int final; /* ENL_GAMEINPROGRESS:0, ENL_GAMEOVERALIVE, ENL_GAMEOVERDEAD */
  5.  {
  6.      char buf[BUFSZ], tmpbuf[BUFSZ];
  7.  
  8.      Strcpy(tmpbuf, plname);
  9.      *tmpbuf = highc(*tmpbuf); /* same adjustment as bottom line */
  10.      /* as in background_enlightenment, when poly'd we need to use the saved
  11.         gender in u.mfemale rather than the current you-as-monster gender */
  12.      Sprintf(buf, "%s the %s's attributes:", tmpbuf,
  13.              ((Upolyd ? u.mfemale : flags.female) && urole.name.f)
  14.                  ? urole.name.f
  15.                  : urole.name.m);
  16.  
  17.      en_win = create_nhwindow(NHW_MENU);
  18.      /* title */
  19.      putstr(en_win, 0, buf); /* "Conan the Archeologist's attributes:" */
  20.      /* background and characteristics; ^X or end-of-game disclosure */
  21.      if (mode & BASICENLIGHTENMENT) {
  22.          /* role, race, alignment, deities */
  23.          background_enlightenment(mode, final);
  24.          /* strength, dexterity, &c */
  25.          characteristics_enlightenment(mode, final);
  26.      }
  27.      /* expanded status line information, including things which aren't
  28.         included there due to space considerations--such as obvious
  29.         alternative movement indicators (riding, levitation, &c), and
  30.         various troubles (turning to stone, trapped, confusion, &c);
  31.         shown for both basic and magic enlightenment */
  32.      status_enlightenment(mode, final);
  33.      /* remaining attributes; shown for potion,&c or wizard mode and
  34.         explore mode ^X or end of game disclosure */
  35.      if (mode & MAGICENLIGHTENMENT) {
  36.          /* intrinsics and other traditional enlightenment feedback */
  37.          attributes_enlightenment(mode, final);
  38.      }
  39.      display_nhwindow(en_win, TRUE);
  40.      destroy_nhwindow(en_win);
  41.      en_win = WIN_ERR;
  42.  }
  43.  

background_enlightenment

  1.  /*ARGSUSED*/
  2.  /* display role, race, alignment and such to en_win */
  3.  STATIC_OVL void
  4.  background_enlightenment(unused_mode, final)
  5.  int unused_mode UNUSED;
  6.  int final;
  7.  {
  8.      const char *role_titl, *rank_titl;
  9.      int innategend, difgend, difalgn;
  10.      char buf[BUFSZ], tmpbuf[BUFSZ];
  11.  
  12.      /* note that if poly'd, we need to use u.mfemale instead of flags.female
  13.         to access hero's saved gender-as-human/elf/&c rather than current one */
  14.      innategend = (Upolyd ? u.mfemale : flags.female) ? 1 : 0;
  15.      role_titl = (innategend && urole.name.f) ? urole.name.f : urole.name.m;
  16.      rank_titl = rank_of(u.ulevel, Role_switch, innategend);
  17.  
  18.      putstr(en_win, 0, ""); /* separator after title */
  19.      putstr(en_win, 0, "Background:");
  20.  
  21.      /* if polymorphed, report current shape before underlying role;
  22.         will be repeated as first status: "you are transformed" and also
  23.         among various attributes: "you are in beast form" (after being
  24.         told about lycanthropy) or "you are polymorphed into <a foo>"
  25.         (with countdown timer appended for wizard mode); we really want
  26.         the player to know he's not a samurai at the moment... */
  27.      if (Upolyd) {
  28.          struct permonst *uasmon = youmonst.data;
  29.  
  30.          tmpbuf[0] = '\0';
  31.          /* here we always use current gender, not saved role gender */
  32.          if (!is_male(uasmon) && !is_female(uasmon) && !is_neuter(uasmon))
  33.              Sprintf(tmpbuf, "%s ", genders[flags.female ? 1 : 0].adj);
  34.          Sprintf(buf, "%sin %s%s form", !final ? "currently " : "", tmpbuf,
  35.                  uasmon->mname);
  36.          you_are(buf, "");
  37.      }
  38.  
  39.      /* report role; omit gender if it's redundant (eg, "female priestess") */
  40.      tmpbuf[0] = '\0';
  41.      if (!urole.name.f
  42.          && ((urole.allow & ROLE_GENDMASK) == (ROLE_MALE | ROLE_FEMALE)
  43.              || innategend != flags.initgend))
  44.          Sprintf(tmpbuf, "%s ", genders[innategend].adj);
  45.      buf[0] = '\0';
  46.      if (Upolyd)
  47.          Strcpy(buf, "actually "); /* "You are actually a ..." */
  48.      if (!strcmpi(rank_titl, role_titl)) {
  49.          /* omit role when rank title matches it */
  50.          Sprintf(eos(buf), "%s, level %d %s%s", an(rank_titl), u.ulevel,
  51.                  tmpbuf, urace.noun);
  52.      } else {
  53.          Sprintf(eos(buf), "%s, a level %d %s%s %s", an(rank_titl), u.ulevel,
  54.                  tmpbuf, urace.adj, role_titl);
  55.      }
  56.      you_are(buf, "");
  57.  
  58.      /* report alignment (bypass you_are() in order to omit ending period) */
  59.      Sprintf(buf, " %s%s%s, %son a mission for %s",
  60.              You_, !final ? are : were,
  61.              align_str(u.ualign.type),
  62.              /* helm of opposite alignment (might hide conversion) */
  63.              (u.ualign.type != u.ualignbase[A_CURRENT]) ? "temporarily "
  64.                 /* permanent conversion */
  65.                 : (u.ualign.type != u.ualignbase[A_ORIGINAL]) ? "now "
  66.                    /* atheist (ignored in very early game) */
  67.                    : (!u.uconduct.gnostic && moves > 1000L) ? "nominally "
  68.                       /* lastly, normal case */
  69.                       : "",
  70.              u_gname());
  71.      putstr(en_win, 0, buf);
  72.      /* show the rest of this game's pantheon (finishes previous sentence)
  73.         [appending "also Moloch" at the end would allow for straightforward
  74.         trailing "and" on all three aligned entries but looks too verbose] */
  75.      Sprintf(buf, " who %s opposed by", !final ? "is" : "was");
  76.      if (u.ualign.type != A_LAWFUL)
  77.          Sprintf(eos(buf), " %s (%s) and", align_gname(A_LAWFUL),
  78.                  align_str(A_LAWFUL));
  79.      if (u.ualign.type != A_NEUTRAL)
  80.          Sprintf(eos(buf), " %s (%s)%s", align_gname(A_NEUTRAL),
  81.                  align_str(A_NEUTRAL),
  82.                  (u.ualign.type != A_CHAOTIC) ? " and" : "");
  83.      if (u.ualign.type != A_CHAOTIC)
  84.          Sprintf(eos(buf), " %s (%s)", align_gname(A_CHAOTIC),
  85.                  align_str(A_CHAOTIC));
  86.      Strcat(buf, "."); /* terminate sentence */
  87.      putstr(en_win, 0, buf);
  88.  
  89.      /* show original alignment,gender,race,role if any have been changed;
  90.         giving separate message for temporary alignment change bypasses need
  91.         for tricky phrasing otherwise necessitated by possibility of having
  92.         helm of opposite alignment mask a permanent alignment conversion */
  93.      difgend = (innategend != flags.initgend);
  94.      difalgn = (((u.ualign.type != u.ualignbase[A_CURRENT]) ? 1 : 0)
  95.                 + ((u.ualignbase[A_CURRENT] != u.ualignbase[A_ORIGINAL])
  96.                    ? 2 : 0));
  97.      if (difalgn & 1) { /* have temporary alignment so report permanent one */
  98.          Sprintf(buf, "actually %s", align_str(u.ualignbase[A_CURRENT]));
  99.          you_are(buf, "");
  100.          difalgn &= ~1; /* suppress helm from "started out <foo>" message */
  101.      }
  102.      if (difgend || difalgn) { /* sex change or perm align change or both */
  103.          Sprintf(buf, " You started out %s%s%s.",
  104.                  difgend ? genders[flags.initgend].adj : "",
  105.                  (difgend && difalgn) ? " and " : "",
  106.                  difalgn ? align_str(u.ualignbase[A_ORIGINAL]) : "");
  107.          putstr(en_win, 0, buf);
  108.      }
  109.  }
  110.  

characteristics_enlightenment

  1.  /* characteristics: expanded version of bottom line strength, dexterity, &c */
  2.  STATIC_OVL void
  3.  characteristics_enlightenment(mode, final)
  4.  int mode;
  5.  int final;
  6.  {
  7.      putstr(en_win, 0, ""); /* separator after background */
  8.      putstr(en_win, 0,
  9.             final ? "Final Characteristics:" : "Current Characteristics:");
  10.  
  11.      /* bottom line order */
  12.      one_characteristic(mode, final, A_STR); /* strength */
  13.      one_characteristic(mode, final, A_DEX); /* dexterity */
  14.      one_characteristic(mode, final, A_CON); /* constitution */
  15.      one_characteristic(mode, final, A_INT); /* intelligence */
  16.      one_characteristic(mode, final, A_WIS); /* wisdom */
  17.      one_characteristic(mode, final, A_CHA); /* charisma */
  18.  }
  19.  

one_characteristic

  1.  /* display one attribute value for characteristics_enlightenment() */
  2.  STATIC_OVL void
  3.  one_characteristic(mode, final, attrindx)
  4.  int mode, final, attrindx;
  5.  {
  6.      boolean hide_innate_value = FALSE, interesting_alimit;
  7.      int acurrent, abase, apeak, alimit;
  8.      const char *attrname, *paren_pfx;
  9.      char subjbuf[BUFSZ], valubuf[BUFSZ], valstring[32];
  10.  
  11.      /* being polymorphed or wearing certain cursed items prevents
  12.         hero from reliably tracking changes to characteristics so
  13.         we don't show base & peak values then; when the items aren't
  14.         cursed, hero could take them off to check underlying values
  15.         and we show those in such case so that player doesn't need
  16.         to actually resort to doing that */
  17.      if (Upolyd) {
  18.          hide_innate_value = TRUE;
  19.      } else if (Fixed_abil) {
  20.          if (stuck_ring(uleft, RIN_SUSTAIN_ABILITY)
  21.              || stuck_ring(uright, RIN_SUSTAIN_ABILITY))
  22.              hide_innate_value = TRUE;
  23.      }
  24.      switch (attrindx) {
  25.      case A_STR:
  26.          attrname = "strength";
  27.          if (uarmg && uarmg->otyp == GAUNTLETS_OF_POWER && uarmg->cursed)
  28.              hide_innate_value = TRUE;
  29.          break;
  30.      case A_DEX:
  31.          attrname = "dexterity";
  32.          break;
  33.      case A_CON:
  34.          attrname = "constitution";
  35.          break;
  36.      case A_INT:
  37.          attrname = "intelligence";
  38.          if (uarmh && uarmh->otyp == DUNCE_CAP && uarmh->cursed)
  39.              hide_innate_value = TRUE;
  40.          break;
  41.      case A_WIS:
  42.          attrname = "wisdom";
  43.          if (uarmh && uarmh->otyp == DUNCE_CAP && uarmh->cursed)
  44.              hide_innate_value = TRUE;
  45.          break;
  46.      case A_CHA:
  47.          attrname = "charisma";
  48.          break;
  49.      default:
  50.          return; /* impossible */
  51.      };
  52.      /* note: final disclosure includes MAGICENLIGHTENTMENT */
  53.      if ((mode & MAGICENLIGHTENMENT) && !Upolyd)
  54.          hide_innate_value = FALSE;
  55.  
  56.      acurrent = ACURR(attrindx);
  57.      (void) attrval(attrindx, acurrent, valubuf); /* Sprintf(valubuf,"%d",) */
  58.      Sprintf(subjbuf, "Your %s ", attrname);
  59.  
  60.      if (!hide_innate_value) {
  61.          /* show abase, amax, and/or attrmax if acurr doesn't match abase
  62.             (a magic bonus or penalty is in effect) or abase doesn't match
  63.             amax (some points have been lost to poison or exercise abuse
  64.             and are restorable) or attrmax is different from normal human
  65.             (while game is in progress; trying to reduce dependency on
  66.             spoilers to keep track of such stuff) or attrmax was different
  67.             from abase (at end of game; this attribute wasn't maxed out) */
  68.          abase = ABASE(attrindx);
  69.          apeak = AMAX(attrindx);
  70.          alimit = ATTRMAX(attrindx);
  71.          /* criterium for whether the limit is interesting varies */
  72.          interesting_alimit =
  73.              final ? TRUE /* was originally `(abase != alimit)' */
  74.                    : (alimit != (attrindx != A_STR ? 18 : STR18(100)));
  75.          paren_pfx = final ? " (" : " (current; ";
  76.          if (acurrent != abase) {
  77.              Sprintf(eos(valubuf), "%sbase:%s", paren_pfx,
  78.                      attrval(attrindx, abase, valstring));
  79.              paren_pfx = ", ";
  80.          }
  81.          if (abase != apeak) {
  82.              Sprintf(eos(valubuf), "%speak:%s", paren_pfx,
  83.                      attrval(attrindx, apeak, valstring));
  84.              paren_pfx = ", ";
  85.          }
  86.          if (interesting_alimit) {
  87.              Sprintf(eos(valubuf), "%s%slimit:%s", paren_pfx,
  88.                      /* more verbose if exceeding 'limit' due to magic bonus */
  89.                      (acurrent > alimit) ? "innate " : "",
  90.                      attrval(attrindx, alimit, valstring));
  91.              /* paren_pfx = ", "; */
  92.          }
  93.          if (acurrent != abase || abase != apeak || interesting_alimit)
  94.              Strcat(valubuf, ")");
  95.      }
  96.      enl_msg(subjbuf, "is ", "was ", valubuf, "");
  97.  }
  98.  

status_enlightenment

  1.  /* status: selected obvious capabilities, assorted troubles */
  2.  STATIC_OVL void
  3.  status_enlightenment(mode, final)
  4.  int mode;
  5.  int final;
  6.  {
  7.      boolean magic = (mode & MAGICENLIGHTENMENT) ? TRUE : FALSE;
  8.      int cap;
  9.      char buf[BUFSZ], youtoo[BUFSZ];
  10.      boolean Riding = (u.usteed
  11.                        /* if hero dies while dismounting, u.usteed will still
  12.                           be set; we want to ignore steed in that situation */
  13.                        && !(final == ENL_GAMEOVERDEAD
  14.                             && !strcmp(killer.name, "riding accident")));
  15.      const char *steedname = (!Riding ? (char *) 0
  16.                        : x_monnam(u.usteed,
  17.                                   u.usteed->mtame ? ARTICLE_YOUR : ARTICLE_THE,
  18.                                   (char *) 0,
  19.                                   (SUPPRESS_SADDLE | SUPPRESS_HALLUCINATION),
  20.                                   FALSE));
  21.  
  22.      /*\
  23.       * Status (many are abbreviated on bottom line; others are or
  24.       *     should be discernible to the hero hence to the player)
  25.      \*/
  26.      putstr(en_win, 0, ""); /* separator after title or characteristics */
  27.      putstr(en_win, 0, final ? "Final Status:" : "Current Status:");
  28.  
  29.      Strcpy(youtoo, You_);
  30.      /* not a traditional status but inherently obvious to player; more
  31.         detail given below (attributes section) for magic enlightenment */
  32.      if (Upolyd)
  33.          you_are("transformed", "");
  34.      /* not a trouble, but we want to display riding status before maybe
  35.         reporting steed as trapped or hero stuck to cursed saddle */
  36.      if (Riding) {
  37.          Sprintf(buf, "riding %s", steedname);
  38.          you_are(buf, "");
  39.          Sprintf(eos(youtoo), "and %s ", steedname);
  40.      }
  41.      /* other movement situations that hero should always know */
  42.      if (Levitation) {
  43.          if (Lev_at_will && magic)
  44.              you_are("levitating, at will", "");
  45.          else
  46.              enl_msg(youtoo, are, were, "levitating", from_what(LEVITATION));
  47.      } else if (Flying) { /* can only fly when not levitating */
  48.          enl_msg(youtoo, are, were, "flying", from_what(FLYING));
  49.      }
  50.      if (Underwater) {
  51.          you_are("underwater", "");
  52.      } else if (u.uinwater) {
  53.          you_are(Swimming ? "swimming" : "in water", from_what(SWIMMING));
  54.      } else if (walking_on_water()) {
  55.          /* show active Wwalking here, potential Wwalking elsewhere */
  56.          Sprintf(buf, "walking on %s",
  57.                  is_pool(u.ux, u.uy) ? "water"
  58.                  : is_lava(u.ux, u.uy) ? "lava"
  59.                    : surface(u.ux, u.uy)); /* catchall; shouldn't happen */
  60.          you_are(buf, from_what(WWALKING));
  61.      }
  62.      if (Upolyd && (u.uundetected || youmonst.m_ap_type != M_AP_NOTHING))
  63.          youhiding(TRUE, final);
  64.  
  65.      /* internal troubles, mostly in the order that prayer ranks them */
  66.      if (Stoned)
  67.          you_are("turning to stone", "");
  68.      if (Slimed)
  69.          you_are("turning into slime", "");
  70.      if (Strangled) {
  71.          if (u.uburied) {
  72.              you_are("buried", "");
  73.          } else {
  74.              Strcpy(buf, "being strangled");
  75.              if (wizard)
  76.                  Sprintf(eos(buf), " (%ld)", (Strangled & TIMEOUT));
  77.              you_are(buf, from_what(STRANGLED));
  78.          }
  79.      }
  80.      if (Sick) {
  81.          /* prayer lumps these together; botl puts Ill before FoodPois */
  82.          if (u.usick_type & SICK_NONVOMITABLE)
  83.              you_are("terminally sick from illness", "");
  84.          if (u.usick_type & SICK_VOMITABLE)
  85.              you_are("terminally sick from food poisoning", "");
  86.      }
  87.      if (Vomiting)
  88.          you_are("nauseated", "");
  89.      if (Stunned)
  90.          you_are("stunned", "");
  91.      if (Confusion)
  92.          you_are("confused", "");
  93.      if (Hallucination)
  94.          you_are("hallucinating", "");
  95.      if (Blind) {
  96.          /* from_what() (currently wizard-mode only) checks !haseyes()
  97.             before u.uroleplay.blind, so we should too */
  98.          Sprintf(buf, "%s blind",
  99.                  !haseyes(youmonst.data) ? "innately"
  100.                  : u.uroleplay.blind ? "permanently"
  101.                    /* better phrasing desperately wanted... */
  102.                    : Blindfolded_only ? "deliberately"
  103.                      : "temporarily");
  104.          if (wizard && (Blinded & TIMEOUT) != 0L
  105.              && !u.uroleplay.blind && haseyes(youmonst.data))
  106.              Sprintf(eos(buf), " (%ld)", (Blinded & TIMEOUT));
  107.          /* !haseyes: avoid "you are innately blind innately" */
  108.          you_are(buf, !haseyes(youmonst.data) ? "" : from_what(BLINDED));
  109.      }
  110.      if (Deaf)
  111.          you_are("deaf", from_what(DEAF));
  112.  
  113.      /* external troubles, more or less */
  114.      if (Punished) {
  115.          if (uball) {
  116.              Sprintf(buf, "chained to %s", ansimpleoname(uball));
  117.          } else {
  118.              impossible("Punished without uball?");
  119.              Strcpy(buf, "punished");
  120.          }
  121.          you_are(buf, "");
  122.      }
  123.      if (u.utrap) {
  124.          char predicament[BUFSZ];
  125.          struct trap *t;
  126.          boolean anchored = (u.utraptype == TT_BURIEDBALL);
  127.  
  128.          if (anchored) {
  129.              Strcpy(predicament, "tethered to something buried");
  130.          } else if (u.utraptype == TT_INFLOOR || u.utraptype == TT_LAVA) {
  131.              Sprintf(predicament, "stuck in %s", the(surface(u.ux, u.uy)));
  132.          } else {
  133.              Strcpy(predicament, "trapped");
  134.              if ((t = t_at(u.ux, u.uy)) != 0)
  135.                  Sprintf(eos(predicament), " in %s",
  136.                          an(defsyms[trap_to_defsym(t->ttyp)].explanation));
  137.          }
  138.          if (u.usteed) { /* not `Riding' here */
  139.              Sprintf(buf, "%s%s ", anchored ? "you and " : "", steedname);
  140.              *buf = highc(*buf);
  141.              enl_msg(buf, (anchored ? "are " : "is "),
  142.                      (anchored ? "were " : "was "), predicament, "");
  143.          } else
  144.              you_are(predicament, "");
  145.      } /* (u.utrap) */
  146.      if (u.uswallow) {
  147.          Sprintf(buf, "swallowed by %s", a_monnam(u.ustuck));
  148.          if (wizard)
  149.              Sprintf(eos(buf), " (%u)", u.uswldtim);
  150.          you_are(buf, "");
  151.      } else if (u.ustuck) {
  152.          Sprintf(buf, "%s %s",
  153.                  (Upolyd && sticks(youmonst.data)) ? "holding" : "held by",
  154.                  a_monnam(u.ustuck));
  155.          you_are(buf, "");
  156.      }
  157.      if (Riding) {
  158.          struct obj *saddle = which_armor(u.usteed, W_SADDLE);
  159.  
  160.          if (saddle && saddle->cursed) {
  161.              Sprintf(buf, "stuck to %s %s", s_suffix(steedname),
  162.                      simpleonames(saddle));
  163.              you_are(buf, "");
  164.          }
  165.      }
  166.      if (Wounded_legs) {
  167.          /* when mounted, Wounded_legs applies to steed rather than to
  168.             hero; we only report steed's wounded legs in wizard mode */
  169.          if (u.usteed) { /* not `Riding' here */
  170.              if (wizard && steedname) {
  171.                  Strcpy(buf, steedname);
  172.                  *buf = highc(*buf);
  173.                  enl_msg(buf, " has", " had", " wounded legs", "");
  174.              }
  175.          } else {
  176.              Sprintf(buf, "wounded %s", makeplural(body_part(LEG)));
  177.              you_have(buf, "");
  178.          }
  179.      }
  180.      if (Glib) {
  181.          Sprintf(buf, "slippery %s", makeplural(body_part(FINGER)));
  182.          you_have(buf, "");
  183.      }
  184.      if (Fumbling) {
  185.          if (magic || cause_known(FUMBLING))
  186.              enl_msg(You_, "fumble", "fumbled", "", from_what(FUMBLING));
  187.      }
  188.      if (Sleepy) {
  189.          if (magic || cause_known(SLEEPY)) {
  190.              Strcpy(buf, from_what(SLEEPY));
  191.              if (wizard)
  192.                  Sprintf(eos(buf), " (%ld)", (HSleepy & TIMEOUT));
  193.              enl_msg("You ", "fall", "fell", " asleep uncontrollably", buf);
  194.          }
  195.      }
  196.      /* hunger/nutrition */
  197.      if (Hunger) {
  198.          if (magic || cause_known(HUNGER))
  199.              enl_msg(You_, "hunger", "hungered", " rapidly",
  200.                      from_what(HUNGER));
  201.      }
  202.      Strcpy(buf, hu_stat[u.uhs]); /* hunger status; omitted if "normal" */
  203.      mungspaces(buf);             /* strip trailing spaces */
  204.      if (*buf) {
  205.          *buf = lowc(*buf); /* override capitalization */
  206.          if (!strcmp(buf, "weak"))
  207.              Strcat(buf, " from severe hunger");
  208.          else if (!strncmp(buf, "faint", 5)) /* fainting, fainted */
  209.              Strcat(buf, " due to starvation");
  210.          you_are(buf, "");
  211.      }
  212.      /* encumbrance */
  213.      if ((cap = near_capacity()) > UNENCUMBERED) {
  214.          const char *adj = "?_?"; /* (should always get overridden) */
  215.  
  216.          Strcpy(buf, enc_stat[cap]);
  217.          *buf = lowc(*buf);
  218.          switch (cap) {
  219.          case SLT_ENCUMBER:
  220.              adj = "slightly";
  221.              break; /* burdened */
  222.          case MOD_ENCUMBER:
  223.              adj = "moderately";
  224.              break; /* stressed */
  225.          case HVY_ENCUMBER:
  226.              adj = "very";
  227.              break; /* strained */
  228.          case EXT_ENCUMBER:
  229.              adj = "extremely";
  230.              break; /* overtaxed */
  231.          case OVERLOADED:
  232.              adj = "not possible";
  233.              break;
  234.          }
  235.          Sprintf(eos(buf), "; movement %s %s%s", !final ? "is" : "was", adj,
  236.                  (cap < OVERLOADED) ? " slowed" : "");
  237.          you_are(buf, "");
  238.      } else {
  239.          /* last resort entry, guarantees Status section is non-empty
  240.             (no longer needed for that purpose since weapon status added;
  241.             still useful though) */
  242.          you_are("unencumbered", "");
  243.      }
  244.      /* report being weaponless; distinguish whether gloves are worn */
  245.      if (!uwep) {
  246.          you_are(uarmg ? "empty handed" /* gloves imply hands */
  247.                        : humanoid(youmonst.data)
  248.                           /* hands but no weapon and no gloves */
  249.                           ? "bare handed"
  250.                           /* alternate phrasing for paws or lack of hands */
  251.                           : "not wielding anything",
  252.                  "");
  253.      /* two-weaponing implies a weapon (not other odd stuff) in each hand */
  254.      } else if (u.twoweap) {
  255.          you_are("wielding two weapons at once", "");
  256.      /* report most weapons by their skill class (so a katana will be
  257.         described as a long sword, for instance; mattock and hook are
  258.         exceptions), or wielded non-weapon item by its object class */
  259.      } else {
  260.          const char *what = weapon_descr(uwep);
  261.  
  262.          if (!strcmpi(what, "armor") || !strcmpi(what, "food")
  263.              || !strcmpi(what, "venom"))
  264.              Sprintf(buf, "wielding some %s", what);
  265.          else
  266.              Sprintf(buf, "wielding %s",
  267.                      (uwep->quan == 1L) ? an(what) : makeplural(what));
  268.          you_are(buf, "");
  269.      }
  270.      /* report 'nudity' */
  271.      if (!uarm && !uarmu && !uarmc && !uarmg && !uarmf && !uarmh) {
  272.          if (u.uroleplay.nudist)
  273.              enl_msg(You_, "do", "did", " not wear any armor", "");
  274.          else
  275.              you_are("not wearing any armor", "");
  276.      }
  277.  }
  278.  

attributes_enlightenment

  1.  /* attributes: intrinsics and the like, other non-obvious capabilities */
  2.  void
  3.  attributes_enlightenment(unused_mode, final)
  4.  int unused_mode UNUSED;
  5.  int final;
  6.  {
  7.      static NEARDATA const char if_surroundings_permitted[] =
  8.          " if surroundings permitted";
  9.      int ltmp, armpro;
  10.      char buf[BUFSZ];
  11.  
  12.      /*\
  13.       *  Attributes
  14.      \*/
  15.      putstr(en_win, 0, "");
  16.      putstr(en_win, 0, final ? "Final Attributes:" : "Current Attributes:");
  17.  
  18.      if (u.uevent.uhand_of_elbereth) {
  19.          static const char *const hofe_titles[3] = { "the Hand of Elbereth",
  20.                                                      "the Envoy of Balance",
  21.                                                      "the Glory of Arioch" };
  22.          you_are(hofe_titles[u.uevent.uhand_of_elbereth - 1], "");
  23.      }
  24.  
  25.      /* note: piousness 20 matches MIN_QUEST_ALIGN (quest.h) */
  26.      if (u.ualign.record >= 20)
  27.          you_are("piously aligned", "");
  28.      else if (u.ualign.record > 13)
  29.          you_are("devoutly aligned", "");
  30.      else if (u.ualign.record > 8)
  31.          you_are("fervently aligned", "");
  32.      else if (u.ualign.record > 3)
  33.          you_are("stridently aligned", "");
  34.      else if (u.ualign.record == 3)
  35.          you_are("aligned", "");
  36.      else if (u.ualign.record > 0)
  37.          you_are("haltingly aligned", "");
  38.      else if (u.ualign.record == 0)
  39.          you_are("nominally aligned", "");
  40.      else if (u.ualign.record >= -3)
  41.          you_have("strayed", "");
  42.      else if (u.ualign.record >= -8)
  43.          you_have("sinned", "");
  44.      else
  45.          you_have("transgressed", "");
  46.      if (wizard) {
  47.          Sprintf(buf, " %d", u.ualign.record);
  48.          enl_msg("Your alignment ", "is", "was", buf, "");
  49.      }
  50.  
  51.      /*** Resistances to troubles ***/
  52.      if (Invulnerable)
  53.          you_are("invulnerable", from_what(INVULNERABLE));
  54.      if (Antimagic)
  55.          you_are("magic-protected", from_what(ANTIMAGIC));
  56.      if (Fire_resistance)
  57.          you_are("fire resistant", from_what(FIRE_RES));
  58.      if (Cold_resistance)
  59.          you_are("cold resistant", from_what(COLD_RES));
  60.      if (Sleep_resistance)
  61.          you_are("sleep resistant", from_what(SLEEP_RES));
  62.      if (Disint_resistance)
  63.          you_are("disintegration-resistant", from_what(DISINT_RES));
  64.      if (Shock_resistance)
  65.          you_are("shock resistant", from_what(SHOCK_RES));
  66.      if (Poison_resistance)
  67.          you_are("poison resistant", from_what(POISON_RES));
  68.      if (Acid_resistance)
  69.          you_are("acid resistant", from_what(ACID_RES));
  70.      if (Drain_resistance)
  71.          you_are("level-drain resistant", from_what(DRAIN_RES));
  72.      if (Sick_resistance)
  73.          you_are("immune to sickness", from_what(SICK_RES));
  74.      if (Stone_resistance)
  75.          you_are("petrification resistant", from_what(STONE_RES));
  76.      if (Halluc_resistance)
  77.          enl_msg(You_, "resist", "resisted", " hallucinations",
  78.                  from_what(HALLUC_RES));
  79.      if (u.uedibility)
  80.          you_can("recognize detrimental food", "");
  81.  
  82.      /*** Vision and senses ***/
  83.      if (!Blind && (Blinded || !haseyes(youmonst.data)))
  84.          you_can("see", from_what(-BLINDED)); /* Eyes of the Overworld */
  85.      if (See_invisible) {
  86.          if (!Blind)
  87.              enl_msg(You_, "see", "saw", " invisible", from_what(SEE_INVIS));
  88.          else
  89.              enl_msg(You_, "will see", "would have seen",
  90.                      " invisible when not blind", from_what(SEE_INVIS));
  91.      }
  92.      if (Blind_telepat)
  93.          you_are("telepathic", from_what(TELEPAT));
  94.      if (Warning)
  95.          you_are("warned", from_what(WARNING));
  96.      if (Warn_of_mon && context.warntype.obj) {
  97.          Sprintf(buf, "aware of the presence of %s",
  98.                  (context.warntype.obj & M2_ORC) ? "orcs"
  99.                  : (context.warntype.obj & M2_ELF) ? "elves"
  100.                  : (context.warntype.obj & M2_DEMON) ? "demons" : something);
  101.          you_are(buf, from_what(WARN_OF_MON));
  102.      }
  103.      if (Warn_of_mon && context.warntype.polyd) {
  104.          Sprintf(buf, "aware of the presence of %s",
  105.                  ((context.warntype.polyd & (M2_HUMAN | M2_ELF))
  106.                   == (M2_HUMAN | M2_ELF))
  107.                      ? "humans and elves"
  108.                      : (context.warntype.polyd & M2_HUMAN)
  109.                            ? "humans"
  110.                            : (context.warntype.polyd & M2_ELF)
  111.                                  ? "elves"
  112.                                  : (context.warntype.polyd & M2_ORC)
  113.                                        ? "orcs"
  114.                                        : (context.warntype.polyd & M2_DEMON)
  115.                                              ? "demons"
  116.                                              : "certain monsters");
  117.          you_are(buf, "");
  118.      }
  119.      if (Warn_of_mon && context.warntype.speciesidx) {
  120.          Sprintf(buf, "aware of the presence of %s",
  121.                  makeplural(mons[context.warntype.speciesidx].mname));
  122.          you_are(buf, from_what(WARN_OF_MON));
  123.      }
  124.      if (Undead_warning)
  125.          you_are("warned of undead", from_what(WARN_UNDEAD));
  126.      if (Searching)
  127.          you_have("automatic searching", from_what(SEARCHING));
  128.      if (Clairvoyant)
  129.          you_are("clairvoyant", from_what(CLAIRVOYANT));
  130.      else if ((HClairvoyant || EClairvoyant) && BClairvoyant) {
  131.          Strcpy(buf, from_what(-CLAIRVOYANT));
  132.          if (!strncmp(buf, " because of ", 12))
  133.              /* overwrite substring; strncpy doesn't add terminator */
  134.              (void) strncpy(buf, " if not for ", 12);
  135.          enl_msg(You_, "could be", "could have been", " clairvoyant", buf);
  136.      }
  137.      if (Infravision)
  138.          you_have("infravision", from_what(INFRAVISION));
  139.      if (Detect_monsters)
  140.          you_are("sensing the presence of monsters", "");
  141.      if (u.umconf)
  142.          you_are("going to confuse monsters", "");
  143.  
  144.      /*** Appearance and behavior ***/
  145.      if (Adornment) {
  146.          int adorn = 0;
  147.  
  148.          if (uleft && uleft->otyp == RIN_ADORNMENT)
  149.              adorn += uleft->spe;
  150.          if (uright && uright->otyp == RIN_ADORNMENT)
  151.              adorn += uright->spe;
  152.          /* the sum might be 0 (+0 ring or two which negate each other);
  153.             that yields "you are charismatic" (which isn't pointless
  154.             because it potentially impacts seduction attacks) */
  155.          Sprintf(buf, "%scharismatic",
  156.                  (adorn > 0) ? "more " : (adorn < 0) ? "less " : "");
  157.          you_are(buf, from_what(ADORNED));
  158.      }
  159.      if (Invisible)
  160.          you_are("invisible", from_what(INVIS));
  161.      else if (Invis)
  162.          you_are("invisible to others", from_what(INVIS));
  163.      /* ordinarily "visible" is redundant; this is a special case for
  164.         the situation when invisibility would be an expected attribute */
  165.      else if ((HInvis || EInvis) && BInvis)
  166.          you_are("visible", from_what(-INVIS));
  167.      if (Displaced)
  168.          you_are("displaced", from_what(DISPLACED));
  169.      if (Stealth)
  170.          you_are("stealthy", from_what(STEALTH));
  171.      if (Aggravate_monster)
  172.          enl_msg("You aggravate", "", "d", " monsters",
  173.                  from_what(AGGRAVATE_MONSTER));
  174.      if (Conflict)
  175.          enl_msg("You cause", "", "d", " conflict", from_what(CONFLICT));
  176.  
  177.      /*** Transportation ***/
  178.      if (Jumping)
  179.          you_can("jump", from_what(JUMPING));
  180.      if (Teleportation)
  181.          you_can("teleport", from_what(TELEPORT));
  182.      if (Teleport_control)
  183.          you_have("teleport control", from_what(TELEPORT_CONTROL));
  184.      /* actively levitating handled earlier as a status condition */
  185.      if (BLevitation) { /* levitation is blocked */
  186.          long save_BLev = BLevitation;
  187.  
  188.          BLevitation = 0L;
  189.          if (Levitation)
  190.              enl_msg(You_, "would levitate", "would have levitated",
  191.                      if_surroundings_permitted, "");
  192.          BLevitation = save_BLev;
  193.      }
  194.      /* actively flying handled earlier as a status condition */
  195.      if (BFlying) { /* flight is blocked */
  196.          long save_BFly = BFlying;
  197.  
  198.          BFlying = 0L;
  199.          if (Flying)
  200.              enl_msg(You_, "would fly", "would have flown",
  201.                      Levitation
  202.                         ? "if you weren't levitating"
  203.                         : (save_BFly == FROMOUTSIDE)
  204.                            ? if_surroundings_permitted
  205.                            /* both surroundings and [latent] levitation */
  206.                            : " if circumstances permitted",
  207.                      "");
  208.          BFlying = save_BFly;
  209.      }
  210.      /* actively walking on water handled earlier as a status condition */
  211.      if (Wwalking && !walking_on_water())
  212.          you_can("walk on water", from_what(WWALKING));
  213.      /* actively swimming (in water but not under it) handled earlier */
  214.      if (Swimming && (Underwater || !u.uinwater))
  215.          you_can("swim", from_what(SWIMMING));
  216.      if (Breathless)
  217.          you_can("survive without air", from_what(MAGICAL_BREATHING));
  218.      else if (Amphibious)
  219.          you_can("breathe water", from_what(MAGICAL_BREATHING));
  220.      if (Passes_walls)
  221.          you_can("walk through walls", from_what(PASSES_WALLS));
  222.  
  223.      /*** Physical attributes ***/
  224.      if (Regeneration)
  225.          enl_msg("You regenerate", "", "d", "", from_what(REGENERATION));
  226.      if (Slow_digestion)
  227.          you_have("slower digestion", from_what(SLOW_DIGESTION));
  228.      if (u.uhitinc)
  229.          you_have(enlght_combatinc("to hit", u.uhitinc, final, buf), "");
  230.      if (u.udaminc)
  231.          you_have(enlght_combatinc("damage", u.udaminc, final, buf), "");
  232.      if (u.uspellprot || Protection) {
  233.          int prot = 0;
  234.  
  235.          if (uleft && uleft->otyp == RIN_PROTECTION)
  236.              prot += uleft->spe;
  237.          if (uright && uright->otyp == RIN_PROTECTION)
  238.              prot += uright->spe;
  239.          if (HProtection & INTRINSIC)
  240.              prot += u.ublessed;
  241.          prot += u.uspellprot;
  242.          if (prot)
  243.              you_have(enlght_combatinc("defense", prot, final, buf), "");
  244.      }
  245.      if ((armpro = magic_negation(&youmonst)) > 0) {
  246.          /* magic cancellation factor, conferred by worn armor */
  247.          static const char *const mc_types[] = {
  248.              "" /*ordinary*/, "warded", "guarded", "protected",
  249.          };
  250.          /* sanity check */
  251.          if (armpro >= SIZE(mc_types))
  252.              armpro = SIZE(mc_types) - 1;
  253.          you_are(mc_types[armpro], "");
  254.      }
  255.      if (Half_physical_damage)
  256.          enlght_halfdmg(HALF_PHDAM, final);
  257.      if (Half_spell_damage)
  258.          enlght_halfdmg(HALF_SPDAM, final);
  259.      /* polymorph and other shape change */
  260.      if (Protection_from_shape_changers)
  261.          you_are("protected from shape changers",
  262.                  from_what(PROT_FROM_SHAPE_CHANGERS));
  263.      if (Unchanging) {
  264.          const char *what = 0;
  265.  
  266.          if (!Upolyd) /* Upolyd handled below after current form */
  267.              you_can("not change from your current form",
  268.                      from_what(UNCHANGING));
  269.          /* blocked shape changes */
  270.          if (Polymorph)
  271.              what = !final ? "polymorph" : "have polymorphed";
  272.          else if (u.ulycn >= LOW_PM)
  273.              what = !final ? "change shape" : "have changed shape";
  274.          if (what) {
  275.              Sprintf(buf, "would %s periodically", what);
  276.              /* omit from_what(UNCHANGING); too verbose */
  277.              enl_msg(You_, buf, buf, " if not locked into your current form",
  278.                      "");
  279.          }
  280.      } else if (Polymorph) {
  281.          you_are("polymorphing periodically", from_what(POLYMORPH));
  282.      }
  283.      if (Polymorph_control)
  284.          you_have("polymorph control", from_what(POLYMORPH_CONTROL));
  285.      if (Upolyd && u.umonnum != u.ulycn) {
  286.          /* foreign shape (except were-form which is handled below) */
  287.          Sprintf(buf, "polymorphed into %s", an(youmonst.data->mname));
  288.          if (wizard)
  289.              Sprintf(eos(buf), " (%d)", u.mtimedone);
  290.          you_are(buf, "");
  291.      }
  292.      if (lays_eggs(youmonst.data) && flags.female) /* Upolyd */
  293.          you_can("lay eggs", "");
  294.      if (u.ulycn >= LOW_PM) {
  295.          /* "you are a werecreature [in beast form]" */
  296.          Strcpy(buf, an(mons[u.ulycn].mname));
  297.          if (u.umonnum == u.ulycn) {
  298.              Strcat(buf, " in beast form");
  299.              if (wizard)
  300.                  Sprintf(eos(buf), " (%d)", u.mtimedone);
  301.          }
  302.          you_are(buf, "");
  303.      }
  304.      if (Unchanging && Upolyd) /* !Upolyd handled above */
  305.          you_can("not change from your current form", from_what(UNCHANGING));
  306.      if (Hate_silver)
  307.          you_are("harmed by silver", "");
  308.      /* movement and non-armor-based protection */
  309.      if (Fast)
  310.          you_are(Very_fast ? "very fast" : "fast", from_what(FAST));
  311.      if (Reflecting)
  312.          you_have("reflection", from_what(REFLECTING));
  313.      if (Free_action)
  314.          you_have("free action", from_what(FREE_ACTION));
  315.      if (Fixed_abil)
  316.          you_have("fixed abilities", from_what(FIXED_ABIL));
  317.      if (Lifesaved)
  318.          enl_msg("Your life ", "will be", "would have been", " saved", "");
  319.  
  320.      /*** Miscellany ***/
  321.      if (Luck) {
  322.          ltmp = abs((int) Luck);
  323.          Sprintf(buf, "%s%slucky",
  324.                  ltmp >= 10 ? "extremely " : ltmp >= 5 ? "very " : "",
  325.                  Luck < 0 ? "un" : "");
  326.          if (wizard)
  327.              Sprintf(eos(buf), " (%d)", Luck);
  328.          you_are(buf, "");
  329.      } else if (wizard)
  330.          enl_msg("Your luck ", "is", "was", " zero", "");
  331.      if (u.moreluck > 0)
  332.          you_have("extra luck", "");
  333.      else if (u.moreluck < 0)
  334.          you_have("reduced luck", "");
  335.      if (carrying(LUCKSTONE) || stone_luck(TRUE)) {
  336.          ltmp = stone_luck(0);
  337.          if (ltmp <= 0)
  338.              enl_msg("Bad luck ", "does", "did", " not time out for you", "");
  339.          if (ltmp >= 0)
  340.              enl_msg("Good luck ", "does", "did", " not time out for you", "");
  341.      }
  342.  
  343.      if (u.ugangr) {
  344.          Sprintf(buf, " %sangry with you",
  345.                  u.ugangr > 6 ? "extremely " : u.ugangr > 3 ? "very " : "");
  346.          if (wizard)
  347.              Sprintf(eos(buf), " (%d)", u.ugangr);
  348.          enl_msg(u_gname(), " is", " was", buf, "");
  349.      } else {
  350.          /*
  351.           * We need to suppress this when the game is over, because death
  352.           * can change the value calculated by can_pray(), potentially
  353.           * resulting in a false claim that you could have prayed safely.
  354.           */
  355.          if (!final) {
  356.  #if 0
  357.              /* "can [not] safely pray" vs "could [not] have safely prayed" */
  358.              Sprintf(buf, "%s%ssafely pray%s", can_pray(FALSE) ? "" : "not ",
  359.                      final ? "have " : "", final ? "ed" : "");
  360.  #else
  361.              Sprintf(buf, "%ssafely pray", can_pray(FALSE) ? "" : "not ");
  362.  #endif
  363.              if (wizard)
  364.                  Sprintf(eos(buf), " (%d)", u.ublesscnt);
  365.              you_can(buf, "");
  366.          }
  367.      }
  368.  
  369.      /* named fruit debugging (doesn't really belong here...) */
  370.      if (wizard) {
  371.          int fcount = 0;
  372.          struct fruit *f;
  373.          char buf2[BUFSZ];
  374.  
  375.          for (f = ffruit; f; f = f->nextf) {
  376.              Sprintf(buf, "Fruit %d ", ++fcount);
  377.              Sprintf(buf2, "%s (id %d)", f->fname, f->fid);
  378.              enl_msg(buf, "is ", "was ", buf2, "");
  379.          }
  380.          enl_msg("The current fruit ", "is ", "was ", pl_fruit, "");
  381.          Sprintf(buf, "%d", flags.made_fruit);
  382.          enl_msg("The made fruit flag ", "is ", "was ", buf, "");
  383.      }
  384.  
  385.      {
  386.          const char *p;
  387.  
  388.          buf[0] = '\0';
  389.          if (final < 2) { /* still in progress, or quit/escaped/ascended */
  390.              p = "survived after being killed ";
  391.              switch (u.umortality) {
  392.              case 0:
  393.                  p = !final ? (char *) 0 : "survived";
  394.                  break;
  395.              case 1:
  396.                  Strcpy(buf, "once");
  397.                  break;
  398.              case 2:
  399.                  Strcpy(buf, "twice");
  400.                  break;
  401.              case 3:
  402.                  Strcpy(buf, "thrice");
  403.                  break;
  404.              default:
  405.                  Sprintf(buf, "%d times", u.umortality);
  406.                  break;
  407.              }
  408.          } else { /* game ended in character's death */
  409.              p = "are dead";
  410.              switch (u.umortality) {
  411.              case 0:
  412.                  impossible("dead without dying?");
  413.              case 1:
  414.                  break; /* just "are dead" */
  415.              default:
  416.                  Sprintf(buf, " (%d%s time!)", u.umortality,
  417.                          ordin(u.umortality));
  418.                  break;
  419.              }
  420.          }
  421.          if (p)
  422.              enl_msg(You_, "have been killed ", p, buf, "");
  423.      }
  424.  }
  425.  

minimal_enlightenment

  1.  #if 0  /* no longer used */
  2.  STATIC_DCL boolean NDECL(minimal_enlightenment);
  3.  
  4.  /*
  5.   * Courtesy function for non-debug, non-explorer mode players
  6.   * to help refresh them about who/what they are.
  7.   * Returns FALSE if menu cancelled (dismissed with ESC), TRUE otherwise.
  8.   */
  9.  STATIC_OVL boolean
  10.  minimal_enlightenment()
  11.  {
  12.      winid tmpwin;
  13.      menu_item *selected;
  14.      anything any;
  15.      int genidx, n;
  16.      char buf[BUFSZ], buf2[BUFSZ];
  17.      static const char untabbed_fmtstr[] = "%-15s: %-12s";
  18.      static const char untabbed_deity_fmtstr[] = "%-17s%s";
  19.      static const char tabbed_fmtstr[] = "%s:\t%-12s";
  20.      static const char tabbed_deity_fmtstr[] = "%s\t%s";
  21.      static const char *fmtstr;
  22.      static const char *deity_fmtstr;
  23.  
  24.      fmtstr = iflags.menu_tab_sep ? tabbed_fmtstr : untabbed_fmtstr;
  25.      deity_fmtstr = iflags.menu_tab_sep ? tabbed_deity_fmtstr
  26.                                         : untabbed_deity_fmtstr;
  27.      any = zeroany;
  28.      buf[0] = buf2[0] = '\0';
  29.      tmpwin = create_nhwindow(NHW_MENU);
  30.      start_menu(tmpwin);
  31.      add_menu(tmpwin, NO_GLYPH, &any, 0, 0, iflags.menu_headings,
  32.               "Starting", FALSE);
  33.  
  34.      /* Starting name, race, role, gender */
  35.      Sprintf(buf, fmtstr, "name", plname);
  36.      add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_NONE, buf, FALSE);
  37.      Sprintf(buf, fmtstr, "race", urace.noun);
  38.      add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_NONE, buf, FALSE);
  39.      Sprintf(buf, fmtstr, "role",
  40.              (flags.initgend && urole.name.f) ? urole.name.f : urole.name.m);
  41.      add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_NONE, buf, FALSE);
  42.      Sprintf(buf, fmtstr, "gender", genders[flags.initgend].adj);
  43.      add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_NONE, buf, FALSE);
  44.  
  45.      /* Starting alignment */
  46.      Sprintf(buf, fmtstr, "alignment", align_str(u.ualignbase[A_ORIGINAL]));
  47.      add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_NONE, buf, FALSE);
  48.  
  49.      /* Current name, race, role, gender */
  50.      add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_NONE, "", FALSE);
  51.      add_menu(tmpwin, NO_GLYPH, &any, 0, 0, iflags.menu_headings,
  52.               "Current", FALSE);
  53.      Sprintf(buf, fmtstr, "race", Upolyd ? youmonst.data->mname : urace.noun);
  54.      add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_NONE, buf, FALSE);
  55.      if (Upolyd) {
  56.          Sprintf(buf, fmtstr, "role (base)",
  57.                  (u.mfemale && urole.name.f) ? urole.name.f
  58.                                              : urole.name.m);
  59.          add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_NONE, buf, FALSE);
  60.      } else {
  61.          Sprintf(buf, fmtstr, "role",
  62.                  (flags.female && urole.name.f) ? urole.name.f
  63.                                                 : urole.name.m);
  64.          add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_NONE, buf, FALSE);
  65.      }
  66.      /* don't want poly_gender() here; it forces `2' for non-humanoids */
  67.      genidx = is_neuter(youmonst.data) ? 2 : flags.female;
  68.      Sprintf(buf, fmtstr, "gender", genders[genidx].adj);
  69.      add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_NONE, buf, FALSE);
  70.      if (Upolyd && (int) u.mfemale != genidx) {
  71.          Sprintf(buf, fmtstr, "gender (base)", genders[u.mfemale].adj);
  72.          add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_NONE, buf, FALSE);
  73.      }
  74.  
  75.      /* Current alignment */
  76.      Sprintf(buf, fmtstr, "alignment", align_str(u.ualign.type));
  77.      add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_NONE, buf, FALSE);
  78.  
  79.      /* Deity list */
  80.      add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_NONE, "", FALSE);
  81.      add_menu(tmpwin, NO_GLYPH, &any, 0, 0, iflags.menu_headings,
  82.               "Deities", FALSE);
  83.      Sprintf(buf2, deity_fmtstr, align_gname(A_CHAOTIC),
  84.              (u.ualignbase[A_ORIGINAL] == u.ualign.type
  85.               && u.ualign.type == A_CHAOTIC)               ? " (s,c)"
  86.                  : (u.ualignbase[A_ORIGINAL] == A_CHAOTIC) ? " (s)"
  87.                  : (u.ualign.type   == A_CHAOTIC)          ? " (c)" : "");
  88.      Sprintf(buf, fmtstr, "Chaotic", buf2);
  89.      add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_NONE, buf, FALSE);
  90.  
  91.      Sprintf(buf2, deity_fmtstr, align_gname(A_NEUTRAL),
  92.              (u.ualignbase[A_ORIGINAL] == u.ualign.type
  93.               && u.ualign.type == A_NEUTRAL)               ? " (s,c)"
  94.                  : (u.ualignbase[A_ORIGINAL] == A_NEUTRAL) ? " (s)"
  95.                  : (u.ualign.type   == A_NEUTRAL)          ? " (c)" : "");
  96.      Sprintf(buf, fmtstr, "Neutral", buf2);
  97.      add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_NONE, buf, FALSE);
  98.  
  99.      Sprintf(buf2, deity_fmtstr, align_gname(A_LAWFUL),
  100.              (u.ualignbase[A_ORIGINAL] == u.ualign.type
  101.               && u.ualign.type == A_LAWFUL)                ? " (s,c)"
  102.                  : (u.ualignbase[A_ORIGINAL] == A_LAWFUL)  ? " (s)"
  103.                  : (u.ualign.type   == A_LAWFUL)           ? " (c)" : "");
  104.      Sprintf(buf, fmtstr, "Lawful", buf2);
  105.      add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_NONE, buf, FALSE);
  106.  
  107.      end_menu(tmpwin, "Base Attributes");
  108.      n = select_menu(tmpwin, PICK_NONE, &selected);
  109.      destroy_nhwindow(tmpwin);
  110.      return (boolean) (n != -1);
  111.  }
  112.  #endif /*0*/
  113.  

doattributes

  1.  /* ^X command */
  2.  STATIC_PTR int
  3.  doattributes(VOID_ARGS)
  4.  {
  5.      int mode = BASICENLIGHTENMENT;
  6.  
  7.      /* show more--as if final disclosure--for wizard and explore modes */
  8.      if (wizard || discover)
  9.          mode |= MAGICENLIGHTENMENT;
  10.  
  11.      enlightenment(mode, ENL_GAMEINPROGRESS);
  12.      return 0;
  13.  }
  14.  

youhiding

  1.  void
  2.  youhiding(via_enlghtmt, msgflag)
  3.  boolean via_enlghtmt; /* englightment line vs topl message */
  4.  int msgflag;          /* for variant message phrasing */
  5.  {
  6.      char *bp, buf[BUFSZ];
  7.  
  8.      Strcpy(buf, "hiding");
  9.      if (youmonst.m_ap_type != M_AP_NOTHING) {
  10.          /* mimic; hero is only able to mimic a strange object or gold
  11.             or hallucinatory alternative to gold, so we skip the details
  12.             for the hypothetical furniture and monster cases */
  13.          bp = eos(strcpy(buf, "mimicking"));
  14.          if (youmonst.m_ap_type == M_AP_OBJECT) {
  15.              Sprintf(bp, " %s", an(simple_typename(youmonst.mappearance)));
  16.          } else if (youmonst.m_ap_type == M_AP_FURNITURE) {
  17.              Strcpy(bp, " something");
  18.          } else if (youmonst.m_ap_type == M_AP_MONSTER) {
  19.              Strcpy(bp, " someone");
  20.          } else {
  21.              ; /* something unexpected; leave 'buf' as-is */
  22.          }
  23.      } else if (u.uundetected) {
  24.          bp = eos(buf); /* points past "hiding" */
  25.          if (youmonst.data->mlet == S_EEL) {
  26.              if (is_pool(u.ux, u.uy))
  27.                  Sprintf(bp, " in the %s", waterbody_name(u.ux, u.uy));
  28.          } else if (hides_under(youmonst.data)) {
  29.              struct obj *o = level.objects[u.ux][u.uy];
  30.  
  31.              if (o)
  32.                  Sprintf(bp, " underneath %s", ansimpleoname(o));
  33.          } else if (is_clinger(youmonst.data) || Flying) {
  34.              /* Flying: 'lurker above' hides on ceiling but doesn't cling */
  35.              Sprintf(bp, " on the %s", ceiling(u.ux, u.uy));
  36.          } else {
  37.              /* on floor; is_hider() but otherwise not special: 'trapper' */
  38.              if (u.utrap && u.utraptype == TT_PIT) {
  39.                  struct trap *t = t_at(u.ux, u.uy);
  40.  
  41.                  Sprintf(bp, " in a %spit",
  42.                          (t && t->ttyp == SPIKED_PIT) ? "spiked " : "");
  43.              } else
  44.                  Sprintf(bp, " on the %s", surface(u.ux, u.uy));
  45.          }
  46.      } else {
  47.          ; /* shouldn't happen; will result in generic "you are hiding" */
  48.      }
  49.  
  50.      if (via_enlghtmt) {
  51.          int final = msgflag; /* 'final' is used by you_are() macro */
  52.  
  53.          you_are(buf, "");
  54.      } else {
  55.          /* for dohide(), when player uses '#monster' command */
  56.          You("are %s %s.", msgflag ? "already" : "now", buf);
  57.      }
  58.  }
  59.  

doconduct

  1.  /* KMH, #conduct
  2.   * (shares enlightenment's tense handling)
  3.   */
  4.  STATIC_PTR int
  5.  doconduct(VOID_ARGS)
  6.  {
  7.      show_conduct(0);
  8.      return 0;
  9.  }
  10.  

show_conduct

  1.  void
  2.  show_conduct(final)
  3.  int final;
  4.  {
  5.      char buf[BUFSZ];
  6.      int ngenocided;
  7.  
  8.      /* Create the conduct window */
  9.      en_win = create_nhwindow(NHW_MENU);
  10.      putstr(en_win, 0, "Voluntary challenges:");
  11.  
  12.      if (u.uroleplay.blind)
  13.          you_have_been("blind from birth");
  14.      if (u.uroleplay.nudist)
  15.          you_have_been("faithfully nudist");
  16.  
  17.      if (!u.uconduct.food)
  18.          enl_msg(You_, "have gone", "went", " without food", "");
  19.      /* But beverages are okay */
  20.      else if (!u.uconduct.unvegan)
  21.          you_have_X("followed a strict vegan diet");
  22.      else if (!u.uconduct.unvegetarian)
  23.          you_have_been("vegetarian");
  24.  
  25.      if (!u.uconduct.gnostic)
  26.          you_have_been("an atheist");
  27.  
  28.      if (!u.uconduct.weaphit) {
  29.          you_have_never("hit with a wielded weapon");
  30.      } else if (wizard) {
  31.          Sprintf(buf, "used a wielded weapon %ld time%s", u.uconduct.weaphit,
  32.                  plur(u.uconduct.weaphit));
  33.          you_have_X(buf);
  34.      }
  35.      if (!u.uconduct.killer)
  36.          you_have_been("a pacifist");
  37.  
  38.      if (!u.uconduct.literate) {
  39.          you_have_been("illiterate");
  40.      } else if (wizard) {
  41.          Sprintf(buf, "read items or engraved %ld time%s", u.uconduct.literate,
  42.                  plur(u.uconduct.literate));
  43.          you_have_X(buf);
  44.      }
  45.  
  46.      ngenocided = num_genocides();
  47.      if (ngenocided == 0) {
  48.          you_have_never("genocided any monsters");
  49.      } else {
  50.          Sprintf(buf, "genocided %d type%s of monster%s", ngenocided,
  51.                  plur(ngenocided), plur(ngenocided));
  52.          you_have_X(buf);
  53.      }
  54.  
  55.      if (!u.uconduct.polypiles) {
  56.          you_have_never("polymorphed an object");
  57.      } else if (wizard) {
  58.          Sprintf(buf, "polymorphed %ld item%s", u.uconduct.polypiles,
  59.                  plur(u.uconduct.polypiles));
  60.          you_have_X(buf);
  61.      }
  62.  
  63.      if (!u.uconduct.polyselfs) {
  64.          you_have_never("changed form");
  65.      } else if (wizard) {
  66.          Sprintf(buf, "changed form %ld time%s", u.uconduct.polyselfs,
  67.                  plur(u.uconduct.polyselfs));
  68.          you_have_X(buf);
  69.      }
  70.  
  71.      if (!u.uconduct.wishes) {
  72.          you_have_X("used no wishes");
  73.      } else {
  74.          Sprintf(buf, "used %ld wish%s", u.uconduct.wishes,
  75.                  (u.uconduct.wishes > 1L) ? "es" : "");
  76.          you_have_X(buf);
  77.  
  78.          if (!u.uconduct.wisharti)
  79.              enl_msg(You_, "have not wished", "did not wish",
  80.                      " for any artifacts", "");
  81.      }
  82.  
  83.      /* Pop up the window and wait for a key */
  84.      display_nhwindow(en_win, TRUE);
  85.      destroy_nhwindow(en_win);
  86.      en_win = WIN_ERR;
  87.  }
  88.  

Command list data structures

  1.  #ifndef M
  2.  #ifndef NHSTDC
  3.  #define M(c) (0x80 | (c))
  4.  #else
  5.  #define M(c) ((c) -128)
  6.  #endif /* NHSTDC */
  7.  #endif
  8.  #ifndef C
  9.  #define C(c) (0x1f & (c))
  10.  #endif
  11.  
  12.  static const struct func_tab cmdlist[] = {
  13.      { C('d'), FALSE, dokick }, /* "D" is for door!...?  Msg is in dokick.c */
  14.      { C('e'), TRUE, wiz_detect },
  15.      { C('f'), TRUE, wiz_map },
  16.      { C('g'), TRUE, wiz_genesis },
  17.      { C('i'), TRUE, wiz_identify },
  18.      { C('l'), TRUE, doredraw },    /* if number_pad is set */
  19.      { C('n'), TRUE, donamelevel }, /* if number_pad is set */
  20.      { C('o'), TRUE, dooverview_or_wiz_where }, /* depends on wizard status */
  21.      { C('p'), TRUE, doprev_message },
  22.      { C('r'), TRUE, doredraw },
  23.      { C('t'), TRUE, dotele },
  24.      { C('v'), TRUE, wiz_level_tele },
  25.      { C('w'), TRUE, wiz_wish },
  26.      { C('x'), TRUE, doattributes },
  27.      { C('z'), TRUE, dosuspend_core },
  28.      { 'a', FALSE, doapply },
  29.      { 'A', FALSE, doddoremarm },
  30.      { M('a'), TRUE, doorganize },
  31.      { M('A'), TRUE, donamelevel }, /* #annotate */
  32.      /*  'b', 'B' : go sw */
  33.      { 'c', FALSE, doclose },
  34.      { 'C', TRUE, docallcmd },
  35.      { M('c'), TRUE, dotalk },
  36.      { M('C'), TRUE, doconduct }, /* #conduct */
  37.      { 'd', FALSE, dodrop },
  38.      { 'D', FALSE, doddrop },
  39.      { M('d'), FALSE, dodip },
  40.      { 'e', FALSE, doeat },
  41.      { 'E', FALSE, doengrave },
  42.      { M('e'), TRUE, enhance_weapon_skill },
  43.      { 'f', FALSE, dofire },
  44.      /*  'F' : fight (one time) */
  45.      { M('f'), FALSE, doforce },
  46.      /*  'g', 'G' : multiple go */
  47.      /*  'h', 'H' : go west */
  48.      { 'h', TRUE, dohelp }, /* if number_pad is set */
  49.      { 'i', TRUE, ddoinv },
  50.      { 'I', TRUE, dotypeinv }, /* Robert Viduya */
  51.      { M('i'), TRUE, doinvoke },
  52.      /*  'j', 'J', 'k', 'K', 'l', 'L', 'm', 'M', 'n', 'N' : move commands */
  53.      { 'j', FALSE, dojump }, /* if number_pad is on */
  54.      { M('j'), FALSE, dojump },
  55.      { 'k', FALSE, dokick }, /* if number_pad is on */
  56.      { 'l', FALSE, doloot }, /* if number_pad is on */
  57.      { M('l'), FALSE, doloot },
  58.      /*  'n' prefixes a count if number_pad is on */
  59.      { M('m'), TRUE, domonability },
  60.      { 'N', TRUE, docallcmd }, /* if number_pad is on */
  61.      { M('n'), TRUE, docallcmd },
  62.      { M('N'), TRUE, docallcmd },
  63.      { 'o', FALSE, doopen },
  64.      { 'O', TRUE, doset },
  65.      { M('o'), FALSE, dosacrifice },
  66.      { M('O'), TRUE, dooverview }, /* #overview */
  67.      { 'p', FALSE, dopay },
  68.      { 'P', FALSE, doputon },
  69.      { M('p'), TRUE, dopray },
  70.      { 'q', FALSE, dodrink },
  71.      { 'Q', FALSE, dowieldquiver },
  72.      { M('q'), TRUE, done2 },
  73.      { 'r', FALSE, doread },
  74.      { 'R', FALSE, doremring },
  75.      { M('r'), FALSE, dorub },
  76.      { M('R'), FALSE, doride }, /* #ride */
  77.      { 's', TRUE, dosearch, "searching" },
  78.      { 'S', TRUE, dosave },
  79.      { M('s'), FALSE, dosit },
  80.      { 't', FALSE, dothrow },
  81.      { 'T', FALSE, dotakeoff },
  82.      { M('t'), TRUE, doturn },
  83.      { M('T'), FALSE, dotip }, /* #tip */
  84.      /*  'u', 'U' : go ne */
  85.      { 'u', FALSE, dountrap }, /* if number_pad is on */
  86.      { M('u'), FALSE, dountrap },
  87.      { 'v', TRUE, doversion },
  88.      { 'V', TRUE, dohistory },
  89.      { M('v'), TRUE, doextversion },
  90.      { 'w', FALSE, dowield },
  91.      { 'W', FALSE, dowear },
  92.      { M('w'), FALSE, dowipe },
  93.      { 'x', FALSE, doswapweapon },
  94.      { 'X', FALSE, dotwoweapon },
  95.      /*  'y', 'Y' : go nw */
  96.      { 'z', FALSE, dozap },
  97.      { 'Z', TRUE, docast },
  98.      { '<', FALSE, doup },
  99.      { '>', FALSE, dodown },
  100.      { '/', TRUE, dowhatis },
  101.      { '&', TRUE, dowhatdoes },
  102.      { '?', TRUE, dohelp },
  103.      { M('?'), TRUE, doextlist },
  104.  #ifdef SHELL
  105.      { '!', TRUE, dosh },
  106.  #endif
  107.      { '.', TRUE, donull, "waiting" },
  108.      { ' ', TRUE, donull, "waiting" },
  109.      { ',', FALSE, dopickup },
  110.      { ':', TRUE, dolook },
  111.      { ';', TRUE, doquickwhatis },
  112.      { '^', TRUE, doidtrap },
  113.      { '\\', TRUE, dodiscovered }, /* Robert Viduya */
  114.      { '`', TRUE, doclassdisco },
  115.      { '@', TRUE, dotogglepickup },
  116.      { M('2'), FALSE, dotwoweapon },
  117.      { WEAPON_SYM, TRUE, doprwep },
  118.      { ARMOR_SYM, TRUE, doprarm },
  119.      { RING_SYM, TRUE, doprring },
  120.      { AMULET_SYM, TRUE, dopramulet },
  121.      { TOOL_SYM, TRUE, doprtool },
  122.      { '*', TRUE, doprinuse }, /* inventory of all equipment in use */
  123.      { GOLD_SYM, TRUE, doprgold },
  124.      { SPBOOK_SYM, TRUE, dovspell }, /* Mike Stephenson */
  125.      { '#', TRUE, doextcmd },
  126.      { '_', TRUE, dotravel },
  127.      { 0, 0, 0, 0 }
  128.  };
  129.  
  130.  struct ext_func_tab extcmdlist[] = {
  131.      { "adjust", "adjust inventory letters", doorganize, TRUE },
  132.      { "annotate", "name current level", donamelevel, TRUE },
  133.      { "chat", "talk to someone", dotalk, TRUE }, /* converse? */
  134.      { "conduct", "list voluntary challenges you have maintained", doconduct,
  135.        TRUE },
  136.      { "dip", "dip an object into something", dodip, FALSE },
  137.      { "enhance", "advance or check weapon and spell skills",
  138.        enhance_weapon_skill, TRUE },
  139.      { "exploremode", "enter explore mode", enter_explore_mode, TRUE },
  140.      { "force", "force a lock", doforce, FALSE },
  141.      { "invoke", "invoke an object's powers", doinvoke, TRUE },
  142.      { "jump", "jump to a location", dojump, FALSE },
  143.      { "loot", "loot a box on the floor", doloot, FALSE },
  144.      { "monster", "use a monster's special ability", domonability, TRUE },
  145.      { "name", "name a monster or an object", docallcmd, TRUE },
  146.      { "offer", "offer a sacrifice to the gods", dosacrifice, FALSE },
  147.      { "overview", "show an overview of the dungeon", dooverview, TRUE },
  148.      { "pray", "pray to the gods for help", dopray, TRUE },
  149.      { "quit", "exit without saving current game", done2, TRUE },
  150.      { "ride", "ride (or stop riding) a monster", doride, FALSE },
  151.      { "rub", "rub a lamp or a stone", dorub, FALSE },
  152.      { "sit", "sit down", dosit, FALSE },
  153.      { "terrain", "show map without obstructions", doterrain, TRUE },
  154.      { "tip", "empty a container", dotip, FALSE },
  155.      { "turn", "turn undead", doturn, TRUE },
  156.      { "twoweapon", "toggle two-weapon combat", dotwoweapon, FALSE },
  157.      { "untrap", "untrap something", dountrap, FALSE },
  158.      { "version", "list compile time options for this version of NetHack",
  159.        doextversion, TRUE },
  160.      { "wipe", "wipe off your face", dowipe, FALSE },
  161.      { "?", "get this list of extended commands", doextlist, TRUE },
  162.      /*
  163.       * There must be a blank entry here for every entry in the table
  164.       * below.
  165.       */
  166.      { (char *) 0, (char *) 0, donull, TRUE }, /* levelchange */
  167.      { (char *) 0, (char *) 0, donull, TRUE }, /* lightsources */
  168.  #ifdef DEBUG_MIGRATING_MONS
  169.      { (char *) 0, (char *) 0, donull, TRUE }, /* migratemons */
  170.  #endif
  171.      { (char *) 0, (char *) 0, donull, TRUE }, /* monpolycontrol */
  172.      { (char *) 0, (char *) 0, donull, TRUE }, /* panic */
  173.      { (char *) 0, (char *) 0, donull, TRUE }, /* polyself */
  174.  #ifdef PORT_DEBUG
  175.      { (char *) 0, (char *) 0, donull, TRUE }, /* portdebug */
  176.  #endif
  177.      { (char *) 0, (char *) 0, donull, TRUE }, /* seenv */
  178.      { (char *) 0, (char *) 0, donull, TRUE }, /* stats */
  179.      { (char *) 0, (char *) 0, donull, TRUE }, /* timeout */
  180.      { (char *) 0, (char *) 0, donull, TRUE }, /* vanquished */
  181.      { (char *) 0, (char *) 0, donull, TRUE }, /* vision */
  182.      { (char *) 0, (char *) 0, donull, TRUE }, /* wizsmell */
  183.  #ifdef DEBUG
  184.      { (char *) 0, (char *) 0, donull, TRUE }, /* wizdebug_traveldisplay */
  185.      { (char *) 0, (char *) 0, donull, TRUE }, /* wizdebug_bury */
  186.  #endif
  187.      { (char *) 0, (char *) 0, donull, TRUE }, /* wizrumorcheck */
  188.      { (char *) 0, (char *) 0, donull, TRUE }, /* wmode */
  189.      { (char *) 0, (char *) 0, donull, TRUE }  /* sentinel */
  190.  };
  191.  
  192.  /* there must be a placeholder in the table above for every entry here */
  193.  static const struct ext_func_tab debug_extcmdlist[] = {
  194.      { "levelchange", "change experience level", wiz_level_change, TRUE },
  195.      { "lightsources", "show mobile light sources", wiz_light_sources, TRUE },
  196.  #ifdef DEBUG_MIGRATING_MONS
  197.      { "migratemons", "migrate n random monsters", wiz_migrate_mons, TRUE },
  198.  #endif
  199.      { "monpolycontrol", "control monster polymorphs", wiz_mon_polycontrol,
  200.        TRUE },
  201.      { "panic", "test panic routine (fatal to game)", wiz_panic, TRUE },
  202.      { "polyself", "polymorph self", wiz_polyself, TRUE },
  203.  #ifdef PORT_DEBUG
  204.      { "portdebug", "wizard port debug command", wiz_port_debug, TRUE },
  205.  #endif
  206.      { "seenv", "show seen vectors", wiz_show_seenv, TRUE },
  207.      { "stats", "show memory statistics", wiz_show_stats, TRUE },
  208.      { "timeout", "look at timeout queue", wiz_timeout_queue, TRUE },
  209.      { "vanquished", "list vanquished monsters", dovanquished, TRUE },
  210.      { "vision", "show vision array", wiz_show_vision, TRUE },
  211.      { "wizsmell", "smell monster", wiz_smell, TRUE },
  212.  #ifdef DEBUG
  213.      { "wizdebug_traveldisplay", "wizard debug: toggle travel display",
  214.        wiz_debug_cmd_traveldisplay, TRUE },
  215.      { "wizdebug_bury", "wizard debug: bury objs under and around you",
  216.        wiz_debug_cmd_bury, TRUE },
  217.  #endif
  218.      { "wizrumorcheck", "verify rumor boundaries", wiz_rumor_check, TRUE },
  219.      { "wmode", "show wall modes", wiz_show_wmodes, TRUE },
  220.      { (char *) 0, (char *) 0, donull, TRUE }
  221.  };
  222.  

add_debug_extended_commands

  1.  /*
  2.   * Insert debug commands into the extended command list.  This function
  3.   * assumes that the last entry will be the help entry.
  4.   *
  5.   * You must add entries in ext_func_tab every time you add one to the
  6.   * debug_extcmdlist().
  7.   */
  8.  void
  9.  add_debug_extended_commands()
  10.  {
  11.      int i, j, k, n;
  12.  
  13.      /* count the # of help entries */
  14.      for (n = 0; extcmdlist[n].ef_txt[0] != '?'; n++)
  15.          ;
  16.  
  17.      for (i = 0; debug_extcmdlist[i].ef_txt; i++) {
  18.          /* need enough room for "?" entry plus terminator */
  19.          if (n + 2 >= SIZE(extcmdlist))
  20.              panic("Too many debugging commands!");
  21.          for (j = 0; j < n; j++)
  22.              if (strcmp(debug_extcmdlist[i].ef_txt, extcmdlist[j].ef_txt) < 0)
  23.                  break;
  24.  
  25.          /* insert i'th debug entry into extcmdlist[j], pushing down  */
  26.          for (k = n; k >= j; --k)
  27.              extcmdlist[k + 1] = extcmdlist[k];
  28.          extcmdlist[j] = debug_extcmdlist[i];
  29.          n++; /* now an extra entry */
  30.      }
  31.  }
  32.  

cmd_from_func

  1.  STATIC_OVL char
  2.  cmd_from_func(fn)
  3.  int NDECL((*fn));
  4.  {
  5.      int i;
  6.      for (i = 0; i < SIZE(cmdlist); ++i)
  7.          if (cmdlist[i].f_funct == fn)
  8.              return cmdlist[i].f_char;
  9.      return 0;
  10.  }
  11.  

size_obj

  1.  static const char template[] = "%-18s %4ld  %6ld";
  2.  static const char count_str[] = "                   count  bytes";
  3.  static const char separator[] = "------------------ -----  ------";
  4.  
  5.  STATIC_OVL int
  6.  size_obj(otmp)
  7.  struct obj *otmp;
  8.  {
  9.      int sz = (int) sizeof(struct obj);
  10.  
  11.      if (otmp->oextra) {
  12.          sz += (int) sizeof(struct oextra);
  13.          if (ONAME(otmp))
  14.              sz += (int) strlen(ONAME(otmp)) + 1;
  15.          if (OMONST(otmp))
  16.              sz += (int) sizeof(struct monst);
  17.          if (OMID(otmp))
  18.              sz += (int) sizeof(unsigned);
  19.          if (OLONG(otmp))
  20.              sz += (int) sizeof(long);
  21.          if (OMAILCMD(otmp))
  22.              sz += (int) strlen(OMAILCMD(otmp)) + 1;
  23.      }
  24.      return sz;
  25.  }
  26.  

count_obj

  1.  STATIC_OVL void
  2.  count_obj(chain, total_count, total_size, top, recurse)
  3.  struct obj *chain;
  4.  long *total_count;
  5.  long *total_size;
  6.  boolean top;
  7.  boolean recurse;
  8.  {
  9.      long count, size;
  10.      struct obj *obj;
  11.  
  12.      for (count = size = 0, obj = chain; obj; obj = obj->nobj) {
  13.          if (top) {
  14.              count++;
  15.              size += size_obj(obj);
  16.          }
  17.          if (recurse && obj->cobj)
  18.              count_obj(obj->cobj, total_count, total_size, TRUE, TRUE);
  19.      }
  20.      *total_count += count;
  21.      *total_size += size;
  22.  }
  23.  

obj_chain

  1.  STATIC_OVL void
  2.  obj_chain(win, src, chain, total_count, total_size)
  3.  winid win;
  4.  const char *src;
  5.  struct obj *chain;
  6.  long *total_count;
  7.  long *total_size;
  8.  {
  9.      char buf[BUFSZ];
  10.      long count = 0, size = 0;
  11.  
  12.      count_obj(chain, &count, &size, TRUE, FALSE);
  13.      *total_count += count;
  14.      *total_size += size;
  15.      Sprintf(buf, template, src, count, size);
  16.      putstr(win, 0, buf);
  17.  }
  18.  

mon_invent_chain

  1.  STATIC_OVL void
  2.  mon_invent_chain(win, src, chain, total_count, total_size)
  3.  winid win;
  4.  const char *src;
  5.  struct monst *chain;
  6.  long *total_count;
  7.  long *total_size;
  8.  {
  9.      char buf[BUFSZ];
  10.      long count = 0, size = 0;
  11.      struct monst *mon;
  12.  
  13.      for (mon = chain; mon; mon = mon->nmon)
  14.          count_obj(mon->minvent, &count, &size, TRUE, FALSE);
  15.      *total_count += count;
  16.      *total_size += size;
  17.      Sprintf(buf, template, src, count, size);
  18.      putstr(win, 0, buf);
  19.  }
  20.  

contained

  1.  STATIC_OVL void
  2.  contained(win, src, total_count, total_size)
  3.  winid win;
  4.  const char *src;
  5.  long *total_count;
  6.  long *total_size;
  7.  {
  8.      char buf[BUFSZ];
  9.      long count = 0, size = 0;
  10.      struct monst *mon;
  11.  
  12.      count_obj(invent, &count, &size, FALSE, TRUE);
  13.      count_obj(fobj, &count, &size, FALSE, TRUE);
  14.      count_obj(level.buriedobjlist, &count, &size, FALSE, TRUE);
  15.      count_obj(migrating_objs, &count, &size, FALSE, TRUE);
  16.      /* DEADMONSTER check not required in this loop since they have no
  17.       * inventory */
  18.      for (mon = fmon; mon; mon = mon->nmon)
  19.          count_obj(mon->minvent, &count, &size, FALSE, TRUE);
  20.      for (mon = migrating_mons; mon; mon = mon->nmon)
  21.          count_obj(mon->minvent, &count, &size, FALSE, TRUE);
  22.  
  23.      *total_count += count;
  24.      *total_size += size;
  25.  
  26.      Sprintf(buf, template, src, count, size);
  27.      putstr(win, 0, buf);
  28.  }
  29.  

size_monst

  1.  STATIC_OVL int
  2.  size_monst(mtmp)
  3.  struct monst *mtmp;
  4.  {
  5.      int sz = (int) sizeof(struct monst);
  6.  
  7.      if (mtmp->mextra) {
  8.          sz += (int) sizeof(struct mextra);
  9.          if (MNAME(mtmp))
  10.              sz += (int) strlen(MNAME(mtmp)) + 1;
  11.          if (EGD(mtmp))
  12.              sz += (int) sizeof(struct egd);
  13.          if (EPRI(mtmp))
  14.              sz += (int) sizeof(struct epri);
  15.          if (ESHK(mtmp))
  16.              sz += (int) sizeof(struct eshk);
  17.          if (EMIN(mtmp))
  18.              sz += (int) sizeof(struct emin);
  19.          if (EDOG(mtmp))
  20.              sz += (int) sizeof(struct edog);
  21.          /* mextra->mcorpsenm doesn't point to more memory */
  22.      }
  23.      return sz;
  24.  }
  25.  

mon_chain

  1.  STATIC_OVL void
  2.  mon_chain(win, src, chain, total_count, total_size)
  3.  winid win;
  4.  const char *src;
  5.  struct monst *chain;
  6.  long *total_count;
  7.  long *total_size;
  8.  {
  9.      char buf[BUFSZ];
  10.      long count, size;
  11.      struct monst *mon;
  12.  
  13.      for (count = size = 0, mon = chain; mon; mon = mon->nmon) {
  14.          count++;
  15.          size += size_monst(mon);
  16.      }
  17.      *total_count += count;
  18.      *total_size += size;
  19.      Sprintf(buf, template, src, count, size);
  20.      putstr(win, 0, buf);
  21.  }
  22.  

wiz_show_stats

  1.  /*
  2.   * Display memory usage of all monsters and objects on the level.
  3.   */
  4.  static int
  5.  wiz_show_stats()
  6.  {
  7.      char buf[BUFSZ];
  8.      winid win;
  9.      long total_obj_size = 0, total_obj_count = 0;
  10.      long total_mon_size = 0, total_mon_count = 0;
  11.  
  12.      win = create_nhwindow(NHW_TEXT);
  13.      putstr(win, 0, "Current memory statistics:");
  14.      putstr(win, 0, "");
  15.      Sprintf(buf, "Objects, size %d", (int) sizeof(struct obj));
  16.      putstr(win, 0, buf);
  17.      putstr(win, 0, "");
  18.      putstr(win, 0, count_str);
  19.  
  20.      obj_chain(win, "invent", invent, &total_obj_count, &total_obj_size);
  21.      obj_chain(win, "fobj", fobj, &total_obj_count, &total_obj_size);
  22.      obj_chain(win, "buried", level.buriedobjlist, &total_obj_count,
  23.                &total_obj_size);
  24.      obj_chain(win, "migrating obj", migrating_objs, &total_obj_count,
  25.                &total_obj_size);
  26.      mon_invent_chain(win, "minvent", fmon, &total_obj_count, &total_obj_size);
  27.      mon_invent_chain(win, "migrating minvent", migrating_mons,
  28.                       &total_obj_count, &total_obj_size);
  29.  
  30.      contained(win, "contained", &total_obj_count, &total_obj_size);
  31.  
  32.      putstr(win, 0, separator);
  33.      Sprintf(buf, template, "Total", total_obj_count, total_obj_size);
  34.      putstr(win, 0, buf);
  35.  
  36.      putstr(win, 0, "");
  37.      putstr(win, 0, "");
  38.      Sprintf(buf, "Monsters, size %d", (int) sizeof(struct monst));
  39.      putstr(win, 0, buf);
  40.      putstr(win, 0, "");
  41.  
  42.      mon_chain(win, "fmon", fmon, &total_mon_count, &total_mon_size);
  43.      mon_chain(win, "migrating", migrating_mons, &total_mon_count,
  44.                &total_mon_size);
  45.  
  46.      putstr(win, 0, separator);
  47.      Sprintf(buf, template, "Total", total_mon_count, total_mon_size);
  48.      putstr(win, 0, buf);
  49.  
  50.  #if defined(__BORLANDC__) && !defined(_WIN32)
  51.      show_borlandc_stats(win);
  52.  #endif
  53.  
  54.      display_nhwindow(win, FALSE);
  55.      destroy_nhwindow(win);
  56.      return 0;
  57.  }
  58.  

sanity_check

  1.  void
  2.  sanity_check()
  3.  {
  4.      obj_sanity_check();
  5.      timer_sanity_check();
  6.      mon_sanity_check();
  7.      light_sources_sanity_check();
  8.  }
  9.  

wiz_migrate_mons

  1.  #ifdef DEBUG_MIGRATING_MONS
  2.  static int
  3.  wiz_migrate_mons()
  4.  {
  5.      int mcount = 0;
  6.      char inbuf[BUFSZ];
  7.      struct permonst *ptr;
  8.      struct monst *mtmp;
  9.      d_level tolevel;
  10.  
  11.      getlin("How many random monsters to migrate? [0]", inbuf);
  12.      if (*inbuf == '\033')
  13.          return 0;
  14.      mcount = atoi(inbuf);
  15.      if (mcount < 0 || mcount > (COLNO * ROWNO) || Is_botlevel(&u.uz))
  16.          return 0;
  17.      while (mcount > 0) {
  18.          if (Is_stronghold(&u.uz))
  19.              assign_level(&tolevel, &valley_level);
  20.          else
  21.              get_level(&tolevel, depth(&u.uz) + 1);
  22.          ptr = rndmonst();
  23.          mtmp = makemon(ptr, 0, 0, NO_MM_FLAGS);
  24.          if (mtmp)
  25.              migrate_to_level(mtmp, ledger_no(&tolevel), MIGR_RANDOM,
  26.                               (coord *) 0);
  27.          mcount--;
  28.      }
  29.      return 0;
  30.  }
  31.  #endif
  32.  

reset_commands

  1.  #define unctrl(c) ((c) <= C('z') ? (0x60 | (c)) : (c))
  2.  #define unmeta(c) (0x7f & (c))
  3.  
  4.  /* called at startup and after number_pad is twiddled */
  5.  void
  6.  reset_commands(initial)
  7.  boolean initial;
  8.  {
  9.      static const char sdir[] = "hykulnjb><",
  10.                        sdir_swap_yz[] = "hzkulnjb><",
  11.                        ndir[] = "47896321><",
  12.                        ndir_phone_layout[] = "41236987><";
  13.      static const int ylist[] = {
  14.          'y', 'Y', C('y'), M('y'), M('Y'), M(C('y'))
  15.      };
  16.      const struct func_tab *cmdtmp;
  17.      boolean flagtemp;
  18.      int c, i, updated = 0;
  19.  
  20.      if (initial) {
  21.          updated = 1;
  22.          for (i = 0; i < SIZE(cmdlist); i++) {
  23.              c = cmdlist[i].f_char & 0xff;
  24.              Cmd.commands[c] = &cmdlist[i];
  25.          }
  26.          Cmd.num_pad = FALSE;
  27.          Cmd.pcHack_compat = Cmd.phone_layout = Cmd.swap_yz = FALSE;
  28.      } else {
  29.          /* basic num_pad */
  30.          flagtemp = iflags.num_pad;
  31.          if (flagtemp != Cmd.num_pad) {
  32.              Cmd.num_pad = flagtemp;
  33.              ++updated;
  34.          }
  35.          /* swap_yz mode (only applicable for !num_pad) */
  36.          flagtemp = (iflags.num_pad_mode & 1) ? !Cmd.num_pad : FALSE;
  37.          if (flagtemp != Cmd.swap_yz) {
  38.              Cmd.swap_yz = flagtemp;
  39.              ++updated;
  40.              /* Cmd.swap_yz has been toggled;
  41.                 perform the swap (or reverse previous one) */
  42.              for (i = 0; i < SIZE(ylist); i++) {
  43.                  c = ylist[i] & 0xff;
  44.                  cmdtmp = Cmd.commands[c];              /* tmp = [y] */
  45.                  Cmd.commands[c] = Cmd.commands[c + 1]; /* [y] = [z] */
  46.                  Cmd.commands[c + 1] = cmdtmp;          /* [z] = tmp */
  47.              }
  48.          }
  49.          /* MSDOS compatibility mode (only applicable for num_pad) */
  50.          flagtemp = (iflags.num_pad_mode & 1) ? Cmd.num_pad : FALSE;
  51.          if (flagtemp != Cmd.pcHack_compat) {
  52.              Cmd.pcHack_compat = flagtemp;
  53.              ++updated;
  54.              /* pcHack_compat has been toggled */
  55.              c = M('5') & 0xff;
  56.              cmdtmp = Cmd.commands['5'];
  57.              Cmd.commands['5'] = Cmd.commands[c];
  58.              Cmd.commands[c] = cmdtmp;
  59.              c = M('0') & 0xff;
  60.              Cmd.commands[c] = Cmd.pcHack_compat ? Cmd.commands['I'] : 0;
  61.          }
  62.          /* phone keypad layout (only applicable for num_pad) */
  63.          flagtemp = (iflags.num_pad_mode & 2) ? Cmd.num_pad : FALSE;
  64.          if (flagtemp != Cmd.phone_layout) {
  65.              Cmd.phone_layout = flagtemp;
  66.              ++updated;
  67.              /* phone_layout has been toggled */
  68.              for (i = 0; i < 3; i++) {
  69.                  c = '1' + i;                           /* 1,2,3 <-> 7,8,9 */
  70.                  cmdtmp = Cmd.commands[c];              /* tmp = [1] */
  71.                  Cmd.commands[c] = Cmd.commands[c + 6]; /* [1] = [7] */
  72.                  Cmd.commands[c + 6] = cmdtmp;          /* [7] = tmp */
  73.                  c = (M('1') & 0xff) + i;  /* M-1,M-2,M-3 <-> M-7,M-8,M-9 */
  74.                  cmdtmp = Cmd.commands[c]; /* tmp = [M-1] */
  75.                  Cmd.commands[c] = Cmd.commands[c + 6]; /* [M-1] = [M-7] */
  76.                  Cmd.commands[c + 6] = cmdtmp;          /* [M-7] = tmp */
  77.              }
  78.          }
  79.      } /*?initial*/
  80.  
  81.      if (updated)
  82.          Cmd.serialno++;
  83.      Cmd.dirchars = !Cmd.num_pad
  84.                         ? (!Cmd.swap_yz ? sdir : sdir_swap_yz)
  85.                         : (!Cmd.phone_layout ? ndir : ndir_phone_layout);
  86.      Cmd.alphadirchars = !Cmd.num_pad ? Cmd.dirchars : sdir;
  87.  
  88.      Cmd.move_W = Cmd.dirchars[0];
  89.      Cmd.move_NW = Cmd.dirchars[1];
  90.      Cmd.move_N = Cmd.dirchars[2];
  91.      Cmd.move_NE = Cmd.dirchars[3];
  92.      Cmd.move_E = Cmd.dirchars[4];
  93.      Cmd.move_SE = Cmd.dirchars[5];
  94.      Cmd.move_S = Cmd.dirchars[6];
  95.      Cmd.move_SW = Cmd.dirchars[7];
  96.  }
  97.  

accept_menu_prefix

  1.  STATIC_OVL boolean
  2.  accept_menu_prefix(cmd_func)
  3.  int NDECL((*cmd_func));
  4.  {
  5.      if (cmd_func == dopickup || cmd_func == dotip
  6.          || cmd_func == doextcmd || cmd_func == doextlist)
  7.          return TRUE;
  8.      return FALSE;
  9.  }
  10.  

rhack

  1.  void
  2.  rhack(cmd)
  3.  register char *cmd;
  4.  {
  5.      boolean do_walk, do_rush, prefix_seen, bad_command,
  6.          firsttime = (cmd == 0);
  7.  
  8.      iflags.menu_requested = FALSE;
  9.  #ifdef SAFERHANGUP
  10.      if (program_state.done_hup)
  11.          end_of_input();
  12.  #endif
  13.      if (firsttime) {
  14.          context.nopick = 0;
  15.          cmd = parse();
  16.      }
  17.      if (*cmd == '\033') {
  18.          context.move = FALSE;
  19.          return;
  20.      }
  21.      if (*cmd == DOAGAIN && !in_doagain && saveq[0]) {
  22.          in_doagain = TRUE;
  23.          stail = 0;
  24.          rhack((char *) 0); /* read and execute command */
  25.          in_doagain = FALSE;
  26.          return;
  27.      }
  28.      /* Special case of *cmd == ' ' handled better below */
  29.      if (!*cmd || *cmd == (char) 0377) {
  30.          nhbell();
  31.          context.move = FALSE;
  32.          return; /* probably we just had an interrupt */
  33.      }
  34.  
  35.      /* handle most movement commands */
  36.      do_walk = do_rush = prefix_seen = FALSE;
  37.      context.travel = context.travel1 = 0;
  38.      switch (*cmd) {
  39.      case 'g':
  40.          if (movecmd(cmd[1])) {
  41.              context.run = 2;
  42.              do_rush = TRUE;
  43.          } else
  44.              prefix_seen = TRUE;
  45.          break;
  46.      case '5':
  47.          if (!Cmd.num_pad)
  48.              break; /* else FALLTHRU */
  49.      case 'G':
  50.          if (movecmd(lowc(cmd[1]))) {
  51.              context.run = 3;
  52.              do_rush = TRUE;
  53.          } else
  54.              prefix_seen = TRUE;
  55.          break;
  56.      case '-':
  57.          if (!Cmd.num_pad)
  58.              break; /* else FALLTHRU */
  59.      /* Effects of movement commands and invisible monsters:
  60.       * m: always move onto space (even if 'I' remembered)
  61.       * F: always attack space (even if 'I' not remembered)
  62.       * normal movement: attack if 'I', move otherwise.
  63.       */
  64.      case 'F':
  65.          if (movecmd(cmd[1])) {
  66.              context.forcefight = 1;
  67.              do_walk = TRUE;
  68.          } else
  69.              prefix_seen = TRUE;
  70.          break;
  71.      case 'm':
  72.          if (movecmd(cmd[1]) || u.dz) {
  73.              context.run = 0;
  74.              context.nopick = 1;
  75.              if (!u.dz)
  76.                  do_walk = TRUE;
  77.              else
  78.                  cmd[0] = cmd[1]; /* "m<" or "m>" */
  79.          } else
  80.              prefix_seen = TRUE;
  81.          break;
  82.      case 'M':
  83.          if (movecmd(lowc(cmd[1]))) {
  84.              context.run = 1;
  85.              context.nopick = 1;
  86.              do_rush = TRUE;
  87.          } else
  88.              prefix_seen = TRUE;
  89.          break;
  90.      case '0':
  91.          if (!Cmd.num_pad)
  92.              break;
  93.          (void) ddoinv(); /* a convenience borrowed from the PC */
  94.          context.move = FALSE;
  95.          multi = 0;
  96.          return;
  97.      case CMD_CLICKLOOK:
  98.          if (iflags.clicklook) {
  99.              context.move = FALSE;
  100.              do_look(2, &clicklook_cc);
  101.          }
  102.          return;
  103.      case CMD_TRAVEL:
  104.          if (flags.travelcmd) {
  105.              context.travel = 1;
  106.              context.travel1 = 1;
  107.              context.run = 8;
  108.              context.nopick = 1;
  109.              do_rush = TRUE;
  110.              break;
  111.          }
  112.          /*FALLTHRU*/
  113.      default:
  114.          if (movecmd(*cmd)) { /* ordinary movement */
  115.              context.run = 0; /* only matters here if it was 8 */
  116.              do_walk = TRUE;
  117.          } else if (movecmd(Cmd.num_pad ? unmeta(*cmd) : lowc(*cmd))) {
  118.              context.run = 1;
  119.              do_rush = TRUE;
  120.          } else if (movecmd(unctrl(*cmd))) {
  121.              context.run = 3;
  122.              do_rush = TRUE;
  123.          }
  124.          break;
  125.      }
  126.  
  127.      /* some special prefix handling */
  128.      /* overload 'm' prefix to mean "request a menu" */
  129.      if (prefix_seen && cmd[0] == 'm') {
  130.          /* (for func_tab cast, see below) */
  131.          const struct func_tab *ft = Cmd.commands[cmd[1] & 0xff];
  132.          int NDECL((*func)) = ft ? ((struct func_tab *) ft)->f_funct : 0;
  133.  
  134.          if (func && accept_menu_prefix(func)) {
  135.              iflags.menu_requested = TRUE;
  136.              ++cmd;
  137.          }
  138.      }
  139.  
  140.      if ((do_walk || do_rush) && !context.travel && !dxdy_moveok()) {
  141.          /* trying to move diagonally as a grid bug;
  142.             this used to be treated by movecmd() as not being
  143.             a movement attempt, but that didn't provide for any
  144.             feedback and led to strangeness if the key pressed
  145.             ('u' in particular) was overloaded for num_pad use */
  146.          You_cant("get there from here...");
  147.          context.run = 0;
  148.          context.nopick = context.forcefight = FALSE;
  149.          context.move = context.mv = FALSE;
  150.          multi = 0;
  151.          return;
  152.      }
  153.  
  154.      if (do_walk) {
  155.          if (multi)
  156.              context.mv = TRUE;
  157.          domove();
  158.          context.forcefight = 0;
  159.          return;
  160.      } else if (do_rush) {
  161.          if (firsttime) {
  162.              if (!multi)
  163.                  multi = max(COLNO, ROWNO);
  164.              u.last_str_turn = 0;
  165.          }
  166.          context.mv = TRUE;
  167.          domove();
  168.          return;
  169.      } else if (prefix_seen && cmd[1] == '\033') { /* <prefix><escape> */
  170.          /* don't report "unknown command" for change of heart... */
  171.          bad_command = FALSE;
  172.      } else if (*cmd == ' ' && !flags.rest_on_space) {
  173.          bad_command = TRUE; /* skip cmdlist[] loop */
  174.  
  175.          /* handle all other commands */
  176.      } else {
  177.          register const struct func_tab *tlist;
  178.          int res, NDECL((*func));
  179.  
  180.  #if 0
  181.          /* obsolete - scan through the cmdlist array looking for *cmd */
  182.          for (tlist = cmdlist; tlist->f_char; tlist++) {
  183.              if ((*cmd & 0xff) != (tlist->f_char & 0xff))
  184.                  continue;
  185.  #else
  186.          /* current - use *cmd to directly index cmdlist array */
  187.          if ((tlist = Cmd.commands[*cmd & 0xff]) != 0) {
  188.  #endif
  189.              if (u.uburied && !tlist->can_if_buried) {
  190.                  You_cant("do that while you are buried!");
  191.                  res = 0;
  192.              } else {
  193.                  /* we discard 'const' because some compilers seem to have
  194.                     trouble with the pointer passed to set_occupation() */
  195.                  func = ((struct func_tab *) tlist)->f_funct;
  196.                  if (tlist->f_text && !occupation && multi)
  197.                      set_occupation(func, tlist->f_text, multi);
  198.                  res = (*func)(); /* perform the command */
  199.              }
  200.              if (!res) {
  201.                  context.move = FALSE;
  202.                  multi = 0;
  203.              }
  204.              return;
  205.          }
  206.          /* if we reach here, cmd wasn't found in cmdlist[] */
  207.          bad_command = TRUE;
  208.      }
  209.  
  210.      if (bad_command) {
  211.          char expcmd[10];
  212.          register char c, *cp = expcmd;
  213.  
  214.          while ((c = *cmd++) != '\0'
  215.                 && (int) (cp - expcmd) < (int) (sizeof expcmd - 3)) {
  216.              if (c >= 040 && c < 0177) {
  217.                  *cp++ = c;
  218.              } else if (c & 0200) {
  219.                  *cp++ = 'M';
  220.                  *cp++ = '-';
  221.                  *cp++ = c & ~0200;
  222.              } else {
  223.                  *cp++ = '^';
  224.                  *cp++ = c ^ 0100;
  225.              }
  226.          }
  227.          *cp = '\0';
  228.          if (!prefix_seen || !iflags.cmdassist
  229.              || !help_dir(0, "Invalid direction key!"))
  230.              Norep("Unknown command '%s'.", expcmd);
  231.      }
  232.      /* didn't move */
  233.      context.move = FALSE;
  234.      multi = 0;
  235.      return;
  236.  }
  237.  

xytod

  1.  /* convert an x,y pair into a direction code */
  2.  int
  3.  xytod(x, y)
  4.  schar x, y;
  5.  {
  6.      register int dd;
  7.  
  8.      for (dd = 0; dd < 8; dd++)
  9.          if (x == xdir[dd] && y == ydir[dd])
  10.              return dd;
  11.      return -1;
  12.  }
  13.  

dtoxy

  1.  /* convert a direction code into an x,y pair */
  2.  void
  3.  dtoxy(cc, dd)
  4.  coord *cc;
  5.  register int dd;
  6.  {
  7.      cc->x = xdir[dd];
  8.      cc->y = ydir[dd];
  9.      return;
  10.  }
  11.  

movecmd

  1.  /* also sets u.dz, but returns false for <> */
  2.  int
  3.  movecmd(sym)
  4.  char sym;
  5.  {
  6.      register const char *dp = index(Cmd.dirchars, sym);
  7.  
  8.      u.dz = 0;
  9.      if (!dp || !*dp)
  10.          return 0;
  11.      u.dx = xdir[dp - Cmd.dirchars];
  12.      u.dy = ydir[dp - Cmd.dirchars];
  13.      u.dz = zdir[dp - Cmd.dirchars];
  14.  #if 0 /* now handled elsewhere */
  15.      if (u.dx && u.dy && NODIAG(u.umonnum)) {
  16.          u.dx = u.dy = 0;
  17.          return 0;
  18.      }
  19.  #endif
  20.      return !u.dz;
  21.  }
  22.  

dxdy_moveok

  1.  /* grid bug handling which used to be in movecmd() */
  2.  int
  3.  dxdy_moveok()
  4.  {
  5.      if (u.dx && u.dy && NODIAG(u.umonnum))
  6.          u.dx = u.dy = 0;
  7.      return u.dx || u.dy;
  8.  }
  9.  

redraw_cmd

  1.  /* decide whether a character (user input keystroke) requests screen repaint */
  2.  boolean
  3.  redraw_cmd(c)
  4.  char c;
  5.  {
  6.      return (boolean) (c == C('r') || (Cmd.num_pad && c == C('l')));
  7.  }
  8.  

get_adjacent_loc

  1.  /*
  2.   * uses getdir() but unlike getdir() it specifically
  3.   * produces coordinates using the direction from getdir()
  4.   * and verifies that those coordinates are ok.
  5.   *
  6.   * If the call to getdir() returns 0, Never_mind is displayed.
  7.   * If the resulting coordinates are not okay, emsg is displayed.
  8.   *
  9.   * Returns non-zero if coordinates in cc are valid.
  10.   */
  11.  int
  12.  get_adjacent_loc(prompt, emsg, x, y, cc)
  13.  const char *prompt, *emsg;
  14.  xchar x, y;
  15.  coord *cc;
  16.  {
  17.      xchar new_x, new_y;
  18.      if (!getdir(prompt)) {
  19.          pline1(Never_mind);
  20.          return 0;
  21.      }
  22.      new_x = x + u.dx;
  23.      new_y = y + u.dy;
  24.      if (cc && isok(new_x, new_y)) {
  25.          cc->x = new_x;
  26.          cc->y = new_y;
  27.      } else {
  28.          if (emsg)
  29.              pline1(emsg);
  30.          return 0;
  31.      }
  32.      return 1;
  33.  }
  34.  

getdir

  1.  int
  2.  getdir(s)
  3.  const char *s;
  4.  {
  5.      char dirsym;
  6.      int is_mov;
  7.  
  8.  retry:
  9.      if (in_doagain || *readchar_queue)
  10.          dirsym = readchar();
  11.      else
  12.          dirsym = yn_function((s && *s != '^') ? s : "In what direction?",
  13.                               (char *) 0, '\0');
  14.      /* remove the prompt string so caller won't have to */
  15.      clear_nhwindow(WIN_MESSAGE);
  16.  
  17.      if (redraw_cmd(dirsym)) { /* ^R */
  18.          docrt();              /* redraw */
  19.          goto retry;
  20.      }
  21.      savech(dirsym);
  22.  
  23.      if (dirsym == '.' || dirsym == 's') {
  24.          u.dx = u.dy = u.dz = 0;
  25.      } else if (!(is_mov = movecmd(dirsym)) && !u.dz) {
  26.          boolean did_help = FALSE, help_requested;
  27.  
  28.          if (!index(quitchars, dirsym)) {
  29.              help_requested = (dirsym == '?');
  30.              if (help_requested || iflags.cmdassist) {
  31.                  did_help =
  32.                      help_dir((s && *s == '^') ? dirsym : 0,
  33.                               help_requested ? (const char *) 0
  34.                                              : "Invalid direction key!");
  35.                  if (help_requested)
  36.                      goto retry;
  37.              }
  38.              if (!did_help)
  39.                  pline("What a strange direction!");
  40.          }
  41.          return 0;
  42.      } else if (is_mov && !dxdy_moveok()) {
  43.          You_cant("orient yourself that direction.");
  44.          return 0;
  45.      }
  46.      if (!u.dz && (Stunned || (Confusion && !rn2(5))))
  47.          confdir();
  48.      return 1;
  49.  }
  50.  

help_dir

  1.  STATIC_OVL boolean
  2.  help_dir(sym, msg)
  3.  char sym;
  4.  const char *msg;
  5.  {
  6.      char ctrl;
  7.      winid win;
  8.      static const char wiz_only_list[] = "EFGIOVW";
  9.      char buf[BUFSZ], buf2[BUFSZ], *explain;
  10.  
  11.      win = create_nhwindow(NHW_TEXT);
  12.      if (!win)
  13.          return FALSE;
  14.      if (msg) {
  15.          Sprintf(buf, "cmdassist: %s", msg);
  16.          putstr(win, 0, buf);
  17.          putstr(win, 0, "");
  18.      }
  19.      if (letter(sym)) {
  20.          sym = highc(sym);
  21.          ctrl = (sym - 'A') + 1;
  22.          if ((explain = dowhatdoes_core(ctrl, buf2))
  23.              && (!index(wiz_only_list, sym) || wizard)) {
  24.              Sprintf(buf, "Are you trying to use ^%c%s?", sym,
  25.                      index(wiz_only_list, sym)
  26.                          ? ""
  27.                          : " as specified in the Guidebook");
  28.              putstr(win, 0, buf);
  29.              putstr(win, 0, "");
  30.              putstr(win, 0, explain);
  31.              putstr(win, 0, "");
  32.              putstr(win, 0, "To use that command, you press");
  33.              Sprintf(buf, "the <Ctrl> key, and the <%c> key at the same time.",
  34.                      sym);
  35.              putstr(win, 0, buf);
  36.              putstr(win, 0, "");
  37.          }
  38.      }
  39.      if (NODIAG(u.umonnum)) {
  40.          putstr(win, 0, "Valid direction keys in your current form are:");
  41.          Sprintf(buf, "             %c   ", Cmd.move_N);
  42.          putstr(win, 0, buf);
  43.          putstr(win, 0, "             |   ");
  44.          Sprintf(buf, "          %c- . -%c", Cmd.move_W, Cmd.move_E);
  45.          putstr(win, 0, buf);
  46.          putstr(win, 0, "             |   ");
  47.          Sprintf(buf, "             %c   ", Cmd.move_S);
  48.          putstr(win, 0, buf);
  49.      } else {
  50.          putstr(win, 0, "Valid direction keys are:");
  51.          Sprintf(buf, "          %c  %c  %c", Cmd.move_NW, Cmd.move_N,
  52.                  Cmd.move_NE);
  53.          putstr(win, 0, buf);
  54.          putstr(win, 0, "           \\ | / ");
  55.          Sprintf(buf, "          %c- . -%c", Cmd.move_W, Cmd.move_E);
  56.          putstr(win, 0, buf);
  57.          putstr(win, 0, "           / | \\ ");
  58.          Sprintf(buf, "          %c  %c  %c", Cmd.move_SW, Cmd.move_S,
  59.                  Cmd.move_SE);
  60.          putstr(win, 0, buf);
  61.      };
  62.      putstr(win, 0, "");
  63.      putstr(win, 0, "          <  up");
  64.      putstr(win, 0, "          >  down");
  65.      putstr(win, 0, "          .  direct at yourself");
  66.      if (msg) {
  67.          /* non-null msg means that this wasn't an explicit user request */
  68.          putstr(win, 0, "");
  69.          putstr(win, 0,
  70.                 "(Suppress this message with !cmdassist in config file.)");
  71.      }
  72.      display_nhwindow(win, FALSE);
  73.      destroy_nhwindow(win);
  74.      return TRUE;
  75.  }
  76.  

confdir

  1.  void
  2.  confdir()
  3.  {
  4.      register int x = NODIAG(u.umonnum) ? 2 * rn2(4) : rn2(8);
  5.  
  6.      u.dx = xdir[x];
  7.      u.dy = ydir[x];
  8.      return;
  9.  }
  10.  

directionname

  1.  const char *
  2.  directionname(dir)
  3.  int dir;
  4.  {
  5.      static NEARDATA const char *const dirnames[] = {
  6.          "west",      "northwest", "north",     "northeast", "east",
  7.          "southeast", "south",     "southwest", "down",      "up",
  8.      };
  9.  
  10.      if (dir < 0 || dir >= SIZE(dirnames))
  11.          return "invalid";
  12.      return dirnames[dir];
  13.  }
  14.  

isok

  1.  int
  2.  isok(x, y)
  3.  register int x, y;
  4.  {
  5.      /* x corresponds to curx, so x==1 is the first column. Ach. %% */
  6.      return x >= 1 && x <= COLNO - 1 && y >= 0 && y <= ROWNO - 1;
  7.  }
  8.  

click_to_cmd

  1.  static NEARDATA int last_multi;
  2.  
  3.  /*
  4.   * convert a MAP window position into a movecmd
  5.   */
  6.  const char *
  7.  click_to_cmd(x, y, mod)
  8.  int x, y, mod;
  9.  {
  10.      int dir;
  11.      static char cmd[4];
  12.      cmd[1] = 0;
  13.  
  14.      if (iflags.clicklook && mod == CLICK_2) {
  15.          clicklook_cc.x = x;
  16.          clicklook_cc.y = y;
  17.          cmd[0] = CMD_CLICKLOOK;
  18.          return cmd;
  19.      }
  20.  
  21.      x -= u.ux;
  22.      y -= u.uy;
  23.  
  24.      if (flags.travelcmd) {
  25.          if (abs(x) <= 1 && abs(y) <= 1) {
  26.              x = sgn(x), y = sgn(y);
  27.          } else {
  28.              u.tx = u.ux + x;
  29.              u.ty = u.uy + y;
  30.              cmd[0] = CMD_TRAVEL;
  31.              return cmd;
  32.          }
  33.  
  34.          if (x == 0 && y == 0) {
  35.              /* here */
  36.              if (IS_FOUNTAIN(levl[u.ux][u.uy].typ)
  37.                  || IS_SINK(levl[u.ux][u.uy].typ)) {
  38.                  cmd[0] = mod == CLICK_1 ? 'q' : M('d');
  39.                  return cmd;
  40.              } else if (IS_THRONE(levl[u.ux][u.uy].typ)) {
  41.                  cmd[0] = M('s');
  42.                  return cmd;
  43.              } else if ((u.ux == xupstair && u.uy == yupstair)
  44.                         || (u.ux == sstairs.sx && u.uy == sstairs.sy
  45.                             && sstairs.up)
  46.                         || (u.ux == xupladder && u.uy == yupladder)) {
  47.                  return "<";
  48.              } else if ((u.ux == xdnstair && u.uy == ydnstair)
  49.                         || (u.ux == sstairs.sx && u.uy == sstairs.sy
  50.                             && !sstairs.up)
  51.                         || (u.ux == xdnladder && u.uy == ydnladder)) {
  52.                  return ">";
  53.              } else if (OBJ_AT(u.ux, u.uy)) {
  54.                  cmd[0] =
  55.                      Is_container(level.objects[u.ux][u.uy]) ? M('l') : ',';
  56.                  return cmd;
  57.              } else {
  58.                  return "."; /* just rest */
  59.              }
  60.          }
  61.  
  62.          /* directional commands */
  63.  
  64.          dir = xytod(x, y);
  65.  
  66.          if (!m_at(u.ux + x, u.uy + y)
  67.              && !test_move(u.ux, u.uy, x, y, TEST_MOVE)) {
  68.              cmd[1] = Cmd.dirchars[dir];
  69.              cmd[2] = '\0';
  70.              if (IS_DOOR(levl[u.ux + x][u.uy + y].typ)) {
  71.                  /* slight assistance to the player: choose kick/open for them
  72.                   */
  73.                  if (levl[u.ux + x][u.uy + y].doormask & D_LOCKED) {
  74.                      cmd[0] = C('d');
  75.                      return cmd;
  76.                  }
  77.                  if (levl[u.ux + x][u.uy + y].doormask & D_CLOSED) {
  78.                      cmd[0] = 'o';
  79.                      return cmd;
  80.                  }
  81.              }
  82.              if (levl[u.ux + x][u.uy + y].typ <= SCORR) {
  83.                  cmd[0] = 's';
  84.                  cmd[1] = 0;
  85.                  return cmd;
  86.              }
  87.          }
  88.      } else {
  89.          /* convert without using floating point, allowing sloppy clicking */
  90.          if (x > 2 * abs(y))
  91.              x = 1, y = 0;
  92.          else if (y > 2 * abs(x))
  93.              x = 0, y = 1;
  94.          else if (x < -2 * abs(y))
  95.              x = -1, y = 0;
  96.          else if (y < -2 * abs(x))
  97.              x = 0, y = -1;
  98.          else
  99.              x = sgn(x), y = sgn(y);
  100.  
  101.          if (x == 0 && y == 0) /* map click on player to "rest" command */
  102.              return ".";
  103.  
  104.          dir = xytod(x, y);
  105.      }
  106.  
  107.      /* move, attack, etc. */
  108.      cmd[1] = 0;
  109.      if (mod == CLICK_1) {
  110.          cmd[0] = Cmd.dirchars[dir];
  111.      } else {
  112.          cmd[0] = (Cmd.num_pad
  113.                       ? M(Cmd.dirchars[dir])
  114.                       : (Cmd.dirchars[dir] - 'a' + 'A')); /* run command */
  115.      }
  116.  
  117.      return cmd;
  118.  }
  119.  

parse

  1.  STATIC_OVL char *
  2.  parse()
  3.  {
  4.  #ifdef LINT /* static char in_line[COLNO]; */
  5.      char in_line[COLNO];
  6.  #else
  7.      static char in_line[COLNO];
  8.  #endif
  9.      register int foo;
  10.      boolean prezero = FALSE;
  11.  
  12.      multi = 0;
  13.      context.move = 1;
  14.      flush_screen(1); /* Flush screen buffer. Put the cursor on the hero. */
  15.  
  16.  #ifdef ALTMETA
  17.      alt_esc = iflags.altmeta; /* readchar() hack */
  18.  #endif
  19.      if (!Cmd.num_pad || (foo = readchar()) == 'n')
  20.          for (;;) {
  21.              foo = readchar();
  22.              if (foo >= '0' && foo <= '9') {
  23.                  multi = 10 * multi + foo - '0';
  24.                  if (multi < 0 || multi >= LARGEST_INT)
  25.                      multi = LARGEST_INT;
  26.                  if (multi > 9) {
  27.                      clear_nhwindow(WIN_MESSAGE);
  28.                      Sprintf(in_line, "Count: %d", multi);
  29.                      pline1(in_line);
  30.                      mark_synch();
  31.                  }
  32.                  last_multi = multi;
  33.                  if (!multi && foo == '0')
  34.                      prezero = TRUE;
  35.              } else
  36.                  break; /* not a digit */
  37.          }
  38.  #ifdef ALTMETA
  39.      alt_esc = FALSE; /* readchar() reset */
  40.  #endif
  41.  
  42.      if (foo == '\033') { /* esc cancels count (TH) */
  43.          clear_nhwindow(WIN_MESSAGE);
  44.          multi = last_multi = 0;
  45.      } else if (foo == DOAGAIN || in_doagain) {
  46.          multi = last_multi;
  47.      } else {
  48.          last_multi = multi;
  49.          savech(0); /* reset input queue */
  50.          savech((char) foo);
  51.      }
  52.  
  53.      if (multi) {
  54.          multi--;
  55.          save_cm = in_line;
  56.      } else {
  57.          save_cm = (char *) 0;
  58.      }
  59.      /* in 3.4.3 this was in rhack(), where it was too late to handle M-5 */
  60.      if (Cmd.pcHack_compat) {
  61.          /* This handles very old inconsistent DOS/Windows behaviour
  62.             in a different way: earlier, the keyboard handler mapped
  63.             these, which caused counts to be strange when entered
  64.             from the number pad. Now do not map them until here. */
  65.          switch (foo) {
  66.          case '5':
  67.              foo = 'g';
  68.              break;
  69.          case M('5'):
  70.              foo = 'G';
  71.              break;
  72.          case M('0'):
  73.              foo = 'I';
  74.              break;
  75.          default:
  76.              break; /* as is */
  77.          }
  78.      }
  79.  
  80.      in_line[0] = foo;
  81.      in_line[1] = '\0';
  82.      if (foo == 'g' || foo == 'G' || foo == 'm' || foo == 'M' || foo == 'F'
  83.          || (Cmd.num_pad && (foo == '5' || foo == '-'))) {
  84.          foo = readchar();
  85.          savech((char) foo);
  86.          in_line[1] = foo;
  87.          in_line[2] = 0;
  88.      }
  89.      clear_nhwindow(WIN_MESSAGE);
  90.      if (prezero)
  91.          in_line[0] = '\033';
  92.      return in_line;
  93.  }
  94.  

hangup

  1.  #ifdef HANGUPHANDLING
  2.  /* some very old systems, or descendents of such systems, expect signal
  3.     handlers to have return type `int', but they don't actually inspect
  4.     the return value so we should be safe using `void' unconditionally */
  5.  /*ARGUSED*/
  6.  void
  7.  hangup(sig_unused) /* called as signal() handler, so sent at least one arg */
  8.  int sig_unused UNUSED;
  9.  {
  10.      if (program_state.exiting)
  11.          program_state.in_moveloop = 0;
  12.      nhwindows_hangup();
  13.  #ifdef SAFERHANGUP
  14.      /* When using SAFERHANGUP, the done_hup flag it tested in rhack
  15.         and a couple of other places; actual hangup handling occurs then.
  16.         This is 'safer' because it disallows certain cheats and also
  17.         protects against losing objects in the process of being thrown,
  18.         but also potentially riskier because the disconnected program
  19.         must continue running longer before attempting a hangup save. */
  20.      program_state.done_hup++;
  21.      /* defer hangup iff game appears to be in progress */
  22.      if (program_state.in_moveloop && program_state.something_worth_saving)
  23.          return;
  24.  #endif /* SAFERHANGUP */
  25.      end_of_input();
  26.  }
  27.  

end_of_input

  1.  void
  2.  end_of_input()
  3.  {
  4.  #ifdef NOSAVEONHANGUP
  5.  #ifdef INSURANCE
  6.      if (flags.ins_chkpt && program_state.something_worth_saving)
  7.          program_statue.preserve_locks = 1; /* keep files for recovery */
  8.  #endif
  9.      program_state.something_worth_saving = 0; /* don't save */
  10.  #endif
  11.  
  12.  #ifndef SAFERHANGUP
  13.      if (!program_state.done_hup++)
  14.  #endif
  15.          if (program_state.something_worth_saving)
  16.              (void) dosave0();
  17.      if (iflags.window_inited)
  18.          exit_nhwindows((char *) 0);
  19.      clearlocks();
  20.      terminate(EXIT_SUCCESS);
  21.      /*NOTREACHED*/ /* not necessarily true for vms... */
  22.      return;
  23.  }
  24.  #endif /* HANGUPHANDLING */
  25.  

readchar

  1.  char
  2.  readchar()
  3.  {
  4.      register int sym;
  5.      int x = u.ux, y = u.uy, mod = 0;
  6.  
  7.      if (*readchar_queue)
  8.          sym = *readchar_queue++;
  9.      else
  10.          sym = in_doagain ? pgetchar() : nh_poskey(&x, &y, &mod);
  11.  
  12.  #ifdef NR_OF_EOFS
  13.      if (sym == EOF) {
  14.          register int cnt = NR_OF_EOFS;
  15.          /*
  16.           * Some SYSV systems seem to return EOFs for various reasons
  17.           * (?like when one hits break or for interrupted systemcalls?),
  18.           * and we must see several before we quit.
  19.           */
  20.          do {
  21.              clearerr(stdin); /* omit if clearerr is undefined */
  22.              sym = pgetchar();
  23.          } while (--cnt && sym == EOF);
  24.      }
  25.  #endif /* NR_OF_EOFS */
  26.  
  27.      if (sym == EOF) {
  28.  #ifdef HANGUPHANDLING
  29.          hangup(0); /* call end_of_input() or set program_state.done_hup */
  30.  #endif
  31.          sym = '\033';
  32.  #ifdef ALTMETA
  33.      } else if (sym == '\033' && alt_esc) {
  34.          /* iflags.altmeta: treat two character ``ESC c'' as single `M-c' */
  35.          sym = *readchar_queue ? *readchar_queue++ : pgetchar();
  36.          if (sym == EOF || sym == 0)
  37.              sym = '\033';
  38.          else if (sym != '\033')
  39.              sym |= 0200; /* force 8th bit on */
  40.  #endif                   /*ALTMETA*/
  41.      } else if (sym == 0) {
  42.          /* click event */
  43.          readchar_queue = click_to_cmd(x, y, mod);
  44.          sym = *readchar_queue++;
  45.      }
  46.      return (char) sym;
  47.  }
  48.  

dotravel

  1.  STATIC_PTR int
  2.  dotravel(VOID_ARGS)
  3.  {
  4.      /* Keyboard travel command */
  5.      static char cmd[2];
  6.      coord cc;
  7.  
  8.      if (!flags.travelcmd)
  9.          return 0;
  10.      cmd[1] = 0;
  11.      cc.x = iflags.travelcc.x;
  12.      cc.y = iflags.travelcc.y;
  13.      if (cc.x == -1 && cc.y == -1) {
  14.          /* No cached destination, start attempt from current position */
  15.          cc.x = u.ux;
  16.          cc.y = u.uy;
  17.      }
  18.      pline("Where do you want to travel to?");
  19.      if (getpos(&cc, TRUE, "the desired destination") < 0) {
  20.          /* user pressed ESC */
  21.          return 0;
  22.      }
  23.      iflags.travelcc.x = u.tx = cc.x;
  24.      iflags.travelcc.y = u.ty = cc.y;
  25.      cmd[0] = CMD_TRAVEL;
  26.      readchar_queue = cmd;
  27.      return 0;
  28.  }
  29.  

wiz_port_debug

  1.  #ifdef PORT_DEBUG
  2.  extern void NDECL(win32con_debug_keystrokes);
  3.  extern void NDECL(win32con_handler_info);
  4.  
  5.  int
  6.  wiz_port_debug()
  7.  {
  8.      int n, k;
  9.      winid win;
  10.      anything any;
  11.      int item = 'a';
  12.      int num_menu_selections;
  13.      struct menu_selection_struct {
  14.          char *menutext;
  15.          void NDECL((*fn));
  16.      } menu_selections[] = {
  17.  #ifdef WIN32
  18.          { "test win32 keystrokes (tty only)", win32con_debug_keystrokes },
  19.          { "show keystroke handler information (tty only)",
  20.            win32con_handler_info },
  21.  #endif
  22.          { (char *) 0, (void NDECL((*) )) 0 } /* array terminator */
  23.      };
  24.  
  25.      num_menu_selections = SIZE(menu_selections) - 1;
  26.      if (num_menu_selections > 0) {
  27.          menu_item *pick_list;
  28.          win = create_nhwindow(NHW_MENU);
  29.          start_menu(win);
  30.          for (k = 0; k < num_menu_selections; ++k) {
  31.              any.a_int = k + 1;
  32.              add_menu(win, NO_GLYPH, &any, item++, 0, ATR_NONE,
  33.                       menu_selections[k].menutext, MENU_UNSELECTED);
  34.          }
  35.          end_menu(win, "Which port debugging feature?");
  36.          n = select_menu(win, PICK_ONE, &pick_list);
  37.          destroy_nhwindow(win);
  38.          if (n > 0) {
  39.              n = pick_list[0].item.a_int - 1;
  40.              free((genericptr_t) pick_list);
  41.              /* execute the function */
  42.              (*menu_selections[n].fn)();
  43.          }
  44.      } else
  45.          pline("No port-specific debug capability defined.");
  46.      return 0;
  47.  }
  48.  #endif /*PORT_DEBUG*/

yn_function

  1.  
  2.  /*
  3.   *   Parameter validator for generic yes/no function to prevent
  4.   *   the core from sending too long a prompt string to the
  5.   *   window port causing a buffer overflow there.
  6.   */
  7.  char
  8.  yn_function(query, resp, def)
  9.  const char *query, *resp;
  10.  char def;
  11.  {
  12.      char qbuf[QBUFSZ];
  13.  
  14.      iflags.last_msg = PLNMSG_UNKNOWN; /* most recent pline is clobbered */
  15.  
  16.      /* maximum acceptable length is QBUFSZ-1 */
  17.      if (strlen(query) < QBUFSZ)
  18.          return (*windowprocs.win_yn_function)(query, resp, def);
  19.  
  20.      /* caller shouldn't have passed anything this long */
  21.      paniclog("Query truncated: ", query);
  22.      (void) strncpy(qbuf, query, QBUFSZ - 1 - 3);
  23.      Strcpy(&qbuf[QBUFSZ - 1 - 3], "...");
  24.      return (*windowprocs.win_yn_function)(qbuf, resp, def);
  25.  }
  26.  

paranoid_query

  1.  /* for paranoid_confirm:quit,die,attack prompting */
  2.  boolean
  3.  paranoid_query(be_paranoid, prompt)
  4.  boolean be_paranoid;
  5.  const char *prompt;
  6.  {
  7.      boolean confirmed_ok;
  8.  
  9.      /* when paranoid, player must respond with "yes" rather than just 'y'
  10.         to give the go-ahead for this query; default is "no" unless the
  11.         ParanoidConfirm flag is set in which case there's no default */
  12.      if (be_paranoid) {
  13.          char qbuf[QBUFSZ], ans[BUFSZ];
  14.          const char *promptprefix = "", *responsetype = ParanoidConfirm
  15.                                                             ? "(yes|no)"
  16.                                                             : "(yes) [no]";
  17.          int trylimit = 6; /* 1 normal, 5 more with "Yes or No:" prefix */
  18.  
  19.          /* in addition to being paranoid about this particular
  20.             query, we might be even more paranoid about all paranoia
  21.             responses (ie, ParanoidConfirm is set) in which case we
  22.             require "no" to reject in addition to "yes" to confirm
  23.             (except we won't loop if response is ESC; it means no) */
  24.          do {
  25.              Sprintf(qbuf, "%s%s %s", promptprefix, prompt, responsetype);
  26.              getlin(qbuf, ans);
  27.              (void) mungspaces(ans);
  28.              confirmed_ok = !strcmpi(ans, "yes");
  29.              if (confirmed_ok || *ans == '\033')
  30.                  break;
  31.              promptprefix = "\"Yes\" or \"No\": ";
  32.          } while (ParanoidConfirm && strcmpi(ans, "no") && --trylimit);
  33.      } else
  34.          confirmed_ok = (yn(prompt) == 'y');
  35.  
  36.      return confirmed_ok;
  37.  }
  38.  

dosuspend_core

  1.  int
  2.  dosuspend_core()
  3.  {
  4.  #ifdef SUSPEND
  5.      /* Does current window system support suspend? */
  6.      if ((*windowprocs.win_can_suspend)()) {
  7.          /* NB: SYSCF SHELLERS handled in port code. */
  8.          dosuspend();
  9.      } else
  10.  #endif
  11.          Norep("Suspend command not available.");
  12.      return 0;
  13.  }
  14.  
  15.  /*cmd.c*/