1 ///////////////////////////////////////////////////////////////////////////////
2 // Copyright (C) 2004-2010 by The Allacrost Project
3 // All Rights Reserved
4 //
5 // This code is licensed under the GNU GPL version 2. It is free software
6 // and you may modify it and/or redistribute it under the terms of this license.
7 // See http://www.gnu.org/copyleft/gpl.html for details.
8 ///////////////////////////////////////////////////////////////////////////////
9
10 /** ****************************************************************************
11 *** \file shop_leave.cpp
12 *** \author Tyler Olsen, roots@allacrost.org
13 *** \brief Source file for leave interface of shop mode
14 ***
15 *** \note The contents of this file are near identical to the contents of
16 *** shop_confirm.cpp. When making any changes to this file, please look to
17 *** shop_confirm.cpp to see if it should have similar changes made.
18 *** ***************************************************************************/
19
20 #include "defs.h"
21 #include "utils.h"
22
23 #include "audio.h"
24 #include "input.h"
25 #include "system.h"
26 #include "video.h"
27 #include "mode_manager.h"
28
29 #include "shop.h"
30 #include "shop_leave.h"
31 #include "shop_buy.h"
32 #include "shop_sell.h"
33 #include "shop_trade.h"
34
35 using namespace std;
36
37 using namespace hoa_utils;
38 using namespace hoa_audio;
39 using namespace hoa_input;
40 using namespace hoa_system;
41 using namespace hoa_video;
42 using namespace hoa_gui;
43 using namespace hoa_mode_manager;
44
45 namespace hoa_shop {
46
47 namespace private_shop {
48
49 // *****************************************************************************
50 // ***** LeaveInterface class methods
51 // *****************************************************************************
52
LeaveInterface()53 LeaveInterface::LeaveInterface() :
54 _state(LEAVE_STATE_MAIN),
55 _active_list(ACTIVE_LIST_BUY),
56 _buy_count(0),
57 _buy_unique(0),
58 _sell_count(0),
59 _sell_unique(0),
60 _trade_count(0),
61 _trade_characters(0),
62 _buy_list_display(NULL),
63 _sell_list_display(NULL)
64 {
65 TextStyle stats_style("text20");
66
67 _buy_header.SetStyle(TextStyle("title22", Color::white));
68 _buy_header.SetText(UTranslate("Purchases"));
69 _buy_stats.SetStyle(stats_style);
70
71 _sell_header.SetStyle(TextStyle("title22", Color::white));
72 _sell_header.SetText(UTranslate("Sales"));
73 _sell_stats.SetStyle(stats_style);
74
75 _trade_header.SetStyle(TextStyle("title22", Color::white));
76 _trade_header.SetText(UTranslate("Trades"));
77 _trade_stats.SetStyle(stats_style);
78
79 _name_header.SetStyle(TextStyle("title24"));
80 _name_header.SetText(UTranslate("Name"));
81
82 _properties_header.SetOwner(ShopMode::CurrentInstance()->GetMiddleWindow());
83 _properties_header.SetPosition(480.0f, 390.0f);
84 _properties_header.SetDimensions(300.0f, 30.0f, 4, 1, 4, 1);
85 _properties_header.SetOptionAlignment(VIDEO_X_RIGHT, VIDEO_Y_CENTER);
86 _properties_header.SetTextStyle(TextStyle("title24"));
87 _properties_header.SetCursorState(VIDEO_CURSOR_STATE_HIDDEN);
88 _properties_header.AddOption(UTranslate("Price"));
89 _properties_header.AddOption(UTranslate("Stock"));
90 _properties_header.AddOption(UTranslate("Own"));
91 _properties_header.AddOption(MakeUnicodeString(""));
92
93 _empty_list_text.SetStyle(TextStyle("text24"));
94 _empty_list_text.SetText(UTranslate("No marked transactions."));
95
96 _buy_list_display = new BuyListDisplay();
97 _sell_list_display = new SellListDisplay();
98
99 _main_prompt.SetStyle(TextStyle("text24"));
100 _main_prompt.SetText(UTranslate("Your order is not yet final. Are you sure you want to leave the shop?"));
101 _main_actions.SetOwner(ShopMode::CurrentInstance()->GetBottomWindow());
102 _main_actions.SetPosition(60.0f, 80.0f);
103 _main_actions.SetDimensions(600.0f, 40.0f, 3, 1, 3, 1);
104 _main_actions.SetOptionAlignment(VIDEO_X_LEFT, VIDEO_Y_CENTER);
105 _main_actions.SetTextStyle(TextStyle("title24"));
106 _main_actions.SetCursorState(VIDEO_CURSOR_STATE_VISIBLE);
107 _main_actions.SetCursorOffset(-55.0f, 30.0f);
108 _main_actions.SetHorizontalWrapMode(VIDEO_WRAP_MODE_NONE);
109 _main_actions.AddOption(UTranslate("View Order"));
110 _main_actions.AddOption(UTranslate("Confirm Order"));
111 _main_actions.AddOption(UTranslate("Leave Shop"));
112 _main_actions.SetSelection(0);
113 }
114
115
116
~LeaveInterface()117 LeaveInterface::~LeaveInterface() {
118 if (_buy_list_display != NULL)
119 delete _buy_list_display;
120 if (_sell_list_display != NULL)
121 delete _sell_list_display;
122
123 _buy_list_display = NULL;
124 _sell_list_display = NULL;
125 }
126
127
128
MakeActive()129 void LeaveInterface::MakeActive() {
130 map<uint32, ShopObject*>* buy_list = ShopMode::CurrentInstance()->GetBuyList();
131 map<uint32, ShopObject*>* sell_list = ShopMode::CurrentInstance()->GetSellList();
132 // TODO: Get a container of all trades
133
134 // Vector constructs required by the BuyListDisplay/SellListDisplay classes
135 vector<ShopObject*> buy_vector;
136 vector<ShopObject*> sell_vector;
137
138 buy_vector.reserve(buy_list->size());
139 sell_vector.reserve(sell_list->size());
140
141 _buy_count = 0;
142 _buy_unique = 0;
143 for (map<uint32, ShopObject*>::iterator i = buy_list->begin(); i != buy_list->end(); i++) {
144 _buy_unique++;
145 _buy_count += i->second->GetBuyCount();
146 buy_vector.push_back(i->second);
147 }
148
149 _sell_count = 0;
150 _sell_unique = 0;
151 for (map<uint32, ShopObject*>::iterator i = sell_list->begin(); i != sell_list->end(); i++) {
152 _sell_unique++;
153 _sell_count += i->second->GetSellCount();
154 sell_vector.push_back(i->second);
155 }
156
157 _trade_count = 0;
158 _trade_characters = 0;
159 // TODO: Iterate through the trade container similar to buy and sell containers
160
161 _buy_list_display->PopulateList(buy_vector);
162 _sell_list_display->PopulateList(sell_vector);
163
164 // Determine which active list should be initially shown and change properties as needed
165 if (_buy_count != 0) {
166 _active_list = ACTIVE_LIST_BUY;
167 _buy_header.SetStyle(TextStyle("title24", Color::yellow));
168 _sell_header.SetStyle(TextStyle("title22", Color::white));
169 _trade_header.SetStyle(TextStyle("title22", Color::white));
170 _properties_header.SetOptionText(3, UTranslate("Buy"));
171 }
172 else if (_sell_count != 0) {
173 _active_list = ACTIVE_LIST_SELL;
174 _buy_header.SetStyle(TextStyle("title22", Color::white));
175 _sell_header.SetStyle(TextStyle("title24", Color::yellow));
176 _trade_header.SetStyle(TextStyle("title22", Color::white));
177 _properties_header.SetOptionText(3, UTranslate("Sell"));
178 }
179 else if (_trade_count != 0) {
180 _active_list = ACTIVE_LIST_TRADE;
181 _buy_header.SetStyle(TextStyle("title22", Color::white));
182 _sell_header.SetStyle(TextStyle("title22", Color::white));
183 _trade_header.SetStyle(TextStyle("title24", Color::yellow));
184 }
185 else {
186 _active_list = ACTIVE_LIST_BUY;
187 _buy_header.SetStyle(TextStyle("title24", Color::yellow));
188 _sell_header.SetStyle(TextStyle("title22", Color::white));
189 _trade_header.SetStyle(TextStyle("title22", Color::white));
190 _properties_header.SetOptionText(3, UTranslate("Buy"));
191 }
192
193 _buy_stats.SetText(NumberToString(_buy_count) + Translate(" count") + "\n" +
194 NumberToString(_buy_unique) + Translate(" unique"));
195 _sell_stats.SetText(NumberToString(_sell_count) + Translate(" count") + "\n" +
196 NumberToString(_sell_unique) + Translate(" unique"));
197 _trade_stats.SetText(NumberToString(_trade_count) + Translate(" count") + "\n" +
198 NumberToString(_trade_characters) + Translate(" characters"));
199
200 _state = LEAVE_STATE_MAIN;
201 _main_actions.SetSelection(0);
202
203 _main_actions.SetCursorState(VIDEO_CURSOR_STATE_VISIBLE);
204 _buy_list_display->GetIdentifyList().SetCursorState(VIDEO_CURSOR_STATE_HIDDEN);
205 _sell_list_display->GetIdentifyList().SetCursorState(VIDEO_CURSOR_STATE_HIDDEN);
206
207 ShopMode::CurrentInstance()->ObjectViewer()->SetSelectedObject(NULL);
208 ShopMode::CurrentInstance()->ObjectViewer()->ChangeViewMode(SHOP_VIEW_MODE_INFO);
209 } // void LeaveInterface::MakeActive()
210
211
212
Update()213 void LeaveInterface::Update() {
214 _main_actions.Update();
215 _buy_list_display->Update();
216 _sell_list_display->Update();
217
218 // A swap press changes the active transaction list being shown. It takes precedence over all other
219 // input events. Only the "info" state ignores this command because the transaction list is not visible
220 // while in this state
221 if ((InputManager->SwapPress()) && (_state != LEAVE_STATE_INFO)) {
222 _CycleActiveTransactionList();
223 return;
224 }
225
226 if (_state == LEAVE_STATE_MAIN) {
227 if (InputManager->CancelPress()) {
228 ShopMode::CurrentInstance()->ChangeState(SHOP_STATE_ROOT);
229 return;
230 }
231
232 else if (InputManager->ConfirmPress()) {
233 switch (_main_actions.GetSelection()) {
234 case 0: // "View Order"
235 _ChangeState(LEAVE_STATE_LIST);
236 return;
237 case 1: // "Confirm Order"
238 ShopMode::CurrentInstance()->ChangeState(SHOP_STATE_CONFIRM);
239 return;
240 case 2: // "Leave Shop"
241 ModeManager->Pop();
242 return;
243 default:
244 IF_PRINT_WARNING(SHOP_DEBUG) << "invalid selection in primary action options: "
245 << _main_actions.GetSelection() << endl;
246 return;
247 }
248 }
249
250 else if (InputManager->LeftPress()) {
251 _main_actions.InputLeft();
252 }
253 else if (InputManager->RightPress()) {
254 _main_actions.InputRight();
255 }
256 }
257
258 else if (_state == LEAVE_STATE_LIST) {
259 if (InputManager->CancelPress()) {
260 _ChangeState(LEAVE_STATE_MAIN);
261 return;
262 }
263
264 switch (_active_list) {
265 case ACTIVE_LIST_BUY:
266 if (InputManager->ConfirmPress()) {
267 _ChangeState(LEAVE_STATE_INFO);
268 }
269 else if (InputManager->UpPress()) {
270 _buy_list_display->InputUp();
271 }
272 else if (InputManager->DownPress()) {
273 _buy_list_display->InputDown();
274 }
275 return;
276 case ACTIVE_LIST_SELL:
277 if (InputManager->ConfirmPress()) {
278 _ChangeState(LEAVE_STATE_INFO);
279 }
280 else if (InputManager->UpPress()) {
281 _sell_list_display->InputUp();
282 }
283 else if (InputManager->DownPress()) {
284 _sell_list_display->InputDown();
285 }
286 return;
287 case ACTIVE_LIST_TRADE:
288 // TODO
289 return;
290 default:
291 IF_PRINT_WARNING(SHOP_DEBUG) << "invalid transaction list was active: "
292 << _active_list << endl;
293 return;
294 }
295 }
296
297 else if (_state == LEAVE_STATE_INFO) {
298 if (InputManager->ConfirmPress() || InputManager->CancelPress()) {
299 _ChangeState(LEAVE_STATE_LIST);
300 return;
301 }
302 }
303
304 else {
305 IF_PRINT_WARNING(SHOP_DEBUG) << "invalid leave state was active: " << _state << endl;
306 _state = LEAVE_STATE_MAIN;
307 }
308 } // void LeaveInterface::Update()
309
310
311
Draw()312 void LeaveInterface::Draw() {
313 // Draw the contents of the middle window. Either selected object information or the active transaction list
314 if (_state == LEAVE_STATE_INFO) {
315 ShopMode::CurrentInstance()->ObjectViewer()->Draw();
316 }
317 else {
318 // Draw the transaction type headers and stats
319 VideoManager->SetDrawFlags(VIDEO_X_LEFT, VIDEO_Y_BOTTOM, 0);
320 VideoManager->Move(140.0f, 525.0f);
321 _buy_header.Draw();
322 VideoManager->SetDrawFlags(VIDEO_Y_TOP, 0);
323 _buy_stats.Draw();
324
325 VideoManager->SetDrawFlags(VIDEO_Y_BOTTOM, 0);
326 VideoManager->MoveRelative(0.0f, -105.0f);
327 _sell_header.Draw();
328 VideoManager->SetDrawFlags(VIDEO_Y_TOP, 0);
329 _sell_stats.Draw();
330
331 VideoManager->SetDrawFlags(VIDEO_Y_BOTTOM, 0);
332 VideoManager->MoveRelative(0.0f, -105.0f);
333 _trade_header.Draw();
334 VideoManager->SetDrawFlags(VIDEO_Y_TOP, 0);
335 _trade_stats.Draw();
336
337 // Draw the list headers and contents
338 if ((_active_list == ACTIVE_LIST_BUY) && (_buy_list_display->IsListEmpty() == false)) {
339 VideoManager->SetDrawFlags(VIDEO_X_LEFT, VIDEO_Y_BOTTOM, 0);
340 VideoManager->Move(295.0f, 558.0f);
341 _name_header.Draw();
342
343 _properties_header.Draw();
344 _buy_list_display->Draw();
345 }
346 else if ((_active_list == ACTIVE_LIST_SELL) && (_sell_list_display->IsListEmpty() == false)) {
347 VideoManager->SetDrawFlags(VIDEO_X_LEFT, VIDEO_Y_BOTTOM, 0);
348 VideoManager->Move(295.0f, 558.0f);
349 _name_header.Draw();
350
351 _properties_header.Draw();
352 _sell_list_display->Draw();
353 }
354 else if ((_active_list == ACTIVE_LIST_TRADE) && (_trade_count != 0)) {
355 // TODO: once trade support is added, change above condition `(_trade_count != 0)`
356 // to a check on the trade list display's empty status
357 }
358 else { // The active list is empty
359 VideoManager->SetDrawFlags(VIDEO_X_CENTER, VIDEO_Y_CENTER, 0);
360 VideoManager->Move(560.0f, 405.0f);
361 _empty_list_text.Draw();
362 }
363 }
364
365 // Draw the contents of the lower window, the main prompt and actions
366 VideoManager->SetDrawFlags(VIDEO_X_LEFT, VIDEO_Y_CENTER, 0);
367 VideoManager->Move(160.0f, 180.0f);
368 _main_prompt.Draw();
369 _main_actions.Draw();
370 } // void LeaveInterface::Draw()
371
372
373
_ChangeState(LEAVE_STATE new_state)374 void LeaveInterface::_ChangeState(LEAVE_STATE new_state) {
375 if (_state == new_state) {
376 IF_PRINT_WARNING(SHOP_DEBUG) << "new state was the same as the current state: " << _state << endl;
377 return;
378 }
379
380 // Modify appropriate display properties of former state
381 if (_state == LEAVE_STATE_MAIN) {
382 _main_actions.SetCursorState(VIDEO_CURSOR_STATE_HIDDEN);
383 }
384 else if (_state == LEAVE_STATE_LIST) {
385 _buy_list_display->GetIdentifyList().SetCursorState(VIDEO_CURSOR_STATE_HIDDEN);
386 _sell_list_display->GetIdentifyList().SetCursorState(VIDEO_CURSOR_STATE_HIDDEN);
387 }
388 else if (_state == LEAVE_STATE_INFO) {
389 ShopMode::CurrentInstance()->ObjectViewer()->SetSelectedObject(NULL);
390 }
391
392 // Modify appropriate display properties of new state
393 if (new_state == LEAVE_STATE_MAIN) {
394 _main_actions.SetCursorState(VIDEO_CURSOR_STATE_VISIBLE);
395 }
396 else if (new_state == LEAVE_STATE_LIST) {
397 _buy_list_display->GetIdentifyList().SetCursorState(VIDEO_CURSOR_STATE_VISIBLE);
398 _sell_list_display->GetIdentifyList().SetCursorState(VIDEO_CURSOR_STATE_VISIBLE);
399 }
400 else if (new_state == LEAVE_STATE_INFO) {
401 ShopObject* selected_object = NULL;
402 switch (_active_list) {
403 case ACTIVE_LIST_BUY:
404 selected_object = _buy_list_display->GetSelectedObject();
405 break;
406 case ACTIVE_LIST_SELL:
407 selected_object = _sell_list_display->GetSelectedObject();
408 break;
409 case ACTIVE_LIST_TRADE:
410 // TODO: implement once trade interface is complete
411 break;
412 default:
413 IF_PRINT_WARNING(SHOP_DEBUG) << "invalid transaction list was active: " << _active_list << endl;
414 break;
415 }
416 ShopMode::CurrentInstance()->ObjectViewer()->SetSelectedObject(selected_object);
417 }
418 _state = new_state;
419 } // void LeaveInterface::_ChangeState(LEAVE_STATE new_state)
420
421
422
_CycleActiveTransactionList()423 void LeaveInterface::_CycleActiveTransactionList() {
424 TextStyle highlight("title24", Color::yellow);
425 TextStyle standard("title22", Color::white);
426
427 if (_active_list == ACTIVE_LIST_BUY) {
428 _active_list = ACTIVE_LIST_SELL;
429 _buy_header.SetStyle(standard);
430 _sell_header.SetStyle(highlight);
431 _properties_header.SetOptionText(3, UTranslate("Sell"));
432 }
433 else if (_active_list == ACTIVE_LIST_SELL) {
434 _active_list = ACTIVE_LIST_TRADE;
435 _sell_header.SetStyle(standard);
436 _trade_header.SetStyle(highlight);
437 }
438 else if (_active_list == ACTIVE_LIST_TRADE) {
439 _active_list = ACTIVE_LIST_BUY;
440 _trade_header.SetStyle(standard);
441 _buy_header.SetStyle(highlight);
442 _properties_header.SetOptionText(3, UTranslate("Buy"));
443 }
444 else {
445 IF_PRINT_WARNING(SHOP_DEBUG) << "invalid transaction list was active: " << _active_list << endl;
446 }
447 }
448
449 } // namespace private_shop
450
451 } // namespace hoa_shop
452