1 /*
2  * Copyright 2010-2014 OpenXcom Developers.
3  *
4  * This file is part of OpenXcom.
5  *
6  * OpenXcom is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation, either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * OpenXcom is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with OpenXcom.  If not, see <http://www.gnu.org/licenses/>.
18  */
19 
20 #include <sstream>
21 #include <algorithm>
22 #include "Ufopaedia.h"
23 #include "ArticleStateItem.h"
24 #include "../Ruleset/Ruleset.h"
25 #include "../Ruleset/ArticleDefinition.h"
26 #include "../Ruleset/RuleItem.h"
27 #include "../Engine/Game.h"
28 #include "../Engine/Palette.h"
29 #include "../Engine/Surface.h"
30 #include "../Engine/SurfaceSet.h"
31 #include "../Engine/Language.h"
32 #include "../Resource/ResourcePack.h"
33 #include "../Interface/Text.h"
34 #include "../Interface/TextButton.h"
35 #include "../Interface/TextList.h"
36 
37 namespace OpenXcom
38 {
39 
ArticleStateItem(Game * game,ArticleDefinitionItem * defs)40 	ArticleStateItem::ArticleStateItem(Game *game, ArticleDefinitionItem *defs) : ArticleState(game, defs->id)
41 	{
42 		RuleItem *item = _game->getRuleset()->getItem(defs->id);
43 
44 		// add screen elements
45 		_txtTitle = new Text(148, 32, 5, 24);
46 
47 		// Set palette
48 		setPalette("PAL_BATTLEPEDIA");
49 
50 		ArticleState::initLayout();
51 
52 		// add other elements
53 		add(_txtTitle);
54 
55 		// Set up objects
56 		_game->getResourcePack()->getSurface("BACK08.SCR")->blit(_bg);
57 		_btnOk->setColor(Palette::blockOffset(9));
58 		_btnPrev->setColor(Palette::blockOffset(9));
59 		_btnNext->setColor(Palette::blockOffset(9));
60 
61 		_txtTitle->setColor(Palette::blockOffset(14)+15);
62 		_txtTitle->setBig();
63 		_txtTitle->setWordWrap(true);
64 		_txtTitle->setText(tr(defs->title));
65 
66 		// IMAGE
67 		_image = new Surface(32, 48, 157, 5);
68 		add(_image);
69 
70 		item->drawHandSprite(_game->getResourcePack()->getSurfaceSet("BIGOBS.PCK"), _image);
71 
72 		std::vector<std::string> *ammo_data = item->getCompatibleAmmo();
73 
74 		// SHOT STATS TABLE (for firearms only)
75 		if (item->getBattleType() == BT_FIREARM)
76 		{
77 			_txtShotType = new Text(100, 17, 8, 66);
78 			add(_txtShotType);
79 			_txtShotType->setColor(Palette::blockOffset(14)+15);
80 			_txtShotType->setWordWrap(true);
81 			_txtShotType->setText(tr("STR_SHOT_TYPE"));
82 
83 			_txtAccuracy = new Text(50, 17, 104, 66);
84 			add(_txtAccuracy);
85 			_txtAccuracy->setColor(Palette::blockOffset(14)+15);
86 			_txtAccuracy->setWordWrap(true);
87 			_txtAccuracy->setText(tr("STR_ACCURACY_UC"));
88 
89 			_txtTuCost = new Text(60, 17, 158, 66);
90 			add(_txtTuCost);
91 			_txtTuCost->setColor(Palette::blockOffset(14)+15);
92 			_txtTuCost->setWordWrap(true);
93 			_txtTuCost->setText(tr("STR_TIME_UNIT_COST"));
94 
95 			_lstInfo = new TextList(204, 55, 8, 82);
96 			add(_lstInfo);
97 
98 			_lstInfo->setColor(Palette::blockOffset(15)+4); // color for %-data!
99 			_lstInfo->setColumns(3, 100, 52, 52);
100 			_lstInfo->setBig();
101 
102 			int current_row = 0;
103 			if (item->getTUAuto()>0)
104 			{
105 				std::wstring tu = Text::formatPercentage(item->getTUAuto());
106 				if (item->getFlatRate())
107 				{
108 					tu.erase(tu.end() - 1);
109 				}
110 				_lstInfo->addRow(3,
111 								 tr("STR_SHOT_TYPE_AUTO").c_str(),
112 								 Text::formatPercentage(item->getAccuracyAuto()).c_str(),
113 								 tu.c_str());
114 				_lstInfo->setCellColor(current_row, 0, Palette::blockOffset(14)+15);
115 				current_row++;
116 			}
117 
118 			if (item->getTUSnap()>0)
119 			{
120 				std::wstring tu = Text::formatPercentage(item->getTUSnap());
121 				if (item->getFlatRate())
122 				{
123 					tu.erase(tu.end() - 1);
124 				}
125 				_lstInfo->addRow(3,
126 								 tr("STR_SHOT_TYPE_SNAP").c_str(),
127 								 Text::formatPercentage(item->getAccuracySnap()).c_str(),
128 								 tu.c_str());
129 				_lstInfo->setCellColor(current_row, 0, Palette::blockOffset(14)+15);
130 				current_row++;
131 			}
132 
133 			if (item->getTUAimed()>0)
134 			{
135 				std::wstring tu = Text::formatPercentage(item->getTUAimed());
136 				if (item->getFlatRate())
137 				{
138 					tu.erase(tu.end() - 1);
139 				}
140 				_lstInfo->addRow(3,
141 								 tr("STR_SHOT_TYPE_AIMED").c_str(),
142 								 Text::formatPercentage(item->getAccuracyAimed()).c_str(),
143 								 tu.c_str());
144 				_lstInfo->setCellColor(current_row, 0, Palette::blockOffset(14)+15);
145 				current_row++;
146 			}
147 
148 			// text_info is BELOW the info table
149 			_txtInfo = new Text((ammo_data->size()<3 ? 300 : 180), 56, 8, 138);
150 		}
151 		else
152 		{
153 			// text_info is larger and starts on top
154 			_txtInfo = new Text(300, 125, 8, 67);
155 		}
156 
157 		add(_txtInfo);
158 
159 		_txtInfo->setColor(Palette::blockOffset(14)+15);
160 		_txtInfo->setWordWrap(true);
161 		_txtInfo->setText(tr(defs->text));
162 
163 
164 		// AMMO column
165 		std::wostringstream ss;
166 
167 		for (int i = 0; i<3; ++i)
168 		{
169 			_txtAmmoType[i] = new Text(82, 16, 194, 20 + i*49);
170 			add(_txtAmmoType[i]);
171 			_txtAmmoType[i]->setColor(Palette::blockOffset(14)+15);
172 			_txtAmmoType[i]->setAlign(ALIGN_CENTER);
173 			_txtAmmoType[i]->setVerticalAlign(ALIGN_MIDDLE);
174 			_txtAmmoType[i]->setWordWrap(true);
175 
176 			_txtAmmoDamage[i] = new Text(82, 17, 194, 40 + i*49);
177 			add(_txtAmmoDamage[i]);
178 			_txtAmmoDamage[i]->setColor(Palette::blockOffset(2));
179 			_txtAmmoDamage[i]->setAlign(ALIGN_CENTER);
180 			_txtAmmoDamage[i]->setBig();
181 
182 			_imageAmmo[i] = new Surface(32, 48, 280, 16 + i*49);
183 			add(_imageAmmo[i]);
184 		}
185 
186 		switch (item->getBattleType())
187 		{
188 			case BT_FIREARM:
189 				_txtDamage = new Text(82, 10, 194, 7);
190 				add(_txtDamage);
191 				_txtDamage->setColor(Palette::blockOffset(14)+15);
192 				_txtDamage->setAlign(ALIGN_CENTER);
193 				_txtDamage->setText(tr("STR_DAMAGE_UC"));
194 
195 				_txtAmmo = new Text(50, 10, 268, 7);
196 				add(_txtAmmo);
197 				_txtAmmo->setColor(Palette::blockOffset(14)+15);
198 				_txtAmmo->setAlign(ALIGN_CENTER);
199 				_txtAmmo->setText(tr("STR_AMMO"));
200 
201 				if (ammo_data->empty())
202 				{
203 					_txtAmmoType[0]->setText(tr(getDamageTypeText(item->getDamageType())));
204 
205 					ss.str(L"");ss.clear();
206 					ss << item->getPower();
207 					if (item->getShotgunPellets())
208 					{
209 						ss << L"x" << item->getShotgunPellets();
210 					}
211 					_txtAmmoDamage[0]->setText(ss.str());
212 				}
213 				else
214 				{
215 					for (size_t i = 0; i < std::min(ammo_data->size(), (size_t)3); ++i)
216 					{
217 						ArticleDefinition *ammo_article = _game->getRuleset()->getUfopaediaArticle((*ammo_data)[i]);
218 						if (Ufopaedia::isArticleAvailable(_game->getSavedGame(), ammo_article))
219 						{
220 							RuleItem *ammo_rule = _game->getRuleset()->getItem((*ammo_data)[i]);
221 							_txtAmmoType[i]->setText(tr(getDamageTypeText(ammo_rule->getDamageType())));
222 
223 							ss.str(L"");ss.clear();
224 							ss << ammo_rule->getPower();
225 							if (ammo_rule->getShotgunPellets())
226 							{
227 								ss << L"x" << ammo_rule->getShotgunPellets();
228 							}
229 							_txtAmmoDamage[i]->setText(ss.str());
230 
231 							ammo_rule->drawHandSprite(_game->getResourcePack()->getSurfaceSet("BIGOBS.PCK"), _imageAmmo[i]);
232 						}
233 					}
234 				}
235 				break;
236 			case BT_AMMO:
237 			case BT_GRENADE:
238 			case BT_PROXIMITYGRENADE:
239 			case BT_MELEE:
240 				_txtDamage = new Text(82, 10, 194, 7);
241 				add(_txtDamage);
242 				_txtDamage->setColor(Palette::blockOffset(14)+15);
243 				_txtDamage->setAlign(ALIGN_CENTER);
244 				_txtDamage->setText(tr("STR_DAMAGE_UC"));
245 
246 				_txtAmmoType[0]->setText(tr(getDamageTypeText(item->getDamageType())));
247 
248 				ss.str(L"");ss.clear();
249 				ss << item->getPower();
250 				_txtAmmoDamage[0]->setText(ss.str());
251 				break;
252 			default: break;
253 		}
254 
255 		centerAllSurfaces();
256 	}
257 
~ArticleStateItem()258 	ArticleStateItem::~ArticleStateItem()
259 	{}
260 
261 }
262