comparison urogue/command.c @ 256:c495a4f288c6

Import UltraRogue from the Roguelike Restoration Project (r1490)
author John "Elwin" Edwards
date Tue, 31 Jan 2017 19:56:04 -0500
parents
children 911f0aa6e758
comparison
equal deleted inserted replaced
253:d9badb9c0179 256:c495a4f288c6
1 /*
2 command.c - Read and execute the user commands
3
4 UltraRogue: The Ultimate Adventure in the Dungeons of Doom
5 Copyright (C) 1985, 1986, 1992, 1993, 1995 Herb Chong
6 All rights reserved.
7
8 Based on "Advanced Rogue"
9 Copyright (C) 1984, 1985 Michael Morgan, Ken Dalka
10 All rights reserved.
11
12 Based on "Rogue: Exploring the Dungeons of Doom"
13 Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman
14 All rights reserved.
15
16 See the file LICENSE.TXT for full copyright and licensing information.
17 */
18
19 #include <string.h>
20 #include <stdlib.h>
21 #include <ctype.h>
22 #include "rogue.h"
23
24 /*
25 command()
26 Process the user commands
27 */
28
29 void
30 command(void)
31 {
32 static char repcommand; /* Command to repeat if we are repeating */
33 static int fight_to_death; /* Flags if we are fighting to death */
34 static coord dir; /* Last direction specified */
35
36 object *obj;
37 char ch;
38 int ntimes = 1; /* Number of player moves */
39 coord nullcoord;
40
41 nullcoord.x = nullcoord.y = 0;
42
43 if (on(player, CANFLY) && rnd(2))
44 ntimes++;
45
46 if (on(player, ISHASTE))
47 ntimes++;
48
49 if (fighting && att_bonus())
50 ntimes *= 2;
51
52 if (on(player, ISSLOW))
53 {
54 if (player.t_turn != TRUE)
55 ntimes--;
56
57 player.t_turn ^= TRUE;
58 }
59
60 if (ntimes == 0)
61 return;
62
63 while (ntimes--)
64 {
65 moving = FALSE;
66
67 /* If player is infested, take off a hit point */
68
69 if (on(player, HASINFEST) && !is_wearing(R_HEALTH))
70 {
71 if ((pstats.s_hpt -= infest_dam) <= 0)
72 {
73 death(D_INFESTATION);
74 return;
75 }
76 }
77
78 look(after);
79
80 if (!running)
81 door_stop = FALSE;
82
83 status(FALSE);
84 wmove(cw, hero.y, hero.x);
85
86 if (!((running || count) && jump))
87 wrefresh(cw); /* Draw screen */
88
89 take = 0;
90 after = TRUE;
91
92 /*
93 * Read command or continue run
94 */
95
96 if (!no_command)
97 {
98 if (fighting)
99 {
100 ch = (fight_to_death) ? 'F' : 'f';
101 }
102 else if (running)
103 {
104 /*
105 * If in a corridor, if we are at a turn with
106 * only one way to go, turn that way.
107 */
108
109 if ((winat(hero.y, hero.x) == PASSAGE) && off(player, ISHUH) &&
110 (off(player, ISBLIND)))
111 switch (runch)
112 {
113 case 'h': corr_move(0, -1); break;
114 case 'j': corr_move(1, 0); break;
115 case 'k': corr_move(-1, 0); break;
116 case 'l': corr_move(0, 1); break;
117 }
118
119 ch = runch;
120 }
121 else if (count)
122 ch = repcommand;
123 else
124 {
125 ch = readchar();
126
127 if (mpos != 0 && !running)
128 msg(""); /* Erase message if its there */
129 }
130 }
131 else
132 {
133 ch = '.';
134 fighting = moving = FALSE;
135 }
136
137 if (no_command)
138 {
139 if (--no_command == 0)
140 msg("You can move again.");
141 }
142 else
143 {
144
145 /*
146 * check for prefixes
147 */
148
149 if (isdigit(ch))
150 {
151 count = 0;
152 while (isdigit(ch))
153 {
154 count = count * 10 + (ch - '0');
155 ch = readcharw(cw);
156 }
157 repcommand = ch;
158
159 /*
160 * Preserve count for commands which can be
161 * repeated.
162 */
163
164 switch(ch)
165 {
166 case 'h':
167 case 'j':
168 case 'k':
169 case 'l':
170 case 'y':
171 case 'u':
172 case 'b':
173 case 'n':
174 case 'H':
175 case 'J':
176 case 'K':
177 case 'L':
178 case 'Y':
179 case 'U':
180 case 'B':
181 case 'N':
182 case 'q':
183 case 'r':
184 case 's':
185 case 'm':
186 case 't':
187 case 'C':
188 case 'I':
189 case '.':
190 case 'z':
191 case 'p':
192 break;
193 default:
194 count = 0;
195 }
196 }
197
198 /* Save current direction */
199
200 if (!running) /* If running, it is already saved */
201 switch (ch)
202 {
203 case 'h':
204 case 'j':
205 case 'k':
206 case 'l':
207 case 'y':
208 case 'u':
209 case 'b':
210 case 'n':
211 runch = ch;
212 break;
213 case 'H':
214 case 'J':
215 case 'K':
216 case 'L':
217 case 'Y':
218 case 'U':
219 case 'B':
220 case 'N':
221 runch = (char) tolower(ch);
222 break;
223 }
224
225 /*
226 * execute a command
227 */
228
229 if (count && !running)
230 count--;
231
232 switch(ch)
233 {
234 /*
235 * Movement and combat commands
236 */
237
238 case 'h': do_move(0,-1); break;
239 case 'j': do_move(1, 0); break;
240 case 'k': do_move(-1, 0); break;
241 case 'l': do_move(0, 1); break;
242 case 'y': do_move(-1, -1); break;
243 case 'u': do_move(-1, 1); break;
244 case 'b': do_move(1, -1); break;
245 case 'n': do_move(1, 1); break;
246 case 'H': do_run('h'); break;
247 case 'J': do_run('j'); break;
248 case 'K': do_run('k'); break;
249 case 'L': do_run('l'); break;
250 case 'Y': do_run('y'); break;
251 case 'U': do_run('u'); break;
252 case 'B': do_run('b'); break;
253 case 'N': do_run('n'); break;
254 case 'm':
255 moving = TRUE;
256 if (!get_dir())
257 {
258 after = FALSE;
259 break;
260 }
261 do_move(delta.y, delta.x);
262 break;
263 case 'F':
264 case 'f':
265 fight_to_death = (ch == 'F');
266 if (!fighting)
267 {
268 if (get_dir())
269 {
270 dir = delta;
271 beast = NULL;
272 }
273 else
274 {
275 after = FALSE;
276 break;
277 }
278 }
279 do_fight(dir, (ch == 'F') ? TRUE : FALSE);
280 break;
281 case 't':
282 if (get_dir())
283 missile(delta.y, delta.x, get_item("throw", 0),
284 &player);
285 else
286 after = FALSE;
287
288 /*
289 * Informational commands - Do not do
290 * after daemons
291 */
292 break;
293
294 case 0x7f: /* sometime generated by */
295 /* suspend/foreground */
296 case ESCAPE:
297 case ' ':
298 after = FALSE; /* do nothing */
299 break;
300 case 'Q':
301 after = FALSE;
302 quit();
303 break;
304 case 'i':
305 after = FALSE;
306 inventory(pack, '*');
307 break;
308 case 'I':
309 after = FALSE;
310 inventory(pack, 0);
311 break;
312 case '~':
313 after = FALSE;
314 next_exp_level(MESSAGE);
315 break;
316 case '>':
317 after = FALSE;
318 d_level();
319 break;
320 case '<':
321 after = FALSE;
322 u_level();
323 break;
324 case '?':
325 after = FALSE;
326 help();
327 break;
328 case '/':
329 after = FALSE;
330 identify();
331 break;
332 case 'v':
333 after = FALSE;
334 msg("UltraRogue Version %s.", release);
335 break;
336 case 'o':
337 after = FALSE;
338 option();
339 strcpy(fd_data[1].mi_name, fruit);
340 break;
341 case 12: /* ctrl-l */
342 case 18: /* ctrl-r */
343 after = FALSE;
344 clearok(cw, TRUE);
345 wrefresh(cw);
346 break;
347 case 16: /* ctrl-p */
348 {
349 int decrement = FALSE;
350 after = FALSE;
351
352 if (mpos == 0)
353 decrement = TRUE;
354
355 msg_index = (msg_index + 9) % 10;
356 msg(msgbuf[msg_index]);
357 if (decrement)
358 msg_index = (msg_index + 9) % 10;
359 }
360 break;
361
362 case 'S':
363 after = FALSE;
364 if (save_game())
365 {
366 wclear(cw);
367 wrefresh(cw);
368 endwin();
369 exit(0);
370 }