Home | History | Annotate | Line # | Download | only in hack
hack.cmd.c revision 1.2
      1  1.2  mycroft /*
      2  1.2  mycroft  * Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985.
      3  1.2  mycroft  */
      4  1.2  mycroft 
      5  1.2  mycroft #ifndef lint
      6  1.2  mycroft static char rcsid[] = "$Id: hack.cmd.c,v 1.2 1993/08/02 17:17:02 mycroft Exp $";
      7  1.2  mycroft #endif /* not lint */
      8  1.1      cgd 
      9  1.1      cgd #include	"hack.h"
     10  1.1      cgd #include	"def.func_tab.h"
     11  1.1      cgd 
     12  1.1      cgd int doredraw(),doredotopl(),dodrop(),dodrink(),doread(),dosearch(),dopickup(),
     13  1.1      cgd doversion(),doweararm(),dowearring(),doremarm(),doremring(),dopay(),doapply(),
     14  1.1      cgd dosave(),dowield(),ddoinv(),dozap(),ddocall(),dowhatis(),doengrave(),dotele(),
     15  1.1      cgd dohelp(),doeat(),doddrop(),do_mname(),doidtrap(),doprwep(),doprarm(),
     16  1.1      cgd doprring(),doprgold(),dodiscovered(),dotypeinv(),dolook(),doset(),
     17  1.1      cgd doup(), dodown(), done1(), donull(), dothrow(), doextcmd(), dodip(), dopray();
     18  1.1      cgd #ifdef SHELL
     19  1.1      cgd int dosh();
     20  1.1      cgd #endif SHELL
     21  1.1      cgd #ifdef SUSPEND
     22  1.1      cgd int dosuspend();
     23  1.1      cgd #endif SUSPEND
     24  1.1      cgd 
     25  1.1      cgd struct func_tab cmdlist[]={
     26  1.1      cgd 	'\020', doredotopl,
     27  1.1      cgd 	'\022', doredraw,
     28  1.1      cgd 	'\024', dotele,
     29  1.1      cgd #ifdef SUSPEND
     30  1.1      cgd 	'\032', dosuspend,
     31  1.1      cgd #endif SUSPEND
     32  1.1      cgd 	'a', doapply,
     33  1.1      cgd /*	'A' : UNUSED */
     34  1.1      cgd /*	'b', 'B' : go sw */
     35  1.1      cgd 	'c', ddocall,
     36  1.1      cgd 	'C', do_mname,
     37  1.1      cgd 	'd', dodrop,
     38  1.1      cgd 	'D', doddrop,
     39  1.1      cgd 	'e', doeat,
     40  1.1      cgd 	'E', doengrave,
     41  1.1      cgd /*	'f', 'F' : multiple go (might become 'fight') */
     42  1.1      cgd /*	'g', 'G' : UNUSED */
     43  1.1      cgd /*	'h', 'H' : go west */
     44  1.1      cgd 	'I', dotypeinv,		/* Robert Viduya */
     45  1.1      cgd 	'i', ddoinv,
     46  1.1      cgd /*	'j', 'J', 'k', 'K', 'l', 'L', 'm', 'M', 'n', 'N' : move commands */
     47  1.1      cgd /*	'o', doopen,	*/
     48  1.1      cgd 	'O', doset,
     49  1.1      cgd 	'p', dopay,
     50  1.1      cgd 	'P', dowearring,
     51  1.1      cgd 	'q', dodrink,
     52  1.1      cgd 	'Q', done1,
     53  1.1      cgd 	'r', doread,
     54  1.1      cgd 	'R', doremring,
     55  1.1      cgd 	's', dosearch,
     56  1.1      cgd 	'S', dosave,
     57  1.1      cgd 	't', dothrow,
     58  1.1      cgd 	'T', doremarm,
     59  1.1      cgd /*	'u', 'U' : go ne */
     60  1.1      cgd 	'v', doversion,
     61  1.1      cgd /*	'V' : UNUSED */
     62  1.1      cgd 	'w', dowield,
     63  1.1      cgd 	'W', doweararm,
     64  1.1      cgd /*	'x', 'X' : UNUSED */
     65  1.1      cgd /*	'y', 'Y' : go nw */
     66  1.1      cgd 	'z', dozap,
     67  1.1      cgd /*	'Z' : UNUSED */
     68  1.1      cgd 	'<', doup,
     69  1.1      cgd 	'>', dodown,
     70  1.1      cgd 	'/', dowhatis,
     71  1.1      cgd 	'?', dohelp,
     72  1.1      cgd #ifdef SHELL
     73  1.1      cgd 	'!', dosh,
     74  1.1      cgd #endif SHELL
     75  1.1      cgd 	'.', donull,
     76  1.1      cgd 	' ', donull,
     77  1.1      cgd 	',', dopickup,
     78  1.1      cgd 	':', dolook,
     79  1.1      cgd 	'^', doidtrap,
     80  1.1      cgd 	'\\', dodiscovered,		/* Robert Viduya */
     81  1.1      cgd 	 WEAPON_SYM,  doprwep,
     82  1.1      cgd 	 ARMOR_SYM,  doprarm,
     83  1.1      cgd 	 RING_SYM,  doprring,
     84  1.1      cgd 	'$', doprgold,
     85  1.1      cgd 	'#', doextcmd,
     86  1.1      cgd 	0,0,0
     87  1.1      cgd };
     88  1.1      cgd 
     89  1.1      cgd struct ext_func_tab extcmdlist[] = {
     90  1.1      cgd 	"dip", dodip,
     91  1.1      cgd 	"pray", dopray,
     92  1.1      cgd 	(char *) 0, donull
     93  1.1      cgd };
     94  1.1      cgd 
     95  1.1      cgd extern char *parse(), lowc(), unctrl(), quitchars[];
     96  1.1      cgd 
     97  1.1      cgd rhack(cmd)
     98  1.1      cgd register char *cmd;
     99  1.1      cgd {
    100  1.1      cgd 	register struct func_tab *tlist = cmdlist;
    101  1.1      cgd 	boolean firsttime = FALSE;
    102  1.1      cgd 	register res;
    103  1.1      cgd 
    104  1.1      cgd 	if(!cmd) {
    105  1.1      cgd 		firsttime = TRUE;
    106  1.1      cgd 		flags.nopick = 0;
    107  1.1      cgd 		cmd = parse();
    108  1.1      cgd 	}
    109  1.1      cgd 	if(!*cmd || (*cmd & 0377) == 0377 ||
    110  1.1      cgd 	   (flags.no_rest_on_space && *cmd == ' ')){
    111  1.1      cgd 		bell();
    112  1.1      cgd 		flags.move = 0;
    113  1.1      cgd 		return;		/* probably we just had an interrupt */
    114  1.1      cgd 	}
    115  1.1      cgd 	if(movecmd(*cmd)) {
    116  1.1      cgd 	walk:
    117  1.1      cgd 		if(multi) flags.mv = 1;
    118  1.1      cgd 		domove();
    119  1.1      cgd 		return;
    120  1.1      cgd 	}
    121  1.1      cgd 	if(movecmd(lowc(*cmd))) {
    122  1.1      cgd 		flags.run = 1;
    123  1.1      cgd 	rush:
    124  1.1      cgd 		if(firsttime){
    125  1.1      cgd 			if(!multi) multi = COLNO;
    126  1.1      cgd 			u.last_str_turn = 0;
    127  1.1      cgd 		}
    128  1.1      cgd 		flags.mv = 1;
    129  1.1      cgd #ifdef QUEST
    130  1.1      cgd 		if(flags.run >= 4) finddir();
    131  1.1      cgd 		if(firsttime){
    132  1.1      cgd 			u.ux0 = u.ux + u.dx;
    133  1.1      cgd 			u.uy0 = u.uy + u.dy;
    134  1.1      cgd 		}
    135  1.1      cgd #endif QUEST
    136  1.1      cgd 		domove();
    137  1.1      cgd 		return;
    138  1.1      cgd 	}
    139  1.1      cgd 	if((*cmd == 'f' && movecmd(cmd[1])) || movecmd(unctrl(*cmd))) {
    140  1.1      cgd 		flags.run = 2;
    141  1.1      cgd 		goto rush;
    142  1.1      cgd 	}
    143  1.1      cgd 	if(*cmd == 'F' && movecmd(lowc(cmd[1]))) {
    144  1.1      cgd 		flags.run = 3;
    145  1.1      cgd 		goto rush;
    146  1.1      cgd 	}
    147  1.1      cgd 	if(*cmd == 'm' && movecmd(cmd[1])) {
    148  1.1      cgd 		flags.run = 0;
    149  1.1      cgd 		flags.nopick = 1;
    150  1.1      cgd 		goto walk;
    151  1.1      cgd 	}
    152  1.1      cgd 	if(*cmd == 'M' && movecmd(lowc(cmd[1]))) {
    153  1.1      cgd 		flags.run = 1;
    154  1.1      cgd 		flags.nopick = 1;
    155  1.1      cgd 		goto rush;
    156  1.1      cgd 	}
    157  1.1      cgd #ifdef QUEST
    158  1.1      cgd 	if(*cmd == cmd[1] && (*cmd == 'f' || *cmd == 'F')) {
    159  1.1      cgd 		flags.run = 4;
    160  1.1      cgd 		if(*cmd == 'F') flags.run += 2;
    161  1.1      cgd 		if(cmd[2] == '-') flags.run += 1;
    162  1.1      cgd 		goto rush;
    163  1.1      cgd 	}
    164  1.1      cgd #endif QUEST
    165  1.1      cgd 	while(tlist->f_char) {
    166  1.1      cgd 		if(*cmd == tlist->f_char){
    167  1.1      cgd 			res = (*(tlist->f_funct))();
    168  1.1      cgd 			if(!res) {
    169  1.1      cgd 				flags.move = 0;
    170  1.1      cgd 				multi = 0;
    171  1.1      cgd 			}
    172  1.1      cgd 			return;
    173  1.1      cgd 		}
    174  1.1      cgd 		tlist++;
    175  1.1      cgd 	}
    176  1.1      cgd 	{ char expcmd[10];
    177  1.1      cgd 	  register char *cp = expcmd;
    178  1.1      cgd 	  while(*cmd && cp-expcmd < sizeof(expcmd)-2) {
    179  1.1      cgd 		if(*cmd >= 040 && *cmd < 0177)
    180  1.1      cgd 			*cp++ = *cmd++;
    181  1.1      cgd 		else {
    182  1.1      cgd 			*cp++ = '^';
    183  1.1      cgd 			*cp++ = *cmd++ ^ 0100;
    184  1.1      cgd 		}
    185  1.1      cgd 	  }
    186  1.1      cgd 	  *cp++ = 0;
    187  1.1      cgd 	  pline("Unknown command '%s'.", expcmd);
    188  1.1      cgd 	}
    189  1.1      cgd 	multi = flags.move = 0;
    190  1.1      cgd }
    191  1.1      cgd 
    192  1.1      cgd doextcmd()	/* here after # - now read a full-word command */
    193  1.1      cgd {
    194  1.1      cgd 	char buf[BUFSZ];
    195  1.1      cgd 	register struct ext_func_tab *efp = extcmdlist;
    196  1.1      cgd 
    197  1.1      cgd 	pline("# ");
    198  1.1      cgd 	getlin(buf);
    199  1.1      cgd 	clrlin();
    200  1.1      cgd 	if(buf[0] == '\033')
    201  1.1      cgd 		return(0);
    202  1.1      cgd 	while(efp->ef_txt) {
    203  1.1      cgd 		if(!strcmp(efp->ef_txt, buf))
    204  1.1      cgd 			return((*(efp->ef_funct))());
    205  1.1      cgd 		efp++;
    206  1.1      cgd 	}
    207  1.1      cgd 	pline("%s: unknown command.", buf);
    208  1.1      cgd 	return(0);
    209  1.1      cgd }
    210  1.1      cgd 
    211  1.1      cgd char
    212  1.1      cgd lowc(sym)
    213  1.1      cgd char sym;
    214  1.1      cgd {
    215  1.1      cgd     return( (sym >= 'A' && sym <= 'Z') ? sym+'a'-'A' : sym );
    216  1.1      cgd }
    217  1.1      cgd 
    218  1.1      cgd char
    219  1.1      cgd unctrl(sym)
    220  1.1      cgd char sym;
    221  1.1      cgd {
    222  1.1      cgd     return( (sym >= ('A' & 037) && sym <= ('Z' & 037)) ? sym + 0140 : sym );
    223  1.1      cgd }
    224  1.1      cgd 
    225  1.1      cgd /* 'rogue'-like direction commands */
    226  1.1      cgd char sdir[] = "hykulnjb><";
    227  1.1      cgd schar xdir[10] = { -1,-1, 0, 1, 1, 1, 0,-1, 0, 0 };
    228  1.1      cgd schar ydir[10] = {  0,-1,-1,-1, 0, 1, 1, 1, 0, 0 };
    229  1.1      cgd schar zdir[10] = {  0, 0, 0, 0, 0, 0, 0, 0, 1,-1 };
    230  1.1      cgd 
    231  1.1      cgd movecmd(sym)	/* also sets u.dz, but returns false for <> */
    232  1.1      cgd char sym;
    233  1.1      cgd {
    234  1.1      cgd 	register char *dp;
    235  1.1      cgd 
    236  1.1      cgd 	u.dz = 0;
    237  1.1      cgd 	if(!(dp = index(sdir, sym))) return(0);
    238  1.1      cgd 	u.dx = xdir[dp-sdir];
    239  1.1      cgd 	u.dy = ydir[dp-sdir];
    240  1.1      cgd 	u.dz = zdir[dp-sdir];
    241  1.1      cgd 	return(!u.dz);
    242  1.1      cgd }
    243  1.1      cgd 
    244  1.1      cgd getdir(s)
    245  1.1      cgd boolean s;
    246  1.1      cgd {
    247  1.1      cgd 	char dirsym;
    248  1.1      cgd 
    249  1.1      cgd 	if(s) pline("In what direction?");
    250  1.1      cgd 	dirsym = readchar();
    251  1.1      cgd 	if(!movecmd(dirsym) && !u.dz) {
    252  1.1      cgd 		if(!index(quitchars, dirsym))
    253  1.1      cgd 			pline("What a strange direction!");
    254  1.1      cgd 		return(0);
    255  1.1      cgd 	}
    256  1.1      cgd 	if(Confusion && !u.dz)
    257  1.1      cgd 		confdir();
    258  1.1      cgd 	return(1);
    259  1.1      cgd }
    260  1.1      cgd 
    261  1.1      cgd confdir()
    262  1.1      cgd {
    263  1.1      cgd 	register x = rn2(8);
    264  1.1      cgd 	u.dx = xdir[x];
    265  1.1      cgd 	u.dy = ydir[x];
    266  1.1      cgd }
    267  1.1      cgd 
    268  1.1      cgd #ifdef QUEST
    269  1.1      cgd finddir(){
    270  1.1      cgd register int i, ui = u.di;
    271  1.1      cgd 	for(i = 0; i <= 8; i++){
    272  1.1      cgd 		if(flags.run & 1) ui++; else ui += 7;
    273  1.1      cgd 		ui %= 8;
    274  1.1      cgd 		if(i == 8){
    275  1.1      cgd 			pline("Not near a wall.");
    276  1.1      cgd 			flags.move = multi = 0;
    277  1.1      cgd 			return(0);
    278  1.1      cgd 		}
    279  1.1      cgd 		if(!isroom(u.ux+xdir[ui], u.uy+ydir[ui]))
    280  1.1      cgd 			break;
    281  1.1      cgd 	}
    282  1.1      cgd 	for(i = 0; i <= 8; i++){
    283  1.1      cgd 		if(flags.run & 1) ui += 7; else ui++;
    284  1.1      cgd 		ui %= 8;
    285  1.1      cgd 		if(i == 8){
    286  1.1      cgd 			pline("Not near a room.");
    287  1.1      cgd 			flags.move = multi = 0;
    288  1.1      cgd 			return(0);
    289  1.1      cgd 		}
    290  1.1      cgd 		if(isroom(u.ux+xdir[ui], u.uy+ydir[ui]))
    291  1.1      cgd 			break;
    292  1.1      cgd 	}
    293  1.1      cgd 	u.di = ui;
    294  1.1      cgd 	u.dx = xdir[ui];
    295  1.1      cgd 	u.dy = ydir[ui];
    296  1.1      cgd }
    297  1.1      cgd 
    298  1.1      cgd isroom(x,y)  register x,y; {		/* what about POOL? */
    299  1.1      cgd 	return(isok(x,y) && (levl[x][y].typ == ROOM ||
    300  1.1      cgd 				(levl[x][y].typ >= LDOOR && flags.run >= 6)));
    301  1.1      cgd }
    302  1.1      cgd #endif QUEST
    303  1.1      cgd 
    304  1.1      cgd isok(x,y) register x,y; {
    305  1.1      cgd 	/* x corresponds to curx, so x==1 is the first column. Ach. %% */
    306  1.1      cgd 	return(x >= 1 && x <= COLNO-1 && y >= 0 && y <= ROWNO-1);
    307  1.1      cgd }
    308