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 <iomanip>
21 #include "window_varlist.h"
22 #include "game_switches.h"
23 #include "game_variables.h"
24 #include "bitmap.h"
25 #include <lcf/data.h>
26 #include "output.h"
27 #include <lcf/reader_util.h>
28 #include "game_party.h"
29 #include "game_map.h"
30 
Window_VarList(std::vector<std::string> commands)31 Window_VarList::Window_VarList(std::vector<std::string> commands) :
32 Window_Command(commands, 224, 10) {
33 	SetX(0);
34 	SetY(32);
35 	SetHeight(176);
36 	SetWidth(224);
37 }
38 
~Window_VarList()39 Window_VarList::~Window_VarList() {
40 
41 }
42 
Refresh()43 void Window_VarList::Refresh() {
44 	contents->Clear();
45 	for (int i = 0; i < 10; i++) {
46 		DrawItemValue(i);
47 	}
48 }
49 
DrawItemValue(int index)50 void Window_VarList::DrawItemValue(int index){
51 	if (!DataIsValid(first_var+index)) {
52 		return;
53 	}
54 	switch (mode) {
55 		case eSwitch:
56 			{
57 				auto value = Main_Data::game_switches->Get(first_var + index);
58 				auto font = (!value) ? Font::ColorCritical : Font::ColorDefault;
59 				DrawItem(index, Font::ColorDefault);
60 				contents->TextDraw(GetWidth() - 16, 16 * index + 2, font, value ? "[ON]" : "[OFF]", Text::AlignRight);
61 			}
62 			break;
63 		case eVariable:
64 			{
65 				auto value = Main_Data::game_variables->Get(first_var + index);
66 				auto font = (value < 0) ? Font::ColorCritical : Font::ColorDefault;
67 				DrawItem(index, Font::ColorDefault);
68 				contents->TextDraw(GetWidth() - 16, 16 * index + 2, font, std::to_string(value), Text::AlignRight);
69 			}
70 			break;
71 		case eItem:
72 			{
73 				auto value = Main_Data::game_party->GetItemCount(first_var + index);
74 				auto font = (value == 0) ? Font::ColorCritical : Font::ColorDefault;
75 				DrawItem(index, Font::ColorDefault);
76 				contents->TextDraw(GetWidth() - 16, 16 * index + 2, font, std::to_string(value), Text::AlignRight);
77 			}
78 			break;
79 		case eTroop:
80 		case eMap:
81 		case eHeal:
82 		case eCommonEvent:
83 		case eMapEvent:
84 			{
85 				DrawItem(index, Font::ColorDefault);
86 				contents->TextDraw(GetWidth() - 16, 16 * index + 2, Font::ColorDefault, "", Text::AlignRight);
87 			}
88 			break;
89 		case eLevel:
90 			{
91 				auto value = Main_Data::game_party->GetActors()[first_var + index - 1]->GetLevel();
92 				DrawItem(index, Font::ColorDefault);
93 				contents->TextDraw(GetWidth() - 16, 16 * index + 2, Font::ColorDefault, std::to_string(value), Text::AlignRight);
94 			}
95 			break;
96 		case eNone:
97 			break;
98 	}
99 }
100 
UpdateList(int first_value)101 void Window_VarList::UpdateList(int first_value){
102 	static std::stringstream ss;
103 	first_var = first_value;
104 	int map_idx = 0;
105 	if (mode == eMap) {
106 		auto iter = std::lower_bound(lcf::Data::treemap.maps.begin(), lcf::Data::treemap.maps.end(), first_value,
107 				[](const lcf::rpg::MapInfo& l, int r) { return l.ID < r; });
108 		map_idx = iter - lcf::Data::treemap.maps.begin();
109 	}
110 	for (int i = 0; i < 10; i++){
111 		if (!DataIsValid(first_var+i)) {
112 			continue;
113 		}
114 		ss.str("");
115 		ss << std::setfill('0') << std::setw(4) << (first_value + i) << ": ";
116 		switch (mode) {
117 			case eSwitch:
118 				ss << Main_Data::game_switches->GetName(first_value + i);
119 				break;
120 			case eVariable:
121 				ss << Main_Data::game_variables->GetName(first_value + i);
122 				break;
123 			case eItem:
124 				ss << lcf::ReaderUtil::GetElement(lcf::Data::items, first_value+i)->name;
125 				break;
126 			case eTroop:
127 				ss << lcf::ReaderUtil::GetElement(lcf::Data::troops, first_value+i)->name;
128 				break;
129 			case eMap:
130 				if (map_idx < static_cast<int>(lcf::Data::treemap.maps.size())) {
131 					auto& map = lcf::Data::treemap.maps[map_idx];
132 					if (map.ID == first_value + i) {
133 						ss << map.name;
134 						++map_idx;
135 					}
136 				}
137 				break;
138 			case eHeal:
139 				if (first_value + i == 1) {
140 					ss << "Party";
141 				} else {
142 					auto* actor = Main_Data::game_party->GetActors()[first_value + i-2];
143 					ss << actor->GetName() << " " << actor->GetHp() << " / " << actor->GetMaxHp();
144 				}
145 				break;
146 			case eLevel:
147 				if (first_value + i >= 1) {
148 					auto* actor = Main_Data::game_party->GetActors()[first_value + i-1];
149 					ss << actor->GetName();
150 				}
151 				break;
152 			case eCommonEvent:
153 				ss << lcf::ReaderUtil::GetElement(lcf::Data::commonevents, first_value+i)->name;
154 				break;
155 			case eMapEvent:
156 				ss << Game_Map::GetEvent(first_value+i)->GetName();
157 				break;
158 			default:
159 				break;
160 		}
161 		this->SetItemText(i, ss.str());
162 	}
163 }
164 
SetMode(Mode mode)165 void Window_VarList::SetMode(Mode mode) {
166 	this->mode = mode;
167 	SetVisible((mode != eNone));
168 	Refresh();
169 }
170 
DataIsValid(int range_index)171 bool Window_VarList::DataIsValid(int range_index) {
172 	switch (mode) {
173 		case eSwitch:
174 			return Main_Data::game_switches->IsValid(range_index);
175 		case eVariable:
176 			return Main_Data::game_variables->IsValid(range_index);
177 		case eItem:
178 			return range_index > 0 && range_index <= static_cast<int>(lcf::Data::items.size());
179 		case eTroop:
180 			return range_index > 0 && range_index <= static_cast<int>(lcf::Data::troops.size());
181 		case eMap:
182 			return range_index > 0 && range_index <= (lcf::Data::treemap.maps.size() > 0 ? lcf::Data::treemap.maps.back().ID : 0);
183 		case eHeal:
184 			return range_index > 0 && range_index <= static_cast<int>(Main_Data::game_party->GetActors().size()) + 1;
185 		case eLevel:
186 			return range_index > 0 && range_index <= static_cast<int>(Main_Data::game_party->GetActors().size());
187 		case eCommonEvent:
188 			return range_index > 0 && range_index <= static_cast<int>(lcf::Data::commonevents.size());
189 		case eMapEvent:
190 			return Game_Map::GetEvent(range_index) != nullptr;
191 		default:
192 			break;
193 	}
194 	return false;
195 }
196 
197