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