void Window_Message::Update() {
	Window_Selectable::Update();
	number_input_window->Update();
	gold_window->Update();

	if (pause) {
		WaitForInput();
	} else if (active) {
		InputChoice();
	} else if (number_input_window->GetVisible()) {
		InputNumber();
	} else if (!text.empty()) {
		// Output the remaining text for the current page
		UpdateMessage();
	} else if (IsNextMessagePossible()) {
		// Output a new page
		if (Game_Temp::inn_calling) {
			ShowGoldWindow();
		}

		StartMessageProcessing();
		//printf("Text: %s\n", text.c_str());
		if (!visible) {
			// The MessageBox is not open yet but text output is needed
			// Open and Close Animations are skipped in battle
			SetOpenAnimation(Game_Temp::battle_running ? 0 : 5);
		} else if (closing) {
			// Cancel closing animation
			SetOpenAnimation(0);
		}
		Game_Message::visible = true;
	} else if (!Game_Message::message_waiting && Game_Message::visible) {
		if (visible && !closing) {
			// Start the closing animation
			SetCloseAnimation(Game_Temp::battle_running ? 0 : 5);
		} else if (!visible) {
			// The closing animation has finished
			Game_Message::visible = false;
			Game_Message::owner_id = 0;
		}
	}
}
void Window_Message::UpdateMessage() {
	// Message Box Show Message rendering loop

	// Contains at what frame the sleep is over
	static int sleep_until = -1;
	bool instant_speed = false;

	if (Player::debug_flag && Input::IsPressed(Input::SHIFT)) {
		sleep_until = -1;
		instant_speed = true;
	}

	if (sleep_until > -1) {
		if (Player::GetFrames() >= sleep_until) {
			// Sleep over
			sleep_until = -1;
		} else {
			return;
		}
	}

	int loop_count = 0;
	int loop_max = speed_table[speed_modifier] == 0 ? 2 : 1;

	while (instant_speed || loop_count < loop_max) {
		if (!instant_speed) {
			// It's assumed that speed_modifier is between 0 and 20
			++speed_frame_counter;

			if (speed_table[speed_modifier] != 0 &&
				speed_table[speed_modifier] != speed_frame_counter) {
				break;
			}

			speed_frame_counter = 0;
		}

		++loop_count;
		if (text_index == end) {
			FinishMessageProcessing();
			break;
		} else if (line_count == 4) {
			pause = true;
			new_page_after_pause = true;
			break;
		} else if (pause) {
			break;
		}

		if (*text_index == '\n') {
			if (instant_speed) {
				// instant_speed stops at the end of the line, unless
				// there's a /> at the beginning of the next line
				if (std::distance(text_index, end) > 2 &&
					*(text_index + 1) == escape_char &&
					*(text_index + 2) == '>') {
					text_index += 2;
				} else {
					instant_speed = false;
				}
			}
			InsertNewLine();
		} else if (*text_index == '\f') {
			instant_speed = false;
			++text_index;
			if (*text_index == '\n') {
				++text_index;
			}
			if (text_index != end) {
				pause = true;
				new_page_after_pause = true;
			}
			break;
		} else if (*text_index == escape_char && std::distance(text_index, end) > 1) {
			// Special message codes
			++text_index;

			int parameter;
			bool is_valid;
			switch (tolower(*text_index)) {
			case 'c':
				// Color
				parameter = ParseParameter(is_valid);
				text_color = parameter > 19 ? 0 : parameter;
				break;
			case 's':
				// Speed modifier
				parameter = ParseParameter(is_valid);
				speed_modifier = max(0, min(parameter, 20));
				break;
			case '_':
				// Insert half size space
				contents_x += contents->GetFont()->GetSize(" ").width / 2;
				break;
			case '$':
				// Show Gold Window
				ShowGoldWindow();
				break;
			case '!':
				// Text pause
				pause = true;
				break;
			case '^':
				// Force message close
				// The close happens at the end of the message, not where
				// the ^ is encountered
				kill_message = true;
				break;
			case '>':
				// Instant speed start
				instant_speed = true;
				break;
			case '<':
				// Instant speed stop
				instant_speed = false;
				break;
			case '.':
				// 1/4 second sleep
				if (instant_speed) break;
				sleep_until = Player::GetFrames() + 60 / 4;
				++text_index;
				return;
			case '|':
				// Second sleep
				if (instant_speed) break;
				sleep_until = Player::GetFrames() + 60;
				++text_index;
				return;
			case '\n':
			case '\f':
				// \ followed by linebreak, don't skip them
				--text_index;
				break;
			default:
				if (*text_index == escape_char) {
					// Show Escape Symbol
					contents->TextDraw(contents_x, contents_y, text_color, Player::escape_symbol);
					contents_x += contents->GetFont()->GetSize(Player::escape_symbol).width;
				}
			}
		} else if (*text_index == '$'
				   && std::distance(text_index, end) > 1
				   && std::isalpha(*std::next(text_index))) {
			// ExFont
			std::string const glyph(Utils::EncodeUTF(std::u32string(text_index, std::next(text_index, 2))));
			contents->TextDraw(contents_x, contents_y, text_color, glyph);
			contents_x += 12;
			++loop_count;
			++text_index;
		} else {
			std::string const glyph(Utils::EncodeUTF(std::u32string(text_index, std::next(text_index))));

			contents->TextDraw(contents_x, contents_y, text_color, glyph);
			int glyph_width = contents->GetFont()->GetSize(glyph).width;
			// Show full-width characters twice as slow as half-width characters
			if (glyph_width >= 12)
				loop_count++;
			contents_x += glyph_width;
		}

		++text_index;
	}
}
Ejemplo n.º 3
0
void Window_Message::UpdateMessage() {
	// Message Box Show Message rendering loop

	// Contains at what frame the sleep is over
	static int sleep_until = -1;
	bool instant_speed = false;

	if (Player::debug_flag && Input::IsPressed(Input::SHIFT)) {
		sleep_until = -1;
		instant_speed = true;
	}

	if (sleep_until > -1) {
		if (Player::GetFrames() >= sleep_until) {
			// Sleep over
			sleep_until = -1;
		} else {
			return;
		}
	}

	int loop_count = 0;
	int loop_max = speed_table[speed_modifier] == 0 ? 2 : 1;

	while (instant_speed || loop_count < loop_max) {
		// It's assumed that speed_modifier is between 0 and 20
		++speed_frame_counter;

		if (speed_table[speed_modifier] != 0 &&
			speed_table[speed_modifier] != speed_frame_counter) {
				break;
		}

		speed_frame_counter = 0;

		++loop_count;
		if (text_index == end) {
			FinishMessageProcessing();
			break;
		} else if (line_count == 4) {
			pause = true;
			new_page_after_pause = true;
			break;
		} else if (pause) {
			break;
		}

		if (*text_index == '\n') {
			instant_speed = false;
			InsertNewLine();
		} else if (*text_index == '\f') {
			instant_speed = false;
			++text_index;
			if (*text_index == '\n') {
				++text_index;
			}
			if (text_index != end) {
				pause = true;
				new_page_after_pause = true;
			}
			break;
		} else if (*text_index == escape_char && std::distance(text_index, end) > 1) {
			// Special message codes
			++text_index;

			std::string command_result;

			switch (tolower(*text_index)) {
			case 'c':
			case 'n':
			case 's':
			case 'v':
				// These commands support indirect access via \v[]
				command_result = ParseCommandCode();
				contents->TextDraw(contents_x, contents_y, text_color, command_result);
				contents_x += contents->GetFont()->GetSize(command_result).width;
				break;
			case '_':
				// Insert half size space
				contents_x += contents->GetFont()->GetSize(" ").width / 2;
				break;
			case '$':
				// Show Gold Window
				ShowGoldWindow();
				break;
			case '!':
				// Text pause
				pause = true;
				break;
			case '^':
				// Force message close
				// The close happens at the end of the message, not where
				// the ^ is encountered
				kill_message = true;
				break;
			case '>':
				// Instant speed start
				instant_speed = true;
				break;
			case '<':
				// Instant speed stop
				instant_speed = false;
				break;
			case '.':
				// 1/4 second sleep
				sleep_until = Player::GetFrames() + 60 / 4;
				++text_index;
				return;
				break;
			case '|':
				// Second sleep
				sleep_until = Player::GetFrames() + 60;
				++text_index;
				return;
				break;
			default:
				if (*text_index == escape_char) {
					// Show Escape Symbol
					contents->TextDraw(contents_x, contents_y, text_color, Player::escape_symbol);
					contents_x += contents->GetFont()->GetSize(Player::escape_symbol).width;
				}
			}
		} else if (*text_index == '$'
				   && std::distance(text_index, end) > 1
				   && std::isalpha(*boost::next(text_index))) {
			// ExFont
			contents->TextDraw(contents_x, contents_y, text_color,
							   std::string(text_index.base(), boost::next(text_index, 2).base()));
			contents_x += 12;
			++text_index;
		} else {
			std::string const glyph(text_index.base(), boost::next(text_index).base());

			contents->TextDraw(contents_x, contents_y, text_color, glyph);
			contents_x += contents->GetFont()->GetSize(glyph).width;
		}

		++text_index;
	}
	loop_count = 0;
}