Source:NetHack 3.0.0/cmd.c

From NetHackWiki
Revision as of 04:21, 4 March 2008 by Kernigh bot (talk | contribs) (NetHack 3.0.0/cmd.c moved to Source:NetHack 3.0.0/cmd.c: Robot: moved page)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search

Below is the full text to cmd.c from the source code of NetHack 3.0.0. To link to a particular line, write [[NetHack 3.0.0/cmd.c#line123]], for example.

Warning! This is the source code from an old release. For the latest release, see Source code

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

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

1.    /*	SCCS Id: @(#)cmd.c	3.0	88/10/24
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 DUMB	/* stuff commented out in extern.h, but needed here */
9.    extern int doapply(); /**/
10.   extern int dorub(); /**/
11.   extern int dojump(); /**/
12.   extern int doextlist(); /**/
13.   extern int dodrop(); /**/
14.   extern int doddrop(); /**/
15.   extern int dodown(); /**/
16.   extern int doup(); /**/
17.   extern int donull(); /**/
18.   extern int dowipe(); /**/
19.   extern int do_mname(); /**/
20.   extern int ddocall(); /**/
21.   extern int dotakeoff(); /**/
22.   extern int doremring(); /**/
23.   extern int dowear(); /**/
24.   extern int doputon(); /**/
25.   extern int doddoremarm(); /**/
26.   extern int dokick(); /**/
27.   extern int dothrow(); /**/
28.   extern int doeat(); /**/
29.   extern int done2(); /**/
30.   extern int doengrave(); /**/
31.   extern int dopickup(); /**/
32.   extern int ddoinv(); /**/
33.   extern int dotypeinv(); /**/
34.   extern int dolook(); /**/
35.   extern int doprgold(); /**/
36.   extern int doprwep(); /**/
37.   extern int doprarm(); /**/
38.   extern int doprring(); /**/
39.   extern int dopramulet(); /**/
40.   extern int doprtool(); /**/
41.   extern int dosuspend(); /**/
42.   extern int doforce(); /**/
43.   extern int doopen(); /**/
44.   extern int doclose(); /**/
45.   extern int dosh(); /**/
46.   extern int dodiscovered(); /**/
47.   extern int doset(); /**/
48.   extern int dotogglepickup(); /**/
49.   extern int dowhatis(); /**/
50.   extern int dowhatdoes(); /**/
51.   extern int dohelp(); /**/
52.   extern int dohistory(); /**/
53.   extern int dosh(); /**/
54.   extern int doloot(); /**/
55.   extern int dodrink(); /**/
56.   extern int dodip(); /**/
57.   extern int dosacrifice(); /**/
58.   extern int dopray(); /**/
59.   extern int doturn(); /**/
60.   extern int doredraw(); /**/
61.   extern int doread(); /**/
62.   extern int dosave(); /**/
63.   extern int dosave0(); /**/
64.   extern int dosearch(); /**/
65.   extern int dosearch0 P((int)); /**/
66.   extern int doidtrap(); /**/
67.   extern int dopay(); /**/
68.   extern int dosit(); /**/
69.   extern int dotalk(); /**/
70.   extern int docast(); /**/
71.   extern int dovspell(); /**/
72.   extern int doredotopl(); /**/
73.   extern int dotele(); /**/
74.   extern int dountrap(); /**/
75.   extern int doversion(); /**/
76.   extern int dowield(); /**/
77.   extern int dozap(); /**/
78.   #endif /* DUMB */
79.   
80.   static int (*timed_occ_fn)();
81.   #ifdef POLYSELF
82.   static int domonability();
83.   #endif
84.   
85.   /* Count down by decrementing multi */
86.   static int
87.   timed_occupation() {
88.   	(*timed_occ_fn)();
89.   	if (multi > 0)
90.   		multi--;
91.   	return multi > 0;
92.   }
93.   
94.   /* If a time is given, use it to timeout this function, otherwise the
95.    * function times out by its own means.
96.    */
97.   void
98.   set_occupation(fn, txt, xtime)
99.   int (*fn)();
100.  char *txt;
101.  int xtime;
102.  {
103.  	if (xtime) {
104.  		occupation = timed_occupation;
105.  		timed_occ_fn = fn;
106.  	} else
107.  		occupation = fn;
108.  	occtxt = txt;
109.  	occtime = 0;
110.  	return;
111.  }
112.  
113.  #ifdef REDO
114.  /* Provide a means to redo the last command.  The flag `in_doagain' is set
115.   * to true while redoing the command.  This flag is tested in commands that
116.   * require additional input (like `throw' which requires a thing and a
117.   * direction), and the input prompt is not shown.  Also, while in_doagain is
118.   * TRUE, no keystrokes can be saved into the saveq.
119.   */
120.  #define BSIZE 20
121.  static char pushq[BSIZE], saveq[BSIZE];
122.  static int phead, ptail, shead, stail;
123.  
124.  static char
125.  popch() {
126.  	/* If occupied, return 0, letting tgetch know a character should
127.  	 * be read from the keyboard.  If the character read is not the
128.  	 * ABORT character (as checked in pcmain.c), that character will be
129.  	 * pushed back on the pushq.
130.  	 */
131.  	if (occupation) return 0;
132.  	if (in_doagain) return (shead != stail) ? saveq[stail++] : 0;
133.  	else		return (phead != ptail) ? pushq[ptail++] : 0;
134.  }
135.  
136.  char
137.  pgetchar() {		/* curtesy of aeb@cwi.nl */
138.  	register int ch;
139.  
140.  	if(!(ch = popch()))
141.  		ch = tgetch();
142.  	return(ch);
143.  }
144.  
145.  /* A ch == 0 resets the pushq */
146.  void
147.  pushch(ch)
148.  char ch;
149.  {
150.  	if (!ch)
151.  		phead = ptail = 0;
152.  	if (phead < BSIZE)
153.  		pushq[phead++] = ch;
154.  	return;
155.  }
156.  
157.  /* A ch == 0 resets the saveq.  Only save keystrokes when not
158.   * replaying a previous command.
159.   */
160.  void
161.  savech(ch)
162.  char ch;
163.  {
164.  	if (!in_doagain) {
165.  		if (!ch)
166.  			phead = ptail = shead = stail = 0;
167.  		else if (shead < BSIZE)
168.  			saveq[shead++] = ch;
169.  	}
170.  	return;
171.  }
172.  #endif /* REDO */
173.  
174.  static int
175.  doextcmd()	/* here after # - now read a full-word command */
176.  {
177.  	char buf[BUFSZ];
178.  	register struct ext_func_tab *efp = extcmdlist;
179.  again:
180.  	pline("# ");
181.  #ifdef COM_COMPL
182.  	get_ext_cmd(buf);
183.  #else
184.  	getlin(buf);
185.  #endif
186.  	clrlin();
187.  	if(buf[0] == '\0' || buf[0] == '\033')
188.  		return 0;
189.  	if(buf[0] == '?') {
190.  		(void) doextlist();
191.  		goto again;
192.  	}
193.  	while(efp->ef_txt) {
194.  		if(!strcmp(efp->ef_txt, buf))
195.  			return (*(efp->ef_funct))();
196.  		efp++;
197.  	}
198.  	pline("%s: unknown extended command.", buf);
199.  	return 0;
200.  }
201.  
202.  int
203.  doextlist()	/* here after #? - now list all full-word commands */
204.  {
205.  	register struct ext_func_tab *efp = extcmdlist;
206.  	char     buf[BUFSZ];
207.  
208.  	set_pager(0);
209.  	if(page_line("") ||
210.  	   page_line("            Extended Commands List") ||
211.  	   page_line("") ||
212.  	   page_line("    Press '#', then type (first letter only):") ||
213.  	   page_line(""))					 goto quit;
214.  
215.  	while(efp->ef_txt) {
216.  
217.  		Sprintf(buf, "    %-8s  - %s.", efp->ef_txt, efp->ef_desc);
218.  		if(page_line(buf)) goto quit;
219.  		efp++;
220.  	}
221.  	set_pager(1);
222.  	return 0;
223.  quit:
224.  	set_pager(2);
225.  	return 0;
226.  }
227.  
228.  #ifdef POLYSELF
229.  static int
230.  domonability()
231.  {
232.  	if (can_breathe(uasmon)) return dobreathe();
233.  	else if (attacktype(uasmon, AT_SPIT)) return dospit();
234.  	else if (u.usym == S_NYMPH) return doremove();
235.  	else if (u.usym == S_UMBER) return doconfuse();
236.  	else if (is_were(uasmon)) return dosummon();
237.  	else if (webmaker(uasmon)) return dospinweb();
238.  	else if (is_hider(uasmon)) return dohide();
239.  	else if (u.umonnum >= 0)
240.  		pline("Any special ability you may have is purely reflexive.");
241.  	else You("don't have a special ability!");
242.  	return 0;
243.  }
244.  #endif
245.  
246.  #ifdef WIZARD
247.  static int
248.  wiz_wish()	/* Unlimited wishes for wizard mode by Paul Polderman */
249.  {
250.  	if (wizard)	makewish();
251.  	else		pline("Unavailable command '^W'.");
252.  	return 0;
253.  }
254.  
255.  static int
256.  wiz_identify()
257.  {
258.  	struct obj *obj;
259.  
260.  	if (!wizard)
261.  		pline("Unavailable command '^I'.");
262.  	else {
263.  		for (obj = invent; obj; obj = obj->nobj)
264.  			if (!objects[obj->otyp].oc_name_known || !obj->known
265.  						|| !obj->dknown || !obj->bknown)
266.  				(void) identify(obj);
267.  	}
268.  	return 0;
269.  }
270.  
271.  static int
272.  wiz_map()
273.  {
274.  	if (wizard)	do_mapping();
275.  	else		pline("Unavailable command '^F'.");
276.  	return 0;
277.  }
278.  
279.  static int
280.  wiz_genesis()
281.  {
282.  	if (wizard)	(void) create_particular();
283.  	else		pline("Unavailable command '^G'.");
284.  	return 0;
285.  }
286.  
287.  static int
288.  wiz_where()
289.  {
290.  	if (wizard) {
291.  		pline("Medusa:%d  Wiz:%d  Big:%d", medusa_level, wiz_level, bigroom_level);
292.  #ifdef STRONGHOLD
293.  #  ifdef MUSIC
294.  		pline("Castle:%d (tune %s)  Tower:%d-%d", 
295.  		      stronghold_level, tune, tower_level, tower_level+2);
296.  #  else
297.  		pline("Castle:%d  Tower:%d-%d",
298.  		      stronghold_level, tower_level, tower_level+2);
299.  #  endif
300.  #endif
301.  #ifdef REINCARNATION
302.  		pline("Rogue:%d", rogue_level);
303.  #endif
304.  #ifdef ORACLE
305.  		pline("Oracle:%d", oracle_level);
306.  #endif
307.  	}
308.  	else	pline("Unavailable command '^O'.");
309.  	return 0;
310.  }
311.  
312.  static int
313.  wiz_detect()
314.  {
315.  	if(wizard)  (void) findit();
316.  	else	    pline("Unavailable command '^E'.");
317.  	return 0;
318.  }
319.  
320.  static int
321.  wiz_level_tele()
322.  {
323.  	if (wizard)	level_tele();
324.  	else		pline("Unavailable command '^V'.");
325.  	return 0;
326.  }
327.  
328.  #endif /* WIZARD */
329.  
330.  void
331.  enlightenment() {
332.  
333.  	cornline(0, "Current Attributes:");
334.  
335.  	if (u.ualign == 0) cornline(1, "You are nominally aligned.");
336.  	else if (u.ualign > 3) cornline(1, "You are stridently aligned.");
337.  	else if (u.ualign > 0) cornline(1, "You are haltingly aligned.");
338.  	else cornline(1, "You have strayed.");
339.  
340.  	if (Adornment) cornline(1, "You are adorned.");
341.  	if (Teleportation) cornline(1, "You can teleport.");
342.  	if (Regeneration) cornline(1, "You regenerate.");
343.  	if (Searching) cornline(1, "You have automatic searching.");
344.  	if (See_invisible) cornline(1, "You see invisible.");
345.  	if (Stealth) cornline(1, "You are stealthy.");
346.  	if (Levitation) cornline(1, "You are levitating.");
347.  	if (Hunger) cornline(1, "You have hunger.");
348.  	if (Aggravate_monster) cornline(1, "You aggravate monsters.");
349.  	if (Poison_resistance) cornline(1, "You are poison resistant.");
350.  	if (Fire_resistance) cornline(1, "You are fire resistant.");
351.  	if (Cold_resistance) cornline(1, "You are cold resistant.");
352.  	if (Shock_resistance) cornline(1, "You are shock resistant.");
353.  	if (Sleep_resistance) cornline(1, "You are sleep resistant.");
354.  	if (Disint_resistance) cornline(1, "You are disintegration-resistant.");
355.  	if (Protection_from_shape_changers)
356.  		cornline(1, "You are protected from shape changers.");
357.  	if (Conflict) cornline(1, "You cause conflict.");
358.  	if (Protection) cornline(1, "You are protected.");
359.  	if (Warning) cornline(1, "You are warned.");
360.  	if (Teleport_control) cornline(1, "You have teleport control.");
361.  	if (Polymorph) cornline(1, "You are polymorphing.");
362.  	if (Polymorph_control) cornline(1, "You have polymorph control.");
363.  	if (Telepat) cornline(1, "You are telepathic.");
364.  	if (Fast) cornline(1, "You are fast.");
365.  	/* if (Stunned) cornline(1, "You are stunned."); */
366.  	/* if (Confusion) cornline(1, "You are confused."); */
367.  	/* if (Sick) cornline(1, "You are sick."); */
368.  	/* if (Blinded) cornline(1, "You are blinded."); */
369.  	if (Invisible) cornline(1, "You are invisible.");
370.  	else if (Invis) cornline(1, "You are invisible to others.");
371.  	if (Wounded_legs) {
372.  		char buf[41];
373.  
374.  		Sprintf(buf, "You have wounded %s.",
375.  						makeplural(body_part(LEG)));
376.  		cornline(1, buf);
377.  	}
378.  	if (Stoned) cornline(1, "You are turning to stone.");
379.  	/* if (Hallucination) cornline(1, "You are hallucinating."); */
380.  	if (Glib) {
381.  		char buf[41];
382.  
383.  		Sprintf(buf, "You have slippery %s.",
384.  						makeplural(body_part(FINGER)));
385.  		cornline(1, buf);
386.  	}
387.  	if (Reflecting) cornline(1, "You have reflection.");
388.  	if (Strangled) cornline(1, "You are being strangled.");
389.  	if (Lifesaved) cornline(1, "Your life will be saved.");
390.  	if (Fumbling) cornline(1, "You fumble.");
391.  	if (Jumping) cornline(1, "You can jump.");
392.  	if (Wwalking) cornline(1, "You can walk on water.");
393.  	if (Antimagic) cornline(1, "You are magic-protected.");
394.  	if (Displaced) cornline(1, "You are displaced.");
395.  	if (Clairvoyant) cornline(1, "You are clairvoyant.");
396.  	if (stone_luck(TRUE) > 0) cornline(1, "You have extra luck.");
397.  	if (stone_luck(TRUE) < 0) cornline(1, "You have reduced luck.");
398.  	if (carrying(LUCKSTONE)) {
399.  		if (stone_luck(FALSE) <= 0)
400.  			cornline(1, "Bad luck does not time out for you.");
401.  		if (stone_luck(FALSE) >= 0)
402.  			cornline(1, "Good luck does not time out for you.");
403.  	}
404.  
405.  	cornline(2, "");
406.  	return;
407.  }
408.  
409.  #if defined(WIZARD) || defined(EXPLORE_MODE)
410.  static int
411.  wiz_attributes()
412.  {
413.  	if (wizard || discover)
414.  		enlightenment();
415.  	else
416.  		pline("Unavailable command '^X'.");
417.  	return 0;
418.  }
419.  #endif /* WIZARD || EXPLORE_MODE */
420.  
421.  const struct func_tab cmdlist[]={
422.  	{'\004', /* ^D */ dokick},	/* "D" is for door!...? */
423.  #ifdef WIZARD
424.  	{'\005', /* ^E */ wiz_detect},
425.  	{'\006', /* ^F */ wiz_map},
426.  	{'\007', /* ^G */ wiz_genesis},
427.  	{'\011', /* ^I */ wiz_identify},
428.  	{'\017', /* ^O */ wiz_where},
429.  #endif
430.  	{'\020', /* ^P */ doredotopl},
431.  	{'\022', /* ^R */ doredraw},
432.  	{'\024', /* ^T */ dotele},
433.  #ifdef WIZARD
434.  	{'\026', /* ^V */ wiz_level_tele},
435.  	{'\027', /* ^W */ wiz_wish},
436.  #endif
437.  #if defined(WIZARD) || defined(EXPLORE_MODE)
438.  	{'\030', /* ^X */ wiz_attributes},
439.  #endif
440.  #ifdef SUSPEND
441.  	{'\032', /* ^Z */ dosuspend},
442.  #endif
443.  	{'a', doapply},
444.  	{'A', doddoremarm},
445.  /*	'b', 'B' : go sw */
446.  	{'c', doclose},
447.  	{'C', do_mname},
448.  	{'d', dodrop},
449.  	{'D', doddrop},
450.  	{'e', doeat},
451.  	{'E', doengrave},
452.  /* Soon to be
453.  	{'f', dofight, "fighting"},
454.  	{'F', doFight, "fighting"},
455.   */
456.  /*	'g', 'G' : multiple go */
457.  /*	'h', 'H' : go west */
458.  	{'h', dohelp}, /* if number_pad is set */
459.  	{'i', ddoinv},
460.  	{'I', dotypeinv},		/* Robert Viduya */
461.  /*	'j', 'J', 'k', 'K', 'l', 'L', 'm', 'M', 'n', 'N' : move commands */
462.  	{'j', dojump}, /* if number_pad is on */
463.  	{'k', dokick}, /* if number_pad is on */
464.  	{'l', doloot}, /* if number_pad is on */
465.  /*	'n' prefixes a count if number_pad is on */
466.  	{'N', ddocall}, /* if number_pad is on */
467.  	{'o', doopen},
468.  	{'O', doset},
469.  	{'p', dopay},
470.  	{'P', doputon},
471.  	{'q', dodrink},
472.  	{'Q', done2},
473.  	{'r', doread},
474.  	{'R', doremring},
475.  	{'s', dosearch, "searching"},
476.  	{'S', dosave},
477.  	{'t', dothrow},
478.  	{'T', dotakeoff},
479.  /*	'u', 'U' : go ne */
480.  	{'u', dountrap}, /* if number_pad is on */
481.  	{'v', doversion},
482.  	{'V', dohistory},
483.  	{'w', dowield},
484.  	{'W', dowear},
485.  #ifdef SPELLS
486.  	{'x', dovspell},			/* Mike Stephenson */
487.  #endif
488.  /*	'y', 'Y' : go nw */
489.  	{'z', dozap},
490.  #ifdef SPELLS
491.  	{'Z', docast},
492.  #endif
493.  	{'<', doup},
494.  	{'>', dodown},
495.  	{'/', dowhatis},
496.  	{'&', dowhatdoes},
497.  	{'?', dohelp},
498.  #ifdef SHELL
499.  	{'!', dosh},
500.  #endif
501.  	{'.', donull, "waiting"},
502.  	{' ', donull, "waiting"},
503.  	{',', dopickup},
504.  	{':', dolook},
505.  	{'^', doidtrap},
506.  	{'\\', dodiscovered},		/* Robert Viduya */
507.  	{'@', dotogglepickup},
508.  	{WEAPON_SYM,  doprwep},
509.  	{ARMOR_SYM,  doprarm},
510.  	{RING_SYM,  doprring},
511.  	{AMULET_SYM, dopramulet},
512.  	{TOOL_SYM, doprtool},
513.  	{GOLD_SYM, doprgold},
514.  #ifdef SPELLS
515.  	{SPBOOK_SYM, dovspell},			/* Mike Stephenson */
516.  #endif
517.  	{'#', doextcmd},
518.  	{0,0,0}
519.  };
520.  
521.  const struct ext_func_tab extcmdlist[] = {
522.  	"chat", "talk to someone", dotalk,	/* converse? */
523.  	"dip", "dip an object into something", dodip,
524.  	"force", "force the lock on a chest", doforce,
525.  	"jump", "jump to a location", dojump,
526.  	"loot", "loot a box on the floor", doloot,
527.  #ifdef POLYSELF
528.  	"monster", "use a monster's special ability", domonability,
529.  #endif
530.  	"name", "name an item or type of object", ddocall,
531.  #ifdef THEOLOGY
532.  	"offer", "offer a sacrifice to the gods", dosacrifice,
533.  	"pray", "pray to the gods for help", dopray,
534.  #endif
535.  	"rub", "rub a lamp", dorub,
536.  	"sit", "sit down", dosit,
537.  	"turn", "turn undead", doturn,
538.  	"untrap", "untrap a trapped object", dountrap,
539.  	"wipe", "wipe your face off", dowipe,
540.  	"?", "get this list of extended commands", doextlist,
541.  	NULL, NULL, donull
542.  };
543.  
544.  char
545.  unctrl(sym)
546.  char sym;
547.  {
548.      return (sym >= ('A' & 037) && sym <= ('Z' & 037)) ? sym + 0140 : sym;
549.  }
550.  
551.  void
552.  rhack(cmd)
553.  register char *cmd;
554.  {
555.  	register struct func_tab *tlist = cmdlist;
556.  	boolean firsttime = FALSE;
557.  	register int res;
558.  
559.  	if(!cmd) {
560.  		firsttime = TRUE;
561.  		flags.nopick = 0;
562.  		cmd = parse();
563.  	}
564.  	if(*cmd == (char)033) {
565.  		flags.move = 0;
566.  		return;
567.  	}
568.  #ifdef REDO
569.  	if (*cmd == DOAGAIN && !in_doagain && saveq[0]) {
570.  		in_doagain = TRUE;
571.  		stail = 0;
572.  		rhack(NULL);	/* read and execute command */
573.  		in_doagain = FALSE;
574.  		return;
575.  	}
576.  	/* Special case of *cmd == ' ' handled better below */
577.  	if(!*cmd || *cmd == (char)0377) {
578.  #else
579.  	if(!*cmd || *cmd == (char)0377 || (flags.no_rest_on_space && *cmd == ' ')){
580.  #endif
581.  		bell();
582.  		flags.move = 0;
583.  		return;		/* probably we just had an interrupt */
584.  	}
585.  	if(movecmd(*cmd)) {
586.  	walk:
587.  		if(multi) flags.mv = 1;
588.  		domove();
589.  		return;
590.  	}
591.  	if(!flags.num_pad && movecmd(lowc(*cmd))) {
592.  		flags.run = 1;
593.  	rush:
594.  		if(firsttime){
595.  			if(!multi) multi = COLNO;
596.  			u.last_str_turn = 0;
597.  		}
598.  		flags.mv = 1;
599.  		domove();
600.  		return;
601.  	}
602.  	if(*cmd == 'g' && movecmd(cmd[1])) {
603.  		flags.run = 2;
604.  		goto rush;
605.  	}
606.  	if(((*cmd == 'G' || (flags.num_pad && *cmd == '5')) && 
607.  	    movecmd(lowc(cmd[1]))) || movecmd(unctrl(*cmd))) {
608.  		flags.run = 3;
609.  		goto rush;
610.  	}
611.  	if(*cmd == 'm' && movecmd(cmd[1])) {
612.  		flags.run = 0;
613.  		flags.nopick = 1;
614.  		goto walk;
615.  	}
616.  	if(*cmd == 'M' && movecmd(lowc(cmd[1]))) {
617.  		flags.run = 1;
618.  		flags.nopick = 1;
619.  		goto rush;
620.  	}
621.  	while(tlist->f_char) {
622.  		if(*cmd == tlist->f_char){
623.  			/* Special case of *cmd == ' ' handled here */
624.  			if (*cmd == ' ' && flags.no_rest_on_space)
625.  				break;
626.  
627.  			/* Now control-A can stop lengthy commands */
628.  			/* in the PC version only -- use ^C-N otherwise */
629.  			if (tlist->f_text && !occupation && multi)
630.  				set_occupation(tlist->f_funct, tlist->f_text,
631.  					multi);
632.  			res = (*(tlist->f_funct))();
633.  			if(!res) {
634.  				flags.move = 0;
635.  				multi = 0;
636.  			}
637.  			return;
638.  		}
639.  		tlist++;
640.  	}
641.  	{ char expcmd[10];
642.  	  register char *cp = expcmd;
643.  	  while(*cmd && cp-expcmd < sizeof(expcmd)-2) {
644.  		if(*cmd >= 040 && *cmd < 0177)
645.  			*cp++ = *cmd++;
646.  		else {
647.  			*cp++ = '^';
648.  			*cp++ = *cmd++ ^ 0100;
649.  		}
650.  	  }
651.  	  *cp++ = 0;
652.  	  pline("Unknown command '%s'.", expcmd);
653.  	}
654.  	multi = flags.move = 0;
655.  	return;
656.  }
657.  
658.  char
659.  lowc(sym)
660.  char sym;
661.  {
662.      return (sym >= 'A' && sym <= 'Z') ? sym+'a'-'A' : sym;
663.  }
664.  
665.  /* 'rogue'-like direction commands */
666.  const char sdir[] = "hykulnjb><";
667.  const char ndir[] = "47896321><";
668.  const schar xdir[10] = { -1,-1, 0, 1, 1, 1, 0,-1, 0, 0 };
669.  const schar ydir[10] = {  0,-1,-1,-1, 0, 1, 1, 1, 0, 0 };
670.  const schar zdir[10] = {  0, 0, 0, 0, 0, 0, 0, 0, 1,-1 };
671.  
672.  #ifdef WALKIES
673.  int
674.  xytod(x, y)	/* convert an x,y pair into a direction code */
675.  schar x, y;
676.  {
677.  	register int dd;
678.  
679.  	for(dd = 0; dd < 8; dd++)
680.  	    if(x == xdir[dd] && y == ydir[dd]) return dd;
681.  
682.  	return -1;
683.  }
684.  
685.  void
686.  dtoxy(cc,dd)	/* convert a direction code into an x,y pair */
687.  coord *cc;
688.  register int dd;
689.  {
690.  	cc->x = xdir[dd];
691.  	cc->y = ydir[dd];
692.  	return;
693.  }
694.  #endif /* WALKIES */
695.  
696.  int
697.  movecmd(sym)	/* also sets u.dz, but returns false for <> */
698.  char sym;
699.  {
700.  	register char *dp, *sdp = flags.num_pad ? ndir : sdir;
701.  
702.  	u.dz = 0;
703.  	if(!(dp = index(sdp, sym))) return 0;
704.  	u.dx = xdir[dp-sdp];
705.  	u.dy = ydir[dp-sdp];
706.  	u.dz = zdir[dp-sdp];
707.  	return !u.dz;
708.  }
709.  
710.  int
711.  getdir(s)
712.  boolean s;
713.  {
714.  	char dirsym;
715.  
716.  #ifdef REDO
717.  	if (!in_doagain)
718.  #endif
719.  	    if(s) pline("In what direction? ");
720.  	dirsym = readchar();
721.  #ifdef REDO
722.  	savech(dirsym);
723.  #endif
724.  	if(dirsym == '.' || dirsym == 's')
725.  		u.dx = u.dy = u.dz = 0;
726.  	else if(!movecmd(dirsym) && !u.dz) {
727.  		if(!index(quitchars, dirsym))
728.  			pline("What a strange direction!");
729.  		return 0;
730.  	}
731.  	if(!u.dz && (Stunned || (Confusion && !rn2(5)))) confdir();
732.  	return 1;
733.  }
734.  
735.  void
736.  confdir()
737.  {
738.  	register int x = rn2(8);
739.  	u.dx = xdir[x];
740.  	u.dy = ydir[x];
741.  	return;
742.  }
743.  
744.  int
745.  isok(x,y)
746.  register int x, y;
747.  {
748.  	/* x corresponds to curx, so x==1 is the first column. Ach. %% */
749.  	return x >= 1 && x <= COLNO-1 && y >= 0 && y <= ROWNO-1;
750.  }