Source:NetHack 2.2a/cmd.c

From NetHackWiki
Revision as of 01:57, 4 March 2008 by Kernigh bot (talk | contribs) (NetHack 2.2a/cmd.c moved to Source:NetHack 2.2a/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 2.2a. To link to a particular line, write [[NetHack 2.2a/cmd.c#line123]], for example.

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

Screenshots and source code from Hack are used under the CWI license.

1.    /*	SCCS Id: @(#)cmd.c	2.0	87/09/15
2.    /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
3.    
4.    #include	"hack.h"
5.    #include	"func_tab.h"
6.    
7.    int doredraw(),doredotopl(),dodrop(),dodrink(),doread(),dosearch(),dopickup(),
8.    doversion(),doweararm(),dowearring(),doremarm(),doddoremarm(),doremring(),
9.    dopay(),doapply(),dosave(),dowield(),ddoinv(),dozap(),ddocall(),dowhatis(),
10.   doengrave(),dotele(),dohelp(),doeat(),doddrop(),do_mname(),doidtrap(),
11.   doprwep(),doprarm(),doprring(),doprgold(),dodiscovered(),dotypeinv(),dolook(),
12.   doset(),doup(), dodown(), done1(), donull(), dothrow(), doextcmd(), dodip(),
13.   dopray(), doextlist();
14.   #ifdef WIZARD
15.   int wiz_wish(), wiz_identify();
16.   #endif
17.   #ifdef NEWCLASS
18.   int dosit(), doturn();
19.   #endif
20.   #ifdef SPELLS
21.   int docast(), dovspell(), doxcribe();
22.   #endif
23.   #ifdef SHELL
24.   int dosh();
25.   #endif
26.   #ifdef SUSPEND
27.   int dosuspend();
28.   #endif
29.   #ifdef KAA
30.   int doremove(), dobreathe();
31.   # ifdef KOPS
32.   int dowipe();
33.   # endif
34.   #endif
35.   
36.   int rndobjsym(), rndmonsym();
37.   char *hcolor(), *rndmonnam(), *defmonnam();
38.   
39.   extern char *occtxt;
40.   extern int (*occupation)();
41.   
42.   #ifdef DGKMOD
43.   int dotogglepickup(), doMSCversion();
44.   # ifdef DEBUG
45.   int dodebug();
46.   # endif
47.   
48.   static int (*timed_occ_fn)();
49.   
50.   /* Count down by decrementing multi */
51.   timed_occupation() {
52.   	(*timed_occ_fn)();
53.   	if (multi > 0)
54.   		multi--;
55.   	return (multi > 0);
56.   }
57.   
58.   /* If a time is given, use it to timeout this function, otherwise the
59.    * function times out by its own means.
60.    */
61.   void
62.   set_occupation(fn, txt, time)
63.   int (*fn)();
64.   char *txt;
65.   {
66.   	if (time) {
67.   		occupation = timed_occupation;
68.   		timed_occ_fn = fn;
69.   	} else
70.   		occupation = fn;
71.   	occtxt = txt;
72.   	occtime = 0;
73.   }
74.   #endif /* DGKMOD */
75.   
76.   #ifdef REDO
77.   /* Provide a means to redo the last command.  The flag `in_doagain' is set
78.    * to true while redoing the command.  This flag is tested in commands that
79.    * require additional input (like `throw' which requires a thing and a
80.    * direction), and the input prompt is not shown.  Also, while in_doagain is
81.    * TRUE, no keystrokes can be saved into the saveq.
82.    */
83.   #define BSIZE 20
84.   static char pushq[BSIZE], saveq[BSIZE];
85.   static int phead, ptail, shead, stail;
86.   extern int in_doagain;
87.   
88.   char
89.   popch() {
90.   	/* If occupied, return 0, letting tgetch know a character should
91.   	 * be read from the keyboard.  If the character read is not the
92.   	 * ABORT character (as checked in main.c), that character will be
93.   	 * pushed back on the pushq.
94.   	 */
95.   	if (occupation) return(0);
96.   	if (in_doagain) return ((shead != stail) ? saveq[stail++] : 0);
97.   	else		return ((phead != ptail) ? pushq[ptail++] : 0);
98.   }
99.   
100.  /* A ch == 0 resets the pushq */
101.  void
102.  pushch(ch)
103.  char ch;
104.  {
105.  	if (!ch)
106.  		phead = ptail = 0;
107.  	if (phead < BSIZE)
108.  		pushq[phead++] = ch;
109.  }
110.  
111.  /* A ch == 0 resets the saveq.  Only save keystrokes when not
112.   * replaying a previous command.
113.   */
114.  void
115.  savech(ch)
116.  char ch;
117.  {
118.  	if (!in_doagain) {
119.  		if (!ch)
120.  			phead = ptail = shead = stail = 0;
121.  		else if (shead < BSIZE)
122.  			saveq[shead++] = ch;
123.  	}
124.  }
125.  #endif /* REDO */
126.  
127.  struct func_tab cmdlist[]={
128.  #ifdef WIZARD
129.  	{'\011', wiz_identify},
130.  #endif
131.  	{'\020', doredotopl},
132.  	{'\022', doredraw},
133.  	{'\024', dotele},
134.  #ifdef WIZARD
135.  	{'\027', wiz_wish},
136.  #endif
137.  #ifdef SUSPEND
138.  	{'\032', dosuspend},
139.  #endif
140.  	{'a', doapply},
141.  	{'A', doddoremarm},
142.  /*	'b', 'B' : go sw */
143.  	{'c', ddocall},
144.  	{'C', do_mname},
145.  	{'d', dodrop},
146.  	{'D', doddrop},
147.  	{'e', doeat},
148.  	{'E', doengrave},
149.  /* Soon to be
150.  	{'f', dofight, "fighting"},
151.  	{'F', doFight, "fighting"},
152.   */
153.  /*	'g', 'G' : multiple go */
154.  /*	'h', 'H' : go west */
155.  	{'I', dotypeinv},		/* Robert Viduya */
156.  	{'i', ddoinv},
157.  /*	'j', 'J', 'k', 'K', 'l', 'L', 'm', 'M', 'n', 'N' : move commands */
158.  /*	'o', doopen,	*/
159.  	{'O', doset},
160.  	{'p', dopay},
161.  	{'P', dowearring},
162.  	{'q', dodrink},
163.  	{'Q', done1},
164.  	{'r', doread},
165.  	{'R', doremring},
166.  	{'s', dosearch, "searching"},
167.  	{'S', dosave},
168.  	{'t', dothrow},
169.  	{'T', doremarm},
170.  /*	'u', 'U' : go ne */
171.  	{'v', doversion},
172.  	{'w', dowield},
173.  	{'W', doweararm},
174.  #ifdef SPELLS
175.  	{'x', dovspell},			/* Mike Stephenson */
176.  	{'X', doxcribe},			/* Mike Stephenson */ 
177.  #endif
178.  /*	'y', 'Y' : go nw */
179.  	{'z', dozap},
180.  #ifdef SPELLS
181.  	{'Z', docast},
182.  #endif
183.  	{'<', doup},
184.  	{'>', dodown},
185.  	{'/', dowhatis},
186.  	{'?', dohelp},
187.  #ifdef SHELL
188.  	{'!', dosh},
189.  #endif
190.  	{'.', donull, "waiting"},
191.  	{' ', donull, "waiting"},
192.  	{',', dopickup},
193.  	{':', dolook},
194.  	{'^', doidtrap},
195.  	{'\\', dodiscovered},		/* Robert Viduya */
196.  #ifdef DGKMOD
197.  	{'@', dotogglepickup},
198.  	{'V', doMSCversion},
199.  # ifdef DEBUG_DOESNT_WORK
200.  	{'\004', dodebug},	/* generic debug function */
201.  # endif
202.  #endif
203.  	{WEAPON_SYM,  doprwep},
204.  	{ARMOR_SYM,  doprarm},
205.  	{RING_SYM,  doprring},
206.  	{GOLD_SYM, doprgold},
207.  	{'#', doextcmd},
208.  	{0,0,0}
209.  };
210.  
211.  struct ext_func_tab extcmdlist[] = {
212.  #ifdef KAA
213.  	"breathe", "breathe like a dragon", dobreathe,
214.  #endif
215.  #ifdef SPELLS
216.  	"cast", "cast a spell", docast,
217.  #endif
218.  	"dip", "dip an object into something", dodip,
219.  	"pray", "pray to the gods for help", dopray,
220.  #ifdef KAA
221.  	"remove", "remove a cursed item", doremove,
222.  #endif
223.  #ifdef NEWCLASS
224.  	"sit", "sit down", dosit,
225.  	"turn", "turn undead", doturn,
226.  #endif
227.  #if defined(KOPS) && defined(KAA)
228.  	"wipe", "wipe your face off", dowipe,
229.  #endif
230.  	"?", "get this list of extended commands", doextlist,
231.  	(char *) 0, (char *) 0, donull
232.  };
233.  
234.  extern char *parse(), lowc(), unctrl(), quitchars[];
235.  
236.  rhack(cmd)
237.  register char *cmd;
238.  {
239.  	register struct func_tab *tlist = cmdlist;
240.  	boolean firsttime = FALSE;
241.  	register res;
242.  
243.  	if(!cmd) {
244.  		firsttime = TRUE;
245.  		flags.nopick = 0;
246.  		cmd = parse();
247.  	}
248.  #ifdef REDO
249.  	if (*cmd == DOAGAIN && !in_doagain && saveq[0]) {
250.  		in_doagain = TRUE;
251.  		stail = 0;
252.  		rhack((char *) 0);	/* read and execute command */
253.  		in_doagain = FALSE;
254.  		return;
255.  	}
256.  
257.  	/* Special case of *cmd == ' ' handled better below */
258.  	if(!*cmd || *cmd == (char)0377) {
259.  #else
260.  	if(!*cmd || *cmd == (char)0377 || (flags.no_rest_on_space && *cmd == ' ')){
261.  #endif
262.  		bell();
263.  		flags.move = 0;
264.  		return;		/* probably we just had an interrupt */
265.  	}
266.  	if(movecmd(*cmd)) {
267.  	walk:
268.  		if(multi) flags.mv = 1;
269.  		domove();
270.  		return;
271.  	}
272.  	if(movecmd(lowc(*cmd))) {
273.  		flags.run = 1;
274.  	rush:
275.  		if(firsttime){
276.  			if(!multi) multi = COLNO;
277.  			u.last_str_turn = 0;
278.  		}
279.  		flags.mv = 1;
280.  #ifdef QUEST
281.  		if(flags.run >= 4) finddir();
282.  		if(firsttime){
283.  			u.ux0 = u.ux + u.dx;
284.  			u.uy0 = u.uy + u.dy;
285.  		}
286.  #endif
287.  		domove();
288.  		return;
289.  	}
290.  	if((*cmd == 'g' && movecmd(cmd[1])) || movecmd(unctrl(*cmd))) {
291.  		flags.run = 2;
292.  		goto rush;
293.  	}
294.  	if(*cmd == 'G' && movecmd(lowc(cmd[1]))) {
295.  		flags.run = 3;
296.  		goto rush;
297.  	}
298.  	if(*cmd == 'm' && movecmd(cmd[1])) {
299.  		flags.run = 0;
300.  		flags.nopick = 1;
301.  		goto walk;
302.  	}
303.  	if(*cmd == 'M' && movecmd(lowc(cmd[1]))) {
304.  		flags.run = 1;
305.  		flags.nopick = 1;
306.  		goto rush;
307.  	}
308.  #ifdef QUEST
309.  	if(*cmd == cmd[1] && (*cmd == 'g' || *cmd == 'G')) {
310.  		flags.run = 4;
311.  		if(*cmd == 'G') flags.run += 2;
312.  		if(cmd[2] == '-') flags.run += 1;
313.  		goto rush;
314.  	}
315.  #endif
316.  	while(tlist->f_char) {
317.  		if(*cmd == tlist->f_char){
318.  #ifdef DGKMOD
319.  			/* Special case of *cmd == ' ' handled here */
320.  			if (*cmd == ' ' && flags.no_rest_on_space)
321.  				break;
322.  
323.  			/* Now control-A can stop lengthy commands */
324.  			if (tlist->f_text && !occupation && multi)
325.  				set_occupation(tlist->f_funct, tlist->f_text,
326.  					multi);
327.  #endif
328.  			res = (*(tlist->f_funct))();
329.  			if(!res) {
330.  				flags.move = 0;
331.  				multi = 0;
332.  			}
333.  			return;
334.  		}
335.  		tlist++;
336.  	}
337.  	{ char expcmd[10];
338.  	  register char *cp = expcmd;
339.  	  while(*cmd && cp-expcmd < sizeof(expcmd)-2) {
340.  		if(*cmd >= 040 && *cmd < 0177)
341.  			*cp++ = *cmd++;
342.  		else {
343.  			*cp++ = '^';
344.  			*cp++ = *cmd++ ^ 0100;
345.  		}
346.  	  }
347.  	  *cp++ = 0;
348.  	  pline("Unknown command '%s'.", expcmd);
349.  	}
350.  	multi = flags.move = 0;
351.  	return;
352.  }
353.  
354.  doextcmd()	/* here after # - now read a full-word command */
355.  {
356.  	char buf[BUFSZ];
357.  	register struct ext_func_tab *efp = extcmdlist;
358.  
359.  	pline("# ");
360.  #ifdef COM_COMPL
361.  	get_ext_cmd(buf);
362.  #else
363.  	getlin(buf);
364.  #endif
365.  	clrlin();
366.  	if(buf[0] == '\033')
367.  		return(0);
368.  	while(efp->ef_txt) {
369.  		if(!strcmp(efp->ef_txt, buf))
370.  			return((*(efp->ef_funct))());
371.  		efp++;
372.  	}
373.  	pline("%s: unknown command.", buf);
374.  	return(0);
375.  }
376.  
377.  doextlist()	/* here after #? - now list all full-word commands */
378.  {
379.  	register struct ext_func_tab *efp = extcmdlist;
380.  	char     buf[BUFSZ];
381.  
382.  	set_pager(0);
383.  	if(page_line("") ||
384.  	   page_line("        Extended Command Set:") ||
385.  	   page_line(""))					 goto quit;
386.  
387.  	while(efp->ef_txt) {
388.  
389.  		(void)sprintf(buf, "    %-8s  - %s.", efp->ef_txt, efp->ef_desc);
390.  		if(page_line(buf)) goto quit;
391.  		efp++;
392.  	}
393.  	set_pager(1);
394.  	return(0);
395.  quit:
396.  	set_pager(2);
397.  	return(0);
398.  }
399.  
400.  char
401.  lowc(sym)
402.  char sym;
403.  {
404.      return( (sym >= 'A' && sym <= 'Z') ? sym+'a'-'A' : sym );
405.  }
406.  
407.  char
408.  unctrl(sym)
409.  char sym;
410.  {
411.      return( (sym >= ('A' & 037) && sym <= ('Z' & 037)) ? sym + 0140 : sym );
412.  }
413.  
414.  /* 'rogue'-like direction commands */
415.  char sdir[] = "hykulnjb><";
416.  schar xdir[10] = { -1,-1, 0, 1, 1, 1, 0,-1, 0, 0 };
417.  schar ydir[10] = {  0,-1,-1,-1, 0, 1, 1, 1, 0, 0 };
418.  schar zdir[10] = {  0, 0, 0, 0, 0, 0, 0, 0, 1,-1 };
419.  
420.  movecmd(sym)	/* also sets u.dz, but returns false for <> */
421.  char sym;
422.  {
423.  	register char *dp;
424.  
425.  	u.dz = 0;
426.  	if(!(dp = index(sdir, sym))) return(0);
427.  	u.dx = xdir[dp-sdir];
428.  	u.dy = ydir[dp-sdir];
429.  	u.dz = zdir[dp-sdir];
430.  	return(!u.dz);
431.  }
432.  
433.  getdir(s)
434.  boolean s;
435.  {
436.  	char dirsym;
437.  
438.  #ifdef REDO
439.  	if (!in_doagain)
440.  #endif
441.  	    if(s) pline("In what direction?");
442.  	dirsym = readchar();
443.  #ifdef REDO
444.  	savech(dirsym);
445.  #endif
446.  #ifdef KAA
447.  	if(dirsym == '.' || dirsym == 's')
448.  		u.dx = u.dy = u.dz = 0;
449.  	else
450.  #endif
451.  	if(!movecmd(dirsym) && !u.dz) {
452.  		if(!index(quitchars, dirsym))
453.  			pline("What a strange direction!");
454.  		return(0);
455.  	}
456.  	if(Confusion && !u.dz) confdir();
457.  	return(1);
458.  }
459.  
460.  confdir()
461.  {
462.  	register x = rn2(8);
463.  	u.dx = xdir[x];
464.  	u.dy = ydir[x];
465.  }
466.  
467.  #ifdef QUEST
468.  finddir(){
469.  register int i, ui = u.di;
470.  	for(i = 0; i <= 8; i++){
471.  		if(flags.run & 1) ui++; else ui += 7;
472.  		ui %= 8;
473.  		if(i == 8){
474.  			pline("Not near a wall.");
475.  			flags.move = multi = 0;
476.  			return(0);
477.  		}
478.  		if(!isroom(u.ux+xdir[ui], u.uy+ydir[ui]))
479.  			break;
480.  	}
481.  	for(i = 0; i <= 8; i++){
482.  		if(flags.run & 1) ui += 7; else ui++;
483.  		ui %= 8;
484.  		if(i == 8){
485.  			pline("Not near a room.");
486.  			flags.move = multi = 0;
487.  			return(0);
488.  		}
489.  		if(isroom(u.ux+xdir[ui], u.uy+ydir[ui]))
490.  			break;
491.  	}
492.  	u.di = ui;
493.  	u.dx = xdir[ui];
494.  	u.dy = ydir[ui];
495.  }
496.  
497.  isroom(x,y)  register x,y; {		/* what about POOL? */
498.  	return(isok(x,y) && (levl[x][y].typ == ROOM ||
499.  				(levl[x][y].typ >= LDOOR && flags.run >= 6)));
500.  }
501.  #endif /* QUEST /**/
502.  
503.  isok(x,y) register x,y; {
504.  	/* x corresponds to curx, so x==1 is the first column. Ach. %% */
505.  	return(x >= 1 && x <= COLNO-1 && y >= 0 && y <= ROWNO-1);
506.  }
507.  
508.  #ifdef WIZARD
509.  int wiz_wish()	/* Unlimited wishes for wizard mode by Paul Polderman */
510.  {
511.  	if (!wizard) {
512.  		pline("Alas! You are not allowed to make a wish.");
513.  		pline("Nice try though...");
514.  	} else
515.  		makewish();
516.  	return(0);
517.  }
518.  
519.  int wiz_identify()
520.  {
521.  	struct obj *obj;
522.  
523.  	if (!wizard)
524.  		pline("You don't have the proper identity!");
525.  	else {
526.  		for (obj = invent; obj; obj = obj->nobj)
527.  			if (!objects[obj->otyp].oc_name_known || !obj->known)
528.  				identify(obj);
529.  	}
530.  	return(0);
531.  }
532.  #endif /* WIZARD */