1 /*
2  * Read and execute the user comamnds
3  *
4  * command.c	1.44	(A.I. Design)	2/14/85
5  */
6 
7 #include	"rogue.h"
8 #include	"curses.h"
9 
10 static int lastcount;
11 static byte lastch, do_take, lasttake;
12 
13 command()
14 {
15 	register int ntimes;
16 
17 	if (on(player, ISHASTE))
18 		ntimes = rnd(2) + 2;
19 	else
20 		ntimes = 1;
21 	while (ntimes--) {
22 		status();
23 		SIG2();
24 #ifdef WIZARD
25 		if (wizard)
26 			noscore = TRUE;
27 #endif
28 		if (no_command) {
29 			if (--no_command <= 0) {
30 				msg("you can move again");
31 				no_command = 0;
32 			}
33 		} else
34 			execcom();
35 		do_fuses();
36 		do_daemons();
37 		for (ntimes = LEFT; ntimes <= RIGHT; ntimes++)
38 			if (cur_ring[ntimes])
39 				switch (cur_ring[ntimes]->o_which) {
40 				when R_SEARCH:
41 					search();
42 				when R_TELEPORT:
43 					if (rnd(50) == 17)
44 						teleport();
45 				}
46 	}
47 }
48 
49 com_char()
50 {
51 	register int same, ch;
52 
53 	same = (fastmode == faststate);
54 	ch = readchar();
55 	if (same)
56 		fastmode = faststate;
57 	else
58 		fastmode = !faststate;
59 	switch (ch) {
60 		when '\b': ch = 'h';
61 		when '+': ch = 't';
62 		when '-': ch = 'z';
63 	}
64 	if (mpos && !running)
65 		msg("");
66 	return ch;
67 }
68 
69 /*
70  * Read a command, setting thing up according to prefix like devices
71  * Return the command character to be executed.
72  */
73 
74 get_prefix()
75 {
76 	register int retch, ch, junk;
77 
78 	after = TRUE;
79 	fastmode = faststate;
80 	look(TRUE);
81 	if (!running)
82 		door_stop = FALSE;
83 	do_take = TRUE;
84 	again = FALSE;
85 	if (--count > 0) {
86 		do_take = lasttake;
87 		retch = lastch;
88 		fastmode = FALSE;
89 	} else {
90 		count = 0;
91 		if (running) {
92 			retch = runch;
93 			do_take = lasttake;
94 		} else {
95 			for (retch = 0; retch == 0; ) {
96 				switch (ch = com_char()) {
97 					case '0': case '1': case '2': case '3': case '4':
98 					case '5': case '6': case '7': case '8': case '9':
99 						junk = count * 10;
100 						if ((junk += ch - '0') > 0 && junk < 10000)
101 							count = junk;
102 						show_count();
103 					when 'f':
104 						fastmode = !fastmode;
105 					when 'g':
106 						do_take = FALSE;
107 					when 'a':
108 						retch = lastch;
109 						count = lastcount;
110 						do_take = lasttake;
111 						again = TRUE;
112 					when ' ':	/* Spaces are ignored */
113 					when ESCAPE:
114 						door_stop = FALSE;
115 						count = 0;
116 						show_count();
117 					otherwise:
118 						retch = ch;
119 				}
120 			}
121 		}
122 	}
123 	if (count)
124 		fastmode = FALSE;
125 	switch (retch) {
126 	case 'h': case 'j': case 'k': case 'l':
127 	case 'y': case 'u': case 'b': case 'n':
128 		if (fastmode && !running ) {
129 			if (!on(player, ISBLIND)) {
130 				door_stop = TRUE;
131 				firstmove = TRUE;
132 			}
133 			retch = toupper(retch);
134 		}
135 	case 'H': case 'J': case 'K': case 'L':
136 	case 'Y': case 'U': case 'B': case 'N':
137 	case 'q': case 'r': case 's': case 'z':
138 	case 't': case '.':
139 #ifdef WIZARD
140 	case CTRL(D): case 'C':
141 #endif WIZARD
142 		break;
143 	default:
144 		count = 0;
145 	}
146 	if (count || lastcount)
147 		show_count();
148 	lastch = retch;
149 	lastcount = count;
150 	lasttake = do_take;
151 	return retch;
152 }
153 
154 show_count()
155 {
156 	move(LINES-2, COLS-4);
157 	if (count)
158 		printw("%-4d", count);
159 	else
160 		addstr("    ");
161 }
162 
163 execcom()
164 {
165 	coord mv;
166 	register int ch;
167 
168 	do {
169 		switch (ch = get_prefix()) {
170 		when 'h': case 'j': case 'k': case 'l':
171 		case 'y': case 'u': case 'b': case 'n':
172 			find_dir(ch, &mv);
173 			do_move(mv.y, mv.x);
174 		when 'H': case 'J': case 'K': case 'L':
175 		case 'Y': case 'U': case 'B': case 'N':
176 			do_run(tolower(ch));
177 		when 't':
178 			if (get_dir())
179 				missile(delta.y, delta.x);
180 			else
181 				after = FALSE;
182 		when 'Q': after = FALSE; quit();
183 		when 'i': after = FALSE; inventory(pack, 0, "");
184 		when 'd': drop();
185 		when 'q': quaff();
186 		when 'r': read_scroll();
187 		when 'e': eat();
188 		when 'w': wield();
189 		when 'W': wear();
190 		when 'T': take_off();
191 		when 'P': ring_on();
192 		when 'R': ring_off();
193 		when 'c': after = FALSE; call();
194 		when '>': after = FALSE; d_level();
195 		when '<': after = FALSE; u_level();
196 		when '/': after = FALSE; help(helpobjs);
197 		when '?': after = FALSE; help(helpcoms);
198 		when '!': after = FALSE; fakedos();
199 		when 's': search();
200 		when 'z':
201 			if (get_dir())
202 				do_zap();
203 			else
204 				after = FALSE;
205 		when 'D': after = FALSE; discovered();
206 		when CTRL(T):
207 			after = FALSE;
208 			msg((expert ^= 1)
209 				? "Ok, I'll be brief"
210 				: "Goodie, I can use big words again!");
211 		when 'F': after = FALSE; do_macro(macro, MACROSZ);
212 		when CTRL(F): after = FALSE; typeahead = macro;
213 		when CTRL(R): after = FALSE; msg(huh);
214 		when 'v':
215 			after = FALSE;
216 			if (strcmp(whoami,"The Grand Beeking") == 0)
217 				addmsg("(%d)",csum());
218 			msg("Rogue version %d.%d (Mr. Mctesq was here)", revno, verno);
219 		when 'S': after = FALSE; save_game();
220 		when '.': doctor();
221 		when '^':
222 			after = FALSE;
223 			if (get_dir()) {
224 				coord lookat;
225 
226 				lookat.y = hero.y + delta.y;
227 				lookat.x = hero.x + delta.x;
228 				if (chat(lookat.y, lookat.x) != TRAP)
229 					msg("no trap there.");
230 				else
231 					msg("you found %s",
232 						tr_name(flat(lookat.y, lookat.x) & F_TMASK));
233 			}
234 		when 'o': after = FALSE; msg("i don't have any options, oh my!");
235 		when CTRL(L):
236 			after = FALSE;
237 			msg("the screen looks fine to me (jll was here)");
238 #ifdef WIZARD
239 		when 'C': after = FALSE; create_obj();
240 #endif
241 		otherwise:
242 			after = FALSE;
243 			save_msg = FALSE;
244 			msg("illegal command '%s'", unctrl(ch));
245 			count = 0;
246 			save_msg = TRUE;
247 		}
248 		if (take && do_take)
249 			pick_up(take);
250 		take = 0;
251 		if (!running)
252 			door_stop = FALSE;
253 	} while (after == FALSE);
254 }
255 