Mercurial > hg > early-roguelike
comparison rogue5/command.c @ 33:f502bf60e6e4
Import Rogue 5.4 from the Roguelike Restoration Project (r1490)
author | elwin |
---|---|
date | Mon, 24 May 2010 20:10:59 +0000 |
parents | |
children | f871cb0539d3 |
comparison
equal
deleted
inserted
replaced
32:2dcd75e6a736 | 33:f502bf60e6e4 |
---|---|
1 /* | |
2 * Read and execute the user commands | |
3 * | |
4 * @(#)command.c 4.73 (Berkeley) 08/06/83 | |
5 * | |
6 * Rogue: Exploring the Dungeons of Doom | |
7 * Copyright (C) 1980-1983, 1985, 1999 Michael Toy, Ken Arnold and Glenn Wichman | |
8 * All rights reserved. | |
9 * | |
10 * See the file LICENSE.TXT for full copyright and licensing information. | |
11 */ | |
12 | |
13 #include <stdlib.h> | |
14 #include <string.h> | |
15 #include <curses.h> | |
16 #include <ctype.h> | |
17 #include "rogue.h" | |
18 | |
19 /* | |
20 * command: | |
21 * Process the user commands | |
22 */ | |
23 void | |
24 command(void) | |
25 { | |
26 int ch; | |
27 int ntimes = 1; /* Number of player moves */ | |
28 int *fp; | |
29 THING *mp; | |
30 static int countch, direction, newcount = FALSE; | |
31 | |
32 if (on(player, ISHASTE)) | |
33 ntimes++; | |
34 /* | |
35 * Let the daemons start up | |
36 */ | |
37 do_daemons(BEFORE); | |
38 do_fuses(BEFORE); | |
39 while (ntimes--) | |
40 { | |
41 again = FALSE; | |
42 if (has_hit) | |
43 { | |
44 endmsg(); | |
45 has_hit = FALSE; | |
46 } | |
47 /* | |
48 * these are illegal things for the player to be, so if any are | |
49 * set, someone's been poking in memeory | |
50 */ | |
51 if (on(player, ISSLOW|ISGREED|ISINVIS|ISREGEN|ISTARGET)) | |
52 exit(1); | |
53 | |
54 look(TRUE); | |
55 if (!running) | |
56 door_stop = FALSE; | |
57 status(); | |
58 lastscore = purse; | |
59 move(hero.y, hero.x); | |
60 if (!((running || count) && jump)) | |
61 refresh(); /* Draw screen */ | |
62 take = 0; | |
63 after = TRUE; | |
64 /* | |
65 * Read command or continue run | |
66 */ | |
67 #ifdef MASTER | |
68 if (wizard) | |
69 noscore = TRUE; | |
70 #endif | |
71 if (!no_command) | |
72 { | |
73 if (running || to_death) | |
74 ch = runch; | |
75 else if (count) | |
76 ch = countch; | |
77 else | |
78 { | |
79 ch = readchar(); | |
80 move_on = FALSE; | |
81 if (mpos != 0) /* Erase message if its there */ | |
82 { | |
83 if (ch != '.') | |
84 msg(""); | |
85 } | |
86 } | |
87 } | |
88 else | |
89 ch = '.'; | |
90 if (no_command) | |
91 { | |
92 if (--no_command == 0) | |
93 { | |
94 player.t_flags |= ISRUN; | |
95 msg("you can move again"); | |
96 } | |
97 } | |
98 else | |
99 { | |
100 /* | |
101 * check for prefixes | |
102 */ | |
103 newcount = FALSE; | |
104 if (isdigit(ch)) | |
105 { | |
106 count = 0; | |
107 newcount = TRUE; | |
108 while (isdigit(ch)) | |
109 { | |
110 count = count * 10 + (ch - '0'); | |
111 if (count > 255) | |
112 count = 255; | |
113 ch = readchar(); | |
114 } | |
115 countch = ch; | |
116 /* | |
117 * turn off count for commands which don't make sense | |
118 * to repeat | |
119 */ | |
120 switch (ch) | |
121 { | |
122 case CTRL('B'): case CTRL('H'): case CTRL('J'): | |
123 case CTRL('K'): case CTRL('L'): case CTRL('N'): | |
124 case CTRL('U'): case CTRL('Y'): | |
125 case '.': case 'a': case 'b': case 'h': case 'j': | |
126 case 'k': case 'l': case 'm': case 'n': case 'q': | |
127 case 'r': case 's': case 't': case 'u': case 'y': | |
128 case 'z': case 'B': case 'C': case 'H': case 'I': | |
129 case 'J': case 'K': case 'L': case 'N': case 'U': | |
130 case 'Y': | |
131 #ifdef MASTER | |
132 case CTRL('D'): case CTRL('A'): | |
133 #endif | |
134 break; | |
135 default: | |
136 count = 0; | |
137 } | |
138 } | |
139 /* | |
140 * execute a command | |
141 */ | |
142 if (count && !running) | |
143 count--; | |
144 if (ch != 'a' && ch != ESCAPE && !(running || count || to_death)) | |
145 { | |
146 l_last_comm = last_comm; | |
147 l_last_dir = last_dir; | |
148 l_last_pick = last_pick; | |
149 last_comm = ch; | |
150 last_dir = '\0'; | |
151 last_pick = NULL; | |
152 } | |
153 over: | |
154 switch (ch) | |
155 { | |
156 case ',': { | |
157 THING *obj = NULL; | |
158 int found = 0; | |
159 for (obj = lvl_obj; obj != NULL; obj = next(obj)) | |
160 { | |
161 if (obj->o_pos.y == hero.y && obj->o_pos.x == hero.x) | |
162 { | |
163 found=1; | |
164 break; | |
165 } | |
166 } | |
167 | |
168 if (found) { | |
169 if (levit_check()) | |
170 ; | |
171 else | |
172 pick_up(obj->o_type); | |
173 } | |
174 else { | |
175 if (!terse) | |
176 addmsg("there is "); | |
177 addmsg("nothing here"); | |
178 if (!terse) | |
179 addmsg(" to pick up"); | |
180 endmsg(); | |
181 } | |
182 } | |
183 when '!': shell(); | |
184 when 'h': do_move(0, -1); | |
185 when 'j': do_move(1, 0); | |
186 when 'k': do_move(-1, 0); | |
187 when 'l': do_move(0, 1); | |
188 when 'y': do_move(-1, -1); | |
189 when 'u': do_move(-1, 1); | |
190 when 'b': do_move(1, -1); | |
191 when 'n': do_move(1, 1); | |
192 when 'H': do_run('h'); | |
193 when 'J': do_run('j'); | |
194 when 'K': do_run('k'); | |
195 when 'L': do_run('l'); | |
196 when 'Y': do_run('y'); | |
197 when 'U': do_run('u'); | |
198 when 'B': do_run('b'); | |
199 when 'N': do_run('n'); | |
200 when CTRL('H'): case CTRL('J'): case CTRL('K'): case CTRL('L'): | |
201 case CTRL('Y'): case CTRL('U'): case CTRL('B'): case CTRL('N'): | |
202 { | |
203 if (!on(player, ISBLIND)) | |
204 { | |
205 door_stop = TRUE; | |
206 firstmove = TRUE; | |
207 } | |
208 if (count && !newcount) | |
209 ch = direction; | |
210 else | |
211 { | |
212 ch += ('A' - CTRL('A')); | |
213 direction = ch; | |
214 } | |
215 goto over; | |
216 } | |
217 when 'F': | |
218 kamikaze = TRUE; | |
219 /* FALLTHROUGH */ | |
220 case 'f': | |
221 if (!get_dir()) | |
222 { | |
223 after = FALSE; | |
224 break; | |
225 } | |
226 delta.y += hero.y; | |
227 delta.x += hero.x; | |
228 if ( ((mp = moat(delta.y, delta.x)) == NULL) | |
229 || ((!see_monst(mp)) && !on(player, SEEMONST))) | |
230 { | |
231 if (!terse) | |
232 addmsg("I see "); | |
233 msg("no monster there"); | |
234 after = FALSE; | |
235 } | |
236 else if (diag_ok(&hero, &delta)) | |
237 { | |
238 to_death = TRUE; | |
239 max_hit = 0; | |
240 mp->t_flags |= ISTARGET; | |
241 runch = ch = dir_ch; | |
242 goto over; | |
243 } | |
244 when 't': | |
245 if (!get_dir()) | |
246 after = FALSE; | |
247 else | |
248 missile(delta.y, delta.x); | |
249 when 'a': | |
250 if (last_comm == '\0') | |
251 { | |
252 msg("you haven't typed a command yet"); | |
253 after = FALSE; | |
254 } | |
255 else | |
256 { | |
257 ch = last_comm; | |
258 again = TRUE; | |
259 goto over; | |
260 } | |
261 when 'q': quaff(); | |
262 when 'Q': | |
263 after = FALSE; | |
264 q_comm = TRUE; | |
265 quit(0); | |
266 q_comm = FALSE; | |
267 when 'i': after = FALSE; inventory(pack, 0); | |
268 when 'I': after = FALSE; picky_inven(); | |
269 when 'd': drop(); | |
270 when 'r': read_scroll(); | |
271 when 'e': eat(); | |
272 when 'w': wield(); | |
273 when 'W': wear(); | |
274 when 'T': take_off(); | |
275 when 'P': ring_on(); | |
276 when 'R': ring_off(); | |
277 when 'o': option(); after = FALSE; | |
278 when 'c': call(); after = FALSE; | |
279 when '>': after = FALSE; d_level(); | |
280 when '<': after = FALSE; u_level(); | |
281 when '?': after = FALSE; help(); | |
282 when '/': after = FALSE; identify(); | |
283 when 's': search(); | |
284 when 'z': | |
285 if (get_dir()) | |
286 do_zap(); | |
287 else | |
288 after = FALSE; | |
289 when 'D': after = FALSE; discovered(); | |
290 when CTRL('P'): after = FALSE; msg(huh); | |
291 when CTRL('R'): | |
292 after = FALSE; | |
293 clearok(curscr,TRUE); | |
294 wrefresh(curscr); | |
295 when 'v': | |
296 after = FALSE; | |
297 msg("version %s. (mctesq was here)", release); | |
298 when 'S': | |
299 after = FALSE; | |
300 save_game(); | |
301 when '.': ; /* Rest command */ | |
302 when ' ': after = FALSE; /* "Legal" illegal command */ | |
303 when '^': | |
304 after = FALSE; | |
305 if (get_dir()) { | |
306 delta.y += hero.y; | |
307 delta.x += hero.x; | |
308 fp = &flat(delta.y, delta.x); | |
309 if (!terse) | |
310 addmsg("You have found "); | |
311 if (chat(delta.y, delta.x) != TRAP) | |
312 msg("no trap there"); | |
313 else if (on(player, ISHALU)) | |
314 msg(tr_name[rnd(NTRAPS)]); | |
315 else { | |
316 msg(tr_name[*fp & F_TMASK]); | |
317 *fp |= F_SEEN; | |
318 } | |
319 } | |
320 #ifdef MASTER | |
321 when '+': | |
322 after = FALSE; | |
323 if (wizard) | |
324 { | |
325 wizard = FALSE; | |
326 turn_see(TRUE); | |
327 msg("not wizard any more"); | |
328 } | |
329 else | |
330 { | |
331 wizard = passwd(); | |
332 if (wizard) | |
333 { | |
334 noscore = TRUE; | |
335 turn_see(FALSE); | |
336 msg("you are suddenly as smart as Ken Arnold in dungeon #%d", dnum); | |
337 } | |
338 else | |
339 msg("sorry"); | |
340 } | |
341 #endif | |
342 when ESCAPE: /* Escape */ | |
343 door_stop = FALSE; | |
344 count = 0; | |
345 after = FALSE; | |
346 again = FALSE; | |
347 when 'm': | |
348 move_on = TRUE; | |
349 if (!get_dir()) | |
350 after = FALSE; | |
351 else | |
352 { | |
353 ch = dir_ch; | |
354 countch = dir_ch; | |
355 goto over; | |
356 } | |
357 when ')': current(cur_weapon, "wielding", NULL); | |
358 when ']': current(cur_armor, "wearing", NULL); | |
359 when '=': | |
360 current(cur_ring[LEFT], "wearing", | |
361 terse ? "(L)" : "on left hand"); | |
362 current(cur_ring[RIGHT], "wearing", | |
363 terse ? "(R)" : "on right hand"); | |
364 when '@': | |
365 stat_msg = TRUE; | |
366 status(); | |
367 stat_msg = FALSE; | |
368 after = FALSE; | |
369 otherwise: | |
370 after = FALSE; | |
371 #ifdef MASTER | |
372 if (wizard) switch (ch) | |
373 { | |
374 case '|': msg("@ %d,%d", hero.y, hero.x); | |
375 when 'C': create_obj(); | |
376 when '$': msg("inpack = %d", inpack); | |
377 when CTRL('G'): inventory(lvl_obj, 0); | |
378 when CTRL('W'): whatis(FALSE, 0); | |
379 when CTRL('D'): level++; new_level(); | |
380 when CTRL('A'): level--; new_level(); | |
381 when CTRL('F'): show_map(); | |
382 when CTRL('T'): teleport(); | |
383 when CTRL('E'): msg("food left: %d", food_left); | |
384 when CTRL('Q'): add_pass(); | |