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