1 /*
2  * play.c
3  *
4  * This source herein may be modified and/or distributed by anybody who
5  * so desires, with the following restrictions:
6  *    1.)  No portion of this notice shall be removed.
7  *    2.)  Credit shall not be taken for the creation of this source.
8  *    3.)  This code is not to be traded, sold, or used for personal
9  *         gain or profit.
10  *
11  */
12 
13 #include <stdio.h>
14 #include "rogue.h"
15 
16 #define	CTRL(c)	((c) & 037)
17 
18 boolean interrupted = 0;
19 char *unknown_command = mesg[115];
20 
21 extern short party_room, bear_trap;
22 extern char hit_message[];
23 extern boolean wizard, trap_door;
24 
25 void
play_level()26 play_level()
27 {
28 	short ch, cmd, oldcmd;
29 	int count;
30 
31 	cmd = '.';
32 	for (;;) {
33 		interrupted = 0;
34 		if (hit_message[0]) {
35 			message(hit_message, 1);
36 			hit_message[0] = 0;
37 		}
38 		if (trap_door) {
39 			trap_door = 0;
40 			return;
41 		}
42 		move(rogue.row, rogue.col);
43 		refresh();
44 
45 		oldcmd = cmd;
46 		ch = cmd = rgetchar();
47 		check_message();
48 		count = 0;
49 CH:
50 		switch(ch) {
51 		case '.':
52 			rest((count > 0) ? count : 1);
53 			break;
54 		case 's':
55 			search(((count > 0) ? count : 1), 0);
56 			break;
57 		case 'i':
58 			inventory(&rogue.pack, ALL_OBJECTS);
59 			break;
60 		case 'f':
61 			fight(0);
62 			break;
63 		case 'F':
64 			fight(1);
65 			break;
66 		case 'h':
67 		case 'j':
68 		case 'k':
69 		case 'l':
70 		case 'y':
71 		case 'u':
72 		case 'n':
73 		case 'b':
74 			(void) one_move_rogue(ch, 1);
75 			break;
76 		case 'H':
77 		case 'J':
78 		case 'K':
79 		case 'L':
80 		case 'B':
81 		case 'Y':
82 		case 'U':
83 		case 'N':
84 		case CTRL('H'):
85 		case CTRL('J'):
86 		case CTRL('K'):
87 		case CTRL('L'):
88 		case CTRL('Y'):
89 		case CTRL('U'):
90 		case CTRL('N'):
91 		case CTRL('B'):
92 			multiple_move_rogue(ch);
93 			break;
94 		case 'e':
95 			eat();
96 			break;
97 		case 'q':
98 			quaff();
99 			break;
100 		case 'r':
101 			read_scroll();
102 			break;
103 		case 'm':
104 			move_onto();
105 			break;
106 		case 'd':
107 			drop();
108 			break;
109 		case 'P':
110 			put_on_ring();
111 			break;
112 		case 'R':
113 			remove_ring();
114 			break;
115 		case CTRL('P'):
116 			remessage();
117 			break;
118 		case CTRL('W'):
119 			wizardize();
120 			break;
121 		case '>':
122 			if (drop_check()) {
123 				return;
124 			}
125 			break;
126 		case '<':
127 			if (check_up()) {
128 				return;
129 			}
130 			break;
131 		case ')':
132 		case ']':
133 			inv_armor_weapon(ch == ')');
134 			break;
135 		case '=':
136 			inv_rings();
137 			break;
138 		case '^':
139 			id_trap();
140 			break;
141 		case 'I':
142 			single_inv(0);
143 			break;
144 		case 'T':
145 			take_off();
146 			break;
147 		case 'W':
148 			wear();
149 			break;
150 		case 'w':
151 			wield();
152 			break;
153 		case 'c':
154 			call_it();
155 			break;
156 		case 'z':
157 			zapp();
158 			break;
159 		case 't':
160 			throw();
161 			break;
162 		case 'v':
163 message("Rogue-clone: Version II. (Tim Stoehr was here), tektronix!zeus!tims ", 0);
164 #ifndef ORIGINAL
165 message("Japanese edition: Ver.1.3a (enhanced by ohta@src.ricoh.co.jp)", 0);
166 message("Ver.1.3aS program bug fix/separate (by brx@kmc.kyoto-u.ac.jp)", 0);	/* by Yasha */
167 message(mesg[1], 0);		/* for message version */
168 #endif
169 			break;
170 		case 'Q':
171 			quit(0);
172 		case '0':
173 		case '1':
174 		case '2':
175 		case '3':
176 		case '4':
177 		case '5':
178 		case '6':
179 		case '7':
180 		case '8':
181 		case '9':
182 			move(rogue.row, rogue.col);
183 			refresh();
184 			do {
185 				if (count < 100) {
186 					count = (10 * count) + (ch - '0');
187 				}
188 				ch = rgetchar();
189 			} while (is_digit(ch));
190 			if (ch != CANCEL) {
191 				goto CH;
192 			}
193 			break;
194 		case ' ':
195 			break;
196 		case CTRL('I'):
197 			if (wizard) {
198 				inventory(&level_objects, ALL_OBJECTS);
199 			} else {
200 				message(unknown_command, 0);
201 			}
202 			break;
203 		case CTRL('S'):
204 			if (wizard) {
205 				draw_magic_map();
206 			} else {
207 				message(unknown_command, 0);
208 			}
209 			break;
210 		case CTRL('T'):
211 			if (wizard) {
212 				show_traps();
213 			} else {
214 				message(unknown_command, 0);
215 			}
216 			break;
217 		case CTRL('O'):
218 			if (wizard) {
219 				show_objects();
220 			} else {
221 				message(unknown_command, 0);
222 			}
223 			break;
224 		case CTRL('A'):
225 			show_average_hp();
226 			break;
227 #ifndef ORIGINAL
228 		case CTRL('G'):
229 #endif
230 		case CTRL('C'):
231 			if (wizard) {
232 				new_object_for_wizard();
233 			} else {
234 				message(unknown_command, 0);
235 			}
236 			break;
237 		case CTRL('M'):
238 			if (wizard) {
239 				show_monsters();
240 			} else {
241 				message(unknown_command, 0);
242 			}
243 			break;
244 		case 'S':
245 			save_game();
246 			break;
247 		case ',':
248 			kick_into_pack();
249 			break;
250 #ifndef ORIGINAL
251 		case CTRL('X'):
252 			if (!wizard) {
253 				message(unknown_command, 0);
254 				break;
255 			}
256 			draw_magic_map();
257 			show_monsters();
258 			show_objects();
259 			show_traps();
260 			break;
261 		case '?':
262 			help();
263 			break;
264 		case '@':
265 			print_stats(STAT_ALL);
266 			break;
267 		case 'D':
268 			discovered();
269 			break;
270 		case '/':
271 			identify();
272 			break;
273 		case 'o':
274 			options();
275 			break;
276 		case '!':
277 			doshell();
278 			break;
279 		case 'a':
280 			ch = cmd = oldcmd;
281 			goto CH;
282 #endif /* ORIGINAL */
283 		default:
284 			message(unknown_command, 0);
285 			break;
286 		}
287 	}
288 }
289 
290 #ifndef ORIGINAL
291 char *help_message[] = {
292 mesg[116], mesg[117], mesg[118], mesg[119], mesg[120], mesg[121],
293 mesg[122], mesg[123], mesg[124], mesg[125], mesg[126], mesg[127],
294 mesg[128], mesg[129], mesg[130], mesg[131], mesg[132], mesg[133],
295 mesg[134], mesg[135], mesg[136], mesg[137],
296 "",
297 #ifdef JAPAN
298 "�᥹�ڡ��������Ƥ���������",
299 #else
300 "--Press space to continue--",
301 #endif
302 (char *) 0
303 };
304 
help()305 help()
306 {
307 	register int row, col;
308 	int n;
309 
310 	for (row = 0; row < DROWS; row++)
311 		for (col = 0; col < DCOLS; col++)
312 			descs[row][col] = mvinch(row, col);
313 	clear();
314 	for (n = 0; help_message[n]; n++) {
315 		mvaddstr(n, 0, help_message[n]);
316 		clrtoeol();
317 	}
318 	refresh();
319 	wait_for_ack();
320 
321 #if !defined(CURSES) && defined(JAPAN)	/* if.. by Yasha (for NeXT jcurses) */
322 	for (row = 0; row < DROWS - 1; row++) {	/* by Yasha */
323 #else
324 	for (row = 0; row < DROWS; row++) {
325 #ifdef JAPAN
326 		touch(row, 0, DCOLS-1);
327 #endif
328 #endif
329 		move(row, 0);
330 #if !defined(CURSES) && defined(JAPAN)
331 		clrtoeol();	/* by Yasha */
332 #endif
333 		for (col = 0; col < DCOLS; col++) {
334 			if (row == DROWS - 1 && col == DCOLS - 1)
335 				continue;
336 			if (row < MIN_ROW || row >= DROWS - 1)
337 				addch((unsigned char) descs[row][col]);
338 			else
339 				addch(colored(descs[row][col]));
340 		}
341 	}
342 #if !defined(CURSES) && defined(JAPAN)
343 	move(DROWS - 1, 0);	/* by Yasha */
344 	clrtoeol();		/* by Yasha */
345 	print_stats(STAT_ALL);	/* by Yasha */
346 #endif
347 	refresh();
348 }
349 
350 extern char *m_names[];
351 static char *o_names[] = {
352 	mesg[138], mesg[139], mesg[140], mesg[141], mesg[142], mesg[143],
353 	mesg[144], mesg[145], mesg[146], mesg[147], mesg[148], mesg[149],
354 	mesg[150], mesg[151], mesg[152], mesg[153], mesg[154]
355 };
356 
357 void
358 identify()
359 {
360 	short ch, n;
361 	char *p, buf[80];
362 
363 	message(mesg[155], 0);
364 
365 again:
366 	ch = rgetchar();
367 	if (ch == '\033') {
368 		check_message();
369 		return;
370 	} else if (ch >= 'a' && ch <= 'z' || ch >= 'A' && ch <= 'Z') {
371 		check_message();
372 		if (ch >= 'a' && ch <= 'z')
373 			ch += 'A' - 'a';
374 		p = m_names[ch - 'A'];
375 	} else if ((n = r_index("@.|-+#%^*:])?!/=,", ch, 0)) != -1) {
376 		check_message();
377 		p = o_names[n];
378 	} else {
379 		sound_bell();
380 		goto again;
381 	}
382 	sprintf(buf, "'%c': %s", ch, p);
383 	message(buf, 0);
384 }
385 
386 options()
387 {
388 	register int row, col;
389 	int n, i, j, changed;
390 	short ch;
391 	short pos[DROWS];
392 	boolean bbuf[DROWS];
393 	char cbuf[DROWS][MAX_TITLE_LENGTH];
394 	char optbuf[BUFSIZ];
395 
396 	for (row = 0; row < DROWS; row++)
397 		for (col = 0; col < DCOLS; col++)
398 			descs[row][col] = mvinch(row, col);
399 	clear();
400 	for (n = 0; envopt[n].name; n++) {
401 		mvaddstr(n, 0, optdesc[n]);
402 		addstr(" (\"");
403 		addstr(envopt[n].name);
404 		addstr("\"): ");
405 		if (envopt[n].bp) {
406 			bbuf[n] = *(envopt[n].bp);
407 			addstr(bbuf[n]? "Yes": "No");
408 		} else {
409 			strcpy(cbuf[n], *(envopt[n].cp));
410 			if (envopt[n].ab) {
411 				i = strlen(cbuf[n]);
412 				cbuf[n][i-1] = 0;
413 			}
414 			addstr(cbuf[n]);
415 		}
416 		pos[n] = strlen(optdesc[n]) + strlen(envopt[n].name) + 7;
417 	}
418 
419 	i = 0;
420 	while (i >= 0 && i < n) {
421 		if (envopt[i].bp)
422 			move(i, pos[i]);
423 		else
424 			move(i, pos[i]+strlen(cbuf[i]));
425 		refresh();
426 		ch = rgetchar();
427 		if (ch == CANCEL)
428 			break;
429 		if (r_index("-\r\n", ch, 0) > -1) {
430 			if (envopt[i].bp) {
431 				addstr(bbuf[i]? "Yes": "No");
432 				clrtoeol();
433 			}
434 			if (ch == '-')
435 				i--;
436 			else
437 				i++;
438 			continue;
439 		}
440 		if (envopt[i].bp) {
441 			if (ch >= 'A' && ch <= 'Z')
442 				ch += 'a'- 'Z';
443 			if (ch != 'y' && ch != 'n') {
444 				mvaddstr(i, pos[i], "(Yes or No)");
445 				continue;
446 			}
447 			addstr((ch == 'y')? "Yes": "No");
448 			clrtoeol();
449 			bbuf[i] = (ch == 'y');
450 			i++;
451 		} else {
452 			j = input_line(i, pos[i], cbuf[i], optbuf, ch);
453 			if (j < 0)
454 				break;
455 			strcpy(cbuf[i], optbuf);
456 			i++;
457 		}
458 	}
459 	changed = (i < 0 || i >= n);
460 	if (changed) {
461 		move(n+1, 0);
462 #ifdef JAPAN
463 		addstr("�᥹�ڡ��������Ƥ���������");
464 #else
465 		addstr("--Press space to continue--");
466 #endif
467 		refresh();
468 		wait_for_ack();
469 	}
470 #if defined(CURSES) || !defined(JAPAN)	/* #if.. by Yasha */
471 #ifdef JAPAN
472 	for (row = 0; row < n; row++)
473 		touch(row, 0, DCOLS-1);
474 #endif
475 	for (row = 0; row < DROWS; row++) {
476 #else
477 	for (row = 0; row < DROWS - 1; row++) {	/* by Yasha */
478 #endif
479 		move(row, 0);
480 #if !defined(CURSES) && defined(JAPAN)
481 		clrtoeol();			/* by Yasha */
482 #endif
483 		for (col = 0; col < DCOLS; col++) {
484 			if (row == DROWS - 1 && col == DCOLS - 1)
485 				continue;
486 			if (row < MIN_ROW || row >= DROWS - 1)
487 				addch((unsigned char) descs[row][col]);
488 			else
489 				addch(colored(descs[row][col]));
490 		}
491 	}
492 #if !defined(CURSES) && defined(JAPAN)
493 	move(DROWS - 1, 0);	/* by Yasha */
494 	clrtoeol();		/* by Yasha */
495 	print_stats(STAT_ALL);	/* by Yasha */
496 #endif
497 
498 	if (changed) {
499 		optbuf[0] = 0;
500 		for (i = 0; i < n; i++) {
501 			strcat(optbuf, ",");
502 			if (envopt[i].bp) {
503 				if (!bbuf[i])
504 					strcat(optbuf, "no");
505 				strcat(optbuf, envopt[i].name);
506 			} else {
507 				strcat(optbuf, envopt[i].name);
508 				strcat(optbuf, ":");
509 				strcat(optbuf, cbuf[i]);
510 			}
511 		}
512 		set_opts(optbuf);
513 	}
514 	refresh();
515 }
516 
517 #ifdef MSDOS
518 #ifndef LC4
519 #include <process.h>
520 #endif
521 #endif
522 
523 doshell()
524 {
525 	char *cmd, *md_getenv();
526 
527 #if defined(MSDOS) && !defined(HUMAN)		/* by Yasha */
528 /*#ifdef MSDOS*/
529 	if ((cmd = md_getenv("COMSPEC")) == NULL) {
530 #ifdef JAPAN
531 		message("�Ķ��ѿ� COMSPEC �����åȤ���Ƥ��ޤ���", 0);
532 #else
533 		message("Sorry, no COMSPEC...", 0);
534 #endif
535 		return;
536 	}
537 #endif /*MSDOS*/
538 #ifdef UNIX
539 	if ((cmd = md_getenv("SHELL")) == NULL)
540 		cmd = "/bin/sh";
541 #endif /*UNIX*/
542 	move(DROWS-1, 0);
543 	refresh();
544 	stop_window();
545 	if (*org_dir)
546 		md_chdir(org_dir);
547 #ifdef MSDOS
548 	putstr("\r\n\r\n");
549 	putstr(mesg[156]);
550 	putstr("\r\n");
551 #ifdef HUMAN			/* by Yasha */
552 	system("");		/* by Yasha */
553 /*#ifdef LC4*/
554 #elif defined(LC4)		/* by Yasha */
555 	forkl(cmd, cmd, NULL);
556 #else
557 	spawnl(P_WAIT, cmd, cmd, NULL);
558 #endif
559 #endif /*MSDOS*/
560 #ifdef UNIX
561 	md_ignore_signals();
562 #if defined(JAPAN) && !defined(CURSES)
563 	raw();				/* by Yasha */
564 #endif
565 	putstr(mesg[157]);
566 	putstr("\r\n");
567 	system(cmd);
568 	md_heed_signals();
569 #endif /*UNIX*/
570 	if (game_dir && *game_dir)
571 		md_chdir(game_dir);
572 	start_window();
573 	wrefresh(curscr);
574 }
575 
576 #endif /* ORIGINAL */
577