Commit | Line | Data |
---|---|---|
187f436b KM |
1 | /* |
2 | * Copyright (c) 1980 Regents of the University of California. | |
4cd7a139 KB |
3 | * All rights reserved. |
4 | * | |
5 | * Redistribution and use in source and binary forms are permitted | |
b7647a4b KB |
6 | * provided that the above copyright notice and this paragraph are |
7 | * duplicated in all such forms and that any documentation, | |
8 | * advertising materials, and other materials related to such | |
9 | * distribution and use acknowledge that the software was developed | |
10 | * by the University of California, Berkeley. The name of the | |
11 | * University may not be used to endorse or promote products derived | |
12 | * from this software without specific prior written permission. | |
13 | * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR | |
14 | * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED | |
15 | * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. | |
187f436b KM |
16 | */ |
17 | ||
18 | #ifndef lint | |
b7647a4b | 19 | static char sccsid[] = "@(#)move.c 5.3 (Berkeley) %G%"; |
4cd7a139 | 20 | #endif /* not lint */ |
187f436b KM |
21 | |
22 | # include "robots.h" | |
23 | # include <ctype.h> | |
24 | ||
25 | # define ESC '\033' | |
26 | ||
27 | /* | |
28 | * get_move: | |
29 | * Get and execute a move from the player | |
30 | */ | |
31 | get_move() | |
32 | { | |
33 | register int c; | |
34 | register int y, x, lastmove; | |
35 | static COORD newpos; | |
36 | ||
37 | if (Waiting) | |
38 | return; | |
39 | ||
40 | #ifdef FANCY | |
41 | if (Pattern_roll) { | |
42 | if (Next_move >= Move_list) | |
43 | lastmove = *Next_move; | |
44 | else | |
45 | lastmove = -1; /* flag for "first time in" */ | |
46 | } | |
47 | #endif | |
48 | for (;;) { | |
49 | if (Teleport && must_telep()) | |
50 | goto teleport; | |
51 | if (Running) | |
52 | c = Run_ch; | |
53 | else if (Count != 0) | |
54 | c = Cnt_move; | |
55 | #ifdef FANCY | |
56 | else if (Num_robots > 1 && Stand_still) | |
57 | c = '>'; | |
58 | else if (Num_robots > 1 && Pattern_roll) { | |
59 | if (*++Next_move == '\0') { | |
60 | if (lastmove < 0) | |
61 | goto over; | |
62 | Next_move = Move_list; | |
63 | } | |
64 | c = *Next_move; | |
65 | mvaddch(0, 0, c); | |
66 | if (c == lastmove) | |
67 | goto over; | |
68 | } | |
69 | #endif | |
70 | else { | |
71 | over: | |
72 | c = getchar(); | |
73 | if (isdigit(c)) { | |
74 | Count = (c - '0'); | |
75 | while (isdigit(c = getchar())) | |
76 | Count = Count * 10 + (c - '0'); | |
77 | if (c == ESC) | |
78 | goto over; | |
79 | Cnt_move = c; | |
80 | if (Count) | |
81 | leaveok(stdscr, TRUE); | |
82 | } | |
83 | } | |
84 | ||
85 | switch (c) { | |
86 | case ' ': | |
87 | case '.': | |
88 | if (do_move(0, 0)) | |
89 | goto ret; | |
90 | break; | |
91 | case 'y': | |
92 | if (do_move(-1, -1)) | |
93 | goto ret; | |
94 | break; | |
95 | case 'k': | |
96 | if (do_move(-1, 0)) | |
97 | goto ret; | |
98 | break; | |
99 | case 'u': | |
100 | if (do_move(-1, 1)) | |
101 | goto ret; | |
102 | break; | |
103 | case 'h': | |
104 | if (do_move(0, -1)) | |
105 | goto ret; | |
106 | break; | |
107 | case 'l': | |
108 | if (do_move(0, 1)) | |
109 | goto ret; | |
110 | break; | |
111 | case 'b': | |
112 | if (do_move(1, -1)) | |
113 | goto ret; | |
114 | break; | |
115 | case 'j': | |
116 | if (do_move(1, 0)) | |
117 | goto ret; | |
118 | break; | |
119 | case 'n': | |
120 | if (do_move(1, 1)) | |
121 | goto ret; | |
122 | break; | |
123 | case 'Y': case 'U': case 'H': case 'J': | |
124 | case 'K': case 'L': case 'B': case 'N': | |
125 | case '>': | |
126 | Running = TRUE; | |
127 | if (c == '>') | |
128 | Run_ch = ' '; | |
129 | else | |
130 | Run_ch = tolower(c); | |
131 | leaveok(stdscr, TRUE); | |
132 | break; | |
133 | case 'q': | |
134 | case 'Q': | |
135 | if (query("Really quit?")) | |
136 | quit(); | |
137 | refresh(); | |
138 | break; | |
139 | case 'w': | |
140 | case 'W': | |
141 | Waiting = TRUE; | |
142 | leaveok(stdscr, TRUE); | |
143 | flushok(stdscr, FALSE); | |
144 | goto ret; | |
145 | case 't': | |
146 | case 'T': | |
147 | teleport: | |
148 | Running = FALSE; | |
149 | mvaddch(My_pos.y, My_pos.x, ' '); | |
150 | My_pos = *rnd_pos(); | |
151 | mvaddch(My_pos.y, My_pos.x, PLAYER); | |
152 | leaveok(stdscr, FALSE); | |
153 | refresh(); | |
154 | flush_in(); | |
155 | goto ret; | |
156 | case CTRL(L): | |
157 | wrefresh(curscr); | |
158 | break; | |
159 | case EOF: | |
160 | break; | |
161 | default: | |
162 | putchar(CTRL(G)); | |
163 | reset_count(); | |
164 | fflush(stdout); | |
165 | break; | |
166 | } | |
167 | } | |
168 | ret: | |
169 | if (Count > 0) | |
170 | if (--Count == 0) | |
171 | leaveok(stdscr, FALSE); | |
172 | } | |
173 | ||
174 | /* | |
175 | * must_telep: | |
176 | * Must I teleport; i.e., is there anywhere I can move without | |
177 | * being eaten? | |
178 | */ | |
179 | must_telep() | |
180 | { | |
181 | register int x, y; | |
182 | static COORD newpos; | |
183 | ||
184 | #ifdef FANCY | |
185 | if (Stand_still && Num_robots > 1 && eaten(&My_pos)) | |
186 | return TRUE; | |
187 | #endif | |
188 | ||
189 | for (y = -1; y <= 1; y++) { | |
190 | newpos.y = My_pos.y + y; | |
191 | if (newpos.y <= 0 || newpos.y >= Y_FIELDSIZE) | |
192 | continue; | |
193 | for (x = -1; x <= 1; x++) { | |
194 | newpos.x = My_pos.x + x; | |
195 | if (newpos.x <= 0 || newpos.x >= X_FIELDSIZE) | |
196 | continue; | |
197 | if (Field[newpos.y][newpos.x] > 0) | |
198 | continue; | |
199 | if (!eaten(&newpos)) | |
200 | return FALSE; | |
201 | } | |
202 | } | |
203 | return TRUE; | |
204 | } | |
205 | ||
206 | /* | |
207 | * do_move: | |
208 | * Execute a move | |
209 | */ | |
210 | do_move(dy, dx) | |
211 | int dy, dx; | |
212 | { | |
213 | static COORD newpos; | |
214 | ||
215 | newpos.y = My_pos.y + dy; | |
216 | newpos.x = My_pos.x + dx; | |
217 | if (newpos.y <= 0 || newpos.y >= Y_FIELDSIZE || | |
218 | newpos.x <= 0 || newpos.x >= X_FIELDSIZE || | |
219 | Field[newpos.y][newpos.x] > 0 || eaten(&newpos)) { | |
220 | if (Running) { | |
221 | Running = FALSE; | |
222 | leaveok(stdscr, FALSE); | |
223 | move(My_pos.y, My_pos.x); | |
224 | refresh(); | |
225 | } | |
226 | else { | |
227 | putchar(CTRL(G)); | |
228 | reset_count(); | |
229 | } | |
230 | return FALSE; | |
231 | } | |
232 | else if (dy == 0 && dx == 0) | |
233 | return TRUE; | |
234 | mvaddch(My_pos.y, My_pos.x, ' '); | |
235 | My_pos = newpos; | |
236 | mvaddch(My_pos.y, My_pos.x, PLAYER); | |
237 | if (!jumping()) | |
238 | refresh(); | |
239 | return TRUE; | |
240 | } | |
241 | ||
242 | /* | |
243 | * eaten: | |
244 | * Player would get eaten at this place | |
245 | */ | |
246 | eaten(pos) | |
247 | register COORD *pos; | |
248 | { | |
249 | register int x, y; | |
250 | ||
251 | for (y = pos->y - 1; y <= pos->y + 1; y++) { | |
252 | if (y <= 0 || y >= Y_FIELDSIZE) | |
253 | continue; | |
254 | for (x = pos->x - 1; x <= pos->x + 1; x++) { | |
255 | if (x <= 0 || x >= X_FIELDSIZE) | |
256 | continue; | |
257 | if (Field[y][x] == 1) | |
258 | return TRUE; | |
259 | } | |
260 | } | |
261 | return FALSE; | |
262 | } | |
263 | ||
264 | /* | |
265 | * reset_count: | |
266 | * Reset the count variables | |
267 | */ | |
268 | reset_count() | |
269 | { | |
270 | Count = 0; | |
271 | Running = FALSE; | |
272 | leaveok(stdscr, FALSE); | |
273 | refresh(); | |
274 | } | |
275 | ||
276 | /* | |
277 | * jumping: | |
278 | * See if we are jumping, i.e., we should not refresh. | |
279 | */ | |
280 | jumping() | |
281 | { | |
282 | return (Jump && (Count || Running || Waiting)); | |
283 | } |