Mercurial > hg > early-roguelike
comparison xrogue/command.c @ 133:e6179860cb76
Import XRogue 8.0 from the Roguelike Restoration Project (r1490)
author | John "Elwin" Edwards |
---|---|
date | Tue, 21 Apr 2015 08:55:20 -0400 |
parents | |
children | ce0cf824c192 |
comparison
equal
deleted
inserted
replaced
124:d10fc4a065ac | 133:e6179860cb76 |
---|---|
1 /* | |
2 command.c - Read and execute the user commands | |
3 | |
4 XRogue: Expeditions into the Dungeons of Doom | |
5 Copyright (C) 1991 Robert Pietkivitch | |
6 All rights reserved. | |
7 | |
8 Based on "Advanced Rogue" | |
9 Copyright (C) 1984, 1985 Michael Morgan, Ken Dalka and AT&T | |
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 <curses.h> | |
20 #include <ctype.h> | |
21 #include <signal.h> | |
22 #include "mach_dep.h" | |
23 #include "rogue.h" | |
24 | |
25 /* | |
26 * command: | |
27 * Process the user commands | |
28 */ | |
29 | |
30 command() | |
31 { | |
32 unsigned int ch; | |
33 struct linked_list *item; | |
34 unsigned int countch = 0, direction = 0, newcount = FALSE; | |
35 int segment = 1; | |
36 int monst_limit, monst_current; | |
37 | |
38 monst_limit = monst_current = 1; | |
39 while (playing) { | |
40 /* | |
41 * Let the daemons start up, but only do them once a round | |
42 * (round = 10 segments). | |
43 */ | |
44 if (segment >= 10) { | |
45 do_daemons(BEFORE); | |
46 do_fuses(BEFORE); | |
47 } | |
48 | |
49 after = TRUE; | |
50 do { | |
51 /* One more tick of the clock. */ | |
52 if (segment >= 10 && after && (++turns % DAYLENGTH) == 0) { | |
53 daytime ^= TRUE; | |
54 if (levtype == OUTSIDE) { | |
55 if (daytime) msg("A bright star flares above the horizon."); | |
56 else msg("The bright star travels beyond the horizon."); | |
57 } | |
58 light(&hero); | |
59 } | |
60 | |
61 /* | |
62 * Don't bother with these updates unless the player's going | |
63 * to do something. | |
64 */ | |
65 if (player.t_action == A_NIL && player.t_no_move <= 1) { | |
66 look(after, FALSE); | |
67 lastscore = purse; | |
68 wmove(cw, hero.y, hero.x); | |
69 if (!((running || count) && jump)) { | |
70 status(FALSE); | |
71 } | |
72 } | |
73 | |
74 /* Draw the screen */ | |
75 if (!((running || count) && jump)) { | |
76 wmove(cw, hero.y, hero.x); | |
77 draw(cw); | |
78 } | |
79 | |
80 after = TRUE; | |
81 | |
82 /* | |
83 * Read command or continue run | |
84 */ | |
85 if (--player.t_no_move <= 0) { | |
86 take = 0; /* Nothing here to start with */ | |
87 player.t_no_move = 0; /* Be sure we don't go too negative */ | |
88 if (!running) door_stop = FALSE; | |
89 | |
90 /* Was the player being held? */ | |
91 if (player.t_action == A_FREEZE) { | |
92 player.t_action = A_NIL; | |
93 msg("You can move again."); | |
94 } | |
95 | |
96 if (player.t_action != A_NIL) ch = player.t_action; | |
97 else if (running) { | |
98 char scratch; | |
99 | |
100 /* If in a corridor or maze, if we are at a turn with | |
101 * only one way to go, turn that way. | |
102 */ | |
103 scratch = winat(hero.y, hero.x); | |
104 if ((scratch==PASSAGE||scratch==DOOR||levtype==MAZELEV) && | |
105 off(player, ISHUH) && | |
106 off(player, ISBLIND)) { | |
107 int y, x; | |
108 if (getdelta(runch, &y, &x) == TRUE) { | |
109 corr_move(y, x); | |
110 } | |
111 } | |
112 ch = runch; | |
113 } | |
114 else if (count) ch = countch; | |
115 else { | |
116 ch = wgetch(cw); | |
117 if (mpos != 0 && !running) /* Erase message if its there */ | |
118 msg(""); | |
119 } | |
120 | |
121 /* | |
122 * check for prefixes | |
123 */ | |
124 if (isascii(ch) && isdigit(ch)) | |
125 { | |
126 count = 0; | |
127 newcount = TRUE; | |
128 while (isascii(ch) && isdigit(ch)) | |
129 { | |
130 count = count * 10 + (ch - '0'); | |
131 ch = wgetch(cw); | |
132 } | |
133 countch = ch; | |
134 /* | |
135 * turn off count for commands which don't make sense | |
136 * to repeat | |
137 */ | |
138 switch (ch) { | |
139 case 'h': case 'j': case 'k': case 'l': | |
140 case 'y': case 'u': case 'b': case 'n': | |
141 case 'H': case 'J': case 'K': case 'L': | |
142 case 'Y': case 'U': case 'B': case 'N': | |
143 case C_SEARCH: case '.': | |
144 break; | |
145 default: | |
146 count = 0; | |
147 } | |
148 } | |
149 | |
150 /* Save current direction */ | |
151 if (!running) { /* If running, it is already saved */ | |
152 switch (ch) { | |
153 case 'h': case 'j': case 'k': case 'l': | |
154 case 'y': case 'u': case 'b': case 'n': | |
155 case 'H': case 'J': case 'K': case 'L': | |
156 case 'Y': case 'U': case 'B': case 'N': | |
157 runch = tolower(ch); | |
158 } | |
159 } | |
160 | |
161 /* Perform the action */ | |
162 switch (ch) { | |
163 case 'f': | |
164 if (!on(player, ISBLIND)) | |
165 { | |
166 door_stop = TRUE; | |
167 firstmove = TRUE; | |
168 } | |
169 if (count && !newcount) | |
170 ch = direction; | |
171 else | |
172 ch = wgetch(cw); | |
173 switch (ch) | |
174 { | |
175 case 'h': case 'j': case 'k': case 'l': | |
176 case 'y': case 'u': case 'b': case 'n': | |
177 ch = toupper(ch); | |
178 } | |
179 direction = ch; | |
180 } | |
181 newcount = FALSE; | |
182 | |
183 /* | |
184 * execute a command | |
185 */ | |
186 if (count && !running) | |
187 count--; | |
188 | |
189 switch (ch) { | |
190 case '!' : shell(); | |
191 case KEY_LEFT : do_move(0, -1); | |
192 when KEY_DOWN : do_move(1, 0); | |
193 when KEY_UP : do_move(-1, 0); | |
194 when KEY_RIGHT : do_move(0, 1); | |
195 when KEY_HOME : do_move(-1, -1); | |
196 when KEY_A1 : do_move(-1, -1); | |
197 when KEY_PPAGE : do_move(-1, 1); | |
198 when KEY_A3 : do_move(-1, 1); | |
199 when KEY_END : do_move(1, -1); | |
200 when KEY_C1 : do_move(1, -1); | |
201 when KEY_NPAGE : do_move(1, 1); | |
202 when KEY_C3 : do_move(1, 1); | |
203 #ifdef CTL_RIGHT | |
204 when CTL_RIGHT : do_run('l'); | |
205 when CTL_LEFT : do_run('h'); | |
206 when CTL_UP : do_run('k'); | |
207 when CTL_DOWN : do_run('j'); | |
208 when CTL_HOME : do_run('y'); | |
209 when CTL_PGUP : do_run('u'); | |
210 when CTL_END : do_run('b'); | |
211 when CTL_PGDN : do_run('n'); | |
212 #endif | |
213 when 'h' : do_move(0, -1); | |
214 when 'j' : do_move(1, 0); | |
215 when 'k' : do_move(-1, 0); | |
216 when 'l' : do_move(0, 1); | |
217 when 'y' : do_move(-1, -1); | |
218 when 'u' : do_move(-1, 1); | |
219 when 'b' : do_move(1, -1); | |
220 when 'n' : do_move(1, 1); | |
221 when 'H' : do_run('h'); | |
222 when 'J' : do_run('j'); | |
223 when 'K' : do_run('k'); | |
224 when 'L' : do_run('l'); | |
225 when 'Y' : do_run('y'); | |
226 when 'U' : do_run('u'); | |
227 when 'B' : do_run('b'); | |
228 when 'N' : do_run('n'); | |
229 when A_ATTACK: | |
230 /* Is our attackee still there? */ | |
231 if (isalpha(winat(player.t_newpos.y, | |
232 player.t_newpos.x))) { | |
233 /* Our friend is still here */ | |
234 player.t_action = A_NIL; | |
235 fight(&player.t_newpos, cur_weapon, FALSE); | |
236 } | |
237 else { /* Our monster has moved */ | |
238 player.t_action = A_NIL; | |
239 } | |
240 when A_PICKUP: | |
241 player.t_action = A_NIL; | |
242 if (add_pack((struct linked_list *)NULL, FALSE)) { | |
243 char tch; | |
244 tch = mvwinch(stdscr, hero.y, hero.x); | |
245 if (tch != FLOOR && tch != PASSAGE) { | |
246 player.t_action = A_PICKUP; /*get more */ | |
247 player.t_no_move += 2 * movement(&player); | |
248 } | |
249 } | |
250 when A_THROW: | |
251 if (player.t_action == A_NIL) { | |
252 item = get_item(pack, "throw", ALL, FALSE, FALSE); | |
253 if (item != NULL && get_dir(&player.t_newpos)) { | |
254 player.t_action = A_THROW; | |
255 player.t_using = item; | |
256 player.t_no_move = 2 * movement(&player); | |
257 } | |
258 else | |
259 after = FALSE; | |
260 } | |
261 else { | |
262 missile(player.t_newpos.y, player.t_newpos.x, | |
263 player.t_using, &player); | |
264 player.t_action = A_NIL; | |
265 player.t_using = 0; | |
266 } | |
267 when 'a' : | |
268 if (player.t_action == A_NIL) { | |
269 if (get_dir(&player.t_newpos)) { | |
270 player.t_action = 'a'; | |
271 player.t_no_move = 1 + movement(&player); | |
272 } | |
273 else | |
274 after = FALSE; | |
275 } | |
276 else { | |
277 affect(); | |
278 player.t_action = A_NIL; | |
279 } | |
280 when 'A' : choose_qst(); | |
281 when 'F' : /* frighten a monster */ | |
282 if (player.t_action == A_NIL) { | |
283 player.t_action = 'F'; | |
284 player.t_no_move = 2*movement(&player); | |
285 } | |
286 else { | |
287 after = FALSE; | |
288 player.t_action = A_NIL; | |
289 fright(); | |
290 } | |
291 when 'g' : /* Give command: give slime-molds to monsters */ | |
292 if (player.t_action == A_NIL) { | |
293 player.t_action = 'g'; | |
294 player.t_no_move = 2*movement(&player); | |
295 } | |
296 else { | |
297 after = FALSE; | |
298 player.t_action = A_NIL; | |
299 give(); | |
300 } | |
301 when 'G' : | |
302 if (player.t_action == A_NIL) { | |
303 player.t_action = 'G'; | |
304 player.t_no_move = movement(&player); | |
305 } | |
306 else { | |
307 player.t_action = A_NIL; | |
308 gsense(); | |
309 } | |
310 when 'i' : after = FALSE; inventory(pack, ALL); | |
311 when 'I' : after = FALSE; picky_inven(); | |
312 when 'm' : nameitem((struct linked_list *)NULL, TRUE); | |
313 when 'o' : option(); | |
314 when 'O' : msg("Charactor type: %s Quest item: %s", char_class[char_type].name, rel_magic[quest_item].mi_name); | |
315 when ',' : | |
316 case 'P' : | |
317 if (levtype != POSTLEV) { | |
318 /* We charge 2 movement units per item */ | |
319 player.t_no_move = | |
320 2 * grab(hero.y, hero.x) * movement(&player); | |
321 } | |
322 else { | |
323 /* Let's quote the wise guy a price */ | |
324 buy_it(); | |
325 after = FALSE; | |
326 } | |
327 when 'Q' : after = FALSE; quit(0); | |
328 when 'S' : | |
329 after = FALSE; | |
330 if (save_game()) | |
331 exit_game(EXIT_CLS | EXIT_ENDWIN); | |
332 when 'v' : after = FALSE; | |
333 msg("Advanced xrogue, Version %s ", release); | |
334 when 'X' : /* trap sense */ | |
335 after = FALSE; | |
336 if (player.t_action == A_NIL) { | |
337 player.t_action = 'X'; | |
338 player.t_no_move = movement(&player); | |
339 } | |
340 else { | |
341 xsense(); | |
342 player.t_action = A_NIL; | |
343 } | |
344 when '.' : | |