diff rogue5/command.c @ 33:f502bf60e6e4

Import Rogue 5.4 from the Roguelike Restoration Project (r1490)
author elwin
date Mon, 24 May 2010 20:10:59 +0000
parents
children f871cb0539d3
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/rogue5/command.c	Mon May 24 20:10:59 2010 +0000
@@ -0,0 +1,827 @@
+/*
+ * Read and execute the user commands
+ *
+ * @(#)command.c	4.73 (Berkeley) 08/06/83
+ *
+ * Rogue: Exploring the Dungeons of Doom
+ * Copyright (C) 1980-1983, 1985, 1999 Michael Toy, Ken Arnold and Glenn Wichman
+ * All rights reserved.
+ *
+ * See the file LICENSE.TXT for full copyright and licensing information.
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include <curses.h>
+#include <ctype.h>
+#include "rogue.h"
+
+/*
+ * command:
+ *	Process the user commands
+ */
+void
+command(void)
+{
+    int ch;
+    int ntimes = 1;			/* Number of player moves */
+    int *fp;
+    THING *mp;
+    static int countch, direction, newcount = FALSE;
+
+    if (on(player, ISHASTE))
+	ntimes++;
+    /*
+     * Let the daemons start up
+     */
+    do_daemons(BEFORE);
+    do_fuses(BEFORE);
+    while (ntimes--)
+    {
+	again = FALSE;
+	if (has_hit)
+	{
+	    endmsg();
+	    has_hit = FALSE;
+	}
+	/*
+	 * these are illegal things for the player to be, so if any are
+	 * set, someone's been poking in memeory
+	 */
+	if (on(player, ISSLOW|ISGREED|ISINVIS|ISREGEN|ISTARGET))
+	    exit(1);
+
+	look(TRUE);
+	if (!running)
+	    door_stop = FALSE;
+	status();
+	lastscore = purse;
+	move(hero.y, hero.x);
+	if (!((running || count) && jump))
+	    refresh();			/* Draw screen */
+	take = 0;
+	after = TRUE;
+	/*
+	 * Read command or continue run
+	 */
+#ifdef MASTER
+	if (wizard)
+	    noscore = TRUE;
+#endif
+	if (!no_command)
+	{
+	    if (running || to_death)
+		ch = runch;
+	    else if (count)
+		ch = countch;
+	    else
+	    {
+		ch = readchar();
+		move_on = FALSE;
+		if (mpos != 0)		/* Erase message if its there */
+		{
+		    if (ch != '.')
+			msg("");
+		}
+	    }
+	}
+	else
+	    ch = '.';
+	if (no_command)
+	{
+	    if (--no_command == 0)
+	    {
+		player.t_flags |= ISRUN;
+		msg("you can move again");
+	    }
+	}
+	else
+	{
+	    /*
+	     * check for prefixes
+	     */
+	    newcount = FALSE;
+	    if (isdigit(ch))
+	    {
+		count = 0;
+		newcount = TRUE;
+		while (isdigit(ch))
+		{
+		    count = count * 10 + (ch - '0');
+		    if (count > 255)
+			count = 255;
+		    ch = readchar();
+		}
+		countch = ch;
+		/*
+		 * turn off count for commands which don't make sense
+		 * to repeat
+		 */
+		switch (ch)
+		{
+		    case CTRL('B'): case CTRL('H'): case CTRL('J'):
+		    case CTRL('K'): case CTRL('L'): case CTRL('N'):
+		    case CTRL('U'): case CTRL('Y'):
+		    case '.': case 'a': case 'b': case 'h': case 'j':
+		    case 'k': case 'l': case 'm': case 'n': case 'q':
+		    case 'r': case 's': case 't': case 'u': case 'y':
+		    case 'z': case 'B': case 'C': case 'H': case 'I':
+		    case 'J': case 'K': case 'L': case 'N': case 'U':
+		    case 'Y':
+#ifdef MASTER
+		    case CTRL('D'): case CTRL('A'):
+#endif
+			break;
+		    default:
+			count = 0;
+		}
+	    }
+	    /*
+	     * execute a command
+	     */
+	    if (count && !running)
+		count--;
+	    if (ch != 'a' && ch != ESCAPE && !(running || count || to_death))
+	    {
+		l_last_comm = last_comm;
+		l_last_dir = last_dir;
+		l_last_pick = last_pick;
+		last_comm = ch;
+		last_dir = '\0';
+		last_pick = NULL;
+	    }
+over:
+	    switch (ch)
+	    {
+		case ',': {
+		    THING *obj = NULL;
+		    int found = 0;
+		    for (obj = lvl_obj; obj != NULL; obj = next(obj))
+    			{
+			    if (obj->o_pos.y == hero.y && obj->o_pos.x == hero.x)
+			    {
+				found=1;
+				break;
+			    }
+    			}
+
+		    if (found) {
+			if (levit_check())
+			    ;
+			else
+			    pick_up(obj->o_type);
+		    }
+		    else {
+			if (!terse)
+			    addmsg("there is ");
+			addmsg("nothing here");
+                        if (!terse)
+                            addmsg(" to pick up");
+                        endmsg();
+		    }
+		}
+		when '!': shell();
+		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 CTRL('H'): case CTRL('J'): case CTRL('K'): case CTRL('L'):
+		case CTRL('Y'): case CTRL('U'): case CTRL('B'): case CTRL('N'):
+		{
+		    if (!on(player, ISBLIND))
+		    {
+			door_stop = TRUE;
+			firstmove = TRUE;
+		    }
+		    if (count && !newcount)
+			ch = direction;
+		    else
+		    {
+			ch += ('A' - CTRL('A'));
+			direction = ch;
+		    }
+		    goto over;
+		}
+		when 'F':
+		    kamikaze = TRUE;
+		    /* FALLTHROUGH */
+		case 'f':
+		    if (!get_dir())
+		    {
+			after = FALSE;
+			break;
+		    }
+		    delta.y += hero.y;
+		    delta.x += hero.x;
+		    if ( ((mp = moat(delta.y, delta.x)) == NULL)
+			|| ((!see_monst(mp)) && !on(player, SEEMONST)))
+		    {
+			if (!terse)
+			    addmsg("I see ");
+			msg("no monster there");
+			after = FALSE;
+		    }
+		    else if (diag_ok(&hero, &delta))
+		    {
+			to_death = TRUE;
+			max_hit = 0;
+			mp->t_flags |= ISTARGET;
+			runch = ch = dir_ch;
+			goto over;
+		    }
+		when 't':
+		    if (!get_dir())
+			after = FALSE;
+		    else
+			missile(delta.y, delta.x);
+		when 'a':
+		    if (last_comm == '\0')
+		    {
+			msg("you haven't typed a command yet");
+			after = FALSE;
+		    }
+		    else
+		    {
+			ch = last_comm;
+			again = TRUE;
+			goto over;
+		    }
+		when 'q': quaff();
+		when 'Q':
+		    after = FALSE;
+		    q_comm = TRUE;
+		    quit(0);
+		    q_comm = FALSE;
+		when 'i': after = FALSE; inventory(pack, 0);
+		when 'I': after = FALSE; picky_inven();
+		when 'd': drop();
+		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(); after = FALSE;
+		when 'c': call(); after = FALSE;
+		when '>': after = FALSE; d_level();
+		when '<': after = FALSE; u_level();
+		when '?': after = FALSE; help();
+		when '/': after = FALSE; identify();
+		when 's': search();
+		when 'z':
+		    if (get_dir())
+			do_zap();
+		    else
+			after = FALSE;
+		when 'D': after = FALSE; discovered();
+		when CTRL('P'): after = FALSE; msg(huh);
+		when CTRL('R'):
+		    after = FALSE;
+		    clearok(curscr,TRUE);
+		    wrefresh(curscr);
+		when 'v':
+		    after = FALSE;
+		    msg("version %s. (mctesq was here)", release);
+		when 'S': 
+		    after = FALSE;
+		    save_game();
+		when '.': ;			/* Rest command */
+		when ' ': after = FALSE;	/* "Legal" illegal command */
+		when '^':
+		    after = FALSE;
+		    if (get_dir()) {
+			delta.y += hero.y;
+			delta.x += hero.x;
+			fp = &flat(delta.y, delta.x);
+                        if (!terse)
+                            addmsg("You have found ");
+			if (chat(delta.y, delta.x) != TRAP)
+			    msg("no trap there");
+			else if (on(player, ISHALU))
+			    msg(tr_name[rnd(NTRAPS)]);
+			else {
+			    msg(tr_name[*fp & F_TMASK]);
+			    *fp |= F_SEEN;
+			}
+		    }
+#ifdef MASTER
+		when '+':
+		    after = FALSE;
+		    if (wizard)
+		    {
+			wizard = FALSE;
+			turn_see(TRUE);
+			msg("not wizard any more");
+		    }
+		    else
+		    {