diff srogue/command.c @ 36:2128c7dc8a40

Import Super-Rogue 9.0 from the Roguelike Restoration Project (r1490)
author elwin
date Thu, 25 Nov 2010 12:21:41 +0000
parents
children 5ea4a4d8f961
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/srogue/command.c	Thu Nov 25 12:21:41 2010 +0000
@@ -0,0 +1,714 @@
+/*
+ * Read and execute the user commands
+ *
+ * @(#)command.c	9.0	(rdk)	 7/17/84
+ *
+ * Super-Rogue
+ * Copyright (C) 1984 Robert D. Kindelberger
+ * All rights reserved.
+ *
+ * Based on "Rogue: Exploring the Dungeons of Doom"
+ * Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman
+ * All rights reserved.
+ *
+ * See the file LICENSE.TXT for full copyright and licensing information.
+ */
+
+#include <ctype.h>
+#include <signal.h>
+#include <limits.h>
+#include "rogue.h"
+#include "rogue.ext"
+#ifdef __DJGPP__
+#include <process.h>
+#endif
+
+/*
+ * command:
+ *	Process the user commands
+ */
+command()
+{
+	reg char ch;
+	reg int ntimes = 1;		/* Number of player moves */
+	static char countch, direction, newcount = FALSE;
+
+	if (pl_on(ISHASTE))
+		ntimes++;
+	/*
+	 * Let the daemons start up
+	 */
+	while (ntimes-- > 0) {
+		do_daemons(BEFORE);
+		look(TRUE);
+		if (!running)
+			door_stop = FALSE;
+		lastscore = purse;
+		wmove(cw, hero.y, hero.x);
+		if (!(running || count))
+			draw(cw);			/* Draw screen */
+		take = 0;
+		after = TRUE;
+		/*
+		 * Read command or continue run
+		 */
+		if (wizard)
+			waswizard = TRUE;
+		if (player.t_nocmd <= 0) {
+			player.t_nocmd = 0;
+			if (running)
+				ch = runch;
+			else if (count)
+				ch = countch;
+			else {
+				ch = readchar();
+				if (mpos != 0 && !running) /* Erase message if its there */
+					msg("");
+			}
+		}
+		else
+			ch = '.';
+		if (player.t_nocmd > 0) {
+			if (--player.t_nocmd <= 0)
+				msg("You can move again.");	
+		}
+		else {
+			/*
+			 * check for prefixes
+			 */
+			if (isdigit(ch)) {
+				count = 0;
+				newcount = TRUE;
+				while (isdigit(ch)) {
+					count = count * 10 + (ch - '0');
+					ch = readchar();
+				}
+				countch = ch;
+				/*
+				 * turn off count for commands which don't make sense
+				 * to repeat
+				 */
+				switch (ch) {
+					case 'h': case 'j': case 'k': case 'l':
+					case 'y': case 'u': case 'b': case 'n':
+					case 'H': case 'J': case 'K': case 'L':
+					case 'Y': case 'U': case 'B': case 'N':
+					case 'q': case 'r': case 's': case 'f':
+					case 't': case 'C': case 'I': case '.':
+					case 'z': case 'p':
+						break;
+					default:
+						count = 0;
+				}
+			}
+			switch (ch) {
+			case 'f':
+			case 'g':
+				if (pl_off(ISBLIND)) {
+					door_stop = TRUE;
+					firstmove = TRUE;
+				}
+				if (count && !newcount)
+					ch = direction;
+				else
+					ch = readchar();
+				switch (ch) {
+					case 'h': case 'j': case 'k': case 'l':
+					case 'y': case 'u': case 'b': case 'n':
+						ch = toupper(ch);
+				}
+				direction = ch;
+			}
+			newcount = FALSE;
+			/*
+			 * execute a command
+			 */
+			if (count && !running)
+				count--;
+			switch (ch) {
+				case '!' : shell(); after = FALSE;
+				when 'h' : do_move(0, -1);
+				when 'j' : do_move(1, 0);
+				when 'k' : do_move(-1, 0);
+				when 'l' : do_move(0, 1);
+				when 'y' : do_move(-1, -1);
+				when 'u' : do_move(-1, 1);
+				when 'b' : do_move(1, -1);
+				when 'n' : do_move(1, 1);
+				when 'H' : do_run('h');
+				when 'J' : do_run('j');
+				when 'K' : do_run('k');
+				when 'L' : do_run('l');
+				when 'Y' : do_run('y');
+				when 'U' : do_run('u');
+				when 'B' : do_run('b');
+				when 'N' : do_run('n');
+				when 't':
+					if (!get_dir())
+						after = FALSE;
+					else
+						missile(delta.y, delta.x);
+				when 'Q' : after = FALSE; quit(-1);
+				when 'i' : after = FALSE; inventory(pack, 0);
+				when 'I' : after = FALSE; picky_inven();
+				when 'd' : drop(NULL);
+				when 'q' : quaff();
+				when 'r' : read_scroll();
+				when 'e' : eat();
+				when 'w' : wield();
+				when 'W' : wear();
+				when 'T' : take_off();
+				when 'P' : ring_on();
+				when 'R' : ring_off();
+				when 'O' : option();
+				when 'c' : call();
+				when '>' : after = FALSE; d_level();
+				when '<' : after = FALSE; u_level();
+				when '?' : after = FALSE; help();
+				when '/' : after = FALSE; identify(0);
+				when 's' : search();
+				when 'z' : do_zap(FALSE);
+				when 'p':
+					if (get_dir())
+						do_zap(TRUE);
+					else
+						after = FALSE;
+				when 'v': msg("Super Rogue version %s.",release);
+				when 'D': dip_it();
+				when CTRL('L') : after = FALSE; restscr(cw);
+				when CTRL('R') : after = FALSE; msg(huh);
+				when 'a': after = FALSE; dispmax();
+				when '@' : if (author())
+					msg("Hero @ %d,%d : Stairs @ %d,%d",hero.y,hero.x,stairs.y,stairs.x);
+				when 'S' : 
+					after = FALSE;
+					if (save_game()) {
+						wclear(cw);
+						draw(cw);
+						endwin();
+						byebye(0);
+					}
+				when '.' : ;				/* Rest command */
+				when ' ' : after = FALSE;	/* do nothing */
+				when '=' :
+					if (author()) {
+						activity();
+						after = FALSE;
+					}
+				when CTRL('P') :
+					after = FALSE;
+					if (wizard) {
+						wizard = FALSE;
+						msg("Not wizard any more");
+					}
+					else {
+						wizard = passwd();
+						if (wizard) {
+							msg("Welcome back, Bob!!!!!");
+							waswizard = TRUE;
+						}
+						else
+							msg("Sorry");
+					}
+				when ESCAPE :	/* Escape */
+					door_stop = FALSE;
+					count = 0;
+					after = FALSE;
+				when '#':
+					if (levtype == POSTLEV)		/* buy something */
+						buy_it();
+					after = FALSE;
+				when '$':
+					if (levtype == POSTLEV)		/* price something */
+						price_it();
+					after = FALSE;
+				when '%':
+					if (levtype == POSTLEV)		/* sell something */
+						sell_it();
+					after = FALSE;
+				otherwise :
+					after = FALSE;
+					if (wizard) switch (ch) {
+					case CTRL('A') : ;
+					when 'C'     :	create_obj(FALSE);
+					when CTRL('I') :	inventory(lvl_obj, 1);
+					when CTRL('W') :	whatis(NULL);
+					when CTRL('D') :	level++; new_level(NORMLEV);
+					when CTRL('U') :	if (level > 1) level--; new_level(NORMLEV);
+					when CTRL('F') :	displevl();
+					when CTRL('X') :	dispmons();
+					when CTRL('T') :	teleport(rndspot,&player);
+					when CTRL('E') :	msg("food left: %d", food_left);
+					when CTRL('O') :	add_pass();
+					when 'M' : {
+						int tlev, whichlev;
+						prbuf[0] = '\0';
+						msg("Which level? ");
+						if (get_str(prbuf,cw) == NORM) {
+							whichlev = NORMLEV;
+							tlev = atoi(prbuf);
+							if (tlev < 1)
+								level = 1;
+							if (tlev >= 200) {
+								tlev -= 199;
+								whichlev = MAZELEV;
+							}
+							else if (tlev >= 100) {
+								tlev -= 99;
+								whichlev = POSTLEV;
+							}
+							level = tlev;
+							new_level(whichlev);
+						}
+					}
+					when CTRL('N') : {
+						struct linked_list *item;
+
+						item = get_item("charge", STICK);
+						if (item != NULL) {
+							(OBJPTR(item))->o_charges = 10000;
+							msg("");
+						}
+					}
+					when CTRL('H') : {
+						int i;
+						struct linked_list *item;
+						struct object *obj;
+
+						him->s_exp = e_levels[him->s_lvl + 7] + 1;
+						check_level();
+						/*
+						 * Give the rogue a very good sword
+						 */
+						item = new_thing(FALSE, WEAPON, TWOSWORD);
+						obj = OBJPTR(item);
+						obj->o_hplus = 3;
+						obj->o_dplus = 3;
+						obj->o_flags = ISKNOW;
+						i = add_pack(item, TRUE);
+						if (i)
+							cur_weapon = obj;
+						else
+							discard(item);
+						/*
+						 * And his suit of armor
+						 */
+						item = new_thing(FALSE, ARMOR, PLATEARMOR);
+						obj = OBJPTR(item);
+						obj->o_ac = -8;
+						obj->o_flags = ISKNOW;
+						i = add_pack(item, TRUE);
+						if (i)
+							cur_armor = obj;
+						else
+							discard(item);
+						nochange = FALSE;
+					}
+					otherwise:
+						msg(illegal, unctrl(ch));
+						count = 0;
+				}
+				else {
+					msg(illegal, unctrl(ch));
+					count = 0;
+				}
+			}
+			/*
+			 * turn off flags if no longer needed
+			 */
+			if (!running)
+				door_stop = FALSE;
+		}
+		/*
+		 * If he ran into something to take, let the
+		 * hero pick it up if not in a trading post.
+		 */
+		if (take != 0 && levtype != POSTLEV)
+			pick_up(take);
+		if (!running)
+			door_stop = FALSE;
+	}
+	/*
+	 * Kick off the rest if the daemons and fuses
+	 */
+	if (after) {
+		int  j;
+
+		look(FALSE);
+		do_daemons(AFTER);
+		do_fuses();
+		if (pl_on(ISSLOW))
+			waste_time();
+		for (j = LEFT; j <= RIGHT; j++) {
+			if (cur_ring[j] != NULL) {
+				if (cur_ring[j]->o_which == R_SEARCH)
+					search();
+				else if (cur_ring[j]->o_which == R_TELEPORT)
+					if (rnd(100) < 5)
+						teleport(rndspot, &player);
+	 		}
+		}
+	}
+}
+
+
+/*
+ * quit:
+ *	Have player make certain, then exit.
+ */
+void
+quit(int a)
+{
+	reg char ch, good;
+	/*
+	 * Reset the signal in case we got here via an interrupt
+	 */
+	if (signal(SIGINT, quit) != quit)
+		mpos = 0;
+	msg("Really quit? [y/n/s]");
+/*	ch = tolower(readchar());*/
+	ch = readchar();