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