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 "SelectDestinationState.h"
20 #include <cmath>
21 #include "../Engine/Game.h"
22 #include "../Engine/Screen.h"
23 #include "../Engine/Action.h"
24 #include "../Resource/ResourcePack.h"
25 #include "../Engine/Language.h"
26 #include "../Engine/Palette.h"
27 #include "../Engine/Surface.h"
28 #include "../Interface/Window.h"
29 #include "Globe.h"
30 #include "../Interface/Text.h"
31 #include "../Interface/TextButton.h"
32 #include "../Savegame/Waypoint.h"
33 #include "MultipleTargetsState.h"
34 #include "../Savegame/SavedGame.h"
35 #include "../Savegame/Craft.h"
36 #include "../Ruleset/RuleCraft.h"
37 #include "ConfirmCydoniaState.h"
38 #include "../Engine/Options.h"
39
40 namespace OpenXcom
41 {
42
43 /**
44 * Initializes all the elements in the Select Destination window.
45 * @param game Pointer to the core game.
46 * @param craft Pointer to the craft to target.
47 * @param globe Pointer to the Geoscape globe.
48 */
SelectDestinationState(Game * game,Craft * craft,Globe * globe)49 SelectDestinationState::SelectDestinationState(Game *game, Craft *craft, Globe *globe) : State(game), _craft(craft), _globe(globe)
50 {
51 int dx = _game->getScreen()->getDX();
52 int dy = _game->getScreen()->getDY();
53 _screen = false;
54
55 // Create objects
56 _btnRotateLeft = new InteractiveSurface(12, 10, 259 + dx * 2, 176 + dy);
57 _btnRotateRight = new InteractiveSurface(12, 10, 283 + dx * 2, 176 + dy);
58 _btnRotateUp = new InteractiveSurface(13, 12, 271 + dx * 2, 162 + dy);
59 _btnRotateDown = new InteractiveSurface(13, 12, 271 + dx * 2, 187 + dy);
60 _btnZoomIn = new InteractiveSurface(23, 23, 295 + dx * 2, 156 + dy);
61 _btnZoomOut = new InteractiveSurface(13, 17, 300 + dx * 2, 182 + dy);
62
63 _window = new Window(this, 256, 28, 0, 0);
64 _window->setX(dx);
65 _window->setDY(0);
66 _btnCancel = new TextButton(60, 12, 110 + dx, 8);
67 _btnCydonia = new TextButton(60, 12, 180 + dx, 8);
68 _txtTitle = new Text(100, 16, 10 + dx, 6);
69
70 // Set palette
71 setPalette("PAL_GEOSCAPE", 0);
72
73 add(_btnRotateLeft);
74 add(_btnRotateRight);
75 add(_btnRotateUp);
76 add(_btnRotateDown);
77 add(_btnZoomIn);
78 add(_btnZoomOut);
79
80 add(_window);
81 add(_btnCancel);
82 add(_btnCydonia);
83 add(_txtTitle);
84
85 // Set up objects
86 _globe->onMouseClick((ActionHandler)&SelectDestinationState::globeClick);
87
88 _btnRotateLeft->onMousePress((ActionHandler)&SelectDestinationState::btnRotateLeftPress);
89 _btnRotateLeft->onMouseRelease((ActionHandler)&SelectDestinationState::btnRotateLeftRelease);
90 _btnRotateLeft->onKeyboardPress((ActionHandler)&SelectDestinationState::btnRotateLeftPress, Options::keyGeoLeft);
91 _btnRotateLeft->onKeyboardRelease((ActionHandler)&SelectDestinationState::btnRotateLeftRelease, Options::keyGeoLeft);
92
93 _btnRotateRight->onMousePress((ActionHandler)&SelectDestinationState::btnRotateRightPress);
94 _btnRotateRight->onMouseRelease((ActionHandler)&SelectDestinationState::btnRotateRightRelease);
95 _btnRotateRight->onKeyboardPress((ActionHandler)&SelectDestinationState::btnRotateRightPress, Options::keyGeoRight);
96 _btnRotateRight->onKeyboardRelease((ActionHandler)&SelectDestinationState::btnRotateRightRelease, Options::keyGeoRight);
97
98 _btnRotateUp->onMousePress((ActionHandler)&SelectDestinationState::btnRotateUpPress);
99 _btnRotateUp->onMouseRelease((ActionHandler)&SelectDestinationState::btnRotateUpRelease);
100 _btnRotateUp->onKeyboardPress((ActionHandler)&SelectDestinationState::btnRotateUpPress, Options::keyGeoUp);
101 _btnRotateUp->onKeyboardRelease((ActionHandler)&SelectDestinationState::btnRotateUpRelease, Options::keyGeoUp);
102
103 _btnRotateDown->onMousePress((ActionHandler)&SelectDestinationState::btnRotateDownPress);
104 _btnRotateDown->onMouseRelease((ActionHandler)&SelectDestinationState::btnRotateDownRelease);
105 _btnRotateDown->onKeyboardPress((ActionHandler)&SelectDestinationState::btnRotateDownPress, Options::keyGeoDown);
106 _btnRotateDown->onKeyboardRelease((ActionHandler)&SelectDestinationState::btnRotateDownRelease, Options::keyGeoDown);
107
108 _btnZoomIn->onMouseClick((ActionHandler)&SelectDestinationState::btnZoomInLeftClick, SDL_BUTTON_LEFT);
109 _btnZoomIn->onMouseClick((ActionHandler)&SelectDestinationState::btnZoomInRightClick, SDL_BUTTON_RIGHT);
110 _btnZoomIn->onKeyboardPress((ActionHandler)&SelectDestinationState::btnZoomInLeftClick, Options::keyGeoZoomIn);
111
112 _btnZoomOut->onMouseClick((ActionHandler)&SelectDestinationState::btnZoomOutLeftClick, SDL_BUTTON_LEFT);
113 _btnZoomOut->onMouseClick((ActionHandler)&SelectDestinationState::btnZoomOutRightClick, SDL_BUTTON_RIGHT);
114 _btnZoomOut->onKeyboardPress((ActionHandler)&SelectDestinationState::btnZoomOutLeftClick, Options::keyGeoZoomOut);
115
116 // dirty hacks to get the rotate buttons to work in "classic" style
117 _btnRotateLeft->setListButton();
118 _btnRotateRight->setListButton();
119 _btnRotateUp->setListButton();
120 _btnRotateDown->setListButton();
121
122 _window->setColor(Palette::blockOffset(15)-1);
123 _window->setBackground(_game->getResourcePack()->getSurface("BACK01.SCR"));
124
125 _btnCancel->setColor(Palette::blockOffset(8)+5);
126 _btnCancel->setText(tr("STR_CANCEL_UC"));
127 _btnCancel->onMouseClick((ActionHandler)&SelectDestinationState::btnCancelClick);
128 _btnCancel->onKeyboardPress((ActionHandler)&SelectDestinationState::btnCancelClick, Options::keyCancel);
129
130 _txtTitle->setColor(Palette::blockOffset(15)-1);
131 _txtTitle->setText(tr("STR_SELECT_DESTINATION"));
132 _txtTitle->setVerticalAlign(ALIGN_MIDDLE);
133 _txtTitle->setWordWrap(true);
134
135 if (!_craft->getRules()->getSpacecraft() || !_game->getSavedGame()->isResearched("STR_CYDONIA_OR_BUST"))
136 {
137 _btnCydonia->setVisible(false);
138 }
139 else
140 {
141 _btnCydonia->setColor(Palette::blockOffset(8)+5);
142 _btnCydonia->setText(tr("STR_CYDONIA"));
143 _btnCydonia->onMouseClick((ActionHandler)&SelectDestinationState::btnCydoniaClick);
144 }
145 }
146
147 /**
148 *
149 */
~SelectDestinationState()150 SelectDestinationState::~SelectDestinationState()
151 {
152
153 }
154
155 /**
156 * Stop the globe movement.
157 */
init()158 void SelectDestinationState::init()
159 {
160 State::init();
161 _globe->rotateStop();
162 }
163
164 /**
165 * Runs the globe rotation timer.
166 */
think()167 void SelectDestinationState::think()
168 {
169 State::think();
170 _globe->think();
171 }
172
173 /**
174 * Handles the globe.
175 * @param action Pointer to an action.
176 */
handle(Action * action)177 void SelectDestinationState::handle(Action *action)
178 {
179 State::handle(action);
180 _globe->handle(action, this);
181 }
182
183 /**
184 * Processes any left-clicks for picking a target,
185 * or right-clicks to scroll the globe.
186 * @param action Pointer to an action.
187 */
globeClick(Action * action)188 void SelectDestinationState::globeClick(Action *action)
189 {
190 double lon, lat;
191 int mouseX = (int)floor(action->getAbsoluteXMouse()), mouseY = (int)floor(action->getAbsoluteYMouse());
192 _globe->cartToPolar(mouseX, mouseY, &lon, &lat);
193
194 // Ignore window clicks
195 if (mouseY < 28)
196 {
197 return;
198 }
199
200 // Clicking on a valid target
201 if (action->getDetails()->button.button == SDL_BUTTON_LEFT)
202 {
203 std::vector<Target*> v = _globe->getTargets(mouseX, mouseY, true);
204 if (v.empty())
205 {
206 Waypoint *w = new Waypoint();
207 w->setLongitude(lon);
208 w->setLatitude(lat);
209 v.push_back(w);
210 }
211 _game->pushState(new MultipleTargetsState(_game, v, _craft, 0));
212 }
213 }
214
215 /**
216 * Starts rotating the globe to the left.
217 * @param action Pointer to an action.
218 */
btnRotateLeftPress(Action *)219 void SelectDestinationState::btnRotateLeftPress(Action *)
220 {
221 _globe->rotateLeft();
222 }
223
224 /**
225 * Stops rotating the globe to the left.
226 * @param action Pointer to an action.
227 */
btnRotateLeftRelease(Action *)228 void SelectDestinationState::btnRotateLeftRelease(Action *)
229 {
230 _globe->rotateStopLon();
231 }
232
233 /**
234 * Starts rotating the globe to the right.
235 * @param action Pointer to an action.
236 */
btnRotateRightPress(Action *)237 void SelectDestinationState::btnRotateRightPress(Action *)
238 {
239 _globe->rotateRight();
240 }
241
242 /**
243 * Stops rotating the globe to the right.
244 * @param action Pointer to an action.
245 */
btnRotateRightRelease(Action *)246 void SelectDestinationState::btnRotateRightRelease(Action *)
247 {
248 _globe->rotateStopLon();
249 }
250
251 /**
252 * Starts rotating the globe upwards.
253 * @param action Pointer to an action.
254 */
btnRotateUpPress(Action *)255 void SelectDestinationState::btnRotateUpPress(Action *)
256 {
257 _globe->rotateUp();
258 }
259
260 /**
261 * Stops rotating the globe upwards.
262 * @param action Pointer to an action.
263 */
btnRotateUpRelease(Action *)264 void SelectDestinationState::btnRotateUpRelease(Action *)
265 {
266 _globe->rotateStopLat();
267 }
268
269 /**
270 * Starts rotating the globe downwards.
271 * @param action Pointer to an action.
272 */
btnRotateDownPress(Action *)273 void SelectDestinationState::btnRotateDownPress(Action *)
274 {
275 _globe->rotateDown();
276 }
277
278 /**
279 * Stops rotating the globe downwards.
280 * @param action Pointer to an action.
281 */
btnRotateDownRelease(Action *)282 void SelectDestinationState::btnRotateDownRelease(Action *)
283 {
284 _globe->rotateStopLat();
285 }
286
287 /**
288 * Zooms into the globe.
289 * @param action Pointer to an action.
290 */
btnZoomInLeftClick(Action *)291 void SelectDestinationState::btnZoomInLeftClick(Action *)
292 {
293 _globe->zoomIn();
294 }
295
296 /**
297 * Zooms the globe maximum.
298 * @param action Pointer to an action.
299 */
btnZoomInRightClick(Action *)300 void SelectDestinationState::btnZoomInRightClick(Action *)
301 {
302 _globe->zoomMax();
303 }
304
305 /**
306 * Zooms out of the globe.
307 * @param action Pointer to an action.
308 */
btnZoomOutLeftClick(Action *)309 void SelectDestinationState::btnZoomOutLeftClick(Action *)
310 {
311 _globe->zoomOut();
312 }
313
314 /**
315 * Zooms the globe minimum.
316 * @param action Pointer to an action.
317 */
btnZoomOutRightClick(Action *)318 void SelectDestinationState::btnZoomOutRightClick(Action *)
319 {
320 _globe->zoomMin();
321 }
322
323 /**
324 * Returns to the previous screen.
325 * @param action Pointer to an action.
326 */
btnCancelClick(Action *)327 void SelectDestinationState::btnCancelClick(Action *)
328 {
329 _game->popState();
330 }
331
btnCydoniaClick(Action *)332 void SelectDestinationState::btnCydoniaClick(Action *)
333 {
334 if (_craft->getNumSoldiers() > 0 || _craft->getNumVehicles() > 0)
335 {
336 _game->pushState(new ConfirmCydoniaState(_game, _craft));
337 }
338 }
339
340 /**
341 * Updates the scale.
342 * @param dX delta of X;
343 * @param dY delta of Y;
344 */
resize(int & dX,int & dY)345 void SelectDestinationState::resize(int &dX, int &dY)
346 {
347 for (std::vector<Surface*>::const_iterator i = _surfaces.begin(); i != _surfaces.end(); ++i)
348 {
349 (*i)->setX((*i)->getX() + dX / 2);
350 if (*i != _window && *i != _btnCancel && *i != _txtTitle && *i != _btnCydonia)
351 {
352 (*i)->setY((*i)->getY() + dY / 2);
353 }
354 }
355 }
356 }
357