Mercurial > hg > early-roguelike
comparison rogue3/command.c @ 0:527e2150eaf0
Import Rogue 3.6 from the Roguelike Restoration Project (r1490)
author | edwarj4 |
---|---|
date | Tue, 13 Oct 2009 13:33:34 +0000 |
parents | |
children | e551d384f7c6 |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:527e2150eaf0 |
---|---|
1 /* | |
2 * Read and execute the user commands | |
3 * | |
4 * @(#)command.c 3.45 (Berkeley) 6/15/81 | |
5 * | |
6 * Rogue: Exploring the Dungeons of Doom | |
7 * Copyright (C) 1980, 1981 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 <ctype.h> | |
15 #include <signal.h> | |
16 #include <string.h> | |
17 #include "curses.h" | |
18 #include "machdep.h" | |
19 #include "rogue.h" | |
20 | |
21 /* | |
22 * command: | |
23 * Process the user commands | |
24 */ | |
25 | |
26 void | |
27 command() | |
28 { | |
29 int ch; | |
30 int ntimes = 1; /* Number of player moves */ | |
31 static int countch, direction, newcount = FALSE; | |
32 | |
33 | |
34 if (on(player, ISHASTE)) ntimes++; | |
35 /* | |
36 * Let the daemons start up | |
37 */ | |
38 do_daemons(BEFORE); | |
39 do_fuses(BEFORE); | |
40 while (ntimes--) | |
41 { | |
42 look(TRUE); | |
43 if (!running) | |
44 door_stop = FALSE; | |
45 status(); | |
46 lastscore = purse; | |
47 wmove(cw, hero.y, hero.x); | |
48 if (!((running || count) && jump)) | |
49 draw(cw); /* Draw screen */ | |
50 take = 0; | |
51 after = TRUE; | |
52 /* | |
53 * Read command or continue run | |
54 */ | |
55 if (wizard) | |
56 waswizard = TRUE; | |
57 if (!no_command) | |
58 { | |
59 if (running) ch = runch; | |
60 else if (count) ch = countch; | |
61 else | |
62 { | |
63 ch = readchar(cw); | |
64 if (mpos != 0 && !running) /* Erase message if its there */ | |
65 msg(""); | |
66 } | |
67 } | |
68 else ch = ' '; | |
69 if (no_command) | |
70 { | |
71 if (--no_command == 0) | |
72 msg("You can move again."); | |
73 } | |
74 else | |
75 { | |
76 /* | |
77 * check for prefixes | |
78 */ | |
79 if (isdigit(ch)) | |
80 { | |
81 count = 0; | |
82 newcount = TRUE; | |
83 while (isdigit(ch)) | |
84 { | |
85 count = count * 10 + (ch - '0'); | |
86 ch = readchar(cw); | |
87 } | |
88 countch = ch; | |
89 /* | |
90 * turn off count for commands which don't make sense | |
91 * to repeat | |
92 */ | |
93 switch (ch) { | |
94 case 'h': case 'j': case 'k': case 'l': | |
95 case 'y': case 'u': case 'b': case 'n': | |
96 case 'H': case 'J': case 'K': case 'L': | |
97 case 'Y': case 'U': case 'B': case 'N': | |
98 case 'q': case 'r': case 's': case 'f': | |
99 case 't': case 'C': case 'I': case ' ': | |
100 case 'z': case 'p': | |
101 break; | |
102 default: | |
103 count = 0; | |
104 } | |
105 } | |
106 switch (ch) | |
107 { | |
108 case 'f': | |
109 if (!on(player, ISBLIND)) | |
110 { | |
111 door_stop = TRUE; | |
112 firstmove = TRUE; | |
113 } | |
114 if (count && !newcount) | |
115 ch = direction; | |
116 else | |
117 ch = readchar(cw); | |
118 switch (ch) | |
119 { | |
120 case 'h': case 'j': case 'k': case 'l': | |
121 case 'y': case 'u': case 'b': case 'n': | |
122 ch = toupper(ch); | |
123 } | |
124 direction = ch; | |
125 } | |
126 newcount = FALSE; | |
127 /* | |
128 * execute a command | |
129 */ | |
130 if (count && !running) | |
131 count--; | |
132 switch (ch) | |
133 { | |
134 case '!' : shell(); | |
135 when 'h' : do_move(0, -1); | |
136 when 'j' : do_move(1, 0); | |
137 when 'k' : do_move(-1, 0); | |
138 when 'l' : do_move(0, 1); | |
139 when 'y' : do_move(-1, -1); | |
140 when 'u' : do_move(-1, 1); | |
141 when 'b' : do_move(1, -1); | |
142 when 'n' : do_move(1, 1); | |
143 when 'H' : do_run('h'); | |
144 when 'J' : do_run('j'); | |
145 when 'K' : do_run('k'); | |
146 when 'L' : do_run('l'); | |
147 when 'Y' : do_run('y'); | |
148 when 'U' : do_run('u'); | |
149 when 'B' : do_run('b'); | |
150 when 'N' : do_run('n'); | |
151 when 't': | |
152 if (!get_dir()) | |
153 after = FALSE; | |
154 else | |
155 missile(delta.y, delta.x); | |
156 when 'Q' : after = FALSE; quit(0); | |
157 when 'i' : after = FALSE; inventory(pack, 0); | |
158 when 'I' : after = FALSE; picky_inven(); | |
159 when 'd' : drop(); | |
160 when 'q' : quaff(); | |
161 when 'r' : read_scroll(); | |
162 when 'e' : eat(); | |
163 when 'w' : wield(); | |
164 when 'W' : wear(); | |
165 when 'T' : take_off(); | |
166 when 'P' : ring_on(); | |
167 when 'R' : ring_off(); | |
168 when 'o' : option(); | |
169 when 'c' : call(); | |
170 when '>' : after = FALSE; d_level(); | |
171 when '<' : after = FALSE; u_level(); | |
172 when '?' : after = FALSE; help(); | |
173 when '/' : after = FALSE; identify(); | |
174 when 's' : search(); | |
175 when 'z' : do_zap(FALSE); | |
176 when 'p': | |
177 if (get_dir()) | |
178 do_zap(TRUE); | |
179 else | |
180 after = FALSE; | |
181 when 'v' : msg("Rogue version %s. (mctesq was here)", release); | |
182 when CTRL('L') : after = FALSE; clearok(curscr,TRUE);draw(curscr); | |
183 when CTRL('R') : after = FALSE; msg(huh); | |
184 when 'S' : | |
185 after = FALSE; | |
186 if (save_game()) | |
187 { | |
188 wmove(cw, LINES-1, 0); | |
189 wclrtoeol(cw); | |
190 draw(cw); | |
191 endwin(); | |
192 exit(0); | |
193 } | |
194 when ' ' : ; /* Rest command */ | |
195 when CTRL('P') : | |
196 after = FALSE; | |
197 if (wizard) | |
198 { | |
199 wizard = FALSE; | |
200 msg("Not wizard any more"); | |
201 } | |
202 else | |
203 { | |
204 if (wizard = passwd()) | |
205 { | |
206 msg("You are suddenly as smart as Ken Arnold in dungeon #%d", dnum); | |
207 wizard = TRUE; | |
208 waswizard = TRUE; | |
209 } | |
210 else | |
211 msg("Sorry"); | |
212 } | |
213 when ESCAPE : /* Escape */ | |
214 door_stop = FALSE; | |
215 count = 0; | |
216 after = FALSE; | |
217 otherwise : | |
218 after = FALSE; | |
219 if (wizard) switch (ch) | |
220 { | |
221 case '@' : msg("@ %d,%d", hero.y, hero.x); | |
222 when 'C' : create_obj(); | |
223 when CTRL('I') : inventory(lvl_obj, 0); | |
224 when CTRL('W') : whatis(); | |
225 when CTRL('D') : level++; new_level(); | |
226 when CTRL('U') : level--; new_level(); | |
227 when CTRL('F') : show_win(stdscr, "--More (level map)--"); | |
228 when CTRL('X') : show_win(mw, "--More (monsters)--"); | |
229 when CTRL('T') : teleport(); | |
230 when CTRL('E') : msg("food left: %d", food_left); | |
231 when CTRL('A') : msg("%d things in your pack", inpack); | |
232 when CTRL('C') : add_pass(); | |
233 when CTRL('N') : | |
234 { | |
235 struct linked_list *item; | |
236 | |
237 if ((item = get_item("charge", STICK)) != NULL) | |
238 ((struct object *) ldata(item))->o_charges = 10000; | |
239 } | |
240 when CTRL('H') : | |
241 { | |
242 int i; | |
243 struct linked_list *item; | |
244 struct object *obj; | |
245 | |
246 for (i = 0; i < 9; i++) | |
247 raise_level(); | |
248 /* | |
249 * Give the rogue a sword (+1,+1) | |
250 */ | |
251 item = new_item(sizeof *obj); | |
252 obj = (struct object *) ldata(item); | |
253 obj->o_type = WEAPON; | |
254 obj->o_which = TWOSWORD; | |
255 init_weapon(obj, SWORD); | |
256 obj->o_hplus = 1; | |
257 obj->o_dplus = 1; | |
258 add_pack(item, TRUE); | |
259 cur_weapon = obj; | |
260 /* | |
261 * And his suit of armor | |
262 */ | |
263 item = new_item(sizeof *obj); | |
264 obj = (struct object *) ldata(item); | |
265 obj->o_type = ARMOR; | |
266 obj->o_which = PLATE_MAIL; | |
267 obj->o_ac = -5; | |
268 obj->o_flags |= ISKNOW; | |
269 cur_armor = obj; | |
270 add_pack(item, TRUE); | |
271 } | |
272 otherwise : | |
273 msg("Illegal command '%s'.", unctrl(ch)); | |
274 count = 0; | |
275 } | |
276 else | |
277 { | |
278 msg("Illegal command '%s'.", unctrl(ch)); | |
279 count = 0; | |
280 } | |
281 } | |
282 /* | |
283 * turn off flags if no longer needed | |
284 */ | |
285 if (!running) | |
286 door_stop = FALSE; | |
287 } | |
288 /* | |
289 * If he ran into something to take, let him pick it up. | |
290 */ | |
291 if (take != 0) | |
292 pick_up(take); | |
293 if (!running) | |
294 door_stop = FALSE; | |
295 if (!after) | |
296 ntimes++; | |
297 } | |
298 /* | |
299 * Kick off the rest if the daemons and fuses | |
300 */ | |
301 if (after) | |
302 { | |
303 look(FALSE); | |
304 do_daemons(AFTER); | |
305 do_fuses(AFTER); | |
306 if (ISRING(LEFT, R_SEARCH)) | |
307 search(); | |
308 else if (ISRING(LEFT, R_TELEPORT) && rnd(100) < 2) | |
309 teleport(); | |
310 if (ISRING(RIGHT, R_SEARCH)) | |
311 search(); | |
312 else if (ISRING(RIGHT, R_TELEPORT) && rnd(100) < 2) | |
313 teleport(); | |
314 } | |
315 } | |
316 | |
317 /* | |
318 * quit: | |
319 * Have player make certain, then exit. | |
320 */ | |
321 | |
322 void | |
323 quit(int p) | |
324 { | |
325 /* | |
326 * Reset the signal in case we got here via an interrupt | |
327 */ | |
328 if (signal(SIGINT, quit) != &quit) | |
329 mpos = 0; | |
330 msg("Really quit?"); | |
331 draw(cw); | |
332 if (readchar(cw) == 'y') | |
333 { | |
334 clear(); | |
335 move(LINES-1, 0); | |
336 draw(stdscr); | |
337 endwin(); | |
338 score(purse, 1, 0); | |
339 exit(0); | |
340 } | |
341 else | |
342 { | |
343 signal(SIGINT, quit); | |
344 wmove(cw, 0, 0); | |
345 wclrtoeol(cw); | |
346 status(); | |
347 draw(cw); | |
348 mpos = 0; | |
349 count = 0; | |
350 } | |
351 } | |
352 | |
353 /* | |
354 * search: | |
355 * Player gropes about him to find hidden things. | |
356 */ | |
357 | |
358 void | |
359 search() | |
360 { | |
361 int x, y; | |
362 int ch; | |
363 | |
364 /* | |
365 * Look all around the hero, if there is something hidden there, | |
366 * give him a chance to find it. If its found, display it. | |
367 */ | |
368 if (on(player, ISBLIND)) | |
369 return; | |
370 for (x = hero.x - 1; x <= hero.x + 1; x++) | |
371 for (y = hero.y - 1; y <= hero.y + 1; y++) | |
372 { | |
373 ch = winat(y, x); | |
374 switch (ch) | |
375 { | |
376 case SECRETDOOR: | |
377 if (rnd(100) < 20) { | |
378 mvaddch(y, x, DOOR); | |
379 count = 0; | |
380 } | |
381 break; | |
382 case TRAP: | |
383 { | |
384 struct trap *tp; | |
385 | |
386 if (mvwinch(cw, y, x) == TRAP) | |