Esempio n. 1
0
/*
 * This is called when we receive a request for a command in the birth 
 * process.

 * The birth process continues until we send a final character confirmation
 * command (or quit), so this is effectively called in a loop by the main
 * game.
 *
 * We're imposing a step-based system onto the main game here, so we need
 * to keep track of where we're up to, where each step moves on to, etc.
 */
errr get_birth_command(bool wait)
{
	static enum birth_stage current_stage = BIRTH_RESET;
	static enum birth_stage prev;
	static enum birth_stage roller = BIRTH_RESET;
	enum birth_stage next = current_stage;

	switch (current_stage)
	{
		case BIRTH_RESET:
		{
			cmd_insert(CMD_BIRTH_RESET);

			roller = BIRTH_RESET;
			
			if (quickstart_allowed)
				next = BIRTH_QUICKSTART;
			else
				next = BIRTH_SEX_CHOICE;

			break;
		}

		case BIRTH_QUICKSTART:
		{
			display_player(0);
			next = get_quickstart_command();
			break;
		}

		case BIRTH_SEX_CHOICE:
		case BIRTH_CLASS_CHOICE:
		case BIRTH_RACE_CHOICE:
		case BIRTH_ROLLER_CHOICE:
		{
			menu_type *menu = &sex_menu;
			cmd_code command = CMD_CHOOSE_SEX;

			Term_clear();
			print_menu_instructions();

			if (current_stage > BIRTH_SEX_CHOICE)
			{
				menu_refresh(&sex_menu, FALSE);
				menu = &race_menu;
				command = CMD_CHOOSE_RACE;
			}
			
			if (current_stage > BIRTH_RACE_CHOICE)
			{
				menu_refresh(&race_menu, FALSE);
				menu = &class_menu;
				command = CMD_CHOOSE_CLASS;
			}

			if (current_stage > BIRTH_CLASS_CHOICE)
			{
				menu_refresh(&class_menu, FALSE);
				menu = &roller_menu;
				command = CMD_NULL;
			}
			
			next = menu_question(current_stage, menu, command);

			if (next == BIRTH_BACK)
				next = current_stage - 1;

			/* Make sure that the character gets reset before quickstarting */
			if (next == BIRTH_QUICKSTART) 
				next = BIRTH_RESET;

			break;
		}

		case BIRTH_POINTBASED:
		{
			roller = BIRTH_POINTBASED;
	
			if (prev > BIRTH_POINTBASED)
				point_based_start();

			next = point_based_command();

			if (next == BIRTH_BACK)
				next = BIRTH_ROLLER_CHOICE;

			if (next != BIRTH_POINTBASED)
				point_based_stop();

			break;
		}

		case BIRTH_ROLLER:
		{
			roller = BIRTH_ROLLER;
			next = roller_command(prev < BIRTH_ROLLER);
			if (next == BIRTH_BACK)
				next = BIRTH_ROLLER_CHOICE;

			break;
		}

		case BIRTH_NAME_CHOICE:
		{
			if (prev < BIRTH_NAME_CHOICE)
				display_player(0);

			next = get_name_command();
			if (next == BIRTH_BACK)
				next = roller;

			break;
		}

		case BIRTH_FINAL_CONFIRM:
		{
			if (prev < BIRTH_FINAL_CONFIRM)
				display_player(0);

			next = get_confirm_command();
			if (next == BIRTH_BACK)
				next = BIRTH_NAME_CHOICE;

			break;
		}

		default:
		{
			/* Remove dodgy compiler warning, */
		}
	}

	prev = current_stage;
	current_stage = next;

	return 0;
}
Esempio n. 2
0
/* Allow the user to select from the current menu, and return the
   corresponding command to the game.  Some actions are handled entirely
   by the UI (displaying help text, for instance). */
static enum birth_stage menu_question(enum birth_stage current, menu_type *current_menu, cmd_code choice_command)
{
	struct birthmenu_data *menu_data = current_menu->menu_data;
	int cursor = current_menu->cursor;
	ui_event_data cx;

	enum birth_stage next = BIRTH_RESET;

	/* Print the question currently being asked. */
	clear_question();
	Term_putstr(QUESTION_COL, QUESTION_ROW, -1, TERM_YELLOW, menu_data->hint);

	current_menu->cmd_keys = "?=*\r\n\x18";	 /* ?, ,= *, \n, <ctl-X> */

	while (next == BIRTH_RESET)
	{
		button_kill_all();
		button_add("[ENTER]", '\r');
		if (menu_data->allow_random) button_add("[RANDOM]", '*');
		button_add("[ESCAPE]", ESCAPE);
		button_add("[OPTIONS]", '=');
		button_add("[HELP]", '?');
		button_add("[QUIT]", '\x18');  /* CTRL-X */
		event_signal(EVENT_MOUSEBUTTONS);

		/* Display the menu, wait for a selection of some sort to be made. */
		cx = menu_select(current_menu, &cursor, EVT_CMD);

		/* As all the menus are displayed in "hierarchical" style, we allow
		   use of "back" (left arrow key or equivalent) to step back in
		   the proces as well as "escape". */
		if (cx.type == EVT_BACK || cx.type == EVT_ESCAPE || cx.key == ESCAPE)
		{
			next = BIRTH_BACK;
		}
		/* '\xff' or DEFINED_XFF is a mouse selection, '\r' a keyboard one. */
		else if (cx.key == DEFINED_XFF || cx.key == '\r')
		{
			if (current == BIRTH_ROLLER_CHOICE)
			{
				if (cursor)
				{
					/* Do a first roll of the stats */
					cmd_insert(CMD_ROLL_STATS);
					next = current + 2;
				}
				else
				{
					/*
					 * Make sure we've got a point-based char to play with.
					 * We call point_based_start here to make sure we get
					 * an update on the points totals before trying to
					 * display the screen.  The call to CMD_RESET_STATS
					 * forces a rebuying of the stats to give us up-to-date
					 * totals.  This is, it should go without saying, a hack.
					 */
					point_based_start();
					cmd_insert(CMD_RESET_STATS, TRUE);
					next = current + 1;
				}
			}
			else
			{
				cmd_insert(choice_command, cursor);
				next = current + 1;
			}
		}
		/* '*' chooses an option at random from those the game's provided. */
		else if (cx.key == '*' && menu_data->allow_random)
		{
			current_menu->cursor = randint0(current_menu->count);
			cmd_insert(choice_command, current_menu->cursor);

			menu_refresh(current_menu);
			next = current + 1;
		}
		else if (cx.key == '=')
		{
			do_cmd_options();
			next = current;
		}
		else if (cx.key == KTRL('X'))
		{
			cmd_insert(CMD_QUIT);
			next = BIRTH_COMPLETE;
		}
		else if (cx.key == '?')
		{
			do_cmd_help();
		}
	}

	return next;
}
Esempio n. 3
0
/* Allow the user to select from the current menu, and return the 
   corresponding command to the game.  Some actions are handled entirely
   by the UI (displaying help text, for instance). */
static enum birth_stage menu_question(enum birth_stage current, menu_type *current_menu, cmd_code choice_command)
{
	struct birthmenu_data *menu_data = menu_priv(current_menu);
	ui_event cx;

	enum birth_stage next = BIRTH_RESET;
	
	/* Print the question currently being asked. */
	clear_question();
	Term_putstr(QUESTION_COL, QUESTION_ROW, -1, TERM_YELLOW, menu_data->hint);

	current_menu->cmd_keys = "?=*\x18";	 /* ?, =, *, <ctl-X> */

	while (next == BIRTH_RESET)
	{
		/* Display the menu, wait for a selection of some sort to be made. */
		cx = menu_select(current_menu, EVT_KBRD, FALSE);

		/* As all the menus are displayed in "hierarchical" style, we allow
		   use of "back" (left arrow key or equivalent) to step back in 
		   the proces as well as "escape". */
		if (cx.type == EVT_ESCAPE)
		{
			next = BIRTH_BACK;
		}
		else if (cx.type == EVT_SELECT)
		{
			if (current == BIRTH_ROLLER_CHOICE)
			{
				cmd_insert(CMD_FINALIZE_OPTIONS);

				if (current_menu->cursor)
				{
					/* Do a first roll of the stats */
					cmd_insert(CMD_ROLL_STATS);
					next = current + 2;
				}
				else
				{
					/* 
					 * Make sure we've got a point-based char to play with. 
					 * We call point_based_start here to make sure we get
					 * an update on the points totals before trying to
					 * display the screen.  The call to CMD_RESET_STATS
					 * forces a rebuying of the stats to give us up-to-date
					 * totals.  This is, it should go without saying, a hack.
					 */
					point_based_start();
					cmd_insert(CMD_RESET_STATS);
					cmd_set_arg_choice(cmd_get_top(), 0, TRUE);
					next = current + 1;
				}
			}
			else
			{
				cmd_insert(choice_command);
				cmd_set_arg_choice(cmd_get_top(), 0, current_menu->cursor);
				next = current + 1;
			}
		}
		else if (cx.type == EVT_KBRD)
		{
			/* '*' chooses an option at random from those the game's provided. */
			if (cx.key.code == '*' && menu_data->allow_random) 
			{
				current_menu->cursor = randint0(current_menu->count);
				cmd_insert(choice_command);
				cmd_set_arg_choice(cmd_get_top(), 0, current_menu->cursor);

				menu_refresh(current_menu, FALSE);
				next = current + 1;
			}
			else if (cx.key.code == '=') 
			{
				do_cmd_options_birth();
				next = current;
			}
			else if (cx.key.code == KTRL('X')) 
			{
				cmd_insert(CMD_QUIT);
				next = BIRTH_COMPLETE;
			}
			else if (cx.key.code == '?')
			{
				do_cmd_help();
			}
		}
	}
	
	return next;
}
Esempio n. 4
0
/**
 * This is called when we receive a request for a command in the birth 
 * process.

 * The birth process continues until we send a final character confirmation
 * command (or quit), so this is effectively called in a loop by the main
 * game.
 *
 * We're imposing a step-based system onto the main game here, so we need
 * to keep track of where we're up to, where each step moves on to, etc.
 */
int textui_do_birth(void)
{
	enum birth_stage current_stage = BIRTH_RESET;
	enum birth_stage prev;
	enum birth_stage roller = BIRTH_RESET;
	enum birth_stage next = current_stage;

	bool done = FALSE;

	cmdq_push(CMD_BIRTH_INIT);
	cmdq_execute(CMD_BIRTH);

	while (!done) {

		switch (current_stage)
		{
			case BIRTH_RESET:
			{
				cmdq_push(CMD_BIRTH_RESET);

				roller = BIRTH_RESET;
				
				if (quickstart_allowed)
					next = BIRTH_QUICKSTART;
				else
					next = BIRTH_RACE_CHOICE;

				break;
			}

			case BIRTH_QUICKSTART:
			{
				display_player(0);
				next = textui_birth_quickstart();
				if (next == BIRTH_COMPLETE)
					done = TRUE;
				break;
			}

			case BIRTH_CLASS_CHOICE:
			case BIRTH_RACE_CHOICE:
			case BIRTH_ROLLER_CHOICE:
			{
				struct menu *menu = &race_menu;
				cmd_code command = CMD_CHOOSE_RACE;

				Term_clear();
				print_menu_instructions();

				if (current_stage > BIRTH_RACE_CHOICE) {
					menu_refresh(&race_menu, FALSE);
					menu = &class_menu;
					command = CMD_CHOOSE_CLASS;
				}

				if (current_stage > BIRTH_CLASS_CHOICE) {
					menu_refresh(&class_menu, FALSE);
					menu = &roller_menu;
				}

				next = menu_question(current_stage, menu, command);

				if (next == BIRTH_BACK)
					next = current_stage - 1;

				/* Make sure the character gets reset before quickstarting */
				if (next == BIRTH_QUICKSTART) 
					next = BIRTH_RESET;

				break;
			}

			case BIRTH_POINTBASED:
			{
				roller = BIRTH_POINTBASED;
		
				if (prev > BIRTH_POINTBASED)
					point_based_start();

				next = point_based_command();

				if (next == BIRTH_BACK)
					next = BIRTH_ROLLER_CHOICE;

				if (next != BIRTH_POINTBASED)
					point_based_stop();

				break;
			}

			case BIRTH_ROLLER:
			{
				roller = BIRTH_ROLLER;
				next = roller_command(prev < BIRTH_ROLLER);
				if (next == BIRTH_BACK)
					next = BIRTH_ROLLER_CHOICE;

				break;
			}

			case BIRTH_NAME_CHOICE:
			{
				if (prev < BIRTH_NAME_CHOICE)
					display_player(0);

				next = get_name_command();
				if (next == BIRTH_BACK)
					next = roller;

				break;
			}

			case BIRTH_HISTORY_CHOICE:
			{
				if (prev < BIRTH_HISTORY_CHOICE)
					display_player(0);

				next = get_history_command();
				if (next == BIRTH_BACK)
					next = BIRTH_NAME_CHOICE;

				break;
			}

			case BIRTH_FINAL_CONFIRM:
			{
				if (prev < BIRTH_FINAL_CONFIRM)
					display_player(0);

				next = get_confirm_command();
				if (next == BIRTH_BACK)
					next = BIRTH_HISTORY_CHOICE;

				if (next == BIRTH_COMPLETE)
					done = TRUE;

				break;
			}

			default:
			{
				/* Remove dodgy compiler warning, */
			}
		}

		prev = current_stage;
		current_stage = next;

		/* Execute whatever commands have been sent */
		cmdq_execute(CMD_BIRTH);
	}

	return 0;
}