1 /*
2  * This file is part of EasyRPG Player.
3  *
4  * EasyRPG Player is free software: you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation, either version 3 of the License, or
7  * (at your option) any later version.
8  *
9  * EasyRPG Player is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with EasyRPG Player. If not, see <http://www.gnu.org/licenses/>.
16  */
17 
18 // Headers
19 #include <sstream>
20 #include "game_message.h"
21 #include "player.h"
22 #include "window_battlemessage.h"
23 #include "bitmap.h"
24 #include "font.h"
25 #include "utils.h"
26 #include "output.h"
27 
Window_BattleMessage(int ix,int iy,int iwidth,int iheight)28 Window_BattleMessage::Window_BattleMessage(int ix, int iy, int iwidth, int iheight) :
29 	Window_Base(ix, iy, iwidth, iheight)
30 {
31 	SetContents(Bitmap::Create(width - 20, height - 16));
32 
33 	SetVisible(false);
34 	// Above other windows but below the messagebox
35 	SetZ(Priority_Window + 50);
36 }
37 
Push(StringView message)38 void Window_BattleMessage::Push(StringView message) {
39 #ifdef EP_DEBUG_BATTLE2K_MESSAGE
40 	Output::Debug("Battle2k Message Push \"{}\"", message);
41 #endif
42 	Utils::ForEachLine(message, [this](StringView line)
43 			{ PushLine(line); });
44 }
45 
PushLine(StringView line)46 void Window_BattleMessage::PushLine(StringView line) {
47 	if (Player::IsRPG2kE()) {
48 		Game_Message::WordWrap(
49 				line,
50 				GetWidth() - 20,
51 				[this](StringView wrap_line) {
52 					lines.push_back(std::string(wrap_line));
53 				}
54 				);
55 	}
56 	else {
57 		lines.push_back(std::string(line));
58 	}
59 
60 	needs_refresh = true;
61 }
62 
PushWithSubject(StringView message,StringView subject)63 void Window_BattleMessage::PushWithSubject(StringView message, StringView subject) {
64 	if (Player::IsRPG2kE()) {
65 		Push(Utils::ReplacePlaceholders(
66 			message,
67 			Utils::MakeArray('S'),
68 			Utils::MakeSvArray(subject)
69 		));
70 	}
71 	else {
72 		Push(std::string(subject) + std::string(message));
73 	}
74 	needs_refresh = true;
75 }
76 
Pop()77 void Window_BattleMessage::Pop() {
78 #ifdef EP_DEBUG_BATTLE2K_MESSAGE
79 	Output::Debug("Battle2k Message Pop");
80 #endif
81 	lines.pop_back();
82 	needs_refresh = true;
83 	if (GetIndex() > (int)lines.size()) {
84 		SetIndex(lines.size());
85 	}
86 }
87 
PopUntil(int line_number)88 void Window_BattleMessage::PopUntil(int line_number) {
89 #ifdef EP_DEBUG_BATTLE2K_MESSAGE
90 	Output::Debug("Battle2k Message PopUntil {}", line_number);
91 #endif
92 	while (static_cast<int>(lines.size()) > line_number) {
93 		lines.pop_back();
94 	}
95 	needs_refresh = true;
96 }
97 
Clear()98 void Window_BattleMessage::Clear() {
99 #ifdef EP_DEBUG_BATTLE2K_MESSAGE
100 	Output::Debug("Battle2k Message Clear");
101 #endif
102 	lines.clear();
103 	SetIndex(0);
104 	needs_refresh = true;
105 }
106 
ScrollToEnd()107 void Window_BattleMessage::ScrollToEnd() {
108 	const auto old_index = index;
109 	if (lines.size() > linesPerPage) {
110 		index = lines.size() - linesPerPage;
111 	} else {
112 		index = 0;
113 	}
114 	needs_refresh |= (index != old_index);
115 }
116 
Refresh()117 void Window_BattleMessage::Refresh() {
118 	contents->Clear();
119 
120 	int i = GetIndex();
121 	const auto ed = std::min(i + linesPerPage, (int)lines.size());
122 	int y = 2;
123 	for (; i < ed; ++i) {
124 		contents->TextDraw(0, y, Font::ColorDefault, lines[i]);
125 		y+= 16;
126 	}
127 	needs_refresh = false;
128 }
129 
Update()130 void Window_BattleMessage::Update() {
131 	Window_Base::Update();
132 	if (needs_refresh) {
133 		Refresh();
134 	}
135 }
136 
GetLineCount()137 int Window_BattleMessage::GetLineCount() {
138 	return (int)lines.size();
139 }
140 
IsPageFilled()141 bool Window_BattleMessage::IsPageFilled() {
142 	return (lines.size() - GetIndex()) >= linesPerPage;
143 }
144