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 #include "GeoscapeCraftState.h"
20 #include <sstream>
21 #include "../Engine/Game.h"
22 #include "../Resource/ResourcePack.h"
23 #include "../Engine/Language.h"
24 #include "../Engine/Palette.h"
25 #include "../Interface/TextButton.h"
26 #include "../Interface/Window.h"
27 #include "../Interface/Text.h"
28 #include "../Savegame/Base.h"
29 #include "../Savegame/Craft.h"
30 #include "../Ruleset/RuleCraft.h"
31 #include "../Savegame/CraftWeapon.h"
32 #include "../Ruleset/RuleCraftWeapon.h"
33 #include "../Savegame/Target.h"
34 #include "../Savegame/Ufo.h"
35 #include "../Savegame/SavedGame.h"
36 #include "../Savegame/Waypoint.h"
37 #include "SelectDestinationState.h"
38 #include "../Engine/Options.h"
39 
40 namespace OpenXcom
41 {
42 
43 /**
44  * Initializes all the elements in the Geoscape Craft window.
45  * @param game Pointer to the core game.
46  * @param craft Pointer to the craft to display.
47  * @param globe Pointer to the Geoscape globe.
48  * @param waypoint Pointer to the last UFO position (if redirecting the craft).
49  */
GeoscapeCraftState(Game * game,Craft * craft,Globe * globe,Waypoint * waypoint)50 GeoscapeCraftState::GeoscapeCraftState(Game *game, Craft *craft, Globe *globe, Waypoint *waypoint) : State(game), _craft(craft), _globe(globe), _waypoint(waypoint)
51 {
52 	_screen = false;
53 
54 	// Create objects
55 	_window = new Window(this, 240, 184, 8, 8, POPUP_BOTH);
56 	_btnBase = new TextButton(192, 12, 32, 124);
57 	_btnTarget = new TextButton(192, 12, 32, 140);
58 	_btnPatrol = new TextButton(192, 12, 32, 156);
59 	_btnCancel = new TextButton(192, 12, 32, 172);
60 	_txtTitle = new Text(210, 17, 32, 20);
61 	_txtStatus = new Text(210, 17, 32, 36);
62 	_txtBase = new Text(210, 9, 32, 52);
63 	_txtSpeed = new Text(210, 9, 32, 60);
64 	_txtMaxSpeed = new Text(210, 9, 32, 68);
65 	_txtAltitude = new Text(210, 9, 32, 76);
66 	_txtFuel = new Text(130, 9, 32, 84);
67 	_txtDamage = new Text(80, 9, 164, 84);
68 	_txtW1Name = new Text(130, 9, 32, 92);
69 	_txtW1Ammo = new Text(80, 9, 164, 92);
70 	_txtW2Name = new Text(130, 9, 32, 100);
71 	_txtW2Ammo = new Text(80, 9, 164, 100);
72 	_txtRedirect = new Text(230, 17, 13, 108);
73 	_txtSoldier = new Text(60, 9, 164, 68);
74 	_txtHWP = new Text(80, 9, 164, 76);
75 
76 	// Set palette
77 	setPalette("PAL_GEOSCAPE", 4);
78 
79 	add(_window);
80 	add(_btnBase);
81 	add(_btnTarget);
82 	add(_btnPatrol);
83 	add(_btnCancel);
84 	add(_txtTitle);
85 	add(_txtStatus);
86 	add(_txtBase);
87 	add(_txtSpeed);
88 	add(_txtMaxSpeed);
89 	add(_txtAltitude);
90 	add(_txtFuel);
91 	add(_txtDamage);
92 	add(_txtW1Name);
93 	add(_txtW1Ammo);
94 	add(_txtW2Name);
95 	add(_txtW2Ammo);
96 	add(_txtRedirect);
97 	add(_txtSoldier);
98 	add(_txtHWP);
99 
100 	centerAllSurfaces();
101 
102 	// Set up objects
103 	_window->setColor(Palette::blockOffset(15)-1);
104 	_window->setBackground(_game->getResourcePack()->getSurface("BACK12.SCR"));
105 
106 	_btnBase->setColor(Palette::blockOffset(8)+5);
107 	_btnBase->setText(tr("STR_RETURN_TO_BASE"));
108 	_btnBase->onMouseClick((ActionHandler)&GeoscapeCraftState::btnBaseClick);
109 
110 	_btnTarget->setColor(Palette::blockOffset(8)+5);
111 	_btnTarget->setText(tr("STR_SELECT_NEW_TARGET"));
112 	_btnTarget->onMouseClick((ActionHandler)&GeoscapeCraftState::btnTargetClick);
113 
114 	_btnPatrol->setColor(Palette::blockOffset(8)+5);
115 	_btnPatrol->setText(tr("STR_PATROL"));
116 	_btnPatrol->onMouseClick((ActionHandler)&GeoscapeCraftState::btnPatrolClick);
117 
118 	_btnCancel->setColor(Palette::blockOffset(8)+5);
119 	_btnCancel->setText(tr("STR_CANCEL_UC"));
120 	_btnCancel->onMouseClick((ActionHandler)&GeoscapeCraftState::btnCancelClick);
121 	_btnCancel->onKeyboardPress((ActionHandler)&GeoscapeCraftState::btnCancelClick, Options::keyCancel);
122 
123 	_txtTitle->setColor(Palette::blockOffset(15)-1);
124 	_txtTitle->setBig();
125 	_txtTitle->setText(_craft->getName(_game->getLanguage()));
126 
127 	_txtStatus->setColor(Palette::blockOffset(15)-1);
128 	_txtStatus->setSecondaryColor(Palette::blockOffset(8)+10);
129 	_txtStatus->setWordWrap(true);
130 	std::wstring status;
131 	if (_waypoint != 0)
132 	{
133 		status = tr("STR_INTERCEPTING_UFO").arg(_waypoint->getId());
134 	}
135 	else if (_craft->getLowFuel())
136 	{
137 		status = tr("STR_LOW_FUEL_RETURNING_TO_BASE");
138 	}
139 	else if (_craft->getDestination() == 0)
140 	{
141 		status = tr("STR_PATROLLING");
142 	}
143 	else if (_craft->getDestination() == (Target*)_craft->getBase())
144 	{
145 		status = tr("STR_RETURNING_TO_BASE");
146 	}
147 	else
148 	{
149 		Ufo *u = dynamic_cast<Ufo*>(_craft->getDestination());
150 		if (u != 0)
151 		{
152 			if (_craft->isInDogfight())
153 			{
154 				status = tr("STR_TAILING_UFO");
155 			}
156 			else if (u->getStatus() == Ufo::FLYING)
157 			{
158 				status = tr("STR_INTERCEPTING_UFO").arg(u->getId());
159 			}
160 			else
161 			{
162 				status = tr("STR_DESTINATION_UC_").arg(u->getName(_game->getLanguage()));
163 			}
164 		}
165 		else
166 		{
167 			status = tr("STR_DESTINATION_UC_").arg(_craft->getDestination()->getName(_game->getLanguage()));
168 		}
169 	}
170 	_txtStatus->setText(tr("STR_STATUS_").arg(status));
171 
172 	_txtBase->setColor(Palette::blockOffset(15)-1);
173 	_txtBase->setSecondaryColor(Palette::blockOffset(8)+5);
174 	_txtBase->setText(tr("STR_BASE_UC").arg(_craft->getBase()->getName()));
175 
176 	_txtSpeed->setColor(Palette::blockOffset(15)-1);
177 	_txtSpeed->setSecondaryColor(Palette::blockOffset(8)+5);
178 	_txtSpeed->setText(tr("STR_SPEED_").arg(Text::formatNumber(_craft->getSpeed())));
179 
180 	_txtMaxSpeed->setColor(Palette::blockOffset(15)-1);
181 	_txtMaxSpeed->setSecondaryColor(Palette::blockOffset(8)+5);
182 	_txtMaxSpeed->setText(tr("STR_MAXIMUM_SPEED_UC").arg(Text::formatNumber(_craft->getRules()->getMaxSpeed())));
183 
184 	_txtAltitude->setColor(Palette::blockOffset(15)-1);
185 	_txtAltitude->setSecondaryColor(Palette::blockOffset(8)+5);
186 	std::string altitude = _craft->getAltitude() == "STR_GROUND" ? "STR_GROUNDED" : _craft->getAltitude();
187 	_txtAltitude->setText(tr("STR_ALTITUDE_").arg(tr(altitude)));
188 
189 	_txtFuel->setColor(Palette::blockOffset(15)-1);
190 	_txtFuel->setSecondaryColor(Palette::blockOffset(8)+5);
191 	_txtFuel->setText(tr("STR_FUEL").arg(Text::formatPercentage(_craft->getFuelPercentage())));
192 
193 	_txtDamage->setColor(Palette::blockOffset(15)-1);
194 	_txtDamage->setSecondaryColor(Palette::blockOffset(8)+5);
195 	_txtDamage->setText(tr("STR_DAMAGE_UC_").arg(Text::formatPercentage(_craft->getDamagePercentage())));
196 
197 	_txtW1Name->setColor(Palette::blockOffset(15)-1);
198 	_txtW1Name->setSecondaryColor(Palette::blockOffset(8)+5);
199 
200 	_txtW1Ammo->setColor(Palette::blockOffset(15)-1);
201 	_txtW1Ammo->setSecondaryColor(Palette::blockOffset(8)+5);
202 
203 	if (_craft->getRules()->getWeapons() > 0 && _craft->getWeapons()->at(0) != 0)
204 	{
205 		CraftWeapon *w1 = _craft->getWeapons()->at(0);
206 		_txtW1Name->setText(tr("STR_WEAPON_ONE").arg(tr(w1->getRules()->getType())));
207 		_txtW1Ammo->setText(tr("STR_ROUNDS_").arg(w1->getAmmo()));
208 	}
209 	else
210 	{
211 		_txtW1Name->setText(tr("STR_WEAPON_ONE").arg(tr("STR_NONE_UC")));
212 		_txtW1Ammo->setVisible(false);
213 	}
214 
215 	_txtW2Name->setColor(Palette::blockOffset(15)-1);
216 	_txtW2Name->setSecondaryColor(Palette::blockOffset(8)+5);
217 
218 	_txtW2Ammo->setColor(Palette::blockOffset(15)-1);
219 	_txtW2Ammo->setSecondaryColor(Palette::blockOffset(8)+5);
220 
221 	if (_craft->getRules()->getWeapons() > 1 && _craft->getWeapons()->at(1) != 0)
222 	{
223 		CraftWeapon *w2 = _craft->getWeapons()->at(1);
224 		_txtW2Name->setText(tr("STR_WEAPON_TWO").arg(tr(w2->getRules()->getType())));
225 		_txtW2Ammo->setText(tr("STR_ROUNDS_").arg(w2->getAmmo()));
226 	}
227 	else
228 	{
229 		_txtW2Name->setText(tr("STR_WEAPON_TWO").arg(tr("STR_NONE_UC")));
230 		_txtW2Ammo->setVisible(false);
231 	}
232 
233 	_txtRedirect->setColor(Palette::blockOffset(15)-1);
234 	_txtRedirect->setBig();
235 	_txtRedirect->setAlign(ALIGN_CENTER);
236 	_txtRedirect->setText(tr("STR_REDIRECT_CRAFT"));
237 
238 	_txtSoldier->setColor(Palette::blockOffset(15)-1);
239 	_txtSoldier->setSecondaryColor(Palette::blockOffset(8)+5);
240 	std::wostringstream ss11;
241 	ss11 << tr("STR_SOLDIERS_UC") << ">" << L'\x01' << _craft->getNumSoldiers();
242 	_txtSoldier->setText(ss11.str());
243 
244 	_txtHWP->setColor(Palette::blockOffset(15)-1);
245 	_txtHWP->setSecondaryColor(Palette::blockOffset(8)+5);
246 	std::wostringstream ss12;
247 	ss12 << tr("STR_HWPS") << ">" << L'\x01' << _craft->getNumVehicles();
248 	_txtHWP->setText(ss12.str());
249 
250 	if (_waypoint == 0)
251 	{
252 		_txtRedirect->setVisible(false);
253 	}
254 	else
255 	{
256 		_btnCancel->setText(tr("STR_GO_TO_LAST_KNOWN_UFO_POSITION"));
257 	}
258 
259 	if (_craft->getLowFuel())
260 	{
261 		_btnBase->setVisible(false);
262 		_btnTarget->setVisible(false);
263 		_btnPatrol->setVisible(false);
264 	}
265 
266 	if (_craft->getRules()->getSoldiers() == 0)
267 		_txtSoldier->setVisible(false);
268 	if (_craft->getRules()->getVehicles() == 0)
269 		_txtHWP->setVisible(false);
270 }
271 
272 /**
273  *
274  */
~GeoscapeCraftState()275 GeoscapeCraftState::~GeoscapeCraftState()
276 {
277 
278 }
279 
280 /**
281  * Returns the craft back to its base.
282  * @param action Pointer to an action.
283  */
btnBaseClick(Action *)284 void GeoscapeCraftState::btnBaseClick(Action *)
285 {
286 	_game->popState();
287 	_craft->returnToBase();
288 	delete _waypoint;
289 }
290 
291 /**
292  * Changes the craft's target.
293  * @param action Pointer to an action.
294  */
btnTargetClick(Action *)295 void GeoscapeCraftState::btnTargetClick(Action *)
296 {
297 	_game->popState();
298 	_game->pushState(new SelectDestinationState(_game, _craft, _globe));
299 	delete _waypoint;
300 }
301 
302 /**
303  * Sets the craft to patrol the current location.
304  * @param action Pointer to an action.
305  */
btnPatrolClick(Action *)306 void GeoscapeCraftState::btnPatrolClick(Action *)
307 {
308 	_game->popState();
309 	_craft->setDestination(0);
310 	delete _waypoint;
311 }
312 
313 /**
314  * Closes the window.
315  * @param action Pointer to an action.
316  */
btnCancelClick(Action *)317 void GeoscapeCraftState::btnCancelClick(Action *)
318 {
319 	// Go to the last known UFO position
320 	if (_waypoint != 0)
321 	{
322 		_waypoint->setId(_game->getSavedGame()->getId("STR_WAYPOINT"));
323 		_game->getSavedGame()->getWaypoints()->push_back(_waypoint);
324 		_craft->setDestination(_waypoint);
325 	}
326 	// Cancel
327 	_game->popState();
328 }
329 
330 }
331