Exemplo n.º 1
0
void Window_Message::ApplyTextInsertingCommands() {
	text_index = text.end();
	end = text.end();

	// Contains already substitued \N actors to prevent endless recursion
	std::vector<int> replaced_actors;
	int actor_replacement_start = std::distance(text.begin(), end);

	if (!text.empty()) {
		// Move on first valid char
		--text_index;

		// Apply commands that insert text
		while (std::distance(text_index, text.begin()) <= -1) {
			char ch = tolower(*text_index--);
			switch (ch) {
			case 'n':
			case 'v':
			{
				if (*text_index != escape_char) {
					continue;
				}
				++text_index;

				auto start_code = text_index - 1;
				bool success;
				int parsed_num;
				std::u32string command_result = Utils::DecodeUTF32(ParseCommandCode(success, parsed_num));
				if (start_code < text.begin() + actor_replacement_start) {
					replaced_actors.clear();
				}

				if (!success || std::find(replaced_actors.begin(), replaced_actors.end(), parsed_num) != replaced_actors.end()) {
					text_index = start_code;
					continue;
				}

				if (ch == 'n') {
					replaced_actors.push_back(parsed_num);
					actor_replacement_start = std::min<int>(std::distance(text.begin(), start_code), actor_replacement_start);
				}

				text.replace(start_code, text_index + 1, command_result);
				// Start from the beginning, the inserted text might add new commands
				text_index = text.end();
				end = text.end();
				actor_replacement_start = std::min<int> (std::distance(text.begin(), end), actor_replacement_start);

				// Move on first valid char
				--text_index;

				break;
			}
			default:
				break;
			}
		}
	}
}
void Window_Message::StartMessageProcessing() {
	contents->Clear();
	text.clear();
	for (const std::string& line : Game_Message::texts) {
		text.append(Utils::DecodeUTF32(line)).append(1, U'\n');
	}
	Game_Message::texts.clear();
	item_max = min(4, Game_Message::choice_max);

	text_index = text.end();
	end = text.end();

	if (!text.empty()) {
		// Move on first valid char
		--text_index;

		// Apply commands that insert text
		while (std::distance(text_index, text.begin()) <= -1) {
			switch (tolower(*text_index--)) {
			case 'n':
			case 'v':
			{
				if (*text_index != escape_char) {
					continue;
				}
				++text_index;

				auto start_code = text_index - 1;
				bool success;
				std::u32string command_result = Utils::DecodeUTF32(ParseCommandCode(success));
				if (!success) {
					text_index = start_code - 2;
					continue;
				}
				text.replace(start_code, text_index + 1, command_result);
				// Start from the beginning, the inserted text might add new commands
				text_index = text.end();
				end = text.end();

				// Move on first valid char
				--text_index;

				break;
			}
			default:
				break;
			}
		}
	}

	text_index = text.begin();

	InsertNewPage();
}
Exemplo n.º 3
0
std::string Window_Message::ParseCommandCode(int call_depth) {
	int parameter;
	bool is_valid;
	// sub_code is used by chained arguments like \v[\v[1]]
	// In that case sub_code contains the result from \v[1]
	int sub_code = -1;
	uint32_t cmd_char = *text_index;
	if (std::distance(text_index, end) > 3 &&
		*boost::next(text_index, 2) == '\\' &&
		tolower(*boost::next(text_index, 3)) == 'v') {
		++(++(++text_index));
		// The result is an int value, str-to-int is safe in this case
		std::stringstream ss;
		ss << ParseCommandCode(++call_depth);
		ss >> sub_code;
	}
Exemplo n.º 4
0
void Window_Message::UpdateMessage() {
	// Message Box Show Message rendering loop

	// Contains at what frame the sleep is over
	static int sleep_until = -1;
	if (sleep_until > -1) {
		if (Graphics::GetFrameCount() >= sleep_until) {
			// Sleep over
			sleep_until = -1;
		} else {
			return;
		}
	}

	bool instant_speed = false;
	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;
		}

		if (*text_index == '\n') {
			instant_speed = false;
			InsertNewLine();
			if (pause) {
				break;
			}
		} 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 == '\\' && 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 '\\':
				// Show Backslash
				contents->TextDraw(contents_x, contents_y, text_color, std::string("\\"));
				contents_x += contents->GetFont()->GetSize("\\").width;
				break;
			case '_':
				// Insert half size space
				contents_x += contents->GetFont()->GetSize(" ").width / 2;
				break;
			case '$':
				// Show Gold Window
				gold_window->SetY(y == 0 ? 240 - 32 : 0);
				gold_window->Refresh();
				gold_window->SetOpenAnimation(5);
				gold_window->SetVisible(true);
				break;
			case '!':
				// Text pause
				pause = true;
				break;
			case '^':
				// Force message close
				// The close happens at the end of the message, not where
				// the ^ is encoutered
				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 = Graphics::GetFrameCount() + 60 / 4;
				++text_index;
				return;
				break;
			case '|':
				// Second sleep
				sleep_until = Graphics::GetFrameCount() + 60;
				++text_index;
				return;
				break;
			default:;
			}
		} 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;
}