move.c revision 1.1
1/*	$NetBSD: move.c,v 1.4 1995/04/22 10:08:58 cgd Exp $	*/
2
3/*
4 * Copyright (c) 1980, 1993
5 *	The Regents of the University of California.  All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 *    notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 *    notice, this list of conditions and the following disclaimer in the
14 *    documentation and/or other materials provided with the distribution.
15 * 3. All advertising materials mentioning features or use of this software
16 *    must display the following acknowledgement:
17 *	This product includes software developed by the University of
18 *	California, Berkeley and its contributors.
19 * 4. Neither the name of the University nor the names of its contributors
20 *    may be used to endorse or promote products derived from this software
21 *    without specific prior written permission.
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 * SUCH DAMAGE.
34 */
35
36#ifndef lint
37#if 0
38static char sccsid[] = "@(#)move.c	8.1 (Berkeley) 5/31/93";
39#else
40static char rcsid[] = "$NetBSD: move.c,v 1.4 1995/04/22 10:08:58 cgd Exp $";
41#endif
42#endif /* not lint */
43
44#include <sys/ttydefaults.h>
45#include <ctype.h>
46#include "robots.h"
47
48# define	ESC	'\033'
49
50/*
51 * get_move:
52 *	Get and execute a move from the player
53 */
54get_move()
55{
56	register int	c;
57	register int	y, x, lastmove;
58	static COORD	newpos;
59
60	if (Waiting)
61		return;
62
63#ifdef	FANCY
64	if (Pattern_roll) {
65		if (Next_move >= Move_list)
66			lastmove = *Next_move;
67		else
68			lastmove = -1;	/* flag for "first time in" */
69	}
70#endif
71	for (;;) {
72		if (Teleport && must_telep())
73			goto teleport;
74		if (Running)
75			c = Run_ch;
76		else if (Count != 0)
77			c = Cnt_move;
78#ifdef	FANCY
79		else if (Num_robots > 1 && Stand_still)
80			c = '>';
81		else if (Num_robots > 1 && Pattern_roll) {
82			if (*++Next_move == '\0') {
83				if (lastmove < 0)
84					goto over;
85				Next_move = Move_list;
86			}
87			c = *Next_move;
88			mvaddch(0, 0, c);
89			if (c == lastmove)
90				goto over;
91		}
92#endif
93		else {
94over:
95			c = getchar();
96			if (isdigit(c)) {
97				Count = (c - '0');
98				while (isdigit(c = getchar()))
99					Count = Count * 10 + (c - '0');
100				if (c == ESC)
101					goto over;
102				Cnt_move = c;
103				if (Count)
104					leaveok(stdscr, TRUE);
105			}
106		}
107
108		switch (c) {
109		  case ' ':
110		  case '.':
111			if (do_move(0, 0))
112				goto ret;
113			break;
114		  case 'y':
115			if (do_move(-1, -1))
116				goto ret;
117			break;
118		  case 'k':
119			if (do_move(-1, 0))
120				goto ret;
121			break;
122		  case 'u':
123			if (do_move(-1, 1))
124				goto ret;
125			break;
126		  case 'h':
127			if (do_move(0, -1))
128				goto ret;
129			break;
130		  case 'l':
131			if (do_move(0, 1))
132				goto ret;
133			break;
134		  case 'b':
135			if (do_move(1, -1))
136				goto ret;
137			break;
138		  case 'j':
139			if (do_move(1, 0))
140				goto ret;
141			break;
142		  case 'n':
143			if (do_move(1, 1))
144				goto ret;
145			break;
146		  case 'Y': case 'U': case 'H': case 'J':
147		  case 'K': case 'L': case 'B': case 'N':
148		  case '>':
149			Running = TRUE;
150			if (c == '>')
151				Run_ch = ' ';
152			else
153				Run_ch = tolower(c);
154			leaveok(stdscr, TRUE);
155			break;
156		  case 'q':
157		  case 'Q':
158			if (query("Really quit?"))
159				quit();
160			refresh();
161			break;
162		  case 'w':
163		  case 'W':
164			Waiting = TRUE;
165			leaveok(stdscr, TRUE);
166			flushok(stdscr, FALSE);
167			goto ret;
168		  case 't':
169		  case 'T':
170teleport:
171			Running = FALSE;
172			mvaddch(My_pos.y, My_pos.x, ' ');
173			My_pos = *rnd_pos();
174			mvaddch(My_pos.y, My_pos.x, PLAYER);
175			leaveok(stdscr, FALSE);
176			refresh();
177			flush_in();
178			goto ret;
179		  case CTRL('L'):
180			wrefresh(curscr);
181			break;
182		  case EOF:
183			break;
184		  default:
185			putchar(CTRL('G'));
186			reset_count();
187			fflush(stdout);
188			break;
189		}
190	}
191ret:
192	if (Count > 0)
193		if (--Count == 0)
194			leaveok(stdscr, FALSE);
195}
196
197/*
198 * must_telep:
199 *	Must I teleport; i.e., is there anywhere I can move without
200 * being eaten?
201 */
202must_telep()
203{
204	register int	x, y;
205	static COORD	newpos;
206
207#ifdef	FANCY
208	if (Stand_still && Num_robots > 1 && eaten(&My_pos))
209		return TRUE;
210#endif
211
212	for (y = -1; y <= 1; y++) {
213		newpos.y = My_pos.y + y;
214		if (newpos.y <= 0 || newpos.y >= Y_FIELDSIZE)
215			continue;
216		for (x = -1; x <= 1; x++) {
217			newpos.x = My_pos.x + x;
218			if (newpos.x <= 0 || newpos.x >= X_FIELDSIZE)
219				continue;
220			if (Field[newpos.y][newpos.x] > 0)
221				continue;
222			if (!eaten(&newpos))
223				return FALSE;
224		}
225	}
226	return TRUE;
227}
228
229/*
230 * do_move:
231 *	Execute a move
232 */
233do_move(dy, dx)
234int	dy, dx;
235{
236	static COORD	newpos;
237
238	newpos.y = My_pos.y + dy;
239	newpos.x = My_pos.x + dx;
240	if (newpos.y <= 0 || newpos.y >= Y_FIELDSIZE ||
241	    newpos.x <= 0 || newpos.x >= X_FIELDSIZE ||
242	    Field[newpos.y][newpos.x] > 0 || eaten(&newpos)) {
243		if (Running) {
244			Running = FALSE;
245			leaveok(stdscr, FALSE);
246			move(My_pos.y, My_pos.x);
247			refresh();
248		}
249		else {
250			putchar(CTRL('G'));
251			reset_count();
252		}
253		return FALSE;
254	}
255	else if (dy == 0 && dx == 0)
256		return TRUE;
257	mvaddch(My_pos.y, My_pos.x, ' ');
258	My_pos = newpos;
259	mvaddch(My_pos.y, My_pos.x, PLAYER);
260	if (!jumping())
261		refresh();
262	return TRUE;
263}
264
265/*
266 * eaten:
267 *	Player would get eaten at this place
268 */
269eaten(pos)
270register COORD	*pos;
271{
272	register int	x, y;
273
274	for (y = pos->y - 1; y <= pos->y + 1; y++) {
275		if (y <= 0 || y >= Y_FIELDSIZE)
276			continue;
277		for (x = pos->x - 1; x <= pos->x + 1; x++) {
278			if (x <= 0 || x >= X_FIELDSIZE)
279				continue;
280			if (Field[y][x] == 1)
281				return TRUE;
282		}
283	}
284	return FALSE;
285}
286
287/*
288 * reset_count:
289 *	Reset the count variables
290 */
291reset_count()
292{
293	Count = 0;
294	Running = FALSE;
295	leaveok(stdscr, FALSE);
296	refresh();
297}
298
299/*
300 * jumping:
301 *	See if we are jumping, i.e., we should not refresh.
302 */
303jumping()
304{
305	return (Jump && (Count || Running || Waiting));
306}
307