Beispiel #1
0
/**
 * Ask for a "user pref file" and process it.
 *
 * This function should only be used by standard interaction commands,
 * in which a standard "Command:" prompt is present on the given row.
 *
 * Allow absolute file names?  XXX XXX XXX
 */
static void do_cmd_pref_file_hack(long row)
{
	char ftmp[80];

	screen_save();

	/* Prompt */
	prt("Command: Load a user pref file", row, 0);

	/* Prompt */
	prt("File: ", row + 2, 0);

	/* Default filename */
	strnfmt(ftmp, sizeof ftmp, "%s.prf", player_safe_name(player, true));

	/* Ask for a file (or cancel) */
	if (askfor_aux(ftmp, sizeof ftmp, NULL)) {
		/* Process the given filename */
		if (process_pref_file(ftmp, false, true) == false) {
			/* Mention failure */
			prt("", 0, 0);
			msg("Failed to load '%s'!", ftmp);
		} else {
			/* Mention success */
			prt("", 0, 0);
			msg("Loaded '%s'.", ftmp);
		}
	}

	screen_load();
}
Beispiel #2
0
/**
 * Menu command: dump character dump to file.
 */
static void death_file(const char *title, int row)
{
	char buf[1024];
	char ftmp[80];

	strnfmt(ftmp, sizeof(ftmp), "%s.txt", player_safe_name(player, false));

	if (get_file(ftmp, buf, sizeof buf)) {
		bool success;

		/* Dump a character file */
		screen_save();
		success = dump_save(buf);
		screen_load();

		/* Check result */
		if (success)
			msg("Character dump successful.");
		else
			msg("Character dump failed!");

		/* Flush messages */
		event_signal(EVENT_MESSAGE_FLUSH);
	}
}
Beispiel #3
0
/**
 * Menu command: dump character dump to file.
 */
static void death_file(const char *title, int row)
{
	char buf[1024];
	char ftmp[80];

	/* Get the filesystem-safe name and append .txt */
	player_safe_name(ftmp, sizeof(ftmp), player->full_name, false);
	my_strcat(ftmp, ".txt", sizeof(ftmp));

	if (get_file(ftmp, buf, sizeof buf)) {
		bool success;

		/* Dump a character file */
		screen_save();
		success = dump_save(buf);
		screen_load();

		/* Check result */
		if (success)
			msg("Character dump successful.");
		else
			msg("Character dump failed!");

		/* Flush messages */
		event_signal(EVENT_MESSAGE_FLUSH);
	}
}
Beispiel #4
0
/**
 * Ask for a "user pref file" and process it.
 *
 * This function should only be used by standard interaction commands,
 * in which a standard "Command:" prompt is present on the given row.
 *
 * Allow absolute file names?  XXX XXX XXX
 */
static void do_cmd_pref_file_hack(long row)
{
	char ftmp[80];

	screen_save();

	/* Prompt */
	prt("Command: Load a user pref file", row, 0);

	/* Prompt */
	prt("File: ", row + 2, 0);

	/* Get the filesystem-safe name and append .prf */
	player_safe_name(ftmp, sizeof(ftmp), player->full_name, true);
	my_strcat(ftmp, ".prf", sizeof(ftmp));

	/* Ask for a file (or cancel) */
	if (askfor_aux(ftmp, sizeof ftmp, NULL)) {
		/* Process the given filename */
		if (process_pref_file(ftmp, false, true) == false) {
			/* Mention failure */
			prt("", 0, 0);
			msg("Failed to load '%s'!", ftmp);
		} else {
			/* Mention success */
			prt("", 0, 0);
			msg("Loaded '%s'.", ftmp);
		}
	}

	screen_load();
}
Beispiel #5
0
/**
 * Prompt the user for a filename to save the pref file to.
 */
static bool get_pref_path(const char *what, int row, char *buf, size_t max)
{
	char ftmp[80];
	bool ok;

	screen_save();

	/* Prompt */
	prt(format("%s to a pref file", what), row, 0);
	prt("File: ", row + 2, 0);

	/* Get the filesystem-safe name and append .prf */
	player_safe_name(ftmp, sizeof(ftmp), player->full_name, true);
	my_strcat(ftmp, ".prf", sizeof(ftmp));

	/* Get a filename */
	ok = askfor_aux(ftmp, sizeof ftmp, NULL);
	screen_load();

	/* Build the filename */
	if (ok)
		path_build(buf, max, ANGBAND_DIR_USER, ftmp);

	return ok;
}
Beispiel #6
0
static void ui_leave_birthscreen(game_event_type type, game_event_data *data,
								 void *user)
{
	/* Set the savefile name if it's not already set */
	if (!savefile[0])
		savefile_set_name(player_safe_name(player, TRUE));

	free_birth_menus();
}
/**
 * Save the game
 */
void save_game(void)
{
	char name[80];
	char path[1024];

	/* Disturb the player */
	disturb(player, 1);

	/* Clear messages */
	event_signal(EVENT_MESSAGE_FLUSH);

	/* Handle stuff */
	handle_stuff(player);

	/* Message */
	prt("Saving game...", 0, 0);

	/* Refresh */
	Term_fresh();

	/* The player is not dead */
	my_strcpy(player->died_from, "(saved)", sizeof(player->died_from));

	/* Forbid suspend */
	signals_ignore_tstp();

	/* Save the player */
	if (savefile_save(savefile))
		prt("Saving game... done.", 0, 0);
	else
		prt("Saving game... failed!", 0, 0);

	/* Refresh */
	Term_fresh();

	/* Save the window prefs */
	strnfmt(name, sizeof(name), "%s.prf", player_safe_name(player, TRUE));
	path_build(path, sizeof(path), ANGBAND_DIR_USER, name);
	if (!prefs_save(path, option_dump, "Dump window settings"))
		prt("Failed to save subwindow preferences", 0, 0);

	/* Allow suspend again */
	signals_handle_tstp();

	/* Refresh */
	Term_fresh();

	/* Note that the player is not dead */
	my_strcpy(player->died_from, "(alive and well)", sizeof(player->died_from));
}
Beispiel #8
0
/**
 * Prompt the user for a filename to save the pref file to.
 */
static bool get_pref_path(const char *what, int row, char *buf, size_t max)
{
	char ftmp[80];
	bool ok;

	screen_save();

	/* Prompt */
	prt(format("%s to a pref file", what), row, 0);
	prt("File: ", row + 2, 0);

	/* Default filename */
	strnfmt(ftmp, sizeof ftmp, "%s.prf", player_safe_name(player, true));
	
	/* Get a filename */
	ok = askfor_aux(ftmp, sizeof ftmp, NULL);
	screen_load();

	/* Build the filename */
	if (ok)
		path_build(buf, max, ANGBAND_DIR_USER, ftmp);

	return ok;
}
Beispiel #9
0
/**
 * Hack -- change name
 */
void do_cmd_change_name(void)
{
	ui_event ke;
	int mode = 0;

	const char *p;

	bool more = true;

	/* Prompt */
	p = "['c' to change name, 'f' to file, 'h' to change mode, or ESC]";

	/* Save screen */
	screen_save();

	/* Forever */
	while (more) {
		/* Display the player */
		display_player(mode);

		/* Prompt */
		Term_putstr(2, 23, -1, COLOUR_WHITE, p);

		/* Query */
		ke = inkey_ex();

		if ((ke.type == EVT_KBRD)||(ke.type == EVT_BUTTON)) {
			switch (ke.key.code) {
				case ESCAPE: more = false; break;
				case 'c': {
					if(arg_force_name)
						msg("You are not allowed to change your name!");
					else {
					char namebuf[32] = "";

					/* Set player name */
					if (get_character_name(namebuf, sizeof namebuf))
						my_strcpy(player->full_name, namebuf,
								  sizeof(player->full_name));
					}

					break;
				}

				case 'f': {
					char buf[1024];
					char fname[80];

					/* Get the filesystem-safe name and append .txt */
					player_safe_name(fname, sizeof(fname), player->full_name, false);
					my_strcat(fname, ".txt", sizeof(fname));

					if (get_file(fname, buf, sizeof buf)) {
						if (dump_save(buf))
							msg("Character dump successful.");
						else
							msg("Character dump failed!");
					}
					break;
				}
				
				case 'h':
				case ARROW_LEFT:
				case ' ':
					mode = (mode + 1) % INFO_SCREENS;
					break;

				case 'l':
				case ARROW_RIGHT:
					mode = (mode - 1) % INFO_SCREENS;
					break;
			}
		} else if (ke.type == EVT_MOUSE) {
			if (ke.mouse.button == 1) {
				/* Flip through the screens */			
				mode = (mode + 1) % INFO_SCREENS;
			} else if (ke.mouse.button == 2) {
				/* exit the screen */
				more = false;
			} else {
				/* Flip backwards through the screens */			
				mode = (mode - 1) % INFO_SCREENS;
			}
		}

		/* Flush messages */
		event_signal(EVENT_MESSAGE_FLUSH);
	}

	/* Load screen */
	screen_load();
}
Beispiel #10
0
/*
 * Helper function for "process_pref_file()"
 *
 * Input:
 *   v: output buffer array
 *   f: final character
 *
 * Output:
 *   result
 */
static const char *process_pref_file_expr(char **sp, char *fp)
{
	const char *v;

	char *b;
	char *s;

	char f = ' ';

	/* Initial */
	s = (*sp);

	/* Skip spaces */
	while (isspace((unsigned char) *s))
		s++;

	/* Save start */
	b = s;

	/* Default */
	v = "?o?o?";

	/* Analyze */
	if (*s == '[') {
		const char *p;
		const char *t;

		/* Skip [ */
		s++;

		/* First */
		t = process_pref_file_expr(&s, &f);

		/* Oops */
		if (!*t) {
			/* Nothing */
		}

		/* Function: IOR */
		else if (streq(t, "IOR")) {
			v = "0";
			while (*s && (f != ']')) {
				t = process_pref_file_expr(&s, &f);
				if (*t && !streq(t, "0"))
					v = "1";
			}
		}

		/* Function: AND */
		else if (streq(t, "AND")) {
			v = "1";
			while (*s && (f != ']')) {
				t = process_pref_file_expr(&s, &f);
				if (*t && streq(t, "0"))
					v = "0";
			}
		}

		/* Function: NOT */
		else if (streq(t, "NOT")) {
			v = "1";
			while (*s && (f != ']')) {
				t = process_pref_file_expr(&s, &f);
				if (*t && !streq(t, "0"))
					v = "0";
			}
		}

		/* Function: EQU */
		else if (streq(t, "EQU")) {
			v = "1";
			if (*s && (f != ']')) {
				t = process_pref_file_expr(&s, &f);
			}
			while (*s && (f != ']')) {
				p = t;
				t = process_pref_file_expr(&s, &f);
				if (*t && !streq(p, t))
					v = "0";
			}
		}

		/* Function: LEQ */
		else if (streq(t, "LEQ")) {
			v = "1";
			if (*s && (f != ']')) {
				t = process_pref_file_expr(&s, &f);
			}
			while (*s && (f != ']')) {
				p = t;
				t = process_pref_file_expr(&s, &f);
				if (*t && (strcmp(p, t) >= 0))
					v = "0";
			}
		}

		/* Function: GEQ */
		else if (streq(t, "GEQ")) {
			v = "1";
			if (*s && (f != ']')) {
				t = process_pref_file_expr(&s, &f);
			}
			while (*s && (f != ']')) {
				p = t;
				t = process_pref_file_expr(&s, &f);
				if (*t && (strcmp(p, t) <= 0))
					v = "0";
			}
		}

		/* Oops */
		else {
			while (*s && (f != ']')) {
				t = process_pref_file_expr(&s, &f);
			}
		}

		/* Verify ending */
		if (f != ']')
			v = "?x?x?";

		/* Extract final and Terminate */
		if ((f = *s) != '\0')
			*s++ = '\0';
	}

	/* Other */
	else {
		/* Accept all printables except spaces and brackets */
		while (isprint((unsigned char) *s) && !strchr(" []", *s))
			++s;

		/* Extract final and Terminate */
		if ((f = *s) != '\0')
			*s++ = '\0';

		/* Variable */
		if (*b == '$') {
			if (streq(b + 1, "SYS"))
				v = ANGBAND_SYS;
			else if (streq(b + 1, "GRAF"))
				v = ANGBAND_GRAF;
			else if (streq(b + 1, "RACE"))
				v = rp_ptr->name;
			else if (streq(b + 1, "CLASS"))
				v = cp_ptr->name;
			else if (streq(b + 1, "PLAYER"))
				v = player_safe_name(p_ptr, TRUE);
			else if (streq(b + 1, "GENDER"))
				v = sp_ptr->title;
		}

		/* Constant */
		else {
			v = b;
		}
	}

	/* Save */
	(*fp) = f;
	(*sp) = s;

	return v;
}
Beispiel #11
0
/**
 * Simple "main" function for multiple platforms.
 *
 * Note the special "--" option which terminates the processing of
 * standard options.  All non-standard options (if any) are passed
 * directly to the "init_xxx()" function.
 */
int main(int argc, char *argv[])
{
	int i;

	bool done = FALSE;

	const char *mstr = NULL;
	const char *soundstr = NULL;

	bool args = TRUE;

	/* Save the "program name" XXX XXX XXX */
	argv0 = argv[0];

#ifdef UNIX

	/* Default permissions on files */
	(void)umask(022);

	/* Get the user id */
	player_uid = getuid();

#endif /* UNIX */

#ifdef SETGID

	/* Save the effective GID for later recall */
	player_egid = getegid();

#endif /* UNIX */


	/* Drop permissions */
	safe_setuid_drop();

	/* Get the file paths 
	 * Paths may be overriden by -d options, so this has to occur *before* 
	 * processing command line args */
	init_stuff();

	/* Process the command line arguments */
	for (i = 1; args && (i < argc); i++) {
		const char *arg = argv[i];

		/* Require proper options */
		if (*arg++ != '-') goto usage;

		/* Analyze option */
		switch (*arg++)
		{
			case 'l':
				list_saves();
				exit(0);

			case 'n':
				new_game = TRUE;
				break;

			case 'w':
				arg_wizard = TRUE;
				break;

			case 'p':
				arg_power = TRUE;
				break;

			case 'r':
				arg_rebalance = TRUE;
				break;

			case 'g':
				/* Default graphics tile */
				/* in graphics.txt, 2 corresponds to adam bolt's tiles */
				arg_graphics = 2; 
				if (*arg) arg_graphics = atoi(arg);
				break;

			case 'u': {

				if (!*arg) goto usage;
				my_strcpy(op_ptr->full_name, arg, sizeof op_ptr->full_name);

				/* The difference here is because on setgid we have to be
				 * careful to only let the player have savefiles stored in
				 * the central save directory.  Sanitising input using
				 * player_safe_name() removes anything like that.
				 *
				 * But if the player is running with per-user saves, they
				 * can do whatever the hell they want.
				 */
#ifdef SETGID
				savefile_set_name(player_safe_name(player, FALSE));
#else
				savefile_set_name(arg);
#endif /* SETGID */

				continue;
			}

			case 'm':
				if (!*arg) goto usage;
				mstr = arg;
				continue;

			case 's':
				if (!*arg) goto usage;
				soundstr = arg;
				continue;

			case 'd':
				change_path(arg);
				continue;

			case 'x':
				debug_opt(arg);
				continue;

			case '-':
				argv[i] = argv[0];
				argc = argc - i;
				argv = argv + i;
				args = FALSE;
				break;

			default:
			usage:
				puts("Usage: angband [options] [-- subopts]");
				puts("  -n             Start a new character (WARNING: overwrites default savefile without -u)");
				puts("  -l             Lists all savefiles you can play");
				puts("  -w             Resurrect dead character (marks savefile)");
				puts("  -r             Rebalance monsters");
				puts("  -g             Request graphics mode");
				puts("  -x<opt>        Debug options; see -xhelp");
				puts("  -u<who>        Use your <who> savefile");
				puts("  -d<dir>=<path> Override a specific directory with <path>. <path> can be:");
				for (i = 0; i < (int)N_ELEMENTS(change_path_values); i++) {
#ifdef SETGID
					if (!change_path_values[i].setgid_ok) continue;
#endif
					printf("    %s (default is %s)\n", change_path_values[i].name, *change_path_values[i].path);
				}
				puts("                 Multiple -d options are allowed.");
				puts("  -s<mod>        Use sound module <sys>:");
				for (i = 0; i < (int)N_ELEMENTS(sound_modules); i++)
					printf("     %s   %s\n", sound_modules[i].name,
					       sound_modules[i].help);
				puts("  -m<sys>        Use module <sys>, where <sys> can be:");

				/* Print the name and help for each available module */
				for (i = 0; i < (int)N_ELEMENTS(modules); i++)
					printf("     %s   %s\n",
					       modules[i].name, modules[i].help);

				/* Actually abort the process */
				quit(NULL);
		}
		if (*arg) goto usage;
	}

	/* Hack -- Forget standard args */
	if (args) {
		argc = 1;
		argv[1] = NULL;
	}

	/* Install "quit" hook */
	quit_aux = quit_hook;

	/* If we were told which mode to use, then use it */
	if (mstr)
		ANGBAND_SYS = mstr;

	if (setlocale(LC_CTYPE, "")) {
		/* Require UTF-8 */
		if (strcmp(nl_langinfo(CODESET), "UTF-8") != 0)
			quit("Angband requires UTF-8 support");
	}

	/* Try the modules in the order specified by modules[] */
	for (i = 0; i < (int)N_ELEMENTS(modules); i++) {
		/* User requested a specific module? */
		if (!mstr || (streq(mstr, modules[i].name))) {
			ANGBAND_SYS = modules[i].name;
			if (0 == modules[i].init(argc, argv)) {
				done = TRUE;
				break;
			}
		}
	}

	/* Make sure we have a display! */
	if (!done) quit("Unable to prepare any 'display module'!");

#ifdef UNIX

	/* Get the "user name" as default player name, unless set with -u switch */
	if (!op_ptr->full_name[0]) {
		user_name(op_ptr->full_name, sizeof(op_ptr->full_name), player_uid);

		/* Set the savefile to load */
		savefile_set_name(player_safe_name(player, FALSE));
	}

	/* Create any missing directories */
	create_needed_dirs();

#endif /* UNIX */

	/* Try the modules in the order specified by sound_modules[] */
	for (i = 0; i < (int)N_ELEMENTS(sound_modules); i++)
		if (!soundstr || streq(soundstr, sound_modules[i].name))
			if (0 == sound_modules[i].init(argc, argv))
				break;

	/* Catch nasty signals */
	signals_init();

	/* Set up the command hook */
	cmd_get_hook = textui_get_cmd;

	/* Set up the display handlers and things. */
	init_display();
	init_angband();
	textui_init();

	/* Wait for response */
	pause_line(Term);

	/* Play the game */
	play_game(new_game);

	/* Free resources */
	textui_cleanup();
	cleanup_angband();

	/* Quit */
	quit(NULL);

	/* Exit */
	return (0);
}
Beispiel #12
0
/**
 * Helper function for "process_pref_file()"
 *
 * Input:
 *   v: output buffer array
 *   f: final character
 *
 * Output:
 *   result
 */
static const char *process_pref_file_expr(char **sp, char *fp)
{
	const char *v;

	char *b;
	char *s;

	char f = ' ';

	/* Initial */
	s = (*sp);

	/* Skip spaces */
	while (isspace((unsigned char)*s)) s++;

	/* Save start */
	b = s;

	/* Default */
	v = "?o?o?";

	/* Either the string starts with a [ or it doesn't */
	if (*s == '[') {
		const char *p;
		const char *t;

		/* Skip [ */
		s++;

		/* First */
		t = process_pref_file_expr(&s, &f);

		/* Check all the different types of connective */
		if (!*t) {
			/* Nothing */
		} else if (streq(t, "IOR")) {
			v = "0";
			while (*s && (f != ']')) {
				t = process_pref_file_expr(&s, &f);
				if (*t && !streq(t, "0")) v = "1";
			}
		} else if (streq(t, "AND")) {
			v = "1";
			while (*s && (f != ']')) {
				t = process_pref_file_expr(&s, &f);
				if (*t && streq(t, "0")) v = "0";
			}
		} else if (streq(t, "NOT")) {
			v = "1";
			while (*s && (f != ']')) {
				t = process_pref_file_expr(&s, &f);
				if (*t && !streq(t, "0")) v = "0";
			}
		} else if (streq(t, "EQU")) {
			v = "1";
			if (*s && (f != ']')) {
				t = process_pref_file_expr(&s, &f);
			}
			while (*s && (f != ']')) {
				p = t;
				t = process_pref_file_expr(&s, &f);
				if (*t && !streq(p, t)) v = "0";
			}
		} else if (streq(t, "LEQ")) {
			v = "1";
			if (*s && (f != ']')) {
				t = process_pref_file_expr(&s, &f);
			}
			while (*s && (f != ']')) {
				p = t;
				t = process_pref_file_expr(&s, &f);
				if (*t && (strcmp(p, t) >= 0)) v = "0";
			}
		} else if (streq(t, "GEQ")) {
			v = "1";
			if (*s && (f != ']')) {
				t = process_pref_file_expr(&s, &f);
			}
			while (*s && (f != ']')) {
				p = t;
				t = process_pref_file_expr(&s, &f);
				if (*t && (strcmp(p, t) <= 0)) v = "0";
			}
		} else {
			while (*s && (f != ']')) {
				t = process_pref_file_expr(&s, &f);
			}
		}

		/* Verify ending */
		if (f != ']') v = "?x?x?";

		/* Extract final and Terminate */
		if ((f = *s) != '\0') *s++ = '\0';
	} else {
		/* Accept all printables except spaces and brackets */
		while (isprint((unsigned char)*s) && !strchr(" []", *s)) ++s;

		/* Extract final and Terminate */
		if ((f = *s) != '\0') *s++ = '\0';

		/* Variables start with $, otherwise it's a constant */
		if (*b == '$') {
			if (streq(b+1, "SYS"))
				v = ANGBAND_SYS;
			else if (streq(b+1, "RACE"))
				v = player->race->name;
			else if (streq(b+1, "CLASS"))
				v = player->class->name;
			else if (streq(b+1, "PLAYER"))
				v = player_safe_name(player, true);
		} else {